This application shows an example of how to control the RGB LED over RPC. The app also contains an HTTP server and uses other components such as the LCD and Temperature Sensor to display additional information.

Dependencies:   C12832_lcd EthernetInterface HTTPServer LM75B MutexLocker mbed-rpc mbed-rtos mbed

Revision:
0:452a42421de4
Child:
1:784afed9dbfe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu May 15 16:13:13 2014 +0000
@@ -0,0 +1,377 @@
+/**
+ * Notice:
+ * 
+ * Neither CableLabs nor any member company is responsible to any party for any liability of any nature whatsoever
+ * resulting from or arising out of use or reliance upon this software. This software is furnished on an "AS IS" basis
+ * and neither CableLabs nor its members provides any representation or warranty, express or implied, regarding the
+ * accuracy, completeness, or fitness for a particular purpose of this software.
+ * 
+ * (C)Copyright 2014 Cable Television Laboratories, Inc. All rights reserved.
+ * -----------------------------------------------------------------------------
+ * 
+ * File: main.cpp
+ * 
+ */
+
+#include "mbed.h"
+
+// LCD
+#include "C12832_lcd.h"
+#include "Small_7.h"
+
+// HTTPServer
+#include "HTTPServer.h"
+#include "FsHandler.h"
+#include "LocalFileSystem.h"
+#include "RpcHandler.h"
+#include "mbed_rpc.h"
+
+// Temperature sensor
+#include "mutexlocker.h"
+#include "LM75B.h"
+
+#define ON 1
+#define OFF 0
+#define DIM 0.3
+#define SERIAL_BAUD 115200 // 9600
+#define HTTP_LISTEN_PORT 80
+
+// blinks LED1 when the HTTP server is listening for connections
+//#define LISTENING_LED
+
+// for some reason, getting the return code causes the HTTP server to be unresponsive
+#define ETH_CONNECTION_STATUS
+
+// uncomment the following line for static IP address
+//#define STATIC_IP
+#define STATIC_IP_ADDRESS "192.168.1.177"
+#define STATIC_IP_NETMASK "255.255.255.0"
+#define STATIC_IP_GATEWAY "192.168.1.1"
+
+#define TEMPERATURE_ACTIVE
+
+// LCD
+// LCD object
+C12832_LCD lcd;
+
+// the led's are connected to vcc, so a PwmOut of 100% will shut off the led and 0% will let it shine!
+PwmOut r(p23);
+PwmOut g(p24);
+PwmOut b(p25);
+RpcPwmOut rpc_r(p23,"r");
+RpcPwmOut rpc_g(p24,"g");
+RpcPwmOut rpc_b(p25,"b");
+// used to restore the rgb value after turning LED off and back on 
+bool powerOn = true;
+float lastH = 0.0;
+float lastS = 0.0;
+float lastV = -1.0;
+
+AnalogIn Pot1(p19);
+AnalogIn Pot2(p20);
+
+// Ethernet
+EthernetInterface eth;
+bool ethConnected;
+
+// HTTPServer
+#ifdef LISTENING_LED
+// Use LED1 to indicate that the main loop is still executing
+DigitalOut listeningLed(LED1);
+#endif
+// Use the serial connection 'pc' to dump debug information
+Serial pc(USBTX, USBRX, "pc");
+// Instantiate a HTTPServer to handle incoming requests
+HTTPServer  svr;
+// Instantiate a local file system handler named 'local' which will be used later to access files on the mbed.
+LocalFileSystem local("local");
+
+// Temperature sensor
+Mutex mutex;
+LM75B temperatureSensor(p28,p27);
+
+// RPC Variables
+/*
+//First create the variables you wish to use
+float f;
+int i;
+char c;
+//Then attach them to an RPCVariable Object
+RPCVariable<float> rpc_f(&f, "f");
+RPCVariable<int> rpc_i(&i, "i");
+RPCVariable<char> rpc_c(&c, "c");
+*/
+
+// RPC Functions
+void setLight(Arguments* input, Reply* output);
+
+// invoke with "http://<eth_ip>/RPC/setLightColor/run <H> <S> <V> <brightness> <powerOn>",
+//  where 0 <= H <= 360, 0 <= S <= 1, 0 <= V <= 1
+RPCFunction rpc_setLight(&setLight, "setLight");
+
+// function to convert hue , saturation and  value to RGB
+// see http://en.wikipedia.org/wiki/HSL_and_HSV
+void hsv2rgb(float H,float S, float V)
+{
+    float f,h,p,q,t;
+    int i;
+    if( S == 0.0) {
+        r = 1.0 - V;  // invert pwm !
+        g = 1.0 - V;
+        b = 1.0 - V;
+        return;
+    }
+    if(H > 360.0) H = 0.0;   // check values
+    if(S > 1.0) S = 1.0; 
+    if(S < 0.0) S = 0.0;
+    if(V > 1.0) V = 1.0;
+    if(V < 0.0) V = 0.0;
+    h = H / 60.0;
+    i = (int) h;
+    f = h - i;
+    p = V * (1.0 - S);
+    q = V * (1.0 - (S * f));
+    t = V * (1.0 - (S * (1.0 - f)));
+
+    switch(i) {
+        case 0:
+            r = 1.0 - V;  // invert pwm !
+            g = 1.0 - t;
+            b = 1.0 - p;
+            break;
+        case 1:
+            r = 1.0 - q;
+            g = 1.0 - V;
+            b = 1.0 - p;
+            break;
+        case 2:
+            r = 1.0 - p;
+            g = 1.0 - V;
+            b = 1.0 - t;
+            break;
+        case 3:
+            r = 1.0 - p;
+            g = 1.0 - q;
+            b = 1.0 - V;
+            break;
+        case 4:
+            r = 1.0 - t;
+            g = 1.0 - p;
+            b = 1.0 - V;
+            break;
+        case 5:
+        default:
+            r = 1.0 - V;
+            g = 1.0 - p;
+            b = 1.0 - q;
+            break;
+    }
+}
+
+void setLight(Arguments* input, Reply* output)
+{
+    // Arguments are already parsed into argv array of char*
+    printf("Object name = %s\n\r",input->obj_name);
+    printf("Method name = %s\n\r",input->method_name);
+    for (int i=0; i < input->argc; i++)
+    {
+        printf("argv[%1d] = %s \n\r",i,input->argv[i]);
+    }
+    
+    if (input->argc > 4)
+    {
+        char* strH = input->argv[0];
+        char* strS = input->argv[1];
+        char* strV = input->argv[2];
+        char* strBrightness = input->argv[3];
+        char* strPower = input->argv[4];
+        
+        float h;
+        float s;
+        float v;
+        float brightness;
+        int power;
+        
+        if ((strH != NULL) && (strlen(strH) > 0) && (strcmp(strH, "null") != 0))
+        {
+            // assume that if we got an H, we also got an S & V
+            sscanf(strH, "%f", &h);
+            sscanf(strS, "%f", &s);
+            sscanf(strV, "%f", &v);
+            
+            lastH = h;
+            lastS = s;
+            lastV = v;
+printf("*** set lastV from color to %f\n\r", lastV);
+        }
+        
+        if ((strBrightness != NULL) && (strlen(strBrightness) > 0) && (strcmp(strBrightness, "null") != 0))
+        {
+            sscanf(strBrightness, "%f", &brightness);
+            brightness = brightness / 100.0;
+            brightness = brightness*brightness; // normalization, because in general, the LED is too bright
+            lastV = brightness;
+printf("*** set lastV from brightness to %f\n\r", lastV);
+        }
+        
+        if ((strPower != NULL) && (strlen(strPower) > 0) && (strcmp(strPower, "null") != 0))
+        {
+            sscanf(strPower, "%i", &power);
+            
+            powerOn = (power == ON);
+        }
+        
+        printf("setLight: HSV = '(%s, %s, %s)', Brightness = '%s', Power = '%s'\n\r", strH, strS, strV, strBrightness, strPower);
+        
+        // recall that the power is inverted, so (0.0 == on) and (1.0 == off)
+        if (powerOn)
+        {
+            hsv2rgb(lastH, lastS, lastV);
+        }
+        else
+        {
+            r = 1.0;
+            g = 1.0;
+            b = 1.0;
+        }
+    }
+}
+
+void startHttpServer(void const* arg)
+{
+    // Ethernet
+#ifdef STATIC_IP
+    pc.printf("Configuring Ethernet with Static IP Address.\n\r");
+    //eth.init("192.168.1.177", "255.255.255.0", "192.168.1.1");
+    eth.init(STATIC_IP_ADDRESS, STATIC_IP_NETMASK, STATIC_IP_GATEWAY);
+#else
+    pc.printf("Configuring Ethernet with DHCP IP Address.\n\r");
+    eth.init(); //Use DHCP
+#endif
+    
+#ifdef ETH_CONNECTION_STATUS
+//pc.printf("*** eth.connect()!\n\r");
+    int connected = eth.connect(); // success == 0
+//pc.printf("*** Eth.connect returned %i\n\r", connected);
+    if (connected != 0)
+    {
+        lcd.printf("Ethernet not connected");
+    }
+    else
+    {
+#else
+//pc.printf("*** eth.connect()!\n\r");
+    eth.connect();
+#endif
+        char* ipAddr = eth.getIPAddress();
+//pc.printf("*** ipAddr: %s\n\r", ipAddr);
+        ethConnected = ((ipAddr != NULL) && (strlen(ipAddr) > 0));
+
+        if (ethConnected)
+        {
+            mutex.lock();
+            lcd.locate(10,0);
+            lcd.printf("IP Address: %s", eth.getIPAddress());
+            mutex.unlock();
+            
+#ifndef TEMPERATURE_ACTIVE
+            mutex.lock();
+            lcd.locate(10,10);
+            lcd.printf("WebServer started");
+            mutex.unlock();
+#endif
+        }
+        else
+        {
+            lcd.printf("No IP Address");
+        }
+#ifdef ETH_CONNECTION_STATUS
+    }
+#endif
+    
+    svr.addHandler<HTTPFsRequestHandler>("/");
+    svr.addHandler<HTTPRpcRequestHandler>("/RPC");
+    
+    svr.setPort(HTTP_LISTEN_PORT);
+    svr.setEthernetInterface(&eth);
+    svr.start();
+}
+
+void startTemperatureMonitor(void const* arg)
+{
+    float tempC = 0;
+    float tempF = 0;
+    while(true)
+    {
+        tempC = temperatureSensor.read();
+        tempF = (tempC * 1.8f) + 32.0f;
+        
+        mutex.lock();
+        lcd.locate(10,10);        
+        lcd.printf("Temp: %.3f F\n", tempF);
+        mutex.unlock();
+        wait(1.0);
+    }
+}
+
+int main()
+{
+    // LED
+    float h; //  hue 
+    float s,v; // saturation and  value;
+    unsigned short temp;
+    
+    lcd.cls();
+    lcd.set_font((unsigned char*) Small_7);
+    
+    r.period(0.001); // set pwm period
+    s = 1.0;
+    
+    // initialize the LED from the Pots
+    // get Poti 1 for color
+    temp = Pot1.read_u16();
+    temp = temp >> 6;        // truncate to 10 Bit
+    h = temp * 0.3515625;  // scale to 0 - 360;
+    //lcd.locate(0,13);
+    //lcd.printf("Colour = %3.2f degree",h);
+    // get Poti 2 fo value
+    temp = Pot2.read_u16();
+    temp = temp >> 6;
+    v = temp * 0.0009765624;  // scale to 0 - 1;
+    //lcd.locate(0,23);
+    //lcd.printf("Val = %01.3f ",v);
+    hsv2rgb(h,s,v);
+    
+    lastH = h;
+    lastS = s;
+    lastV = v;
+    
+    //HTTPServer
+    pc.baud(SERIAL_BAUD);
+    
+    // add the interfaces that can be created dynamically
+    RPC::add_rpc_class<RpcDigitalOut>();
+    RPC::add_rpc_class<RpcPwmOut>();
+    
+    HTTPFsRequestHandler::mount("/local/", "/");
+    
+    ethConnected = false;
+    Thread httpsvr( &startHttpServer );
+    
+#ifdef TEMPERATURE_ACTIVE
+    Thread tempMonitor(&startTemperatureMonitor );
+#endif
+    
+    while (true)
+    {
+#ifdef LISTENING_LED
+        if (ethConnected)
+        {
+            listeningLed = ON;
+            wait(0.2);
+            listeningLed = OFF;
+            wait(0.2);
+        }
+#endif
+    }
+}