3

i'm working on project where i'm trying to achieve that arduino parse caller ID so i can use it later to send SMS with sensor reading data.

Somehow i made that code (with much googling) and it works great... But when i include arduino sleep part, it does work at beginning, but after i call SIM800 4-5 times with distinct of 30 seconds, i get unusable data on Serial, so i can't no longer parse correct number.

I tried many things, dropping baud rate to 1200, changing delay, but still i get strange characters after few calls.

Can anyone help me?

P.S. ATMEGA328P ic MCU

Thank you, Matija

#include <SoftwareSerial.h>
#include <avr/sleep.h>


SoftwareSerial SIM800(8, 7);

String buffer1;
unsigned int current_millis = 0;
String phone;

void setup() {
     buffer1.reserve(200);
     phone.reserve(20);

     Serial.begin(19200); //
     SIM800.begin(9600);
     delay(1000);
     SIM800.write("AT\r");  // because of SIM800L autobounding mode
     delay(1000);
     SIM800.write("AT+IPR=9600\r");  // set baud at 9600, i tried with 1200 
     and  other, and with autobauding but still got same problem
     delay(1000);
     SIM800.write("AT+CMGF=1\r");  // set SMS mode to text
     delay(1000);
     SIM800.write("AT+CNMI=2,2,0,0,0\r");
     delay(1000);
     Serial.print(SIM800.readString());
     SIM800.write("AT+CLIP=1\r\n");
     delay(1000);
     SIM800.write("AT+SGPIO=0,7,1,0\r");
     delay(1000);
     SIM800.write("AT+CSCLK=2\r"); //power saving mode of SIM800L
     delay(1000);
     current_millis = millis();
}

void loop() {
   // put your main code here, to run repeatedly:
   if (SIM800.available() > 0) {
      buffer1 = SIM800.readStringUntil('\n'); //Saving string then parsing 
           caller number from it
      Serial.println(buffer1);
      parse();
      current_millis = millis();
      }

    if ((millis() - current_millis) > 10000) { //Putting atmega tu sleep
       sleepNow();
       delay(1000);// tried many delays
       current_millis = millis();
     }

 }

void parse() {
    if (buffer1.indexOf("CLIP:") > 0) {
        phone = buffer1.substring(buffer1.indexOf("+CLIP: ") + 8, 
        buffer1.indexOf("+CLIP: ") + 21); //parsing caller number
        Serial.println(phone);
        SIM800.write("ATH\r"); //hang out phone call
        delay(500);
        SIM800.write("ATH\r");
        delay(500);
  }

}

void sleepNow() { //PIN CHANGE INTERRUPT ON PIN 7,8 BECAUSE SOFTWARE SERIAL 
                   LIBRARY USE IT AND IT WILL WAKE UP ATMEGA
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // sleep mode is set herethe 
                                          sleep bit in the mcucr register
    sleep_mode();            // here the device is actually put to sleep!!
                         // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
    sleep_disable();         // first thing after waking from sleep: disable 
                                sleep...
    }

Serial OUTPUT

bumped to the homepage by Community 9 hours ago

This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.

  • With SoftwareSerial it's anyone's guess what may be going on. Add some extra Serial.println() calls with static text in them to work out if the fault is PC => Arduino or Arduino => SIM800. – Majenko Aug 22 '17 at 9:06
  • Hi Majenko, error is between Arduino and SIM800 (i know because phone call isn't ATH when it should be). I tried your solution but it didn't work... I tried also SIM800.end() and SIM800.begin(9600) before putting arduino to sleep...It doesn't work... Only thing that work for me is reseting arduino after doing the job. Adding void(* resetFunc) (void) = 0; after setup function, and call it resetFunc(); after i send message to caller. Thank you, if you have any idea which solves thing problem better post it here, maybe it will help someone. – user3613833 Aug 23 '17 at 13:49
0

Give AltSoftSerial a try, it's hands down superior.

Reset might work but it does not actually solve your problem, it just swipes it under the mattress. Also, have you considered ditching that String? It is the source of many problems regarding memory. You could relatively easily substitute it for an array of chars instead. Something like this, taken from example#2:

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;

    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}
0

When you use sleep mode SLEEP_MODE_PWR_DOWN you're turning off all of the microcontroller's timers, Including the timer SoftSerial is using. I expect that turning off and then when wake from sleep turning back on the timers is affecting the timing of your serial communications.

Try using SLEEP_MODE_IDLE instead of SLEEP_MODE_PWR_DOWN and see if it corrects the problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.