AndroidスマホとRaspberry Pi Pico WをUSBシリアル通信で接続してステッピングモータを制御する実験を紹介します。スマホ側のアプリはAndroid Studioを使用してKotlin言語で作成しました。
また、スマホ側のUSBシリアル通信用のライブラリーとしてusb-serial-for-androidを使用しました。
Raspberry Pi Pico W側のプログラムはArduino IDEを使用し、Arduino言語で作成しました。
1.動作動画
今回作成した実験装置を動作させた動画です。スマホとRaspberry Pi Pico WをUSB接続すると、アプリ起動許可画面が表示され、「OK」をタップするとアプリが起動されます。
アプリ画面の「接続」ボタンを押すとUSBシリアル通信が接続され、「CW」ボタンを押すとステッピングモータが時計方向に回転します。また「CCW」ボタンを押すとステッピングモータが反時計方向に回転します。
2.スマホ側のアプリに関して
2-1.スマホとRaspberry Pi Pico WのUSB接続に関して
使用したスマホにはType micro-BのUSBコネクタが付いていますので、Type micro-BからType A (メス)への変換ケーブル(OTGケーブル)を使用しました。それとType AとType micro-BのUSBケーブルを接続してスマホとRaspberry Pi Pico Wを接続しました。(図1)

2-2.usb-serial-for-androidに関して
USBシリアル通信を行うのに、usb-serial-for-androidのライブラリを使用しました。(詳細はhttps://github.com/mik3y/usb-serial-for-androidを参照して下さい)
以下でusb-serial-for-androidのライブラリを使用する手順に関して説明します。
2-3.usb-serial-for-androidを使用する手順
1.settings.gradle.kts(Project Settings)の設定
app→Gladle Scripts→settings.gradle.kts(Project Settings)のdependencyResolutionManagementのrepositories内に、
maven { url = uri(“https://jitpack.io”) }
を追加します。(下記6行目)
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
}
2.build.gradle.kts(Module:app)の設定
app→Gladle Scripts→build.gradle.kts(Module:app)のdependencies内に
implementation(“com.github.mik3y:usb-serial-for-android:3.8.1”)
を追加します。(下記7行目)
dependencies {
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.appcompat:appcompat:1.7.0")
implementation("com.google.android.material:material:1.12.0")
implementation("androidx.constraintlayout:constraintlayout:2.2.0")
implementation("com.github.mik3y:usb-serial-for-android:3.8.1")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.2.1")
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
}
3.AndroidManifest.xmlの設定
スマホのUSBにRaspberry Pi Pico Wが接続された場合に、今回作成したアプリの選択画面を表示するために、app→manifests→AndroidManifest.xmlに以下の記述を追加します。
<intent-filter>~</intent-filter>タグ内に
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
を追加します。(下記6行目)
また、
<meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" />
を以下の様に追加します。(下記10行目~12行目)
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" />
</activity>
4.device_filter.xmlの作製
Raspberry Pi Pico WのUSBのVendor IDは0x2e8a (11914)、Product IDは0xf00a (61450)です。
これをapp→res→xmlの下にdevice_filter.xmlと言う名称のxmlファイルを作成して、以下の様に記述することによって、スマホのUSBにRaspberry Pi Pico Wが接続された場合に、今回作成したアプリの選択画面を表示することができます。そのアプリ名称を選択しタップすると、アプリが起動されます。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--Raspberry Pi Pico W USB serial-->
<usb-device vendor-id="11914" product-id="61450" /> <!--0x2e8a / 0xf00a: Pico W -->
</resources>
2-4.Kotlinプログラム概要
①USBシリアル通信の接続部分のソースコード
USBシリアル通信を接続する部分のKotlinのソースコードを以下に示します。
//----USBシリアル通信接続の実施-------
//Raspberry Pi Pico WのベンダーIDとプロダクトID
val VENDOR_ID: Int = 0x2e8a //11914
val PRODUCT_ID: Int = 0xf00a //61450
//シリアルポート
var port: UsbSerialPort? = null
fun serialConnect(): Boolean {
val usbManager: UsbManager = getSystemService(Context.USB_SERVICE) as UsbManager
var driver: UsbSerialDriver? = null
for (dev in UsbSerialProber.getDefaultProber().findAllDrivers(usbManager)) {
val device: UsbDevice = dev.device
//ベンダIDとプロダクトIDがPico Wと一致することを確認
if ((device.vendorId == VENDOR_ID) && (device.productId == PRODUCT_ID)) {
driver = dev
break
}
}
if (driver == null) {
return false
} else {
if (usbManager.hasPermission(driver.device) == true) { //USB使用許可確認
runOnUiThread {
Toast.makeText(this@MainActivity, "USB使用パーミッションOK", Toast.LENGTH_LONG).show()
}
} else {
runOnUiThread {
Toast.makeText(this@MainActivity, "USB使用パーミッションNG", Toast.LENGTH_LONG).show()
}
return false
}
}
val connection = usbManager.openDevice(driver!!.device)
if (connection == null) {
return false
}
port = driver!!.ports[0]
port?.open(connection)
port?.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE)
port?.dtr = true //Dtrをtrueにする
port?.rts = true //Rtsをtrueにする
return true
}
【説明】
3行目、4行目:
val VENDOR_ID: Int = 0x2e8a
val PRODUCT_ID: Int = 0xf00a
でRaspberry Pi Pico WのUSBのVendor IDとProduct IDを定義しています。
14行目、15行目:
device.vendorIdでUSB接続されているデバイスのVendor IDが得られます。
device.productIdでUSB接続されているデバイスのProduct IDが得られます。
Vendor IDとProduct IDがRaspberry Pi Pico Wのそれと一致する場合に、そのUSBシリアルドライバを選びます。
23行目:
if (usbManager.hasPermission(driver.device) == true) {
でUSBの使用許可が取れているかの確認をします。
前述したAndroidManifest.xmlとdevice_filter.xmlの記述がされている場合、スマホのUSBにRaspberry Pi Pico Wを接続された場合に、今回作成したアプリの選択画面が表示されます。
その時に、そのアプリ名称を選択しタップすると、アプリによるUSBの使用が許可された上でアプリが起動されますので、その手順を経た場合は、usbManager.hasPermission(driver.device)はtrueとなります。
何等かの状況でusbManager.hasPermission(driver.device)がfalseの場合は、USBの使用許可を要求する処理が必要ですが、簡略化のため今回のアプリでは無とします。
43行目、44行目:
port?.dtr = true
port?.rts = true
Raspberry Pi Pico Wとデータをやり取りするためには、USBシリアル通信ポートの信号線であるDtrとRtsをtrueにする必要があります。
②データの送信部分のソースコード
以下は、USBシリアル通信を使用して、例として文字列”CW\n”を送信する場合のソースコードです。
val data: String = "CW\n"
val byteData = data.toByteArray() //バイト配列にする
port?.write(byteData, 1000) //データ送信
【説明】
1行目、2行目:
val data: String = “CW\n”
val byteData = data.toByteArray()
で、文字列 “CW\n”を8bitのバイナリに変換してバイトアレイにします。
3行目:
port?.write(byteData, 1000)
でデータを送信します。第1引数は送信するデータのバイトアレイ、第2引数はオーバタイム時間(msec単位)です。
③データの受信部分のソースコード
以下は、USBシリアル通信を使用して、データを受信する部分のソースコードです。
val rcvBuffer: ByteArray = ByteArray(100) //受信バッファ
val numBytes = port?.read(rcvBuffer, 20)
【説明】
2行目:
val numBytes = port?.read(rcvBuffer, 20)
でUSBシリアル通信ポートから受信データを呼び出します。readメソッドの第1引数は、受信データを格納するバイトアレイです。第2引数はオーバタイム時間(msec単位です)
numBytesは呼び出されたデータのバイト数です。
2-5.Kotlin全ソースコード
今回作成したアプリのKotlinの全ソースコードを以下に示します。データの受信部分は、スレッドで行っています。
このプログラムの動作は、アプリ画面の「接続」ボタンを押すとUSBシリアル通信が接続され、「CW」ボタンを押すとステッピングモータが時計方向に回転し、「CCW」ボタンを押すとステッピングモータが反時計方向に回転し、「切断」ボタンを押すとUSBシリアル通信が切断されます。
class MainActivity : AppCompatActivity() {
//Raspberry Pi Pico WのベンダーIDとプロダクトID
val VENDOR_ID: Int = 0x2e8a //11914
val PRODUCT_ID: Int = 0xf00a //61450
//シリアルポート
var port: UsbSerialPort? = null
//接続フラグ
var connectFlag: Boolean = false
//停止フラグ
var stopFlag: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//-----押し釦スイッチ関係リスナ----------
//CWボタンonTouchListenerを設定
val cwButton = findViewById<Button>(R.id.cwButton)
cwButton.setOnTouchListener(CwButtonOnTouchListener())
//CCWボタンonTouchListenerを設定
val ccwButton = findViewById<Button>(R.id.ccwButton)
ccwButton.setOnTouchListener(CcwButtonOnTouchListener())
//接続ボタンのonClickListenerを設定
val connectButton = findViewById<Button>(R.id.connectButton)
connectButton.setOnClickListener(ConnectButtonOnClickListener())
//切断ボタンのonClickListenerを設定
val disconnectButton = findViewById<Button>(R.id.disconnectButton)
disconnectButton.setOnClickListener(DisconnectButtonOnClickListener())
}
//CWボタン押された時のonTouchListener
private inner class CwButtonOnTouchListener : View.OnTouchListener {
override fun onTouch(v: View?, event: MotionEvent?): Boolean {
if (connectFlag == true) { //接続中?
if (event?.action == MotionEvent.ACTION_DOWN) { //ボタン押された
val data: String = "CW\n"
val byteData = data.toByteArray() //バイト配列にする
port?.write(byteData, 1000) //データ送信
} else if (event?.action == MotionEvent.ACTION_UP) { //ボタン離された
val data: String = "STOP\n"
val byteData = data.toByteArray() //バイト配列にする
port?.write(byteData, 1000) //データ送信
}
}
return true
}
}
//CCWボタン押された時のonTouchListener
private inner class CcwButtonOnTouchListener : View.OnTouchListener {
override fun onTouch(v: View?, event: MotionEvent?): Boolean {
if (connectFlag == true) { //接続中?
if (event?.action == MotionEvent.ACTION_DOWN) { //ボタン押された
val data: String = "CCW\n"
val byteData = data.toByteArray() //バイト配列にする
port?.write(byteData, 1000) //データ送信
} else if (event?.action == MotionEvent.ACTION_UP) { //ボタン離された
val data: String = "STOP\n"
val byteData = data.toByteArray() //バイト配列にする
port?.write(byteData, 1000) //データ送信
}
}
return true
}
}
//接続ボタン押された時のonClickListener
private inner class ConnectButtonOnClickListener : View.OnClickListener {
override fun onClick(v: View?) {
if (connectFlag == false) { //接続中?
//シリアル通信接続と受信スレッドスタート
stopFlag = false //停止フラグクリア
val connectThread = ConnectThread()
connectThread.start()
}
}
}
//切断ボタン押された時のonClickListener
private inner class DisconnectButtonOnClickListener : View.OnClickListener {
override fun onClick(v: View?) {
stopFlag = true //停止フラグセット
}
}
//接続と受信スレッド
private inner class ConnectThread() : Thread() {
private val RCV_BUF_SIZE: Int = 1024 //受信バッファサイズ
private val rcvBuffer: ByteArray = ByteArray(RCV_BUF_SIZE) //受信バッファ
private var rcvString: String? = null //受信データ文字列
public override fun run() {
serialConnect() //USBシリアル通信接続の実施
runOnUiThread {
Toast.makeText(this@MainActivity, "USBシリアル通信接続完了", Toast.LENGTH_LONG).show()
}
connectFlag = true //接続中フラグセット
var numBytes: Int? = 0
while (true) {
try {
numBytes = port?.read(rcvBuffer, 20)
}catch (e: IOException){
connectFlag = false //接続中フラグクリア
break
}
if (numBytes != 0) {
//受信データを文字列に変換する
var rcvData: String = String(rcvBuffer, 0, numBytes!!)
//前回までに受信したデータと結合
if (rcvString == null) {
rcvString = rcvData
} else {
rcvString = rcvString + rcvData
}
//ターミネータ"\r\n"検索
val termPos: Int = rcvString?.lastIndexOf("\r\n")!!
if (termPos != -1) { //ターミネータ"\r\n"存在?
//"X:"を検索する
val XPos: Int = rcvString?.lastIndexOf("X:")!!
//"X:"が存在して、"\r\n"より前に存在
if ((XPos != -1) && (XPos < termPos)) {
//数値の部分を抜き出す
val posData: String = rcvString?.substring(XPos + 2, termPos)!!
runOnUiThread { //UIスレッド
val posTextView = findViewById<TextView>(R.id.positionTextView)
posTextView.text = "X " + posData //現在位置をTextViewに表示
}
}
//受信データストリングクリア
rcvString = null
}
}
if (connectFlag == false){ //接続中?
break
}
if (stopFlag == true){ //停止要求?
break
}
}
port?.close()
connectFlag = false //接続中フラグクリア
}
}
//----USBシリアル通信接続の実施-------
fun serialConnect(): Boolean {
val usbManager: UsbManager = getSystemService(Context.USB_SERVICE) as UsbManager
var driver: UsbSerialDriver? = null
for (dev in UsbSerialProber.getDefaultProber().findAllDrivers(usbManager)) {
val device: UsbDevice = dev.device
//ベンダIDとプロダクトIDがPico Wと一致することを確認
if ((device.vendorId == VENDOR_ID) && (device.productId == PRODUCT_ID)) {
driver = dev
break
}
}
if (driver == null) {
return false
} else {
if (usbManager.hasPermission(driver.device) == true) { //USB使用許可確認
runOnUiThread {
Toast.makeText(this@MainActivity, "USB使用パーミッションOK", Toast.LENGTH_LONG).show()
}
} else {
runOnUiThread {
Toast.makeText(this@MainActivity, "USB使用パーミッションNG", Toast.LENGTH_LONG).show()
}
return false
}
}
val connection = usbManager.openDevice(driver!!.device)
if (connection == null) {
return false
}
port = driver!!.ports[0]
port?.open(connection)
port?.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE)
port?.dtr = true //Dtrをtrueにする
port?.rts = true //Rtsをtrueにする
return true
}
}
2-6.アプリ画面のレイアウト
作製したアプリ画面のレイアウトを以下に示します。
アプリ画面のレイアウトは、Buttonを4個とTextViewを1個配置しました。表1に各Viewのidと役割に関して記載します。

名称 | 種類 | id | 役割 |
CWボタン | Button | cwButton | ステッピングモータを時計回り方向に回転させる |
CCWボタン | Button | ccwButton | ステッピングモータを反時計回り方向に回転させる |
接続ボタン | Button | connectButton | USBシリアル通信を接続する |
切断ボタン | Button | disconnectButton | USBシリアル通信を切断する |
現在位置表示 | TextView | positionTextView | ステッピングモータの回転現在位置を表示する |
画面レイアウトに対応したXMLのコード(app→res→layout→activity_main.xml)を以下に示します。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/positionTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="64dp"
android:layout_marginTop="32dp"
android:text="X 0"
android:textSize="48sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/cwButton"
android:layout_width="147dp"
android:layout_height="74dp"
android:layout_marginStart="24dp"
android:layout_marginTop="32dp"
android:text="CW"
android:textSize="34sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/positionTextView" />
<Button
android:id="@+id/ccwButton"
android:layout_width="147dp"
android:layout_height="74dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="24dp"
android:text="CCW"
android:textSize="34sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/positionTextView" />
<Button
android:id="@+id/connectButton"
android:layout_width="147dp"
android:layout_height="74dp"
android:layout_marginStart="24dp"
android:layout_marginTop="80dp"
android:text="接続"
android:textSize="34sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cwButton" />
<Button
android:id="@+id/disconnectButton"
android:layout_width="147dp"
android:layout_height="74dp"
android:layout_marginTop="80dp"
android:layout_marginEnd="24dp"
android:text="切断"
android:textSize="34sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ccwButton" />
</androidx.constraintlayout.widget.ConstraintLayout>
3.実験装置に関して
今回作成した実験装置では、ステッピングモータは28BYJ-48とそのドライバーボードのセットを使用しました。このステッピングモータとドライバーボードは複数のネット通販から購入することが出来ます。
コントローラとしてはRaspberry Pi Pico Wを使用しました。(ステッピングモータ駆動の詳細に関してはこちらを参照して下さい)



今回使用したステッピングモータの主な仕様は表2の通りです。このモータは1/64のギアで減速されていて、1-2相励磁の場合にステップ角は5.625°/64なので4096ステップでモータ軸が1回転します。最大自起動周波数が500ppsなので、500パルス/sec以下で起動する必要があります。起動後は徐々に加速を行った場合に、最大で1000パルス/secまで仕様上は可能と思われます。
ただし、Arduino IDEのStepperライブラリーのstep()関数を使用した場合の励磁方式は2相励磁のようです。そのため2048ステップでモータ1回転となります。
項目 | 仕様 |
相数 | 4相 |
励磁方式 | 1-2相励磁方式 |
ステップ角 | 5.625°/64 (減速比1/64) |
電圧 | 5VDC |
相抵抗 | 22Ω ± 7% 25°C |
最大応答周波数 | 1000pps |
最大自起動周波数 | 500pps |
引き込みトルク | 800gf.cm / 5VDC 400pps |
4.実験装置回路図
図2に実験装置の回路図を示します。1個のステッピングモータをRaspberry Pi Pico Wに接続しています。
28BYJ-48ステッピングモータのドライバーボードはテキサスインスツルメンツのULN2003ANと言うダーリントントランジスタアレイが使用されています。ドライバーボード自体の資料が無かったので、テスタと基板のパターンを見て回路を調べました。
ステッピングモータのドライバーボードの入力信号IN1~IN4をRaspberry Pi Pico WのGP0~GP3に接続しました。
使用したスマホにはType micro-BのUSBコネクタが付いていますので、Type micro-BからType A (メス)への変換ケーブル(OTGケーブル)とType A (オス)とType micro-BのUSBケーブルを使用してスマホとRaspberry Pi Pico WをUSB接続しています。

5.Raspberry Pi Pico Wのプログラム
Raspberry Pi Pico W側のプログラムはArduino IDEを使用して、Arduino言語で作成しました。
これは以前「Raspberry Pi Pico Wを使用してステッピングモータをUSBシリアル通信で制御する実験」の記事で紹介しましたプログラムと同一です。詳細は以前の記事を参照して下さい。(以前の記事はこちら)
概要は、USBシリアル通信で送られた以下コマンドデータに従ってステッピングモータが動作します。
”CW\n” CW方向に回転
”CCW\n” CCW方向に回転
”STOP\n” 回転停止
移動中は、USBシリアルポートに、ステッピングモータの回転現在位置を以下の形式で送信します。
X:「パルス位置」「ターミネータ(”r¥n”)」
例
“X:45\r\n”
ここではプログラム(スケッチ)のコードのみを示します。
//--Raspberry Pi Pico W シリアル通信JOG運転テストソフト-------------
#include <Stepper.h>
#define RPM_SPEED 10 //モータ回転速度(rpm)
#define STEPS 2048 //モータの1回転のステップ数
//軸の現在位置記憶用データ(符号付きステップ位置)
long current_pos = 0;
//経過時間判断用データ
unsigned long last_time = 0; //前回の時間記憶
unsigned long delay_time = 0; //処理待ち時間(次の処理をするまでの時間)
//シリアルデータ受信処理用データ
char rdBuf[100]; //受信データバッファ
int rdNo = 0; //受信データ数
String s_rcvData; //受信文字列
//回転指令フラグ
bool cw_mov_flag = false; //CW回転指令フラグ
bool ccw_mov_flag = false; //CCW回転指令フラグ
//ステッピングモータ初期設定
Stepper stepper(STEPS, 0, 2, 1, 3);//ステッピングモータ設定(1回転2048ステップ)
void setup() {
Serial.begin(9600); //USBシリアル通信初期化
pinMode(0, OUTPUT); //ステッピングモータ(青線)
pinMode(1, OUTPUT); //ステッピングモータ(桃線)
pinMode(2, OUTPUT); //ステッピングモータ(黄線)
pinMode(3, OUTPUT); //ステッピングモータ(橙線)
//ステッピングモータ回転速度設定
stepper.setSpeed(500); //ステッピングモータの回転速度500rpm
//処理待ち時間の設定
delay_time = 60 * 1000 * 1000 / STEPS / RPM_SPEED;
}
void loop() {
//シリアルデータ受信処理
bool res = readSerial();
if (res == true){ //受信完了
com_interpreter(); //受信コマンド解釈処理
}
//前回処理からの経過時間計算
unsigned long pass_time;
unsigned long now_time = micros(); //現在時刻読出し(usec単位)
if (now_time >= last_time){
pass_time = now_time - last_time; //経過時間計算
}else{
//オーバフローを加味して経過時間計算
pass_time = now_time - (0xffffffffUL - last_time + 1);
}
//モータ回転処理
if (pass_time >= delay_time){ //時間到達?
last_time = now_time;
if (cw_mov_flag == true){ //CW回転?
stepper.step(-1); //-1ステップ回転
current_pos--; //現在位置マイナス
//現在位置をPCへシリアル通信
serial_pos();
}
else if (ccw_mov_flag == true){ //CCW回転?
stepper.step(1); //1ステップ回転
current_pos++; //現在位置プラス
//現在位置をPCへシリアル通信
serial_pos();
}
}
}
//現在位置をパソコンにシリアル通信
void serial_pos(){
String text_x = String(current_pos);
String text = String("X:" + text_x);
Serial.println(text); //現在位置をPCへ送信
}
//パソコンからの受信処理
//戻り値: ture 受信完了、false 受信未完了
bool readSerial()
{
bool rdEndFlag = false; //受信完了フラグ
int rNo = Serial.available();
if (rNo > 0){ //受信データ有り
//'\n'までの受信データを読み込む
s_rcvData = Serial.readStringUntil('\n');
rdEndFlag = true; //受信完了フラグセット
} else {
rdEndFlag = false; //受信完了フラグリセット
}
return rdEndFlag;
}
//パソコンからの受信データコマンド解釈
void com_interpreter()
{
if (s_rcvData.startsWith("CW") == true){ //"CW"?
ccw_mov_flag = false; //ccw回転フラグリセット
cw_mov_flag = true; //CW回転フラグセット
}else if (s_rcvData.startsWith("CCW") == true){ //"CCW"?
cw_mov_flag = false; //cw回転フラグリセット
ccw_mov_flag = true; //CCW回転フラグセット
}else if (s_rcvData.startsWith("STOP") == true){//"STOP"?
cw_mov_flag = false; //cw回転フラグリセット
ccw_mov_flag = false; //ccw回転フラグリセット
}
}
6.最後に
今回作成したアプリでは、スマホとRaspberry Pi Pico WをUSBシリアル通信で接続して、ステッピングモータを制御しました。
Raspberry Pi Pico Wでは、Wi-FiやBluetoothが使用出来るので、スマホと通信するのにUSBを使用する必要性は少ないかもしれませんが、スマホをマイコンボードの操作機器として使用する方法の一つとしてトライしました。
尚、AndroidスマホとRaspberry Pi Pico WとのWi-Fi通信やBlutooth通信に関しては、以下の記事を参考にして下さい。
・スマホとPico WとのWi-Fi通信に関する記事はこちら
・スマホとPico WとのBluetooth通信に関する記事はこちら