Lispと一緒(3) uLisp、Wio Terminalのボタンをセンスする

Joseph Halfmoon

前回は中身ばかりで外まで手が伸びませなんだ。今回はマイコンで走るuLispならではの外部入力も含めてみます。まずはWio Terminalの上端面に3つならんでいる「青いユーザーボタン」をセンスできるようにしてみます。LCDパネルに向かって右からボタン1,ボタン2、ボタン3であります。でも端子名は何?

※各種マイコン上で走るLisp処理系、uLispの練習には、SeeedStudioのWio Terminalを使用しております。米MicroChip社製32ビットマイコン、ATSAMD51P20 搭載です。コアは Arm Cortex-M4Fです。LCDパネル、Groveポート、microSDカードスロットにWiFiなど、各種装備テンコ盛りの「小さいけれどなんでもできそうな」デバイスです。

参照ドキュメント

さて今回は、Wio Terminalが標準搭載している3個のユーザーボタンをuLispで受け止めるべし、との回です。参照すべきドキュメントは以下のあたりになるかと思います。

御本家、Seeed Studioの日本語ページ。

Wio Terminal

上記には、Wio Terminalの回路図など外部端子を触るときに必須な情報へのリンクが貼られています。

一方、uLisp側としては、以下のランゲージリファレンスを見れば書ける筈。

uLisp Language reference

といいつつ、機種固有の情報については以下のページにしかりまとめられているのでココみれば安心か。

uLisp Seeed Studio Wio Terminal

これだけ書いてあったら大丈夫だよな~。ホントか?

Wio Terminalのユーザボタン

さて上の方ほページからダウンロードしたWio Terminalの回路図を拝見すれば、3個のボタンはいずれもONのときにプルダウンする方向のスイッチであり、それが接続しているマイコン側端子番号も判明します。

しかしね、以前にも何かで書いた記憶がありますが、Wio Terminalの端子名、一筋縄ではいきませぬ。

    • ATSAMD51P20マイコンの端子名
    • Arduino互換環境向けの端子名
    • Raspberry Pi の40ピン拡張端子の端子名

以上の3つが絡まりあってます。当然、回路図上ではATSAMD51P20マイコンの端子名で書かれてます。またSAMD51用のSDKなど使うのであれば、この端子名必須です。しかし、Arduino IDEなど使ってビルドする際には、D0とかA0とか、Arduino式の端子名で呼びたくなるでしょう(そういえば、uLispのビルドはArduino IDEに依存していたな。)

しかしです。Wio Terminalは、Raspberry Piの40ピン拡張端子に「差し込んで」動作させることも可能というコンセプト?で本体背面の40ピンソケットの信号が並んでます。そのため、Raspberry PiでのBCMxxとかGPIOxxといった端子番号がそのまま使われております。そして

uLispのピン番号はRaspberry Pi式の番号でいいみたい

であります。でも40ピンソケットに出てない端子の番号、分からないじゃん。そういうときは、uLispの機種固有情報のページをしっかり読めとな。ううむ。

今回使用の3端子については以下に(拡張端子に出ていないのでArduino式番号はありませぬ。)

PIN番号(Raspberry Pi式) ATSAMD51P20端子名
BUTTON1(RIGHTMOST) 28 PC26
BUTTON2(CENTRE) 29 PC27
BUTTON3(LEFTMOST) 30 PC28

ともかく、28番、29番、30番端子の値を読めばよいわけね。

実験に使用したコード

実験コードが以下に、一応、BUTTON番号をdefvarしておいて、入力に初期化。pollBUTTONs関数を呼べば、500ミリ秒毎にユーザーボタンをセンスして、もしそのボタンが押されていたら、押されていると標準出力に報告します。これを無限ループ。

(defvar BUTTON1 28)
(defvar BUTTON2 29)
(defvar BUTTON3 30)

(pinmode BUTTON1 :input-pullup)
(pinmode BUTTON2 :input-pullup)
(pinmode BUTTON3 :input-pullup)

(defun pollBUTTONs ()
  (loop
    (if (not (digitalread BUTTON1) )
      (print "BTN1 pushed"))
    (if (not (digitalread BUTTON2) )
      (print "BTN2 pushed"))
    (if (not (digitalread BUTTON3) )
      (print "BTN3 pushed"))
    (delay 500) ))
実験結果

上記のコードをシリアルターミナルからuLispへ流し込んだ後、pollBUTTONsを実行してみたところが以下に。右からボタンを押しては離ししておりますぞ。buttonsResults

ちゃんとボタンが押されていることを検出しているみたいぞなもし。

Lispと一緒(2) uLisp、Lispのリハビリその1、ループを回す へ戻る