Samples_UART - gfd-dennou-club/mrubyc-esp32 GitHub Wiki
はじめに
UART クラスのメソッドについては,Class_UART を参照されたい.
UART の基礎
UART は非同期のシリアル通信である. 非同期のためにクロック用のラインは存在しない.
- 2 本の信号線で構成される (全二重通信)
- TX: データ出力
- RX: データ入力
- クロック同期式と比べて伝送速度は低速 (最大 20 kbps)
- UART にはクロック信号がないため, 通信をする前に送受信するデバイス間で通信速度 (ボーレート) を決める必要がある.
GPS
GPS GYSFDMAXB:https://akizukidenshi.com/catalog/g/gM-09990/
GPSのデータフォーマットも参照のこと.
サンプルプログラム
サンプル (1)
read メソッドで GPS のデータを全部取り出す.
puts "*********************"
puts " UART check (GPS) "
puts "*********************"
###
### 初期化
###
# GPSの電源を入れる (高専ボードの場合に必要)
gps_pw = GPIO.new(5, GPIO::OUT)
gps_pw.write(0)
# GPS初期化 txPin = 17, rxPin = 16 のため uart_num = 2 とする
gps = UART.new(2, baudrate:9600)
# 出力をデフォルトに戻す
sleep 1 #設定変更の前に多少の時間を置く
gps.puts("$PMTK314,-1*04\r\n")
# 入力データをclear_tx_buffer で消去する
puts "> gps.clear_tx_buffer"
gps.clear_tx_buffer
###
### 到着したデータを読み込んで表示
###
puts "------ Loop Start -----"
loop do
# バッファに溜まったデータを取得
puts gps.read( gps.bytes_available )
# 改行コード(CR+LF)で分割して配列化する場合
# array = gps.read( gps.bytes_available ).split("\x0D\x0A")
# 入力データがバッファに溜まるのを待つ
sleep 1
end
以下の様にデータ出力される.
*********************
UART check (GPS)
*********************
> gps.clear_tx_buffer
------ Loop Start -----
$PMTK001,314,3*36
$PMTK010,002*2D
$GPGGA,235942.800,,,,,0,0,,,M,,M,,*4B
$GPGLL,,,,,235942.800,V,N*79
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,1,1,00*79
$GPRMC,235942.800,V,,,,,0.00,0.00,050180,,,N*42
$GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32
$GPZDA,235942.800,05,01,3880,,*52
$GPGGA,235943.800,,,,,0,0,,,M,,M,,*4A
$GPGLL,,,,,235943.800,V,N*78
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,1,1,00*79
$GPRMC,235943.800,V,,,,,0.00,0.00,050180,,,N*43
サンプル (2)
出力を 1 行 (RMC) に限定して 10 秒間隔で表示する.
puts "*********************"
puts " UART check (GPS) "
puts "*********************"
###
### 初期化
###
# GPSの電源を入れる (高専ボードの場合に必要)
gps_pw = GPIO.new(5, GPIO::OUT)
gps_pw.write(0)
# GPS初期化 txPin = 17, rxPin = 16 のため uart_num = 2 とする
gps = UART.new(2, baudrate:9600)
# 出力を 1 行 (RMC のみ) に限定.
sleep 1 #設定変更の前に多少の時間を置く
gps.puts("$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n")
###
### 到着したデータを読み込んで表示
###
puts "------ Loop Start -----"
loop do
# バッファに溜まったデータを 1 行分取得.
puts gps.gets
# バッファに残っているデータを削除.
# これを入れないとバッファにデータが残りつづける.
gps.clear_tx_buffer
# 10 秒待つ
sleep 10
end
10 秒待って,データを 1 行分取り出したので (残りの 9 秒分は捨てる),10 秒間隔でデータが出力される.
*********************
UART check (GPS)
*********************
------ Loop Start -----
$PMTK011,MTKGPS*08 <-- 設定有効になるまで時間かかる
$PMTK001,314,3*36
$GPRMC,235952.800,V,,,,,0.00,0.00,050180,,,N*43
$GPRMC,000002.800,V,,,,,0.00,0.00,050180,,,N*4B
$GPRMC,000012.800,V,,,,,0.00,0.00,050180,,,N*4A
$GPRMC,000022.799,V,,,,,0.00,0.00,050180,,,N*46
$GPRMC,000032.799,V,,,,,0.00,0.00,050180,,,N*47
$GPRMC,000042.799,V,,,,,0.00,0.00,050180,,,N*40
$GPRMC,000052.799,V,,,,,0.00,0.00,050180,,,N*41
$GPRMC,000102.799,V,,,,,0.00,0.00,050180,,,N*45
$GPRMC,000112.799,V,,,,,0.00,0.00,050180,,,N*44
$GPRMC,000122.799,V,,,,,0.00,0.00,050180,,,N*47
000132.799,V,,,,,0.00,0.00,050180,,,N*46 <-- このような取りこぼしもある
00,0.00,050180,,,N*41
*4F
$GPRMC,000203.800,V,,,,,0.00,0.00,050180,,,N*48
$GPRMC,000213.800,V,,,,,0.00,0.00,050180,,,N*49
$GPRMC,000223.800,V,,,,,0.00,0.00,050180,,,N*4A
サンプル (3)
バッファと read, gets メソッドの関係の確認.
puts "*********************"
puts " UART check (GPS) "
puts "*********************"
###
### 初期化
###
# GPSの電源を入れる (高専ボードの場合に必要)
gps_pw = GPIO.new(5, GPIO::OUT)
gps_pw.write(0)
# GPS初期化 txPin = 17, rxPin = 16 のため uart_num = 2 とする
gps = UART.new(2, baudrate:9600)
# 出力を 1 行 (RMC のみ) に限定.
sleep 1
gps.puts("$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n")
###
### read メソッドと gets メソッド
###
# データの到着まで少し待つ
sleep 4
# read メソッドでバッファに溜まったデータを取り出す.
puts "> gps.read"
puts gps.read( gps.bytes_available )
# データの到着まで少し待つ
sleep 4
# gets メソッドで 1 行分のデータを受け取る
puts "> gps.gets"
puts gps.gets
# 10 バイトデータを read メソッドで表示
puts "> gps.read (10)"
puts gps.read( 10 )
# 残りのデータを read メソッドで表示
puts "> gps.read [remaining]"
puts gps.read( gps.bytes_available )
# 入力データをclear_tx_buffer で消去する
puts "> gps.clear_tx_buffer"
gps.clear_tx_buffer
# データ消去直後なので,何もバッファに残っていないので,表示されない
puts "> gps.read"
puts gps.read( gps.bytes_available )
*********************
UART check (GPS)
*********************
> gps.read <-- バッファの中身を全て読み出し
$PMTK011,MTKGPS*08 <-- 設定有効になるまで時間かかる
$PMTK010,001*2E
$PMTK010,002*2D
$PMTK001,314,3*36
$PMTK010,002*2D
$GPRMC,235942.800,V,,,,,0.00,0.00,050180,,,N*42
$GPRMC,235943.800,V,,,,,0.00,0.00,050180,,,N*43
$GPRMC,235944.799,V,,,,,0.00,0.00,050180,,,N*4B
$GPRMC,235945.799,V,,,,,0.00,0.00,050180,,,N*4A
> gps.gets
$GPRMC,235946.799,V,,,,,0.00,0.00,050180,,,N*49 <-- 1 行分読み出し
> gps.read( 10 )
$GPRMC,235 <-- 10 バイト分読みだした
> gps.read [remaining]
947.799,V,,,,,0.00,0.00,050180,,,N*48 <-- 1 つ前の処理で 10 バイト分取り出したので,行の先頭が欠けている
$GPRMC,235948.799,V,,,,,0.00,0.00,050180,,,N*47
$GPRMC,235949.799,V,,,,,0.00,0.00,050180,,,N*46
> gps.clear_tx_buffer <-- バッファクリア
> gps.read
<-- バッファクリア直後なので,何も表示されない
サンプル (4)
出力を 1 行 (RMC) に限定して 10 秒間隔で表示する. データ欠損が起きないようにデータサイズを確認している.
puts "*********************"
puts " UART check (GPS) "
puts "*********************"
###
### 初期化
###
# GPSの電源を入れる (高専ボードの場合に必要)
gps_pw = GPIO.new(5, GPIO::OUT)
gps_pw.write(0)
# GPS初期化 txPin = 17, rxPin = 16 のため uart_num = 2 とする
gps = UART.new(2, baudrate:9600)
# 出力を 1 行 (RMC のみ) に限定.
sleep 1
gps.puts("$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n")
###
### 到着したデータを 1 行ずつ読み込んで表示. 出力を RMC のみに限定.
###
puts "------ Loop Start -----"
loop do
# 入力データがバッファに溜まるのを待つ
sleep 3
# データ取得・表示
num = 0
while (num < 13) # データに欠けがないことを保証
line = gps.gets
num = line.split(',').size
next if gps.bytes_available <= 0 #バッファの中身が無くなれば諦める
end
p line
items = line.split(',')
p items[1] #配列要素の表示
p "#{items[1][0]}#{items[1][1]}#{items[1][2]}" #最初の3文字分だけ表示
# バッファに残っているデータを削除.
# これを入れないとバッファにデータが残りつづける.
gps.clear_tx_buffer
# 待ち時間 (合計で約10秒待つ)
sleep 7
end
実行結果は以下のようになる.
*********************
UART check (GPS)
*********************
------ Loop Start -----
"$GPRMC,235942.800,V,,,,,0.00,0.00,050180,,,N*42"
"235942.800"
"235"
"$GPRMC,235945.799,V,,,,,0.00,0.00,050180,,,N*4A"
"235945.799"
"235"
"$GPRMC,235955.800,V,,,,,0.00,0.00,050180,,,N*44"
"235955.800"
"235"