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...
}
-
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– Majenko2017年08月22日 09:06:52 +00:00Commented 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.user3613833– user36138332017年08月23日 13:49:36 +00:00Commented Aug 23, 2017 at 13:49
2 Answers 2
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;
}
}
}
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.