16

我已经将 ADH8066 (Sparkfun) GSM 模块连接到我的 Arduino Uno,并试图在 Arduino 和 GSM 模块之间进行一些正确的串行传输。当我直接连接到它(通过 USB 或仅通过 TTL 线)时它工作正常,但在通过 Arduino 控制时却不行。一些文本将正确输出,其余文本将出现乱码,几乎就像波特率错误一样,但我只是使用与从 PC 连接时相同的波特率 (115200)。

这是我正在使用的 Arduino 代码:

#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

4

9 回答 9

10

确保“波特”设置与您的草图相匹配。

例如:Serial.begin(115200);>>>> 115200 波特在控制台。

我从 kunalbhat 上面的评论中得到了这个解决方案。但我想把它作为一个独立的答案发布,因为它解决了我的问题,而且我从来没有想过。所以我认为它会帮助很多其他人。

于 2015-02-08T22:47:58.380 回答
7

SoftwareSerial 对时间的挑剔是出了名的,当“太多”同时发生时,它会导致像你描述的那样的问题。它可能会因为您正在做其他事情而变得不同步。

我强烈推荐 AltSoftSerial ( http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html ),它的性能要好得多,但我仍然建议您使用稍低的波特率来提高可靠性。太高的波特率将需要非常精确的时序才能不遗漏任何一个位,并且硬件功能不足以在软件中进行串行通信而不会出现问题。

于 2013-08-13T10:09:15.390 回答
2

原因是,你需要设置命令AT+UART_DEF=9600,8,1,0,0将 ESP 的波特率重置为 9600,或者你也可以使用AT+CIOBAUD=9600
试试看,它对我有用!
我在一些 ESP-01 和 ESP-12 模块上尝试过AT+IPR,有时它可以工作,有时不能(在非常糟糕的情况下,波特率完全改变了)!

于 2017-05-15T05:06:09.940 回答
2

如前所述,问题在于“波特”设置(与串行通信有关——另一个答案)。这可以(通常)在草图的顶部找到,可能如下所示:

Serial.begin(9600);

或这个:

Serial.begin(115200);

对于 Arduino Uno,9600 以外的“波特”设置将导致文本乱码。因此,请确保在草图的开头,您有以下行:

Serial.begin(9600);

随时询问您是否需要任何进一步的帮助。

于 2016-08-22T02:19:59.980 回答
1

我正在使用 Arduino 对 ATtiny84 进行编程,但输出出现乱码或串行在第一行之后停止,直到我重置 Arduino。

问题是 Arduino 加载了“Arduino as ISP”草图,这干扰了来自 ATtiny84 的串行数据。

将空白草图上传到 Arduino 修复了它。

于 2016-10-25T21:42:35.780 回答
0

我必须回到我的兆上的硬件串行才能让它工作。sw系列从来没有好运

硬件串行 sim900 到 mega: //middle rx/tx pin on sim900 to pin tx1/rx1 on mega

于 2017-03-23T01:09:03.920 回答
0

我不得不将我的“波特”设置更改为 9600。

Serial.begin(9600);
于 2015-08-01T12:36:23.153 回答
0

尝试在 Raspberry Pi 3b 上接收来自 Arduino 的串行消息时,我遇到了同样的问题。

在一种情况下,我发现我使用的是旧版本的 Arduino IDE。我从 Arduino 网站下载了最新的 ARM 32 位版本,它解决了这个问题。

在另一种情况下,事实证明在 Pi 上切换它所连接的 USB 端口解决了这个问题。

于 2021-09-14T23:11:43.793 回答
0

您应该使用串行库,而不是软件串行。Serial 是 Arduino IDE 中的官方版本,默认包含在每个程序中。确保显示器和程序的波特率相等,这是乱码的常见错误。9600 是推荐的波特率,您可以使用 Serial.begin(9600)、Serial.read()、Serial.print("") 和 Serial.println("") 等命令。

于 2020-02-21T20:03:43.983 回答