swerve が 2023年03月26日20時40分01秒 に編集
Blynk IoTへの移行
タグの変更
BLE
本文の変更
# 作ったもの
Blynkを用いた、BLE経由でスマホから操縦できる船のラジコンです。
Blynk IoTを用いた、WiFi経由でスマホから操縦できる船のラジコンです。 (記事を書いた2021~2022年までは初代BlynkでBLE経由仕様でしたが、 初代Blynkのサービス終了により更新しました)
船体等のハードは3Dプリンターで製作しています。
浮かべたときの動画 @[youtube](https://youtu.be/JmQgmEYQao8) # 動機 ふと、お台場の船の科学館にあった船のラジコンで遊べるコーナーを思い出したのですが、今は本館が展示休止中(らしいが一向に再オープンの気配が???)のため入れないんですよね... そこでそれっぽい船のラジコンを自作できないか、試作してみました。 # コンセプト - 通信距離 今回は船の科学館にあったラジコンコーナーのような小さめのプールを想定し、通信距離は約10mあればよいこととします。 ラジコンではプロポを使用することが多いと思いますが、今回はbluetoothを使用してみます。利点はスマホでの操作が可能な事などです。 - 規模 大きすぎると持ち運びや製作、保管に手間がかかる、小さすぎると波にさらわれるなどの制約がありますが、今回は家の棚の幅が550㎜だったので、全長500mm程度の大きさのものを想定します。 - モデル ちょっとマイナーかもしれないですが、商船(タンカー等)を作ります。 既製品のプラモなどを改造し利用する手法と、一から設計して製作する手法が考えられますが、 既製品は軍艦が多く、手頃な商船の模型はないので、一から設計します。 - 見栄え 模型のラジコン化には、市販の水中モーターを船底に取り付けるような手法と、実際の船のようにスクリューや舵を備えて動作させる2通りが考えられますが、スクリューが回るのを見ると楽しいので後者を選択します。 # システム構成
Blynkを用いてスマホから船に搭載されているESP32と通信し、操縦します。
Blynk IoTというアプリを用い、スマホから船に搭載されているESP32と通信し、操縦します。
通信を受け取ったESP32がモータドライバやサーボに指令を送ることで船が動きます。  最初、スマホの汎用bluetoothコントローラアプリ”RCBcontroller"を使って実装したのですが、今見ると何故か新規インストールできなくなってしまっていたので、Blynkを用いたものを紹介します。(RCBcontroller便利だから復活してほしいなあ)
[2023年3月追記]:この記事を書いた2021年当時に使用できていたBlynk(初代)は、2022年12月31日にサービスを終了してBlynk IoTなるものに移行したため、さらに内容が変わっています。 スマホアプリでIoTするのは便利ですが、サービス終了の可能性があるのはちょっとリスキーですね
# 回路構成 ESP32の乗っている基板には、1sリポバッテリーを充電できる機能がついています。 秋月に売ってたMCP73831のサンプル回路をそのまま使ってます。  ESP32の基板からはI2C用のコネクタ1つとサーボを動かせるコネクタ2つが生えています。 自動書き込みではなくボタンを2個押して書き込み状態になる方式を取ってます。  プリント基板に実装したものが以下のものになります。 プリント基板にしたのは、発注してみたかっただけなので特に意味はありません。  モータドライバにはATtiny85が乗っていて、I2Cで速度の指令を受け取ります。 これもモータドライバ基板を作ってみたくて作っただけなので、小さいモータ1個ならモータドライバICをそのままESP32に接続した方が省スペースだったかもしれないです。  配線パターンはEAGLEが自動で生成してくれたものをそのまま使ってるだけなので、結構変なことになってたりします。まあ動いてはいるので()  # 回路構成 主な材料(入手先はあってるかは分かりませんが...) | 部品名 | 個数 | 備考 | |:---:|:---:|---| | ESP-WROOM-32E | 1 | [入手先:秋月](https://akizukidenshi.com/catalog/g/gM-09607/) | | タクトスイッチ | 2 | [秋月で売ってるもの](https://akizukidenshi.com/catalog/g/gP-08074/) | |基板用マイクロUSBコネクタ(電源専用)| 1 | [秋月で売ってるもの](https://akizukidenshi.com/catalog/g/gC-10398/)| |基板用スライドスイッチ(横型) ESD175202| 1 | [秋月で売ってるもの](https://akizukidenshi.com/catalog/g/gP-08944//)| | PchチップMOSFET IRLML6402(20V3.7A)| 1 | [秋月で売ってるもの](https://akizukidenshi.com/catalog/g/gI-02553/)| | 超小型単セル用リチウムイオン・リチウムポリマー充電コントローラ MCP73831-2ATI/OT| 1 | [秋月で売ってるもの](https://akizukidenshi.com/catalog/g/gI-13288//)| | ATtiny85-20SUR | 1 | [入手先:秋月](https://akizukidenshi.com/catalog/g/gI-09574/) | | NchパワーMOSFET 60V40A TPH11006NL(4個入) | 1 | [入手先:秋月](https://akizukidenshi.com/catalog/g/gI-07361/) | | ハーフブリッジドライバ IR2302STRPBF | 2 | [入手先:秋月](https://akizukidenshi.com/catalog/g/gI-15656/) | | フォトカプラ 赤外LED+フォトトランジスタ TLP293(BLL)(5個入) | 1 | [入手先:秋月](https://akizukidenshi.com/catalog/g/gI-16783/) | | 抵抗各種(1k,2,2k,10k)| 少々|| | チップ・電解コンデンサ各種| 少々|| | チップダイオード| 少々|[入手先:秋月](https://akizukidenshi.com/catalog/g/gI-07084/)| | XHコネクタ(2,3,4ピン)| 少々 | | | PHコネクタ(2,3,4ピン) | 少々 | | | lipoバッテリー(1s 400mAh) | 1 | [千石で売ってるもの](https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-4YZL) | | 9V電池| 1 | | # ハードウェア 設計はSolidworksで行いました。  全長450mm、幅70mm、重量は電装完了状態で420gとなっています。 船のモデルは特にこれといったものを参考にしているわけではなく、 google画像検索で出てきたものの最大公約数的なものを勝手に練り上げてます。 そのため、構造はかなりナンチャッテです。 とはいえ、縮尺が1/200、実物換算で大体全長90m、幅14mなので調べてみる限りでは 699GT型の内航ケミカルタンカー辺りに該当する感じですかね? 船体の厚さは強度を考えて2mmにしましたが、ちょっと分厚すぎたかも。 あと内部に電装したりと触ることが多いので、手すり等の細かい形状はとりあえず省略しました。  船体の設計が大体終わったら、上記の写真のように3Dプリンタで印刷しやすいようにブロックに分割したり、メンテナンス用に甲板を分割して蓋のようにしたり、回路を取り付ける部品を取り付けるなどして、印刷します。  使用した3DプリンタはFlashForge製のAdventurer3で、印刷範囲と失敗した時のダメージを考えて船体1ブロック当たり110mm程度の長さにしています。 積層式の3Dプリンターはあまり模型向きではない気がしますが、これくらいのサイズの船体だと強度が必要なので向いている気がします。 まあ上の細かい部品とかは光造形式で作りたくはなりますね()  船体が大きいのとブロック同士がぴったり接合できないと辛いことになるので、反り、段差が入ると使えません。 ブロック1個当たり2回印刷して1回失敗するという感じだったので、印刷に失敗したブロックだけでもう1隻作れそうになりました。  船体の各ブロックは上記の写真のように接続面にはんだごてをチョンチョン当てて溶着しています。 最初は接着してたのですが,接着が下手くそだったらしく継ぎ目から浸水したのでこういう処理をしています。 ただ溶着するとブロック間に段差が生じまくって何とも言えない状態になるので、パテやらヤスリやら使ってなるべく平たくします。  スクリュー周りの軸周りは上記の写真のようになっています。 ベアリング入れるのを横着して、内径がΦ3シャフトにほぼぴったりの真鍮パイプを探してきて滑らせるだけにしました。金属シャフトは千石の3Fに売ってたものを使ってます。真鍮パイプはヨドバシだったかな..? スクリュー部から水が入ると色々とやっかいなのでいわゆるスタンチューブを参考にシャフトとパイプの間にタミヤのモリブデングリスを塗布しまくりました。 モリブデングリスにした理由は特にありませんが、とりあえず流出したり浸水するといった事は起きなかったので、まあ大丈夫な気がします。  スクリューを回すモータは秋月で売ってるミネベア社製の12V DCモータ PWN10EB12CBを使っています。 最初は低速でゆっくり回したいなあと思い連続回転サーボFS90Rを使用していたのですが、 あまりにも低速すぎて十分な推進力が得られなかったので、DCモータ直付けにしました。 秋月で売ってるFA130タイプや小さめのギアードモータも買ってみましたが、動作音が一番静かで低速がまあまあ効きそうなこのモータを選定しました。 このモータ、定番商品ではないのがちょっと微妙ですね  舵部は上記のようにサーボにFS90を用いて、4節リンクを組み舵を左右に動かします。 舵の可動範囲は±35度程度としています。 FS90は、形が似てるSG90よりもトルクは劣りますが、動作音がちょっとだけ静か&安いのがいい所ですね。リンクの部品は3Dプリンタ製です。 舵とスクリュー周りの動作の様子は以下の動画のようになっています。 スクリュー回るとなんか楽しいですね @[youtube](https://youtu.be/brl1XIA3oLE) ハードの主要部品 | 部品名 | 個数 | 備考 | |:---:|:---:|---| | Φ3ステンレスシャフト 長さ85(スクリュー用) | 1 | [入手先:千石電商](https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-4KW6) | | Φ2ステンレスシャフト 長さ25(舵用) | 1 | [入手先:千石電商](https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-4KV7) | | 六角穴付きボルトなどのねじ類 | 少々 | [入手先:ねじの西川]] | | モータ PWN10EB12CB| 1 | [入手先:秋月]] (https://akizukidenshi.com/catalog/g/gP-10024/)| | サーボ FS90 | 1 | [入手先:秋月]] (https://akizukidenshi.com/catalog/g/gM-14806/)|  電装すると上記の写真のようになります。 船首側からモータ用電源の9V電池、メイン基板となるesp32とロジック用バッテリーのlipo、モータドライバ、モータ、サーボの構成です。  ハードが完成したのでとりあえず浸水しないか家の風呂で試験しました。 船体が樹脂なので浮きすぎる状態になるかと予想していましたが、船体を分厚く作ったからか電池が重いからか20mm程度沈んで丁度いい感じになりました。 1時間くらい放置したけどスクリュー部からの浸水は特にはなさそう。 プライマーを全体に吹いて、凹凸を確認しつつ、やすりで削ったりを繰り返してから、 各部の塗装をしたらひとまず完成です。塗装がちょっと汚いのは許してください...   主観ですが、まあ船っぽい見た目にはなったんじゃないでしょうか?
# ESP-WROOM-32側のソースコード ```ESP32:blynk経由でBLE通信し、スクリューと舵を動かすコード
# ESP32側のソースコード(Blynk IoT版) ```Arduino:Blynk経由でWiFi通信し、スクリューと舵を動かすコード /* Fill-in information from Blynk Device Info here */ #define BLYNK_TEMPLATE_ID "xxxxxx" #define BLYNK_TEMPLATE_NAME "xxxxxx" #define BLYNK_AUTH_TOKEN "xxxxxx" //Blynkでプロジェクトを作るとここら辺を自動で埋めたコードが出力されるので、その値を使用します。
#include <Wire.h> #include <math.h> #include <ESP32Servo.h>
#include <BLEDevice.h> #include <BLEUtils.h> #include <BLEServer.h>
#include <WiFi.h> #include <WiFiClient.h> #include <BlynkSimpleEsp32.h>
#define I2C_MOTOR_ADR1 62 //モータドライバのi2cアドレス
#define I2C_MOTOR_ADR1 62 //モータドライバのi2cアドレスを入れる
Servo ladder;
Servo rudder;
//BLE #define BLYNK_USE_DIRECT_CONNECT
// Your WiFi credentials. // Set password to "" for open networks. char ssid[] = "xxxxxx";//使用するWiFiを記入 char pass[] = "xxxxxx";
#define BLYNK_PRINT Serial
BlynkTimer timer;
#include <BlynkSimpleEsp32_BLE.h>
int x = 128; int y = 128;
int x; int y;
char auth[] = "xxxxxxxxx";//ここにblynkのトークンを記入
BLYNK_WRITE(V1) {
BLYNK_WRITE(V3) {
y = param[0].asInt(); // Joystick x axis x = param[1].asInt(); // Joystick y axis }
//ここまでBLE
BLYNK_CONNECTED() { // Change Web Link Button message to "Congratulations!" Blynk.setProperty(V3, "offImageUrl", "https://static-image.nyc3.cdn.digitaloceanspaces.com/general/fte/congratulations.png"); Blynk.setProperty(V3, "onImageUrl", "https://static-image.nyc3.cdn.digitaloceanspaces.com/general/fte/congratulations_pressed.png"); Blynk.setProperty(V3, "url", "https://docs.blynk.io/en/getting-started/what-do-i-need-to-blynk/how-quickstart-device-was-made"); }
//ここから下がI2C void I2Cwrite2byte(unsigned int a, unsigned int b , int d){ Wire.beginTransmission( d ); Wire.write( a ); Wire.write( b ); Wire.endTransmission(); } //ここまでI2Cの設定 void setup() {
delay(500); Serial.begin(9600);
Serial.begin(115200);
Wire.begin();
Serial.println("Waiting for connections..."); Blynk.setDeviceName("BLE_ship");//デバイス名の設定 Blynk.begin(auth);
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
ladder.attach(18);
rudder.attach(18);
y=127; x=127;
y=128; x=128;
} void loop() { Blynk.run();
timer.run();
int rotpower;
int ladderangle;
int rudderangle;
//スクリュー用のモータの操作 if(x>127){//前進時 rotpower=map(x,128,255,0,242); I2Cwrite2byte(rotpower,0,I2C_MOTOR_ADR1); } else if(x<127){//後進時 rotpower=map(x,0,126,242,0); I2Cwrite2byte(0,rotpower,I2C_MOTOR_ADR1); } else{ I2Cwrite2byte(0,0,I2C_MOTOR_ADR1);//指令無き時は停止 } //舵のサーボの操作 if(y>128){
ladderangle=map(y,128,255,90,55);
rudderangle=map(y,128,255,90,55);
ladder.write(ladderangle);
rudder.write(ladderangle);
} else if(y<128){
ladderangle=map(y,0,126,128,90);
rudderangle=map(y,0,126,128,90);
ladder.write(ladderangle);
rudder.write(rudderangle);
} else{
ladder.write(90);//指示無き時は戻す
rudder.write(90);//指示無き時は戻す
}
delay(10);
} ```
blynkの設定、といっても何もなくて、真ん中にジョイスティックを配置しただけです。
Blynkの設定、といっても何もなくて、真ん中にジョイスティックを配置しただけです。
上下で前進/後進、左右で舵の操作にしてます。 まあ片手で全操作できることは利点な気はします。


ジョイスティックの設定は以下のようにしました 
ジョイスティックの設定は以下のようにしました。 
```arduino:モータードライバに乗ってるATtiny85のコード //for ATtiny85 motor driver #include<Wire.h> #define motor_id 62 //モータドライバのi2cアドレス int pwm[]={0,0}; void setup() { pinMode(4,OUTPUT); pinMode(1,OUTPUT); pinMode(3,OUTPUT); TCCR1 = (1 << CTC1) | (1 << PWM1A) | (1 << COM1A1); TCCR1 |= (1 << CS13) | (1 << CS11)| (1 << CS10); OCR1C = 255; GTCCR = _BV (PWM1B) | _BV (COM1B1) | _BV (COM1B0); Wire.begin(motor_id); Wire.onReceive(receiveEvent); } void loop() { OCR1A=map(pwm[1],0,254,0,250); OCR1B=map(pwm[0],254,0,5,255); delay(2); } void receiveEvent(int cnt) { if(Wire.available()>1){ pwm[0]=Wire.read(); pwm[1]=Wire.read(); } } ``` ArduinoのコードでPWMを生成して動作させると周波数が約1kHzらしくスクリュー回すたびに”プーン"と鳴るのが気になってしまったので、PWM周波数を変えています。 まあ回ればいいので下げまくっています。 # 動作の様子 完成後、記事一番上の動画のように近くの公園の屋外プールで試運転しました。 前進後進、舵は結構効いてる感じがします。まあタンカーにしてはちょっと早いような... ただこの船、フリーボードが11mmと低いので波が高いときは死ですね。 あと普通にどんどん風に流されます。 余裕をもって推進力を取らないと悲惨なことになりますね
見通しが良いのでBLEでも10m程度は通信できていそうですが、このプール10m以上あるのでうっかりすると圏外になります()
見通しが良いのでBLEでは10m程度は通信できていそうですが、このプール10m以上あるのでうっかりすると圏外になります() WiFiでは何m届くのかはまだ実験していませんが、おそらく同じ程度ですね
プールや小さめの池などの環境がいい所ではこれでも十分かもしれませんが、大きめの池を横断する、もし流されても回収が困難な場所は控えた方がよさそうです # 完成した感想 ひとまず通信距離、規模、モデル、見栄えの4つのコンセプトを満たしていそうな物が得られたので安心が倍増しました。 製作期間ですが、回路の設計に0.5カ月、船体の設計に1.5カ月、船体の印刷組み立てに0.5カ月、塗装に1か月の計3.5カ月程度です。一度作ったものをもう1隻欲しいときには設計の1.5カ月が要らなくなるので、2カ月程度でなんとかなるんでしょうかね?まあ面倒なのでしばらくは作りたくないですが... あとかかった費用の概算してみると9900円程度ですね。ただこれは結構前後する値かも... ハード、塗料、回路、電池の費用の割合に関しては以下のグラフのようになりました。  何から何に至るまで3Dプリンター製なので、フィラメント代がかさんでる感じで、まあ塗料もハードに含めていいのなら船のガワを作るのが一番高いし、手間がかかると言えます。 (もはやハード側が主で電子工作はオマケといえますね、ここに投稿していいのか..?)
実際ハード製作に労力を注ぎ込めるようになったのは、スマホとESP32との通信などの労力をblynkが楽にしてくれているのが大きい気がします。プログラミング弱者なので、Blynkなかったら動かすまでに多分無限時間かかってますね()
実際ハード製作に労力を注ぎ込めるようになったのは、スマホとESP32との通信などの労力をBlynkが楽にしてくれているのが大きい気がします。プログラミング弱者なので、Blynkなかったら動かすまでに多分無限時間かかってますね()
# おわりに
船のラジコン、特に商船はなかなか既製品が無いですが、努力と根性で何とかして3Dモデル作って、3Dプリンターで印刷して、blynkでお手軽にラジコン化すれば、それっぽいものが自作できるのが分かりました。(3Dデータを作るのが結構面倒ですが...)
船のラジコン、特に商船はなかなか既製品が無いですが、努力と根性で何とかして3Dモデル作って、3Dプリンターで印刷して、Blynkでお手軽にラジコン化すれば、それっぽいものが自作できるのが分かりました。(3Dデータを作るのが結構面倒ですが...)
操縦しつつの撮影が結構面倒だったので、センサー積んで、ある程度自動で走らせられるようにする、といった事もすると面白いかもしれないです。 # おまけ タンカー作り終わった後、さらに1隻作りました。 モデルは30FFM(もがみ型?)の1/200ですね(あまり似てないのがアレ) 全長660㎜なので家の棚(550mm)に斜めにしてギリギリ入れてます() これも同じようにラジコン化してあります。やはり船体が大きい方が浮かべた時に安定しますね  # 参考文献 https://lotton-6t.com/motor_drive-h_bridge/(本サイトで用いたモータードライバの構成はおよそこのサイトにあるものと同じです) http://maison-dcc.sblo.jp/article/187713251.html(ATtiny85のPWM周波数変更について参考にしました) https://martyworkshopdiary.blogspot.com/2020/04/attiny85_25.html(ATtiny85のPWM周波数変更について参考にしました)