Introduction:
This is first time in the forum I am going to present the M2M communication principle using Wavecom modem. I will post same using SIMCOM900 modem later on. This project can help anyone to develop web based application of microcontroller which is very popular in the recent times. I have although tried to clear any possible limitation of the program for the reliability of the communication even though some experts could notice some limitation of the code. I will appreciate any positive or negative comment in the code to make it more robust..
Circuit Connection
EB006-00-07 board
EB005 LCD board
EB015 RS232 board
Modem: Wavecom Fastrack Supreme 10 or 20 connected to RS232 board
Server is in listening mode
Description
Initialization:
In the beginning of the code, the GSM module is initialized to TEXT sms format which is done by
AT+CMGF=1 command and looking for “OK” to be returned from GSM module.
Then to receive the message in the modem not in Modem SIM, the following command is used
AT+CNMI=2,2,0,0,0 and looking for “OK” to be returned.
If any of the above “OK” is not returned or both is not returned, command not accepted is returned and the program will remain in loop and try again after one second..
Network Status Checking:
Then the code tests the status of network i.e., whether the Modem is registered to network or not. Modem could be connected to network in two modes: Registered, Registered-Roaming. The status is tested using AT+CREG?
Code: Select all
if ( GSM_STRING_ARRAY[7] == '0' || GSM_STRING_ARRAY[7] == '1' && GSM_STRING_ARRAY[9] == '1' || GSM_STRING_ARRAY[9] == '5')
retval = 1;
In registered mode, the above command should return +CREG: 0,1 or +CREG: 1,0 whereas in roaming mode it should return +CREG: 1,5 or +CREG: 0,5
That’s why in the code 7th and 9th byte of received data array are checked to confirm about registration status. If the Modem responses as above mentioned, the code will return 1. The program will loop until it gets 1 returned from the macro.
Send Command:
Command macro need to modify to accommodate return values..
Code: Select all
//0=ok
//253=CONNECT
//254=Error
//255=no reply
if ((GSM_STRING_ARRAY[0] == 'O') && (GSM_STRING_ARRAY[1] == 'K'))
return 0;
if ((GSM_STRING_ARRAY[0] == 'E') && (GSM_STRING_ARRAY[4] == 'R'))
return 254;
if ((GSM_STRING_ARRAY[0] == 'C') && (GSM_STRING_ARRAY[6] == 'T'))
return 253;
This macro is to send AT commands directly to the modem to perform any task. Like following..
GPRS ON
The following command is used to turn on GPRS interface in modem and as this command follows a <cr> after the command that’s why bSendCR should be 1. If bSendCR = 1 or 0 means whether there is any <cr> is going to add at the end of command or not.
AT+CGREG=1 <cr>
The program will wait in the loop till the command returns “OK”.
TCP/IP ENABLE
The following command will enable TCP/IP
AT+WOPEN=1 <cr>
The program will wait in the loop till the command returns “OK”.
START TCP STACK
The following command will start TCP stack
AT+WIPCFG=1<cr>
The program will wait in the loop till the command returns “OK”. If you repeat this command without restarting or powering up modem, you will get “ERROR” message from modem. That’s why “ERROR” in this case is not a problem rather an indication that you have tried more than once. I have modified the original send command macro to show this “ERROR” return.
OPEN GPRS BEARER
The following command will start TCP stack
AT+WIPBR=1,6 <cr>
The program will wait in the loop till the command returns “OK”. If you repeat this command without restarting or powering up modem, you will also get “ERROR” message from modem.
TCP CLIENT
Now the important bit for this program which is to create TCP client and I have to make custom code for that. The custom macro is added in PIC_GSM.c so can be accessed in flowcode. This enables to create TCP server/client. This is as follows..
Code: Select all
char GPRSTcpClientServer(char SrCt)
{
/*Macro_GPRSTcpClientServer_Start*/
//0 = OK
//254 = Error
//255 = No Reply
char retval = 0;
char idx;
GSM_Send_Byte('A');
GSM_Send_Byte('T');
GSM_Send_Byte('+');
GSM_Send_Byte('W');
GSM_Send_Byte('I');
GSM_Send_Byte('P');
GSM_Send_Byte('B');
GSM_Send_Byte('R');
GSM_Send_Byte('=');
GSM_Send_Byte('4');
GSM_Send_Byte(',');
GSM_Send_Byte('6');
GSM_Send_Byte(',');
if (SrCt)
GSM_Send_Byte('1'); //send 1
else if (SrCt==0)
GSM_Send_Byte('0'); //send 0
GSM_Send_Byte(GSM_CHAR_CR);
while ( StringReceive()==0);
if ((GSM_STRING_ARRAY[0] == 'E') && (GSM_STRING_ARRAY[4] == 'R'))
return 254;
if ((GSM_STRING_ARRAY[0] == 'O') && (GSM_STRING_ARRAY[1] == 'K'))
retval = 0;
StringReceive();
StringReceive();
Wdt_Delay_Ms(100);
return retval;
/*Macro_GPRSTcpClientServer_End*/
}
Here we are waiting for response from modem and that's why we can't use normal command macro as that will return 255 always.
TCP Socket Create
This is also required to be custom made as IP and PORT number both needed to be string and IP needed to be send to modem in " " so I have modified msg send macro to make a new one which will wait for modem to respond. The code is following..
Code: Select all
char TCPSocketInfo (char* ip, char* port)
{
/*Macro_TCPSocketInfo_Start*/
//0=ok
//254=Error
//255=no reply
char idx;
char retval=0;
GSM_Send_Byte('A');
GSM_Send_Byte('T');
GSM_Send_Byte('+');
GSM_Send_Byte('W');
GSM_Send_Byte('I');
GSM_Send_Byte('P');
GSM_Send_Byte('C');
GSM_Send_Byte('R');
GSM_Send_Byte('E');
GSM_Send_Byte('A');
GSM_Send_Byte('T');
GSM_Send_Byte('E');
GSM_Send_Byte('=');
GSM_Send_Byte('2');
GSM_Send_Byte(',');
GSM_Send_Byte('1');
GSM_Send_Byte(',');
GSM_Send_Byte('"');
for (idx=0; idx<MSZ_ip; idx++)
{
if (ip[idx] == 0)
break;
GSM_Send_Byte(ip[idx]);
}
GSM_Send_Byte('"');
GSM_Send_Byte(',');
for (idx=0; idx<MSZ_port; idx++)
{
if (port[idx] == 0)
break;
GSM_Send_Byte(port[idx]);
}
GSM_Send_Byte(GSM_CHAR_CR);
while ( StringReceive()==0);
if ((GSM_STRING_ARRAY[0] == 'E') && (GSM_STRING_ARRAY[4] == 'R'))
return 254;
if ((GSM_STRING_ARRAY[0] == 'O') && (GSM_STRING_ARRAY[1] == 'K'))
retval = 0;
StringReceive();
StringReceive();
Wdt_Delay_Ms(100);
return retval;
/*Macro_TCPSocketInfo_End*/
}
CONNECTION
This command is done with built-in macro send command as this one executes immediately and for this command specially I have added
Code: Select all
if ((GSM_STRING_ARRAY[0] == 'C') && (GSM_STRING_ARRAY[6] == 'T'))
return 253;
in the original send command macro as this command returns "CONNECT" if connection established.
In this command execution loop, I have tested server connection as well. If server is not in listening mode in that an "ERROR" will be returned by the modem and using this info controller will try twice to connect with server if still can't establish connection..Controller will send a "Server Connection Fail" sms to a pre-defined mobile number which can be assigned in the beginning of the code.
DATA SENDING
This is done with SEND Command macro. Here controller will keep modem waiting for server acknowledgement. If server send "OK", in that case controller will assume data has been sent to server. So, to keep modem in data receiving mode I have made a custom data receive code..
Code: Select all
void CheckForData (char* FCR_RETVAL, char FCR_RETVAL_SIZE)
{
/*Macro_CheckForData_Start*/
char idx = 0;
while ( StringReceive()==0);
while ((idx < FCR_RETVAL_SIZE) && (GSM_STRING_ARRAY[idx] > 0))
{
FCR_RETVAL[idx] = GSM_STRING_ARRAY[idx];
idx = idx + 1;
}
if (idx < FCR_RETVAL_SIZE)
FCR_RETVAL[idx] = 0; //String termination
/*Macro_CheckForData_End*/
}
The code I have attached here will create TCP client connection every 30 seconds and I put here a connection counter which will count how many successful connection has made with server to verify the reliability of communication.
DISCONNECTING
Before disconnecting from server, modem need to be taken to command mode from data mode which is done by "+++" command and executed using send command macro.
TCP CLOSE
To disconnect from server AT+WIPCLOSE=2,1 command is executed in send command macro.
Hope everyone will enjoy this..
