LoginSignup
1
0

More than 3 years have passed since last update.

Raspberry Pi 3でソフトUARTを利用

Last updated at Posted at 2020-07-19

はじめに

ラズパイ3ではUARTが2つ用意されていますが、実際に外部接続用に利用できるのは1つしかありません。複数の機器とUARTでシリアル通信する場合にUSBアダプターを追加したりとハードウェアを増やすのも嫌なので、ソフトウェアのUARTデバイスを利用してみます。

ソフトウェアでUART通信するので、高速な通信はできないのですが接続しようとしているGPS受信器キットのデフォルトボーレートが9600bpsと低速なので何とかなるだろうと。

なお、ラズパイ4ではUART1~5まで使えるようになったみたいです。ちょっと欲しいかも…

追記事項あり:helmet_with_cross:

  • 動作が不安定なので、常時利用は難しいかも。詳細はこちら

Goal

  • GPS受信キットからのUART送信をソフトウェアUARTで受け取れること

事前確認

下記設定がすんでいる前提です。

  • シリアルコンソールの無効化
  • UARTの有効化
  • UART0とUART1(Mini UART) の入れ替え

なお、UART0とUART1の入れ替え後は下記となっている想定です。

pi@raspberrypi:~/project/soft_uart $ ll /dev | grep serial
lrwxrwxrwx  1 root root           7 Jul 19 14:28 serial0 -> ttyAMA0
lrwxrwxrwx  1 root root           5 Jul 19 14:28 serial1 -> ttyS0

ソフトウェアUARTの設定

基本は下記Githubに書いてある通りです。
https://github.com/adrianomarto/soft_uart

git clone https://github.com/adrianomarto/soft_uart
sudo apt-get install raspberrypi-kernel-headers
cd soft_uart
make
sudo make install
sudo insmod soft_uart.ko

下記のように /dev/ttySOFT0 があればOKです。

確認
pi@raspberrypi:~/project/soft_uart $ ll /dev | grep SOFT
crw-rw----  1 root dialout 240,   0 Jul 19 15:13 ttySOFT0

なお、再起動には使えなくなるので再度 sudo insmod soft_uart.ko を実行してください。継続利用する場合はOS起動時にロードできるようrcスクリプトなどに書いてください、

ラズパイ側の接続

デフォルトでは以下の設定となっているのでGPIO17と27をワイヤで直結して試してみます。

  • gpio_tx: int [default = 17]
  • gpio_rx: int [default = 27]
配線
GPIO17(TX) --> GPIO27(RX)

確認

minicomで接続確認1
ボーレート9600で確認してみます。

minicom -b 9600 -D /dev/ttySOFT0

別の端末で以下を実行します。

echo "hello" > /dev/ttySOFT0

image.png

へんなタブが気になりますが、ハードウェアのUART側(UART0)も同じ表示になったのでよしとします。

GPS受信キットでの確認

ここまでくれば大丈夫でしょう。試してみます。
特に問題なしでした!

image.png

IMG_4495.jpg

参考サイト

下記サイトのほぼそのままになりました。情報助かりました!

感想

  • シリアル通信周り/電源回りなどを考えるとArduinoの偉大さがよくわかる
  • mrubyがESP32あたりでさくっと動けばなー。今のアップロード手順だと初心者としてはTraial&Errorのたびに心が折れる…
  • RasbperyPi OSは最初から英語版でいれるべきだった。
  • ワイヤ断線ヤバイ…気づくのに時間がかかった…

追記事項

プログラムを中断&再度実行を数回繰り返すとシリアルポートからの読み込みができなくなる現象が発生。

  • 読み込みができないようでプログラムが永遠にブロックされる
  • いったんモジュールを削除してから再度モジュールをロードするとうまく動く
  • プログラムをずっと起動しておく分には問題なさげ

そこで以下を試すも改善せず。

  • Ctrl + C で停止時にきちんとポートを閉じるように SIGINT をトラップ
    • 修正後のソースは後述
  • CPU周波数の固定化(250MHzに固定)
    • echo "core_freq=250" | sudo tee -a /boot/config.txt 後再起動

結局以下の力技で回避した。まさに:muscle:
[PATH_TO_SOFT_UART_DIR] は環境に合わせてください。

require 'serialport'
require 'nmea_plus'

puts `sudo rmmod soft_uart.ko`
sleep 0.1
puts `cd [PATH_TO_SOFT_UART_DIR] && sudo insmod soft_uart.ko`

sp = SerialPort.new('/dev/ttySOFT0', 9600, 8, 1, 0) # see: https://rubydoc.info/gems/serialport/SerialPort#set_modem_params-instance_method

# 最低限お行儀よく振る舞う
trap 'SIGINT' do
  sp.close if sp
  exit
end

source_decorder = NMEAPlus::SourceDecoder.new(sp)
source_decorder.each_complete_message do |message|
  # see: https://github.com/ianfixes/nmea_plus/blob/master/lib/nmea_plus/message/nmea/rmc.rb
  if 'GPRMC' == message.data_type
    puts message.utc_time
    puts message.active? # false: データ無効
    puts message.latitude
    puts message.longitude
    #puts message.speed_over_ground_knots
    #puts message.track_made_good_degrees_true
    #puts message.magnetic_variation_degrees
    puts message.faa_mode # A: 単独測位(精度3m程度), D: 相対測位(精度0.4m程度) 
    puts
  end
end


  1. minicomが日本語ロケールだと表示がずれてしまうので、 LANG=C minicom -s を試したのですが英語化されず…raspi-configからの設定はなぜか効かなかったの、GUI画面の設定からロケールを変更しました。 

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0