GSM/GPRS modems are getting very common these days, as prices are getting cheaper and cheaper. Apart from providing SMS and call functions to my projects I also wanted to communicate via TCP.

Although there are many documents and blog posts to help but I have always found that they either are answers to specific problem faced by someone or not providing complete details. In this post I would first explain the AT commands used in brief. You may connect your SIM900 to your computer via a serial/usb and test these commands. In the later part of this post I would include arduino example code.

AT commands for TCP/UDP Connection with example response and a brief description are given in the table below. Refer to the AT commands manual of your modem for details

AT command Response Description AT OK test command. reply is OK AT+CGATT? +CGATT:n checks if GPRS is attached? n=1 if attached AT+CIPMUX=n OK use n as 0 for single connection

or use 1 for multiple connections AT+CSTT=”apn”,”username”,”pass” OK Sets APN, user name and password AT+CIICR OK Brings up wireless connection AT+CIFSR ip address Get local IP address if connected AT+CIPSTART=“TYPE” , “domain”, “port” Connected Establishes a connection with a server. Type can be UDP or TCP AT+CIPSEND > Sends data when the a connection is established. AT+CIPCLOSE OK Closes the connection AT+CIPSHUT SHUT OK resets IP session if any

how to make a connection:



Send ATr and wait for a response from the modem. You should recieve OK

if everything is set. Make sure that the Modem has registered to network and that PIN code is disabled on the SIM. Send AT+CGATT?r to check if GPRS is attached or not. +CGATT: 1 indicates that GPRS is attached. Send AT+CIPSHUTr . Although its optional this will be helpful as it resets IP session if any. you will get a response SHUT OK . Send AT+CIPMUX=0 to set a single connection mode, response would be OK Now set APN settings by AT+CSTT= “apn ”, “username”, “password”r . replace apn, username and password to match APN (Access Point Name) ,username and password for your service provider. Now send AT+CIICRr , this will bring up the wireless connection. OK is received on successful connection Send AT+CIFSRr , this will reply with the IP address the modem has been assigned. Send AT+CIPSTART=”TCP”,”server domain name or ip”,”port”r , replace the domain name/ip and port with appropriate values, on connection modem will reply with CONNECT OK Now you can send your data using AT+CIPSENDr AT command. modem will respond with > indicating it is ready to receive data to be sent. Type in your data. Now the modem is waiting for the ASCII 26 that is control+z on keyboard. Depending on the terminal software used you can either press control and Z together on keyboard or send hex value 0x1A . The modem will then send the response from server. Now send AT+CIPSHUT to shut down the connection. Modem will reply with SHUT OK cheers 🙂

ARDUINO CODE :

Below is example code for single and multiple connection using arduino and sim900

int8_t answer; int onModulePin= 2; char aux_str[50]; char ip_data[40]="Test string from GPRS shieldrn"; void setup(){ pinMode(onModulePin, OUTPUT); Serial.begin(115200); Serial.println("Starting..."); power_on(); delay(3000); // sets the PIN code sendATcommand2("AT+CPIN=****", "OK", "ERROR", 2000); delay(3000); Serial.println("Connecting to the network..."); while( sendATcommand2("AT+CREG?", "+CREG: 0,1", "+CREG: 0,5", 1000)== 0 ); } void loop(){ // Selects Single-connection mode if (sendATcommand2("AT+CIPMUX=0", "OK", "ERROR", 1000) == 1) { // Waits for status IP INITIAL while(sendATcommand2("AT+CIPSTATUS", "INITIAL", "", 500) == 0 ); delay(5000); // Sets the APN, user name and password if (sendATcommand2("AT+CSTT="APN","user_name","password"", "OK", "ERROR", 30000) == 1) { // Waits for status IP START while(sendATcommand2("AT+CIPSTATUS", "START", "", 500) == 0 ); delay(5000); // Brings Up Wireless Connection if (sendATcommand2("AT+CIICR", "OK", "ERROR", 30000) == 1) { // Waits for status IP GPRSACT while(sendATcommand2("AT+CIPSTATUS", "GPRSACT", "", 500) == 0 ); delay(5000); // Gets Local IP Address if (sendATcommand2("AT+CIFSR", ".", "ERROR", 10000) == 1) { // Waits for status IP STATUS while(sendATcommand2("AT+CIPSTATUS", "IP STATUS", "", 500) == 0 ); delay(5000); Serial.println("Openning TCP"); // Opens a TCP socket if (sendATcommand2("AT+CIPSTART="TCP","IP_address","port"", "CONNECT OK", "CONNECT FAIL", 30000) == 1) { Serial.println("Connected"); // Sends some data to the TCP socket sprintf(aux_str,"AT+CIPSEND=%d", strlen(ip_data)); if (sendATcommand2(aux_str, ">", "ERROR", 10000) == 1) { sendATcommand2(ip_data, "SEND OK", "ERROR", 10000); } // Closes the socket sendATcommand2("AT+CIPCLOSE", "CLOSE OK", "ERROR", 10000); } else { Serial.println("Error openning the connection"); } } else { Serial.println("Error getting the IP address"); } } else { Serial.println("Error bring up wireless connection"); } } else { Serial.println("Error setting the APN"); } } else { Serial.println("Error setting the single connection"); } sendATcommand2("AT+CIPSHUT", "OK", "ERROR", 10000); delay(10000); } void power_on(){ uint8_t answer=0; // checks if the module is started answer = sendATcommand2("AT", "OK", "OK", 2000); if (answer == 0) { // power on pulse digitalWrite(onModulePin,HIGH); delay(3000); digitalWrite(onModulePin,LOW); // waits for an answer from the module while(answer == 0){ // Send AT every two seconds and wait for the answer answer = sendATcommand2("AT", "OK", "OK", 2000); } } } int8_t sendATcommand2(char* ATcommand, char* expected_answer1, char* expected_answer2, unsigned int timeout){ uint8_t x=0, answer=0; char response[100]; unsigned long previous; memset(response, ' ', 100); // Initialize the string delay(100); while( Serial.available() > 0) Serial.read(); // Clean the input buffer Serial.println(ATcommand); // Send the AT command x = 0; previous = millis(); // this loop waits for the answer do{ // if there are data in the UART input buffer, reads it and checks for the asnwer if(Serial.available() != 0){ response[x] = Serial.read(); x++; // check if the desired answer 1 is in the response of the module if (strstr(response, expected_answer1) != NULL) { answer = 1; } // check if the desired answer 2 is in the response of the module else if (strstr(response, expected_answer2) != NULL) { answer = 2; } } } // Waits for the asnwer with time out while((answer == 0) && ((millis() - previous) < timeout)); return answer; }

int8_t answer; int onModulePin= 2; char aux_str[50]; char ip_data[40]="Test string from GPRS shieldrn"; void setup(){ pinMode(onModulePin, OUTPUT); Serial.begin(115200); Serial.println("Starting..."); power_on(); delay(3000); // sets the PIN code sendATcommand2("AT+CPIN=****", "OK", "ERROR", 2000); delay(3000); Serial.println("Connecting to the network..."); while( sendATcommand2("AT+CREG?", "+CREG: 0,1", "+CREG: 0,5", 1000) == 0 ); } void loop(){ // Selects Multi-connection mode if (sendATcommand2("AT+CIPMUX=1", "OK", "ERROR", 1000) == 1) { // Waits for status IP INITIAL while(sendATcommand2("AT+CIPSTATUS", "INITIAL", "", 500) == 0 ); delay(5000); // Sets the APN, user name and password if (sendATcommand2("AT+CSTT="APN","user_name","password"", "OK", "ERROR", 30000) == 1) { // Waits for status IP START while(sendATcommand2("AT+CIPSTATUS", "START", "", 500) == 0 ); delay(5000); // Brings Up Wireless Connection if (sendATcommand2("AT+CIICR", "OK", "ERROR", 30000) == 1) { // Waits for status IP GPRSACT while(sendATcommand2("AT+CIPSTATUS", "GPRSACT", "", 500) == 0 ); delay(5000); // Gets Local IP Address if (sendATcommand2("AT+CIFSR", ".", "ERROR", 10000) == 1) { // Waits for status IP STATUS while(sendATcommand2("AT+CIPSTATUS", "IP STATUS", "", 500) == 0 ); delay(5000); Serial.println("Openning TCP"); // Opens a TCP socket with connection 1 if (sendATcommand2("AT+CIPSTART=1,"TCP","IP_address","port"", "CONNECT OK", "CONNECT FAIL", 30000) == 1) { Serial.println("Connected"); // Sends some data to the TCP socket sprintf(aux_str,"AT+CIPSEND=1,%d", strlen(ip_data)); if (sendATcommand2(aux_str, ">", "ERROR", 10000) == 1) { delay(500); sendATcommand2(ip_data, "SEND OK", "ERROR", 10000); } // Closes the socket sendATcommand2("AT+CIPCLOSE=1", "CLOSE OK", "ERROR", 10000); } else { Serial.println("Error openning the connection 1"); } } else { Serial.println("Error getting the IP address"); } } else { Serial.println("Error bring up wireless connection"); } } else { Serial.println("Error setting the APN"); } } else { Serial.println("Error setting the multi-connection"); } sendATcommand2("AT+CIPSHUT", "OK", "ERROR", 10000); delay(10000); } void power_on(){ uint8_t answer=0; // checks if the module is started answer = sendATcommand2("AT", "OK", "OK", 2000); if (answer == 0) { // power on pulse digitalWrite(onModulePin,HIGH); delay(3000); digitalWrite(onModulePin,LOW); // waits for an answer from the module while(answer == 0){ // Send AT every two seconds and wait for the answer answer = sendATcommand2("AT", "OK", "OK", 2000); } } } int8_t sendATcommand2(char* ATcommand, char* expected_answer1, char* expected_answer2, unsigned int timeout){ uint8_t x=0, answer=0; char response[100]; unsigned long previous; memset(response, ' ', 100); // Initialize the string delay(100); while( Serial.available() > 0) Serial.read(); // Clean the input buffer Serial.println(ATcommand); // Send the AT command x = 0; previous = millis(); // this loop waits for the answer do{ // if there are data in the UART input buffer, reads it and checks for the asnwer if(Serial.available() != 0){ response[x] = Serial.read(); x++; // check if the desired answer 1 is in the response of the module if (strstr(response, expected_answer1) != NULL) { answer = 1; } // check if the desired answer 2 is in the response of the module else if (strstr(response, expected_answer2) != NULL) { answer = 2; } } } // Waits for the asnwer with time out while((answer == 0) && ((millis() - previous) < timeout)); return answer; }