JH7UBCブログ

アマチュア無線 電子工作 家庭菜園など趣味のブログです

Raspberry Pi Pico CircuitPython I2C LCD1602表示テスト

2022-04-28 07:32:41 | Raspberry Pi Pico
 Raspberry Pi Pico + CircuitPython + MuIDE環境で、I2Cインターフェース付きLCD1602の表示テストをします。

 電子工作において、LCD1602表示器は、まだまだ重要な表示パーツです。最近は、I2Cインターフェース付きのものが多く使われています。

 Raspberry Pi Pico + MicroPythonでの表示テストは既にこのブログに記事を書きました。記事はこちら

 今回は、CIrcuitPythonでの表示テストです。スクリプトはMicroPythonのものをCircuitPython用に書き換えて利用します。

 回路図です。
 I2Cは、SCL=GP15,SDA=GP14とし、I2Cの電圧レベル変換用にPCA9306モジュールを使っています。(このモジュールを使わず、直接LCD1602をPicoに接続しても使えますが、安全のため電圧変換モジュールを使用しています。)

 スクリプトです。
 1行目に「Hello World!」を表示し、2行目に数字を0からカウントアップして表示します。
-------------------------------------------------------------------------
"""
Raspberry Pi Pico CircuitPython I2C LCD1602 test
2022.4.28
JH7UBC Keiji Hata
"""

from board import *
import busio
from time import sleep

i2c=busio.I2C(GP15,GP14)

LCD_addr=0x27
LCD_EN=0x04 #LCD Enable
LCD_BL=0x08 #Back Light
CMD=0x00 #command mode
CHR=0x01 #character mode
LINE1=0x80 #Line1 top address
LINE2=0xC0 #Line2 top address

buf=bytearray(2)

while not i2c.try_lock():
         pass

def LCD_write(bits,mode):
     #High 4bits
     data=(bits & 0xF0)|mode
     buf[0]=data|LCD_EN|LCD_BL
     buf[1]=data|LCD_BL
     i2c.writeto(LCD_addr,buf)
     sleep(0.0001)#wait 100us
     #Low 4bits
     data=((bits<<4)&0xF0)|mode
     buf[0]=data|LCD_EN|LCD_BL
     buf[1]=data|LCD_BL
     i2c.writeto(LCD_addr,buf)
     sleep(0.0001)#wait 100us

def LCD_init():
     LCD_write(0x33,CMD)#8bit mode 0x03を2回送る
     LCD_write(0x32,CMD)#8bit mode,4bit mode 0x02を送る
     LCD_write(0x06,CMD)#Entry modeセット
     LCD_write(0x0C,CMD)#表示ON,カーソルOFF,カーソル点滅OFF
     LCD_write(0x28,CMD)#2桁表示,7ドットモード
     LCD_write(0x01,CMD)#Display clear
     sleep(0.002)#waite 2ms

def LCD_clear():
     LCD_write(0x01,CMD)
     sleep(0.002)#waite 2ms

def LCD_home():
     LCD_write(0x02,CMD)
     sleep(0.002)#waite 2ms

def LCD_cursor(x,y):
     if y==0:
         LCD_write(LINE1+x,CMD)
     if y==1:
        LCD_write(LINE2+x,CMD)

def LCD_print(str):
     for c in str:
        LCD_write(ord(c),CHR)

LCD_init()

LCD_clear()
LCD_home()
LCD_cursor(1,0)
LCD_print("Hello World!")
count=0

while True:
     LCD_cursor(1,1)
     LCD_print(str(count))
     count=count+1
     sleep(1)

-------------------------------------------------------------------------
 基本的にMicroPythonのスクリプトと同じなのですが、importの部分をCircuitPythonに合わせて実行すると
「RuntimeError: Function requires lock」というエラーが出てしまいました。
 どうやらCircuitPythonでは、
while not i2c.try_lock():
         pass
という文を入れて、I2C回路接続をロックすることが必要なようです。
これを入れて無事スクリプトが動き、文字がLCD1602に表示されました。
 
ブレッドボードです。


花いっぱい

2022-04-27 13:19:27 | 家庭菜園と花
 昨日、会津若松市北会津町の「ニヘイ」さんから、花の苗と鉢植の花を買ってきました。さっそく今日プランターや鉢に植え替えました。

 ベゴニア・センパフローレンス

 ベゴニア(ピンク)、ネモフィラ、パンジー(黄色)

カーネーションの一種ナスビアン

 そして、その辺に自然に生えたビオラを寄せ植えにしました。

 これで、しばらくの間(夏まで)楽しめそうです。


Raspberry Pi Pico CircuitPython OLED表示テスト

2022-04-25 17:37:35 | Raspberry Pi Pico
 Raspberry Pi Pico + CircuitPython + MuIDE環境でOLEDの表示テストをします。
 接続回路図です。
 OLEDは、I2C接続で,SCL=GP21,SDA=20としました。


 まず、OLED表示用のライブラリをCircuitPythonのLibrariesダウンロードページからダウンロードします。赤丸で囲んだmpyファイルをダウンロードします。


 zipファイルを解凍し、解凍したフォルダ内のlibフォルダから、
 adafruit_ssd1306.mpy
 adafruit_framebuf.mpy
をPico(CIRCUITPY)のlibフォルダにコピーします。
 次に、解凍したフォルダ内のexamplesフォルダの中から
 font5x8.binをPico(CIRCUITPY)のルートにコピーします。
 これで、準備完了です。

 スクリプトです。(code.py)
 このライブラリ(ssd1306)は、文字と簡単なグラフィックスを描くことができます。
「Hello World!」と簡単なグラフィックスを表示し、左下に数字をカウントアップして表示します。
----------------------------------------------------------------
"""
Raspberry Pi Pico OLED test
2022.4.25
JH7UBC Keiji Hata
"""
import board
import busio
import time

# Import the SSD1306 module.
import adafruit_ssd1306

# Create the I2C interface.
i2c = busio.I2C(board.GP21, board.GP20)

oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c)
#OLED clear
oled.fill(0)

#display rectangle and "Hello World!"
oled.rect(10,0,100,18,1)
oled.show()
oled.text("Hello World!",20,5,1)
oled.show()

oled.pixel(10,25,1)
oled.show()

oled.hline(30,30,20,1)
oled.show()

oled.vline(50,35,20,1)
oled.show()

oled.line(55,30,75,50,1)
oled.show()

oled.fill_rect(80,30,20,20,1)
oled.show()

n=0

while True:
     oled.fill_rect(20,40,30,10,0)
     oled.show()
     oled.text(str(n),20,40,1)
     oled.show()
    n = n + 1
     time.sleep(1)
----------------------------------------------------------------
 文字表示とグラフィックスの説明です。
 c=1で表示、c=0で消去です。
 oled.text(" ",x,y,c) x,yを始点として文字を表示します。
 oled.pixel(x,y,c)    x,yにdotを表示します。
 oled.hline(x,y,w,c)  x,yを始点として長さwの水平な線を引きます。
 oled.vline(x,y,h,c)  x,yを始点として長さwの垂直な線を引きます。
 oled.line(x1,y1,x2,y2,c) x1,y1からx2,y2まで線を引きます。
 oled.rect(x,y,w,h,c)  x,yを始点(左上)として、幅w、高さhの四角形を描きます。
 oled.fill_rect (x,y,w,h,c)  x,yを始点(左上)として、幅w、高さhの四角形を描き、中を塗りつぶします。
 oled.fill(c) 画面全体をc色で塗りつぶします。つまり、c=0で全画面クリア、c=1で全画面白になります。

 ブレッドボードです。


Raspberry Pi Pico CircuitPython I2C scaner とI2C LCD AQM0802A表示テスト

2022-04-24 18:55:15 | Raspberry Pi Pico
 Raspberry Pi Pico + CircuitPython + Mu IDE環境で、I2C LCD AQM0802Aの表示テストをします。

 Raspberry Pi Pico は、2つのI2C モジュールを内蔵しています。
 ピンの組み合わせ[SCL,SDA]は、
 [GP1,GP0], [GP3,GP2], [GP5,GP4], [GP7,GP6], [GP9,GP8], [GP11,GP10], [GP13,GP12],[GP15,GP14], [GP17,GP16], [GP19,GP18], [GP21,GP20], [GP27,GP26]  です。
 今回は、SCL=GP21,SDA=GP20とします。
 回路図です。
 

 まず、AQM0802AのI2Cアドレスを調べます。「電子工作を始めよう」などいくつかのサイトで紹介されている下のスクリプトを実行してみました。
 0x3eが表示されました。


 AQM0802Aは、コントローラにST7032が使われています。ST7032用のライブラリを探してみましたが、Adafuitのライブラリには見当たりませんでした。そこで検索してみると「xshige's beta notes」というサイトにAQM0802A用スクリプトとST7032ライブラリを見つけ、それを試しました。

 上記サイトから、ライブラリをMuエディタにコピーして、ST7032i.pyとしてPicoに保存します。保存先は、ルートでもlibフォルダでも、どちらでもOKのようです。
 Demo ScriptもMuエディタにコピーして、code.pyとしてPicoのルートに保存します。
 実行してみると、無事文字が表示されました。
 コピペしたときにスクリプトのインデントがずれたりして、エラーがでることがあります。その場合は、スクリプトを良く見て修正してください。



Raspberry Pi Pico CircuitPython ロータリーエンコーダ テスト

2022-04-23 10:45:09 | Raspberry Pi Pico
 Raspberry Pi Pico CircuitPython の勉強を続けるにあたって、最も参考になるのは、CircuitPythonの本家Adafruitのサイトです。


 左側のメニューの中から「CircuitPython Pins and Modules」を表示してみると、Rapberry Pi icoをPCに接続して、MuエディタからREPLでボードのピンの名前を表示させる方法が出ています。
 プロンプト>>>に下のように入力するとPinの名前が表示されます。


 また、CircuitPythonのビルトインmoduleを下のように入力することによって表示させることができます。


 かなりたくさんのmoduleがあるようです。これまで使ったのは、
board
digitalio
analogio
time
pwmio
です。

 rotaryioというロータリーエンコーダ用のmoduleもありますので、さっそく使ってみましょう。

 回路図です。GP0とGP1にロータリーエンコーダのA,B端子を接続します。
 ロータリーエンコーダのpositionは、shellに表示します。


 ブレッドボードです。


 スクリプトです。(Adafruitのサイトに掲載されているものです。)
---------------------------------------------------------------------------
from board import *
import rotaryio

encoder = rotaryio.IncrementalEncoder(GP0,GP1)
last_position = None

while True:
     position = encoder.position
     if last_position is None or position != last_position:
         print(position)
     last_position = position
---------------------------------------------------------------------------

ロータリーエンコーダを回転させると、shellにpositionの値が表示されました。

 ロータリーエンコーダを回すたびに、確実にカウントアップ、カウントダウンされました。