eカートのモーター制御について

Maker Fair Kyotoに出展が決まりました。

eカートのモーター制御について

eカートの最も重要なパーツであり、心臓部であるモーターコントローラーについて解説する。

eカートのモーターを制御しているモーターコントローラーはAmazonhttps://amzn.asia/d/2spl9cvで手に入る中国製の製品で、似たようなコントローラーは数多くある。この製品はLCD付きで24V/36Vに対応する350wのタイプである。左右のモーター用に2つのコントローラーを購入した。LCDは1つあればよいが、配線が同じものであることと、予備である(実はLCDを1つ短絡して壊してしまった)。
おそらくどの製品も簡素な説明資料があるだけで、使い方はネット(動画含む)で情報を集めて試行錯誤を重ねる必要がある。
幸いにもこのコントローラーのLCDディスプレイの機能説明資料がネットhttps://m.ja.aliexpress.com/item/4000319520169.html?gatewayAdapt=gloPc2jpnMsite(中ほどのView Allの中にLCDの詳細情報がある)で入手できたので、ほとんどの機能が理解できた。
一般的な用途は普通の自転車を電動化するものであるが、値段の割にかなり多機能なものとなっており、十分リーズナブルな製品である。
モーターコントローラー自体の配線によって機能を有効化・無効化したり、LCDにより詳細な設定を保存できたりする。
ここでは、使っている機能について解説し、Raspberry Pi Picoを使用して制御をカスタマイズする方法について述べる。

モータードライバーの機能

配線方法

配線により有効化できる機能は以下の通り

LCDディスプレイ

モータードライバー単体では制御できる機能は限られているが、LCDディスプレイを使うことで、様々な機能が使える。
全ての機能を問題なく使えるわけではないが、LCDディスプレイで制御できる機能は以下の通り。

バックライト明るさ
3 最も明るい設定とする。
速度単位
0 km/hとする。
バッテリー電圧
24 24vに設定する。※現状のバッテリーの公称電圧は25.2vとなっているが、満充電時にはLCD上で28v以上になるので、充電ゲージがなかなか減らない状態となっている(逆に36vにすると常にエンプティとなる)。このため、バッテリーの減りは電圧で確認している。
スリープ時間
30 30分に設定する。
ギア
1 0-5とする。5段階の場合、通常は3で、少しパワーが必要なときに4とする。4と5にほとんど差はないため、5はほとんど使わない。
リムサイズ
6.5 自転車であればリムの規格で決まっているが、使用しているタイヤはリムがないため、メーカー外寸表記の6.5インチとする。
モーター磁極数
5 実際の速度(iPhoneメーターアプリ)に合わせて比率を決めている。


要はリムサイズと合わせて速度の基準となる。P18の速度表示比で更に調整する。

制限速度
100 説明書きでは最高速度の設定と読み取れるが、出力のパーセンテージのような動作となる。低いギアで最高速度に達しないときでも速度が低くなる。制限はしない。
スタートモード
0 ゼロスタートとする。
ランニングモード
1 スロットルのみとする。
ペダルスタート感度
1 ペダルモードは使用しないため、既定値のまま。

1は最も弱い。5は最も強い。

ペダルスタート強度
5 ペダルモードは使用しないため、既定値のまま。
パスセンサータイプ
6 PASセンサーは使用しないため、既定値のまま。
バッテリー電流制限
12 29V(多めに見積)×12A=348Wで計算。
バッテリー最低電圧調整
19 最低電圧
※20Vまで電圧が落ちると充電することにしている。
オートクルーズ設定
0 オートクルーズは設定解除が直感的にできないし、手を離したときに制御が効かないため使用しない。
速度表示比
100 速度表示比
速度表示比
0 ギアモード
通信プロトコル
0 デフォルト
ブレーキ
0 デフォルト
E-ABS
1 回生ブレーキを使用する。

※この機能の詳細情報はないため実機確認した範囲だが、坂道を下る際にバッテリーの値がわずかながら増えるところを見ると、確かに回生していると思われる。

Raspberry Pi Pico によるカスタマイズ

やっと、ソフトウェアの登場である。

カスタマイズによる動作イメージ

接続方法

ソース

from machine import Pin, PWM
import machine
import utime

# PWMの設定
pwm_l = PWM(Pin(0))
pwm_r = PWM(Pin(1))
pwm_l.freq(10000)
pwm_r.freq(10000)

# スロットルセンサーの設定
sensor_throttle = machine.ADC(0)

# 前回の読み取り値を初期化
before_read = sensor_throttle.read_u16()

# 急な操作をキャンセルするための差分閾値、緩やかに加速するための時間差、制限値を設定
diff_term = 0.1
diff_limit = 10000
low_limit = 18000
high_limit = 65535

# 制限フラグの初期化
limit_over = False

# 無限ループでスロットルセンサーの値を読み取り、PWMのデューティー比に反映する
while True:
    reading = sensor_throttle.read_u16()

    # スロットルセンサーの値が上限値を超えた場合は上限値に制限する
    if reading > high_limit:
        reading = high_limit

    # 制限フラグがONの場合は前回の値に戻す
    if limit_over:
        if reading < low_limit:
            limit_over = False
            print("limit off")
        reading = before_read
    else:
        # 前回の値との差分が閾値を超えた場合は制限フラグをONにする
        if reading > before_read:
            if reading - before_read > diff_limit:
                limit_over = True
                print("limit over")
            else:
                # スロットルセンサーの値をPWMのデューティー比に反映する
                pwm_l.duty_u16(int(reading))
                pwm_r.duty_u16(int(reading))
        else:
            # スロットルセンサーの値をPWMのデューティー比に反映する
            pwm_l.duty_u16(int(reading))
            pwm_r.duty_u16(int(reading))

    # 値の確認のために、前回の値、現在の値、制限フラグを出力する
    print(str(before_read) + " " + str(reading) + " " + str(limit_over))

    # 前回の値を更新して、一定時間待つ
    before_read = reading
    utime.sleep(diff_term)