Sleeping GSM alarm - saves power.

Hi,

I'm working on a sleeping GSM alarm for deployment in my remote garden shed (no mains power). I got this working and would welcome some comment or input to improve it (see code below). I intend the GSM module to be eventually powered up by my minimal Arduino (Cisesco Xino), probably using a transistor-relay combination attached to an output on the Xino. Earlier tests show current consumption during sleep as low as 6uA.

/*Avr atmega328p on minimal board (Cisesco Xino) Fuses set using avr studio 4 to save power before Arduino code loaded.
  Brown-out detect off | Use internal 8MHz crystal etc. See http://www.gammon.com.au/forum/?id=11497
  GSM shield: Spark-fun Cellular Shield with SM5100B. See http://www.coolcomponents.co.uk/catalog/cellular-shield-with-sm5100b-p-490.html
  GSM shield Tutorial here: http://tronixstuff.wordpress.com/2011/01/19/tutorial-arduino-and-gsm-cellular-part-one/
  GSM shield is powered by a separate 5v supply due to high current needed when transmitting.

  Arduino goes to sleep after initial setup. Interrupt attached to PIN2 (Arduino interrupt 0).
  grnd pin with 22K resistor. When pin goes HIGH sleep is interrupted and a GSM alarm is activated. LED lights up and txt message sent.
  
  NB I used PINS 7 and 8 on the arduino, for the serial cell to communicate with the GSM shield, but wire them to the GSM shield PINS 2 and 3. 
  This is so the interrupts don't conflict with the serial cell. So the shield is not piggy-backed on the Arduino but is plugged into breadboard.
  
*/


#include <avr/sleep.h>

#define PIN 2  // external interrupt pin 
byte awakeFlag = 0;
const byte LED = 11;

int count = 0;

#include <NewSoftSerial.h>

NewSoftSerial cell(7,8);  // We need to create a serial port to talk to the GSM module. Use pins other than 2 or 3 as we need these for interrupts
//7 and 8 worked ok

char mobilenumber[] = "xxxxxxxxxxxx";  // recipient's mobile number 

void setup() {

  pinMode (LED, OUTPUT);  // so we can update the LED  
  digitalWrite (LED, HIGH);  //test ON /OFF
  delay(200);
  digitalWrite (LED, LOW);  

  pinMode(PIN, INPUT);     //set the iterrupt pin to input
  digitalWrite(PIN, LOW); //set it low

  attachInterrupt(0, awake, CHANGE); // attach a PinChange Interrupt to our pin on CHANGE, grnd pin with 22K resistor

  //=============SLEEP to save power========================================================================
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
  sleep_enable();  
  sleep_cpu ();  
}

void loop() {

  if (awakeFlag > 0)
  {
  alarm(); //trigger alarm
  }
}//end of void loop()

void alarm()
{

  digitalWrite(LED, HIGH); //alarm indicator LED ON



  //TODO code to power up GSM here tranistor - relay combo?? **************************************************************

  cell.begin(9600);
  delay(35000); // give the GSM module time to initialise, locate network etc.
  cell.println("AT+CMGF=1"); // set SMS mode to text

  cell.print("AT+CMGS=");  // now send message...

  cell.print(34,BYTE); // ASCII equivalent of "

  cell.print(mobilenumber);

  cell.println(34,BYTE);  // ASCII equivalent of "

  delay(500); // give the module some thinking time

  cell.print("Shed Alarm");   // our message to send

  cell.println(26,BYTE);  // ASCII equivalent of Ctrl-Z

  delay(15000); // the SMS module needs time to return to OK status

  do // You don't want to send out multiple SMSs.... or do you?

  {

    delay(1);

  }

  while (1 > 0);


}


void awake()
{

  sleep_disable();  
  awakeFlag = 1;

}

Cheers

probably using a transistor-relay combination attached to an output on the Xino.

I find it rather ironic to see you thinking about using a high-current device (the relay) at the same time you are trying to minimize current consumption. They're your batteries, though.

Oops, thanks, didn't think that through - I won't use use the relay.

As I understand from the GSM tutorial it needs a much higher current than can be supplied by an arduino pin. When I have it transmitting it's uses about 1A on my setup.

So should perhaps use a BD135 medium power transistor. The data sheet says max collector current = 1.5A

Cheers

When I have it transmitting it's uses about 1A on my setup.

You will need to have the device on to transmit, regardless of whether you are trying to conserve power, or not.

So, the question isn't how much current the device uses when transmitting. The question is how much power the device uses when idle, and whether or not it makes sense to turn the device off when it is idle.

It uses 40mA when idle, so It is worth switch off I think to conserve the batteries. Estimate a 1500mAh lipo battery will last less than 40 hours.

OK. Some comments on the code, then.

  attachInterrupt(0, awake, CHANGE); // attach a PinChange Interrupt to our pin on CHANGE, grnd pin with 22K resistor

Interrupt 0, on pin 2, is not a pin change interrupt. It is an external interrupt.

  do // You don't want to send out multiple SMSs.... or do you?
  {
    delay(1);
  }
  while (1 > 0);

Hmmm. Something sets pin 2 differently, which wakes the Arduino, which sends a text message, and goes into an infinite loop, requiring a reset to get out of. Is that really what you want?

What, exactly, is connected to pin 2?

Where do you turn the pin on that activates the GSM device? The TODO comment is nice, but you actually need some code there. :slight_smile:

Interrupt 0, on pin 2, is not a pin change interrupt. It is an external interrupt.

I'm using it as an external interrupt that's a rubbish code comment.
should read

attachInterrupt(0, awake, CHANGE); // attach an Interrupt to our pin [pin2] and pull it down to grnd with 22K resistor

What, exactly, is connected to pin 2?

A 22k resistor then to grnd.

I have this code in to switch a transistor using arduino pin

...
const byte GSMpwr = 10;
....

void alarm()
{

  digitalWrite(LED, HIGH); //alarm LED ON

  //**** power up GSM here BC546B tranistor switches GSM power on **************************************************************
  digitalWrite(GSMpwr, HIGH); //alarm GSM pwr ON GSMpwr [pin10] is connected to base of transistor via a 220ohm resistor

So when I pull out the wire on PIN 2 (ext interrupt 0) the sleep is interrupted
Next the power is switched to the GSM
wait 35 secs to allow connections etc..
then send text.

Now I got all that working.
Thanks for pointing me in the right direction.

I'll tidy up the full code and post it.

Thanks again

Now working with:

/*Avr atmega328p on minimal board (Cisesco Xino) Fuses set using avr studio 4 to save power before Arduino code loaded.
 Brown-out detect off | Use internal 8MHz crystal etc. See http://www.gammon.com.au/forum/?id=11497
 GSM shield: Spark-fun Cellular Shield with SM5100B. See http://www.coolcomponents.co.uk/catalog/cellular-shield-with-sm5100b-p-490.html
 GSM shield Tutorial here: http://tronixstuff.wordpress.com/2011/01/19/tutorial-arduino-and-gsm-cellular-part-one/
 GSM shield is powered by a separate 5v supply due to high current needed when transmitting.
 
 Arduino goes to sleep after initial setup. Interrupt attached to PIN2 (Arduino interrupt 0).
 grnd pin with 22K resistor. When pin goes HIGH sleep is interrupted and a GSM alarm is activated. LED lights up and txt message sent.
 
 NB I used PINS 7 and 8 on the arduino, for the serial cell to communicate with the GSM shield, but wire them to the GSM shield PINS 2 and 3. 
 This is so the interrupts don't conflict with the serial cell. So the shield is not piggy-backed on the Arduino but is plugged into breadboard.
 
 */
 
#include <avr/sleep.h>

#define PIN 2  // external interrupt pin 
byte awakeFlag = 0;
const byte LED = 11;
const byte GSMpwr = 10;
int count = 0;

#include <NewSoftSerial.h>

NewSoftSerial cell(7,8);  // We need to create a serial port to talk to the GSM module. Use pins other than 2 or 3 as we need these for interrupts
//7 and 8 worked ok

char mobilenumber[] = "**********";  // recipient's mobile number 

void setup() {
  pinMode (GSMpwr, OUTPUT); 
  digitalWrite(GSMpwr, LOW); //alarm GSM pwr ON

  pinMode (LED, OUTPUT);  // so we can update the LED  
  digitalWrite (LED, HIGH);  //test ON /OFF
  delay(200);
  digitalWrite (LED, LOW);  

  pinMode(PIN, INPUT);     //set the iterrupt pin to input
  digitalWrite(PIN, LOW); //set it low

  attachInterrupt(0, awake, CHANGE); // attach an Interrupt to our pin and grnd it with 22K resistor

  //=============SLEEP to save power========================================================================
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
  sleep_enable();  
  sleep_cpu ();  
}

void loop() {

  if (awakeFlag > 0)
  {
    alarm(); //trigger alarm
  }
}//end of void loop()

void alarm()
{

  digitalWrite(LED, HIGH); //alarm LED ON

  //**** power up GSM here BC546B tranistor switches GSM power on 
//NOTE must get a higher power one for final circuit**************************************************************

  digitalWrite(GSMpwr, HIGH); //alarm GSM pwr ON GSMpwr [pin10] is connected to base of transistor via a 220ohm resistor,
  // +5v to GSM Vin and collector to GSM Vout, emmiter to GRND

  cell.begin(9600);

  delay(35000); // give the GSM module time to initialise, locate network etc.
  cell.println("AT+CMGF=1"); // set SMS mode to text

  cell.print("AT+CMGS=");  // now send message...

  cell.print(34,BYTE); // ASCII equivalent of "

  cell.print(mobilenumber);

  cell.println(34,BYTE);  // ASCII equivalent of "

  delay(500); // give the module some thinking time

  cell.print("Shed Alarm");   // our message to send

  cell.println(26,BYTE);  // ASCII equivalent of Ctrl-Z

  delay(15000); // the SMS module needs time to return to OK status

  {
    delay(1);
  }
  while (1 > 0);
} //end of void alarm()


void awake()
{
  sleep_disable();  
  awakeFlag = 1;
}

I've attached a circuit to show the connections Q1 is a BC546B tranistor - must get a higher power one for final circuit .

The bulb in the circuit symbol represents the GSM module.

I didn't have a GSM module in my circuit simulator.

Cheers

SleepGSM1.gif

'Most' GSM modules have s power button input... Why don't you use this instead?

The actual power pin might not be routed out to the shield, but that can be fixed :roll_eyes:

Then you just need the sw to toggle the drive pin in the beginning an in the end, no need for a high power transistor on the battery lines (be aware that a typical GSM module draws app 3A peak)

Anyhow, this is just my few cents worth

Hi hideout,

thanks for the tip. The data sheet shows that on the GSM. But I don't think it's wired up on the shield on the schematic. How would I access the right pin on the GSM module itself?

Cheers

Edit: actually on closer examination I note the Shield uses a SPX29302 voltage regulator. This has an enable pin which when made HIGH enables the regulator. I think the data sheet is saying that when disabled (enable PIN LOW) the power consumption is a few uA. But I'm not sure, I'm lacking confidence here just reading the data sheet, and possibly going ahead a slight mod (or possible terminal mutilation) of my expensive GSM shield :astonished: I could carefully solder the pin off and hook it up to one of the shield pins. Very wary though it case I'm totally off track.

Anyone got any experience to offer?

many thanks.

I settled for a mosfet to switch the gsm shield due to high current needs, rather than make mods to the shield itself.

Circuit attached. The IC is just to represent the GSM (I know they have a lot more pins) pin1 represents Vin and 4 represents ground, although they are probably not those on the
actual GSM module.

Thanks for the help.