{"id":59,"date":"2012-11-07T10:01:58","date_gmt":"2012-11-07T10:01:58","guid":{"rendered":"http:\/\/ermine-electronics.co.uk\/?p=59"},"modified":"2014-10-04T08:56:55","modified_gmt":"2014-10-04T08:56:55","slug":"how-to-use-openkontrolgateway-data-logging","status":"publish","type":"post","link":"https:\/\/www.richardmudhar.com\/blog\/2012\/11\/how-to-use-openkontrolgateway-data-logging\/","title":{"rendered":"How to use the OpenKontrolGateway for Data Logging"},"content":{"rendered":"<p>The obvious place to look is this post, <a href=\"http:\/\/openmicros.org\/index.php\/articles\/92-ciseco-product-documentation\/openkontrol-gateway\/179-openkontrol-gateway-as-a-data-logger\">OpenKontrol Gateway as Data Logger<\/a> from openmicros.org, which has some sample code, which didn&#8217;t work for me. It created the log file but didn&#8217;t write any data to it.<\/p>\n<p>I hacked this to make it write the data<\/p>\n<pre>unixtime,day\/month\/year hour:minutes:seconds, LLAPmessage\r\n1352219944,6\/11\/2012,16:39:4,ECTMPA7.866\r\n1352219992,6\/11\/2012,16:39:52,EATMPA21.59\r\n1352220052,6\/11\/2012,16:40:52,EBTMPA20.82<\/pre>\n<p>It&#8217;s also a bit more tricky to use, compared to a regular data logger. This is because the RF network is unsynchronised &#8211; the temperature nodes fire themselves up every 5 minutes, transmit a temperature reading and then go to sleep. This isn&#8217;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 &#8211; anything starting with an a is logged.<\/p>\n<p>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.<\/p>\n<p>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<\/p>\n<p>&nbsp;<\/p>\n<p>Modified program shown below<\/p>\n<p><!--more--><\/p>\n<pre lang=\"C\"> \r\n\r\n#include \r\n#include \r\n#include \"RTClib.h\"\r\n\r\n#define ECHO_TO_SERIAL   1 \/\/ echo data to serial port\r\n#define redLEDpin 17\r\n\r\n\/\/ original source http:\/\/openmicros.org\/index.php\/articles\/92-ciseco-product-documentation\/openkontrol-gateway\/179-openkontrol-gateway-as-a-data-logger\r\n\/\/ hacked by an ermine 6 Nov 2012 to make this write data to the SD card\r\n\/\/ and add the unix timestamp\r\n\/\/ see http:\/\/ermine-electronics.co.uk\/?p=59 for more\r\n\/\/ V0.10\r\n\r\nchar incomingMsg[12] = \"nnmmmmmmmmm\";\r\n\r\nRTC_DS1307 RTC; \/\/ define the Real Time Clock object\r\n\r\nconst int chipSelect = 4; \/\/SD Card chip select 4\r\n\r\n\/\/ the logging file\r\nFile logfile;\r\n\r\nchar filename[] = \"LOGGER00.CSV\";  \/\/ ermine: make this global in scope because I am going to open and close it in the logging loop\r\n\r\nvoid error(char *str)\r\n{\r\n  Serial.print(\"error: \");\r\n  Serial.println(str);\r\n  \/\/ red LED indicates error\r\n  digitalWrite(redLEDpin, HIGH);\r\n  while(1);  \/\/halts on error\r\n}\r\n\r\nvoid setup(void)\r\n{\r\n  Serial.begin(9600);\r\n  Serial.println(); \r\n  \/\/ use debugging LEDs\r\n  pinMode(redLEDpin, OUTPUT);\r\n    \/\/ initialize the SD card\r\n  Serial.print(\"Initializing SD card...\");\r\n  \/\/ make sure that the default chip select pin is set to\r\n  \/\/ output, even if you don't use it:\r\n  pinMode(10, OUTPUT);\r\n\r\n  \/\/ see if the card is present and can be initialized:\r\n  if (!SD.begin(chipSelect)) {\r\n    error(\"Card failed, or not present\");\r\n  }\r\n  Serial.println(\"card initialized.\");\r\n\r\n  \/\/ create a new file\r\n  \/\/ char filename[] = \"LOGGER00.CSV\";\r\n  for (uint8_t i = 0; i &lt; 100; i++) {\r\n    filename[6] = i\/10 + '0';\r\n    filename[7] = i%10 + '0';\r\n    if (! SD.exists(filename)) {\r\n      \/\/ only open a new file if it doesn't exist\r\n      logfile = SD.open(filename, FILE_WRITE);\r\n      break;  \/\/ leave the loop!\r\n    }\r\n  }  \r\n  if (! logfile) {\r\n    error(\"couldnt create file\");\r\n  }\r\n  Serial.print(\"Logging to: \");\r\n  Serial.println(filename);\r\n\r\n  \/\/ connect to RTC\r\n  Wire.begin(); \r\n  if (!RTC.begin()) {\r\n    logfile.println(\"RTC failed\");\r\n    error(\"RTC failed\");\r\n  }\r\n   logfile.println(\"unixtime,day\/month\/year hour:minutes:seconds, LLAPmessage\");   \r\n   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\r\n}\r\n\r\n void loop()\r\n {\r\n  if (Serial.available() &gt;= 12)\r\n   {\r\n   logdata();\r\n   }\r\n}\r\n\r\nvoid logdata(){\r\n  DateTime now;\r\n if (Serial.read() == 'a')\r\n    {\r\n      digitalWrite(redLEDpin, HIGH);\r\n      \/\/ got start of message\r\n      for (byte i=0; i&lt;11; i++) incomingMsg[i] = Serial.read();\r\n      incomingMsg[11]=0;  \/\/\r\n        \/\/ fetch the time\r\n  now = RTC.now();\r\n  \/\/ log time\r\n  logfile = SD.open(filename, FILE_WRITE); \/\/ ermine: open for writing first, cos we open and close each data line\r\n  if (logfile) {\r\n    logfile.print(now.unixtime());\r\n    logfile.print(',');\r\n    logfile.print(now.day(), DEC);\r\n    logfile.print(\"\/\");\r\n    logfile.print(now.month(), DEC);\r\n    logfile.print(\"\/\");\r\n    logfile.print(now.year(), DEC);\r\n    logfile.print(\",\");\r\n    logfile.print(now.hour(), DEC);\r\n    logfile.print(\":\");\r\n    logfile.print(now.minute(), DEC);\r\n    logfile.print(\":\");\r\n    logfile.print(now.second(), DEC);\r\n    logfile.print(',');\r\n    \/\/log aP command\r\n    logfile.print(incomingMsg);\r\n    logfile.println();\r\n    logfile.close();  \/\/ ermine: have to close the file to get a line written that you actually get to read with Excel\r\n    }  \r\n  \/\/ if the file isn't open, pop up an error:\r\n  else {\r\n    error(\"error opening log file\");\r\n  } \r\n\r\n  digitalWrite(redLEDpin, LOW);\r\n  Serial.flush();\r\n  }\r\n}\r\n\r\n\/\/ this is the end<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>The obvious place to look is this post, OpenKontrol Gateway as Data Logger from openmicros.org, which has some sample code, which didn&#8217;t work for me. It created the log file but didn&#8217;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&#8217;s also a &hellip; <a href=\"https:\/\/www.richardmudhar.com\/blog\/2012\/11\/how-to-use-openkontrolgateway-data-logging\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;How to use the OpenKontrolGateway for Data Logging&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[57],"tags":[264,25,43,44],"class_list":["post-59","post","type-post","status-publish","format-standard","hentry","category-electronics","tag-arduino","tag-data-logger","tag-okg","tag-openkontrolgateway"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p5aOO7-X","jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.richardmudhar.com\/blog\/wp-json\/wp\/v2\/posts\/59","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.richardmudhar.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.richardmudhar.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.richardmudhar.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.richardmudhar.com\/blog\/wp-json\/wp\/v2\/comments?post=59"}],"version-history":[{"count":1,"href":"https:\/\/www.richardmudhar.com\/blog\/wp-json\/wp\/v2\/posts\/59\/revisions"}],"predecessor-version":[{"id":1625,"href":"https:\/\/www.richardmudhar.com\/blog\/wp-json\/wp\/v2\/posts\/59\/revisions\/1625"}],"wp:attachment":[{"href":"https:\/\/www.richardmudhar.com\/blog\/wp-json\/wp\/v2\/media?parent=59"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.richardmudhar.com\/blog\/wp-json\/wp\/v2\/categories?post=59"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.richardmudhar.com\/blog\/wp-json\/wp\/v2\/tags?post=59"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}