Hello all!
I am currently working on a project that needs to send and receive SMS. For this, I use a SIM800L module, which communicates through serial. As I need to make my final project as little as possible, I have decided to work on a nano.
So in the end, I need to use the SoftwareSerial library.
When I use my arduino as a serial relay, I have no problem. Everything works fine. I use this to test the commands before writing them in the final code.
Here is the code:
#include <SoftwareSerial.h>
SoftwareSerial gsm(7,8);
void setup() {
gsm.begin(9600);
Serial.begin(9600);
}
void loop() {
if(Serial.available()) gsm.print(Serial.readString());
if(gsm.available()){
String temp=gsm.readString();
Serial.print(temp);
for(int i=0; i<temp.length(); i++){
Serial.print(temp[i],DEC);
Serial.print(" ");
}
Serial.println();
}
}
As my code is pretty long, I have decided to write a library (by the way, I couldn't find an existing library working for me...). I successfully send SMS but when it comes to receive them, I have issues. Some characters are lost. I tried to extend the buffer size but same result... I really put all my knowledge on this, I really can't fix this.
Moreover, it happens that the arduino stops running, it looks like it is in an infinite loop but I haven't find where.
Has anyone a solution for me?
Here are the files (.h and .cpp) I'm writing. They are messy but understand this is a work in progress.
.h file:
//GSM_Balise.h
#include <Arduino.h>
#include <SoftwareSerial.h>
#ifndef GSM_Balise_h
#define GSM_Balise_h
class GSM_Balise:public SoftwareSerial{
private:
//String pinCode="8076";
unsigned long _startMillis;
unsigned long _timeout=1000;
public:
GSM_Balise(uint8_t rx=7, uint8_t tx=8);
int GSMTimedRead();
String GSMReadString();
void update();
void unlock(String _pinCode="8076");
void toTextMode();
void sendSMS(String _text, String _num="+32xxxxxxxxx");
void SMS();
void reset();
uint8_t resetPin=6;
bool unlocked=false;
bool SMSOk=false;
bool callOk=false;
bool textMode=false;
bool flagSendSMS=false;
bool texting=false;
bool waitSMSSending=false;
bool SMSWritten=false;
bool SMSAvailable=false;
char rawData;
String text;
String num;
String data[10];
};
#endif
.cpp file:
#include <GSM_Balise.h>
GSM_Balise::GSM_Balise(uint8_t rx, uint8_t tx)
: SoftwareSerial(rx, tx){
SoftwareSerial::begin(9600);
pinMode(resetPin,OUTPUT);
digitalWrite(resetPin,HIGH);
}
int GSM_Balise::GSMTimedRead(){
int c;
_startMillis = millis();
do {
c = read();
Serial.print(c); Serial.print(' ');
if (c >= 0) return c;
} while(millis() - _startMillis < _timeout);
return -1; // -1 indicates timeout
}
String GSM_Balise::GSMReadString()
{
String ret;
int c = GSMTimedRead();
while (c >= 0)
{
if(c==10) return ret;
if(c!=10 && c!=13) ret += (char)c;
c = GSMTimedRead();
}
return ret;
}
void GSM_Balise::update(){
if(flagSendSMS) SMS();
//if(available()) Serial.print(readString());
if(available()){
String temp=GSMReadString();
if(temp!=" " && temp!=""){
for(int i=10; i>0; i--){
data[i]=data[i-1];
}
data[0]=temp;
}
/*for(int i=0; i<10; i++){
Serial.print(" message "); Serial.print(i); Serial.print(" : ");Serial.print(data[i]);
}
Serial.println();*/
/*do{
rawData=read();
if(rawData!='\r'&& rawData!='\n') data[0]=data[0]+rawData;
delay(5);
}while(rawData != '\n' && available());
delay(50);
Serial.println(data[0]);
for(int i=0; i<data[0].length(); i++){
Serial.print(data[0][i],DEC);
Serial.print(" ");
}
Serial.print('\n');*/
if(data[0]=="+CPIN: READY") {unlocked=true;}
else if(data[0]=="Call Ready") {callOk=true;}
else if(data[0]=="SMS Ready") {SMSOk=true;waitSMSSending=false;}
else if(data[0]=="OK" && data[1]=="AT+CMGF=1") {textMode=true;waitSMSSending=false;}
else if(data[0]=="AT+CMGS=\""+num+"\"") {texting=true;waitSMSSending=false;}
else if(data[0]==("> " + text)) {SMSWritten=true;waitSMSSending=false;}
if(available()==0){
for(int i=0; i<10; i++){
Serial.print(" message "); Serial.print(i); Serial.print(" : ");Serial.print(data[i]);
}
Serial.println();
}
}
//delay(1000);
}
void GSM_Balise::unlock(String _pinCode){
println("AT+CPIN=\""+_pinCode+"\"");
}
void GSM_Balise::toTextMode(){
println("AT+CMGF=1");
}
void GSM_Balise::sendSMS(String _text, String _num){
num=_num;
text=_text;
flagSendSMS=true;
}
void GSM_Balise::SMS(){
if(!SMSOk && waitSMSSending==false) {unlock(); waitSMSSending=true;}
if(SMSOk && !textMode && waitSMSSending==false) {toTextMode(); waitSMSSending=true;}
if(textMode && !texting && waitSMSSending==false){
println("AT+CMGS=\""+num+"\"");
texting=true;
waitSMSSending=true;
}
if(texting && !SMSWritten && waitSMSSending==false){
println(text);
SMSWritten=true;
waitSMSSending=true;
}
if(SMSWritten && waitSMSSending==false){
write(26);
Serial.println("SMS sent");
flagSendSMS=false;
delay(200);
reset();
}
delay(100);
}
void GSM_Balise::reset(){
digitalWrite(resetPin,LOW);
delay(100);
digitalWrite(resetPin,HIGH);
delay(4000);
}
.ino file:
#include <GSM_Balise.h>
GSM_Balise gsm(7,8);
unsigned long temps;
void setup() {
Serial.begin(9600);
//gsm.reset();
//gsm.unlock();
//gsm.toTextMode();
//gsm.sendSMS("ESSAI","+32xxxxxxxxx");
//Serial.println("send request: " + gsm.text + " to " + gsm.num);
pinMode(13,OUTPUT);
digitalWrite(13,HIGH);
temps=millis();
}
void loop() {
// put your main code here, to run repeatedly:
gsm.update();
//if(gsm.textMode) Serial.println("text mode ok");
if(Serial.available()){
String temp=Serial.readString();
gsm.print(temp);
}
delay(100);
if(millis()-temps>500){ //used only to verify the arduino is still runing
temps=millis();
digitalWrite(13, !digitalRead(13));
}
}
Thank's by advance,
Yann.
PS: sorry for the lack of comments... Really sorry!