How to use the OpenKontrolGateway for Data Logging

The obvious place to look is this post, OpenKontrol Gateway as Data Logger from openmicros.org, which has some sample code, which didn’t work for me. It created the log file but didn’t write any data to it.

I hacked this to make it write the data

unixtime,day/month/year hour:minutes:seconds, LLAPmessage
1352219944,6/11/2012,16:39:4,ECTMPA7.866
1352219992,6/11/2012,16:39:52,EATMPA21.59
1352220052,6/11/2012,16:40:52,EBTMPA20.82

It’s also a bit more tricky to use, compared to a regular data logger. This is because the RF network is unsynchronised – the temperature nodes fire themselves up every 5 minutes, transmit a temperature reading and then go to sleep. This isn’t a polled system, and there may be other transactions on the network. The data logger simply logs all of these transactions, be they temperature readings, status readings or setting up devices – anything starting with an a is logged.

This is why I added the unix timestamp, so that it would be possible to plot these unsynchronised elements onto the same xy plot, with the timestamp along the x axis. Some data might want to be sampled more frequently than every 5 minutes, and some might be reactive, like a PIR sensor.

The receiving application has to pull all this stuff apart, first splitting the streams into the devices, using LEFT(LLAPmessage,3). This will always be aXY with XY being the deviceID

 

Modified program shown below

 

#include 
#include 
#include "RTClib.h"

#define ECHO_TO_SERIAL   1 // echo data to serial port
#define redLEDpin 17

// original source http://openmicros.org/index.php/articles/92-ciseco-product-documentation/openkontrol-gateway/179-openkontrol-gateway-as-a-data-logger
// hacked by an ermine 6 Nov 2012 to make this write data to the SD card
// and add the unix timestamp
// see http://ermine-electronics.co.uk/?p=59 for more
// V0.10

char incomingMsg[12] = "nnmmmmmmmmm";

RTC_DS1307 RTC; // define the Real Time Clock object

const int chipSelect = 4; //SD Card chip select 4

// the logging file
File logfile;

char filename[] = "LOGGER00.CSV";  // ermine: make this global in scope because I am going to open and close it in the logging loop

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
  // red LED indicates error
  digitalWrite(redLEDpin, HIGH);
  while(1);  //halts on error
}

void setup(void)
{
  Serial.begin(9600);
  Serial.println(); 
  // use debugging LEDs
  pinMode(redLEDpin, OUTPUT);
    // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");

  // create a new file
  // char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break;  // leave the loop!
    }
  }  
  if (! logfile) {
    error("couldnt create file");
  }
  Serial.print("Logging to: ");
  Serial.println(filename);

  // connect to RTC
  Wire.begin(); 
  if (!RTC.begin()) {
    logfile.println("RTC failed");
    error("RTC failed");
  }
   logfile.println("unixtime,day/month/year hour:minutes:seconds, LLAPmessage");   
   logfile.close();    // ermine: you hafta close this darn thing to actulaly get to write the data to the card. Remember to open logfile before writing. Seems to append okay even if you say FILE_WRITE
}

 void loop()
 {
  if (Serial.available() >= 12)
   {
   logdata();
   }
}

void logdata(){
  DateTime now;
 if (Serial.read() == 'a')
    {
      digitalWrite(redLEDpin, HIGH);
      // got start of message
      for (byte i=0; i<11; i++) incomingMsg[i] = Serial.read();
      incomingMsg[11]=0;  //
        // fetch the time
  now = RTC.now();
  // log time
  logfile = SD.open(filename, FILE_WRITE); // ermine: open for writing first, cos we open and close each data line
  if (logfile) {
    logfile.print(now.unixtime());
    logfile.print(',');
    logfile.print(now.day(), DEC);
    logfile.print("/");
    logfile.print(now.month(), DEC);
    logfile.print("/");
    logfile.print(now.year(), DEC);
    logfile.print(",");
    logfile.print(now.hour(), DEC);
    logfile.print(":");
    logfile.print(now.minute(), DEC);
    logfile.print(":");
    logfile.print(now.second(), DEC);
    logfile.print(',');
    //log aP command
    logfile.print(incomingMsg);
    logfile.println();
    logfile.close();  // ermine: have to close the file to get a line written that you actually get to read with Excel
    }  
  // if the file isn't open, pop up an error:
  else {
    error("error opening log file");
  } 

  digitalWrite(redLEDpin, LOW);
  Serial.flush();
  }
}

// this is the end

One thought on “How to use the OpenKontrolGateway for Data Logging”

Leave a Reply

Your email address will not be published. Required fields are marked *