SMS_SS - a-gsm 2.064 send/read/list SMS example utility COPYRIGHT (c) 2014 Dragos Iosub / R&D Software Solutions srl You are legaly entitled to use this SOFTWARE ONLY IN CONJUNCTION WITH a-gsm DEVICES USAGE. Modifications, derivates and redistribution of this software must include unmodified this COPYRIGHT NOTICE. You can redistribute this SOFTWARE and/or modify it under the terms of this COPYRIGHT NOTICE. Any other usage may be permited only after written notice of Dragos Iosub / R&D Software Solutions srl. This SOFTWARE is distributed is provide "AS IS" in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Dragos Iosub, Bucharest 2014. http://itbrainpower.net In order to make your Arduino serial communication reliable (especially for Arduino Uno) with a-gsm shield, you must edit: C:\Program Files\Arduino\libraries\SoftwareSerial\SoftwareSerial.cpp comment the line 42 #define _SS_MAX_RX_BUFF 64 this, will look after that like: //#define _SS_MAX_RX_BUFF 64 and add bellow the next line: #define _SS_MAX_RX_BUFF 128 You just increased the RX buffer size for UNO and other "snails". Now you can compile and upload your code supporting highier buffered serial input data. //#define atdebug //uncomment this line if you want to catch OK/ERROR/TIMEOUT modem response //modify the next 2 line to be convenient for you char message[]="hi!\r\nthis message has been sent from a-gsm v2.064 Arduino shield connected with my Arduino board."; //no more than 160 chars -text SMS maximum lenght char destinationnumber[]="+40123456789"; //usually phone number with International prefix eg. +40 for Romania - in some networks you must use domestic numbers #define powerpin //#define resetpin #define statuspin 7//Arduino Digital pin used to power up / power down the modem 6//Arduino Digital pin used to reset the modem 5//Arduino Digital pin used to monitor if modem is powered #define RXSoft 2 //RX soft -used for software communication #define TXSoft 3 //TX soft -used for software communication #include <SoftwareSerial.h> typedef struct { -1-
int nosms; int totsms; simmsms; simmsms SSMS = {0,0; int sendsms(char* phno, char* phtype, char* message); void readsimm(void); void setupmodemforsmsusage(void); void listsmsstatus(void); do not change under this line! Insteed, make one copy for playing with. int state=0, i=0, powerstate = 0; char ch; char buffd[256]; char IMEI[18]; unsigned long offsettime; int totalchars = 0; SoftwareSerial SSerial(RXSoft, TXSoft); //setup software serial for modem communication utility for sending SMS phno - destination phone number, international format eg.:+40123456789 - char* phtype - destination phone number type 129 (international)/ 147(domestic) - char* message -...what you want to transmit in your SMS :)) - max. 160 chars - char* returns 1 for SUCCESS 0 for FAILURE int sendsms(char* phno, char* phtype, char* message){ return SUCCESSorFAILURE; setupmodemforsmsusage() -utility to set up the modem for SMS (text mode) usage void setupmodemforsmsusage(){ utility for listing SMS (received) from memmory store into SSMS the used/total SMSs SSMS.noSMS --- used SMS (locations)... if >0, we have something to read :) SSMS.totSMS --- total SMS (locations) void listsmsstatus(){ clear buffd preparing it for writing void clearbuffd(void){//just clear the data buffer memset(buffd, 0x00, sizeof(buffd)); -2-
send command -cmd to themodem, waiting Delay_mS msecs after that size_t agsmcmd(char* cmd, int Delay_mS){ send string -str to the modem, NOT ADDING \r\n to the line end size_t agsmwrite(char* str){ return read char from the modem inline char agsmread(void){ Receive data from serial until event: SUCCESS string - 1'st argument FAILURE string - second argument TIMEOUT - third argument in secconds! return: int -1 TIMEOUT 0 FAILURE 1 SUCCESS the string collected from modem => buffd int recuartdata( char* ok, char* err, int to){ return(cmdsuccescode); send AT command, looking for SUCCES STRING(1'st) or FAILURE STRING(second), and TIMEOUT(third) return 1 for succes, 2 for failure, -1 for timeout modem response is loaded in buffd int sendatcommand(char* outstr, char* ok, char* err, int to){ res = recuartdata( ok, err, to); return(res); bool TXavailable(){ return(charsavailableforread); just print debug to Serial void printdebugln(char* what){ Serial.println(what); utility that load into IMEI var the modem IMEI void getimei(){//at+gsn -3-
Arduino hardware setup utility void setup(){ here is the main code void loop(){ char somebuffer[161]; int SMSindex = 1; char * pch0; char * pch1; int res; int i; switch(state){ case 0://check modem status, power it if necessary if(!digitalread(statuspin)) restartmodem(); else i=0; res= 0; while(res!= 1){ res = sendatcommand("at","ok","error",2); if (res!= 1) { if(i++ >= 10) restartmodem(); delay(500); sendatcommand("at+ipr=19200;&w","ok","error",2); delay(2000); case 1://next some init strings... agsmcmd("at+qimode=0",200); agsmcmd("at+qindi=0",200); agsmcmd("at+qimux=0",200); agsmcmd("at+qidnsip=0",200); offsettime=0; case 2://stop if PIN is requested printdebugln("try CPIN..."); if(!offsettime) if ((millis() - offsettime) > 20000) restartmodem(); agsmcmd("at+cpin?",200); i = 0; while(txavailable()){ ch = agsmread(); buffd[i] = ch; i++; -4-
//printdebugln(buffd); delay(100); if(strstr(buffd,"ready")) { offsettime=0; printdebugln("ready"); else { delay(100); case 3: //is the modem registered? getimei();//just for fun if(!offsettime) if ((millis() - offsettime) > 30000) restartmodem(); printdebugln("query GSM registration?"); agsmcmd("at+creg?",1000);//gsm network registration i = 0; while(txavailable()){ ch = agsmread(); buffd[i] = ch; i++; //printdebugln(buffd); delay(100); if(strstr(buffd,"0,1")) { offsettime=0; printdebugln("ready"); else { case 4: //it is SIM/MODEM full initialised? printdebugln("query State of Initialization"); agsmcmd("at+qinistat",200); i = 0; while(txavailable()){ ch = agsmread(); buffd[i] = ch; i++; if(strstr(buffd,"3")) { offsettime=0; printdebugln("ready"); delay(100); else {printdebugln("not yet..."); delay(1000); delay(100); -5-
case 5://Initialize the modem for DTMF receive usage if(!offsettime) if ((millis() - offsettime) > 5000) restartmodem(); printdebugln("let's prepare modem for SMS usage! Wait 10-11 seconds, please!"); setupmodemforsmsusage(); delay(10000); case 6://let's send one SMS to the destination receipment if(!offsettime) if ((millis() - offsettime) > 5000) restartmodem(); printdebugln("let's send one SMS to the destination receipment!"); delay(100); //if(sendsms(destinationnumber,"147",message)==1) printdebugln("test SMS has been send with succees!"); if(sendsms(destinationnumber,"129",message) == 1) printdebugln("test SMS has been send with succees!"); else printdebugln("sms send FAILURE"); delay(10000); case 7://let's read SMSs from active memmory printdebugln("let's find SMS storage usage!"); delay(100); listsmsstatus(); printdebugln(buffd); delay(5000); case 8://let's read one SMS printdebugln("let's read one SMS!"); delay(100); //start READ SMS SMSindex = 1;//h used as SMS index here we read only first index... h >=1, h<=sms.totsms!!!! sprintf(buffd,"at+cmgr=%i,0\r",smsindex);//format the read command... with SMS status changing(second argument) from REC UNREAD to REC READ -6-
agsmwrite(buffd);//send command to modem recuartdata("ok","error",5);//receive modem's response...in buffd //end read SMS printdebugln("modem response:"); printdebugln(buffd);//let's see what modem say //let's extract the message memset(somebuffer,0x00,sizeof(somebuffer)); pch0 = strstr(buffd,"\"\r\n"); pch1 = strstr(buffd,"\r\nok"); strncpy(somebuffer, pch0+3, pch1-pch0-4); printdebugln("list message:"); printdebugln(somebuffer);//here is the message... //end extract the message delay(15000); default: //restartmodem(); delay(10000); state=0; just flush remaining chars from serial void clearhdserial(){ //..function code here -7-