4

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

asked Aug 21, 2017 at 21:49
2
  • 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. Commented Aug 22, 2017 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. Commented Aug 23, 2017 at 13:49

2 Answers 2

1

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;
 }
 }
}
answered Sep 21, 2018 at 10:01
1

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.

answered Nov 20, 2018 at 14:28

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.