そういえば買えるようになったら買おうと思っていたラズパイピコの在庫があったので買ってみた。ピンヘッダ付きとか何かとセットになってるやつは在庫あるのに単品の550円で買えるやつがなかなか在庫なかったので諦めてたんだけど。
2021年7月24日土曜日
Raspberry Pi Picoを買ってみた
2021年7月18日日曜日
WT32-SC01でタッチパネル対応GUIを使ってみる。
先日入手したWT32-SC01でタッチスクリーンを試すのにかっこいいGUIが作れるLVGLライブラリを使ってみた。このライブラリを使うと画像ファイルなしでもかっこいいGUIが作れるらしい?
Arduino IDEでも使えるようだし、液晶パネルのライブラリは前回使用したTFT_eSPIライブラリをそのまま使えるみたい。TFT_eSPIのタッチパネル対応は抵抗膜方式だけっぽかったのでLVGLライブラリでタッチパネルに対応させるためには別なライブラリを使用することに。
まずはタッチパネルの動作確認から。
WT32-SC01のタッチパネル用ライブラリはArduino-FT6336Uを使ってみた。設定もシンプルで良さそうだったし。
WT32-SC01ではFT6336Uの接続はI2Cのみの接続になっていたので、ライブラリで使われている割り込みPinとリセットPinはTPで出ているだけで未接続だった。なのでタッチパネルに触ったかどうかの判別はポーリングで行うことに。
とりあえずサンプルスケッチで動作確認。
#include "FT6336U.h" #define I2C_SDA 18 #define I2C_SCL 19 FT6336U ft6336u(I2C_SDA, I2C_SCL, -1, -1);
サンプルスケッチの上の方はこんな感じで割り込みPinとリセットPinを無効にしてみた。そんでもってINT_N_PINの判別をなくしてシリアルコンソールで入力を確認できた。
ft6336u.read_td_status()
でタッチパネルに触れている指の数(最大2)がわかるっぽいので、ポーリングだけでも触ったことがわかりそうだから問題なさそう。
タッチパネルがなんとなく動いてそうなことがわかったのでお次はLVGLの設定。LVGLライブラリの設定は結構たいへんだった…
まずはライブラリを入れたあとにlv_conf_template.hをArduinoのlibrariesにlv_conf.hとしてコピーして"#if 0"を"#if 1"に変更したり、DEMOを使えるように#define LV_USE_DEMO_WIDGETSを1に変更したりexampleフォルダをコピーしたりする。詳しくは本家サイト参照
そんでもってサンプルのLVGL_Arduino.inoをいじってタッチパネル部分をFT6336Uに対応させてみた。
先程のサンプルスケッチの上の方をそのまま移植して、
void my_touchpad_read( lv_indev_drv_t * indev_drv, lv_indev_data_t * data ) { uint16_t touchX, touchY; uint8_t touched = ft6336u.read_td_status(); if( touched == 0 ) { data->state = LV_INDEV_STATE_REL; } else { data->state = LV_INDEV_STATE_PR; touchY = 320 - ft6336u.read_touch1_x(); touchX = ft6336u.read_touch1_y(); data->point.x = touchX; data->point.y = touchY; } }
タッチパネルが90°ズレていたのでmy_touchpad_read関数を上のように変更した。
setup内ではtft.setRotation( 1 );をtft.setRotation( 3);に変更して液晶の向きを戻して、tft.setTouch( calData );をft6336u.begin();に変更してTFT_eSPIのタッチパネル機能から別ライブラリのArduino-FT6336Uに変更できた。
TFT_eSPIの設定は前回のものそのままで使用できた。例によってバックライト用の2行も追加しないと画面が真っ暗のままなので注意。
ちなみにタッチスクリーンを使うときは上の方で出てきたlv_conf.hの中の#define LV_TICK_CUSTOMを1に変更する必要があるっぽい。(これをやらないと読み込まれない)
そしてついでにタッチパネルのテストをしたいので#define LV_USE_DEMO_WIDGETSも1にしておいた。
サンプルスケッチのlv_demo_widgets();のコメントアウトを外して書き込めばとりあえずタッチパネルのテストができる。
とりあえずシングルタッチで実装してみたけどスワイプもいい感じに動いてる。ESP32でこんなにきれいなGUIを実装できるなんてLVGLライブラリ恐るべし。2021年7月17日土曜日
WT32-SC01を買ってみた。
Aliexpressを見ていたらESP32に静電容量式タッチ対応LCDがついたボードが安かったのでポチってみた。WT32-SC01ってやつ。3500円ぐらいだった。M5Stackとかもいいなーと思っていたんだけどこっちのほうが安くてLCDも大きかったので…
ESP32-WROVER-Bモジュールと3.5インチのSPI接続のディスプレイが乗っている。2ポイントまでの静電容量タッチディスプレイらしい。表面はツルツル。左側に穴が空いているように見えるけど黒い部分が抜かれてるだけで、部品は未実装だった。光センサとかつけようとしていたのかな?裏面にはピンヘッダが並んでいる。このピンヘッダ、2.0mmピッチっぽいので少し扱いにくいかも…ちなみに発注時の画像にも合ったけど技適マーク付きのESP32-WROVER-Bモジュールだった。
#define ST7796_DRIVER
#define USE_HSPI_PORT 1 #define TFT_MISO 12 #define TFT_MOSI 13 #define TFT_SCLK 14 #define TFT_CS 15 #define TFT_DC 21 #define TFT_RST 22 #define TFT_BL 23
#define SPI_FREQUENCY 80000000
pinMode(TFT_BL, OUTPUT); digitalWrite(TFT_BL, 128);
tft.init();
最初User_Setup.hをいじるの知らなくてバックライトがうねうねしてたけどちゃんと設定したら映った。
2021年7月10日土曜日
HX711をI2Cから読めるようにしてみた
Orange Pi PCでうまくHX711が使えなかったので、やっぱりSBCとかで使うにはI2Cのほうが便利ということでHX711をI2C経由で使えるようにしてみた。
やっぱりこういうデバイスはGPIOで頑張るよりちょっとしたマイコンで読んでもらったほうが楽勝な気がする…SBC側のCPU負荷も減るんじゃないかな。
今回はとりあえずAttiny202を使ってHX711のデータを連続で読みに行って、読んだ値をI2C用のレジスタに格納しておいてI2Cからはスレーブでレジスタを読みに来ればいい感じにしてみた。
HX711は10spsモードだからといって一定周期で読もうとすると変なデータになってしまったりするので調べてみるとナゾの一定周期パルスが出ている影響らしい?
とりあえず適当に対策してみたら10spsモードのHX711とAttiny202を繋いで連続で読みに行くと平均177msかかってる。一定周期パルスの2倍の周期でしか読めなかったけど、とりあえず用途的には十分なので良し。
I2C側は割り込みだし、loop内はHX711にだけ注力していればいいので簡単に対策できた。
I2Cでレジスタを読む形のスレーブデバイスを作る部分はちょっと前に作成したコードがそのままattiny202でも使えた。それにHX711を読み込むところを追加したぐらい…
#include <Arduino.h> #include <Wire.h> #define DAT 1 #define CLK 0 #define SLAVE_ADDRESS 0x60 #define DISABLE_INTERNAL_PULLUP //使用するレジスタ範囲指定 #define I2C_REG_ROW 1 #define I2C_REG_COL 4 uint8_t I2C_REG[I2C_REG_ROW][I2C_REG_COL]; //読み書きするレジスタアドレス uint8_t REG_SELECTED; //i2c受信イベント void receiveEvent(int _length) { //1byte目を読み込む(レジスタアドレス指定) REG_SELECTED = Wire.read(); uint8_t startRow = REG_SELECTED >> 4; uint8_t startCol = (REG_SELECTED & 0x0F); while (Wire.available() > 0) { if (startRow < I2C_REG_ROW && startCol < I2C_REG_COL) { I2C_REG[startRow][startCol] = Wire.read(); } else { Wire.read(); } ++startCol; } } void requestEvent() { uint8_t startRow = REG_SELECTED >> 4; uint8_t startCol = (REG_SELECTED & 0x0F); if (startRow < I2C_REG_ROW && startCol < I2C_REG_COL) { Wire.write(&I2C_REG[startRow][startCol], I2C_REG_COL - startCol); } } void setup() { //SlaveでWireライブラリを初期化 Wire.begin(SLAVE_ADDRESS); //イベント設定 Wire.onReceive(receiveEvent); Wire.onRequest(requestEvent); //内蔵プルアップ無効にする場合 #ifdef DISABLE_INTERNAL_PULLUP pinMode(SDA, INPUT); pinMode(SCL, INPUT); #endif //HX711用ピン設定 pinMode(CLK, OUTPUT); pinMode(DAT, INPUT); } void loop() { //HX711データ取得 uint8_t rawdata[3] = {0, 0, 0}; while (digitalRead(DAT) == 0); while (digitalRead(DAT) != 0); for (char k = 0; k < 3; k++) { for (char i = 0; i < 8; i++) { digitalWrite(CLK, 1); delayMicroseconds(1); digitalWrite(CLK, 0); delayMicroseconds(1); rawdata[k] = (rawdata[k] << 1) | (digitalRead(DAT)); } } I2C_REG[0][0] = 0x12; I2C_REG[0][1] = rawdata[2]; I2C_REG[0][2] = rawdata[1]; I2C_REG[0][3] = rawdata[0]; }
mills()/micros()を無効にして、Attiny202の67%に収まってる。とりあえずゲインの調整とかもなしで生データをひたすら177msで更新しているので適当なタイミングでi2cから読みに行けばいい感じ。50ms周期とかで読んでもデータ化けはなかったので用途的には大丈夫そうかな。
一応HX711側は5Vで使う場合はI2C側かHX711側でレベル変換すれば良さそう。HX711側でDATだけを抵抗分圧だけで行けないかなとか思っている。テストではFETでI2C側をレベル変換しているけど。
生データでそのまま吐き出しているので(一応ヘッダ的なのはつけておいたけど)、Orange Pi PC側のPythonのライブラリで値を取得するところだけsmbusからデータ取るようにしたらそのまま使えないかなぁとか思ったり。SBC側のソフトは作成中…
i2cdumpではうまく動いている。
せっかくI2Cデバイスにしてマイコン挟むならゲイン調整とかゼロセットとか、重量の換算までできるようにしたいな。I2Cだから複数のHX711を取り扱うのは楽になりそう。
2021年7月3日土曜日
安価なSDカードリーダ買ってみた
KingstoneのSDカードリーダを使っていたんだけど、どうもカードを指しても認識しなくなる時があって何回か指し直すと認識はするんだけども面倒になったのでAliexpressで送料含めても1.8ドルで売っていたのを買ってみた。
まぁ例によって梱包がアレなので細かい擦り傷がついていたり文字が一部消えていたり…この前ドラレコ用に購入した高耐久microSDと同じものを購入しておいたので測定してみた。
Kingstoneのリーダーでの結果と比べるとQ1T1以外はほぼ同じ。Q1T1だけ遅くなってる。どうやらこのリーダーのコントローラーはシングルキューが遅いよう?