質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

Q&A

解決済

4回答

3612閲覧

PICマイコン シリアル通信 文字化け

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

0グッド

1クリップ

投稿2018/08/28 06:20

<問題>
arduinoからPicマイコンへデータを送信しているのですが、Picマイコンで上手く受け取れていません。
Tera Tarm で確認したところ、送信した文字が、"9" → "1"に、"B" → "F"に変換されてしまっているようです。文字コードや通信速度も確認しましたが怪しいところが見つかりませんでした。

<現状>
picマイコンは "16F886" を使っています。
MPLABのバージョンもいくつか変更して試しましたが駄目でした。
Tera Tarmを使用していない時もオシロスコープでデータが渡されていることは確認しています。

考えられる可能性をなんでもいいので教えて頂けると助かります。

pic マイコン(割り込み処理と関係する部分のみ)

C

1// Constants 2#define RXBUFSIZE 96 // Serial buffer size 3#define TXBUFSIZE 32 // Serial buffer size 4// Work vars 5char Servo1; // Servo1 position (0 to 99) 6char Servo2; // Servo2 position (0 to 99) 7char RxBuf[RXBUFSIZE]; // Recieve queue 8char TxBuf[TXBUFSIZE]; // Transmit queue 9char Digit[8]; // Digit buffer 10char Reply[16]; // Reply data buffer 11char Index; // Result store index 12 13char PortB; // PORTB image copy for asynchronous bit operation 14volatile char Tick; // PORTB copy for bit operation 15volatile char RxIn; // Receive queue entry pointer 16volatile char RxOut; // Receive queue output pointer 17volatile char TxIn; // Receive queue entry pointer 18volatile char TxOut; // Receive queue output pointer 19ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー 20char RxSense(void) 21{ 22 signed char i; 23 i = RxIn - RxOut; // Check queued number 24 if(i < 0) // Negative? (may wraped queue index) 25 i += RXBUFSIZE; // Make it plus 26 return i; // Return with queued number 27} 28ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー 29char GetChar(void) 30{ 31 char i; 32 while(!RxSense()); // Wait untill receive data has come 33 i = RxBuf[RxOut]; // Get queued data 34 if(RxOut == RXBUFSIZE - 1) // Reach to the end of the queue? 35 RxOut = 0; // Go to top again (ring buffer) 36 else 37 RxOut++; // Advance get pointer 38 return i; // Return with received data 39} 40ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー 41// Main 42// 43main() 44{ 45 char i; 46 while(!(OSCCON & 0x04)); // Wait untill HFINTOSC is stabled 47 48// Clock setup 49 OSCCON = 0x71; // Set prescaler 8MHz and use internal clock 50 51// Set port direction & purpose 52 ANSEL = 0x00; // Set PA0 & PA1 is analog input 0x03 53 PORTA = 0x00; // Clear PORTA 54 PortB = 0x30; // Clear PORTB & set servo ports 55 PORTB = PortB; // Set PORT B data 56 PORTC = 0x00; // Clear PORTC 57 TRISA = 0x0f; // Set PA4,5,6,7 output 58 TRISB = 0xc0; // Set PB0,1,2,3,4,5 output 59 TRISC = 0xc0; // Set PC0,1,2,3,4,5 output 60 61// Setup variables 62 Servo1 = 99; // Set default servo1 position 63 Servo2 = 50; // Set default servo2 position 64 RxIn = 0; RxOut = 0; // Clear receive queue pointers 65 TxIn = 0; TxOut = 0; // Clear tansmit queue pointers 66 67// Setup serial port 68 SPBRG = 12; // Set 9600bps of 8MHz clock 69 RCSTA = 0x80; // Enable TX & RX pin 70 TXEN = 1; // Enable TX 71 CREN = 1; // Enable RX 72 RCIE = 1; // Enable serial receive interrupts 73 74// Set A/D converter 75 ADCON0 = 0x81; // A/D clock source is FOSC/32 & enable A/D logic 76 ADCON1 = 0x80; // Set A/D result format is right justified 77 78// Setup TIMER 79 OPTION_REG = 0x84; // Prescaler = 64 TIMER0 tick will 16uS OSC 8MHz/4/32 80 TMR1ON = 1; // Enable TIMER1 81 TMR1IE = 1; // Enable TIMER1 interrupts 82 T2CON = 0x0f; // Enable TIMER2 & prescaler 1:4 & postscaler 1:8 83 84// Enable interrupts 85 PEIE = 1; // Enable peripheral interrupts 86 GIE = 1; // Enable global interrupts 87 88// Start main loop 89 for(;;) 90 { 91 92// Receive process 93 if(RxSense()) 94 { 95 if(RXBUFSIZE != 0){ 96 // Serial data has come from WiFi module 97 i = GetChar(); // Get one byte 98 switch(i) // Only ACT A,B,C 99 { 100 case 'A': // Servo 1? 101 Servo1 = GetValue(); // Get servo 1 value 102 break; 103 case 'B': // Servo 1? 104 Servo2 = GetValue(); // Get servo 2 value 105 break; 106 case 'D': // Temperture ? 107 case 'E': // Variable register?? 108 GetValue(); // Get value and skip 109 break; 110 111 } 112 } 113 else{ 114 Servo1=99; 115 Servo2=50; 116 } 117 } 118 }

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

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

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

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

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

hillacken

2018/08/28 13:42

送られてきた値をそのまま返すよう書き換えたソースコードもアップしてください。
退会済みユーザー

退会済みユーザー

2018/08/29 00:13

ご意見ありがとうございます。今週は遠出の用事があり開発に戻れないため、来週頭にアップします!
a_saitoh

2018/08/29 03:49

(PCの)Teratermで確認できたということは、RS232C電圧レベルに変換して送受信していますか?
guest

回答4

0

皆さんたくさんの意見ありがとうございます。
原因はpicマイコンが製造時に通信速度にばらつきが起きるためでした。
専用のメソッドがあったのでそれで通信速度を合わせることができました。

投稿2018/09/07 05:47

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

ベストアンサー

文字化けのパターンは、常に一致しているのでしょうか。
"B"は、時々、"F" で、"9" は常に"1" という事で、他はOK?
どんな文字で化けて、どんな文字は OKなのでしょうか。 化ける場合の bitパターンでみると問題が分かる時があります。

時々、化けるという事ならば、ハードの問題も考えられます。
オシロスコープがあるならば、文字化け時のパターンを確認して、正しいかどうか確認すべきです。(0/1 なので、数文字なら、読めると思います)
同時に波形に乱れが無いかも要確認です。 ((俗にいう)232Cあたりだとノイズに弱いです)
また、双方の電圧は OKでしょうか? 片方の電圧が低くて正しく認識しないという事はないでしょうか? "16F886"を見たら、5Vくらいのようですが、、(VDDに依存?)

ざっと思いつくところまで。

投稿2018/08/28 11:56

pepperleaf

総合スコア6383

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

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

退会済みユーザー

退会済みユーザー

2018/08/29 00:22

回答ありがとうございます。 文字化けのパターンはその通りです。JISコードのやり取りで、 "9"→"1"の場合 0011 1001 → 0011 0001 "B"→"F"の場合 0100 0010 → 0100 0110 だと思います。必ず同じビットが変化している訳では無いのですが、文字化けするパターンは固定です。 電圧の可能性はあるかもしれません!今用事があり遠出しているので開発環境が確認出来ないのですが、PICへの書き込みは3.3Vで行なっていたかもしれません。書き込み完了となっていたので確認を怠っていました。 戻り次第確認してみます!
guest

0

コードのデバッグは誰かがやってくれるだろうから、ここではデバッグ法を書いておきます

まず、Arduinoの送信データは正しく行われているのかをチェックしてください。
ArduinoとPCをつないでどういう文字列がPCで受信できているかをチェックします

で、Arduinoの送信データは全く正しい、というのを確認したあと、PICの方のデバッグです

まず、一定のウェイトを置いて、特定の文字1文字を送信してそれを繰り返すコードをを組み、それをPICに書き込んで走らせておきます

オシロで送信波形を見て、正常に文字が送信できているか、パルス幅から想定したボーレートになっているかを確認します。
それが確認されたら、PCと繋いで、文字列が正常に送受信されるかをチェックします

がんばってください

投稿2018/08/28 06:41

y_waiwai

総合スコア87719

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

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

退会済みユーザー

退会済みユーザー

2018/08/28 07:05

回答ありがとうございます。 言葉足らずで申し訳ありません。Arudinoはシリアルモニタとオシロスコープでデータが正しく遅れていることは確認済みです。mainloopに送られてきた値をそのまま返すよう書き換えて試してみたのですが、"A"のみですが文字化けせずに帰ってきましたが、それ以外の数では文字化けがしている状況です。。
ozwk

2018/08/28 07:09

それ本当に'A'だけが文字化けしないんですか? リセット後の1番目に受信した文字だけ正常に返すとかでなく?
y_waiwai

2018/08/28 07:09

ならそれ以外の文字を送ってオシロで確認しましょう。 典型的なボーレート、あるいは設定違いの症状ですね
退会済みユーザー

退会済みユーザー

2018/08/28 07:18

"A"は連続で送っても文字化けしないのですが、"B"は連続して送るとたまに"F"に、"9"は毎回"1"に変わって表示されています。 設定違いだと疑ってみているのですが、もう一度確認してみたいと思います!
y_waiwai

2018/08/28 07:21

まあ、特定の文字だけは、データパターンの具合でたまたまエラーに引っかからない、ということはよくあるあるなはなしなんで、そこらへんよく確認しましょう
退会済みユーザー

退会済みユーザー

2018/08/29 00:28

ありがとうございます! 今週は用事があり開発に戻れないため戻り次第確認してみたいと思います。
guest

0

ざっとソースコードを見た感じですが、以下の点は設定したものが一致していますか?

  • スタートビットの設定
  • パリティビットの設定 (なし/偶数/奇数
  • データ長の設定(7ビット/8ビット
  • ストップビット

電気的な仕組みを理解する必要があるかと思います。
以下URLを参考にしてみてください。
http://www5b.biglobe.ne.jp/~kouta_y/news/newsvb/vb14.html

また、このあたりはレジスタに明示的に設定しない場合、デフォルトが使用されます。
マイコンごとの設定は各データシートを御覧ください。

投稿2018/08/28 06:31

編集2018/08/28 06:33
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2018/08/28 07:08

ありがとうございます。 記事、参考にさせて頂きます。 電気的な仕組みは本当に初心者なので助かります。またご教授よろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問