Simple code to upload temperature readings to SensorUp SensorThings Playground (http://pg.sensorup.com)from the LM75B temperature sensor in a mbed application board.It works with mbed LPC1768.

Dependencies:   C12832 EthernetNetIf LM75B mbed

Files at this revision

API Documentation at this revision

Comitter:
robinlk
Date:
Thu Dec 10 01:53:20 2015 +0000
Commit message:
Simple code to upload temperature readings to SensorUp SensorThings Playground (http://pg.sensorup.com)from the LM75B temperature sensor in an mbed application board.It works with mbed LPC1768.

Changed in this revision

C12832.lib Show annotated file Show diff for this revision Revisions of this file
EthernetNetIf.lib Show annotated file Show diff for this revision Revisions of this file
LM75B.lib Show annotated file Show diff for this revision Revisions of this file
TinyHTTP.cpp Show annotated file Show diff for this revision Revisions of this file
TinyHTTP.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/C12832.lib	Thu Dec 10 01:53:20 2015 +0000
@@ -0,0 +1,1 @@
+https://mbed.org/users/chris/code/C12832/#7de323fa46fe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EthernetNetIf.lib	Thu Dec 10 01:53:20 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/donatien/code/EthernetNetIf/#bc7df6da7589
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LM75B.lib	Thu Dec 10 01:53:20 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/neilt6/code/LM75B/#fc27dc535ea9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TinyHTTP.cpp	Thu Dec 10 01:53:20 2015 +0000
@@ -0,0 +1,240 @@
+/*
+ * mbed Tiny HTTP Client
+ * Copyright (c) 2011 Hiroshi Suga
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+
+/** @file
+ * @brief Tiny HTTP Client
+ */
+
+#include "mbed.h"
+#include "EthernetNetIf.h"
+#include "TCPSocket.h"
+#include "DNSRequest.h"
+#include "TinyHTTP.h"
+#include <ctype.h>
+
+
+TCPSocket *http;
+volatile int tcp_ready, tcp_readable, tcp_writable;
+volatile int dns_status;
+
+// Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
+int base64enc(const char *input, unsigned int length, char *output, int len) {
+  static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  unsigned int c, c1, c2, c3;
+
+  if (len < ((((length-1)/3)+1)<<2)) return -1;
+  for(unsigned int i = 0, j = 0; i<length; i+=3,j+=4) {
+    c1 = ((((unsigned char)*((unsigned char *)&input[i]))));
+    c2 = (length>i+1)?((((unsigned char)*((unsigned char *)&input[i+1])))):0;
+    c3 = (length>i+2)?((((unsigned char)*((unsigned char *)&input[i+2])))):0;
+
+    c = ((c1 & 0xFC) >> 2);
+    output[j+0] = base64[c];
+    c = ((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4);
+    output[j+1] = base64[c];
+    c = ((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6);
+    output[j+2] = (length>i+1)?base64[c]:'=';
+    c = (c3 & 0x3F);
+    output[j+3] = (length>i+2)?base64[c]:'=';
+  }
+  output[(((length-1)/3)+1)<<2] = '\0';
+  return 0;
+}
+
+// Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
+int urlencode(char *str, char *buf, int len) {
+  static const char to_hex[] = "0123456789ABCDEF";
+//  char *pstr = str, *buf = (char*)malloc(strlen(str) * 3 + 1), *pbuf = buf;
+  char *pstr = str, *pbuf = buf;
+
+  if (len < (strlen(str) * 3 + 1)) return -1;
+  while (*pstr) {
+    if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') {
+      *pbuf++ = *pstr;
+    } else if (*pstr == ' ') {
+      *pbuf++ = '+';
+    } else { 
+      *pbuf++ = '%';
+      *pbuf++ = to_hex[(*pstr >> 4) & 0x0f];
+      *pbuf++ = to_hex[*pstr & 0x0f];
+    }
+    pstr++;
+  }
+  *pbuf = '\0';
+  return 0;
+}
+
+
+void isr_http (TCPSocketEvent e) {
+
+#ifdef DEBUG
+    printf("tcp(%d)\r\n", e);
+#endif
+    switch(e) {
+    case TCPSOCKET_CONNECTED:
+        tcp_ready = 1;
+        break;
+
+    case TCPSOCKET_READABLE: //Incoming data
+        tcp_readable = 1;
+        break;
+
+    case TCPSOCKET_WRITEABLE: //We can send data
+        tcp_writable = 1;
+        break;
+
+    case TCPSOCKET_CONTIMEOUT:
+    case TCPSOCKET_CONRST:
+    case TCPSOCKET_CONABRT:
+    case TCPSOCKET_ERROR:
+    case TCPSOCKET_DISCONNECTED:
+        tcp_ready = 0;
+        break;
+    }
+}
+
+void createauth (char *user, char *pwd, char *buf, int len) {
+    char tmp[80];
+
+    strncpy(buf, "Authorization: Basic ", len);
+    snprintf(tmp, sizeof(tmp), "%s:%s", user, pwd);
+    base64enc(tmp, strlen(tmp), &buf[strlen(buf)], len - strlen(buf));
+    strncat(buf, "\r\n", len - strlen(buf));
+}
+
+void isr_dns (DNSReply r) {
+
+#ifdef DEBUG
+    printf("dns(%d)\r\n", r);
+#endif
+    if (DNS_FOUND) {
+        dns_status = 1;
+    } else {
+        dns_status = -1;
+    }
+}
+
+int httpRequest (int method, Host *host, char *uri, char *head, char *body) {
+    TCPSocketErr err;
+    Timer timeout;
+    char buf[1500];
+    int i, ret = -1;
+
+    http = new TCPSocket;
+    tcp_ready = 0;
+    tcp_readable = 0;
+    tcp_writable = 0;
+
+    http->setOnEvent(isr_http);
+
+    // connect
+    if (host->getIp().isNull()) {
+        // resolv
+        DNSRequest dns;
+        dns_status = 0;
+        dns.setOnReply(isr_dns);
+        if (dns.resolve(host) != DNS_OK) goto exit;
+        timeout.reset();
+        timeout.start();
+        while (timeout.read_ms() < HTTP_TIMEOUT) {
+            if (dns_status) break;
+            Net::poll();
+        }
+        timeout.stop();
+        if (dns_status <= 0) goto exit;
+#ifdef DEBUG
+        printf("%s [%d.%d.%d.%d]\r\n", host->getName(), (unsigned char)host->getIp()[0], (unsigned char)host->getIp()[1], (unsigned char)host->getIp()[2], (unsigned char)host->getIp()[3]);
+#endif
+    }
+    if (! host->getPort()) {
+        host->setPort(HTTP_PORT);
+    }
+    err = http->connect(*host);
+    if (err != TCPSOCKET_OK) goto exit;
+
+    // wait connect
+    timeout.reset();
+    timeout.start();
+    while (timeout.read_ms() < HTTP_TIMEOUT) {
+        if (tcp_ready) break;
+        Net::poll();
+    }
+    timeout.stop();
+    if (! tcp_ready) goto exit;
+
+    // send request
+    if (method == METHOD_POST) {
+        http->send("POST ", 5);
+    } else {
+        http->send("GET ", 4);
+    }
+    http->send(uri, strlen(uri));
+    http->send(" HTTP/1.1\r\nHost: ", 17);
+    http->send(host->getName(), strlen(host->getName()));
+    http->send("\r\n", 2);
+    http->send("Connection: close\r\n", 19);
+    if (head) {
+        http->send(head, strlen(head));
+    }
+    if (method == METHOD_POST) {
+        sprintf(buf, "Content-Length: %d\r\n", strlen(body));
+        http->send(buf, strlen(buf));
+    }
+    http->send("\r\n", 2);
+
+    // post method
+    if (method == METHOD_POST && body) {
+        http->send(body, strlen(body));
+    }
+
+    // wait responce
+    timeout.reset();
+    timeout.start();
+    while (timeout.read_ms() < HTTP_TIMEOUT) {
+        if (tcp_readable) break;
+        Net::poll();
+    }
+    timeout.stop();
+    if (! tcp_readable) goto exit;
+
+    // recv responce
+    i = http->recv(buf, sizeof(buf) - 1);
+    buf[i] = 0;
+    if (i < sizeof(buf) - 1) tcp_readable = 0;
+    if (strncmp(buf, "HTTP/", 5) == 0) {
+        ret = atoi(&buf[9]);
+    }
+#ifdef DEBUG
+    printf(buf);
+#endif
+
+    // recv dummy
+    timeout.reset();
+    timeout.start();
+    while (timeout.read_ms() < HTTP_TIMEOUT) {
+        if (tcp_readable) {
+            i = http->recv(buf, sizeof(buf) - 1);
+            buf[i] = 0;
+            if (i < sizeof(buf) - 1) tcp_readable = 0;
+#ifdef DEBUG
+            printf(buf);
+#endif
+            timeout.reset();
+        } else
+        if (! tcp_ready) {
+            break;
+        }
+        Net::poll();
+    }
+    timeout.stop();
+
+exit:
+    http->resetOnEvent();
+    http->close();
+    delete http;
+
+    return ret;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TinyHTTP.h	Thu Dec 10 01:53:20 2015 +0000
@@ -0,0 +1,38 @@
+/*
+ * mbed Tiny HTTP Client
+ * Copyright (c) 2011 Hiroshi Suga
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+
+/** @file
+ * @brief Tiny HTTP Client
+ */
+
+#ifndef TinyHTTP_h
+#define TinyHTTP_h
+
+#define DEBUG
+
+#define HTTP_PORT 80
+#define HTTP_TIMEOUT 15000 // ms
+
+#define METHOD_GET 0
+#define METHOD_POST 1
+
+/** send http request
+ * @param method METHOD_GET or METHOD_POST
+ * @param host http server
+ * @param uri URI
+ * @param head http header (CR+LF) (or NULL)
+ * @param body POST body (or NULL)
+ * @return http code, -1:failue
+ */
+int httpRequest (int method, Host *host, char *uri, char *head, char *body);
+
+void createauth (char *user, char *pwd, char *buf, int len);
+
+int base64enc(const char *input, unsigned int length, char *output, int len);
+
+int urlencode(char *str, char *buf, int len);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Dec 10 01:53:20 2015 +0000
@@ -0,0 +1,86 @@
+/*
+ * This content is released under the (https://opensource.org/licenses/MIT) MIT License.
+ *
+ * Simple code to upload temperature readings to SensorUp SensorThings Playground (http://pg.sensorup.com)
+ * from the LM75B temperature sensor(https://developer.mbed.org/cookbook/LM75B-Temperature-Sensor)   
+ * in an mbed application board(https://developer.mbed.org/cookbook/mbed-application-board)
+ * It works with mbed LPC1768. (https://developer.mbed.org/platforms/mbed-LPC1768/)
+ */
+#include "mbed.h"
+#include "EthernetNetIf.h"
+#include "TCPSocket.h"
+#include "TinyHTTP.h"
+#include "LM75B.h"
+#include "C12832.h"
+
+/*
+* Change the DATASTREAM_ID_TEMP to the id of you SensorThigns Datastream.
+* You can get the Datastream <id> from the SensorUp playground's Observation
+* API Request:/st-playground/proxy/v1.0/Datastreams(<id>)/Observations
+*/
+const int DATASTREAM_ID_TEMP = 116680;
+/*
+* Change the ACCESS_TOKEN to the token of you SensorThigns Datastream
+* You can get the ACCESS_TOKEN from the SensorUp playground's Observation 
+* API Request: St-P-Access-Token: 78cc7eb2-9394-4675-b231-ff0a377a3674
+*/
+const char *ACCESS_TOKEN = "78cc7eb2-9394-4675-b231-ff0a377a3674";
+/*
+* Interval(second) to post temperature
+*/
+const int INTERVAL  = 5;
+// Temperature sensor
+LM75B sensor(p28,p27);
+//Ethernet network interface
+EthernetNetIf eth;
+//LCD
+C12832 lcd(p5, p7, p6, p8, p11);
+
+int postToServer(float temp)
+{
+    Host host;
+	char msg[50],uri[100], head[160];
+	// header
+	snprintf(head, sizeof(head), "Content-type: application/json\r\nSt-P-Access-Token: %s\r\n", ACCESS_TOKEN);
+	// uri
+	snprintf(uri, sizeof(uri), "/st-playground/proxy/v1.0/Datastreams(%d)/Observations", DATASTREAM_ID_TEMP);
+	// msg
+	snprintf(msg, sizeof(msg), "{\"result\":%.3f\n}", temp);
+
+	host.setName("pg-api.sensorup.com");
+	host.setPort(HTTP_PORT);
+	return httpRequest(METHOD_POST, &host, uri, head, msg);
+}
+
+int main () {
+    EthernetErr ethErr;
+    Host host;
+    int r;
+	// Start the Ethernet connection
+    ethErr = eth.setup();
+    if(ethErr) {
+        printf("connect error\r\n");
+        return -1;
+    }
+	printf("start\r\n");
+
+ 	//Try to open the LM75B
+    if (sensor.open()) {
+        printf("Device detected!\n");
+
+        while (1) {
+            lcd.cls();
+            lcd.locate(0,3);
+            //Display the air temperature on LCD
+            //The returned temperature is in degrees Celcius.
+            lcd.printf("Temp = %.3f\n", (float)sensor);
+            // Post temperature to SensorUp SensorThings Playground
+            r = postToServer((float)sensor);
+            printf("status %d\r\n", r);
+            wait(INTERVAL);
+        }
+    } else {
+        error("Device not detected!\n");
+    }
+    return 0;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Dec 10 01:53:20 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912