LoginSignup
12
1

日本語 | English

本記事は「#NervesJP Advent Calendar 2020」の21日目です。

前日は@piacerexさんのRespberry Pi Zero WHにElixir IoTフレームワーク「Nerves」を入れてみたでした。

はじめに

プログラミング言語を学ぶときは、まず「Hello」と文字を表示するところから始まりますが、IoTの世界ではLチカがその役目をしているようです。僕がLチカ後に興味を持ったのは、11日目に話をしたパルス幅変調 (PWM)でのLチカでした。

しばらくLチカプラスαで遊んだあと、その次にやりたくなったことは、何らかの方法で実際に「Hello」表示することでした。その話をします。

nerves_hello_lcd_20201219_152639

どういう手法で「Hello」?

Nerves JP@takasehidekiさんからのアドバイスでどーんとまとめて入手した部品が多数手元にあったので、それぞれの使い方をザクッと把握しながら、どれにしようかと検討をはじめました。以下のものを検討しました。

  • LEDをたくさんならべる
  • 赤色7セグメントLED表示器(1文字)
  • 赤色7セグメントLED表示器(4文字)
  • 赤色ドットマトリクスLED(8×8)
  • LCDキャラクタディスプレイモジュール(16×2行)
  • Web
  • Mobile

色々悩んでLCDにI2Cインターフェースを取り付け、シリアル通信することに決めました。理由は、下記のとおりです。

  • WebとMobileは実用的かもしれないが、今は電子工作をしたい
  • 他の選択肢が物理的な配線が多くてめんどくさそう
  • LCDに興味をもった
  • I2Cで接続すると少ない配線で通信できるのがカッコいい

調査

まずは、ひたすらググり、Youtubeのビデオも片っ端から見ました。いくつか役に立ったものを挙げます。

配線に関しては、パラレル通信でもシリアル通信でも特に何も難しいことはありませんでした。
プログラミングに関しては、ほとんどがC、C++やPythonで書かれたLCDドライバを使用する場合の説明が多く、Elixirプログラミングする上であまり参考にはなりませんでした。

Elixirで使えそうなライブラリを探しました。I2Cシリアル通信にはElixir Circuits - I2Cが使えるのは、知っていたのですが、肝心のLCD操作のライブラリに良いのがありません。ExLCDがありますが、(2020年12月現在)長い間メンテされてなくI2Cにも対応していません。ExLCDをフォークして改善を試みましたが、既存の実装に納得行かない部分が色々あったので、それを参考にしつつ自分で実装することにしました。

しばらくの間、他言語で書かれたLCDドライバーのソースコードをいくつか読んでElixirで同様のことができるのかを探りました。ある時点で、LCD本体自体の資料(データシート)に出くわし、それらのLCDドライバーはただデータシートの通りにコマンドを実行している単純なものであると気づきました。当たり前の事だったのかもしれません。気づいてよかった。

デモアプリ

まずLCD本体自体の資料(データシート)をよく読み、各種ピンの役割、初期化の方法、4ビットモード、各種コマンドについての理解を深めました。実験用Nervesアプリで試行錯誤しながら、コードを書いていきました。

動くようになるまで、結構時間がかかりました。例えば「Hello」と入力してるのに変な文字が表示されたりしました。焦りました。

一旦動くのが確認されたら、最低限のテストを書いて回帰試験しながら、リファクタリングしていきました。LCDを動かす部分とデモアプリを切り離せたので、LCDを動かす部分はライブラリに、デモアプリはそのライブラリの使用例とすることにしました。

もし、Nervesに取り組むのが初めての方おられましたら、2日目に@kentaroさんが発表されたウェブチカでElixir/Nervesに入門する(2020年12月版)がわかりやすく説明してくれています。また、NervesJP Slackにジョインされれば、コミュニティが色々教えてくれます。僕もそのNervesJP Slackにお世話になっている一人です。

ハードウェア

Connect:

デモアプリをダウンロード

git clone git@github.com:mnishiguchi/lcd_display.git
cd examples/nerves_hello_lcd

ファームウェアをSDカードに焼く

必要な環境関数をセット。 ターゲット機器タグ一覧

$ export WIFI_SSID=_____  # your WIFI id
$ export WIFI_PSK=______  # your WIFI password
$ export MIX_TARGET=rpi4  # your target board

依存するライブラリをインストール。

$ mix deps.get

FYI: ファームウェア関連のコマンド一覧。

$ mix help | grep firmware

mix burn                   # Write a firmware image to an SDCard
mix firmware               # Build a firmware bundle
mix firmware.burn          # Build a firmware bundle and write it to an SDCard
mix firmware.gen.script    # Generates a shell script for pushing firmware updates
mix firmware.image         # Create a firmware image file
mix firmware.metadata      # Print out metadata for the current firmware
mix firmware.patch         # Build a firmware patch
mix firmware.unpack        # Unpack a firmware bundle for inspection
mix upload                 # Uploads firmware to a Nerves device over SSH

ファームウェアをつくる。

$ mix firmware

SDカードをホストマシンにSDカードを挿入。
下記のコマンドでファームウェアをSDカードに焼く。

$ mix firmware.burn

SDカードをターゲット機器にSDカードを挿入。ターゲット機器の電源オン。

ターゲット機器にWIFI接続

WIFIが接続できているか確認。

$ ping nerves.local

SSHでターゲット機器に接続。しばらくすると、IExシェルが起動する。

$ ssh nerves.local

Interactive Elixir (1.11.2) - press Ctrl+C to exit (type h() ENTER for help)
Toolshed imported. Run h(Toolshed) for more info.
RingLogger is collecting log messages from Elixir and Linux. To see the
messages, either attach the current IEx session to the logger:

  RingLogger.attach

or print the next messages in the log:

  RingLogger.next

iex(1)> RingLogger.attach
:ok
iex(2)> NervesHelloLcd.hello_i2c
  • RingLogger.attach関数を呼ぶと、ログが表示される。
  • NervesHelloLcd.hello_i2c関数を呼ぶと、LCDにHello worldが表示される。

nerves_hello_lcd_20201213_185620

さいごに

いい経験になりました。内容によってはデータシートさえしっかり読めば、特に専用ライブラリがなくても自分でできることがわかりました。

最終的に、ラズパイのGPIOピンをフルに使ってのHelloもやってみました。見た目上、I2Cを使うと配線が少なくシンプルに見えますが、実際はIOエキスパンダが間にあるかどうかの違いでだけで、やってることは同じなのですね。

これからNervesを始める人にも手軽にLCDを操作する一助になれば幸いです。

明日は@ringo156さんです。

12
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
1