Introduction: SMS Alarm With PIC Microcontroller
This instrucable introduce the software component of a home alarm system based on a PIC microcontroller and a GPS modem.
The article is part of a serie. The first instructable was about the GPS modem component and some concept of using it. This article is about controlling the GSM modem to send SMS when some sensors are triggered.
In a nutshell the alarm system features are:
- Can handle up to 5 separate trigger events.
- Creates and sends custom SMS messages regarding to the triggers.
- Avoids recurring messages within predefined time delays.
- Very low power consumption - the GSM modem is only powered up on demand.
- The GSM modem may be used concurrently by another device.
- Operation LED indicates that the device is in standby or in SMS sending mode.
In my case the triggers I listen to are: movement on the steps of my basement, opening it's door and mains power outage.
GSM/GPRS modem can be controlled by any "intelligent" device: a PC, Raspberry Pi, microcontrollers and more. In this ible I show you how to program a little PIC microcontroller to rule the GSM modem. Using a small PIC model as I did is probably the most low-scaled method to send SMS. I use my alarm system controller just for this purpuse:
- send SMS when needed
- stay in standby mode and require no attention, maintainance or any other interaction from me
- let other (more intelligent and more sophisticated devices) to also use the GSM/GPRS modem as a service
PIC microcontroller implementation features:
- Extreme low-cost solution: a PIC chip costs less than 2 USD and hardly requires more than a cheap LM7805 voltage regulator. (The GSM modem I used costs about 3 USD.)
- Microcontroller's watchdog feature provides real robustness and reliability.
- If you like the 8-bit retro feeling than programming a low-end PIC microcontroller will give you a lot of fun! ;-)
Why not Arduino?
Well, just because programming a PIC provides more challange.
Step 1: MicroC Code
Microchip provides plenty of PIC microcontroller versions for different applications. I choosed PIC 16F688, one of the simplest controllers with 14 pin. It has very limited capabilities: 4 kB program memory, and 2x256 bytes (yes, just a few dozen of bytes! :-) ) data memory. Here comes the challange! :-D
On the other hand, a microcontroller is a realtime operation device (no multitasking) and provides very-very reliable operation.
If you read this ible I assume you are interested in microcontroller programming, so let's analyze the code structure of the alarm system controller.
AT command declarations
You can command the GSM modem by AT instructions. These commands are predefined in the source code (see the picture) and eats up data memory. So you really must use the most neccessary commands and nothing more.
If an outer sensor is triggered it is expected to provide a logical HIGH voltage level on the appropriate pin of the PIC microcontroller. In the code the pins are named like TRIGGER_STEPS, TRIGGER_DOOR and TRIGGER_MAINS. Beacuse of the limited RAM capacity of the microcontroller (and mainly because bit shifting is fun) I store all of the recognised events in one single byte: the lower 3 bits (bit 0, bit 1, bit 2) represents activated steps, door or mains trigger. (See the picture of the code snippet.)
Assembling the SMS message
String handling is a bit rough in C language, as a text in reality is just a string of bytes in the data memory. To make the problem simpler I used string.h functions to concatenate the parts of the SMS message.
After proper UART initialization sending an SMS is an issue of AT commands sent to the TX pin of the microcontroller.
However here is another small feature: as I plan to utilize the GPRS data transfer feature of the GSM modem - a function which require a more complex controller, probably an Arduino - I have to check if the GSM modem is already in use when the PIC tries to send the SMS.
It is implemented by the most simple way: if the GSM Power On contol pin reads a HIGH state (there is 5V on the pin) then another device is powering (and so using) the GSM/GPRS modem. In this case the PIC simply waits for it's turn and meanwhile does what it has to: observes the trigger events. As soon as the modem is available (the power control pin reads LOW) the PIC starts sending the alarm SMS.
Initializing serial communication on UART
16F688 PIC microcontroller has build-in support for standard asynchronous serial communication - the very method we need to talk to the GSM modem. Unfortunately to make it work you need quite a lot of correct configuration values. Any of them is set with a wrong value - and your modem will not follow your AT commands. I spent hours to find the correct settings.
#define _XTAL_FREQ 6000000 // 6 MHz external crystal<br>SPBRG = 9; // with this config this means 38400 bit/s
Setting the right value of SPBRG is tricky. It's value must align with BRG16 and BRGH bit values, otherwise it will not work. There is a nice but rather complex formula in the PIC data sheet to calculate the SPBRG value. You should do your math - or simply try out some values to see which one works.
Step 2: Hardware Issues
Testing a microcontroller means you have to wire it up into it's hardware environment and inspect it's behaviour.
In this case this means I programmed the chip, inserted into a breadboard, enpowered the chip and watched it's signal LED to determine the internal state of the algorithm. Without at least one periphery (a LED as the simplest solution) testing a microcontroller is close to impossible.
There are some important criteria of this implementation:
My GSM modem communicates by default at 38400 baud rate. So I had to configure my PIC to talk at the very same bit rate on it's serial port. This was tricky...
First, as PIC has it's own internal oscillator but serial communication requires a more precise one I had to use and external oscillator - in my case a 6MHz crystal. These are the related code lines:
#define _XTAL_FREQ 6000000 // 6 MHz external crystal.
#pragma config FOSC=XT // XT oscillator: Crystal/resonator on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN
SPBRG = 9; // with this config this means 38400 bit/s
BAUDCTLbits.BRG16 = 0;
TXSTAbits.BRGH = 1; // high baud rate
Trigger pull-down resistors
I use RC0, RC1 and RC2 pins to trigger alert events. To avoid false alerts pull-down resistors are fixed to these ports with 1 mega Ohm resistors. The event sources are limited to 5V and attached to the pins through 20 kOhm resistors.
Command by PIC, read by PC
One trick I considered useful is using the PIC to control the GSM modem, but the modem's TX pin should be connected to a personal computer. I used PuTTY to visualize the answers came from the modem.
As my modem is configured by default to echo all the AT commands it getting I was able to follow the whole process of sending AT commands, delaying time frames, modem responses and return codes (OK/ERROR). Without this trick it is extremely hard to achieve a working solution.
Of course there is a simulator in MPLAB X IDE which Microchip provides for programming it's microcontrollers. But learning to use those simulators requires some time of you, and finally every simulator has it's limits - they are what they are, simulators.
GSM modem power control
While the PIC must run 24/7 and consumes approximately 200 μA (it's next to nothing) than the GSM modem eats up to 2 Ampers. So it should not run all the time just to wait an incoming alert trigger. (I run everything I can with solar energy so power consumption is a hot issue for me.)
The algorithm works like this:
- One or more alert trigger arising.
- The GSM modem gets powered (if it is not in use by an other device at the moment).
- The microcontroller waits a while for the modem to boot up and connect to the mobile network.
- AT commands goes to the modem and the SMS goes out.
- The microcontroller gives shut down command to the modem and wait a while until the modem correctly logs out from the mobile network.
- GSM modem power is getting cut.
"Hope the best" strategy
As this PIC model has so little memory there is some heavy compromise in the algorithm and the implementation. Biggest one is that I sacrified the processing of modem's responses.
This means that if an AT command has been sent to the modem the microcontroller does not try to read and interpret the response code from the modem. In fact the microcontroller does not even care if there is a modem at all - it just send it's commands and hopes there is a modem operating at the other end of the wire. There are some tried timings and delays to ensure successful SMS sending if everything works fine: there is a modem, it boots up all right, the SIM card works fine, the mobile network service is available etc.
This approach works fine in this case as there is really not much the microcontroller could do if it would detect a modem/network error. So I not even wired the RX pin of the microcontroller (the one that transfers the modem's reactions to the microcontroller). Interpreting incoming strings would require more data space than 16F688 has, but even if it has the required capacity there is nothing it could do with the errors may occure.
Well yes, there are some issues... but what would you expect from a $5 home alarm system? ;-)
My DIY basement alarm system now has an assembled and tested GSM modem, and it's PIC controller. Next step will be building the circuit, installing sensors in my basement (steps, doors and mains) and final deployment of the unit. These steps will be accomodated by another instructable...