2013-07-27 18 views
11

Podłączyłem moduł GSM ADH8066 (Sparkfun) do mojego Arduino Uno i próbuję uzyskać poprawne połączenie pomiędzy Arduino i modułem GSM. Działa to dobrze, gdy podłączam się do niego bezpośrednio (przez USB lub tylko linie TTL), ale nie podczas sterowania przez Arduino. Niektóre teksty będą wyprowadzane poprawnie, reszta będzie zniekształcona, prawie tak, jakby szybkość transmisji była nieprawidłowa, ale używam tego samego baud (115200), co robię, gdy podłączam się z komputera.Arduino - zniekształcone wyjście szeregowe

Oto kod Arduino Używam:

#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); 
} 

Poniżej jest to, co widzę na monitorze seryjny:

http://imgur.com/i5jEPds

+0

Może to być problem z zasilaniem/uziemieniem. Jak zasilane są te dwa urządzenia? Czy dzielą tę samą dostawę? Czy używasz konwertera DC lub baterii? Czy masz wystarczające odłączenie zasilania (kondensatory)? Wystarczająco dobry teren? Wszystkie te rzeczy mają znaczenie, szczególnie gdy masz szybką prędkość transmisji - mały szum dźwiękowy wyrzuci wszystko. – Floris

+0

Są one zasilane z tego samego zasilania regulowanego 12V 2A, przechodząc do Arduino, a następnie wyciągam 5V/GND do modułu GSM. Wydaje mi się, że to wymyśliłem. Zrobiłem trochę czytania i wygląda na to, że SoftwareSerial jest niewiarygodny dla bod powyżej 19200, więc próbowałem zamieniać linię szeregową na SoftwareSerial i dla Arduino komunikować się z modułem GSM przez szeregowy sprzęt (Serial). Bum! Nigdy więcej śmieci. Teraz po prostu wyrzucam śmieci z modemu, takie jak: Wiadomość GPRS: [ + G: 0084E9971343964396971397169716971697161009797439643969797139713] – mabnz

+0

... (ciąg dalszy) Teraz po prostu staję się starym długopisem z modemu (zamiast + CMTI spodziewam), takie jak: GPRS Wiadomość: [ + G: 0084E9971343964396971397169716971697161009797439643969797139713] – mabnz

Odpowiedz

7

SoftwareSerial jest notorycznie wybredna o czas i będzie powodować problemy, jak opisujesz, kiedy "za dużo" dzieje się w tym samym czasie. Prawdopodobnie nie jest zsynchronizowany, ponieważ robisz inne rzeczy na boku.

Gorąco polecam AltSoftSerial (http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html), który działa znacznie lepiej, ale nadal sugeruję, abyś używał nieco niższych prędkości transmisji, aby zwiększyć niezawodność. Zbyt wysokie szybkości transmisji będą wymagały bardzo dokładnego taktowania, aby nie przegapić ani jednego bitu, a sprzęt nie jest wystarczająco silny, by wykonywać seryjny ruch w oprogramowaniu bez problemów.

+1

I + 1'ed to, ponieważ doświadczałem tego problemu z CC3000 Adafruit, a obniżenie szybkości transmisji z 115200 do 9600 pomogło natychmiast rozszyfrować zniekształcony tekst. Tylko upewnij się, że ustawienie szybkości transmisji w Serial Monitor odpowiada temu, co masz w szkicu. – kunalbhat

7

Upewnij się, że ustawienie "baud" odpowiada szkicowi.

Ex: Serial.begin (115200); >>>> 115200 bodów w konsoli.

Mam to rozwiązanie z powyższego komentarza od kunalbhat. Ale chciałem opublikować to jako samodzielną odpowiedź, ponieważ rozwiązało to mój problem i nigdy by mi nie przyszło. Myślę więc, że pomoże to wielu innym ludziom.

0

musiałem zmienić ustawienia „baud” do 9600.

Serial.begin(9600); 
1

jak zostało powiedziane wcześniej, problem jest z „transmisji” ustawienia (który ma do czynienia z seryjnym komunikacji-kolejna odpowiedź). Można go znaleźć (zazwyczaj) w górnej części szkicu i może wyglądać następująco:

Serial.begin(9600); 

Albo to:

Serial.begin(115200); 

W przypadku Arduino Uno, a „transmisji” ustawienia inne niż 9600 spowoduje nieczytelny tekst. W związku z tym upewnij się, że na początku szkicu masz linię:

Serial.begin(9600); 

Możesz zapytać, czy potrzebujesz dodatkowej pomocy.

1

Użyłem Arduino do zaprogramowania ATtiny84, ale otrzymywałem zniekształcone wyjście lub serial zatrzymywał się po pierwszej linii, dopóki nie zresetowałem Arduino.

Problem polegał na tym, że Arduino miał załadowany szkic "Arduino jak ISP", który zakłócał dane szeregowe nadchodzące z ATtiny84.

Załadowanie pustego szkicu do Arduino poprawiło to.

0

Musiałem wrócić do seryjnego sprzętu na moim mega, aby go uruchomić.Nigdy nie miałem szczęścia z SW szeregowego

hardware SIM900 Mega: // środkowe piny RX/TX na SIM900 przypiąć TX1/RX1 na mega

+0

korekta: SoftwareSerial GPRS (10, 11); /// pinów goto 10,11 na mega od środkowych pinów RX/TX na sim900 – lagunacomputer

+0

Należy pamiętać, że [komentarze są tymczasowe i mogą zostać usunięte w dowolnym momencie] (https://stackoverflow.com/help/privileges/comment). Jeśli chcesz wprowadzić poprawki, zaktualizuj odpowiedź, klikając link ** "[edit]" pod postem. [Zobacz tutaj] (https://meta.stackexchange.com/q/19756/204869) w celu uzyskania szczegółowych informacji. Dziękuję Ci. – Pang

1

Powodem jest to, że trzeba ustawić komendę AT + UART_DEF = 9600,8,1,0,0, aby zresetować szybkość ESP do 9600, lub można również użyć AT + CIOBAUD = 9600!
Spróbuj, działa dla mnie!
Próbowałem już AT + IPR na niektórych modułach ESP-01 i ESP-12, czasami działa, a czasami nie (aw naprawdę złym przypadku, baud całkowicie się zmienia)!

+0

Czy to nie jest komentarz? Dodaj więcej punktów. – surajsn

+0

AT + IPR = 9600 rozwiązał moje problemy z zniekształconymi I/O na jednej tarczy Elecrow GSM/GPRS (w oparciu o układ SIMCom SIM800C). – unserializable