Raspberry Pi Pico WのUART通信とMicroPythonで超音波距離センサ を使ってみよう。

2024年9月9日

【 当サイトには広告リンクが含まれています。 】


ラズパイPicoW(Raspberry Pi Pico W)に超音波距離センサ(US-100)と液晶ディスプレイ(LCD)を接続し、UART通信を使ってLCDに超音波距離センサで測定した距離を表示させます。



実験準備

実験に必要な環境や部品を準備します。

機器とプログラム

「I2C通信で液晶ディスプレイ(LCD)に文字表示。」の回路に超音波距離センサ(US-100)を追加し、プログラムを改造して実験します。


使う部品

超音波距離センサ(US-100)及び液晶ディスプレイ(LCD)、I2CシリアルI/Fモジュールなど実験に使う部品を準備します。(「I2C通信で液晶ディスプレイ(LCD)に文字表示。」と一部、重複しています。)

部 品 名規 格数 量取扱い店(参考)
超音波距離センサ (GPIO)US-1001スイッチサイエンス
液晶ディスプレイ(LCD)LCD 1602A1Amazon (セット)
I2CシリアルI/FモジュールLCM1602
ブレッドボードBB-1021秋月電子通商
ジャンパーワイヤオス-メス
(約20cm)
1電子工作ステーション
ジャンパーワイヤオス-オス
(約20cm)
1電子工作ステーション


US-100はジャンパを配置してUARTモードで使います。仕様等はスイッチサイエンスさんのホームページを参照してください。


配線

準備した機器と部品をつなぎ、MicroPythonでプログラミングを行って、超音波距離センサで測定した距離を、液晶ディスプレイ(LCD)に表示させます。

配線リスト

超音波距離センサ(US-100)は、UART通信のチャンネルにジャンパーワイヤで接続し、液晶ディスプレイ(LCD)は、I2C通信のチャンネルにジャンパーワイヤで接続します。

液晶ディスプレイ(LCD)は5Vで動作しますので、VBUS (5V)に接続し、超音波距離センサ(US-100)は仕様上、5Vでも動作しますが、今回は3.3Vの3V3に接続します。


▶️超音波距離センサ(US-100)の配線

ラズパイPicoW超音波距離センサ(US-100)備 考
GP0Trig/Tx
GP1Echo/Rx
3V3 (3.3V)VCC
GNDGND
GNDGND


▶️液晶ディスプレイ(LCD)の配線

ラズパイPicoW液晶ディスプレイ(LCD)備 考
GP16SDA
GP17SCL
VBUS (5V)VCC
GNDGND


配線図



液晶ディスプレイ(LCD)とI2CシリアルI/Fモジュールは、ブレッドボード内部の配線で接続します。


距離測定プログラムの実行

超音波距離センサ(US-100)は、2cm~450cm(20mm~4500mm)の測定範囲の距離を16ビットのディジタルデータに変換し、9600ボーUART通信を通して、ラズパイPicoWなどのコンピュータに提供します。

ラズパイPicoWは読み込んだディジタルデータを処理し、距離をミリメータで液晶ディスプレイ(LCD)に表示します。

Raspi4BのThonnyを起動し、次のコードを「エディタ」に入力するか、リストをコピーしてペーストします。


##################################################
#
#      モジュールの読み込み
#
##################################################

#UART/I2C
from machine import UART, Pin, I2C
import utime

#LCD
from pico_i2c_lcd import I2cLcd


##################################################
#
#      US-100接続 UARTの設定
#
##################################################

#UART接続パラメータ
UART_CH = 0

#UARTオブジェクト作成
uart0 = UART(UART_CH, baudrate=9600, tx=Pin(0), rx=Pin(1))

#作成待ち
utime.sleep_ms(100)

#データ受信用バッファ設定(2バイト)
buf = bytearray(2)

#US-100 応答待ち時間初期化
wttm = 0


##################################################
#
#      液晶ディスプレイ(LCD)初期設定
#
##################################################

#I2Cを利用するため、オブジェクト(i2c)を作成
i2c = I2C(0,sda=Pin(16), scl=Pin(17), freq=400000)


#LCDのパラメータを設定
ADR = 0x27
ROW = 2
COL = 16


#LCDを利用するため、オブジェクト(lcd)を作成
lcd = I2cLcd(i2c, ADR, ROW, COL)


##################################################
#
#      【関数】距離測定
#
##################################################

def dstn_msurmnt():
    
    #データ受信用バッファ クリア
    buf[0] = 0
    buf[1] = 0
    
    #US-100へ距離測定の開始要求
    uart0.write(b'\x55')
    
    #US-100 応答待ち時間 ミリ秒カウンタ開始
    wttm = utime.ticks_ms()
              
    #受信データの有無を確認
    while uart0.any() == 0:
       
        if utime.ticks_diff(utime.ticks_ms(), wttm) > 100:
            #100ms超えても受信データが無い場合はエラー
            try:
                raise
            except:
                
                #LCD消灯
                lcd.clear
                
                #LCDにエラー表示
                lcd_disp("Reading Timeout", "from US-100!")
                
                #ラズパイPicoWリセット
                machine.reset()            
        
        #100us処理待ち
        utime.sleep_us(100)
        
    #US-100からbufに2バイト読み込み    
    uart0.readinto(buf, 2)
    
    #HighByte(左に8ビットシフト)をLowByteと連結
    return((buf[0] << 8) | buf[1])
        

##################################################
#
#      【関数】LCDに文字表示
#
##################################################


def lcd_disp(msg1, msg2):
    
    #LCDに文字を表示
    lcd.move_to(0, 0)
    lcd.putstr(msg1) 
    lcd.move_to(0, 1)
    lcd.putstr(msg2)
    
    
##################################################
#
#      メイン
#
##################################################

try:
    while True:
        
        #距離測定
        dstn = dstn_msurmnt()
        
        #文字整形
        frmt_dctn = "Distance: " + "{:03d}".format(dstn) + " mm"
        
        #LCDに文字表示
        lcd_disp(frmt_dctn, "")
        
        #50ミリ秒ごとに測定
        utime.sleep_ms(50)
        
        
except KeyboardInterrupt:
    # Turn off the display
    print("「Ctrl + c」キーが押されました。")
    
    #LCD消灯
    lcd.backlight_off()
    lcd.display_off()
    
    #ラズパイPicoWリセット
    machine.reset()        


Thonnyの「F5」キーを押して、距離測定プログラムを実行すると、対象物との距離が測定され、結果が液晶ディスプレイ(LCD)に表示されます。



確認後、Thonnyの「Ctrl + c」キーを押すと、液晶ディスプレイ(LCD)が消灯し、処理が中断しますので、中断後、「Ctrl + F2」キーを押して、プログラムを終了させます。


任意のファイル名でラズパイPicoWに保存します。(ここでは「3_10uartdstnc.py」で保存しました。)


距離測定プログラムの仕組み

対象物との距離を測定し、液晶ディスプレイ(LCD)に、距離(ミリメータ)を表示するまでのプログラムの動きを簡単に見ていきます。

【関数】は決められた処理を実行し、その結果を返す命令で、メインや他の関数から呼び出され、利用されます。

モジュールの読み込み

液晶ディスプレイ(LCD)との接続、超音波距離センサ(US-100)との接続するためのモジュールを読み込み(インポート)ます。

#UART/I2C
from machine import UART, Pin, I2C
import utime

#LCD
from pico_i2c_lcd import I2cLcd


US-100接続 UARTの設定

GPピン0と1を通して、超音波距離センサ(US-100)と、9600ボーでUART通信を行うためのオブジェクトを作成ます。

#UART接続パラメータ
UART_CH = 0

#UARTオブジェクト作成
uart0 = UART(UART_CH, baudrate=9600, tx=Pin(0), rx=Pin(1))

#作成待ち
utime.sleep_ms(100)

#データ受信用バッファ設定(2バイト)
buf = bytearray(2)

#US-100 応答待ち時間初期化
wttm = 0


液晶ディスプレイ(LCD)初期設定

I2C通信を使って液晶ディスプレイ(LCD)を利用するため、I2C通信用のオブジェクト、LCD表示用のオブジェクトを作成します。

#I2Cを利用するため、オブジェクト(i2c)を作成
i2c = I2C(0,sda=Pin(16), scl=Pin(17), freq=400000)


#LCDのパラメータを設定
ADR = 0x27
ROW = 2
COL = 16


#LCDを利用するため、オブジェクト(lcd)を作成
lcd = I2cLcd(i2c, ADR, ROW, COL)


【関数】距離測定

UARTのオブジェクトを使って、US-100へ距離測定の開始要求メッセージを送り、応答を待ちます。

応答が既定の時間内に返らない場合は、エラーメッセージを液晶ディスプレイ(LCD)に表示し、ラズパイPicoWをリセットします。

応答があった場合は、2バイト分の距離データを読み取り、連結して16ビットのデータとして処理を行い、呼び出し元に結果を返します。

def dstn_msurmnt():
    
    #データ受信用バッファ クリア
    buf[0] = 0
    buf[1] = 0
    
    #US-100へ距離測定の開始要求
    uart0.write(b'\x55')
    
    #US-100 応答待ち時間 ミリ秒カウンタ開始
    wttm = utime.ticks_ms()
              
    #受信データの有無を確認
    while uart0.any() == 0:
       
        if utime.ticks_diff(utime.ticks_ms(), wttm) > 100:
            #100ms超えても受信データが無い場合はエラー
            try:
                raise
            except:
                
                #LCD消灯
                lcd.clear
                
                #LCDにエラー表示
                lcd_disp("Reading Timeout", "from US-100!")
                
                #ラズパイPicoWリセット
                machine.reset()            
        
        #100us処理待ち
        utime.sleep_us(100)
        
    #US-100からbufに2バイト読み込み    
    uart0.readinto(buf, 2)
    
    #HighByte(左に8ビットシフト)をLowByteと連結
    return((buf[0] << 8) | buf[1])


【関数】LCDに文字表示

2つのメッセ―ジを引数として受け取り、それぞれ、液晶ディスプレイ(LCD)の上段と下段に表示します。

def lcd_disp(msg1, msg2):
    
    #LCDに文字を表示
    lcd.move_to(0, 0)
    lcd.putstr(msg1) 
    lcd.move_to(0, 1)
    lcd.putstr(msg2)


メイン

50ミリ秒ごとに【関数】距離測定を呼出し、取得した距離データを整形後、液晶ディスプレイ(LCD)に表示します。

「Ctrl + c」キーを押すと、液晶ディスプレイ(LCD)が消灯し、ラズパイPicoWをリセットします。

try:
    while True:
        
        #距離測定
        dstn = dstn_msurmnt()
        
        #文字整形
        frmt_dctn = "Distance: " + "{:03d}".format(dstn) + " mm"
        
        #LCDに文字表示
        lcd_disp(frmt_dctn, "")
        
        #50ミリ秒ごとに測定
        utime.sleep_ms(50)
        
        
except KeyboardInterrupt:
    # Turn off the display
    print("「Ctrl + c」キーが押されました。")
    
    #LCD消灯
    lcd.backlight_off()
    lcd.display_off()
    
    #ラズパイPicoWリセット
    machine.reset()       


まとめ

ラズパイPicoW(Raspberry Pi Pico W)に超音波距離センサ(US-100)と液晶ディスプレイ(LCD)を接続し、UART通信を使ってLCDに超音波距離センサで測定した距離を表示させました。

UART通信の基本、ラズパイPicoW(Raspberry Pi Pico W)を使った接続方法を学びました。

超音波距離センサ(US-100)から、UART通信を使った距離データの取得方法を学びました。