I have been using this cellular shield:
And so far, mostly so good. However, I have been having one large problem that has been driving me crazy. Thus far I have had no luck trying to solve it.
Basically, when I call the module from my cell phone, the phone module rings about two times and then crashes. Of course, to complicate matters, this problem only happens about 75% of the time. Sometimes it works perfectly fine, which continues to baffle me further.
When it crashes, the phone module both stops audibly ringing through a speaker I attached and printing the "ring!" alert to the serial terminal. And then, the terminal freezes and the whole thing needs to be rebooted.
To confuse matters even further, it happens with two different sets of code. One is the example code from Sparkfun which echos the feedback from the module back through the serial terminal. The other buffers the incoming serial data and prints out responses based on the incoming data.
This is the sparkfun example code:
/*
SparkFun Cellular Shield - Pass-Through Sample Sketch
SparkFun Electronics
Written by Ryan Owens
3/8/10
Description: This sketch is written to interface an Arduino Duemillanove to a Cellular Shield from SparkFun Electronics.
The cellular shield can be purchased here: http://www.sparkfun.com/commerce/product_info.php?products_id=9607
In this sketch serial commands are passed from a terminal program to the SM5100B cellular module; and responses from the cellular
module are posted in the terminal. More information is found in the sketch comments.
An activated SIM card must be inserted into the SIM card holder on the board in order to use the device!
This sketch utilizes the NewSoftSerial library written by Mikal Hart of Arduiniana. The library can be downloaded at this URL:
http://arduiniana.org/libraries/NewSoftSerial/
This code is provided under the Creative Commons Attribution License. More information can be found here:
http://creativecommons.org/licenses/by/3.0/
(Use our code freely! Please just remember to give us credit where it's due. Thanks!)
*/
#include <SoftwareSerial.h> //Include the NewSoftSerial library to send serial commands to the cellular module.
#include <string.h> //Used for string manipulations
char incoming_char=0; //Will hold the incoming character from the Serial Port.
SoftwareSerial cell(2,3); //Create a 'fake' serial port. Pin 2 is the Rx pin, pin 3 is the Tx pin.
void setup()
{
//Initialize serial ports for communication.
Serial.begin(9600);
cell.begin(9600);
//Let's get started!
Serial.println("Starting SM5100B Communication...");
}
void loop() {
//If a character comes in from the cellular module...
if(cell.available() >0)
{
incoming_char=cell.read(); //Get the character from the cellular serial port.
Serial.print(incoming_char); //Print the incoming character to the terminal.
}
//If a character is coming from the terminal to the Arduino...
if( Serial.available( ) > 0)
{
incoming_char = Serial.read( ); // Get the character coming from the terminal
if(incoming_char == '~') // If it’s a tilde…
incoming_char = 0x0D; // ...convert to a carriage return
else if( incoming_char == '^') // If it’s an up caret…
incoming_char = 0x1A; // ...convert to ctrl-Z
cell.print( incoming_char ); // Send the character to the cellular module.
Serial.print( incoming_char ); // Echo it back to the terminal
}
}
This is the buffering code:
#include <SoftwareSerial.h>
#include <PString.h>
#define BUFFSIZ 90
char at_buffer[BUFFSIZ];
char buffidx;
int network_registered;
int network_AT_ready;
int firstTimeInLoop = 1;
//int ring = 0;
//Will hold the incoming character from the Serial Port.
char incoming_char=0;
char buffer[60];
PString myString(buffer,sizeof(buffer));
//Create a 'fake' serial port. Pin 2 is the Rx pin, pin 3 is the Tx pin.
SoftwareSerial cell(2,3);
// Do system wide initialization here in this function
void setup() {
//Initialize serial ports for communication.
Serial.begin(9600);
cell.begin(9600);
//Let's get started!
Serial.println("Starting SM5100B Communication...");
delay(1000);
/* Currently network is not registered and AT is not ready */
network_registered = 0;
network_AT_ready = 0;
}
/* Reads AT String from the SM5100B GSM/network Module */
void readATString(void) {
char c;
buffidx= 0; // start at begninning
while (1) {
if(cell.available() > 0) {
c=cell.read();
if (c == -1) {
at_buffer[buffidx] = '\0';
return;
}
if (c == '\n') {
continue;
}
if ((buffidx == BUFFSIZ - 1) || (c == '\r')){
at_buffer[buffidx] = '\0';
return;
}
at_buffer[buffidx++]= c;
}
}
}
/* Processes the AT String to determine if network is registered and AT is ready */
void ProcessATString() {
if( strstr(at_buffer, "+SIND: 8") != 0 ) {
network_registered = 0;
Serial.println("network Network Not Available");
}
if( strstr(at_buffer, "+SIND: 11") != 0 ) {
network_registered=1;
Serial.println("network Registered");
}
if( strstr(at_buffer, "+SIND: 4") != 0 ) {
network_AT_ready=1;
Serial.println("network AT Ready");
}
}
void IncomingCall() {
if( strstr(at_buffer, "RING") != 0 ) {
Serial.println("ring!");
}
if( strstr(at_buffer, "NO CARRIER") != 0 ) {
Serial.println("hung up on");
}
}
void loop() {
/* If called for the first time, loop until network and AT is ready */
if(firstTimeInLoop == 1) {
firstTimeInLoop = 0;
while (network_registered == 0 || network_AT_ready == 0) {
readATString();
ProcessATString();
}
}
readATString();
IncomingCall();
}
I'm beginning to suspect that maybe the module is sending junk data back to the Arduino when it gets the ring command. This then confuses and crashes the code... perhaps? However, I have yet to discover any real evidence of this.
I'm at about my wits end on this one. If anyone has any ideas as to what may be going on, it would be appreciated.