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
main.cpp
- Committer:
- cabledev
- Date:
- 2014-05-19
- Revision:
- 2:1c34cfdbc18a
- Parent:
- 1:784afed9dbfe
File content as of revision 2:1c34cfdbc18a:
/** * 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. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * ----------------------------------------------------------------------------- * * 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 setLightProperties(float h, float s, float v, bool power) { printf("setLightProperties: HSV = '(%2f, %2f, %2f)', Power = '%s'\n\r", h, s, v, (power ? "ON" : "OFF")); if (powerOn) { hsv2rgb(h, s, v); } else { r = 1.0; g = 1.0; b = 1.0; } } 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); setLightProperties(lastH, lastS, lastV, powerOn); } } 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(ð); 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() { lcd.cls(); lcd.set_font((unsigned char*) Small_7); r.period(0.001); // set pwm period // LED lastH = 120; lastS = 1; lastV = 0.5f; setLightProperties(lastH, lastS, lastV, true); //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 } }