Samples_UART - gfd-dennou-club/mrubyc-esp32 GitHub Wiki

はじめに

UART クラスのメソッドについては,Class_UART を参照されたい.

UART の基礎

UART は非同期のシリアル通信である. 非同期のためにクロック用のラインは存在しない.

  • 2 本の信号線で構成される (全二重通信)
    • TX: データ出力
    • RX: データ入力
  • クロック同期式と比べて伝送速度は低速 (最大 20 kbps)
  • UART にはクロック信号がないため, 通信をする前に送受信するデバイス間で通信速度 (ボーレート) を決める必要がある.

image

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"