An apology: The software is not yet in a state where I feel comfortable about publishing it as open source. So for now, I’m only going to give some explanations about its structure, but not the source code itself.

Alarmino’s software is divided into blocks (implemented as C++ classes) that take care of the following aspects:

  • Communicating with the alarm system – emulating a phone line and a central-station (handling the Contact-ID protocol)
  • Communicating with the GSM modem
  • User interface – There are two user interfaces:
    • A terminal-based UI – A shell-like UI. The user gets to this UI by connecting a PC to Alarmino with a USB cable, and using a terminal-emulator application (I’m using PuTTY). This UI gives complete control over Alarmino, and most commands are only available through it
    • An SMS-based UI – Some commands can be issued by sending an SMS with the commands to Alarmino, and receiving a response via a reply SMS. This UI is password-protected (every SMS must start with a password). It is (at least in the current version) very limited
  • Event logging – Events are stored in a 16-entries cyclic log in EEPROM. When a new event is logged, it replaces the oldest event in the log. To make this simple, and since EEPROM space is scarce, events are not stored as text messages, but rather as structured blocks of data. Each event is stored with its time-stamp (date and time).
  • Configuration
  • Miscellaneous

Cooperative Multitasking and Response Time

One of the most dominant aspects of Alarmino’s software, and certainly the one thing that had the greatest influence on its architecture was the need to be able to do real-time multitasking. First I want to explain how multitasking can be achieved in a small system like Arduino.

Note to experienced developers – This section is sort of a general introduction to cooperative multitasking and how it affects response times of microcontroller-based systems. If you’re already familiar with these concepts, simply skip this section.

So, you’re still with me, ehh? I appreciate it.

The problem with blocking I/O

Let’s start with a simple example of a microcontroller-based system. Our system is not totally unlike Alarmino. It is connected to two devices: an alarm system and a GSM modem. (I know; Now you think this is exactly like Alarmino. But it’s by pure coincidence. Honestly!).
Anyway, the alarm system has some strict timing requirements: It can “pick-up” the phone at any time, and must “hear” a dial-tone immediately, or it will deem the phone line defective. Then it communicates using the Contact-ID protocol that has strict timing windows of its own. For example, a kiss-off tone must be received by the alarm within a certain time window after a message transmission. Otherwise, the alarm thinks that the message was lost and retransmits it.
The GSM modem, on the other hand, has operations that can take a long time. Communicating with the modem is done over a serial port with AT Commands (http://en.wikipedia.org/wiki/AT_Commands). For every command we send the modem, we receive a response that indicates whether the command was executed successfully or not. Sometimes we send a command and the modem fail to receive it. We detect this by realizing that too much time (e.g. 1 second) has passed since we sent the command to the modem, and we still didn’t receive a response. In this case we usually retransmit the command. The retransmission can also fail, and so on. After a few retransmissions we probably realize that something is totally messed up with our modem, reset it, and retry all over again.
A straightforward implementation of this would be a function that takes the AT command, sends it to the modem and waits for a response. Waiting is done in a tight-loop that simply checks if a response has arrived from the modem. If it waits more than a second without getting a response, it re-transmits the command. This can be repeated up to 3 times. If three retransmissions occur, it resets the modem and start all over again. All this can take a very long time, and within all that time, the function never returns to its caller.
I think that by now you start to see the problem: If the alarm suddenly needs our attention, but we’re busy talking to the modem, and ignore its signals for too long, the alarm is not going to be happy… (in reality it will probably declare a phone-line malfunctioning, because it doesn’t get the expected responses to its signals). We need to find a way to attend both to the modem and the alarm at the same time. The solution is called cooperative multitasking.

Cooperative Multitasking

The concept of cooperative multitasking is really simple. The system is build of one controller and multiple workers (in an Arduino system, typically the controller and each of the workers would be implemented in a separate C++ class). Each of the worker classes is responsible for a certain aspect of the system. In our example, there would be one worker responsible for the communication with the alarm, and another for the communication with the modem. Each worker class has a main entry-point. This is a method that is called whenever we want the class to “do its stuff”. Let’s call this method exec(). All the worker classes guarantee that their exec() method never blocks for a long period of time. They always do something simple and return.
The controller simply calls the exec() methods of all the workers one after the other in a loop. This arrangement guarantees that if an external event occurs and requires prompt handling, the responsible worker always gets a chance to handle it on time.
By now you’re probably saying “this is too good to be true. Where’s the catch?”. Well, the catch is in the complexity added to the workers. Let’s go back to our example. In this example, the code responsible for the modem sent an AT-command to the modem, and then waited for a response. The wait might be long, because there’s no guarantee that the modem will answer within a certain amount of time. With our shiny new technique, this long wait for the modem response is a big no-no. So how do we handle this? Well, the trick is that each worker employs a state-machine, where it stores its state. In our example, when the modem handler sends an AT-command to the modem, it stores the current time and the state I’m-waiting-for-a-response-for-an-AT-command-I-just-sent-to-the-modem in its state, and returns. Then, when it is called again, it looks at the state and knows that it should look for a response from the modem. If a response is received, it handles it. If not it can look whether too much time has passed since the command was sent. If indeed too much time has passed it can retransmit the command. If not, it does nothing. In any event it returns pretty quickly to the controller.
Handling all the possible states in the workers becomes a large part of developing an application like Alarmino. Still, it’s the simplest way to guarantee quick response to external events in a system that handles multiple devices.

Cooperative Multitasking

Alarmino’s Implementation of Cooperative Multitasking

All the software of Alarmino is build around the cooperative-multitasking model. The code never blocks or calls Arduino’s delay() function.
All the workers in Alarmino are singletons (simply in the sense that there’s one instance of each one of them). Each worker implements a setup() and a loop() methods, and maintain its own state information. Each worker’s setup() method is called once after boot from the main setup() function. The controller is simply the main loop() method, which calls the loop() methods of all the workers one after the other in an infinite loop.

Software for Handling the GSM Modem

Probably the most complicated part of Alarmino’s code is the GSM modem handler. Iteadstudio, the maker of the IComSat GSM modem, provide on their website some software to go with their board. On Google Code there’s a newer version of the same library, and I suggest that if you’re going to use this library, you’ll download the latest version from there.
At first I thought I could utilize this library, which would save me quite a lot of coding. However when the time came to actually use it, I realized it doesn’t fit my needs, and I ended up coding everything from scratch. The main reason for this was that this library occasionally blocks for long periods of time, and I needed this code to play nicely in my multitasking scheme.

Decoupling Event Producers and Consumers in Multitasking Systems

Many times a complex system can be simplified by decoupling some of its components. For example, in Alarmino, an alarm event can generate a message that has to be sent via an SMS message. A straightforward solution is to have the code that handles the alarm event call a function that is responsible to sending SMS messages. However since we’re dealing with a multitasking system, it’s very possible that exactly at this time, the system is busy sending a previous SMS message. Handling these situations in the modem’s code can be such a huge mess, that even the bravest programmer will get so stressed, that it’ll negatively affect his marital life in ways I won’t discuss here.
To prevent this (marital life mess and stuff) from happening, we simply decouple the alarm code (event producer) from the modem code (event consumer). This is done by means of a job-queue. Whenever an alarm event is generated, the alarm handler code simply places it in a job-queue and forgets about it. The modem code, on its part, checks the queue for new jobs whenever it is idle. If a new job is found, the modem handler fetch the job from the queue and handles it. During the time it handles the job (which might be long) more jobs can be added to the queue, but this doesn’t bother anyone, since the queue will only be checked once the current task is finished.
Experience developers might think that building a queue is a tad complicated, because a typical queue requires, in addition to the queue itself, some locking mechanisms. However this is not the case here since Arduino has no multithreading and no context-switching. Thus, implementing a queue in Arduino is actually trivial.

Development Environment

When I started using Arduino, I used its IDE which is part of the “Arduino Software”. However I quickly realized that it’s a big step backwards for anyone that has done professional software development before. Things you would take for granted like a powerful editor, code refactoring, code verification as you type, code structure analysis tools (e.g. call hierarchy, etc), and many many more, were simply missing. After a quick search for an alternative I found the Arduino Eclipse plugin (http://www.baeyens.it/eclipse/). I moved to that environment and never looked back. I strongly recommend to anyone developing a larger-than-trivial project with Arduino to use this Eclipse-based environment. This is especially true if you are familiar with Eclipse (because otherwise, I admit, there’s quite a steep learning curve to Eclipse itself).

Next

Next, you can read about Alarmino’s hardware, about the Contact-ID protocol, or go back to Alarmino’s main page.

Advertisements

19 Responses to “Alarmino – Software”


  1. 1 Timothy Gray September 18, 2012 at 5:53 pm

    Can you share your code? I would love to build this for my alarm at home.

    • 2 li0r September 18, 2012 at 6:11 pm

      I’m still working on the code and I don’t feel comfortable publishing it in its current state.
      I do plan to publish it when I’m done though. (Although there’s a saying in Hebrew: “Man plans, God laughs”)…

  2. 3 Putyn September 18, 2012 at 7:54 pm

    great write up – i would also love to take a look at the code 🙂

  3. 4 kip September 19, 2012 at 8:32 am

    I would also love if you would share your code 🙂

  4. 5 Bernd January 29, 2013 at 10:04 pm

    Hi,

    I have the same gsm shield. I’m trying to control a servo. It should move if a sms is coming in. My problem: where i find the rigt pwm output on the shield?
    Thanks for your help,
    Bernd

  5. 6 San July 3, 2013 at 4:27 pm

    I am using the same Icomsat 1.1 shield with Duemilanove. My problem is that it ain’t registering. Do I need the 2A spike during registration too? But I am using 12V 7.2Ah battery which makes the regulator of the Duemilanove quiet hot. Any solutions?

    • 7 li0r July 3, 2013 at 6:51 pm

      Take a look at my circuit, and see how I’m using an LM350 to drop the battery’s 12V to a more reasonable 8.2V for the Arduino. This way the Arduino’s regulator doesn’t have to dissipate too much heat. The LM350 is fitted with a small aluminum heat-sink, and everybody is happy.

      • 8 San July 4, 2013 at 3:45 am

        Ah. Guess I have some 7809s lying around. Will use that with heatsink. And about the 2A current; my project runs on the battery I mentioned w/ a solar panel(20W). Do you think it will be good enough?

        Regards,
        San.

      • 9 li0r July 4, 2013 at 6:24 am

        I think that the 7809 is limited to 1A. It’s possible that the small 2A bursts won’t cause any problems though. It’s up to you to decide how robust you want the design to be. This is why I went with the LM350.
        As for power – Let’s assume your circuit consumes 100mA when idle (just an assumption. You need to check this in real life), and let’s assume that your battery is good for 5Ah (never assume the theoretical capacity), then you got about 50 hours of operation time on a full charge. If you don’t expect to ever have more than 50 hours without sunlight (e.g. a couple of very cloudy days), you should be OK. I’m no expert in solar power, but 20W seems OK to me because you can probably get a full charge with only few hours of good sunlight.

  6. 10 San July 4, 2013 at 6:55 am

    I am yet to check the current consumption of the ckt. And I reckon we can send the Gsm900 to idle mode, which will help in decreasing the power consumption. Anyways thanks for the replies. Cheers.

  7. 11 brian September 3, 2013 at 7:31 pm

    I’d love to see your code. I’m interested in communicating with my alarm system using Arduino, and then reporting states to my Raspberry Pi (which I already have connected to it) so that it can handle sending SMS messages or emails.

  8. 12 Emiliano November 15, 2013 at 10:14 pm

    hola, me gustaría si puede poner el código que lee el contac-id.
    muy lindo proyecto, gracias por el aporte!

  9. 13 Emiliano November 15, 2013 at 10:48 pm

    Hello, I would like if you can put the code that reads the contact-id.
    Very cute project, thanks for the input!

  10. 14 Chris O'Sullivan February 28, 2014 at 2:52 pm

    Hi Lior
    I’m not sure you are still monitoring this thread but anyhow…

    Great info (well the H/W side anyhow 😉 ). Your project covers the functionality of what I want to do but (as usual) I want to do something differently. Let me explain….I want to split your functionality into two components (1) the alarm capture component -and- (2) the SMS component.

    I’m trying to build a “Smart Home” (or whatever the marketeers want to call it) to monitor (a) environmental conditions (temp,humidity, etc) (b) energy consumption/production (c) solar hot water management (d) intrusion alarms…etc. Essentially, SMS will be just another service and an intrusion alarm is just another “event” (albeit an important one!). All the commercial units that I can purchase that provide Alarminos functionality, simply want to replace the phone line (PSTN) with an internet back-to-base protocol (“ET phone home” mentality). A US company sells something useful but not outside the USA.

    I’ll try and build your solution without the GSM i/f component. Instead, I’ll try and make it talk to my MQTT broker (a simple message broker running on a Raspberry Pi) via an RS485 bus. The GSM gateway funtionality will be just another service provided within my MQTT managed system. I know it sounds complicated but (as best I can tell with my limited experience in this area) it really simplifies things.

    So thanks for the H/W schematics….but as I said before, what I would love to do is buy this functionality “off the shelf” but that seems too hard right now. Yes, I’m a software person an I’m sure I’ll be uncomfortable with my h/w build but that is life!

    Cheers
    Chris

    Bokarina Beach
    Sunshine Coast
    Queensland
    Australia

  11. 16 Alejandro April 22, 2014 at 3:12 pm

    Please the arduino code !

  12. 17 Dave May 15, 2014 at 11:37 am

    li0r, we promise we won’t judge you. Please share the code you’ve written to date so we don’t have to start from scratch. I’ll let you fool around with my hot little wife. Please.

  13. 18 Javierfer October 28, 2015 at 4:47 am

    Very good your project !! congratulations, after all I’m trying to do what you have described but for now without success please if you’ve completed the code, can you share your code?
    thank you
    Javier

  14. 19 timharrington363576950 June 19, 2016 at 10:05 pm

    Please please please share the source code! I was really excited to find this article, but without the code as a starting point (even if it’s not finished) I’ll never have the time to replicate what you’ve done here.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s





%d bloggers like this: