Go言語で書いたプログラムをMCU上で走らせることができるTinyGoは、多くのマイコンボードをサポートしているだけでなく、定番の周辺デバイスも多数サポートしています。直接デバイスとしてのサポートが無くても、I2CやSPIといった標準インタフェースをサポートしてくれているので楽。今回は秋月製の定番LCDを接続。
※「AT SAMの部屋」 投稿順indexはこちら
今回接続のLCDは、狭ピッチのパネル+秋月製のDIP化キットという組み合わせです。小さくてお手頃価格、簡単に接続できる定番。私メも「ちょいとディスプレイが欲しいな」という時(大抵トラブッた時ですが)にチョイチョイお世話になっております。以下は通販サイトへのリンクです。
秋月電子通商 I2C接続小型キャラクタLCDモジュール(16×2行・3.3V/5V)ピッチ変換キット
Seeduino Xiaoへの接続
接続回路図描こうかと思ったのですがI2Cです。面倒くさいのでとりあえずなしとしてしまいました。後で何かもっと接続したら描きますです。TinyGoのXiaoボードに関するページが以下に。
Xiaoは端子数の少ない極小ボードなので、以下の日本語ページの端子図をみれば十分な気もします。
I2Cの0番として参照することになる周辺回路は以下の端子にアサインされています。SCLはArduino式の端子名D5であり、SAMD21マイコンのPA09端子です。そしてTinyGoでは SCL_PIN という名称でもアクセスできます。SDAも同様、以下の通り。
-
- SCL — D5 (PA09) — SCL_PIN
- SDA — D4 (PA08) — SDA_PIN
SCL_PINと書けばソフトは抽象的で他ボードに移植しやすいかも知れませんが、実機のどの端子に回路を接続したら良いのか年寄りは忘れてしまいます。それでことさらD5、D4などと書いてます。Xiaoボードの上に付属のシールを張り付けると読める端子番号です。
なお、このLCDは5Vでも3.3Vでも動作可能(コントラストは異なるのでお好みで要調整)なので、Xiaoにあわせて今回は3.3V使いです。秋月基板は半田ブリッジでプルアップ抵抗をイネーブルできるのですが、今回使用の部品には盛ってません。外付けの4.5kΩをプルアップにつけてます。
動作確認用のTinyGoのソース
さて秋月殿の部品付属の説明書(1枚のペラ紙)の末尾には「Arduinoとの接続」ということでArduino用のC風味ソースが掲載されとります。その初期化、データ、コマンドの書き込み関数をほぼそのままGoに「移植」する感じで以下のソースを作成させていただきました。こんな感じ。
package main import ( "machine" "time" ) const ( AQM1602ADR = 0x3E AQMCMD = 0x40 AQMDAT = 0x00 ) func delayA(arg time.Duration) { time.Sleep(arg * time.Millisecond) } func writeData(dat byte) { arg := make([]byte, 1) arg[0]=dat machine.I2C0.WriteRegister(AQM1602ADR, AQMCMD, arg) delayA(1) } func writeCommand(dat byte) { arg := make([]byte, 1) arg[0]=dat machine.I2C0.WriteRegister(AQM1602ADR, AQMDAT, arg) delayA(1) } func initAQM1602() { delayA(100) writeCommand(0x38) delayA(20) writeCommand(0x39) delayA(20) writeCommand(0x14) delayA(20) writeCommand(0x73) delayA(20) writeCommand(0x56) delayA(20) writeCommand(0x6C) delayA(20) writeCommand(0x38) delayA(20) writeCommand(0x01) delayA(20) writeCommand(0x0C) delayA(20) } func main() { machine.I2C0.Configure(machine.I2CConfig{ Frequency: 100000, SCL: machine.D5, SDA: machine.D4 }) initAQM1602() var message = "TinyGo: AQM1602" writeCommand(0x80) for idx := 0; idx < len(message); idx++ { writeData(byte(message[idx])) } var c byte = 0x30 for { writeCommand(0x80+40) writeData(c) if c >= 0x39 { c = 0x30 } else { c += 1 } time.Sleep(1000 * time.Millisecond) } }
動作確認
例によって最初トラブって表示が出なかったのは、これまた例によって私の早合点でした。実は最初 SCL_PIN などと抽象端子名で書いたため、ブレッドボード上で配線するにあたってSCLとSDAの端子を間違えておりました。表示がでるわけない。
それに気づき、接続しなおしたらあっけなく表示されました。冒頭のアイキャッチ画像をご覧ください。あたりまえか。それでことさらD4、D5とボード上に印刷されてある端子名をソースに記するようにした次第。でも接続間違えたのは私なんだけれども。八つ当たりか。
毎度のことだね~自分。