
概要

回路・制御基板

考え方です。3つのスイッチのON/OFFでコイルの電流方向を変えてモーターを回転させます。この3つスイッチとON/OFF制御を行ってくれるのがESC(Electric Speed Controller)。ここの部分を作ります。

スイッチ回路一つはハーフブリッジ回路となります。いい物が見つからなたっかのでフルブリッジのDRV8870ドライバをハーフブリッジ回路変わりに使用します。電流センサ付いてますが今回は使用してません。
| IN1 | IN2 | OUT1 | OUT2 |
| 0 | 0 | High-Z | High-Z |
| 1 | 0 | H | L |
| 0 | 1 | L | H |
| 1 | 1 | L | L |
IN2ピンをHiレベルに固定。IN1ピンでOUT2出力を制御してハーフブリッジとして使用します。少し無理やりですが動いているのでOKです。 MOSFETやゲートドライバなどでハーフブリッジを作るべきかと思いますが面倒だったのでこの方法で行きます。
モーター1個でスイッチ回路が3つ必要。なのでモーター3個で9つ分の回路が必要ですがブレッドボードやユニバーサル基板では厳しそうなので制御基板を作成しました。

JLCPCBに発注。表面部品実装までお願いして5枚で$14程度。

スルーホール部品を付けて完成。制御はRaspberyPiPicoを使用します。
ソースコード

//2025/06/21 imo Lab.
//http://garchiving.com
void loop1() {
currentTime[1] = micros();
for (int i = 0; i < 3; i++) {
if (freq[i] > targetFreq[i]) freq[i] -= 0.05;
if (freq[i] < targetFreq[i]) freq[i] += 0.05;
freq[i] > 0 ? dir[i] = 1 : dir[i] = -1;
abs(targetFreq[i]) == 0 ? interval[i] = 1000000 : interval[i] = 1000000.0 / (abs(freq[i]) * (360 / degStep));
}
if (currentTime[1] - PWMTimer[0] > interval[0]) {
PWMTimer[0] = currentTime[1];
motorControl(0, 1, 0, 1);
}
if (currentTime[1] - PWMTimer[1] > interval[1]) {
PWMTimer[1] = currentTime[1];
motorControl(1, 0, 1, 0);
}
if (currentTime[1] - PWMTimer[2] > interval[2]) {
PWMTimer[2] = currentTime[1];
motorControl(2, 1, 0, 1);
}
}
void motorControl(uint8_t i, uint8_t ch1, uint8_t ch2, uint8_t ch3) {
float val1 = 0.5 + 0.5 * sin(deg[i] * PI / 180.0);
float val2 = 0.5 + 0.5 * sin((deg[i] + 120) * PI / 180.0);
float val3 = 0.5 + 0.5 * sin((deg[i] + 240) * PI / 180.0);
deg[i] == 360 - degStep ? deg[i] = 0 : deg[i] += dir[i] * degStep;
pwm_set_chan_level(u[i], ch1, val1 * 50);
pwm_set_chan_level(v[i], ch2, val2 * 50);
pwm_set_chan_level(w[i], ch3, val3 * 50);
}
モーター制御部分の抜粋です。PCから3つ分のモーター速度、方向指示を受け取って回転制御してます。
for()分で、受信した速度指示(-100~+100)から、回転方向と速度(疑似タイマーの間隔)を決めてます。でその後のif()分で速度指示に応じて各々モーター毎のPWMピンから正弦波出力を行ってます。
動作確認
モーター4個ありますが制御しているのは3個です(左2つは同じ動きします)。それほど正確な制御では無いですが、今回の目的ように単純な制御であればこれくらいの動きで十分な感じ。
バグが無いか少し心配ですがモーター制御テストはこれくらいにして、次回は筐体作成に着手していきます。
コメント