For the Internet of Things (IoT) assignment for the course Capita Selecta: Distributed Systems we were supposed to create a burglar alarm. A passive infrared sensor (IR) detects movements, which triggers a 60 second timer. If the correct code is not entered using a potentiometer and pushbutton, a relay enables the alarm. Although pretty basic, this was probably one of the more fun assignments during my education at the KU Leuven.

Zigduino

We're using Ziguino micro-controllers because they have a low power 802.15.4 radio on the board. This makes them excellent for our application. The first assignment (which was totally optional) was soldering the headers and radio connector to the PCB.

Soldering

Contiki

Contiki is an open source IoT operation system. It's developed with low-power and internet-connected microcontrollers in mind. Development is pretty easy and deploying to our Zigduino's was done in no-time. We played around with the digital pins, the ADC and external interrupts.

Here's an example of a very simple Contiki process that prints the voltage reading from the first analog port.

#include "contiki.h"
#include <stdio.h>
#include "adc.h"

PROCESS(hello_adc_process, "Hello ADC Process");
AUTOSTART_PROCESSES(&hello_adc_process);

PROCESS_THREAD(hello_adc_process, ev, data)
{
    PROCESS_BEGIN();

    printf("Hello, world!\n");

    //Enable all external interupts 
    EIMSK = 0xff;
    
    //Enable listening to all interupts (on rising edge)
    EICRA = 0x03;

    while(1)
    {
        PROCESS_WAIT_EVENT();
    }

    PROCESS_END();
}

ISR(INT0_vect)
{
    int p = readADC(0);
    printf("ADC=%d\n",p);
}

A push button and potentiometer connected to the zigduino. The Zigduino is connected to the development computer with a JTAGICE3 for flashing images.

LooCI

LooCI stands for Loosely-coupled Component Infrastructure. It has been developed by the iMinds-DistriNet research group at my university.

LooCI is a component-based middleware existing out of an execution environment, a component model and an event-based publish/subscribe binding model.

LooCI Execution Environment

For our burglary alarm, we introduced four LooCI components in addition to the back-end:

  1. A button component. When the button is triggered, a button pushed event is published.
  2. A potentiometer component. When this component receives an event from the button component, it publishes the current value of the potentiometer.
  3. The PIR components detects movement, which triggers a motion detected event.
  4. Finally, the relay components receives events from the back-end when the alarm needs to be triggered.

The button and potentiometer component were deployed on the same node to reduce communication. Nevertheless they can easily be deployed on separate boards. The actuator and movement detection node are each deployed on their own micro-controller.

PIR connected to the Zigduino

Below the code is given for the button components.

#include "contiki.h"
#include "looci.h"
#include "event-types.h"

#ifdef LOOCI_COMPONENT_DEBUG
#include "debug.h"
#else
#include "nodebug.h"
#endif


struct state{struct etimer et;};

static bool pressed;

#define LOOCI_COMPONENT_NAME button_component
#define LOOCI_NR_PROPERTIES 0
LOOCI_PROPERTIES();
COMPONENT_INTERFACES(BUTTON_READING);
COMPONENT_NO_RECEPTACLES();
LOOCI_COMPONENT("Button Component", struct state);

static uint8_t activate(struct state* compState, void* data){

	printf("Button component activated\r\n");

	//Enable all external interrupts
    EIMSK = 0xff;

    //Enable listening to all interrupts (on rising edge)
    EICRA = 0x03;

    // Set pressed to false
    pressed = false;

    // Activate timer
    ETIMER_SET(&compState->et, CLOCK_SECOND);

	return 1;
}

static uint8_t deactivate(struct state* compState, void* data){
	ETIMER_STOP(&compState->et);
	return 1;
}

static uint8_t time(struct state* compState, void* data){
	if(pressed){
		PUBLISH_EVENT(BUTTON_READING,true, sizeof(bool));
		pressed = false;
	}
	ETIMER_RESET(&compState->et);
	return 1;
}

ISR(INT0_vect)
{
    pressed = true;
}

COMP_FUNCS_INIT
COMP_FUNC_ACTIVATE(activate)
COMP_FUNC_DEACTIVATE(deactivate)
COMP_FUNC_TIMER(time)
COMP_FUNCS_END(NULL)

Hopefully it's clear that creating a component is pretty straightforward. What was more of a nuisance was the creation of system images. Fortunately it's pretty much identical every time, so it's just a matter of knowing what needs to be done.

Conclusion

Even though it wasn't always easy, I think I can speak for our whole team (Dieter, Koen, Maxim, Sophie, Sven and myself) by saying that it was very enjoyable assignment. LooCi seems like very promising middleware, especially with micro Plug-and-Play soon being part of the toolkit.

The complete code base for this project can be found at https://github.com/CapitaSelecta-Team1/PotentioTeam.