Nucleo

2021年2月 7日 (日)

MicroPython/CircuitPython Performance Test

2021/2/7

MicroPython CircuitPython Performace Test (v2)

MicroPython CircuitPython Performace Test (v2)

概要

MicroPython/CircuitPython Performance Test この記事は「 MicroPython Performance Test 」を見直して新たな結果を追加した第2版にあたる。

pyborad/STM32用MicroPythonスクリプト

PerformaceTest.py

# Peformace Test import pyb def performanceTest(): millis = pyb.millis endTime = millis() + 10000 count = 0 while millis() < endTime: count += 1 print("Count: ", count) performanceTest()

ESP32/ESP8266用MicroPythonスクリプト

PerformaceTestESP32.py

# Peformace Test for ESP32 from machine import RTC rtc = RTC() rtc.datetime((2020, 2, 9, 1, 12, 48, 0, 0)) # (year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]) def performanceTest(): secs = rtc.datetime()[6] endTime = secs + 10 count = 0 while rtc.datetime()[6] < endTime: count += 1 print("Count: ", count) performanceTest()

PC/BareMetal-RpiZeo/Linux-Rpizero/Maixduino用スクリプト

PerformanceRpiZero.py

# Peformace Test RpiZero import time def performanceTest(): msec = time.ticks_ms endTime = msec() + 10000 count = 0 while msec() < endTime: count += 1 print("Count: ", count) performanceTest()

CC3200用MicroPythonスクリプト

PerformanceTestCC3200.py

# Peformace Test for CC3200 from machine import RTC rtc = RTC(datetime=(2020, 2, 9, 10, 11, 0, 0, None)) def performanceTest(): secs = rtc.now()[5] endTime = secs + 10 count = 0 while rtc.now()[5] < endTime: count += 1 print("Count: ", count) performanceTest()

CircuitPython/Python3用スクリプト

performanceTestCPY.py

# Peformace Test CircuitPython from time import monotonic_ns def performanceTest(): endTime = monotonic_ns() + 10000000000 # 10 sec count = 0 while monotonic_ns() < endTime: count += 1 print("Count: ", count) performanceTest()

XIAO CircuitPython用スクリプト

PerformanceCircuitPython_XIAO.py

# Peformace Test XIAO CircuitPython from time import monotonic def performanceTest(): endTime = monotonic() + 10.0 # 10 sec count = 0 while monotonic() < endTime: count += 1 print("Count: ", count) performanceTest()

実行例

# pyboard/STM32の場合 $ ./pyboard.py --device /dev/ttyACM0 PerformanceTest.py Count: 2825625 # ESP32/ESP866の場合 $ ./pyboard.py --device /dev/ttyUSB0 PerformanceTestESP32.py Count: 39187

結果

ボード名 M/C/P Count
F767ZI M 5,676,566
F446RE M 2,825,625
F4Disco M 2,882,769
Maixduino M 2,218,879
Pico-MP M 1,507,516
F401RE M 1,362,752
L476RG M 1,089,347
PyPortal C 474,734
Grand-Central-M4-Express C 445,404
Feather-M4-Express C 438,444
Teensy4.0 C 432,413
Pico-CPY C 341,033
XIAO C 174,388
Circuit-Playground-Express C 121,800
ESP8266 M 64,049
ESP32 M 39,187
CC3200 M 5,529
BareMetal-RpiZero M 680,525
Linux-RpiZero P 6,370,022
PC(linux) P 161,265,687
micropython-Rpi4 M 16,117,283
python3-Rpi4 P 11,359,199


M/C/Pは、pythonの種類を表し、
M:MicroPython、
C:CircuitPython、
P:Python3
を表す。

コメント

・Pico-MPは、RPI_Picoボードの MicroPython、Pico-CPYは、RPI_PicoボードのCircuitPythonを意味する。

・BareMetal-RpiZeroは、RpiZeroでのBareMetalのmicropython、 Linux-RpiZeroは、linux上でのmicropython、 PC(Linux)は、PCのLinux上でのmicropythonを意味する。

・MaixduinoはMaixduinoのmicropythonであるMaixPyを意味する。

・Teensy4.0はTeensy4.0のCircuitPythonを意味する。

・python3-Rpi4は「python3 performanceCircuitPython.py」の数字、 micropython-Rpi4は「micropython performanceCircuitPython.py」の数字を意味する。

なお、PC(linux)のCPUは、「Intel® Core™ i7-3520M CPU @ 2.90GHz × 4 )」である。

・STM32系(F7xx/F4xx/L4xx)がESP32/ESP8266に比べてダントツに速いようだ。

・Linux-RpiZeroとBareMetal-RpiZeroの数字の違いはCPUキャッシュの有効/無効の差と思われる。

・CC3200は、他のMicroPythonボードに比べて極端に遅い結果だが、省電優先設計のせいだと思われる。

・Teensy4.0のCircuitPythonはmonotonic_ns()のオーバーヘッドが大きい気がする。

・XIAOとCircuit-Playground-Expressは、同じプロセッサATSAMD21(Cortex-M0+,48MHz)にもかかわらず、性能差が出ているのは実装の違いで、XIAOのほうは、floatで動いているのに対して、Circuit-Playground-Expressのほうは、long_intで動いていることによる差が出ていると考えている。

・Pico-MP,Pico-CPYはCortex-M0であるがクロックが他のM0より高いこと(最大133Mz)と浮動小数点ライブラリが最適化されていることでM4並みの性能が出ているようだ。MP,CPYの性能差は最適化が進んでいるかどうかの差と思われる。

参照情報

PicoボードにMicropython/CircuitPythonをインストールする

RaspberryPiのpython3でCircuitPythonのAPIを使用する

XIAOにCircuitPythonをインストールする

Circuit-Playground-ExpressにCircuitPythonをインストールする

Teensy4.0にCurcuitPythonをインストールする

BareMetalのMicropythonをRaspberryPi_Zeroにインストールしてみる

NUCLEO-F767ZIにMicropythonをインストールする(v2)
Nucleo-L476RGにMicroPythonをインストールする
Nucleo-F401REにMicroPythonをインストールする
STM32F4-Discovery」にMicroPythonをインストールする
NUCLEO-F446REにMicropythonをインストールする(v2)
NUCLEO F446RE MicroPython インストール方法

CC3200 MicroPython インストール

ESP32のMicroPythonのインストール方法
ESP-WROOM-02 MicroPython インストール方法

MicroPythonのツールとしてpyboad.pyを使う
The pyboard.py tool

ESP32-DevKitC ESP-WROOM-32開発ボード
MicroPython - Quick reference for the ESP32

ampyを用いたMicroPythonのファイル操作とプログラム実行

以上

続きを読む "MicroPython/CircuitPython Performance Test"

| | コメント (0)

2021年1月 3日 (日)

MicroPython(F767ZI) Network Samples

2021/1/3
初版

MicroPython(F767ZI ) Network Samples

MicroPython(F767ZI ) Network Samples

概要

MicroPython(F767ZI) Network Samples

この記事は「 MicroPython(F767ZI)でStartwars(AsciiArt)を動かす 」の続編にあたり、NetworkアクセスSamplesを記述している。ネットワークの接続が完了すれば、それ以降はESP8266のmicropythonとほぼ同じようだ。
(ホストはubuntuを想定している)

sample1

http_get.py

# ネットワークを有効化する import network nic = network.LAN() nic.active(1) # 以下はESP8266のサンプルと全く同じ def http_get(url): import socket _, _, host, path = url.split('/', 3) addr = socket.getaddrinfo(host, 80)[0][-1] s = socket.socket() s.connect(addr) s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8')) while True: data = s.recv(100) if data: print(str(data, 'utf8'), end='') else: break s.close() print(http_get('http://micropython.org/ks/test.html'))

REPL実行例:

paste mode; Ctrl-C to cancel, Ctrl-D to finish === import network === nic = network.LAN() === nic.active(1) === === >>> nic.ifconfig() ('192.168.0.18', '255.255.255.0', '192.168.0.4', '192.168.0.4') >>> paste mode; Ctrl-C to cancel, Ctrl-D to finish === === def http_get(url): === import socket === _, _, host, path = url.split('/', 3) === addr = socket.getaddrinfo(host, 80)[0][-1] === s = socket.socket() === s.connect(addr) === s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8')) === while True: === data = s.recv(100) === if data: === print(str(data, 'utf8'), end='') === else: === break === s.close() === === print(http_get('http://micropython.org/ks/test.html')) === ===

REPL出力結果:

HTTP/1.1 200 OK Server: nginx/1.10.3 Date: Sun, 03 Jan 2021 09:54:59 GMT Content-Type: text/html Content-Length: 180 Last-Modified: Tue, 03 Dec 2013 00:16:26 GMT Connection: close Vary: Accept-Encoding ETag: "529d22da-b4" Accept-Ranges: bytes <!DOCTYPE html> <html lang="en"> <head> <title>Test</title> </head> <body> <h1>Test</h1> It's working if you can read this! </body> </html> None

sample2

目的のプログラム実行前に
以下を実行して ネットワークの有効化と
IPアドレスの確認を行なう。

import network nic = network.LAN() nic.active(1) nic.ifconfig()

httpserver.py

# 以下はESP8266のサンプルを差分のあるmachine関係をコメントアウトしたもの #import machine #pins = [machine.Pin(i, machine.Pin.IN) for i in (0, 2, 4, 5, 12, 13, 14, 15)] html = """<!DOCTYPE html> <html> <head> <title>ESP8266 Pins</title> </head> <body> <h1>ESP8266 Pins</h1> <table border="1"> <tr><th>Pin</th><th>Value</th></tr> %s </table> </body> </html> """ import socket addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1] s = socket.socket() s.bind(addr) s.listen(1) print('listening on', addr) while True: cl, addr = s.accept() print('client connected from', addr) cl_file = cl.makefile('rwb', 0) while True: line = cl_file.readline() if not line or line == b'\r\n': break #rows = ['<tr><td>%s</td><td>%d</td></tr>' % (str(p), p.value()) for p in pins] rows = ['<tr><td>ABC</td><td>123</td></tr>'] response = html % '\n'.join(rows) cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n') cl.send(response) cl.close()

REPL実行例:

>>> nic.active() True >>> nic.ifconfig() ('192.168.0.18', '255.255.255.0', '192.168.0.4', '192.168.0.4') >>> # 上の192.168.0.18がサーバーアドレスになるので覚えておいてサーバー起動後、このIPアドレスにアクセスする paste mode; Ctrl-C to cancel, Ctrl-D to finish === #import machine === #pins = [machine.Pin(i, machine.Pin.IN) for i in (0, 2, 4, 5, 12, 13, 14, 15)] === === html = """<!DOCTYPE html> === <html> === <head> <title>ESP8266 Pins</title> </head> === <body> <h1>ESP8266 Pins</h1> === <table border="1"> <tr><th>Pin</th><th>Value</th></tr> %s </table> === </body> === </html> === """ === === import socket === addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1] === === s = socket.socket() === s.bind(addr) === s.listen(1) === === print('listening on', addr) === === while True: === cl, addr = s.accept() === print('client connected from', addr) === cl_file = cl.makefile('rwb', 0) === while True: === line = cl_file.readline() === if not line or line == b'\r\n': === break === === #rows = ['<tr><td>%s</td><td>%d</td></tr>' % (str(p), p.value()) for p in pins] === rows = ['<tr><td>ABC</td><td>123</td></tr>'] === response = html % '\n'.join(rows) === cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n') === cl.send(response) === cl.close() === ===

上でサーバーを起動したら 確認したIPアドレス(192.128.0.xxx:80)で ブラウザー・アクセスする。

REPL出力例:

listening on ('0.0.0.0', 80) client connected from ('192.168.0.2', 56016) 44 229 client connected from ('192.168.0.2', 56018) 44 229

ウェブ画面表示例:

ESP8266 Pins

Pin Value
ABC 123

参考情報

https://docs.micropython.org/en/latest/esp8266/tutorial/network_basics.html
https://docs.micropython.org/en/latest/esp8266/tutorial/network_tcp.html

M5Stack MicroPython API調査記録 ネットワーク編
ESP32/ESP8266のMicroPythonでMQTTを使ってみた
ESP32のMicroPythonでOSC(Open Sound Control)で通信する

以上

続きを読む "MicroPython(F767ZI) Network Samples"

| | コメント (0)

2020年12月29日 (火)

MicroPython(F767ZI)でStartwars(AsciiArt)を動かす

2020/12/28:
初版

MicroPython(F767ZI) STARWARS

MicroPython(F767ZI) STARWARS

概要

MicroPython(F767ZI)でStartwars(AsciiArt)を動かす

本記事では「 NUCLEO F767ZI MicroPython Install(v2) 」 でビルドしたMicroPythonでStarwars(AsciiArt)を動かす。

接続

(1)本体ボード部分のUSBはホストPCに接続する
(2)デバッグ(st-link)ボード部分のUSBは電源供給用なのでACアダプターなどに接続する
(3)LANソケットは有線LANに接続する

デモ・プログラム

以下のプログラムをmicropythonのフラッシュに置く:

PYBFLASH/starwars.py

# starwars import network, socket nic = network.LAN() nic.active(1) addr = socket.getaddrinfo('towel.blinkenlights.nl', 23)[0][-1] s = socket.socket() s.connect(addr) while True: data = s.recv(1500) print(data.decode('utf-8'), end='')

「picocom /dev/ttyACM0 -b115200」を実行してREPLモードに入る:
(なにも表示されないようなら、本体ボードのリセット・ボタンを押す)

$ picocom /dev/ttyACM0 -b115200 <省略> import starwars #以下のようなAsciiArtのアニメが実行される: ........... @@@@@ @@@@@ ........... .......... @ @ @ @ .......... ........ @@@ @ @ .......... ....... @@ @ @ ......... ...... @@@@@@@ @@@@@ th ........ ..... ----------------------- ....... .... C E N T U R Y ....... ... ----------------------- ..... .. @@@@@ @@@@@ @ @ @@@@@ ... == @ @ @ @ @ == __||__ @ @@@@ @ @ __||__ | | @ @ @ @ @ | | _________|______|_____ @ @@@@@ @ @ @ _____|______|_________

参考情報

MicroPythonでSTM32のEthernetが正式サポートされました
5. ネットワーク - TCPソケット

Installing ST-Link v2 to flash STM32 targets on Linux

以上

続きを読む "MicroPython(F767ZI)でStartwars(AsciiArt)を動かす"

| | コメント (0)

2020年5月22日 (金)

NUCLEO-F767ZIにMicropythonをインストールする(v2)

2020/5/22

NUCLEO F767ZI MicroPython Install(v2)

NUCLEO F767ZI MicroPython Install(v2)

概要

「NUCLEO F767ZI」にMicropythonをインストールする方法について記載する (ホストPCとしてはubuntuを想定している)

事前準備

(1)書き込みツール(st-flash)のインストール

sudo apt install cmake sudo apt install libusb-1.0 git clone https://github.com/texane/stlink.git cd stlink make cd build/Release sudo make install sudo ldconfig

(2)ampyのインストール
AMPY_PORTは、自分の環境に合わせる。

pip install adafruit-ampy export AMPY_PORT=/dev/ttyACM0 export AMPY_BAUD=115200

(3)picocomのインストール

sudo apt-get install picocom

以上のうち、exportしているものは、.bashrcに登録することを勧める。

コンパイラのバージョンアップ

以下でインストールしたコンパイラが古くてビルドエラーが出たのでバージョンアップする。
sudo apt-get install gcc-arm-none-eabi

(1)以下のurlから最新版をダウンロードする:
https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads

解凍したものを以下のフォルダに置く:
$HOME/Downloads/gcc-arm-none-eabi-8-2019-q3-update

(2)パス設定
#古いコンパイラを削除する
sudo apt-get remove gcc-arm-none-eabi
#パスを設定する
export PATH=$PATH:$HOME/Downloads/gcc-arm-none-eabi-8-2019-q3-update/bin

ビルド手順

以下の手順で行なう:

mkdir mp_nucleo cd mp_nucleo git clone https://github.com/micropython/micropython.git cd micropython cd mpy-cross make cd .. cd ports/stm32 make submodules make BOARD=NUCLEO_F767ZI ls -l build-NUCLEO_F767ZI/firmware.* -rw-rw-r-- 1 xxxx xxxx 458749 5月 21 23:42 build-NUCLEO_F767ZI/firmware.dfu -rwxrwxr-x 1 xxxx xxxx 921348 5月 21 23:42 build-NUCLEO_F767ZI/firmware.elf -rw-rw-r-- 1 xxxx xxxx 1289515 5月 21 23:42 build-NUCLEO_F767ZI/firmware.hex -rw-rw-r-- 1 xxxx xxxx 1949998 5月 21 23:42 build-NUCLEO_F767ZI/firmware.map arm-none-eabi-objcopy -O binary build-NUCLEO_F767ZI/firmware.elf build-NUCLEO_F767ZI/firmware.bin ls -l build-NUCLEO_F767ZI/firmware.* -rwxrwxr-x 1 xxxx xxxx 574668 5月 21 23:44 build-NUCLEO_F767ZI/firmware.bin -rw-rw-r-- 1 xxxx xxxx 458749 5月 21 23:42 build-NUCLEO_F767ZI/firmware.dfu -rwxrwxr-x 1 xxxx xxxx 921348 5月 21 23:42 build-NUCLEO_F767ZI/firmware.elf -rw-rw-r-- 1 xxxx xxxx 1289515 5月 21 23:42 build-NUCLEO_F767ZI/firmware.hex -rw-rw-r-- 1 xxxx xxxx 1949998 5月 21 23:42 build-NUCLEO_F767ZI/firmware.map

書き込み手順

上でビルドしたbinをst-flashで書き込む

st-flash write build-NUCLEO_F767ZI/firmware.bin 0x8000000 #出力例: st-flash 1.6.0 2020-05-21T23:51:37 INFO common.c: Loading device parameters.... 2020-05-21T23:51:37 INFO common.c: Device connected is: F76xxx device, id 0x10016451 2020-05-21T23:51:37 INFO common.c: SRAM size: 0x80000 bytes (512 KiB), Flash: 0x200000 bytes (2048 KiB) in pages of 2048 bytes 2020-05-21T23:51:37 INFO common.c: Attempting to write 574668 (0x8c4cc) bytes to stm32 address: 134217728 (0x8000000) Flash page at addr: 0x08080000 erasedEraseFlash - Sector:0x6 Size:0x40000 2020-05-21T23:51:43 INFO common.c: Finished erasing 7 pages of 262144 (0x40000) bytes 2020-05-21T23:51:43 INFO common.c: Starting Flash write for F2/F4/L4 2020-05-21T23:51:43 INFO flash_loader.c: Successfully loaded flash loader in sram enabling 32-bit flash writes size: 32768 size: 32768 <省略> size: 32768 size: 17612 2020-05-21T23:51:52 INFO common.c: Starting verification of write complete 2020-05-21T23:51:57 INFO common.c: Flash written and verified! jolly good!

動作確認

picocomを使いボードとシリアルで通信する。
以下、通信(REPL)例:

$ picocom /dev/ttyACM0 -b115200 MicroPython v1.12-464-gcae77da on 2020-05-21; NUCLEO-F767ZI with STM32F767 Type "help()" for more information. >>> import os >>> os.uname() (sysname='pyboard', nodename='pyboard', release='1.12.0', version='v1.12-464-gcae77da on 2020-05-21', machine='NUCLEO-F767ZI with STM32F767') >>> >>> >>> list(5 * x + y for x in range(10) for y in [4, 2, 1]) [4, 2, 1, 9, 7, 6, 14, 12, 11, 19, 17, 16, 24, 22, 21, 29, 27, 26, 34, 32, 31, 39, 37, 36, 44, 42, 41, 49, 47, 46] >>> >>> import gc >>> gc.collect() >>> gc.mem_free() 273696 >>> >>> help('modules') __main__ math uasyncio/lock uos _onewire micropython uasyncio/stream urandom _uasyncio network ubinascii ure _webrepl onewire ucollections uselect builtins pyb ucryptolib usocket cmath stm uctypes ussl dht sys uerrno ustruct framebuf uarray uhashlib utime gc uasyncio/__init__ uheapq utimeq lcd160cr uasyncio/core uio uwebsocket lcd160cr_test uasyncio/event ujson uzlib lwip uasyncio/funcs umachine Plus any modules on the filesystem >>> # network,usocket,uwebsocketなどネットワーク関連が追加されていることが分かる。

ampy実行例

$ ampy -p /dev/ttyACM0 ls /flash $ ampy -p /dev/ttyACM0 ls /flash /flash/README.txt /flash/boot.py /flash/main.py /flash/pybcdc.inf $ ampy -p /dev/ttyACM0 get /flash/boot.py # boot.py -- run on boot-up # can run arbitrary Python, but best to keep it minimal import machine import pyb pyb.country('US') # ISO 3166-1 Alpha-2 code, eg US, GB, DE, AU #pyb.main('main.py') # main script to run after this one #pyb.usb_mode('VCP+MSC') # act as a serial and a storage device #pyb.usb_mode('VCP+HID') # act as a serial device and a mouse $ ampy -p /dev/ttyACM0 get /flash/main.py # main.py -- put your code here!

サンプルスクリプト

blink.py

# LED(1) // Green LED on board # LED(2) // Blue LED on board # LED(3) // Red LED on board while True: pyb.LED(1).on() pyb.LED(2).on() pyb.LED(3).on() pyb.delay(1000) pyb.LED(1).off() pyb.LED(2).off() pyb.LED(3).off() pyb.delay(250)

ボード上の3つのLEDが点滅する。

実行例:

$ ampy -p /dev/ttyACM0 run blink.py

この場合、flashにスクリプトを書き込まずに直接RAMで実行される。

ボードの電源オンで直接スクリプトを実行する場合は
以下のようにする。(blink.pyをmain.pyに上書きする)

$ ampy -p /dev/ttyACM0 put blink.py /flash/main.py

この書き込み後、リセットボタンを押すと自動的にスクリプトが動作する。

User USB

User_USBコネクタをホストPCとUSB接続するとPYBFLASHホルダが現れ、ここにMicroPythonのプログラムを置くことができる。 (電源はstlink側のUSBコネクタから供給されているので、stlink側のコネクタもホストPCに接続する必要がある)
ストレージとしてMicroPythonのプログラムを置くことができるので、この場合、ampyを使用する必要はない、

Perfomance Test

performanceTest.py

# Peformace Test import pyb def performanceTest(): millis = pyb.millis endTime = millis() + 10000 count = 0 while millis() < endTime: count += 1 print("Count: ", count) performanceTest()

実行結果としては以下のような数字になった:

>>> import performanceTest Count: 5676566 >>>

参照URL

Turtorial Examples for Nucleo-MicroPython

NUCLEO-F767ZI digikey
NUCLEO-F767ZI mbed

The MicroPython project
STM32 Nucleo Board STM32F446RE
Quick reference for the pyboard ampyを用いたMicroPythonのファイル操作とプログラム実行
MicroPython pyboard v1.1
新しいボードへMicroPythonを対応させる方法をざっくり解説

MicroPython Performance Test

以上

続きを読む "NUCLEO-F767ZIにMicropythonをインストールする(v2)"

| | コメント (0)

2020年5月16日 (土)

Nucleo-F303K8でADCの値をLCD(AQM0802)(i2c)に表示する(Arduino版)

2020/5/16

PlatformIO Nucleo-F303K8 AQM0802

PlatformIO Nucleo-F303K8 AQM0802

概要

Nucleo-F303K8でADCの値を以下のLCD(AQM0802)(i2c)に表示する。(Arduino版)
(ホストPCとしてはubuntuを想定している)

I2C接続小型LCDモジュール(8×2行)ピッチ変換キット(AE-AQM0802)
(基板上のプルアップは有効にしている)

PlatformIOのインストール

python3 -m venv pio_env source pio_env/bin/activate pip3 install platformio インストール後も、本ツールを使用する場合 同じディレクトリで以下を実行する: source pio_env/bin/activate # 「source」は、「.」でも良い

準備

以下を実行して、udevのrulesを登録する:

curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/master/scripts/99-platformio-udev.rules | sudo tee /etc/udev/rules.d/99-platformio-udev.rules sudo udevadm control --reload-rules sudo usermod -a -G dialout $USER sudo usermod -a -G plugdev $USER

接続

以下の表のように、ボードとLCDを接続する:

F303K8 AE-AQM0802
3V3 VDD
RESET NC
D5 SCL
D4 SDA
GND GND

NC: None Connection

テスト用プロジェクト sample-adc1 を作成/実行する

#ターゲットボードのtarget名を検索する # (ここではNucleo-F303K8を検索する) $ pio boards | grep -i F303K8 #出力例: nucleo_f303k8 STM32F303K8T6 72MHz 64KB 12KB ST Nucleo F303K8 nucleo_f303k8 #target名として「nucleo_f303k8」が判明した # プロジェクトnucleo-adc1 のディレクトリを作成する mkdir nucleo-adc1 cd sample-nucleo # 以下を実行して必要なファイルを作成する pio init --board nucleo_f303k8 # platformioを編集する nano platfomio.ini #以下の内容に編集する:
; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:nucleo_f303k8] platform = ststm32 board = nucleo_f303k8 framework = arduino upload_protocol = stlink debug_took = stlink

続き:

# LCD(ST7032)ライブラリをインストールする pio lib install 445 # テスト用のmain.cppを作成する nano src/main.cpp 以下の内容に編集する:
#include <Arduino.h> #include <Wire.h> #include <ST7032.h> // initialize the library with the numbers of the interface pins //LiquidCrystal lcd(12, 11, 5, 4, 3, 2); ST7032 lcd; int a0; int a1; int a2; int a3; void setup() { Serial.begin(115200); // setup serial // set up the LCD's number of columns and rows: lcd.begin(8, 2); lcd.setContrast(30); // should be changed to fit your board // Print a message to the LCD. lcd.print("HelloWLD"); Serial.println("Hello World."); } void loop() { a0 = analogRead(0); a1 = analogRead(1); a2 = analogRead(2); a3 = analogRead(3); // set the cursor to column 0, line 1 // (note: line 1 is the second row, since counting begins with 0): lcd.setCursor(0, 0); lcd.print("A0: "+String(a0)+" "); // +" " to clear garbage float v1 = a1 * 3.3 / 1023.0; lcd.setCursor(0, 1); lcd.print("V1: "+String(v1)+" "); // show voltage // Serial.println("A0: "+String(a0)); Serial.println("A1: "+String(a1)); Serial.println("A2: "+String(a2)); Serial.println("A3: "+String(a3)); Serial.println("------------------"); delay(500); }

続き:

# build pio run # ボードをホストPCに接続する # build&upload(flash) pio run -t upload # buildしないで書き込む場合は以下を実行する: pio run -t nobuild -t upload -v # -v は、詳細を表示するオプション # 注意:エラーが出て書き込めない場合 # いったん、USBの接続を切って再接続すると良いようだ。

書き込み後、LCDの1行目にA0の値が2行目にA1の値を電圧に変換した値が表示される。 シリアル出力(/dev/ttyACM0)には、A0,A1,A2,A3の値が出力される。

参考情報

Library for ST7032i display

NUCLEO-F303K8
開発ツールPlatformIOをcli(comand line interface)で使う(Nucleo版)

PlatformIO Core (CLI)

以上

続きを読む "Nucleo-F303K8でADCの値をLCD(AQM0802)(i2c)に表示する(Arduino版)"

| | コメント (0)

2020年5月11日 (月)

プログラミング言語RustをNucleo-F103RBボードで動かす(STM32F1xx)

2020/5/11

Rust STM32F1xx

Rust STM32F1xx

概要

プログラミング言語Rustを以下のNucleo-F103RBボードで動かす。 (ホストPCとしてはubuntuを想定している)

STM32 Nucleo Board STM32F103RB

関連ツールのインストール

以下で必要なツールをインスールする:
(0)rustツールのインストール

curl https://sh.rustup.rs -sSf | sh

(1)書き込みツール(st-flash)のインストール

sudo apt install cmake sudo apt install libusb-1.0 git clone https://github.com/texane/stlink.git cd stlink make cd build/Release sudo make install sudo ldconfig

(2)Cコンパイラのバージョンアップ
binを作成するのに、これに含まれるツールを使用するのでインストールする

以下でインストールしたコンパイラが古くてビルドエラーが出たのでバージョンアップする。 sudo apt-get install gcc-arm-none-eabi (1)以下のurlから最新版をダウンロードする: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads 解凍したものを以下のフォルダに置く: $HOME/Downloads/gcc-arm-none-eabi-8-2019-q3-update (2)パス設定 #古いコンパイラを削除する sudo apt-get remove gcc-arm-none-eabi #パスを設定する export PATH=$PATH:$HOME/Downloads/gcc-arm-none-eabi-8-2019-q3-update/bin

exportは、.bashrcに登録する

(3)その他の必要ツールのインストール

sudo apt-get install openocd sudo apt-get install picocom

sample#0(blinky)を実行する

最初の設定のターゲットボードがblue-pillになっているので、Nucleo-F103RBの設定に変更して動かす。

(1)rust関連の設定

git clone https://github.com/stm32-rs/stm32f1xx-hal.git cd stm32f1xx-hal rustup default nightly rustup target add thumbv7m-none-eabi

(2)memory.xの変更
以下のように変更する:
(Flash容量を64Kから128Kに変更する)

cat memory.x /* Linker script for the NUCLEO-F103RB */ MEMORY { FLASH : ORIGIN = 0x08000000, LENGTH = 128K RAM : ORIGIN = 0x20000000, LENGTH = 20K }

(3)examples/blinky.rsの変更
(オンボードのLEDのポートをpc13からpa5に変更する)

37行付近: let mut gpioc = dp.GPIOC.split(&mut rcc.apb2); → let mut gpioa = dp.GPIOA.split(&mut rcc.apb2);
40行付近: let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh); → let mut led = gpioa.pa5.into_push_pull_output(&mut gpioa.crl);

点滅周期を変更したい場合、以下のような変更を行なう:

42行付近: let mut timer = Timer::syst(cp.SYST, &clocks).start_count_down(1.hz()); → let mut timer = Timer::syst(cp.SYST, &clocks).start_count_down(10.hz());

(4)ビルド

cargo clean cargo build --example blinky --release --features=stm32f103

(5)elfをbinに変換する

arm-none-eabi-objcopy -O binary target/thumbv7m-none-eabi/release/examples/blinky F103_blinky.bin

(6)書き込む

#ボートとホストPCをUSBで接続する st-flash write F103_blinky.bin 0x8000000

ボードのグリーンLED(LD2)が点滅すれば動作としてはOKとなる。

その他のサンプル

以下に、その他のサンプルがあるのでボードに依存するポートなどを変更すれば、Nucleo-F103RBで動作すると思われる。

$ ls examples adc-dma-circ.rs itm.rs serial-dma-peek.rs adc-dma-rx.rs led.rs serial-dma-rx.rs adc.rs mfrc522.rs serial-dma-tx.rs adc_temperature.rs motor.rs.disabled serial-fmt.rs blinky.rs mpu9250.rs.disabled serial.rs blinky_generic.rs nojtag.rs serial_config.rs blinky_rtc.rs panics.rs spi-dma.rs blinky_timer_irq.rs pwm.rs timer-interrupt-rtfm.rs delay.rs pwm_custom.rs usb_serial.rs enc28j60-coap.rs.disabled pwm_input.rs usb_serial_interrupt.rs enc28j60.rs.disabled qei.rs usb_serial_rtfm.rs exti.rs rtc.rs hello.rs serial-dma-circ.rs

ターゲット情報

Cortex-Mプロセッサとターゲットは以下の対応になっている:

thumbv6m-none-eabi - Cortex-M0 と M0+ thumbv7m-none-eabi - Cortex M3 thumbv7em-none-eabi - Cortex M4 と M7、FPU なし thumbv7em-none-eabihf - Cortex M4 と M7、FPU あり

参照情報

STM32 Nucleo Board STM32F103RB

The Embedded Rust Book
The Embedded Rust Book - Semihosting

UbuntuにRustをインストールする

以上

続きを読む "プログラミング言語RustをNucleo-F103RBボードで動かす(STM32F1xx)"

| | コメント (0)

2020年5月 8日 (金)

プログラミング言語RustをNucleo-F401REボードで動かす(STM32F4xxx)

2020/5/8

Rust STM32F4xx

Rust STM32F4xx

概要

プログラミング言語Rustを以下のNucleo-F401REボードで動かす。 (ホストPCとしてはubuntuを想定している)

STM32 Nucleo Board STM32F401

関連ツールのインストール

以下で必要なツールをインスールする:
(0)rustツールのインストール

curl https://sh.rustup.rs -sSf | sh

(1)書き込みツール(st-flash)のインストール

sudo apt install cmake sudo apt install libusb-1.0 git clone https://github.com/texane/stlink.git cd stlink make cd build/Release sudo make install sudo ldconfig

(2)Cコンパイラのバージョンアップ
binを作成するのに、これに含まれるツールを使用するのでインストールする

以下でインストールしたコンパイラが古くてビルドエラーが出たのでバージョンアップする。 sudo apt-get install gcc-arm-none-eabi (1)以下のurlから最新版をダウンロードする: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads 解凍したものを以下のフォルダに置く: $HOME/Downloads/gcc-arm-none-eabi-8-2019-q3-update (2)パス設定 #古いコンパイラを削除する sudo apt-get remove gcc-arm-none-eabi #パスを設定する export PATH=$PATH:$HOME/Downloads/gcc-arm-none-eabi-8-2019-q3-update/bin

exportは、.bashrcに登録する

(3)その他の必要ツールのインストール

sudo apt-get install openocd sudo apt-get install picocom

sample#0( gpio_hal_blinky)をビルドして実行する

最初の設定がターゲットボードとしてSTM32F401REになっているので、そのまま動かす。

git clone https://github.com/jkristell/nucleo-f401re.git cd nucleo-f401re rustup target add thumbv7em-none-eabihf cargo clean cargo build --example gpio_hal_blinky arm-none-eabi-objcopy -O binary target/thumbv7em-none-eabihf/debug/examples/gpio_hal_blinky firmware.bin #ボードのUSBコネクタをホストPCに接続する st-flash write firmware.bin 0x8000000

正常に動作した場合、ボードのグリーンLEDが点滅する。

sample#1(delay-blinky)をビルドして実行する

上とは別のgitから持ってきたものを実行してみる。
ターゲットボードをSTM32F401REにするために memory.xを以下に変更する。
(gitでダウンロード後)

memory.x

MEMORY { /* NOTE K = KiBi = 1024 bytes */ FLASH : ORIGIN = 0x08000000, LENGTH = 512K RAM : ORIGIN = 0x20000000, LENGTH = 96K } /* This is where the call stack will be allocated. */ /* The stack is of the full descending type. */ /* NOTE Do NOT modify `_stack_start` unless you know what you are doing */ _stack_start = ORIGIN(RAM) + LENGTH(RAM);

以下の手順を実行する。
(memory.xは、上の内容に変更すること)

git clone https://github.com/stm32-rs/stm32f4xx-hal.git cd stm32f4xx-hal rustup target add thumbv7em-none-eabihf cargo clean cargo build --example delay-blinky --release --features="rt stm32f411" # elfをbinに変換する arm-none-eabi-objcopy -O binary target/thumbv7em-none-eabihf/release/examples/delay-blinky firmare.bin # binを書き込む #ボードのUSBコネクタをホストPCに接続する st-flash write firmware.bin 0x8000000 以下のようなエラーがでて書き込めない場合、OpenOCDで書き込む。 $ st-flash write firmware.bin 0x8000000 st-flash 1.6.0 2020-05-08T20:53:06 INFO common.c: Loading device parameters.... 2020-05-08T20:53:06 INFO common.c: Device connected is: F4 device (Dynamic Efficency), id 0x10006433 2020-05-08T20:53:06 INFO common.c: SRAM size: 0x18000 bytes (96 KiB), Flash: 0x80000 bytes (512 KiB) in pages of 16384 bytes open(firmware.bin) == -1 2020-05-08T20:53:06 ERROR common.c: map_file() == -1 stlink_fwrite_flash() == -1

正常に動作した場合、ボードのグリーンLEDが点滅する。(sample#0と同様)

OpenOCDによる書き込み

今までは、st-flashで書き込んだが、以下の手順でOpenOCDで書き込むこともできる。
別の端末で以下を実行する:

openocd -f interface/stlink-v2-1.cfg -f target/stm32f4x.cfg

エラーになった場合、stlinkのファームウェアが古い可能性があるので そのときは「tlink-v2-1.cfg」を「tlink-v2.cfg」に変更して実行する。 実行するとopenocdがサーバーとして動作して、gdb(やtelnet)を待ち受ける状態になる。

buildの作業で使っている端末で以下を実行する: (delay-blinkyの場合)

cargo run --example delay-blinky --release --features="rt stm32f411" #ビルドが完了すると自動的にgdbが起動するので #以下の手順でopenocdと接続してファームウェアを書き込む。 (gdb) target remote :3333 Remote debugging using :3333 0x00000000 in ?? () (gdb) load Loading section .vector_table, size 0x198 lma 0x8000000 Loading section .text, size 0x50c lma 0x8000198 Loading section .rodata, size 0x13c lma 0x80006b0 Start address 0x800055c, load size 2016 Transfer rate: 3 KB/sec, 672 bytes/write. (gdb) quit Quit anyway? (y or n) y #[reset]ボタンは無効になっているようなので、 #USB接続を切って電源をオフした後、再度、USBを接続して再起動すること

openocdの起動用スクリプトを設定すると書き込みを自動化できるようだが、ここでは、それを使用していない。

ターゲット情報

Cortex-Mプロセッサとターゲットは以下の対応になっている:

thumbv6m-none-eabi - Cortex-M0 と M0+ thumbv7m-none-eabi - Cortex M3 thumbv7em-none-eabi - Cortex M4 と M7、FPU なし thumbv7em-none-eabihf - Cortex M4 と M7、FPU あり

参照情報

STM32 Nucleo Board STM32F401

The Embedded Rust Book
The Embedded Rust Book - Semihosting

UbuntuにRustをインストールする

以上

続きを読む "プログラミング言語RustをNucleo-F401REボードで動かす(STM32F4xxx)"

| | コメント (0)

2020年5月 5日 (火)

Nucleo-F303K8でLCD(AQM0802)(i2c)を動かす

2020/5/5

PlatformIO Nucleo AQM0802

PlatformIO Nucleo AQM0802

概要

Nucleo-F303K8で以下のLCD(AQM0802)(i2c)を動かす。(Arduino版)
(ホストPCとしてはubuntuを想定している)

I2C接続小型LCDモジュール(8×2行)ピッチ変換キット(AE-AQM0802)
(基板上のプルアップは有効にしている)

PlatformIOのインストール

python3 -m venv pio_env source pio_env/bin/activate pip3 install platformio インストール後も、本ツールを使用する場合 同じディレクトリで以下を実行する: source pio_env/bin/activate # 「source」は、「.」でも良い

準備

以下を実行して、udevのrulesを登録する:

curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/master/scripts/99-platformio-udev.rules | sudo tee /etc/udev/rules.d/99-platformio-udev.rules sudo udevadm control --reload-rules sudo usermod -a -G dialout $USER sudo usermod -a -G plugdev $USER

接続

以下の表のように、ボードとLCDを接続する:

F303K8 AE-AQM0802
3V3 VDD
RESET NC
D5 SCL
D4 SDA
GND GND

NC: None Connection

テスト用プロジェクト sample-nucleo を作成/実行する

#ターゲットボードのtarget名を検索する # (ここではNucleo-F303K8を検索する) $ pio boards | grep -i F303K8 #出力例: nucleo_f303k8 STM32F303K8T6 72MHz 64KB 12KB ST Nucleo F303K8 nucleo_f303k8 #target名として「nucleo_f303k8」が判明した # プロジェクトsample-nucleo のディレクトリを作成する mkdir sample-nucleo cd sample-nucleo # 以下を実行して必要なファイルを作成する pio init --board nucleo_f303k8 # platformioを編集する nano platfomio.ini #以下の内容に編集する:
; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:nucleo_f303k8] platform = ststm32 board = nucleo_f303k8 framework = arduino upload_protocol = stlink debug_took = stlink

続き:

# LCD(ST7032)ライブラリをインストールする pio lib install 445 # テスト用のmain.cppを作成する nano src/main.cpp 以下の内容に編集する:
#include <Arduino.h> #include <Wire.h> #include <ST7032.h> // initialize the library with the numbers of the interface pins //LiquidCrystal lcd(12, 11, 5, 4, 3, 2); ST7032 lcd; void setup() { // set up the LCD's number of columns and rows: lcd.begin(8, 2); lcd.setContrast(30); // should be changed to fit your board // Print a message to the LCD. lcd.print("HelloWLD"); } void loop() { // set the cursor to column 0, line 1 // (note: line 1 is the second row, since counting begins with 0): lcd.setCursor(0, 1); // print the number of seconds since reset: lcd.print(String(millis()/1000)+" sec"); }

続き:

# build pio run # ボードをホストPCに接続する # build&upload(flash) pio run -t upload # buildしないで書き込む場合は以下を実行する: pio run -t nobuild -t upload -v # -v は、詳細を表示するオプション # 注意:エラーが出て書き込めない場合 # いったん、USBの接続を切って再接続すると良いようだ。

書き込み後、LCDに表示がでればOKである。

参考情報

Library for ST7032i display

NUCLEO-F303K8
開発ツールPlatformIOをcli(comand line interface)で使う(Nucleo版)

PlatformIO Core (CLI)

以上

続きを読む "Nucleo-F303K8でLCD(AQM0802)(i2c)を動かす"

| | コメント (0)

2020年3月24日 (火)

CircuitPython/MicroPythonに温度センサーTMP102(i2c)を接続する

2020/2/24

CircuitPython TMP102(i2c)

CircuitPython TMP102(i2c)

概要

CircuitPython/MicroPythonに以下の温度センサーTMP102(i2c)を接続する。
(ホストPCとしてはubuntuを想定している)

TMP102搭載 デジタル温度センサモジュール

接続

以下のように接続する。

Wiring:

TMP102 Teensy4.0(CircuitPython)
SCL D19(SCL0)
SDA D18(SDA0)
VCC 3.3V
GND GND

該当モジュールのインストール

Module Install:

git clone https://github.com/khoulihan/micropython-tmp102.git cd micropython-tmp102 cp _tmp102.py tmp102_cpy.py # Patch  次項目の内容のようにtmp102_cpy.pyにパッチする。 # copy related modules cp tmp102_cpy.py CIRCUTPY/lib/

tmp102_cpy.pyの内容:
「#m」を含む行が修正行になる。
(コメントアウト行も含む)

# tmp102_cpy.py # 2020/3/24 modification for CircutPython REGISTER_TEMP = 0 REGISTER_CONFIG = 1 EXTENDED_MODE_BIT = 0x10 def _set_bit(b, mask): return b | mask def _clear_bit(b, mask): return b & ~mask def _set_bit_for_boolean(b, mask, val): if val: return _set_bit(b, mask) else: return _clear_bit(b, mask) class Tmp102(object): def __init__(self, bus, address, temperature_convertor=None, **kwargs): # There doesn't seem to be a way to check this at present. The first # send or recv should throw an error instead if the mode is incorrect. #if not bus.in_master_mode(): # raise ValueError('bus must be in master mode') self.bus = bus self.address = address self.temperature_convertor = temperature_convertor # The register defaults to the temperature. self._last_write_register = REGISTER_TEMP self._extended_mode = False if len(kwargs) > 0: # Apply the passed in settings config = bytearray(self._get_config()) for key, value in kwargs.items(): applyfunc = '_apply_{}'.format(key) config = getattr(self, applyfunc)(config, value) self._set_config(config) if 'thermostat_high_temperature' in kwargs: self.thermostat_high_temperature = kwargs['thermostat_high_temperature'] if 'thermostat_low_temperature' in kwargs: self.thermostat_low_temperature = kwargs['thermostat_low_temperature'] def _read_register(self, register): val = bytearray(2) #m if register != self._last_write_register: # Reads come from the last register written. self._write_register(register) try: #m val = self.bus.readfrom(self.address, 2) self.bus.readfrom_into(self.address, val) except AttributeError: #m val = self.bus.recv(2, addr=self.address) self.bus.readfrom_into(self.address, val) return val def _write_register(self, register, value=None): bvals = bytearray() bvals.append(register) if value is not None: for val in value: bvals.append(val) try: self.bus.writeto(self.address, bvals) except AttributeError: self.bus.send(bvals, addr=self.address) self._last_write_register = register def _get_config(self): return self._read_register(REGISTER_CONFIG) def _set_config(self, config): self._write_register(REGISTER_CONFIG, config) self._extended_mode = config[1] & EXTENDED_MODE_BIT def _read_temperature_register(self, register): rt = self._read_register(register) lo = rt[1] hi = rt[0] negative = (hi >> 7) == 1 shift = 4 if self._extended_mode: shift = 3 if not negative: t = (((hi * 256) + lo) >> shift) * 0.0625 else: remove_bit = 0b011111111111 if self._extended_mode: remove_bit = 0b0111111111111 ti = (((hi * 256) + lo) >> shift) # Complement, but remove the first bit. ti = ~ti & remove_bit t = -(ti * 0.0625) if self.temperature_convertor is not None: t = self.temperature_convertor.convert_to(t) return rt, t @property def temperature(self): """ The most recently recorded temperature. """ rt, t = self._read_temperature_register(REGISTER_TEMP) return t

CircuitPythonとMicroPythonに共通してあるi2c.writeto,i2c.readfrom_intoを使用しているので、両方に対応できている。

Demo Script(動作確認)

import time import busio import board i2c = busio.I2C(board.SCL, board.SDA) i2c.try_lock() from tmp102_cpy import Tmp102 sensor = Tmp102(i2c, 0x48) while True: print('Temperature: {0:.1f}'.format(sensor.temperature)) time.sleep(2)

MicroPython(Nucleo)の場合

該当モジュールtmp102_cpy.pyが、CircuitPython/MicroPython両方に対応しているので そのまま/flashに書き込むだけでパッチなどは必要ない。

Demo Script:

import time from machine import Pin, I2C i2c = I2C(1) from tmp102_cpy import Tmp102 sensor = Tmp102(i2c, 0x48) while True: print('Temperature: {0:.1f}'.format(sensor.temperature)) time.sleep(2)

デバイスなどの初期化以外はCircuitPythonのものと全く同じ。

参照情報

TMP102搭載 デジタル温度センサモジュール

ESP8266のMicroPythonに温度センサーTMP102(i2c)を接続する

Turtorial Examples for CircuitPython(Teensy4.0)
Teensy4.0にCircuitPythonをインストールする

Turtorial Examples for Nucleo-MicroPytho
NUCLEO-F446REにMicropythonをインストールする(v2)

CircuitPython 5.0.x - I2C

以上

続きを読む "CircuitPython/MicroPythonに温度センサーTMP102(i2c)を接続する"

| | コメント (0)

CircuitPython/MicroPythonにi2c-LCD(AE-AQM0802)を接続する

2020/2/24

CircuitPython AE-AQM0802(i2c)

CircuitPython AE-AQM0802(i2c)

概要

CircuitPython/MicroPythonに以下のi2c-LCD(AE-AQM0802)を接続する。
(ホストPCとしてはubuntuを想定している)

I2C接続小型キャラクタLCDモジュール(8×2行)完成品

接続

以下のように接続する。

Wiring:

AE-AQM0802 Teensy4.0(CircuitPython)
SCL D19(SCL0)
SDA D18(SDA0)
VCC 3.3V
GND GND

該当モジュールのインストール

Module Install:

# 以下のリンクからダウンロードする wget https://beta-notes.way-nifty.com/blog/files/st7032i.py # rename mv st7032i.py ST7032i.py # copy related modules cp ST7032i.py CIRCUTPY/lib/

ST7032.pyの内容

# ST7032i.py # this module is forked from the following souces: # https://gist.github.com/boochow/6ffd0c939abbcc1a9c62bf6ab6b60cef#file-st7032i-py # https://qiita.com/f_nishio/items/b1b99b4763993a9239c6 # 2020/3/23 patch for contrast from micropython import const #from machine import Pin, I2C import time CLEAR_DISPLAY = const(0x01) RETURN_HOME = const(0x02) SET_ENTRY_MODE = const(0x04) DISPLAY_ON = const(0x0C) FUNCTION_SET = const(0x20) OSC_FREQUENCY = const(0x10) POW_ICON_CONTRAST = const(0x50) FOLLOWER = const(0x60) SET_CONTRAST = const(0x70) class ST7032i(object): def __init__(self, i2c, addr=0x3e): self.i2c = i2c self.addr = addr self.buf = bytearray(2) self.init_display() def write_cmd(self, cmd): self.buf[0] = 0x00 self.buf[1] = cmd self.i2c.writeto(self.addr, self.buf) def write_data(self, char): self.buf[0] = 0x40 self.buf[1] = char self.i2c.writeto(self.addr, self.buf) def init_display(self): """ for cmd in ( # data is 8 bits | 2 lines mode FUNCTION_SET | 0x10 | 0x08, # select Instruction table 1 FUNCTION_SET | 0x10 | 0x08 | 0x01, # BS=1 (1/4 bias), OSC frequency=183Hz OSC_FREQUENCY | 0x08 | 0x04, # ICON on, Booster on, Contrast(upper 2bits) = 10 POW_ICON_CONTRAST | 0x08 | 0x04 | 0x02, # Contrast(lower 4bits) = 1000 SET_CONTRAST | 0x08, # Follower on, amplify ratio = 4/8 FOLLOWER | 0x08 | 0x04 ): self.write_cmd(cmd) time.sleep(0.2) for cmd in ( DISPLAY_ON, CLEAR_DISPLAY, # Left to right, no shift SET_ENTRY_MODE | 0x02 ): self.write_cmd(cmd) """ # 2020/3/23: patched init self.i2c.writeto(self.addr, b'\x00\x38') self.i2c.writeto(self.addr, b'\x00\x39') self.i2c.writeto(self.addr, b'\x00\x14') self.i2c.writeto(self.addr, b'\x00\x73') self.i2c.writeto(self.addr, b'\x00\x56') self.i2c.writeto(self.addr, b'\x00\x6c') self.i2c.writeto(self.addr, b'\x00\x38') self.i2c.writeto(self.addr, b'\x00\x0C') self.i2c.writeto(self.addr, b'\x00\x01') def clear(self): """ Clear display and return to home position. """ self.write_cmd(0x01) # clear display time.sleep(0.01) # wait time > 1.08 ms self.write_cmd(0x02) # return home time.sleep(0.01) # wait time > 1.08 ms def return_home(self): """ return to home """ self.write_cmd(0x02) # return home time.sleep(0.01) # wait time > 1.08 ms def set_contrast(self, contrast): """ Set contrast (0 - 15). """ if contrast < 0: contrast = 0 if contrast > 0x0f: contrast = 0x0f self.write_cmd(0x39) self.write_cmd(0x70 + contrast) def set_cursor(self, x, y): """ set cursor location (address counter).""" if x < 0: x = 0 if y < 0: y = 0 ddram_addr = y * 0x40 + x self.write_cmd(0x80 + ddram_addr) # set DDRAM address def set_entry_mode(self, increment, shift): mode = 0x04 if (increment): mode = mode + 2 if (shift): mode = mode + 1 self.write_cmd(mode) def print(self, str, wait = 0): for c in str: self.write_data(ord(c)) if (wait > 0): time.sleep(wait) if __name__ == '__main__': # MicroPython #from machine import Pin, I2C #i2c=I2C(1) # CircuitPython #import board #import busio # Create the I2C interface. #i2c = busio.I2C(board.SCL, board.SDA) #i2c.try_lock() import time from ST7032i import ST7032i lcd = ST7032i(i2c) lcd.set_entry_mode(False, False) lcd.set_contrast(1) lcd.clear() # show characters in 2 lines lcd.set_cursor(0, 0) lcd.print('1234') lcd.set_cursor(4, 1) lcd.print('5678') # LCD clear time.sleep(2) lcd.clear() # ticker lcd.set_entry_mode(True, True) lcd.set_cursor(8, 0) lcd.print('Hello, this is a ticker message.', 0.5)

CircuitPythonとMicroPythonに共通してあるi2c.writetoのみを使用しているので、両方に対応できている。。

Demo Script(動作確認)

import time import board import busio # Create the I2C interface. i2c = busio.I2C(board.SCL, board.SDA) i2c.try_lock() from ST7032i import ST7032i lcd = ST7032i(i2c) lcd.set_entry_mode(False, False) lcd.set_contrast(1) lcd.clear() # show characters in 2 lines lcd.set_cursor(0, 0) lcd.print('1234') lcd.set_cursor(4, 1) lcd.print('5678') # LCD clear time.sleep(2) lcd.clear() # ticker lcd.set_entry_mode(True, True) lcd.set_cursor(8, 0) lcd.print('Hello, this is a ticker message.', 0.5)

MicroPython(Nucleo)の場合

該当モジュールST7032i.pyが、CircuitPython/MicroPython両方に対応しているので そのまま/flashに書き込むだけでパッチなどは必要ない。

Module Install:

wget https://beta-notes.way-nifty.com/blog/files/st7032i.py mv st7032i.py ST7032i.py ampy put ST7032.py

Demo Script:

import time from machine import Pin, I2C # Create the I2C interface. i2c = I2C(1) from ST7032i import ST7032i lcd = ST7032i(i2c) lcd.set_entry_mode(False, False) lcd.set_contrast(1) lcd.clear() # show characters in 2 lines lcd.set_cursor(0, 0) lcd.print('1234') lcd.set_cursor(4, 1) lcd.print('5678') # LCD clear time.sleep(2) lcd.clear() # ticker lcd.set_entry_mode(True, True) lcd.set_cursor(8, 0) lcd.print('Hello, this is a ticker message.', 0.5)

デバイスなどの初期化以外はCircuitPythonのものと全く同じ。

参照情報

I2C接続小型キャラクタLCDモジュール(8×2行)完成品
I2C接続小型キャラクタLCDモジュール(8×2行)の質問と回答

ESP32 + MicroPythonでLCDモジュールに文字を表示させてみた
WiringPi-Pythonを使ってAQM0802A / ST7032i LCD表示
MicroPythonでAE-AQM0802を使ってみる。
"MicroPythonでAE-AQM0802を使ってみる"の続き

Turtorial Examples for CircuitPython(Teensy4.0)
Teensy4.0にCircuitPythonをインストールする

Turtorial Examples for Nucleo-MicroPytho
NUCLEO-F446REにMicropythonをインストールする(v2)

以上

続きを読む "CircuitPython/MicroPythonにi2c-LCD(AE-AQM0802)を接続する"

| | コメント (0)