mbed IoT Gateway board demo. This program received wireless data from JeeNode and uploads to Pachube. http://www.skpang.co.uk/catalog/mbed-iot-gateway-board-p-1051.html Full kit: http://www.skpang.co.uk/catalog/mbed-iot-gateway-full-kit-p-1052.html

Dependencies:   EthernetNetIf mbed

Files at this revision

API Documentation at this revision

Comitter:
pangsk
Date:
Mon Jan 02 20:03:01 2012 +0000
Child:
1:63b6db2e24a5
Commit message:
Initial release.

Changed in this revision

EthernetNetIf.lib Show annotated file Show diff for this revision Revisions of this file
HTTPClient.lib Show annotated file Show diff for this revision Revisions of this file
Pachube/Pachube.cpp Show annotated file Show diff for this revision Revisions of this file
Pachube/Pachube.h Show annotated file Show diff for this revision Revisions of this file
Pachube/PachubeV2CSV.cpp Show annotated file Show diff for this revision Revisions of this file
Pachube/PachubeV2CSV.h Show annotated file Show diff for this revision Revisions of this file
RF12B/RF12B.cpp Show annotated file Show diff for this revision Revisions of this file
RF12B/RF12B.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EthernetNetIf.lib	Mon Jan 02 20:03:01 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/donatien/code/EthernetNetIf/#bc7df6da7589
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPClient.lib	Mon Jan 02 20:03:01 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/donatien/code/HTTPClient/#d0be6af2d1db
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Pachube/Pachube.cpp	Mon Jan 02 20:03:01 2012 +0000
@@ -0,0 +1,17 @@
+/**
+ * Pachube API interface driver. (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+
+#include "Pachube.h"
+
+const std::string Pachube::REQUESTHEADER = "X-PachubeApiKey";
+const std::string Pachube::URLBASE_V2 = "http://api.pachube.com/v2";
+
+Pachube::Pachube(std::string APIKEY) : APIKEY(APIKEY) {
+}
+
+Pachube::~Pachube() {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Pachube/Pachube.h	Mon Jan 02 20:03:01 2012 +0000
@@ -0,0 +1,168 @@
+/**
+ * Pachube API interface driver. (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+
+#ifndef _PACHUBE_H_
+#define _PACHUBE_H_
+
+#include <string>
+
+class Pachube {
+public:
+
+    explicit Pachube(std::string APIKEY);
+
+    virtual ~Pachube();
+
+    /*
+     * =================================================================
+     *  Environments (feeds)
+     * =================================================================
+     */
+
+    /**
+     * List all available feeds: GET /v2/feeds
+     *
+     * @param page Integer indicating which page of results you are requesting.
+     * @param per_page Integer defining how many results to return per page (1 to 1000).
+     * @param content String parameter ('full' or 'summary') describing whether we want full or summary results. Full results means all datastream values are returned, summary just returns the environment meta data for each feed.
+     * @param q Full text search parameter. Should return any feeds matching this string.
+     * @param tag Returns feeds containing datastreams tagged with the search query.
+     * @param user Returns feeds created by the user specified.
+     * @param units Returns feeds containing datastreams with units specified by the search query.
+     * @param status Possible values ('live', 'frozen', or 'all'). Whether to search for only live feeds, only frozen feeds, or all feeds. Defaults to all.
+     * @param order Order of returned feeds. Possible values ('created_at', 'retrieved_at', or 'relevance').
+     */
+    virtual int listAllAvailableFeeds(
+        int page,
+        int per_page,
+        std::string content,
+        std::string q,
+        std::string tag,
+        std::string user,
+        std::string units,
+        std::string status,
+        std::string order,
+        std::string &datatext) = 0;
+
+    /**
+     * Create new feed: POST /v2/feeds
+     */
+    virtual int createNewFeed(void) = 0;
+
+    /**
+     * Read feed: GET /v2/feeds/<feed_id>
+     */
+    virtual int readFeed(int feed_id, std::string &datatext) = 0;
+
+    /**
+     * Update feed: PUT /v2/feeds/<feed_id>
+     */
+    virtual int updateFeed(int feed_id) = 0;
+
+    /**
+     * Delete feed: DELETE /v2/feeds/<feed_id>
+     */
+    virtual int deleteFeed(int feed_id) = 0;
+
+    /*
+     * =================================================================
+     *  Datastreams
+     * =================================================================
+     */
+
+    /**
+     * Create new datastream: POST /v2/feeds/<feed_id>/datastreams
+     *
+     * @param feed_id Feed ID.
+     * @param stream_id Stream ID text.
+     * @param value value.
+     *
+     * @return Return code from a web server.
+     */
+    virtual int createNewDataStream(int feed_id, std::string stream_id, std::string value) = 0;
+
+    /**
+     * Read datastream - GET /v2/feeds/<feed_id>/datastreams/<datastream_id>
+     *
+     * @param feed_id Feed ID.
+     * @param stream_id Stream ID text.
+     *
+     * @return Return code from a web server.
+     */
+    virtual int readDataStream(int feed_id, std::string stream_id, std::string &datatext) = 0;
+
+    /**
+     * Update datastream: PUT /v2/feeds/<feed_id>/datastreams/<datastream_id>
+     *
+     * @param feed_id Feed ID.
+     * @param stream_id Stream ID text.
+     * @param value value.
+     *
+     * @return Return code from a web server.
+     */
+    virtual int updateDataStream(int feed_id, std::string stream_id, std::string value) = 0;
+
+    /**
+     * Delete datastream: DELETE /v2/feeds/<feed_id>/datastreams/<datastream_id>
+     *
+     * @param feed_id Feed ID.
+     * @param stream_id Stream ID text.
+     *
+     * @return Return code from a web server.
+     */
+    virtual int deleteDataStream(int feed_id, std::string stream_id) = 0;
+
+protected:
+    const std::string APIKEY;
+    static const std::string REQUESTHEADER;
+    static const std::string URLBASE_V2;
+};
+
+#endif
+
+/*
+Pachube v2 API Documentation
+http://api.pachube.com/v2/
+
+# Environments (feeds)
+
+o   * List all available feeds: GET /v2/feeds
+o   * Create new feed: POST /v2/feeds
+o   * Read feed: GET /v2/feeds/<feed_id>
+o   * Update feed: PUT /v2/feeds/<feed_id>
+o   * Delete feed: DELETE /v2/feeds/<feed_id>
+
+# Datastreams
+
+o   * Create new datastream: POST /v2/feeds/<feed_id>/datastreams
+o   * Read datastream - GET /v2/feeds/<feed_id>/datastreams/<datastream_id>
+o   * Update datastream: PUT /v2/feeds/<feed_id>/datastreams/<datastream_id>
+o   * Delete datastream: DELETE /v2/feeds/<feed_id>/datastreams/<datastream_id>
+
+# Datapoints
+
+    * Create datapoint: POST /v2/feeds/<feed_id>/datastreams/<datastream_id>/datapoints
+    * Read datapoint: GET /v2/feeds/<feed_id>/datastreams/<datastream_id>/datapoints/<timestamp>
+    * Update datapoint: PUT /v2/feeds/<feed_id>/datastreams/<datastream_id>/datapoints/<timestamp>
+    * Delete datapoint: DELETE /v2/feeds/<feed_id>/datastreams/<datastream_id>/datapoints/<timestamp>
+
+# Triggers
+
+    * List triggers: GET /v2/triggers
+    * Create trigger: POST /v2/triggers
+    * Read trigger: GET /v2/triggers/<trigger_id>
+    * Update trigger: PUT /v2/triggers/<trigger_id>
+    * Delete trigger: DELETE /v2/triggers/<trigger_id>
+
+# Users
+
+    * List all users: GET /v2/users
+    * Create user: POST /v2/users
+    * Read user: GET /v2/users/<user_id>
+    * Update user: PUT /v2/users/<user_id>
+    * Delete user: DELETE /v2/users/<user_id>
+*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Pachube/PachubeV2CSV.cpp	Mon Jan 02 20:03:01 2012 +0000
@@ -0,0 +1,266 @@
+/**
+ * Pachube API interface driver. (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+
+#include "PachubeV2CSV.h"
+#include "EthernetNetIf.h"
+#include "HTTPClient.h"
+
+PachubeV2CSV::PachubeV2CSV(std::string APIKEY) : Pachube(APIKEY) {
+}
+
+PachubeV2CSV::~PachubeV2CSV() {
+}
+
+/*
+ * =================================================================
+ *  Environments (feeds)
+ * =================================================================
+ */
+
+/**
+ * List all available feeds: GET /v2/feeds
+ */
+int PachubeV2CSV::listAllAvailableFeeds(
+        int page,
+        int per_page,
+        std::string content,
+        std::string q,
+        std::string tag,
+        std::string user,
+        std::string units,
+        std::string status,
+        std::string order,
+        std::string &datatext) {
+    HTTPClient client;
+    client.setRequestHeader(Pachube::REQUESTHEADER, APIKEY);
+
+    HTTPText text("text/csv");
+    text.set("");
+    HTTPText data;
+    
+    /*
+     * Example: http://api.pachube.com/v2/feeds
+     */
+    char tmp[32];
+    sprintf(tmp, "?page=%d&per_page=%d", page, per_page);
+    string URL = Pachube::URLBASE_V2 + "/feeds.csv" + std::string(tmp);
+    
+    if (content.length() > 0) {
+        URL = URL + "&content=" + content;
+    }
+    if (q.length() > 0) {
+        URL = URL + "&q=" + q;
+    }
+    if (tag.length() > 0) {
+        URL = URL + "&tag=" + tag;
+    }
+    if (user.length() > 0) {
+        URL = URL + "&user=" + user;
+    }
+    if (units.length() > 0) {
+        URL = URL + "&units=" + units;
+    }
+    if (status.length() > 0) {
+        URL = URL + "&status=" + status;
+    }
+    if (order.length() > 0) {
+        URL = URL + "&order=" + order;
+    }
+
+    HTTPResult result = client.get(URL.c_str(), &data);
+    datatext = data.get();
+    
+    return client.getHTTPResponseCode();
+}
+
+/**
+ * Create new feed: POST /v2/feeds
+ */
+int PachubeV2CSV::createNewFeed(void) {
+    error("CSV is not supported for creating Environments because it cannot represent the required parameters due to its very simple format.");
+    return 404;
+}
+
+/**
+ * Read feed: GET /v2/feeds/<feed_id>
+ */
+int PachubeV2CSV::readFeed(int feed_id, std::string &datatext) {
+    HTTPClient client;
+    client.setRequestHeader(Pachube::REQUESTHEADER, APIKEY);
+
+    HTTPText text("text/csv");
+    text.set("");
+    HTTPText data;
+
+    /*
+     * Example: http://api.pachube.com/v2/feeds/1977
+     */
+    char feed_id_char[32];
+    sprintf(feed_id_char, "%d", feed_id);
+    const string URL = Pachube::URLBASE_V2 + "/feeds/" + std::string(feed_id_char) + ".csv";
+
+    HTTPResult result = client.get(URL.c_str(), &data);
+    datatext = data.get();
+    return client.getHTTPResponseCode();
+}
+
+/**
+ * Update feed: PUT /v2/feeds/<feed_id>
+ */
+int PachubeV2CSV::updateFeed(int feed_id) {
+    HTTPClient client;
+    client.setRequestHeader(Pachube::REQUESTHEADER, APIKEY);
+
+    HTTPText text("text/csv");
+    text.set("");
+
+    /*
+     * Example: http://api.pachube.com/v2/feeds/1977?_method=put
+     */
+    char feed_id_char[32];
+    sprintf(feed_id_char, "%d", feed_id);
+    const string URL = Pachube::URLBASE_V2 + "/feeds/" + std::string(feed_id_char) + "?_method=put";
+
+    HTTPResult result = client.post(URL.c_str(), text, NULL);
+    return client.getHTTPResponseCode();
+}
+
+/**
+ * Delete feed: DELETE /v2/feeds/<feed_id>
+ */
+int PachubeV2CSV::deleteFeed(int feed_id) {
+    HTTPClient client;
+    client.setRequestHeader(Pachube::REQUESTHEADER, APIKEY);
+
+    HTTPText text("text/csv");
+    text.set("");
+
+    /*
+     * Example: http://api.pachube.com/v2/feeds/1977?_method=delete
+     */
+    char feed_id_char[32];
+    sprintf(feed_id_char, "%d", feed_id);
+    const string URL = Pachube::URLBASE_V2 + "/feeds/" + std::string(feed_id_char) + "?_method=delete";
+
+    HTTPResult result = client.post(URL.c_str(), text, NULL);
+    return client.getHTTPResponseCode();
+}
+
+/*
+ * =================================================================
+ *  Datastreams
+ * =================================================================
+ */
+
+/**
+ * Create new datastream: POST /v2/feeds/<feed_id>/datastreams
+ *
+ * @param feed_id Feed ID.
+ * @param stream_id Stream ID text.
+ * @param value value.
+ *
+ * @return Return code from a web server.
+ */
+int PachubeV2CSV::createNewDataStream(int feed_id, std::string stream_id, std::string value) {
+    HTTPClient client;
+    client.setRequestHeader(Pachube::REQUESTHEADER, APIKEY);
+
+    std::string data = stream_id + "," + value;
+    HTTPText text("text/csv");
+    text.set(data);
+
+    /*
+     * Example: http://api.pachube.com/v2/feeds/1977/datastreams
+     */
+    char feed_id_char[32];
+    sprintf(feed_id_char, "%d", feed_id);
+    const string URL = Pachube::URLBASE_V2 + "/feeds/" + std::string(feed_id_char) + "/datastreams";
+
+    HTTPResult result = client.post(URL.c_str(), text, NULL);
+    return client.getHTTPResponseCode();
+}
+
+/**
+ * Read datastream - GET /v2/feeds/<feed_id>/datastreams/<datastream_id>
+ *
+ * @param feed_id Feed ID.
+ * @param stream_id Stream ID text.
+ *
+ * @return Return code from a web server.
+ */
+int PachubeV2CSV::readDataStream(int feed_id, std::string stream_id, std::string &datatext) {
+    HTTPClient client;
+    client.setRequestHeader(Pachube::REQUESTHEADER, APIKEY);
+
+    HTTPText text("text/csv");
+    text.set("");
+    HTTPText data;
+
+    /*
+     * Example: http://api.pachube.com/v2/feeds/1977/datastreams/energy
+     */
+    char feed_id_char[32];
+    sprintf(feed_id_char, "%d", feed_id);
+    const string URL = Pachube::URLBASE_V2 + "/feeds/" + std::string(feed_id_char) + "/datastreams/" + stream_id + ".csv";
+
+    HTTPResult result = client.get(URL.c_str(), &data);
+    datatext = data.get();
+    return client.getHTTPResponseCode();
+}
+
+/**
+ * Update datastream: PUT /v2/feeds/<feed_id>/datastreams/<datastream_id>
+ *
+ * @param feed_id Feed ID.
+ * @param stream_id Stream ID text.
+ * @param value value.
+ *
+ * @return Return code from a web server.
+ */
+int PachubeV2CSV::updateDataStream(int feed_id, std::string stream_id, std::string value) {
+    HTTPClient client;
+    client.setRequestHeader(Pachube::REQUESTHEADER, APIKEY);
+
+    HTTPText text("text/csv");
+    text.set(value);
+
+    /*
+     * Example: http://api.pachube.com/v2/feeds/1977/datastreams/energy?_method=put
+     */
+    char feed_id_char[32];
+    sprintf(feed_id_char, "%d", feed_id);
+    const string URL = Pachube::URLBASE_V2 + "/feeds/" + std::string(feed_id_char) + "/datastreams/" + stream_id + "?_method=put";
+
+    HTTPResult result = client.post(URL.c_str(), text, NULL);
+    return client.getHTTPResponseCode();
+}
+
+/**
+ * Delete datastream: DELETE /v2/feeds/<feed_id>/datastreams/<datastream_id>
+ *
+ * @param feed_id Feed ID.
+ * @param stream_id Stream ID text.
+ *
+ * @return Return code from a web server.
+ */
+int PachubeV2CSV::deleteDataStream(int feed_id, std::string stream_id) {
+    HTTPClient client;
+    client.setRequestHeader(Pachube::REQUESTHEADER, APIKEY);
+
+    HTTPText text("text/csv");
+    text.set("");
+
+    /*
+     * Example: http://api.pachube.com/v2/feeds/1977/datastreams/energy?_method=delete
+     */
+    char feed_id_char[32];
+    sprintf(feed_id_char, "%d", feed_id);
+    const string URL = Pachube::URLBASE_V2 + "/feeds/" + std::string(feed_id_char) + "/datastreams/" + stream_id + "?_method=delete";
+
+    HTTPResult result = client.post(URL.c_str(), text, NULL);
+    return client.getHTTPResponseCode();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Pachube/PachubeV2CSV.h	Mon Jan 02 20:03:01 2012 +0000
@@ -0,0 +1,121 @@
+/**
+ * Pachube API interface driver. (Version 0.0.1)
+ *
+ * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
+ * http://shinta.main.jp/
+ */
+
+#ifndef _PACHUBE_V2_CSV_H_
+#define _PACHUBE_V2_CSV_H_
+
+#include "Pachube.h"
+
+class PachubeV2CSV : public Pachube {
+public:
+
+    explicit PachubeV2CSV(std::string APIKEY);
+
+    virtual ~PachubeV2CSV();
+
+    /*
+     * =================================================================
+     *  Environments (feeds)
+     * =================================================================
+     */
+
+    /**
+     * List all available feeds: GET /v2/feeds
+     *
+     * @param page Integer indicating which page of results you are requesting.
+     * @param per_page Integer defining how many results to return per page (1 to 1000).
+     * @param content String parameter ('full' or 'summary') describing whether we want full or summary results. Full results means all datastream values are returned, summary just returns the environment meta data for each feed.
+     * @param q Full text search parameter. Should return any feeds matching this string.
+     * @param tag Returns feeds containing datastreams tagged with the search query.
+     * @param user Returns feeds created by the user specified.
+     * @param units Returns feeds containing datastreams with units specified by the search query.
+     * @param status Possible values ('live', 'frozen', or 'all'). Whether to search for only live feeds, only frozen feeds, or all feeds. Defaults to all.
+     * @param order Order of returned feeds. Possible values ('created_at', 'retrieved_at', or 'relevance').
+     */
+    virtual int listAllAvailableFeeds(
+        int page,
+        int per_page,
+        std::string content,
+        std::string q,
+        std::string tag,
+        std::string user,
+        std::string units,
+        std::string status,
+        std::string order,
+        std::string &datatext);
+
+    /**
+     * Create new feed: POST /v2/feeds
+     */
+    virtual int createNewFeed(void);
+
+    /**
+     * Read feed: GET /v2/feeds/<feed_id>
+     */
+    virtual int readFeed(int feed_id, std::string &datatext);
+
+    /**
+     * Update feed: PUT /v2/feeds/<feed_id>
+     */
+    virtual int updateFeed(int feed_id);
+
+    /**
+     * Delete feed: DELETE /v2/feeds/<feed_id>
+     */
+    virtual int deleteFeed(int feed_id);
+
+    /*
+     * =================================================================
+     *  Datastreams
+     * =================================================================
+     */
+
+    /**
+     * Create new datastream: POST /v2/feeds/<feed_id>/datastreams
+     *
+     * @param feed_id Feed ID.
+     * @param stream_id Stream ID text.
+     * @param value value.
+     *
+     * @return Return code from a web server.
+     */
+    virtual int createNewDataStream(int feed_id, std::string stream_id, std::string value);
+
+    /**
+     * Read datastream - GET /v2/feeds/<feed_id>/datastreams/<datastream_id>
+     *
+     * @param feed_id Feed ID.
+     * @param stream_id Stream ID text.
+     *
+     * @return Return code from a web server.
+     */
+    virtual int readDataStream(int feed_id, std::string stream_id, std::string &datatext);
+
+    /**
+     * Update datastream: PUT /v2/feeds/<feed_id>/datastreams/<datastream_id>
+     *
+     * @param feed_id Feed ID.
+     * @param stream_id Stream ID text.
+     * @param value value.
+     *
+     * @return Return code from a web server.
+     */
+    virtual int updateDataStream(int feed_id, std::string stream_id, std::string value);
+
+    /**
+     * Delete datastream: DELETE /v2/feeds/<feed_id>/datastreams/<datastream_id>
+     *
+     * @param feed_id Feed ID.
+     * @param stream_id Stream ID text.
+     *
+     * @return Return code from a web server.
+     */
+    virtual int deleteDataStream(int feed_id, std::string stream_id);
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RF12B/RF12B.cpp	Mon Jan 02 20:03:01 2012 +0000
@@ -0,0 +1,276 @@
+/* RF12B Library. Based on work done by JeeLabs.org ported to mbed by SK Pang.
+http://jeelabs.net/projects/cafe/wiki/RF12
+
+http://opensource.org/licenses/mit-license.php
+
+Jan 2012 skpang.co.uk
+
+*/
+
+#include "RF12B.h"
+
+// RF12 command codes
+#define RF_RECEIVER_ON  0x82DD
+#define RF_XMITTER_ON   0x823D
+#define RF_IDLE_MODE    0x820D
+#define RF_SLEEP_MODE   0x8205
+#define RF_WAKEUP_MODE  0x8207
+#define RF_TXREG_WRITE  0xB800
+#define RF_RX_FIFO_READ 0xB000
+#define RF_WAKEUP_TIMER 0xE000
+
+// RF12 status bits
+#define RF_LBD_BIT      0x0400
+#define RF_RSSI_BIT     0x0100
+
+// bits in the node id configuration byte
+#define NODE_BAND       0xC0        // frequency band
+#define NODE_ACKANY     0x20        // ack on broadcast packets if set
+#define NODE_ID         0x1F        // id of this node, as A..Z or 1..31
+
+// transceiver states, these determine what to do with each interrupt
+enum {
+    TXCRC1, TXCRC2, TXTAIL, TXDONE, TXIDLE,
+    TXRECV,
+    TXPRE1, TXPRE2, TXPRE3, TXSYN1, TXSYN2,
+};
+
+DigitalOut rfled(LED3);
+DigitalOut t1(p5);
+DigitalOut t2(p6);
+
+RF12B::RF12B(PinName _SDI,
+             PinName _SDO,
+             PinName _SCK,
+             PinName _NCS,
+             PinName _NIRQ):spi(_SDI, _SDO, _SCK),
+        NCS(_NCS), NIRQ(_NIRQ), NIRQ_in(_NIRQ), rfled(LED3),t1(p5),t2(p6) {
+
+    /* SPI frequency, word lenght, polarity and phase */
+    spi.format(8,0);
+    spi.frequency(2000000);
+
+    /* Set ~CS high */
+    NCS = 1;
+
+    /* Setup interrupt to happen on falling edge of NIRQ */
+    NIRQ.fall(this, &RF12B::rxISR);
+}
+
+
+/**********************************************************************
+ *  PRIVATE FUNCTIONS
+ *********************************************************************/
+
+/* Initialises the RF12B module */
+void RF12B::init(uint8_t id, uint8_t band, uint8_t g) {
+  
+    nodeid = id;
+    group = g;
+    rf12_grp = g; 
+    
+    writeCmd(0x0000); // intitial SPI transfer added to avoid power-up problem
+    writeCmd(RF_SLEEP_MODE); // DC (disable clk pin), enable lbd
+    
+    // wait until RFM12B is out of power-up reset, this takes several *seconds*
+    writeCmd(RF_TXREG_WRITE); // in case we're still in OOK mode
+      
+    while (NIRQ == 0)  writeCmd(0x0000);
+        
+    writeCmd(0x80C7 | (2 << 4)); // EL (ena TX), EF (ena RX FIFO), 12.0pF 
+    writeCmd(0xA640); // 868MHz 
+    writeCmd(0xC606); // approx 49.2 Kbps, i.e. 10000/29/(1+6) Kbps
+    writeCmd(0x94A2); // VDI,FAST,134kHz,0dBm,-91dBm 
+    writeCmd(0xC2AC); // AL,!ml,DIG,DQD4 
+   
+    writeCmd(0xCA83); // FIFO8,2-SYNC,!ff,DR 
+    writeCmd(0xCE00 | 1); // SYNC=2DXX&#65307; 
+    
+    writeCmd(0xC483); // @PWR,NO RSTRIC,!st,!fi,OE,EN 
+    writeCmd(0x9850); // !mp,90kHz,MAX OUT 
+    writeCmd(0xCC77); // OB1&#65292;OB0, LPX,&#65281;ddy&#65292;DDIT&#65292;BW0 
+    writeCmd(0xE000); // NOT USE 
+    writeCmd(0xC800); // NOT USE 
+    writeCmd(0xC049); // 1.66MHz,3.1V 
+
+    rxstate = TXIDLE;
+       
+    rfled = 0;
+}
+
+/* Write a command to the RF Module */
+unsigned int RF12B::writeCmd(unsigned int cmd) {
+    NCS = 0;
+    unsigned int recv = spi.write(cmd >>8);
+    recv = spi.write(cmd);
+    NCS = 1;
+    return recv;
+}
+
+/* Sends a byte of data across RF */
+void RF12B::send(unsigned char data) {
+   while (NIRQ);
+   writeCmd(0xB800 + data);
+}
+
+
+/* Interrupt routine for data reception and Txing */
+void RF12B::rxISR() {
+
+   // a transfer of 2x 16 bits @ 2 MHz over SPI takes 2x 8 us inside this ISR
+    writeCmd(0x0000);
+    
+    if (rxstate == TXRECV) {
+        uint8_t in = rf12_xfer(RF_RX_FIFO_READ);
+
+        if (rxfill == 0 && group != 0)
+            rf12_buf[rxfill++] = group;
+            
+        rf12_buf[rxfill++] = in;
+        rf12_crc = _crc16_update(rf12_crc, in);
+
+        if (rxfill >= rf12_len + 5 || rxfill >= RF_MAX)
+            rf12_xfer(RF_IDLE_MODE);
+    } else {
+        uint8_t out;
+
+        if (rxstate < 0) {
+            uint8_t pos = 3 + rf12_len + rxstate++;
+            out = rf12_buf[pos];
+            rf12_crc = _crc16_update(rf12_crc, out);
+        } else
+            switch (rxstate++) {
+                case TXSYN1: out = 0x2D; break;
+                case TXSYN2: out = rf12_grp; rxstate = - (2 + rf12_len); break;
+                case TXCRC1: out = rf12_crc; break;
+                case TXCRC2: out = rf12_crc >> 8; break;
+                case TXDONE: rf12_xfer(RF_IDLE_MODE); // fall through
+                default: out = 0xAA;
+            }
+       
+        rf12_xfer(RF_TXREG_WRITE + out);
+    }
+ }
+
+
+void RF12B::rf12_sendStart (uint8_t hdr, const void* ptr, uint8_t len)
+{
+    rf12_len = len;
+    memcpy((void*) rf12_data, ptr, len);
+  
+    rf12_sendStart2(hdr);
+
+}
+void RF12B::rf12_sendStart2 (uint8_t hdr) {
+    rf12_hdr = hdr & RF12_HDR_DST ? hdr :
+                (hdr & ~RF12_HDR_MASK) + (nodeid & NODE_ID);
+ 
+ /*   if (crypter != 0)
+        crypter(1);
+ */   
+    rf12_crc = ~0;
+
+    rf12_crc = _crc16_update(rf12_crc, rf12_grp);
+    rxstate = TXPRE1;
+      
+    rf12_xfer(RF_XMITTER_ON); // bytes will be fed via interrupts
+}
+
+
+ uint16_t RF12B::rf12_xfer (uint16_t cmd) {
+    NCS = 0;
+    uint16_t reply = rf12_byte(cmd >> 8) << 8;
+    reply |= rf12_byte(cmd);
+    NCS = 1;
+    return reply;
+}
+
+ void RF12B::rf12_recvStart (void) {
+    rxfill = rf12_len = 0;
+    rf12_crc = ~0;
+
+    if (group != 0)
+        rf12_crc = _crc16_update(~0, group);
+
+    rxstate = TXRECV;    
+    rf12_xfer(RF_RECEIVER_ON);
+}
+uint16_t RF12B::check_crc(void)
+{
+
+    return rf12_crc;
+}
+uint8_t RF12B::length(void)
+{
+
+    return rf12_len;
+}
+ uint8_t* RF12B::get_data(void)
+{
+    return  (uint8_t*)rf12_data;
+
+}
+
+
+uint8_t  RF12B::rf12_recvDone (void) {
+    
+     if (rxstate == TXRECV && (rxfill >= rf12_len + 5 || rxfill >= RF_MAX)) {
+        rxstate = TXIDLE;
+ 
+        if (rf12_len > RF12_MAXDATA)
+            rf12_crc = 1; // force bad crc if packet length is invalid
+        if (!(rf12_hdr & RF12_HDR_DST) || (nodeid & NODE_ID) == 31 ||
+                (rf12_hdr & RF12_HDR_MASK) == (nodeid & NODE_ID)) {
+                /*
+                for(i=0;i<rf12_len+6;i++)
+                {
+                    printf("%X ",rf12_buf[i]);
+                }
+                printf(" crc:%x",rf12_crc);
+                */
+           /*     
+            if (rf12_crc == 0 && crypter != 0)
+                crypter(0);
+            else
+                rf12_seq = -1;
+                 */
+            return 1; // it's a broadcast packet or it's addressed to this node
+           
+        }
+    }
+    if (rxstate == TXIDLE)
+        rf12_recvStart();
+    return 0;
+}
+
+uint8_t RF12B::rf12_byte(uint8_t out)
+{
+  unsigned char recv = spi.write(out);
+ 
+    return recv;
+}
+ 
+uint16_t RF12B::_crc16_update(uint16_t crc, uint8_t data) {
+    int i;
+
+    crc ^= data;
+    for (i = 0; i < 8; ++i)
+    {
+        if (crc & 1)
+        crc = (crc >> 1) ^ 0xA001;
+        else
+        crc = (crc >> 1);
+    }
+
+    return crc;
+}
+
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RF12B/RF12B.h	Mon Jan 02 20:03:01 2012 +0000
@@ -0,0 +1,90 @@
+#ifndef _RF12B_H
+#define _RF12B_H
+
+#include "mbed.h"
+
+
+#define rf12_grp        rf12_buf[0]
+#define rf12_hdr        rf12_buf[1]
+#define rf12_len        rf12_buf[2]
+#define rf12_data       (rf12_buf + 3)
+
+#define RF12_HDR_CTL    0x80
+#define RF12_HDR_DST    0x40
+#define RF12_HDR_ACK    0x20
+#define RF12_HDR_MASK   0x1F
+
+#define RF12_MAXDATA    66
+// maximum transmit / receive buffer: 3 header + data + 2 crc bytes
+#define RF_MAX   (RF12_MAXDATA + 5)
+#define PACKET_LEN 16
+
+// shorthand to simplify sending out the proper ACK when requested
+#define RF12_WANTS_ACK ((rf12_hdr & RF12_HDR_ACK) && !(rf12_hdr & RF12_HDR_CTL))
+#define RF12_ACK_REPLY (rf12_hdr & RF12_HDR_DST ? RF12_HDR_CTL : \
+            RF12_HDR_CTL | RF12_HDR_DST | (rf12_hdr & RF12_HDR_MASK))
+            
+            
+//enum rfmode_t{RX, TX};
+
+class RF12B {
+public:
+    /* Constructor */
+    RF12B(PinName SDI,
+          PinName SDO,
+          PinName SCK,
+          PinName NCS,
+          PinName NIRQ);
+   
+     
+    /* Initialises the RF12B module */
+    void init(uint8_t id, uint8_t band, uint8_t g);
+        
+ 
+    /* Returns the packet length if data is available in the receive buffer, 0 otherwise*/
+   unsigned int available();
+   void rf12_sendStart (uint8_t hdr, const void* ptr, uint8_t len);
+   void rf12_sendStart2 (uint8_t hdr); 
+   uint8_t  rf12_recvDone (void);
+   void rf12_recvStart (void);
+   uint16_t check_crc(void);
+   uint8_t length(void);
+   uint8_t* get_data(void);
+   
+protected:
+
+    /* SPI module */
+    SPI spi;
+    
+    /* Other digital pins */
+    DigitalOut NCS;
+    InterruptIn NIRQ;
+    DigitalIn NIRQ_in;
+    DigitalOut rfled;
+    DigitalOut t1;
+    DigitalOut t2;
+    volatile uint16_t rf12_crc; // running crc value
+    volatile unsigned char rf12_buf[RF_MAX];  // recv/xmit buf, including hdr & crc bytes  
+    volatile  uint8_t nodeid;              // address of this node
+    volatile  uint8_t group;               // network grou
+    volatile uint8_t rxfill;     // number of data bytes in rf12_buf
+    volatile int8_t rxstate;     // current transceiver state
+ 
+
+    /* Write a command to the RF Module */
+    unsigned int writeCmd(unsigned int cmd);
+    
+    /* Sends a byte of data across RF */
+    void send(unsigned char data);
+    
+    /* Interrupt routine for data reception */
+    void rxISR();
+    
+
+    uint16_t _crc16_update(uint16_t crc, uint8_t data);
+    
+    uint16_t rf12_xfer (uint16_t cmd);    
+    uint8_t rf12_byte(uint8_t out);
+};
+
+#endif /* _RF12B_H */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Jan 02 20:03:01 2012 +0000
@@ -0,0 +1,69 @@
+/*
+mbed IoT Gateway demo
+
+This is a demo program to read data from a JeeNode and upload to Pachube.
+
+http://www.skpang.co.uk/catalog/mbed-iot-gateway-board-p-1051.html
+
+Jan 2012 skpang.co.uk
+*/
+#include "mbed.h"
+#include "RF12B.h"
+#include "PachubeV2CSV.h"
+#include "EthernetNetIf.h"
+#include "HTTPClient.h"
+ 
+#define API_KEY "PUT YOUR CODE KEY HERE"
+#define FEED_ID 40980
+#define STREAM_ID "1"
+
+PachubeV2CSV web(API_KEY);
+EthernetNetIf eth;
+
+DigitalOut myled(LED1);
+
+DigitalOut led(p25);
+RF12B radiolink(p11, p12, p13, p14, p18);
+
+Serial pc(USBTX, USBRX); // tx, rx
+
+int main() {
+   const int feed_id = FEED_ID;
+   const std::string stream_id = STREAM_ID;
+   float payload;
+ 
+   char val1_text[32];
+      
+    led = 1;
+    pc.baud(115200);
+    printf("RF12B test with Pachube\r\n");
+  
+    eth.setup();
+   
+    radiolink.init(2,2,1);   //id = 2, band 869, group 1
+
+    led = 0;
+    
+    while(1) {
+   
+                 
+    if (radiolink.rf12_recvDone() && (radiolink.check_crc() == 0)) // && rf12_crc == 0 && rf12_len == sizeof payload)
+    {
+     led = 1;
+        // Copy the received data into payload:
+        memcpy(&payload, (uint8_t*) radiolink.get_data(), sizeof(payload));
+
+        // Print it out:
+        printf("  payload: %f ", payload);
+        sprintf(val1_text, "%f", payload);
+     
+        printf("updateDataStream(%d)\n", web.updateDataStream(feed_id, stream_id, std::string(val1_text)));
+         
+        led = 0; 
+   }
+         myled = 1;
+      //  wait(0.1);
+        myled = 0;
+     
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Jan 02 20:03:01 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/7110ebee3484