2013-07-27 24 views
11

私はArduino UnoにADH8066(Sparkfun)GSMモジュールを接続し、ArduinoとGSMモジュールの間で正しいシリアル接続をしようとしています。それは、(USBまたはTTLラインを介して)直接接続するとうまく動作しますが、Arduino経由で制御されているときはうまく動作しません。いくつかのテキストは正しく出力され、残りは文字通りボーレートが間違っているように文字化けしますが、私はPCから接続するときと同じボー(115200)を使用しています。Arduino - garbleed serial output

以下
#include <SoftwareSerial.h> 

#define rxPin 7 
#define txPin 8 
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin); 

// EN: String buffer for the GPRS shield message 
String SmsStorePos = String(""); 
String msg = String(""); 
String snTmp = String(""); 
String snFull = String(""); 

// EN: Set to 1 when the next GPRS shield message will contains the SMS message 
int SmsContentFlag = 0; 

// EN: Pin of the LED to turn ON and OFF depending on the received message 
int ledPin = 5; 
int powerPin = 6; 

void setup() 
{ 
    mySerial.begin(115200);    // the GPRS baud rate 
    mySerial.print("\r"); 
    delay(1000); 
    Serial.begin(115200);     // the Arduino IDE serial 
    Serial.println("Started!"); 

    pinMode(ledPin, OUTPUT); 
    digitalWrite(ledPin, LOW); 

    pinMode(powerPin, OUTPUT); 
    digitalWrite(powerPin, LOW); // brings ONKEY low to turn on the modem (aka pressing the ONKEY) 
    delay(3000); 
    digitalWrite(powerPin, HIGH); // sets the pin HIGH again (restore 5V) 
    delay(5000); 

    // test LED pin 
    digitalWrite (ledPin, HIGH); 
    delay(1000); 
    digitalWrite(ledPin, LOW); 
} 

void loop() 
{ 
    char SerialInByte; 

    // Send anything we receive from the IDE to the modem 
    if(Serial.available()) 
    { 
     mySerial.print((unsigned char)Serial.read()); 
    } 
    else if(mySerial.available()) 
    { 
     char SerialInByte; 
     SerialInByte = (unsigned char)mySerial.read(); 
     //SerialInByte = mySerial.read(); 

     // EN: Relay to Arduino IDE Monitor 
     Serial.print(SerialInByte); 

     // ------------------------------------------------------------------- 
     // EN: Program also listen to the GPRS shield message. 
     // ------------------------------------------------------------------- 

     // EN: If the message ends with <CR> then process the message 
     if(SerialInByte == 13){ 
      // EN: Store the char into the message buffer 
      ProcessGprsMsg(); 
     } 
     if(SerialInByte == 10){ 
      // EN: Skip Line feed 
     } 
     else { 
      // EN: store the current character in the message string buffer 
      msg += String(SerialInByte); 
     } 
    } 
} 

// EN: Make action based on the content of the SMS. 
//  Notice than SMS content is the result of the processing of several GPRS shield messages. 
void ProcessSms(String sms){ 
    sms.toLowerCase(); 
    Serial.print("ProcessSms for ["); 
    Serial.print(sms); 
    Serial.println("]"); 

    if(sms.indexOf("on") >= 0){ 
    digitalWrite(ledPin, HIGH); 
    Serial.println("LED IS ON"); 
    return; 
    } 
    if(sms.indexOf("off") >= 0){ 
    digitalWrite(ledPin, LOW); 
    Serial.println("LED IS OFF"); 
    return; 
    } else { 
    mySerial.print("AT+CMGF=1\r"); //Because we want to send the SMS in text mode 
    delay(1000); 
    mySerial.print("AT+CMGS=\""); 
    mySerial.print(snFull); 
    mySerial.print("\"\r"); 
    delay(1000); 
    mySerial.print("Unknown Command: "); 
    mySerial.print(sms); 
    mySerial.print("\r"); 
    delay(1000); 
    mySerial.write(0x1A); //Equivalent to sending Ctrl+Z  
    return; 
    } 
} 
// EN: Request Text Mode for SMS messaging 
void GprsTextModeSMS(){ 
    mySerial.println("AT+CMGF=1"); 
} 

void GprsReadSmsStore(String SmsStorePos){ 
    // Serial.print("GprsReadSmsStore for storePos "); 
    // Serial.println(SmsStorePos); 
    mySerial.print("AT+CMGR="); 
    mySerial.println(SmsStorePos); 
} 

// EN: Clear the GPRS shield message buffer 
void ClearGprsMsg(){ 
    msg = ""; 
} 

// EN: interpret the GPRS shield message and act appropiately 
void ProcessGprsMsg() { 
    Serial.println(""); 
    Serial.print("GPRS Message: ["); 
    Serial.print(msg); 
    Serial.println("]"); 

    if(msg.indexOf("Call Ready") >= 0){ 
    Serial.println("*** GPRS Shield registered on Mobile Network ***"); 
    GprsTextModeSMS(); 
    } 

    // EN: unsolicited message received when getting a SMS message 
    if(msg.indexOf("+CMTI") >= 0){ 
    Serial.println("*** SMS Received ***"); 
    // EN: Look for the coma in the full message (+CMTI: "SM",6) 
    //  In the sample, the SMS is stored at position 6 
    int iPos = msg.indexOf(","); 
    SmsStorePos = msg.substring(iPos+1); 
    Serial.print("SMS stored at "); 
    Serial.println(SmsStorePos); 

    // EN: Ask to read the SMS store 
    GprsReadSmsStore(SmsStorePos); 
    } 

    // EN: SMS store read via UART (result of GprsReadSmsStore request) 
    if(msg.indexOf("+CMGR:") >= 0){ 
    // get number of sender 
    int snPos = msg.indexOf("+1"); 
    Serial.print("SMS From: "); 
    snTmp = msg.substring(snPos+1); 
    snFull = ""; 
    for (int i = 0; i < 11; i++){ 
     snFull += snTmp[i];  
    } 
    Serial.println(snFull); 

    // EN: Next message will contains the BODY of SMS 
    SmsContentFlag = 1; 
    // EN: Following lines are essentiel to not clear the flag! 
    ClearGprsMsg(); 
    return; 
    } 

    // EN: +CMGR message just before indicate that the following GRPS Shield message 
    //  (this message) will contains the SMS body 
    if(SmsContentFlag == 1){ 
    Serial.println("*** SMS MESSAGE CONTENT ***"); 
    Serial.println(msg); 
    Serial.println("*** END OF SMS MESSAGE ***"); 
    ProcessSms(msg); 
    delSMS(); 
    } 

    ClearGprsMsg(); 
    // EN: Always clear the flag 
    SmsContentFlag = 0; 
} 
void delSMS() { 
    mySerial.print("AT+CMGD="); 
    mySerial.println(SmsStorePos); 
} 

私はシリアルモニターで見ているものです::

http://imgur.com/i5jEPds

+0

これは電源/接地の問題である可能性があります。 2つのデバイスの電源はどのようになっていますか?彼らは同じ供給を共有していますか? DCコンバータまたはバッテリを使用していますか?十分な電源デカップリング(コンデンサ)がありますか?十分な地面?これらのすべてのことが重要です。特にボーレートが速い場合は、ノイズが激しくなります。 – Floris

+0

これらは同じ12V 2Aの安定化された電源を切ってArduinoに入り、その後5V/GNDをGSMモジュールに引き込みます。 私はそれを考え出したと思います。私はいくつかの読書をして、SoftwareSerialが19200以上のボードのために信頼できないように見えるので、シリアルラインをSoftwareSerialに交換し、Arduinoがハードウェアシリアル(シリアル)上のGSMモジュールと通信することを試みました。 ブーム!ゴミはこれ以上ありません。 GPRSメッセージ: + G:0084E9971343964396971397169716971697161009797439643969797139713 – mabnz

+0

...(今すぐ)モデムから古くなった長い文字列を取得しています(+ CMTI私は期待して)、例えば: GPRSメッセージ:[ + G:0084E9971343964396971397169716971697161009797439643969797139713] – mabnz

答えて

7

SoftwareSerialは、タイミングと意志について悪名うるさいですがここで

は、私が使用しているArduinoのコードですあなたが "あまりにも多くの"ことが同時に起こっている時を記述するような問題を引き起こします。それはおそらくあなたの側で他のものをやっているので、同期が外れてしまいます。

AltSoftSerial(http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html)の方がはるかに優れていますが、信頼性を高めるには少し低いボーレートを使用することをお勧めします。ボーレートが高すぎると、1ビットを逃さないために非常に正確なタイミングが必要となり、ハードウェアはソフトウェアでシリアルトラフィックを問題なく実行できるほど強力ではありません。

+1

AdafruitのCC3000でこの問題が発生し、ボーレートを115200から9600に下げると、すぐに文字化けしたテキストを解読するのに役立ちましたので、これを+1しました。シリアルモニタのボーレート設定があなたのスケッチと同じであることを確認してください。 – kunalbhat

7

"ボー"の設定がスケッチと一致していることを確認してください。

例:Serial.begin(115200); >>>>コンソールの115200ボー。

私はkunalbhatの上記のコメントからこの解決法を得ました。しかし私はそれを私の問題を解決したのでスタンドアローンの回答として掲示したいと思っていました。だから私はそれが他の多くの人々に役立つだろうと思う。

0

私が前に言った9600

Serial.begin(9600); 
1

ように私の「ボー」の設定を変更しなければならなかった、問題は(シリアルcommunication-別の答えに関係しています)、「ボー」設定です。これはあなたのスケッチの上部にある(一般的に)見つけることができる、と次のようになります。

Serial.begin(9600); 

またはこの:Arduinoの宇野、「ボー」設定の場合には

Serial.begin(115200); 

9600以外の文字は文字化けします。そのように、あなたのスケッチの冒頭で、あなたはラインを持っていることを確認してください。

Serial.begin(9600); 

は、あなたがそれ以上の助けを必要とするかどうか尋ねること自由に感じています。

1

私はArduinoを使ってATtiny84をプログラムしていましたが、Arduinoをリセットするまで、第1行の後に出力が乱れていたり、シリアルが停止していました。

問題はArduinoがATtiny84から入ってくるシリアルデータを妨害していた「Arduino as ISP」スケッチを読み込んでいたことでした。

Arduinoに空白のスケッチをアップロードすると修正されました。

0

私はメガのハードウェアシリアルに戻って動作させる必要がありました。メガにSWシリアル

ハードウェアシリアルsim900と幸運を持っていなかっ:sim900上 //真ん中のRX/TXピンはメガ

+0

訂正:SoftwareSerial GPRS(10,11); /// sim900のRX/TX中間ピンからメガに10,11を移動する – lagunacomputer

+0

[コメントは一時的であり、いつでも削除することができます](https://stackoverflow.com/help/privileges/comment)注意してください。修正が必要な場合は、投稿の下の** [編集] **リンクをクリックして回答を更新してください。 [詳細はこちら](https://meta.stackexchange.com/q/19756/204869)をご覧ください。ありがとうございました。 – Pang

1

理由は、コマンドを設定する必要がある、ということである上TX1/RX1端子へAT + UART_DEF = 9600,8,1,0,0 ESPのボーを9600にリセットするか、AT + CIOBAUD = 9600を使用することもできます。
それを試して、それは私のために働いている!
いくつかのESP-01とESP-12モジュールでAT + IPRを試してみましたが、時にはうまくいきませんでした(実際には悪いケースではボーレートが完全に変わります)!

+0

コメントはありませんか?いくつかのポイントを追加してください。 – surajsn

+0

AT + IPR = 9600は、1つのElecrow GSM/GPRSシールド(SIMcom SIM800Cチップに基づく)上の文字化けしたI/Oに関する私の問題を解決しました。 – unserializable

関連する問題