![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
An alarm clock that wakes you up naturally!
Dependencies: 4DGL-uLCD-SE DebounceIn mbed RPCInterface
Revision 1:57e06832197a, committed 2017-05-03
- Comitter:
- ooglezoiden
- Date:
- Wed May 03 15:05:12 2017 +0000
- Parent:
- 0:397faf7a0a52
- Commit message:
- added Alexa support
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RPCInterface.lib Wed May 03 15:05:12 2017 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/MichaelW/code/RPCInterface/#bcc2e05e5da4
--- a/main.cpp Thu Mar 16 19:38:55 2017 +0000 +++ b/main.cpp Wed May 03 15:05:12 2017 +0000 @@ -1,32 +1,104 @@ #include "mbed.h" #include "uLCD_4DGL.h" #include "DebounceIn.h" +#include "mywifi.h" +#include "mbed_rpc.h" Timeout alarm; Timer t; -PwmOut lights(p25); +PwmOut lights(p24); uLCD_4DGL uLCD(p9,p10,p11); AnalogIn photocell(p15); DebounceIn pb1(p8); DebounceIn pb2(p7); -Serial blue(p28,p27); +DebounceIn pb3(p6); +Serial blue(p13,p14); + +Serial pc(USBTX, USBRX); +Serial esp(p28, p27); +char ssid[32] = "Hotspot"; +char pwd[32] = "1234567890"; +char port[32] = "1035"; // must be port forwarded +char timeout[32] = "28800"; // 28800 is max +volatile int tx_in=0; +volatile int tx_out=0; +volatile int rx_in=0; +volatile int rx_out=0; +const int buffer_size = 4095; +char tx_buffer[buffer_size+1]; +char rx_buffer[buffer_size+1]; +char cmdbuff[1024]; +char rx_line[1024]; +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); -void lightsOn(){ +// ---------------- Light Functions For Alexa ------------------ + + + +void alexaLightsOn(Arguments *in, Reply *out){ uLCD.cls(); uLCD.printf("Turning on lights!"); //lights = 1; while(lights<=0.99f){ lights = lights + .01f; - wait(1); + wait_ms(100); + } + while(1);//do nothing until reset +} + +void alexaLightsOff(Arguments *in, Reply *out){ + uLCD.cls(); + uLCD.printf("Turning off lights!"); + //lights = 1; + while(lights>=0.01f){ + lights = lights - .01f; + wait_ms(100); } while(1);//do nothing until reset } +void alexaDimLights(Arguments *in, Reply *out){ + float level = in->getArg<float>(); + uLCD.cls(); + uLCD.printf("Dimming lights to %f percent.", level); + lights = level; +} + +void lightsOn(){ + uLCD.cls(); + uLCD.printf("Turning on lights!"); + lights = 1.0; + //while(lights<=0.99f){ + // lights = lights + 0.1f; + // wait(1); + //} + while(1);//do nothing until reset +} + +void alexaTimer(Arguments *in, Reply *out){ + int time = in->getArg<int>(); + alarm.attach(&lightsOn, time); + t.start(); + float curTime; + while(1){ + uLCD.cls(); + curTime = t.read(); + uLCD.printf("%f secs since alarm set.\n", curTime); + } +} + +// --------------------- Modes ------------------------ + + + void lightMode(){ uLCD.cls(); uLCD.printf("not bright out yet!\n"); - while(photocell.read() < .9f){ + while(photocell.read() < .8f){ uLCD.cls(); uLCD.printf("not bright out yet!\n"); } @@ -108,15 +180,89 @@ } +void alexaMode(){ + uLCD.cls(); + uLCD.printf("Alexa mode started!\n"); + pc.baud(9600); + esp.baud(9600); + esp.attach(&Rx_interrupt, Serial::RxIrq); + esp.attach(&Tx_interrupt, Serial::TxIrq); + wait(5); + connectToNetwork(); + uLCD.printf("Connected to network!!\n"); + wait(0.2); + char rpc_in[256]; + char rpc_out[256]; + while (1) { + getReply(); + memset(&rpc_in[0], 0, sizeof(rpc_in)); + memset(&rpc_out[0], 0, sizeof(rpc_out)); + int length = (int)rx_line[3] - 48; // bytes 0 to 2 are trash; byte 3 is length of message + if (length > 0 && length < 256) { + for (int i = 0; i < length; i++) { + rpc_in[i] = rx_line[i+4]; // bytes 4 to length+3 are the valid data + } + RPC::call(rpc_in, rpc_out); + pc.printf("%s\n", rpc_out); + } + // lambda function is event-triggered and non-persistent + // after it terminates, we need to close the existing connection and start another one + strcpy(cmdbuff, "srv:close()\r\n"); + sendCMD(); + wait(.5); + getReply(); + strcpy(cmdbuff, "srv=net.createServer(net.TCP,"); + strcat(cmdbuff, timeout); + strcat(cmdbuff, ")\r\n"); + sendCMD(); + wait(.5); + getReply(); + strcpy(cmdbuff, "srv:listen("); + strcat(cmdbuff, port); + strcat(cmdbuff, ",function(conn)\r\n"); + sendCMD(); + wait(.5); + getReply(); + strcpy(cmdbuff, "conn:on(\"receive\", function(conn, payload) \r\n"); + sendCMD(); + wait(.5); + getReply(); + strcpy(cmdbuff, "print(payload)\r\n"); + sendCMD(); + wait(.5); + getReply(); + strcpy(cmdbuff, "end)\r\n"); + sendCMD(); + wait(.5); + getReply(); + strcpy(cmdbuff, "end)\r\n"); + sendCMD(); + wait(.5); + getReply(); + } +} + + + +// --------------- Main Function ---------------------- + + + int main() { lights = 0; - uLCD.printf("LIGHT_ALARM V1.0 Donn Green\n\n"); + uLCD.printf("LIGHT_ALARM V2.0 Donn Green\n\n"); uLCD.printf("Press Button 1 to begin light activation mode\n"); uLCD.printf("Press Button 2 to begin timer activation mode\n"); + uLCD.printf("Press Button 3 to begin smart home mode\n"); pb1.mode(PullDown); pb2.mode(PullDown); + pb3.mode(PullDown); lights.period(1.0f/25000.0f); - while(!(pb1||pb2)){ + RPCFunction rpcOn(&alexaLightsOn, "turnOn"); + RPCFunction rpcOff(&alexaLightsOff, "turnOff"); + RPCFunction rpcDim(&alexaDimLights, "dim"); + RPCFunction rpcSet(&alexaTimer, "set"); + while(!(pb1||pb2||pb3)){ //do nothing until a button is pressed } if(pb1){ @@ -126,4 +272,242 @@ int time = getTime(); timerMode(time); } + else if(pb3){ + alexaMode(); + } } + + + +// ------------ WIFI Functions --------------------- + + + +void connectToNetwork() { + pc.printf("# Resetting ESP\r\n"); + uLCD.cls(); + uLCD.printf("# Resetting ESP\r\n"); + strcpy(cmdbuff,"node.restart()\r\n"); + sendCMD(); + wait(5); + getReply(); + + led1=1,led2=0,led3=0; + pc.printf("# Setting Mode\r\n"); + uLCD.cls(); + uLCD.printf("# Setting Mode\r\n"); + strcpy(cmdbuff, "wifi.setmode(wifi.STATION)\r\n"); + sendCMD(); + getReply(); + + wait(2); + led1=0,led2=1,led3=0; + pc.printf("# Connecting to AP\r\n"); + pc.printf("# ssid = %s\t\tpwd = %s\r\n", ssid, pwd); + uLCD.cls(); + uLCD.printf("# ssid = %s\t\tpwd = %s\r\n"); + strcpy(cmdbuff, "wifi.sta.config(\""); + strcat(cmdbuff, ssid); + strcat(cmdbuff, "\",\""); + strcat(cmdbuff, pwd); + strcat(cmdbuff, "\")\r\n"); + sendCMD(); + getReply(); + + wait(2); + led1=0,led2=0,led3=1; + pc.printf("# Get IP Address\r\n"); + uLCD.cls(); + uLCD.printf("# Get IP Address\r\n"); + strcpy(cmdbuff, "print(wifi.sta.getip())\r\n"); + sendCMD(); + getReply(); + + wait(2); + led1=1,led2=0,led3=0; + pc.printf("# Get Connection Status\r\n"); + uLCD.cls(); + uLCD.printf("# Get Connection Status\r\n"); + strcpy(cmdbuff, "print(wifi.sta.status())\r\n"); + sendCMD(); + getReply(); + + wait(2); + led1=0,led2=1,led3=0; + pc.printf("# Listen on Port\r\n"); + uLCD.cls(); + uLCD.printf("# Listen on Port\r\n"); + strcpy(cmdbuff, "srv=net.createServer(net.TCP,"); + strcat(cmdbuff, timeout); + strcat(cmdbuff, ")\r\n"); + sendCMD(); + getReply(); + + wait(2); + led1=0,led2=0,led3=1; + strcpy(cmdbuff, "srv:listen("); + strcat(cmdbuff, port); + strcat(cmdbuff, ",function(conn)\r\n"); + sendCMD(); + getReply(); + + wait(2); + led1=1,led2=0,led3=0; + strcpy(cmdbuff, "conn:on(\"receive\", function(conn, payload) \r\n"); + sendCMD(); + getReply(); + + wait(2); + led1=0,led2=1,led3=0; + //strcpy(cmdbuff, "conn:send('"); + //strcat(cmdbuff, reportStatus()); + //strcat(cmdbuff, "')\r\n"); + //sendCMD(); + //getReply(); + + wait(2); + led1=0,led2=0,led3=1; + strcpy(cmdbuff, "print(payload)\r\n"); + sendCMD(); + getReply(); + + wait(2); + led1=1,led2=0,led3=0; + strcpy(cmdbuff, "end)\r\n"); + sendCMD(); + getReply(); + + wait(2); + led1=0,led2=1,led3=0; + strcpy(cmdbuff, "end)\r\n"); + sendCMD(); + getReply(); + + strcpy(cmdbuff, "tmr.alarm(0, 1000, 1, function()\r\n"); + sendCMD(); + getReply(); + wait(0.2); + strcpy(cmdbuff, "if wifi.sta.getip() == nil then\r\n"); + sendCMD(); + getReply(); + wait(0.2); + strcpy(cmdbuff, "print(\"Connecting to AP...\\n\")\r\n"); + sendCMD(); + getReply(); + wait(0.2); + strcpy(cmdbuff, "else\r\n"); + sendCMD(); + getReply(); + wait(0.2); + strcpy(cmdbuff, "ip, nm, gw=wifi.sta.getip()\r\n"); + sendCMD(); + getReply(); + wait(0.2); + strcpy(cmdbuff,"print(\"IP Address: \",ip)\r\n"); + sendCMD(); + getReply(); + wait(0.2); + strcpy(cmdbuff,"tmr.stop(0)\r\n"); + sendCMD(); + getReply(); + wait(0.2); + strcpy(cmdbuff,"end\r\n"); + sendCMD(); + getReply(); + wait(0.2); + strcpy(cmdbuff,"end)\r\n"); + sendCMD(); + getReply(); + wait(0.2); + + pc.printf("\n\n++++++++++ Ready ++++++++++\r\n\n"); +} + +void sendCMD() +{ + int i; + char temp_char; + bool empty; + i = 0; +// Start Critical Section - don't interrupt while changing global buffer variables + NVIC_DisableIRQ(UART1_IRQn); + empty = (tx_in == tx_out); + while ((i==0) || (cmdbuff[i-1] != '\n')) { +// Wait if buffer full + if (((tx_in + 1) % buffer_size) == tx_out) { +// End Critical Section - need to let interrupt routine empty buffer by sending + NVIC_EnableIRQ(UART1_IRQn); + while (((tx_in + 1) % buffer_size) == tx_out) { + } +// Start Critical Section - don't interrupt while changing global buffer variables + NVIC_DisableIRQ(UART1_IRQn); + } + tx_buffer[tx_in] = cmdbuff[i]; + i++; + tx_in = (tx_in + 1) % buffer_size; + } + if (esp.writeable() && (empty)) { + temp_char = tx_buffer[tx_out]; + tx_out = (tx_out + 1) % buffer_size; +// Send first character to start tx interrupts, if stopped + esp.putc(temp_char); + } +// End Critical Section + NVIC_EnableIRQ(UART1_IRQn); + return; +} + +// Read a line from the large rx buffer from rx interrupt routine +void getReply() { + int i; + i = 0; +// Start Critical Section - don't interrupt while changing global buffer variables + NVIC_DisableIRQ(UART1_IRQn); +// Loop reading rx buffer characters until end of line character + while ((i==0) || (rx_line[i-1] != '\r')) { +// Wait if buffer empty + if (rx_in == rx_out) { +// End Critical Section - need to allow rx interrupt to get new characters for buffer + NVIC_EnableIRQ(UART1_IRQn); + while (rx_in == rx_out) { + } +// Start Critical Section - don't interrupt while changing global buffer variables + NVIC_DisableIRQ(UART1_IRQn); + } + rx_line[i] = rx_buffer[rx_out]; + i++; + rx_out = (rx_out + 1) % buffer_size; + } +// End Critical Section + NVIC_EnableIRQ(UART1_IRQn); + rx_line[i-1] = 0; + return; +} + +// Interupt Routine to read in data from serial port +void Rx_interrupt() { + //led3=1; +// Loop just in case more than one character is in UART's receive FIFO buffer +// Stop if buffer full + while ((esp.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) { + rx_buffer[rx_in] = esp.getc(); +// Uncomment to Echo to USB serial to watch data flow + pc.putc(rx_buffer[rx_in]); + rx_in = (rx_in + 1) % buffer_size; + } + return; +} + + +// Interupt Routine to write out data to serial port +void Tx_interrupt() { + //led2=1; +// Loop to fill more than one character in UART's transmit FIFO buffer +// Stop if buffer empty + while ((esp.writeable()) && (tx_in != tx_out)) { + esp.putc(tx_buffer[tx_out]); + tx_out = (tx_out + 1) % buffer_size; + } + //led2=0; + return; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mywifi.h Wed May 03 15:05:12 2017 +0000 @@ -0,0 +1,5 @@ +void Tx_interrupt(); +void Rx_interrupt(); +void sendCMD(); +void getReply(); +void connectToNetwork(); \ No newline at end of file