We created an interactive tutorial for the OGC SensorThings API and you can find the link here – http://pg.sensorup.com.  If you haven’t tried it out, go check it out!  If you have tried it, we would love to learn your comments and feedbacks.  Please share with us so that we can make the tutorial better.

One of the very first feedback we received was “can you provide a tutorial of connecting an Arduino to OGC SensorThings API?“.  And yes, we hear you.  Here is a simple tutorial of connecting an Arduino Ethernet board to OGC SensorThings API.

First of all, please register an account in our playground and update the following variable values:

#define DATASTREAM_ID_TEMP 1186 &amp;lt;-- update to your datastream id in the playground.<br />

and

#define ACCESS_TOKEN "8a4bec01-fda3-462d-a9c0-a46e6d921807"  &amp;lt;-- update the value of ACCESS_TOKEN<br />

Below is the complete Arduino sketch. (Or you can fork the GIST here).  Just simply update the above two values, and you should be able to see new readings showing up in your SensorThings playground!!  Of course, if you want to upload readings to a different SensorThings API service, just simply change the server address and it should be plug-and-play!  That’s the benefit of interoperable standards!  Enjoy!

<br />
/*<br />
 * 2015 SensorUp (http://www.sensorup.com)<br />
 * This content is released under the (https://opensource.org/licenses/MIT) MIT License.<br />
 *<br />
 * Simple code to upload temperature readings to SensorUp SensorThings Playground (http://pg.sensorup.com)<br />
 * from the internal temperature sensor in an Arduino (http://playground.arduino.cc/Main/InternalTemperatureSensor).<br />
 *<br />
 * It works with Arduino Ethernet board. (https://www.arduino.cc/en/Main/ArduinoBoardEthernet)<br />
 */</p>
<p>#include &amp;lt;SPI.h&amp;gt;<br />
#include &amp;lt;HttpClient.h&amp;gt;<br />
#include &amp;lt;Ethernet.h&amp;gt;</p>
<p>/******************************************************************************************<br />
 * change the &amp;lt;id&amp;gt; from the line below (e.g., #define DATASTREAM_ID_TEMP &amp;lt;id&amp;gt;) to the<br />
 * &amp;lt;id&amp;gt; of your SensorThings Datastream. You can get the Datastream &amp;lt;id&amp;gt; from the SensorUp<br />
 * playground's Observation API Request: /st-playground/proxy/v1.0/Datastreams(&amp;lt;id&amp;gt;)/Observations<br />
 *****************************************************************************************/</p>
<p>#define DATASTREAM_ID_TEMP 1186</p>
<p>/******************************************************************************************<br />
 * change the &amp;lt;token&amp;gt; from the line below (e.g., #define ACCESS_TOKEN &amp;lt;token&amp;gt;) to the<br />
 * &amp;lt;token&amp;gt; of your SensorThings Datastream. You can get the St-P-Access-Token &amp;lt;token&amp;gt; from the SensorUp<br />
 * playground's Observation API Request: St-P-Access-Token: 8a4bec01-fda3-462d-a9c0-a46e6d921807<br />
 *****************************************************************************************/</p>
<p>#define ACCESS_TOKEN "8a4bec01-fda3-462d-a9c0-a46e6d921807"</p>
<p>#define SERVER_IP "pg-api.sensorup.com"<br />
#define PORT 80<br />
// Enter a MAC address for your controller below.<br />
// Newer Ethernet shields have a MAC address printed on a sticker on the shield<br />
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };<br />
// Set the static IP address to use if the DHCP fails to assign<br />
IPAddress ip(127, 0, 0, 1);<br />
// Initialize the Ethernet client library<br />
// with the IP address and port of the server<br />
// that you want to connect to (port 80 is default for HTTP):<br />
EthernetClient client;<br />
unsigned long datastream[] = {DATASTREAM_ID_TEMP};</p>
<p>double GetTemp(void)<br />
{<br />
 unsigned int wADC;<br />
 double t;</p>
<p> // The internal temperature has to be used<br />
 // with the internal reference of 1.1V.<br />
 // Channel 8 can not be selected with<br />
 // the analogRead function yet.</p>
<p> // Set the internal reference and mux.<br />
 ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));<br />
 ADCSRA |= _BV(ADEN); // enable the ADC</p>
<p> delay(20); // wait for voltages to become stable.</p>
<p> ADCSRA |= _BV(ADSC); // Start the ADC</p>
<p> // Detect end-of-conversion<br />
 while (bit_is_set(ADCSRA,ADSC));</p>
<p> // Reading register "ADCW" takes care of how to read ADCL and ADCH.<br />
 wADC = ADCW;</p>
<p> // The offset of 324.31 could be wrong. It is just an indication.<br />
 t = (wADC - 324.31 ) / 1.22;</p>
<p> // The returned temperature is in degrees Celcius.<br />
 return (t);<br />
}</p>
<p>void postToServer(double value,unsigned long datastreamId)<br />
{<br />
 Serial.println("connecting...");<br />
 String str = "{ ";<br />
 str += " \"result\":";<br />
 str += value;<br />
 str += "}";<br />
 Serial.println(str);</p>
<p> // if you get a connection, report back via serial:<br />
 if (client.connect(SERVER_IP, PORT)) {<br />
 Serial.println("connected");<br />
 // Make a HTTP request:<br />
 client.println("POST /st-playground/proxy/v1.0/Datastreams("+ String(datastreamId) +")/Observations HTTP/1.1");<br />
 String host = "Host: ";<br />
 host.concat(SERVER_IP);<br />
 client.println(host);<br />
 client.println("Connection: close");<br />
 client.println("Content-Type: application/json");<br />
 String token = "St-P-Access-Token:";<br />
 token += ACCESS_TOKEN;<br />
 client.println(token);<br />
 client.println("Cache-Control: no-cache");<br />
 client.print("Content-Length: ");<br />
 client.print(str.length());<br />
 client.print("\n\n");<br />
 client.print(str);<br />
 while(true)<br />
 {<br />
 // if there are incoming bytes available<br />
 // from the server, read them and print them:<br />
 if (client.available()) {<br />
 char c = client.read();<br />
 Serial.print(c);<br />
 }</p>
<p> // if the server's disconnected, stop the client:<br />
 if (!client.connected()) {<br />
 Serial.println();<br />
 Serial.println("disconnecting.");<br />
 client.stop();<br />
 break;<br />
 }<br />
 }</p>
<p> }<br />
 else {<br />
 // if you didn't get a connection to the server:<br />
 Serial.println("connection failed");<br />
 }</p>
<p>}</p>
<p>void setup() {<br />
 // Open serial communications and wait for port to open:<br />
 Serial.begin(9600);</p>
<p> // start the Ethernet connection:<br />
 if (Ethernet.begin(mac) == 0) {<br />
 Serial.println("Failed to configure Ethernet using DHCP");<br />
 // no point in carrying on, so do nothing forevermore:<br />
 // try to congifure using IP address instead of DHCP:<br />
 Ethernet.begin(mac, ip);<br />
 }<br />
 // give the Ethernet shield a second to initialize:<br />
 delay(1000);<br />
}</p>
<p>void loop()<br />
{<br />
 //The internal temperature is the temperature inside the chip<br />
 postToServer(GetTemp(),datastream[0]);<br />
 delay(2500);<br />
}<br />