🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

Q&A

解決済

3回答

1553閲覧

Arduinoのシリアル通信

zzzzzz

総合スコア6

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

0グッド

0クリップ

投稿2019/12/06 00:47

編集2019/12/07 12:45

前提・実現したいこと

下記のような簡単なスケッチで、受信した文字列を転送しよう(最終的には送られてきた文字列を違う文字列に変換して送信)としたい。

発生している問題・エラーメッセー

スケッチにある$WIWMV...しか送信されてきません。ArduinoのLEDは送信、受信とも点滅しています。USBではなくシリアルピンで接続しています。arduinoへ文字列を送信している側からデータが送られていることは直接PCと接続して確認しています(スケッチにある$WIWMV...の数字が違うだけです)。スケッチのネタ元とnmea.hは下記です。全くの素人ですのでアドバイスを頂けると助かります。

https://kingtidesailing.blogspot.com/2015/09/how-to-connect-any-nmea-0183-device-to.html

https://github.com/ericbarch/arduino-libraries/tree/master/NMEA

### 該当のソースコード ```Arduino ソースコード #include <nmea.h> NMEA nmeaDecoder(ALL); void setup() { Serial.begin(4800); } void loop() { if (Serial.available()) { // if something is incoming through the Serial Port if (nmeaDecoder.decode(Serial.read())) { // if it's a valid NMEA sentence Serial.println(nmeaDecoder.sentence()); // print it } } Serial.println("$WIWMV,256,R,14,N,A*39"); delay(1000); }

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ozwk

2019/12/06 01:05

状況がいまいちよくわからないのですが、 PCとArduinoをつないでPCからNMEAフォーマットの文字列を送ってもArduinoが返答しないということですか?
zzzzzz

2019/12/06 01:33

有難うございます。その通りです。
ozwk

2019/12/06 01:58 編集

PCから文字列はどうやって送っているんですか? Teratermでキーボードカタカタしてるんですか? マクロ? Teratermのローカルエコー設定どうなってますか?
zzzzzz

2019/12/06 01:58

PCからではなく航海計器のnmea出力ポートから電圧を5vに落としてarduinoのシリアルポートに入れています。写真は航海計器からUSBシリアル変換でPCにつなぎ受信したものです。
ozwk

2019/12/06 02:04 編集

じゃあ"その通り"じゃないんですね。 航海計器の出力データをArduino経由してPCに送りたいが 航海計器がデータ出力しているはずなのに PCに受信データが現れないってことですか?
zzzzzz

2019/12/06 04:19

そうです。失礼しました。
ozwk

2019/12/06 04:55

計器のシリアル通信線をArduinoのどのピンに PCとArduinoをどのArduinoのどのピン/コネクタにどうつないでいるか教えて下さい
zzzzzz

2019/12/06 08:50

こんな感じです(GNDは省略)。level convは秋月で買った5v系-rs232変換基盤です。 arduino nano level conv PC 航海機器 Tx =======Rx-Tx===Rx Rx=======Tx-Rx=========Tx
ozwk

2019/12/06 09:07 編集

レベルコンバータ経由で ArduinoのTxがPC(usbシリアル変換)のRx ArduinoのRxが機器のTxですね
SHOMI

2019/12/06 09:05

Serialのバッファは64バイトですが1秒もdelayすると溢れているのでは?
zzzzzz

2019/12/06 09:21

Serial.println("$WIWMV,256,R,14,N,A*39"); delay(1000); 最初は上記無しだったのですが、全く何も出て来なかったため、試しに入れてみたものです。この文字列は出てきたのでarduino、レベル変換基盤、PCの通信は出来ていることは確認出来ました。もう一度外して試してみます。
SHOMI

2019/12/06 09:31

なら次は本当に受信できているか、Serial.read()したデータをそのままSerial.print()してみるべきでは?
zzzzzz

2019/12/06 09:49

有難うございます。週末船に行ければ試してみたいと思います。
thkana

2019/12/07 02:13

船で移動しているのならいいですけれど、NMEA情報をそのまま見せたら所在地がモロバレなのでは...
zzzzzz

2019/12/07 12:46

有難うございます。念のため写真を削除しました。
guest

回答3

0

ベストアンサー

全部組んじゃって「うまくいかない」なら、個々の要素をstep by stepで確認していくことになるのでは。

(1) 機器からデータが出ているか確認

直接PCと接続して確認

RS232で接続、ですね? ではここは大丈夫でしょう。

(2) RS232-UARTコンバーターの動作を確認する。
ArduinoのRXのLEDが点滅しているとのことで大丈夫なような気もしますが、「まともな信号が出ていない」なんていう事態も考えられなくはないかしら。
Arduinoは一旦外して、
機器のTX -> コンバーターの(RS232)RX -> (UART)TX -> (UART)RX -> (RS232)TX -> PCのRX
とつないで、機器からのデータがPCで受信出来ることを確認

(3) Arduino側で一切加工せずにPCに中継

Arduino

1void setup(){ 2 Serial.begin(4800); 3} 4void loop(){ 5 if(Serial.available()){ 6 char c=Serial.read(); 7 Serial.write(c); 8 } 9}

(4) NMEAライブラリを通して受信の確認

Arduino

1include <nmea.h> 2 3NMEA nmeaDecoder(ALL); 4 5void setup() { 6 Serial.begin(4800); 7} 8void loop() { 9 if (Serial.available()) { 10 if (nmeaDecoder.decode(Serial.read())) { 11 Serial.println(nmeaDecoder.sentence()); 12 } 13 } 14//余計なことはしない 15}

これで概ね動作するなら、残りの二行が悪さをしている、ということが決定できそうに思いますが。いかがでしょう。


Arduinoのシリアルの送信は一応割り込みを使っているので、プログラムが動作しているウラでデータの送受信を行えます。しかし、そのためのバッファ(一時データ置き場)は64byte(だったっけ)しかなく、それ以上のデータを連続して送ろうとすると、データが全部バッファに入り切るようになるまで待たされます。また、受信の場合はバッファが一杯になっていると以降受信したデータは失われます。

$WIWMV,256,R,14,N,A*39
が22文字+改行2文字で24文字、というのは覚えておいて...

プログラムが開始されると、最初はデータが来ていませんから、Serial.println()は文字列をバッファに入れるだけで瞬時に次に進みます。
で、loop()が一旦終わって次回のloop。今度もまだ受信出来ているわけがないですから、また文字列をバッファに入れて48文字。
同様に回ってまたloopですが、今度はバッファにすでに48文字が入っていて、空きが16文字分しかありませんから、このデータを全てバッファに送り込むまでSerial.println()から処理が戻れません。残り8文字分。この間にもしかしたら機器側からも8文字拾えているかも知れませんが、まだNMEAの1行には満たないでしょう。次のloopに入ります。今度は24文字分全部待ちになるでしょう。この間、機器側から24文字拾えているかも。以降、送信バッファは常に一杯ですから、loopに入る度に24文字分の時間がかかって、受信バッファにも文字が溜まっていくのですが、受信バッファも64byteしか容量がありませんからやがていっぱいになってしまうでしょう。そうなると、24文字分の送信待ちはいわば受信の「不感時間」となり、この期間に受けたデータは取りこぼす可能性が高くなります。48文字分毎にそういう状況になると、多分データの受信がまともに出来なくなるのではないでしょうか。

結果として

スケッチにある$WIWMV...しか送信されてきません。

となっているような気がします。そこにdelayを入れるなんてもってのほか。

投稿2019/12/07 02:56

編集2019/12/07 02:57
thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zzzzzz

2019/12/07 12:44

詳細に有難うございます。経緯としてはまず(4)からスタートし全く何も出て来なかったので、2行追加したところ追加したテキストは出てきたのでハード的には問題ないのかなというところです。(1)は確認済み、(2)は今一つ理解していないのですが、送信機器tx→レベルコンバタrx→レベルコンバタtx→シリアルUSB→pcという繋ぎではデータは出ています。まずは(3)を試してみます。
zzzzzz

2019/12/08 11:18

今日船に行ったのですが、PCが不調でテスト出来ませんでした。少しややこしいですが、かわりに家でArduino nanoでテキストを送信、RS232レベルに昇圧し、別のレベルコンバターに入力、5Vに降圧し、もう一台のnano(上記4のスケッチ転送済み)に入力、シリアルの出力を12Vに昇圧しPCに入れたところちゃんと出てきました。ハードもスケッチも問題ないようです。航海機器からはちゃんとRS232でテキストが出てきているのも確認しているので不思議ですが、いずれにしても次回船に別のPCを持ち込み試してみます。
guest

0

1つのSerialが通信できる相手は1つです。
機器 --> Serial --> SoftwareSerial(Serial1があればそれでも可) --> PC
となるようにしましょう

投稿2019/12/06 05:07

ozwk

総合スコア13551

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zzzzzz

2019/12/06 08:42

有難うございます。シリアルのtxとrxにそれぞれ違う相手をつなぐのは無しということでしょうか? PCとかでは問題ないよう気がしますが。。。arduinoの仕様でしょうか?
ozwk

2019/12/06 09:12

すみません思ってたのと状況違いました
guest

0

おそらく受信側に問題があります。

シリアル-USB変換ケーブルなどで、そのシリアル信号をPCのシリアルターミナルで受信してどうなってるのか見てみましょう。

投稿2019/12/06 00:53

y_waiwai

総合スコア88040

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zzzzzz

2019/12/06 01:33

有難うございます。PCで受信すると追加した写真のように出てきます。
y_waiwai

2019/12/06 02:08

>if (Serial.available()) { // if something is incoming through the Serial Port >if (nmeaDecoder.decode(Serial.read())) { // if it's a valid NMEA sentence シリアル通信は遅いです。1文字単位で読み込まれるため、このように読むと1文字単位でしか読めません なので、改行コードが来るまで、受信文字を貯めておき、改行コードが来たら1行分揃ったとして、その後の処理に回すようにしないといけないです
ozwk

2019/12/06 02:10

...って処理をnmeaDecoder.decode(char c)でやってるのでは。
y_waiwai

2019/12/06 02:23

> $WIWMV...しか送信されてきません ってことなんで、まともに受信できてないってことですな #Arduinoの相手側?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問