Web enabled thermostat demo using the Mission Cognition baseboard.

Dependencies:   NetServices mbed AvailableMemory

Revision:
0:2e82bfc9dc19
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Oct 03 21:45:56 2011 +0000
@@ -0,0 +1,178 @@
+/*
+    Copyright (c) 2011 Jim Thomas, jt@missioncognition.net
+ 
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+ 
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+ 
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+*/
+
+#include "mbed.h"
+#include "SDHCFileSystem.h"
+#include "EthernetNetIf.h"
+#include "HTTPClient.h"
+#include "NTPClient.h"
+#include "HTTPServer.h"
+#include "RPCFunction.h"
+#include "RPCVariable.h"
+#include "AvailableMemory.h"
+
+
+#define HOSTNAME "mbedSE"
+#define PORT 80
+
+// Setup the SD card file system on the /sd path
+SDFileSystem sd(p5, p6, p7, p8, "sd");
+
+EthernetNetIf eth(HOSTNAME);
+HTTPClient http;
+NTPClient ntp;
+HTTPServer svr;
+
+// Setup an analog input
+AnalogIn rawtemp(p15, "temp"); // "AIN1"
+
+// Setup Relay outputs
+DigitalOut relay1(p26, "relay1"); // "PWM1"
+DigitalOut relay2(p25, "relay2"); // "PWM2"
+
+// Setup some variables for a thermostat (degress F)
+float stat_heat_setpoint = 68.0;
+float stat_hysteresis = 1.0;
+float stat_cool_setpoint = 74.0;
+float stat_current_temp = 0.0; // Will be updated from the temp sensor reading
+
+// Make the variables RPC accessible individually
+RPCVariable<float> rpc_stat_heat_setpoint(&stat_heat_setpoint, "stat_heat_setpoint");
+RPCVariable<float> rpc_stat_hysteresis(&stat_hysteresis, "stat_hysteresis");
+RPCVariable<float> rpc_stat_cool_setpoint(&stat_cool_setpoint, "stat_cool_setpoint");
+RPCVariable<float> rpc_stat_current_temp(&stat_current_temp, "stat_current_temp");
+
+// Make the whole state readable all at once as a JSON dict
+void DoGetThermostat(char * input, char* output);
+RPCFunction GetThermostat(&DoGetThermostat, "GetThermostat");
+
+void DoGetThermostat(char * input, char* output) {
+    // Input is ignored
+    printf("Thermostat: %0.1f %0.1f %0.1f %0.1f\n", stat_heat_setpoint, stat_hysteresis, stat_cool_setpoint, stat_current_temp);
+    printf("Relays: %d %d\n", relay1.read(), relay2.read());
+
+    sprintf(output, "{\"hs\":%0.1f,\"hy\":%0.1f,\"cs\":%0.1f,\"ct\":%0.1f,\"rh\":%d,\"rc\":%d}",
+            stat_heat_setpoint, stat_hysteresis, stat_cool_setpoint, stat_current_temp,
+            relay1.read(), relay2.read());
+}
+
+// Setup the status LED
+DigitalOut led1(LED1, "led1");
+
+int main() {
+    float aval;
+    float res;
+    int counter = 0;
+
+    EthernetErr ethErr;
+    int count = 0;
+    do {
+        printf("Setting up %d...\n", ++count);
+        ethErr = eth.setup();
+        if (ethErr) printf("Timeout\n", ethErr);
+    } while (ethErr != ETH_OK);
+
+    printf("Connected OK\n");
+    const char* hwAddr = eth.getHwAddr();
+    printf("HW address : %02x:%02x:%02x:%02x:%02x:%02x\n",
+           hwAddr[0], hwAddr[1], hwAddr[2],
+           hwAddr[3], hwAddr[4], hwAddr[5]);
+
+    IpAddr ethIp = eth.getIp();
+    printf("IP address : %d.%d.%d.%d\n", ethIp[0], ethIp[1], ethIp[2], ethIp[3]);
+    printf("Check router DHCP table for name : %s\n", eth.getHostname());
+
+    time_t ctTime;
+    ctTime = time(NULL);
+    printf("\nCurrent time is (UTC): %d %s\n", ctTime, ctime(&ctTime));
+    printf("NTP setTime...\n");
+    Host server(IpAddr(), 123, "pool.ntp.org");
+    printf("Result : %d\n", ntp.setTime(server));
+
+    ctTime = time(NULL);
+    printf("\nTime is now (UTC): %d %s\n", ctTime, ctime(&ctTime));
+
+    char ip[16];
+    sprintf(ip, "%d.%d.%d.%d", ethIp[0], ethIp[1], ethIp[2], ethIp[3]);
+
+    FSHandler::mount("/sd/www", "/"); //Mount uSD www path on web root path
+
+    svr.addHandler<RPCHandler>("/rpc");  // Enable RPC functionality under the /rpc path
+    svr.addHandler<FSHandler>("/"); // Add the file handler at the root
+
+    svr.bind(PORT);
+    printf("Server listening (port %d)\n", PORT);
+    printf("- LED1 flashes server heartbeat\n");
+    printf("- URL for RPC commands: %s/rpc \n", ip);
+
+    Timer tm;
+    tm.start();
+
+    while (true) {
+        Net::poll();
+        if (tm.read() > 0.5) {
+            tm.start();
+
+            if (counter % 128 == 0) printf("Available memory (exact bytes) : %d\n", AvailableMemory(1));
+
+            // Keep a loop counter
+            counter++;
+
+            // Toggle the LED
+            led1 = !led1;
+
+            // Read our rawtemp sensor and convert to degrees F
+            // ref http://www.seeedstudio.com/wiki/index.php?title=Project_Seven_-_rawtemp
+            // ref http://www.seeedstudio.com/wiki/index.php?title=GROVE_-_Starter_Bundle_V1.0b#rawtemp_Sensor_Twig
+            aval = rawtemp.read();
+            res = (10000.0 / aval) - 10000.0; // Reference resistor is 10k ohm
+            stat_current_temp = (1.0 / ((log(res / 10000.0) / 3975.0) + 1 / 298.15) - 273.15) * 9.0 / 5.0 + 32.0;
+
+            // Make sure that the setpoints don't cross
+            if (stat_cool_setpoint < stat_heat_setpoint + 2 * stat_hysteresis)
+                stat_cool_setpoint = stat_heat_setpoint + 2 * stat_hysteresis;
+
+            // Update relays once every 8 loops (~ 4 seconds)
+            // ref http://www.seeedstudio.com/wiki/index.php?title=Project_Five_%E2%80%93_Relay_Control
+            if (counter % 8 == 0) {
+                printf("Thermostat: %0.1f %0.1f %0.1f %0.1f\n", stat_heat_setpoint, stat_hysteresis, stat_cool_setpoint, stat_current_temp);
+
+                if ((stat_current_temp < stat_heat_setpoint - stat_hysteresis) && !relay1) {
+                    relay1 = 1;
+                    printf("Turning Relay 1 On\n");
+                }
+                if ((stat_current_temp > stat_heat_setpoint + stat_hysteresis) && relay1) {
+                    relay1 = 0;
+                    printf("Turning Relay 1 Off\n");
+                }
+                if ((stat_current_temp < stat_cool_setpoint - stat_hysteresis) && relay2) {
+                    relay2 = 0;
+                    printf("Turning Relay 2 Off\n");
+                }
+                if ((stat_current_temp > stat_cool_setpoint + stat_hysteresis) && !relay2) {
+                    relay2 = 1;
+                    printf("Turning Relay 2 On\n");
+                }
+            }
+        }
+    }
+}
\ No newline at end of file