2017年10月05日

Micropython + SH1106 OLEDでの表示

sh1106-spi-esp32.jpg

前回表示させたOLEDは0.96インチの製品でしたが、実は1.3インチのOLEDモジュールも買ったまま放置していました。
AmazonマーケットプレイスでHiLetGoが販売していたものです。
こちらもSPIインタフェースなので、差し替えて動くかどうか試してみたところ、以下のように正常な表示はできませんでした。
sh1106-spi-esp32b.jpg

上記の製品ページの説明をよく見ると、
ドライバIC:SSH1106 or SSD1306

と記載されています。
製品には手がかりは書かれていないのですが、おそらくSSD1306のドライバで動かないからにはSSH1106(これも記載ミスで、正確には「SH1106」です)なのだろうと推測しました。

ネット上の情報をいろいろ見てみると、SSD1306とSH1106はかなり似ているものの、SH1106は内部的には132×64ピクセルの構成になっているようです。
さらに、データシートもダウンロードして眺めてみると、内部のメモリは下図のようになっており、データを転送するには「Page」「Column」の両方を指定する必要があることが分かりました。
sh1106.png

開始位置としてPageとColumnを指定し、データをどんどん転送していくとColumn値が勝手に増えていきますが、上限である0x83を超えてもPageは繰り上がりません。
従って、Column 0x83に到達したらPageを1増やし、Columnをリセットしてやる必要があります。
実際のディスプレイは横128ピクセルしかなく、メモリのColumn 2〜Column130が表示されますので、この範囲にフレームバッファを転送すれば良いことになります。

以上を踏まえて、Micropython用のSH1106ドライバをSSD1306のサブクラスとして実装したのが以下のコードです。
SSD1306との違いはフレームバッファを転送するところだけです。

使い方の例は以下のようになります。
ESP32-DevKitCとの結線は前回と同じです。
SSD1306-ESP32.png

>>> from machine import Pin, SPI
>>> spi = SPI(1, baudrate=8000000, polarity=0, phase=0, sck=Pin(14), mosi=Pin(13), miso=Pin(12))
>>> oled = SH1106_SPI(128, 64, spi, dc=Pin(16), res=Pin(17), cs=Pin(18))
>>> oled.line(0,0,128,64,1);oled.show()
>>> oled.line(128,0,0,64,1);oled.show()
>>> oled.text('SH1106',36,0);oled.show()
>>> oled.text('Micropython',24,56);oled.show()
>>>
ラベル:MicroPython
posted by boochow at 00:52| Comment(0) | ESP8266/ESP32 | このブログの読者になる | 更新情報をチェックする

2017年10月01日

ESP32 + MicroPythonでOLEDに表示させてみた

ssd1306-spi-esp32.jpg

Micropython + ESP32でI2C経由の表示ができましたので、次はSPIを試してみました。
Micropythonには既にSSD1306のドライバが用意されていますので、これを使ってみます。
使用したOLEDは0.96インチのSPI接続のもので、使っている方も多いと思います。

結線は下図のとおりです。
SSD1306-ESP32.png

信号線の対応は

OLED ESP32
GND GND
VCC 3V3
D0 IO14(CLK)
D1 IO13(MOSI)
RES IO17
DC IO16
CS IO5

となります。

SPIの信号線のうち、MISOはこのモジュールにはありませんので結線していませんが、ソフトウェア的にはIO12をMISOに使用することにします。
ESP32にはハードウェアSPIの機能も備わっていますが、そのデフォルトのピン配置は
SPI(1) : sck=Pin(6), mosi=Pin(8), miso=Pin(7)
SPI(2) : sck=Pin(14), mosi=Pin(13), miso=Pin(12)
となっているそうです。今回はSPI(2)のほうへ合わせてみました。

What are ESP32 SPI Ports for Micropython SPI(1)? - MicroPython Forum

次にソフトウェアです。
SSD1306のドライバ「ssd1306.py」はMicropythonのソースコードディレクトリの

micropython-esp32/drivers/display/

の中にあります。
このファイルをWindows側のフォルダへ持ってきます。
そして、uPyCraftを使ってESP32へ転送します。
これはuPyCraftでssd1306.pyを開き、DownloadAndRunボタンを押すだけです。
これでファイルはESP32のファイルシステム内へ保存されます(電源を切っても保持されます)ので、以降はimport文で読み込めるようになります。

ではREPLでOLEDへ表示させてみましょう。
>>> from machine import SPI
>>> from machine import Pin
>>> from ssd1306 import SSD1306_SPI
>>> spi = SPI(1, baudrate=8000000, polarity=0, phase=0, sck=Pin(14), mosi=Pin(13), miso=Pin(12))
>>> oled = SSD1306_SPI(128, 64, spi, dc=Pin(16), res=Pin(17), cs=Pin(18))
>>> oled.fill(0)
>>> oled.text('Micropython', 0, 0)
>>> oled.text('works fine!', 0, 10)
>>> oled.show()
>>>

これで冒頭の写真のように文字が表示されます。

SPIの第一引数は、1か2しか使えないようです。
他の値を指定すると
SPI ID must be either HSPI(1) or VSPI(2)

というメッセージが出ます。(Software SPIの場合はID=-1を指定しますが、これを使うとエラーにはなりませんがOLEDへ表示されませんでした)
MicropythonのSPIクラスの解説ドキュメントはこちらにあります。

OLEDへの表示は、フレームバッファクラスが使われています。
フレームバッファクラスは線、矩形などの描画も可能です。
しかし現時点でmicropython-esp32に一緒に入っていたssd1306.pyには、文字列描画(text(str,x,y))とドット描画(pixel(x,y,color))と塗りつぶし(fill(color))しか実装されていません。

本家の最新版のssd1306.pyでは、それ以外の描画機能もサポートされているようですので、こちらを使えば図形も描画できそうです。
まず、古いファイルを削除しましょう。
>>> import os
>>> os.listdir()
['boot.py', 'ssd1306.py']
>>> os.remove('ssd1306.py')
>>> os.listdir()
['boot.py']
>>>

そして、最新版のssd1306.pyを改めてuPyCraftで転送します。
これで矩形と線が描けるようになりました。
こんな感じで使います。
oled.fill(0)
oled.hline(0,32,128,1)
oled.vline(64,0,64,1)
oled.show()

oled.line(0,0,127,63,1)
oled.rect(72,8,24,16,1)
oled.fill_rect(24,48,24,16,1)
oled.show()

ssd1306-spi-esp32b.jpg
ラベル:MicroPython
posted by boochow at 21:22| Comment(0) | ESP8266/ESP32 | このブログの読者になる | 更新情報をチェックする

ESP32 + MicropythonでLCDにサーバから取得した情報を表示してみた

ex-rate-esp32.jpg

MicropythonでネットにつながりLCDに表示ができることも確認しましたので、以前ESP8266+Arduinoで動かした以下のプログラムと同じものをMicropythonで作ってみました。

ESP8266版Arduinoでネットから情報を取ってきてLCDに表示する: 楽しくやろう。

ざっとおさらいすると、HTTP GETで取得したJSONのデータをパースしてキャラクタ液晶に表示する。というものです。
従って、追加で必要なのはHTTP GETとJSONのパースだけですが、どちらもゼロから作る必要はありません。

HTTPのサンプルは以下にあります。
ちなみにESP32では標準でmicropython-libのurequestsというパッケージも用意されているようですが、今回は使いませんでした。

5. Network - TCP sockets − MicroPython 1.9.2 documentation

JSONのライブラリは標準で用意されており、使い方は以下の記事が参考になりました。
(Pythonのユーザには常識なのかもしれませんが・・・)

ESP32 MicroPython: Parsing JSON | techtutorialsx

ESP8266+ArduinoではJSONの扱いが若干難儀だったような記憶がありますが、今回は特に苦労することはありませんでした。

というわけで作ってみたのが以下のコードです。
ハードウェアの配線はLCD出力の実験と同じです。

REPLでコピペしたあと(wlan_connect()に与えるSSIDとパスワードはmain()の中で追加してください)、
main()

を実行すると、現時点の円・ドルレートがLCDに表示されます。



前半はST7032iのドライバです。
カーソル移動と文字列表示を追加しました。
最初のi2c通信がエラーになる現象は直っていませんので、main()の中で一度i2c.scan()を呼んでいます。

そのあと無線LAN接続、HTTP GET、メインと3つの関数が続いています。
簡単な内容なので説明は省略します。

Micropythonでのプログラミングはやはり楽です。組み込みプログラミングの中ではおそらく最もイージーモードですね。
ラベル:MicroPython
posted by boochow at 00:34| Comment(0) | ESP8266/ESP32 | このブログの読者になる | 更新情報をチェックする

2017年09月29日

Micropython + ESP32のためのIDE「uPyCraft」を使ってみた

upycraft01.png

ESP32でMicropythonが動いていますが、REPLで毎度コードをペーストするのも大変です。
ファイルをESP32にダウンロードするツールがあるのではないかと探してみたら、uPyCraftというツールを見つけました。

Introduction ・ uPyCraft_en

Windowsでも動作しますし、エディタとコンソールが一体化していてなかなか便利そうです。

使い方も難しくはなく、設定としてはMicropythonが動作しているESP32のシリアルポートをメニューの「Tools」→「Serial」から選択すれば完了です。

このツールはもともとFireBeetle ESP32という開発ボード用に作られたもののようです。
中国の会社の製品のようですが、DevKitCとそれほど違いがあるわけではなく、問題なく使用できました。

Arduinoのように、「File」→「Examples」にいろいろなサンプルがもとから付属しています。
この中から、試しに「Basics」→「mario.py」を動作させてみました。

コードを見ていくと、IO25に音声を出力させているのがわかります。
圧電ブザーをIO25とGNDに接続して試してみました。
upycraft02.png
upycraft1.png

まず、ウインドウのConnectボタン(STOPボタンの右)を押します。
これでESP32のシリアルポートに接続されるはずですが、接続されない場合はメニューの「Tools」→「Serial」でシリアルポートが選択されているか確認してください。

そして、「DowloadAndRun」ボタン(右向き三角のボタン)をクリックすると、ファイルがESP32に転送され、実行されます。
見事!マリオのテーマが圧電ブザーから流れました。

サンプルはまだ作成中のものも多いようですが、uPyCraftはArduino的なお手軽さをESP32 + Micropythonで実現できており、なかなかのお勧めだと思います。
ラベル:MicroPython
posted by boochow at 01:50| Comment(0) | ESP8266/ESP32 | このブログの読者になる | 更新情報をチェックする

2017年09月26日

ESP32 + MicroPythonでLCDモジュールに文字を表示させてみた

MicroPythonが動作したので、次はデバイスを使ってみたいと思い、I2C接続のキャラクタ液晶をつないでみました。
使った液晶は、以前使っていた以下の記事のものです。

Arduino(10) aitendoの激安キャラクタ液晶をArduino Pro Mini(3.3V)に接続: 楽しくやろう。

接続の仕方はArduinoの場合と同じで、I2Cインタフェースですので基本的には3.3V、GND、SCL、SDAの4本の線をつなぎます。
SCLはIO21、SDAはIO22を使いました。
他に、この液晶モジュールではバックライト用の電源と、RESET端子を3.3Vに接続します。
バックライトは白色LEDですので、抵抗を入れます。
接続図は以下のようになります。
このESP32のfritzing用データはht_dekoさんのものを拝借しました。

SPLC792-ESP32.png


次にソフトウェアです。
この液晶はST7032iというコントローラが使われていますが、ちょっと調べた範囲ではMicropythonですぐ使えそうなドライバが見つからなかったので、データシートを見ながら書いてみました。
(あとから考えてみたら、別にMicropythonでなくとも、Raspberry Piにこのモジュールを接続してPythonで制御するコードでも使えたはずでしたが・・・)

データシートは型番で検索すればすぐ見つかります。初期化コードの例も(アセンブラですが)載っています。
コマンドのサマリと初期化コードのサンプルは以下のようになっています。
st7032-1.png
st7032-2.png
st7032-3.png


MicropythonのソースコードのESP32のフォルダの中にSSD1306のドライバが付属していたので、このコードを参考に、ST7032のドライバを見よう見まねで書いてみました。

micropython-esp32/ssd1306.py at esp32 ・ micropython/micropython-esp32 ・ GitHub

書いたドライバはこちらです。


エディタで作成したこのコードをMicroPythonで実行させるには、これまでのインタープリターモードのままでは不便です。

インタープリタの画面で「Ctrl-E」を入力します。
すると、以下のように「ペーストモード」になります。

paste-mode.png


この状態で、作成したコードをコピー&ペーストし、最後に「Ctrl-D」を入力するとインタープリタに戻ってきます。

paste-mode2.png


これで、ペーストしたコードは既に読み込み済みですので、インタープリタから実行することができます。
まずi2cオブジェクトを作ります。

===
>>> i2c = I2C(scl=Pin(21), sda=Pin(22), freq=100000)
>>>


これでLCDモジュールを呼び出せるはずなのですが、なぜかそのままLCDと通信しようとすると「ENODEV」エラーが出てしまうので、いったんこのi2cオブジェクトを使ってi2cバスをスキャンします。

>>> i2c.scan()
[9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119]
>>>


このスキャン結果も変(デバイスは1つしかつながってないはずなのに!)なのですが、プルアップの設定か何かがまずいのかもしれません。
ともかく、このi2cオブジェクトを使ってLCDオブジェクトを生成します。

>>> lcd = ST7032i(i2c)
>>>


この状態で、LCDの初期化が済んでいます。
あとは、文字を1文字ずつ(ASCIIコードで)送ると、文字が表示されました。

>>> lcd.write_data(65)
>>> lcd.write_data(66)
>>> lcd.write_data(67)
>>>


st7032-micropython.jpg


やはりPythonで書けるというのは楽ですね。
Arduinoだと直すたびにコンパイルしてバイナリを転送しなければならなかったので、試行錯誤のペースは格段に上がると思います。
ラベル:MicroPython
posted by boochow at 20:38| Comment(0) | ESP8266/ESP32 | このブログの読者になる | 更新情報をチェックする
人気記事