Pages

Sunday, December 23, 2012

Wireless Arduino programming/serial link

My initial plan is to install my Arduino board, motor and sensors in a closed container. However, being contained like that will make programming and debug difficult, that is, removing the device and attaching it to a USB cable to re-program it, and then re-installing it would not likely be much fun.

The best solution is for me to do wireless programming. Normally the Arduino board is loaded with the new sketch and then the USB cable "sends" a board reset (this is all done through an FTDI chip). This in turn gets the new sketch started. Doing this remotely is a bit more difficult because a wireless connection must send a reset, and the receiver must in turn set the reset pin low momentarily to get the sketch started. Fortunately my question on an Arduino forum pointed me to a possible solution. Well I should say at this point, the only solution I've found so far.

On LadyAda's website she has a project description for creating a wireless programming/serial link. All of the components will cost about $90, so it's not a cheap solution, and I'm not sure it will work on my Seeeduino because I don't know if the bootloader complies with the requirements (even though I lucked out and it is a Duemilanove compliant board). I also posted a question on SeeedStudio's forum asking if their UartSBee board could do something similar. So far there has been no replies but in a private email exchange with them they said they said it could be done but were looking into the exact procedure.

So now I've begun to look into XBee communications. Wow, so much to learn.

If I can get this all working correctly, I could have my toy rolling around in the living room and re-program it while I'm in my studio. Way cool.

After development and debug are complete, I would remove the RF component.

UPDATED 12.24.12 -----------------------------------------

A posting from SeeedStudio this morning indicates I could use SeeedStudio's UartSBee V4 component to replace the FTDI cable and AdaFruit XBee Adapter kit. This would save me about $10 from the AdaFruit solution that would cost $90.

The hardware path would be:

PC -> USB Cable -> UartSBee V4 -> XBee S1 RF -> transmit
receive -> XBee S1 RF -> XBee Adapter kit -> Arduino (Duemilanove)

with reset hardware patch.

Monday, December 17, 2012

ADF - design feasibility study is concluded

To my last posted Asynchronous Device Platform code I added a sound sensor and an I2C three axis accelerometer using a SeeedStudio ADXL345 library and the standard wire library to my project. The framework handled the additions with no problems. This brings the total to 3 analog input sensors, 2 digital input sensors, 1 I2C sensor and 4 digital outputs for a total of 10 asynchronous IO's. The sketch takes about 14K SRAM and it ran fine with a time tick of 2.5ms but crashed at 2ms.

At this point I believe I could reliably operate at 3ms time ticks with at least 10 I/O's spanning digital, analog and I2C bus. The only Con I can think of at this point is that I could run out of timer interrupts running on the 328P. In this case I would need to move to a processor that had more timer interrupts, read more expensive board. The Seeeduino board I'm using now costs $22.


So unless something drastically changes, I believe the Quantum Leaps platform will make an excellent base for my ADF platform to support my projects.

project files are here

Thursday, December 13, 2012

The start of an Asynchronous Device Framework

Since my last post I refactored my digital input and output controllers and added an analog input controller. I've decided for now to call this my Asynchronous Device Framework, or ADF for short. The name, as it implies, is using the Quantum Leaps QP software framework to carve out slices of time for each of the input and output device controllers. The devices are grouped by functionality, so for example, simple digital output devices are controlled by a Digital Output Device Controller (DigitalODC) class. I have a Digital Input device controller and an Analog Input device controller. The controller for the logic is called MyController; it receives events from the various input devices and issues event commands to the output devices. One nice feature of the Quantum framework is the ability for each task, in this case a controller, to issue inter-process communications (IPC) to other controllers. This message framework makes it easy for an input controller to send sensor data to the logic controller asynchronously. This of course moves the task of polling a sensor to a process running in an independent "thread". This means no logic is ever blocked waiting for input, it is all event driven.


In the above picture, all of these devices are running asynchronously: 3 LED's, a PIR, a switch, a vibrator, a temperature sensor and a light sensor. When the state of any of the digital input modules is changed, that state is sent to the logic controller. The analog temperature sensor is sending readings once every 5 seconds and the light sensor every second.

The code to "program" the inputs and outputs is done in the logic controller (MyController). For example, the digital output controller exposes a simple add method:

  // pre-program the operation LED to constantly blink
  // at 600 ms on and 600ms off
  DigitalODC_Add(OPERATION_LED, 600, DOD_MODE_CYCLE);

  // pre-program the Warning LED to flash once for 1/2 second
  DigitalODC_Add(WARNING_LED, 500, DOD_MODE_ONESHOT);

  // pre-program the vibration sensor to buzz for 1 second
  DigitalODC_Add(VIBRATION, 1000, DOD_MODE_ONESHOT);

  // pre-program the GO LED in the off state
  // this control might be somewhat useless
  // unless its mode can change.
  DigitalODC_Add(GO_LED, 0, DOD_MODE_OFF);

The first argument of the add method is the digital i/o pin number; the second value is an on/off cycle rate in milliseconds or the duration if its mode is one shot, and the final argument is the Digital Output Device mode, currently one of:

// Digital Output Device Mode
enum DOD_MODE
{
    DOD_MODE_OFF = 1, // direct controlled and is off
    DOD_MODE_ON,     
// direct controlled and is on
    DOD_MODE_CYCLE,   // cycle continuously
    DOD_MODE_ONESHOT  // only on for duration of the cycle time
};


So the operation LED blinks continuously for 600ms on and 600ms off. The warning LED, when triggered will flash for 500ms, and the vibrator module will run for 1 second. The GO_LED is under direct control of MyController, that is, it is explicitly commanded to be either on or off.

As for the inputs, they are programmed as well:

  // setup the passive infrared sensor as an input
  DigitalIDC_Add(PIR_SENSOR); 

  // setup the switch (with pullup!) as an input
  // probably need to add input-with-pull up option as well
  DigitalIDC_Add(SWITCH);

  // add an analog light sensor input and have it
  // send status every second
  AnalogIDC_Add(LIGHT_SENSOR, 1000);

  // add an analog light sensor input and have it
  // send status every 5 seconds seconds
  AnalogIDC_Add(TEMPERATURE_SENSOR, 5000);

The Digital Input Device Controller, at this time, will only send a state change, so it is only necessary to add the PIR sensor and the slide SWITCH. However, the analog inputs are instructed to send data updates every 1000ms and 5000ms respectively.

The MyController logic for the PIR sensor looks like this:

case DID_STATE_CHANGED_SIG:
   if((CAST_TO_DDEventArg->pinNumber == PIR_SENSOR) &&
      (CAST_TO_DDEventArg->state == HIGH))
   {
      DigitalODC_Set(WARNING_LED, HIGH); // fire warning LED and
      if(switchState)    // if the switch is on then
          DigitalODC_Set(VIBRATION, HIGH);  // vibrate
   }
   else if(CAST_TO_DDEventArg->pinNumber == SWITCH) // if switch
   {
      switchState = CAST_TO_DDEventArg->state; // when changed
      DigitalODC_Set(GO_LED,CAST_TO_DDEventArg->state); // LED changes
   }
   break;

To understand what is happening beyond this logic, you need to understand the IPC (inter-process communications) mechanism. When MyController gets a slice of time, it may or may not have a message waiting for it. If it does it comes in the form of an enumerated signal, in this case, DID_STATE_CHANGED_SIG. To further clarify, I defined this signal in my framework, and programmed the Digital Input Device to publish this event message if one of its monitored inputs changed state. In this case, we can have two digital inputs, one from the PIR and one from the SWITCH, so we need to figure out which one is related to this event. The event message arrives with a pointer to a class object, in this case I've programmed the digital input device controller to send a Digital Device Event Argument (DDEventArg). It has two members, a pin number and a state. So if the message is DID_STATE_CHANGED_SIG AND the pin number is the PIR sensor AND its state has gone positive, something happened. In this case it sends an "on" signal to the warning led, which was pre-programmed to flash on for only 500 ms. If the switch state happens to be "on", then the vibrator module is sent an "on" signal and it vibrates for the pre-programmed 1 second.

If on the other hand, the incoming message is DID_STATE_CHANGED_SIG and the pin number is SWITCH, then we just capture that state in the switchState variable and make the GO_LED track this state.

I created the DigitalODC_Set method to hide the details of sending the IPC message to the Output Device Controller. Here is what it looks like:

// set a binary output device's state
void DigitalODC_Set(uint8_t pinNumber, uint8_t state)
{
    DDEventArg *ea = Q_NEW(DDEventArg, SET_DOD_STATE);
    ea->pinNumber = pinNumber;
    ea->state = state;
    QF::PUBLISH(ea, SET_BOD_STATE);
}

This method takes the pin number and state of the device to be triggered and wraps that up in a Q_NEW event argument class object then Publishes that as a SET_DOD_STATE message. Because the DOD controller has subscribed to this message, when it gets its time slice it will receive the message and set the output accordingly. See my previous posts for more information on quantum platform's IPC mechanism.

To kick things off in the ino file I've encapsulated the start ups in each of the class definition files, so the ino startup looks like this:

    uint8_t priority = 1;

    DigitalODC_Start( ++priority );
    DigitalIDC_Start( ++priority );
    AnalogIDC_Start ( ++priority );

    MyController_Start( ++priority );

This code segment does not show the standard QP initialization calls.

I've designed the controllers to be able to accept responsibility for as many devices as reasonable. By that I mean that I can't add 200 LEDs to the DOD controller, the code would fall over. In that case I would write a MultiLED controller so MyController would send messages to that controller. This means there needs to be some good decisions about the granularity of control because of messaging issues and response latency.

Each controller uses a simple linked list of devices to control/monitor. Because the devices are not removed during runtime, there is no need to worry about memory fragmentation issues that would become problematic with dynamic lists. So in effect, the controllers can support any number of virtual devices as long as there is a pin or pins for them to run on.

Memory requirements so far are about 9K for ROM and an SRAM monitor shows about 1.2K free out of 2K at runtime. Also note there are no huge libraries loaded at this time and I have no idea how much code squeeze this might cause. If necessary I might have to move to a Mega for large complicated asynchronous projects.

I use recursion to walk the linked list of devices and I'm not sure if that may put too much stress on the stack. I've run this code overnight at 300 ticks per second. It did not crash and I saw no RAM creep. I don't have a logic analyzer so I don't know what the real response is like. If time ticks are 3 ms each, it would take up to 3 ms to detect an input change, 3 ms for MyController to send a message to an output controller and 3 ms to change it. That means a theoretical response of up to 9 ms, perhaps more. For faster responses I would need to move to the pre-emptive mode in QP and that brings in a whole lot of issues and greatly complicates the code. Note that I have not explored the possibility of directly invoking the destination controller through a FIFO post that is built into the QP framework. This could speed up response if it becomes necessary.

I plan to add an SPI interface to a 3 axis accelerometer that I have. If this framework can support some additional stress like SPI communications and maybe concurrent serial I/O, then it might be a worthwhile framework to which I could base some applications.

Anyhow, for now, I'm not planning to upload the code until I get it cleaned up a bit. I'll make it available here for anyone that cares to use/evaluate it.

More later ...

Monday, December 10, 2012

A more complex Arduino sketch using QP

I've built an application that monitors digital input and controls digital outputs using the asynchronous event driven state machine from Quantum Leaps (also see my previous posts on this platform). I wanted to test the feasibility of using this platform for an Arduino application that doesn't use the standard loop() method to poll inputs.

The project blinks one LED continuously while a passive infrared sensor triggers another LED to flash when motion is first detected (edge trigger). A green LED tracks the state of a switch, and if the switch is on when the PIR senses motion, the controller runs a vibrator module for 1 second. The code consumes about 8K.

The inputs and outputs are setup as linked lists so adding additional IO to this project would be trivial. This project only deals with binary digital inputs and outputs. I plan to look into PWM outputs and analog inputs next, so I expect Project 2 to build on this one, just as this one was build from the simple event and publish projects.

There are three running "processes"; a digital input controller, a logic controller and a digital output controller. The digital input controller scans a linked list of inputs every 10 ms and publishes an event for each one that changes. The logic controller subscribes to these input events and uses a simple state/event check to determine what outputs are to be changed. The controller then publishes events that the digital output controller uses to change the outputs on 10 ms intervals.

Not all of the outputs are under direct control of the logic controller. In the case of the blinking LED the output controller is making is blink directly.

The qp_Project_1.zip file is here:

http://code.google.com/p/quantum-leaps-arduino-light/downloads/list

Again I would like to note that I am not associated with this company. and I'm not an expert on this platform. I've only started using it a few weeks ago.

Thursday, December 6, 2012

A note about configuration management

My background is in software development and over the last 30 years I've used a variety of software configuration management tools, from RCS/CVS to massive projects using Rational's Cleascase tools. So I guess it is no surprise that I would look for a lightweight configuration management tool for my personal projects.

In January of this year, before I retired, I started to investigate tools I could use as a hermit software developer for my C# projects. One that came to my attention as a result of an inquiry on StackOverflow was from this post. There was and is great enthusiasm over PlasticSCM and now that I've been using it for about a week now, I tend to agree. It is an exceptional package and it comes with a free license.

It was extremely easy to install and add all my personal and professional C++ and C# projects. It integrated with VS2010 automatically, but I mostly use its own interface to checkin files and drop labels. Even if you develop in the Arduino IDE all of your configuration management can be done through their simple browser. When you modify a file that is under source control it is automatically checked out. Later you can diff the changes, check them in or discard them. Very simple. It has some very advanced features that a team could use, but for the most part, a simple version control system is all I needed.

If you are a solo developer, a small or even large team, and you are in need of a simple effective SCM tool, I would highly recommend this platform. Just to give an idea, here is my last Arduino blog post project displayed in the PlasticSCM browser.It shows the top level directory selected and I am about to checkin all of the checked out (red dot) files in the directory. I could have select one or more individual files to checkin as well.


... and a diff of one of the files between the current version and the previous one showing deleted and modified (by spaces) lines of code.


Wednesday, December 5, 2012

Quantum Leaps’ Arduino State Machine Tutorial - Part 2

Next I'll demonstrate a simple input device publishing its state to all subscribers. I've added a class and modified the code published in Part 1. The entire project can be downloaded from http://code.google.com/p/quantum-leaps-arduino-light/downloads/list as the qp_SimplePublish.zip file.

To begin, I added a new input pin definition, event type and event arg to the globals.h file:

enum APPSignals
{
    TIME_TICK_SIG = Q_USER_SIG,
    PIR1_SIG,                    // motion detection
    MAX_PUB_SIG
};
...
const uint8_t    PIRPin        =    2;
...
class PirEvtArgs : public QEvt
{        
    public:
        bool    isTrue;
};


A passive infrared component on pin 2 will send out a PIR1_SIG signal. The event will be sent with a PirEventArgs status of isTrue = true if it senses movement and will transition to false when it no longer senses that movement.

 Then I added a PIR01 class to the project.

--- Pir01.h

#ifndef Pir01_h
#define Pir01_h

#include "qp_port.h"
#include "bsp.h"
#include "globals.h"

using namespace QP;

class Pir01 :
    public QActive
{
    uint8_t m_Pir01Value;

    public:
        Pir01(void) : 
               QActive(Q_STATE_CAST (&Pir01::initial)),
               m_Pir01Value(0) {}

    protected:
        static QState initial (Pir01 *me, QEvent const *e);
        static QState active  (Pir01 *me, QEvent const *e);
};

    static Pir01 l_Pir01;
    QActive * const AO_Pir01 = &l_Pir01;

#endif  // Pir01_h

---

Note that I'm using class member variable m_PirValue and during construction it is being set to 0. This is slightly different than the Blink class definition. Note that this member variable will use a few more bytes than a static reference, but appears "cleaner" in implementation.

--- Pir01.cpp

#include "Pir01.h"
#include "BlinkLED.h"


QState Pir01::initial(Pir01 *me, QEvent const *)
{
        me->subscribe(TIME_TICK_SIG);
        return Q_TRAN(&Pir01::active);
}


QState Pir01::active(Pir01 *me, QEvent const *e)
{
    uint8_t temp = 0;

    switch (e->sig)
    {
        case Q_INIT_SIG:
            pinMode(PIRPin, INPUT);
            me->m_Pir01Value = digitalRead(PIRPin);
            break;
       
        case TIME_TICK_SIG:
            temp = digitalRead(PIRPin);
            if( temp != me->m_Pir01Value )
            {
                PirEvtArgs *ea = Q_NEW(PirEvtArgs, PIR1_SIG);
                ea->isTrue = temp > 0 ? true : false;
                QF::PUBLISH(ea, PIR1_SIG);
                me->m_Pir01Value = temp;
            }
            break;
   
        default:
            break;
     }
     return Q_SUPER(&QHsm::top);
}
---

The operation for active() Init are similar to the LED example. The real difference is that the Pir pin is programmed for input and its initial value is stored in the class member variable me->m_Pir01Value.

However, during the time tick operation the sensor is read and if it has changed it creates an event arg, sets the isTrue boolean and publishes the event. Note that the second argument to PUBLISH, in this case PIR1_SIG is actually a dummy argument in this platform implementation.

Next, the LED blink class was modified to subscribe to the PIR event:

QState BlinkLED::initial(BlinkLED *me, QEvent const *)
{
        me->subscribe(TIME_TICK_SIG);
        me->subscribe(PIR1_SIG);
        return Q_TRAN(&BlinkLED::active);
}

and a case for the PIR signal was coded into the active(...) method:

        case PIR1_SIG:
            {
                bool isOn = Q_EVT_CAST(PirEvtArgs)->isTrue;
                if( isOn )
                    me->m_togglePoint = me->m_togglePoint/10;
                else
                    me->m_togglePoint = me->m_togglePoint*10;
            }
            break;

When the PIR_SIG arrives, the boolean isOn is extracted from the *e args using the expected class cast operation, in this case PirEventArgs. To make this example simple, the LED flashes 10 times faster than normal during motion detection. Also note the macro Q_EVT_CAST is defined as:

#define Q_EVT_CAST(class_)   (static_cast<class_ const *>(e))

This means that it expects the the method argument to be "e", as in:

QState BlinkLED::active(BlinkLED *me, QEvent const *e)

So if you changed the signature of the method, you will need to explicitly cast the argument.

Next I added the event pool, class instance storage and start to the ino file:

static QF_MPOOL_EL(PirEvtArgs)    l_medPoolSto[1];
 ...
static QEvent const  *l_Pir01QueueSto[1]; // PIR Store
 ...
QF::poolInit(l_medPoolSto, sizeof(l_medPoolSto),
                  sizeof(l_medPoolSto[0]));

    AO_Pir01->start
    (
        priority++,   
        l_Pir01QueueSto,
        Q_DIM(l_Pir01QueueSto),     
        (void *)0,
        0U
    );

Because the event is published, any class could subscribe to the PIR event and all classes would get the PIR signal, just as all classes get the tick signal that is published in the interrupt. Also note that two event pools are used, and in this case the medium size pool size is set to 1. I believe this will be okay because we do not expect to have more than 1 event in the queue at a time. During the design phase you would need to determine the maximum number of events you could have queued in the store at any one time. If you had 6 input devices that could post a maximum of 1 event each during the time tick phase, then I would expect the store to need enough space for 6 simultaneous events.

Tuesday, December 4, 2012

Quantum Leaps’ Arduino State Machine Tutorial - Part 1



Quantum Leaps’ Arduino State Machine Framework (QF) hand coded Tutorial

The purpose of this post is to help others that may wish to evaluate the Quantum Leaps state machine interrupt driven framework for an Arduino project. I’m posting this because it took me some concerted effort to understand how the framework could be used from a bottom up hand coding way, rather than top down Quantum Modeling UML way. Those examples are great, but IMHO are too complex for simple understanding. This in no way is intended to reflect poorly on the great job Quantum Leaps has done in presenting this framework.

To begin, I would strongly recommend you spend some time reading the documents that come with the Quantum Platform download. Without a basic understanding of how the framework operates, this tutorial may be of marginal use in understanding the concepts.

As noted, this example does not use the QM modeling tool. This example is a bare bones hand coded event machine example. When you complete this tutorial you will be able to create an event driven blinky sketch. I plan to evaluate this platform as a single “threaded” asynchronous finite state machine, not as a concurrent state machine promoted by Quantum Leaps, however this example can be used for both.

I will preface this post by saying that, as of this writing, I found discrepancies between the supplied functioning example code (in this case Dining Philosopher Problem) and some of the example code found in the available documentation (specifically “7. Coding Hierarchical State Machines” in the "Fly 'n' Shoot" game). I am not an expert on this platform; I’ve only studied it for a few days, however this code in this example compiles and runs on my Arduino Duemilanove board very nicely, and with a slight modification to slow down the time tick calls, it runs well with the VisualMicroVS2010 IDE plugin debugger.

To begin, install the Quantum Platform library linked here (http://arduino.cc/playground/Code/QP), follow the installation directions and create a new Arduino sketch.

Add the QP library to your project and delete the Loop() method. The Loop() routine is implemented by the framework so you will get a compile error if it remains in your ino file. You will also need to add the Board Support Package files (bsp.h and bsp.cpp) to your project. I started by copying these files from the Dining Philosopher Problem (qp_dpp) example project found in the download.

You will need to remove the reference to dpp.h from the bsp.cpp file, however removing this reference also removes the namespace directive so add “using namespace QP;” under the Arduino.h include reference.  If you compile this you will get an undeclared reference “PAUSE_SIG” error in the ISR(TIMER2_COMPA_vect), so remove the entire if… conditional and leave this method as:
 ----------------------------------------
ISR(TIMER2_COMPA_vect)
{
    QF::TICK(&l_TIMER2_COMPA);  // process all armed time events
}
---------------------------------------- 
The project should compile and show about 3500 bytes of used code. This means the QF engine takes about 3K of code space, which is very efficient for the features it offers!

Next create a global include file for the entire project, I’ll call it globals.h, and add the following section:
----------------------------------------
#ifndef globals_h
#define globals_h

#include "Arduino.h"

using namespace QP;

enum APPSignals
{
    TIME_TICK_SIG = Q_USER_SIG, // time tick for all classes that sign up
    MAX_PUB_SIG,                // the last published signal
};

const uint8_t  LEDPin = 4;

#endif  // globals_h
 ----------------------------------------
Here we are defining a time tick TIME_TICK_SIGnal as an extension of the QP built-in signals by post pending our set onto the end of framework Q_USER_SIG. Also note the “size” definition of MAX_PUB_SIG. We will code the time tick to be sent to all subscribers every time the interrupt runs. Also note that I’ve set the LED pin to 4. Note that QP uses pin 13 LED. While running normally the Arduino board LED glows, but if there is an assertion failure this LED turns full on so it shows brightly. This is a good debug aid.

To code up the time tick, go back to the bsp.cpp file and add the globals.h include ”#include "globals.h"”.  Then add a call to publish the time event on each timer interrupt to any classes that have subscribed to the event. I put this before the “QF::TICK” process but it works equally well, for now, after it.
---------------------------------------- 
ISR(TIMER2_COMPA_vect)
{
    QF::PUBLISH(Q_NEW(QEvt, TIME_TICK_SIG), &l_TIMER2_COMPA);
    QF::TICK(&l_TIMER2_COMPA);   // process all armed time events
}
----------------------------------------
Next build an LED blink class and subscribe to the time tick event. The BlinkLED.h file:

---------------------------------------- 
#include "qp_port.h"
#include "bsp.h"
#include "globals.h"

using namespace QP;

class BlinkLED :
      public QActive
{
      public:
            BlinkLED(void) : QActive(Q_STATE_CAST(&BlinkLED::initial)){}

      protected:
            static QState initial (BlinkLED *me, QEvent const *e);
            static QState active  (BlinkLED *me, QEvent const *e);
};

      Static BlinkLED l_BlinkLED; // sole instance of the active object
      QActive * const AO_BlinkLED = &l_BlinkLED; // ptr to AO_BlinkLED

      static      uint16_t    BLED_tickCount    =     0;
      static      uint16_t    BLED_togglePoint  =     66;
      static      uint8_t     BLED_ledState     =     LOW;

#endif  // BlinkLED_h
---------------------------------------- 

This class was modeled from the QP documentation. The constructor initializes the base class QActive with a starting pointer to “initial()”. I designed this class to only have two methods, initial and active, and both methods must return a type of QActive and must take a pointer to this instance and to an event argument pointer (*e). Although not required for this example, the event arg has to be cast to the type we are expecting before it can be used.

The instance is a static global “l_BlinkLED and the const active object is this reference. This is used by the setup method in ino. The 3 static storage variables are used to count the number of times this object is called during the timer tick interrupt and toggles the LED every “togglePoint” times it is called. I’m not advocating this method for tracking time, it is just for this exercise, and that is, the LED doesn’t blink unless it is called multiple times.

The BlinkLED.cpp
---------------------------------------- 
#include "BlinkLED.h"

QState BlinkLED::initial(BlinkLED *me, QEvent const *)
{
       me->subscribe(TIME_TICK_SIG);
       return Q_TRAN(&BlinkLED::active); // initial transition
}

QState BlinkLED::active(BlinkLED *me, QEvent const *e)
{
      switch (e->sig)
      {
            case Q_INIT_SIG:
                  pinMode(LEDPin, OUTPUT);
                  digitalWrite(LEDPin,BLED_ledState);
                  break;
           
            case TIME_TICK_SIG:
                  if(BLED_tickCount++ > BLED_togglePoint)
                  {
                     BLED_ledState = BLED_ledState == LOW ? HIGH : LOW;
                     BLED_tickCount = 0;
                     digitalWrite(LEDPin,BLED_ledState);
                  }
                  break;
     
            default:
                  break;
     }
     return Q_SUPER(&QHsm::top);
}
---------------------------------------- 

The framework will initialize the QActive base class which in turn sets up the call to initial(…). This methods in turn subscribes to the TIME_TICK_SIGNAL and returns a pointer to the a method the framework is to call on the next subscribed event, which is the active(…) method.

During startup, the active(…) method will be called with Q_ENTRY_SIG, Q_EXIT_SIG and Q_INIT_SIG. We are only interested in the INIT signal event, and use it to initialize class variables etc. After that, each subsequent call, in this example, will be the time tick event. The init calls are made during the Setup(…) routine, whereas the time tick event is initiated in the interrupt routine.

 The last step is getting the framework initialized and running in the ino setup() routine.
----------------------------------------
#include <qp_port.h>
#include "bsp.h"
#include "globals.h"

#include "BlinkLED.h"

static QF_MPOOL_EL(QEvt) l_smlPoolSto[5];         // small event pool
static QSubscrList       l_subscrSto[MAX_PUB_SIG];// subscriber store
static QEvent const     *l_BlinkLEDQueueSto[1];   // One LED blinker


void setup()
{
    BSP_init();
    QF::init();     // initialize the framework and underlying RT kernel

    QF::poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), 
                              sizeof(l_smlPoolSto[0]));

    QF::psInit(l_subscrSto, Q_DIM(l_subscrSto)); 
                                // init publish-subscribe

    uint8_t priority = 1;

    AO_BlinkLED->start
    (
       priority++,      // object priority, 63 is highest no two alike
       l_BlinkLEDQueueSto, // storage queue used by this object
       Q_DIM(l_BlinkLEDQueueSto),  // size of object in queue
       (void *)0, // the stack storage in bytes.
        0U        // the stack size in bytes.
     );
}
----------------------------------------  

Some notes and caveats.

The event (QEvt) pool size is based on two factors, the [size] of the array and the size of the structure referenced. For example the QEvt class is small, so if you derive from this class and add members you need to change the event argument reference, for example QF_MPOOL_EL(MyEventArgStructure). I discovered that when I changed the QEvt arg reference structure and did not reference it in this allocation my application crashed. I do not know yet if this allocation should be the largest of the structures you will use if you define multiple event arg classes (I will attempt to cover this in a subsequent blog post). In this example we don't send anything but the default event so the simple allocation in this example works fine.

The QSubscriberList storage is self-evident, but the queue size for the Blink LED is not. There is a reference to the Quantum Leaps manual that you can purchase that describes how to determine the required storage. Perhaps I can figure this out through trial and error or additional reading but I suspect it might have to do with a preemptive interrupt configuration. The model that this example is running on is the non-preemptive RTC style Run-To-Completion model (a.k.a. Simple Non-Preemptive "Vanilla" Kernel).

The BSP init and QF init are standard platform setup calls as well as the poolInit and psInit.

The active object start(…) call registers the class. What I found is that the priority of the object is not like a thread priority similar to low medium and high, but rather, it must be a unique priority, so each object should have a different priority from 1 the lowest, to 63 the highest. For convenience in adding other classes I have used priority++ to set and increment the priority, but in this example it could have been set to 1. If the priority for two objects is identical, the initialization fails and the framework appears to get into an endless startup loop so it never runs.

One last note, the framework Run(..) method call is not required in the Startup method even though it appears in some QP documentation. It is called when the framework runs it's predefined loop() method.

So hopefully your LED should be blinking while pin 13 LED glows. I followed these exact steps while creating this post so I hope I didn’t forget to write something down.

I plan to build on this project by adding a sensor to demonstrate an object that posts an event to registered subscriber.

Project files can be downloaded here:

"Simple Event Driven Blinky Sketch - Arduino IDE version"
http://code.google.com/p/quantum-leaps-arduino-light/downloads/list