Arduino - искаженный серийный выход

Я подключил GSM-модуль ADH8066 (Sparkfun) к своему Arduino Uno, и я пытаюсь получить правильный последовательный переход между модулем Arduino и GSM. Он отлично работает, когда я подключаюсь к нему напрямую (через USB или только линии TTL), но не при управлении через Arduino. Некоторый текст будет выводиться корректно, остальные будут искажены, почти так же, как если бы скорость передачи была неправильной, но я просто использую тот же бод (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

Ответ 1

SoftwareSerial заведомо придирчивы к срокам и вызовет проблемы, которые вы описываете, когда "слишком много" происходит одновременно. Вероятно, он выходит из строя из-за того, что вы делаете другие вещи сбоку.

Я горячо рекомендую AltSoftSerial (http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html), который работает намного лучше, но я все же предлагаю вам использовать несколько более низкие скорости передачи для повышения надежности. Слишком высокие скорости передачи данных потребуют очень точного времени, чтобы не пропустить ни одного бита, а аппаратное обеспечение недостаточно мощное, чтобы без проблем выполнять последовательный трафик в программном обеспечении.

Ответ 2

Убедитесь, что настройка "бод" соответствует вашему эскизу.

Пример: Serial.begin(115200); → → 115200 бод в консоли.

Я получил это решение из комментария выше от kunalbhat. Но я хотел опубликовать его как автономный ответ, потому что он решил мою проблему, и мне это никогда не приходило в голову. Поэтому я думаю, что это поможет многим другим людям.

Ответ 3

Как уже было сказано, проблема связана с настройкой "бод" (что связано с последовательной связью - другой ответ). Это можно найти (обычно) в верхней части эскиза и может выглядеть так:

Serial.begin(9600);

Или это:

Serial.begin(115200);

В случае Arduino Uno установка "бод", отличная от 9600, приведет к искажению текста. Как таковой, убедитесь, что в начале вашего эскиза у вас есть строка:

Serial.begin(9600);

Не стесняйтесь спрашивать, нужна ли вам дополнительная помощь.

Ответ 4

Я использовал Arduino для программирования ATtiny84, но получал искаженный вывод или серийный номер останавливался после первой строки, пока я reset Arduino.

Проблема заключалась в том, что у Arduino был загружен эскиз "Arduino as ISP", который мешал последовательным данным, поступающим с ATtiny84.

Загрузка пустого эскиза в Arduino исправила его.

Ответ 5

Причина в том, что вам нужно установить команду AT + UART_DEF = 9600,8,1,0,0 на reset бод ESP на 9600, или вы также можете использовать AT + CIOBAUD = 9600!
Попробуйте, это работает для меня!
Я пробовал AT + IPR на некоторых модулях ESP-01 и ESP-12, иногда это работает, а иногда нет (и в самом деле плохо случай, полное изменение бода)!

Ответ 6

Мне пришлось изменить настройки "бод" на 9600.

Serial.begin(9600);

Ответ 7

Мне пришлось вернуться к серийному аппарату на моем мега, чтобы заставить его работать. никогда не было удачи с серийной серией

аппаратный серийный sim900 для мега:  // контакты среднего rx/tx на sim900 для вывода tx1/rx1 на мега