たまたま気づいただけですが、Macbook pro 16(2019)のキーボードのバックライト照明が効かない。変えようとすると、照度変更禁止のようなマークが出ます。
Macbook proだけかと思ってacbook air(2018)見ても同じだから、いずれかのOSアップデートでそうなった可能性。
実用上は問題ないから、そのうち治るのを待つ。
P.S.
夕方になったら、Macboo pro/airとも可変できるようになってた、何だったんだろう?
admin

la vie libre
たまたま気づいただけですが、Macbook pro 16(2019)のキーボードのバックライト照明が効かない。変えようとすると、照度変更禁止のようなマークが出ます。
Macbook proだけかと思ってacbook air(2018)見ても同じだから、いずれかのOSアップデートでそうなった可能性。
実用上は問題ないから、そのうち治るのを待つ。
P.S.
夕方になったら、Macboo pro/airとも可変できるようになってた、何だったんだろう?
admin
変換基板届いたので、早速動かしてみた。一番の懸念はアナログ方式ならば、概ねどのサーボモーターでも扱えるのかということ。
変換ボードはこんな形、緑色の樹脂は端を捲れば除去できます。
micro:bitはおそらくどちらの面でも挿入できるでしょうが、スイッチサイエンスの写真を参考に以下のように、タッチセンサーが見える面を以下のように挿入しました。端子の並び考えれば、自ずとそうなりますが、おそらく逆向きでも壊れることのないような端子配列にはなっているでしょう、やっては見ませんが。
https://isehara-3lv.sakura.ne.jp/blog/2022/01/28/サーボモーターの動作確認m5stack-gray/
ここで使ったサーボモーターに制御信号だけつないで動かしてみた。
ブロックコードは以下のリンクになります。タッチセンサー、環境音センスもしくは照度センサーのオア条件でモーターを起動しています。
https://github.com/chateight/servo_motor
動作している動画は、
このように、非常にあっけなく動かすことができます。
admin
micro:bitもGPIOがあるから、サーボモーターも駆動できるんだろうと思っていたけれども、ブロックコマンド使って簡単に動かせるんですね。
ただ、あまりに簡単すぎてどんなサーボモーターでも扱えるのかは不明だから、ちょっと動作確認してみようと思う。クリップで止める(接続する)のは面倒だから、スイッチサイエンスで変換ボード購入してmicro:bit本体にははんだ付けしないようなやり方で動作確認します。
https://www.switch-science.com/catalog/3181/
admin
UnitV2 AIカメラからは認識結果が垂れ流しで出力されてくるようなので、それをM5stackで受け取ってみます。
M5stackのgroveは標準ではI2Cなので、シリアルで使うためにSoftwareSerialライブラリを使います。
参考は、
https://qiita.com/ma2shita/items/37d403fb7a79814d4d4c
ですが、SoftwareSerialの設定(インスタンス作成)では上のリンクのソースと21 <=> 22を入れ替え必要でした。
groveコネクタというのは物理的な形状や接続しか定義していないので、中を通る信号線は自由に定義できるから。
以下の画像から、
ピン21 — SDA — Tx(左端)
ピン22 — SCL — Rx(左端から2番目)
となるので、シリアルのツイスト対抗ピン設定すると”Grove(22, 21); // define rx/tx”となります。
#include <M5Stack.h>
#include <ArduinoJson.h>
#include <SoftwareSerial.h>
SoftwareSerial Grove(22, 21); // define rx/tx connecting to the UnitV2 camera
// SoftwareSerial(rxPin, txPin, inverse_logic)
int x;
int y;
long k;
char data[50];
void setup() {
M5.begin();
M5.Lcd.setCursor(20, 40);
M5.Lcd.setTextSize(2);
Serial.begin(115200);
Grove.begin(115200);
M5.Lcd.print("--initialized--"); // display M5 Lcd message
Serial.print("---initialized---"); // output serial line
}
void loop_(){
if(Grove.available()) {
String recvStr = Grove.readStringUntil('\n');
if(recvStr[0] == '{'){
Serial.print(recvStr);
}
}
}
void readJSON(void){
String recvStr = Grove.readStringUntil('\n');
StaticJsonDocument<128> doc;
DeserializationError error = deserializeJson(doc, recvStr);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
x = doc["x"];
y = doc["y"];
k = doc["k"];
const char* running = doc["running"]; // "Lane Line Tracker"
}
void loop(){
if(Grove.available()) {
readJSON();
sprintf(data,"x = %d , y = %d , k = %ld",x,y,k);
Serial.println(data);
}
}
AIカメラの電源はgrove経由でM5stackから供給されるので、一度ブラウザでAIカメラの動作モードを指定してやれば、あとはAIカメラのUSBケーブルは抜いても引き続き動作します。
AIカメラから送信されるデータはjson形式なので、生のデータはこんな感じ。
これを、ArduinoJsont使って、解析します。
サンプルの事例ではLaneLineTrackerだったので同じコードを流用してますが、いかようにも変えられるでしょう。
生データ出力と解析データ表示は、ソース中ではloop()とloop_()関数で埋め込んで切り替えています。
また結果はUSBシリアルへの出力ですが、M5stackに表示させるだけで十分ならば画面表示させれば良いし、さらにパソコンやラズパイなどに無線で飛ばしても良いでしょう。
時々deserializeがエラーしているので、これはシリアルの転送速度を落としてやらないとダメかもしれません。
admin
TFカードと呼んでますが、実態はmacroSDとほぼ同じだろう。本体にスロットがあり、取り出し簡単ではなかったけれども抜いてみたら、SunDiskの16GBのカードが入っていて中はカラっぽ。
すでにsshコマンドで確認済みですが。
https://isehara-3lv.sakura.ne.jp/blog/2022/03/07/unit-v2カメラにsshログオン/
A.Iカメラの基本機能でそれなりのことはできるけれども、何かやろうとするとA.Iカメラ側にコード書かなければいけないけれども、関連情報はこれからサーチ。まあ、Pythonも3.0系が入っているし、c/c++も使えばやりたいことはできるでしょう。
Groveインターフェース介して、電源供給とシリアル通信使うのが現実的なアプリケーションになると思う。
admin
Arduinoのステッピングモーター駆動は挙動不審、どうも脱調しているかの如く、同じ動作の繰り返しでも段々位置ずれするから、M5stackでも動かしてみる。
ライブラリ使うとブラックボックスになるので、直接ソースで動作を指定しました。
#include <M5Stack.h>
// motor/driver 28BYJ-48/ULN2003
//
// original source https://blog.takumus.io/entry/2016/09/13/190510
//
const int IN1 = 2;
const int IN2 = 16;
const int IN3 = 5;
const int IN4 = 17;
const int d_hs[8] = { // 1-2 drive, 4096 cycles/turn ; gear ration 64:1
0B00001000,
0B00001100,
0B00000100,
0B00000110,
0B00000010,
0B00000011,
0B00000001,
0B00001001
};
int i = 0;
void step(int d);
void setup()
{
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
}
void loop()
{
for(int i=0; i < 8*256; ++i)
{
step(1);
delayMicroseconds(2000); // it does not work properly lower than 2 ms
}
for(int i=0; i < 8*512; ++i)
{
step(-1);
delayMicroseconds(2000);
}
for(int i=0; i < 8*256; ++i)
{ step(1); delayMicroseconds(2000);
}
}
void step(int d) // d = -1 : anticlockwise, d = 1 : clockwise { i += d; if(i > 7) i = 0;
if(i < 0) i = 7;
byte b = d_hs[i];
digitalWrite(IN1, bitRead(b, 0)); // bit position 0 ; LSB
digitalWrite(IN2, bitRead(b, 1));
digitalWrite(IN3, bitRead(b, 2));
digitalWrite(IN4, bitRead(b, 3));
}
M5stackは外部に出ているGPIOピンが少ないので、使用するピンは限定されます。
以下の画像で、3-R0, 18-SCKなどは同じピンがオスメスの違いで出力されているだけです。
最初、2/5/35/36使ったら動かない、35/36は入力専用だから。次に2/5/25/26使うと動いたけど、スピーカーと兼用らしくて五月蝿い。で最終的に2/5/16/17を使用。
<結論>
M5stackでは正確に角度を刻める、ただし時間待ちを1,500μsぐらいに小さくすると抜けが出るようです。値を大きく取って、連続して動かしていてもターンテーブルの位置は変わらないから、時間待ちがどうも問題の本質のようです。
あとArduinoIDEはイマイチだから、Arduinoの開発環境もVScodeにしたほうがいいかもしれない。
P.S. (2022/5/22)
Arduinoから線引き出して、同じ条件で二つのモーターの動作比較して、
・本体のモーターが片方向しか回転しないのは、モータードライバ基板へのArduino側の配線が一本外れてた。-> これは該当問題とは無縁の突発事象
・外部モーターもライブラリ使わないとFreeRTOS配下ではうまく動作しない。圧電スピーカーでもそうだったけど、どうも時間待ちという処理でFreeRTOSとリソース競合が起こるように見える。
・ライブラリ使っても、ライブラリなしと同様に回転速度を落とさないとパルスが抜けるように見える。
と言うことで、回転速度を” myStepper.setSpeed(5); // 10 -> 5回転/1分に設定、つまりライブラリなしでの時間待ちを長くするに相当、に落とすとまともに動いてるように見えるから、高速では動けないモーターだったということ。
アップデートは、
https://github.com/chateight/arduino/tree/master/smart_car_RTOS
にアップロードしました。
admin
立ち上げで初期化完了時にサウンド、バックするときにも違うサウンドを出す、としたいけど、初期化完了時はともかく、バックする時にサウンド出すと、なぜか前進切り替わり時にDCモーターの左側が動いたり動かなかったり(大半は動かない)。なんで圧電スピーカーならすDIO(pin14)とそれ以外のDIOが干渉するか分かりませんが、どうもタスクコントロールに問題があるんだろうからFreeRTOSに理解が浅いだけだろうと思う。
スピーカーはArduinoやDCモーター駆動基板を覆うような形で作ってみた。造形時間3時間ぐらいで、天井に圧電スピーカーをマウントできるようにしています。Arduinoとの接続はハンダ付だと分解が大変そうなので、ピンをArduinoのコネクタに差し込むようにして対応。
P.S.
タスクにしないで、直接関数呼び出しても同じ現象が起こるから、RTOS問題では無さそう。tone()関数はCPUのタイマー使っているから、実はそれがRTOSと競合しているとかあるのかな?
DIOを14から16に変えても状況に変化無し。
ということでback_sound()ではtone()関数使わないで、”ド4(およそ262Hz)”の音をおよそ0.3秒間出すようにしてみたらDCモーターがマトモに動くようです。
setup()からはtone()を呼び出してもこれは問題ないからそのまま使います。ArduinoライブラリにはFreeRTOS、つまりマルチタスク環境では上手く動作しない関数(thread safeでは無い関数)があるのかもしれません。
int pinNo = 16;
void buzzer_setup() {
tone( pinNo, 98, 200 ); // Gの音を発信
delay( 220 );
tone( pinNo, 110, 200 ); // Aの音を発信
delay( 220 );
tone( pinNo, 123, 200 ); // Bの音を発信
delay( 220 );
tone( pinNo, 130, 200 ); // Cの音を発信
delay( 1000 );
}
void back_sound() {
//tone( pinNo, 98, 100 ); // Gの音を発信
//delay( 150 );
//tone( pinNo, 98, 100 ); // Gの音を発信
//delay( 150 );
for(uint16_t count=0; count<78; count++){
digitalWrite(pinNo, HIGH);
delayMicroseconds(1908);
digitalWrite(pinNo, LOW);
delayMicroseconds(1909);
}
}現状のソースコードやstlファイルのリンクはこちら。
https://github.com/chateight/arduino/tree/master/smart_car_RTOS
admin
特に何もしてない状態で電源切れる現象(ファンがいきなり高回転して電源断)が多発。
備え付けのdiagnosisでは問題発見できないけれども、現象からしてボード交換コースになりそうだ。
費用もともかく使えないのが困る、非常用はMacbook airだけれども、環境がまるで違うから、代替えにはなり得ない。
P.S.
近所のApple authorized repair centerで診断 : ハード診断は問題なし。とすると二年経過で、ACアダプタ常時つなぎっぱなしの電池あたりか。充電容量満充電付近では、頻繁に起きてたシャットダウンは発生しないようだから。
P.S._02
5月9日の朝も発生、
同じような時刻に再発して、もしかしたらnasへのtimemachineとタイミング的に合っているような気もする。
・特に操作していない時に起きる
・周辺機の接続はなし
・バッテリー容量には関係ないようだ、最初はバッテリーエラーを疑ったけど
・落ちる前にはポインティングデバイス無反応、つまりOSが処理続行不能状態
・昨日も今日もNASの電源落としている、つまりtimemachine動かない、と発生しない
ハードじゃなくて、ソフト問題で尚且つtimemeachine関連だね
P.S._03(2022/5/10)
早朝にMac sleep時にtimemachineバックアップ設定してたら、やはりKP起きてたから、現象は特定できたけど回避方法はこれから。
ローカルのディスク(USB)にはtimemachineバックアップ正常終了したから、ネットワークディスク関連で問題。
原因は特定できないので、NASに領域切り直してtimemachineは正常に完了。また出るかもしれないけど、その時はまた切り直せば凌げるだろう。あと領域が少なすぎるのも問題なのかもしれないから、いずれSSDが安くなれば交換か、稼働時間限定だからHDDを使うか。所詮Wi-Fi経由だと、速度的にもそれほどSSDのメリットもないし。
P.S._03(2022/5/11)
qnapのNASはボリュームの使用を80%推奨になってますが、95%とかギリギリに設定していたので、SSDを一台HDDに入れ替えて容量増やして、推奨条件で使うように再構成。アプリとかはSSDのままにしておいて速度が低下しないように変更。所詮Wi-Fi接続だからせいぜい60MB/secぐらいしか速度出ないから、SSDでもNASでも書き込み時間的には大差はない。
もともとバックアップは外部SSDやHDDにも多重化して持っているので、NASのディスクが壊れても致命的ではないから、NASはraid構成にはしていない。ディスクは生きてても、制御部が壊れることもあるわけだからNASを全面的に信用する運用は避けるべきだろう。
admin
PyGameの迷路のコントローラーとしてM5stackを使ってみた。
M5stackとMacとの通信は以下の方法で。
https://isehara-3lv.sakura.ne.jp/blog/2022/05/05/m5stack-bluetoothでのmacとの送受信/
迷路ゲームについては、迷路作成は壁のばし法
のクラスファイル流用して、ゲーム本体は、
https://news.mynavi.jp/techplus/article/zeropython-90/
から迷路作成ロジックだけ入れ替えですが、ほぼそのまま使えました。
M5stackのボタン処理は、ボタンが三つしか無いから、そのままではL/R/U/Dの処理ができないから、M5stackを傾けてボタンA/Cを操作したらU/Dになるように重力加速度の値で読み替えしてます。
ゲーム中にボタンBを押すとゲーム終了します。
#define M5STACK_MPU6886
#include "BluetoothSerial.h"
#include <M5Stack.h>
BluetoothSerial bts;
String btn;
float accX = 0.0F; // Define variables for storing inertial sensor data
float accY = 0.0F;
float accZ = 0.0F;
float angle_th = 0.5F; // r/l or u/l decision threashold
void read_imu() {
M5.IMU.getAccelData(&accX,&accY,&accZ); //Stores the triaxial accelerometer.
M5.Lcd.setCursor(0, 90);
M5.Lcd.printf(" accX");
M5.Lcd.setCursor(0, 130);
M5.Lcd.printf("%5.2f G", accX);
}
void setup() {
M5.begin();
M5.Power.begin(); //Init Power module.
M5.IMU.Init(); //Init IMU sensor.
M5.Lcd.setRotation(3);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(0, 0, 2);
M5.Lcd.println("Maze game");
bts.begin("ESP32test");
}
void loop() {
btn = ""; // button info. clear
M5.update();
if(M5.BtnA.wasPressed())
{
btn = "r";
}
if(M5.BtnB.wasPressed())
{
btn = "t";
}
if(M5.BtnC.wasPressed())
{
btn = "l";
}
read_imu(); // imu data read
if(btn != "")
{
if (btn != "t") // t(ButtonB) key terminate the Maze game
{
if (accX < -angle_th | accX > angle_th) // if M5stack is tilted, r/l keys are changed to u/d
{
if (accX < -angle_th){ if (btn == "r") { btn = "u"; } else { btn = "d"; } } if (accX > angle_th)
{
if (btn == "r")
{
btn = "d";
}
else
{
btn = "u";
}
}
}
}
bts.println(btn); // send pressed key info.
M5.Lcd.setCursor(0, 50, 2);
M5.Lcd.println(btn);
}
delay(100);
}Bluetoothシリアルがコードを弄ってると繋がらなくなることが頻繁に起きて、その都度リブートしてるのは面倒です。本質的な原因はなんなんだろう?
全体のコードは、
https://github.com/chateight/PlatformIO/tree/master/bte_serial/src
にあります。
pythonのmaze.pyがメイン処理、make_maze.pyが迷路作成コード、receive.pyはM5stackのキー入力確認用のスクリプトでゲームと直接は関係ありません。
admin
プロトコルの煩雑なbleではなく、シンプルなbluetoothで接続してみます。
<環境>
・M5stack gray
・Macbook Monterey
・Python3 : mac側の動作確認用スクリプト記述
<ライブラリ>
bluetoothをあたかもシリアルのように見せるライブラリ(M5stack :
・pyserialをインストールする
pip3 install pyserial
・BluetoothSerial.hのインストール
<main.cpp>
#include "BluetoothSerial.h"
#include <M5Stack.h>
BluetoothSerial bts;
void setup() {
M5.begin();
M5.Lcd.setRotation(3);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(0, 0, 2);
M5.Lcd.println("Bluetooth TEST");
bts.begin("ESP32test");
}
void loop() {
M5.Lcd.setCursor(0, 20, 2);
M5.Lcd.printf("Start Bluetooth");
bts.println("message from the M5stack");
//Serial.println("loop");
String str = bts.readString();
M5.Lcd.setCursor(0, 60, 2);
M5.Lcd.println(str);
delay(1000);
}
・シリアルポートを調べる
M5stackにコード書き込んで、シリアルポートを調べます。
% ls -l /dev/tty.*
crw-rw-rw- 1 root wheel 0x9000008 5 4 18:03 /dev/tty.ESP32test
<write.py>
該当のポート情報に上の情報を設定します。
import serial
mes = "messge from my Mac"
# initialize bt serial
m5data = serial.Serial('/dev/tty.ESP32test',115200, timeout=3)
# read from bt
line = m5data.readline()
print(line.decode()[:-2:])
# write to bt
m5data.write(mes.encode())
m5data.close()・実行
% python write.py
b”
‘’に何も表示されないということはタイムアウトしている。
・macをリブートして、USBシリアル経由でpyserialの機能を確認してみる。
% ls -l /dev/tty.*
crw-rw-rw- 1 root wheel 0x9000008 5 5 09:39 /dev/tty.SLAB_USBtoUART
write.pyに以下のデバッグ行追加
Serial.println(“loop”);
% python write.py
b’loop\r\n’
デバッグ用にコンソールに出力させて、シリアルポート切り替えると受信できるからpyserialそのものは動いているんだろう。
じゃ、本来のbluetoothでどうなの?この時MacからESPtestのbluetoothに接続はしない。
% python write.py
b’message from the M5stack\r\n’
ちゃんと受信できるから、どこかクリアされない状態があった?
リブートで状態がクリアされているようで、結果としてmacの設定でbluetoothの接続をしてしまうとダメ。一度接続選択すると接続選択解除してもpythonスクリプトからは使えなくなるから接続の権利(と言ってもmacに変わりはないけど)を他でキープしているようだ。
P.S ここでは接続しないと、% ls -l /dev/tty.*で見えないからダメだけど、
ここでは接続してはいけない。
読み出し文字列中のb’’はバイトストリングと言うことらしいけど、実際には必要ないからdecode()して普通の文字列に変換してやります。また書き込みの時にはencode()が必要です。
M5stackのスクショってどうすれば取れるんだろう?
bluetooth経由でデータの送受信ができるとやれることが広がります。
admin