ESP32の無線基板を使用したラジコンクローラーの紹介です。
コントローラーは、プレステ3のコントローラーとBluetoothで接続しています。
これだけでは、巷のネット記事であふれている試作内容と変わらないのでスタッフブログで紹介するまでもないのですが、単一電源で全てを賄っている点はアピールポイントとなります。
当医院でも販売しているArduino Pro mini用のUSBホストシールドでBluetoothのUSBドングルでPS3のコントローラーと接続した同じような試作と行っておりました。
それぞれのざっくりとした構成です。
ESP32クローラーラジコン構成
- ESP-WROOM-32基板
- MX1616Hモータードライバ基板
- 3.3V昇圧基板
- 10000uF電解コンデンサー
- Panasonic eneloop 4本
- タミヤ 楽しい工作キット
Arduino pro miniクローラーラジコン構成
- Arduino primini
- USBホストシールド
- MP4212 自作モータードライバ
- 5.0V昇圧基板
- 47uF電解コンデンサー
- Bluetoothドングル
- Panasonic eneloop 4本
- タミヤ 楽しい工作キット
MP4212のモータードライバーと5.0V昇圧基板は、1Fに設置しています。
Promini版のラジコンクローラーは、priminiとUSBホストシールドなどが二階建てで、モータードライバ基板も1Fにあったりとやや複雑でした。
今回のESP32のラジコンクローラーは、USBドングルとUSBホストシールドおよびArduino promini部分がESP32基板に集約でき一体化しておりますので、かなり省スペース化ができます。
ということで今回の記事となりました。
ただ、USBホストシールド版と同様にモーターの起動電圧降下による瞬停(ペアリング解除)を防ぐ電源設計が一番の難点でした。というのは、ラジコンを設計された経験があれば以下のような事態に遭遇します。
トイラジコンのような、いわゆる受診のみに特化したラジコンであれば、Bluetoothのようなペアリングは不要であるので、瞬低によるペアリング解除の心配はありません。
ですが、コントローラーとしてPS3のコントローラーを使用する場合は、このペアリング問題を解決しないといけません。
とうことで、コンセプトは、モーター起動時の電圧低下を補間できるように昇圧回路と特大電解コンデンサーで解決します。
ESP32用電源
1.2V * 4本 = 4.8V eneloop → ショットキーバリアダイオード Vf=1.2Vで3.6Vまで降圧します。
この3.6Vは、ESP32の最大定格ギリギリで印加します。
MX1616Hモータードライバ電源
MOSFETのVDDに1.2V * 4本 = 4.8V eneloopの電源をそのまま印加します。
ロジックの制御側のVCCには基板上の高圧抵抗で減圧された電源が印加されます。
恐らくここまでの電源設計は、誰でもできるかとは思いますが、この状態ではモーター起動時に大きい電圧降下を招きESP32が再起動しペアリングが解除されます。
参考までにESP32の3.3Vをモニターした波形が以下です。
低下後、復帰しますが、速度追い付かずペアリングが解除されます。
そこで、USBホストシールド版のラジコンクローラーでも適用した昇圧回路を挿入します。
Vf=1.2Vショットキーバリアダイオード → 3.3V昇圧回路 → ESP32
ですが、これでも昇圧回路の復帰速度が間に合わず瞬低でペアリングが解除されます。
最後に、3.3V昇圧回路の出力側に大きな電解コンデンサーを挿入します。
いろいろ試してみたのですが、10000uFの電解コンデンサーでやっと電圧補償が間に合い瞬低時でもペアリングが解除されなくなりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
// ESP32 PS3 RC Crawler v0.1 // Target device : ESP-WROOM-32 // Date : 2023/12/22 // Author : Takishita of Delivery Toy Hospital // http://wwww.takishita.jp/toy_hospital // #include <Ps3Controller.h> // R-ch #define PWM_PIN1_1 25 // 25pin #define PWM_PIN1_2 26 // 26pin // L-ch #define PWM_PIN2_1 32 // 32pin #define PWM_PIN2_2 33 // 33pin #define CH0 0 // CH number 0 #define CH1 1 // CH number 1 #define CH2 2 // CH number 2 #define CH3 3 // CH number 3 #define DUTY_F 127 // duty full #define DUTY_Z 0 // duty zero #define FREQ 1000 // 1kHz #define BIT_RES 7 // 7 bit resolution(0-127) // Globals int8_t duty_x = 0; // X axis 0% = PWM OFF int8_t duty_y = 0; // Y axis 0% = PWM OFF // int8_t player = 0; // int8_t battery = 0; void setup() { Serial.begin(9600); // Ps3.attach(notify); // Ps3.attachOnConnect(onConnect); Ps3.begin("xx:xx:xx:xx:xx:xx"); // Serial.println("Ready."); // Pin initilal setting // R-ch pinMode(PWM_PIN1_1, OUTPUT); pinMode(PWM_PIN1_2, OUTPUT); // L-ch pinMode(PWM_PIN2_1, OUTPUT); pinMode(PWM_PIN2_2, OUTPUT); // PWM initial setting ledcSetup(CH0, FREQ, BIT_RES); ledcSetup(CH1, FREQ, BIT_RES); ledcAttachPin(PWM_PIN1_1, CH0); ledcAttachPin(PWM_PIN1_2, CH1); ledcSetup(CH2, FREQ, BIT_RES); ledcSetup(CH3, FREQ, BIT_RES); ledcAttachPin(PWM_PIN2_1, CH2); ledcAttachPin(PWM_PIN2_2, CH3); } void loop() { // Foward or Backward if( abs(Ps3.data.analog.stick.rx) < 10) { // Exclusive processing with left or right rotation stick posion // Serial.print("y="); Serial.println(Ps3.data.analog.stick.ly, DEC); // debug // Serial.print("duty_y="); Serial.println(duty_y, BIN); // debug // Stop if( Ps3.data.analog.stick.ly >= -15 && Ps3.data.analog.stick.ly <= 15 ){ // Stop zone // R-ch ledcWrite(CH0, DUTY_Z); // duty zero ledcWrite(CH1, DUTY_Z); // duty zero // L-ch ledcWrite(CH2, DUTY_Z); // duty zero ledcWrite(CH3, DUTY_Z); // duty zero // Foward } else if( Ps3.data.analog.stick.ly < -15 ){ // Foward detection duty_y = map(Ps3.data.analog.stick.ly, 0, -128, 128, 0); // Negative to positive and top to bottom mapping if( duty_y >= 115 ) { // Top saturation duty_y = 127; } // Serial.print("duty_y="); Serial.println(duty_y, DEC); // debug // R-ch ledcWrite(CH0, duty_y); // PWM output ledcWrite(CH1, DUTY_F); // Hi // L-ch ledcWrite(CH2, duty_y); // PWM output ledcWrite(CH3, DUTY_F); // Hi // Backward } else if( Ps3.data.analog.stick.ly > 15 ){ // Backward detection duty_y = map(Ps3.data.analog.stick.ly, 0, 128, 128, 0); // Top to bottom mapping if( duty_y >= 115 ) { // Top saturation duty_y = 127; } // Serial.print("duty_y="); Serial.println(duty_y, DEC); // debug // R-ch ledcWrite(CH0, DUTY_F); // Hi ledcWrite(CH1, duty_y); // PWM output // L-ch ledcWrite(CH2, DUTY_F); // Hi ledcWrite(CH3, duty_y); // PWM output } } // Right or Left if( abs(Ps3.data.analog.stick.ly) < 10) { // Exclusive processing with Foward or Backward stick posion // Serial.print("x="); Serial.println(Ps3.data.analog.stick.rx, DEC); // debug // Serial.print("duty_x="); Serial.println(duty_x, BIN); // debug // Stop if( Ps3.data.analog.stick.rx >= -15 && Ps3.data.analog.stick.rx <= 15 ){ // Stop zone // R-ch ledcWrite(CH0, DUTY_Z); // duty zero ledcWrite(CH1, DUTY_Z); // duty zero // L-ch ledcWrite(CH2, DUTY_Z); // duty zero ledcWrite(CH3, DUTY_Z); // duty zero // Right } else if( Ps3.data.analog.stick.rx < -15 ){ // Right detection duty_x = map(Ps3.data.analog.stick.rx, 0, -128, 128, 0); // Negative to positive and top to bottom mapping if( duty_x >= 115 ) { // Top saturation duty_x = 127; } // Serial.print("duty_x="); Serial.println(duty_x, DEC); // debug // R-ch ledcWrite(CH0, duty_x); // PWM output ledcWrite(CH1, DUTY_F); // Hi // L-ch ledcWrite(CH2, DUTY_F); // Hi ledcWrite(CH3, duty_x); // PWM output // Backward } else if( Ps3.data.analog.stick.rx > 15 ){ // Backward detection duty_x = map(Ps3.data.analog.stick.rx, 0, 128, 128, 0); // Top to bottom mapping if( duty_x >= 115 ) { // Top saturation duty_x = 127; } // Serial.print("duty_x="); Serial.println(duty_x, DEC); // debug // R-ch ledcWrite(CH0, DUTY_F); // Hi ledcWrite(CH1, duty_x); // PWM output // L-ch ledcWrite(CH2, duty_x); // PWM output ledcWrite(CH3, DUTY_F); // Hi } } } |
PS3コントローラーとのぺリング方法の事前設定などやノイズ取り用のコンデンサーの使い方などは、もちろんご経験があるという前提という記事となります。
PWMとは?とか、モーターのブラシノイズとは?とか、突入電流とは?という方は、それらを習得してから再度お読みください。