Here is my preliminary code for sending and receiving calls with a sim900 GSM shield and uno. Long story short calling from shield doesn't work and calling to the shield simply plays faint music from the speaker and doesn't generate the ring at all. I've used test code to separately call from the shield and generate a ring and its worked before. (Haven't worked out a test for calling to the shield yet
I'm using this library Google Code Archive - Long-term storage for Google Code Project Hosting.
#include "SIM900.h"
#include <SoftwareSerial.h>
#include "call.h";
//TX and RX changed from default 2 and 3 to 8 and 9 in GSM.cpp
//nonintegrated cradle version
//integrate in delays?
CallGSM vcs; //call instance
char dialarray[] = {'1','2','3','4','5','6','7','8','9','0'};//array of chars to append to phone number as digits are read in
//variables to read in dial pulses
int needToPrint = 0;
int count; //dial pulse counts
int lastState = LOW;
int trueState = LOW;
long lastStateChangeTime = 0;
// constants
int dialHasFinishedRotatingAfterMs = 100;
int debounceDelay = 10;
//phone number variables
int numquota = 0;//keeps track of how many digits of the phone number we have entered
char* callednum;//number to call
char transferredchar;//char to append to callednum whenever a new digit is read in
int ringingcounter=0;//keeps track of time ringing
int ringbreak; //breaks out of ringing sequence if button is pressed
//PIN SETUP
int dialPin = 2;
int ringPin = 4; // transistor connected to digital pin 4
int buttonPin = 5; // the pin that the pushbutton is attached to
int powerPin =7; //keyed to turn on the GSM power
void setup()
{
// PIN Setup for Dialing, Button, Power, and Ringing Pins
pinMode(dialPin, INPUT);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(ringPin, OUTPUT);
pinMode(powerPin, OUTPUT);
digitalWrite(powerPin,LOW); //turn on GSM network
delay(1000);
digitalWrite(powerPin,HIGH);
delay(2000);
digitalWrite(powerPin,LOW);
Serial.begin(9600);
//RECEIVE
// initialize serial communications
//"Receive Voice Call"
if (gsm.begin(2400))//fix?
Serial.println("\nstatus=READY");
else Serial.println("\nstatus=IDLE");
// This makes sure the modem notifies correctly incoming events
vcs.HangUp();
//"Waiting Call"
}
void loop()
{
// Check the status of the voice call
switch (vcs.CallStatus())
{
case CALL_NONE: // Nothing is happening or in the process of dialing
numquota = 0;//reset phonedigit count just in case?
dial(); //Detect dialing
if (numquota != 0) //while dialing continue to detect dialing until phone number completed or button is pressed
{
while ((numquota != 0 ) && digitalRead(buttonPin)!=LOW)
dial();
}
callednum = ""; //RESET number for next dialing.
break;
case CALL_NO_RESPONSE: // play a tone to indicate a call is taking place. Fix?
//"CALLING"
Serial.println("AT+SIMTONE=1,30,200,200,1000");
break;
case CALL_INCOM_VOICE: // If receiving a call, set up ringing and check to see if user answers
ringingcounter=0; //counter to track time spent ringing and silent
ringbreak=0; //value to skip to phone pickup if button is pressed
digitalWrite(ringPin, HIGH); // sets the ring on
while (ringingcounter<=2000) // waits for two second
{
if (digitalRead(buttonPin)!=LOW && vcs.CallStatus()== CALL_INCOM_VOICE)//if button is pressed and call is still incoming
{
ringbreak = 1;
break;
}
delay(100);
ringingcounter=ringingcounter+100;
}
digitalWrite(ringPin, LOW); // sets the ring off
while (ringingcounter<=6000 && ringbreak == 0) // waits for four seconds
{
if (digitalRead(buttonPin)!=LOW && vcs.CallStatus()== CALL_INCOM_VOICE)//if button is pressed and call is still incoming
{
ringbreak = 1;
break;
}
delay(100);
ringingcounter=ringingcounter+100;
}
if (digitalRead(buttonPin)==LOW && vcs.CallStatus()== CALL_INCOM_VOICE)//answer call
{
vcs.PickUp();
}
break;
case CALL_ACTIVE_VOICE: // In this case the call would be established
//TALKING. Press Button to hangup.
while(digitalRead(buttonPin)!=LOW)
{
delay(100);//BRACES?
}
vcs.HangUp();
break;
}
delay(1000);
//RECEIVE
}
int dial() //code for recognizing and reading in dial pulses
{
int reading = digitalRead(dialPin);//set pin to read dial pulses
if ((millis() - lastStateChangeTime) > dialHasFinishedRotatingAfterMs) {
// the dial isn't being dialed, or has just finished being dialed.
if (needToPrint) {
// if it's only just finished being dialed, we need to send the number
// and reset the count.
transferredchar = dialarray[count-1];
callednum += transferredchar;
needToPrint = 0;
count = 0;
numquota++;//increment till phone number length reached
}
}
if (reading != lastState) {
lastStateChangeTime = millis();
}
if ((millis() - lastStateChangeTime) > debounceDelay) {
// debounce - this happens once it's stablized
if (reading != trueState) {
// this means that the switch has either just gone from closed->open or vice versa.
trueState = reading;
if (trueState == HIGH) {
// increment the count of pulses if it's gone high.
count++;
needToPrint = 1; // we'll need to print this number (once the dial has finished rotating)
}
}
}
lastState = reading;
//rotary addition
if (numquota == 11 ) {//once the last digit has been reached send the number
gsm.call(callednum, 100);//send number to call
while(1);
numquota = 0;//resets phone number digit count
callednum = "";
}
}
)