PythonでTENORI-ONを動かすblog(仮)

PythonでMIDIを作ってYAMAHAのTENORI-ONをごにょごにょするよ。

M5AtomでBLEマウスっぽいものを作った

唐突なんですが、右手の親指を動かすとめちゃめちゃ痛むようになり、リモートワークで使っているLenovoキーボードの左ボタンが押せなくなりました。

 

休日と業務時間外は私物のmacなので全く困らないのですが、これでは仕事ができないので、急遽マウスの左ボタンだけを別で使う機能が必要になりました。

 

手元にあった使えそうなもの

残念ながらUSBデバイスとして使えるものArduino Pro MicroやArduino Leonardoを持っていない。

  • M5Stackシリーズ
  • M5StickC
  • M5Atom シリーズ
  • Arduino UNO互換機
  • Arduino Nano互換機
  • ラズパイ3B+ 、ZERO WH

ESP32でBLEマウスを作れると言う情報はいくつかあったので、手近なところでM5Atomを選部ことに。

 

最終的にできたもの

  • BLEでPCと接続して、以下の動作をするもの
    • M5Atom Liteのボタンを押すと左クリック
    • M5Atom Liteのボタンを押すと左ボタン長押し

※ダブルクリックのことは頭になかったけど、使ってみたら無くても困らなかったので除外した。

 

f:id:bastardeyes:20200827000820j:plain

長押しで"press"、クリックで"click"と出力

 

コード

限定用途なのでたいしたものではないですが、ライブラリ「ESP32-BLE-Mouse」を使うとこんなあっさりしたコードでPCと接続できると言うのは結構衝撃でした。

姉妹品?にESP32-BLE-Keyboardというのもあるので、それぞれサンプルをチェックしていただければ使いどころはイメージできるのではと思います。

github.com

#include "M5Atom.h"
#include 
BleMouse bleMouse;

void setup() {
  M5.begin(true, false, true);
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  bleMouse.begin();
  
  M5.dis.drawpix(0, 0xffffff);
  delay(500);
}

void loop() {  
  
  if(bleMouse.isConnected()) {
     if (M5.Btn.wasPressed() ) {
      M5.dis.drawpix(0, 0x00f000);
      
      Serial.println("Left click");
      bleMouse.click(MOUSE_LEFT);
      
      M5.dis.drawpix(0, 0x000000);
        
      }else if(M5.Btn.isPressed()){
        M5.dis.drawpix(0, 0x000f00);
  
        Serial.println("press");
        bleMouse.press(MOUSE_LEFT);
        
      }else if(M5.Btn.isReleased()){
         M5.dis.drawpix(0, 0x000000);
        bleMouse.release(MOUSE_LEFT);
      }
      delay(300);
      M5.update();
    }
}

参考

M5StickCの加速度センサを利用したものではこんな作品も。

qiita.com

失念したこと

ボタンの代わりに、タッチセンサか圧力センサを使いたかったのですが、無線接続を有効にした途端にセンサの値が意図しないものになってしまい、平日深夜だったので切り捨てました。(無念)

原因

ESP32にお詳しい たなかまさゆき さん曰く、無線有効時のアナログピンはピン32以上の数字のものしか正常動作しないのだとか。。

 

→ピン33などでも試していたのですが、ESP32 Pico Kitなので挙動が違う可能性も??
と言うことで一旦アナログは無視することにしました。

 

当初は赤丸のところにタッチセンサを設置するつもりでした。

f:id:bastardeyes:20200827005053j:plain

ぷにぷにマウスレスト、意外と良いです。でかいけど。

実際試してみた感想

100点ではないけれど、手の痛みを緩和する目的は果たせたのでまずまず。

 

しかし、今の仕事で手に負荷がかかっているのがドキュメント作成やドキュメントレビューの画面スクロールやセル移動の動きなので、本当に必要なUI/UXはキーボードやマウスではないということに気がつきました。

 

顧客が本当に欲しかったのは、左手用のボタン付きジョイスティックでは?

 

今回はLenovoキーボードの左ボタン押しすぎでドケルバン症候群になったようなのですが、普通のマウスを使うと腱鞘炎&昔患った三角繊維軟骨複合体(TFCC)損傷の再発もあり。

右手は使わず、左手でスムーズに使えるインターフェース、、Nintendo Switchのようなものが理想なのかも。

 

f:id:bastardeyes:20200827003151j:plain

この赤×青の色合いについてはイマイチ納得していない

 

たぶん↓に筐体をつけてやるのが理想形な気がしています。

novicengineering.com

 ちなみに

公私とも色んな方からオススメいただいたのがケンジントントラックボールでした。

安価なところではロジクールも良いらしい。

 

トラックボールは以前に新宿ヨドバシで色々試したものの、手が小さすぎてちょっと合わなかったのですが、普通に指を動かせるようになったら再検討しようかと思います。。(その頃にはコーディングに入って、使わなくなってる可能性もあり)

 

necobit.com

 

 

 

Maixduinoで使える部品類(※8/24追記)

※追記) 2020/8/24 カメラとスピーカー

 

付属カメラのケーブルが断線した時、結構苦労したのでこれもメモ。

 デュアルカメラやマイク等はスイッチサイエンスで買えるものの、以外とちょっとしたものを探すのに悩んだ。

 

カメラ

魚眼レンズ(純正)

一番安いのはスイッチサイエンスですが、現在は品切れ。

Shigezoneに在庫がある場合も。

www.sengoku.co.jp

通常レンズ(互換品?)

アリエクで発見してしまったので、国内では探していないです。

2つ購入して、正常動作を確認しています。

a.aliexpress.com

その他

M5StickVですが、OV2640と同様に使用可能なカメラについて情報をお寄せいただきました。感謝!!

 

ケーブル延長基板

カメラ断線を繰り返さないためにネットで調べてAitendoにて購入。

Aitendoは今、お品切れの様子。

検索キーワード「FFB FFC 0.5 24P」で出てきます。

qiita.com

www.aitendo.com

 アリエクなら、これの24Pが同じだと思います。

ja.aliexpress.com

延長ケーブル

前述の基板に接続するもの。向き注意。

最初Aitendoで表-表しか買ってなくて、慌ててAmazonで表-裏を追加発注した記憶。。

検索キーワード「FFC 0.5 24P」で出てきます。

カメラ用

表-裏向きのものが必要。0.5mmピッチ24ピン。

Aitendoで言うところの「Wタイプ」、アリエク・Amazonで言う「Bタイプ」が該当。

 

LCD

表-表向きが必要。

Aitendoで言うところの「Sタイプ」、アリエク・Amazonで言う「Aタイプ」が該当。

 

www.aitendo.com

ja.aliexpress.com

www.amazon.co.jp

色々接続するとこう。LCDのケーブルも断線怖いので、マスキングテープで固定しています。

f:id:bastardeyes:20200824010415j:plain

ピントがボケてることは気にしない

LCD

付属のものと全く同じSeeed製品。

アリエクでもっと安価なものがあるかもしれませんが、探してないです。

www.amazon.co.jp

スピーカー

 1.25mmピッチコネクタ(molex 51021)がついたもの。

検索"1.25mm スピーカー"である程度引っかかってくるはず。

うちのはAitendoで買った適当なものに、ケーブルをハンダ付けしたので正確な型番は不明ですが、おそらくTwitterなど見る限りではスイッチサイエンスのこれが使える。

www.switch-science.com


失敗編

互換性あるかなーと思って失敗したもの。

 

大きめ3.2インチLCD(ST7789 8bit版) ←NG

付属の2.4インチより大きいものが欲しかったので。

発注当時、回路図探せなかったけれどピン数、ピッチ、ドライバーは同じなのでとりあえず試してみた。

結果、配線が違ったのでNG。連結基板を自作すれば使えるのかもしれないけれど、時間をかける余裕がないので保留。

 

ja.aliexpress.com

失敗した方3.2インチのデータシート

購入当時は到着品のコネクタに書かれた型番"jlt32018b-v"を、百度で探さないと見つからなかったけれど、今はアリババのリンクが出てくる。

 

付属品2.4インチのデータシート

 →これは普通にseeedが売ってるので探せる。モノもAmazonで買える。

 

 

 

・・・まとめてみたら結構な人柱感ありますね。

MaixduinoでMakerDrive(モータードライバ )制御

注意) BLINKアプリでの操作は、MaixPyにuselectが実装されていないので、2020/8/23現在はできません!!

 

ようやくスタートラインに立った感。

Maixduinoでモータードライバ を動かすまで、結構長い道のりだった。

 

用意したもの

  • Maixduino
  • USB type-Cケーブル(Maixduino用)
  • MakerDrive (モータードライバ )
  • タミヤ ダブルギヤボックス
  • 外部電源(3.3V or 5V) ※↑の動画では3.3V使用
  • ジャンパーピン
    • オスーメス 5本(MakerDrive - Maixduino用)
    • 外部電源用2本 ※何を使うかによる

加えて、モーターにコンデンサー 100nF、外部電源のところにパスコンとしてコンデンサー 1μFつけるのがベターなのですが、そもそもArduino・ラズパイを通らずMaixduinoにチャレンジする人はそうそういないので割愛。

f:id:bastardeyes:20200823184209j:plain

接続イメージ

f:id:bastardeyes:20200823185026j:plain

モーターにコンデンサの図

USBから3.3Vor5V取るのは、みんなのラボさんの「ブレッドボード電源モジュール」が重宝してます。マルツ本店2Fに在庫が買えるとラッキーです。

minnanolab.net

実体配線図

データを作る余力がありませんでした。。

あと前述のコンデンサー書いてないですが、まぁ動きます。

f:id:bastardeyes:20200823184150j:plain

手書きですみません



コード

 前進、後進、右回転、左回転をするだけです。MakerDrive用のライブラリは不要。

トラ技2019年11月号に掲載されているPCA9685はライブラリがあるので、これとは違った内容になります。

import time
from machine import Timer,PWM
from Maix import GPIO

freq=100000
max_duty=50 #最大100。大きいほど速い。

tim_1 = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PWM)
tim_2 = Timer(Timer.TIMER0, Timer.CHANNEL1, mode=Timer.MODE_PWM)
tim_3 = Timer(Timer.TIMER0, Timer.CHANNEL2, mode=Timer.MODE_PWM)
tim_4 = Timer(Timer.TIMER0, Timer.CHANNEL3, mode=Timer.MODE_PWM)


#右タイヤ前進(ボード 8番ピン)
ch_r1 = PWM(tim_1, freq=freq, duty=0,pin=14)
#右タイヤ後進(ボード 9番ピン)
ch_r2 = PWM(tim_2, freq=freq, duty=0,pin=13)
#左タイヤ前進(ボード 10番ピン)
ch_l2 = PWM(tim_3, freq=freq, duty=0,pin=12)
#左タイヤ後進(ボード 11番ピン)
ch_l1 = PWM(tim_4, freq=freq, duty=0,pin=11)


#前進
ch_r1.duty(max_duty)
ch_l1.duty(max_duty)
ch_r2.duty(0)
ch_l2.duty(0)
time.sleep(3)

#後進
ch_r1.duty(0)
ch_l1.duty(0)
ch_r2.duty(max_duty)
ch_l2.duty(max_duty)
time.sleep(3)

#右回転
ch_r1.duty(0)
ch_l1.duty(max_duty)
ch_r2.duty(0)
ch_l2.duty(0)
time.sleep(3)

#左回転
ch_r1.duty(max_duty)
ch_l1.duty(0)
ch_r2.duty(0)
ch_l2.duty(0)
time.sleep(3)


ch_r1.disable()
ch_r2.disable()
ch_l2.disable()
ch_l1.disable()

参考資料

PWMは最大12こまで扱える。

Timerは0-3まで。それぞれにChannel 0-4が割り当てられている。

maixpy.sipeed.com

ピンアサインはSipeedのGitHubからmaixduino_pins.pngを参照。

 

この先やりたいこと

一旦はBLINKアプリで動作させたかったけれど、uselectが使えないのでそれは先のお話。

カメラを使って自動運転できると良いなぁ。

そういえばM5Atom(Arduino) + MakerDrive + BLINKアプリの記事を書いてないので、後で書く予定。

MaixduinoをMaixPyでPWM制御する方法

さて、前回 でようやくGPIOの出力を理解したので、PWMが使えるようになりました。

 

 

コード

例によって、ボードの9番ピンからLEDをちょっとずつ明るく光らせるだけの簡素なものです。

ピンアサインはSipeedのGitHubからmaixduino_pins.pngを入手して確認してください。

import time
from machine import Timer,PWM
from Maix import GPIO

tim = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PWM)
# ボードの9番 =pin13
ch = PWM(tim, freq=500000, duty=0,pin=13) 

duty =0
for duty in range(100):
    ch.duty(duty)
    time.sleep(0.5)

ドキュメント

ちょっと紛らわしいのですが、MaixduinoのAnalog I/Oの項ではなく、MaixPyのPWMの項に掲載されています。

maixpy.sipeed.com

 

参考資料

高度な応用例についてはトラ技201911月号の、砂川寛行さんの記事「第4章 K210の研究4 ニューラル・ネットワークとI/O」に二足歩行AIロボットの例があるのでそちらがオススメです。

cc.cqpub.co.jp

 

 

以上。作業の日が空くと忘れてしまうので備忘録でした。

MaixduinoのMaixPyでGPIO制御

※理解が正しくない部分など、ちょいちょい加筆・修正しています

 

前回、MaixduinoでMaixPyからESP32よぶにはシリアル通信が必要と書きましたが、間違いでした。。

 

どうもこれが正解のようです。。

  • ANALOG IN(A0〜5)はArduino IDE使わないとダメ
  • DIGITAL/PWMはMaixPyを使う

 

読むべき資料

SipeedのGitHubから以下の資料を入手する

  • maixduino_pins.png
    • 青枠の数字を"IO"はつけずに定義してやればOK
    • 定数もあるけれど資料と合ってない部分があったので、かえってつまづくかも
  • MaixDunio(Pin assignment table).xlsx
    • 前述の青枠の数字の代わりに、Functionの定数を使うこともできる
    • しかし、print(board_info.LED_R) で戻ってきたのが13ではなく14だった(あれ?)

その他、MaixPyで下記を実行すると、ピンに割り当てる機能の定数が確認できる。(fm.fpioa.GPIO0など)

from fpioa_manager import fm
print(fm.fpioa.help())

 コード

ボードの9番ピンからLEDを光らせるだけですが。

import time
from Maix import GPIO
from fpioa_manager import fm

# ボードの9番にLEDを繋いで光らせる場合
fm.register(13, fm.fpioa.GPIO0)
led_1 = GPIO(GPIO.GPIO0, GPIO.OUT)

flg=0
while(1):
    led_1.value(flg)
    if flg==0:
        flg=1
    else :
        flg=0
    time.sleep(1)

ハマった点

ESP32のFWは通常と異なるので、Arduino IDEでも通常のESP32のコードの流用はできないこともある。

  • ArduinoIDEでledcSetupなど対応していないメソッドを呼ぶと、ESP32が延々再起動する
  • ArduinoIDEはanalogWriteもコンパイルエラーになった。
  • analogReadは動く。(逆にMaixPy上で動かせない)

homemadegarbage.com

MaixPyのPWM制御はトラ技にあったので、こちらを参考にしようと思います。

cc.cqpub.co.jp

GPIOのピンアサインさえわかれば、あとはM5StickVでググるのが吉。

 

・・・そういえばBLEって使えないんですかね。

まぁ、通常のESP32のようなことがしたいなら、M5Atom LiteかM5StickCと接続した方が良い気もします。

www.switch-science.com

MaixduinoでBLINK使おうとして失念した話

※理解が正しくない部分など、ちょいちょい加筆・修正しています

 

本当は「M5Atom LiteとBLINKでモータードライバ を動かす」話を先にかくべきだったのに、順序が逆になってしまうのですが。。

失敗まとめは時間が経つと書く気が無くなるので、勢いがあるうちに書いておきます。

 

BLINKとは

blog.livedoor.jp

試そうとしたライブラリ

Readmeの手順参照

github.com

失念した理由

  • Maixpyがライブラリ"uselect"を扱わなくなったため、blinklib_mp.pyの読み込みでエラーになる。
    • uselectは公式から綺麗さっぱり消えてる。。
    • replでhelp('modules')を叩いても出てこない。
    • 結論)現段階では無理そう。
    • 追記)2020/8/22現在は、Ano研さんがSipeedにIssueをあげてくださってるので、今後に期待。

古いバージョンなら使えるとか、Micropythonのソースから持ってくる手もあるのかもしれないけれど、今時間をかけてやる意義はないと判断した。

maixpy.sipeed.com

失念したけれど勉強になったこと

  • MaixduinoでK210からESP32を呼び出すには、K210とESP32でシリアル通信をする必要がある。 MaixPyから直接DIGITAL/PWM呼ぶ方法がわかったので、別記事書きました。(ANALOG INはK210とESP32をシリアル通信で良いらしい)
  • K210はMaixPy IDEから書き込み。ESP32は Arduino IDEから書き込みを行う。
    • シリアルポートに2種類出てくる。AがK210、BがESP32。
  • シリアル通信やWi-FI接続でエラーが出る場合は、ESP32のファーム書き換えが解決する場合がある。
    • windowsGUIのツールがあるが、macの場合はestpool.pyで書き込む(後述)
  • この辺のまとまった情報については、Ano研さんの「MAiX MAniaX」が良い。
  • Maix Bitを使ったGPIO制御ならトラ技の2019年11月号も情報量がある。(ESP32ではない)
  • Wi-Fiの処理はK210側でやるのが基本らしい。
    • 試しにESP32側でWi-Fi処理書いたら、ひたすら再起動かかってダメだった。

ちなみにArduino IDEで、全手の処理をArduinoで書くという手もあるけれど、IDEのバージョンなどでSDカード読み込めなくてはまるなどあって、今は触っていない。(もしかしたらファームの更新で改善されたかも?)

 

cc.cqpub.co.jp

 mac OSによるESP32のファーム更新

 参考になった記事。

dev.classmethod.jp

自分の環境ではこうなりました。

/Users/ユーザー名/.pyenv/versions/anaconda3-5.0.1/envs/py/bin/esptool.py --chip esp32 --port /dev/tty.usbserial-00002114B --baud 115200 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size detect 0x000 ./maixduino_esp32_firmware_v1.4.1_0x0.bin

M5StackでLED万華鏡を作ってみた

なんとなく思いついて、部品を取り寄せた勢いだけで作ってみました。

 

材料

  •  どこのご家庭にもあるM5Stack(AtomやStickCでもOK)
  • ミラーシート
  • マスキングテープ
  • M5Stack用NeoPixel互換LED搭載 六角形ユニット
  • M5Stack用Groveケーブル
  • (あると尚良し)拡散版

 

www.switch-science.com

www.amazon.co.jp

作り方

ミラーシートを1.8mm×10.5mmカットする。6本用意する。

f:id:bastardeyes:20200802174537j:plain

 

ミラーシートの間隔を約1mm開けて、マスキングテープで止める。

1箇所だけ写真のように深さ3mm程度の切れ目を入れる。

f:id:bastardeyes:20200802174554j:plain

 

上から見るとこんな状態になります。

f:id:bastardeyes:20200802174607j:plain

 

M5StackにLED37こをランダム点灯するコードを書き込みます(後述)

f:id:bastardeyes:20200802174623j:plain

 

拡散板がないので、折りたたんだティッシュペーパーをかぶせてみました。

だいぶ柔らかくなります。

f:id:bastardeyes:20200802183835j:plain



 

Arduinoコード

37個すべてランダム色にしていますが、色を白ベースにして赤系・青系などに絞ったほうが綺麗だと思います。

せっかくM5Stackを使っているのだから画面にも何か出したかったのですが、空いてるのが画面破損しているものしかなかった。。

 

#include <M5Stack.h>
#include "FastLED.h"

#define DATA_PIN 21
#define LED_TYPE WS2812B 
#define COLOR_ORDER GRB
#define NUM_LEDS 37
#define BRIGHTNESS 5

CRGB leds[NUM_LEDS];

uint8_t direction;//0: clockwise 1: anti-clockwise

void setup() {
  M5.begin(true, false, true);
  Wire.begin();
  Serial.begin(115200);
  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); // initializes LED strip
  FastLED.setBrightness(BRIGHTNESS);
  showLedCleanUp(1);

  M5.Lcd.clear();
  M5.Lcd.setCursor(0, 0);
  showLedRandom(500);
}


void showLedCleanUp(long delayTime) {
  for (int i = 0; i < NUM_LEDS; ++i) {
    leds[i] = CRGB::Black;
  }
  FastLED.show();
  delay(delayTime);
}

void showLedRandom(long delayTime) {
  while(1) {
    for (int i = 0; i < NUM_LEDS; ++i) {
      leds[i] = CHSV(random8(), 255, 255); 
    }
    FastLED.show();
    delay(delayTime);
  }
}

void loop() {
 
}

 

未解決事件簿

LEDのうち1つだけ(10番)信号の制御がうまくいかず、点灯しないor意図した色にならないという問題がありました。

詳しい方々から教えていただいたのですが、ESP32のあるある問題らしい。。

 

もしかしたら検索「Fast LED 一部 光らない」などでこのブログに辿り着くことがあれば、以下参考になさってください。

 

  • Adafruits_NeopixelはESP32だと誤点灯が起きる(Arduinoだと問題なし)
  • RTOS等入ってないので信号生成系ライブラリはESP32だと大体死ぬ
  • AVRだと割り込み禁止にしておけば、正確にCPUとGPIOで信号生成処理出来るが、ESP32だとRTOSとかキャッシュとかいろんな要因で難しい
  • パルス幅とかが正確じゃ無いと困る系は、ESP32対応と謳っているものを使うのが無難

 

f:id:bastardeyes:20200802174511j:plain