A program using ESP8266 Huzzah to receive message from Amazon AWS service and control a servo to flip on/off the mechanical light switch.

Dependencies:   RPCInterface Servo mbed

Fork of dotbot by Graham Miles

main.cpp

Committer:
AlanPig
Date:
2017-12-14
Revision:
3:99303dc07632
Parent:
2:747b84e54088

File content as of revision 3:99303dc07632:

#include "mbed.h"
#include "Light.h"
#include "mywifi.h"
#include "Servo.h"
#include "mbed_rpc.h"

Serial esp(p28, p27);
Servo myservo(p22);
char ssid[32] = "GTother";
char pwd[32] = "GeorgeP@1927";
char port[32] = "80"; // 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);

float range = 0.0005;
float position = 0.5;
RPCFunction rpcLightOn(&lightOn, "on");
RPCFunction rpcLightOff(&lightOff, "off");

int main() {
    esp.baud(9600);
    led1=0,led2=0,led3=0,led4=0;
    esp.attach(&Rx_interrupt, Serial::RxIrq);
    esp.attach(&Tx_interrupt, Serial::TxIrq);
    wait(2);
    connectToNetwork();
    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
    //    pc.printf(" the length is %d, and rpc_in is %s\n",length,rpc_in);
        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("rpc _out is %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, "conn:send('");
        strcat(cmdbuff, "')\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();
        led4 = 1;
        wait(.5);
        led4 = 0;
        getReply();
    }
}


void lightOff(Arguments *in, Reply *out) {
    led4=1;
    position = 0.11;
    myservo = position;
    wait(1);
    position = 0.5;
    myservo = position;
    led4=0;
}

void lightOn(Arguments *in, Reply *out) {
    led1=1;
    position = 0.8;
    myservo = position;
    wait(1);
    position = 0.5;
    myservo = position;
    led1=0;
}

/* WIFI FUNCTIONS */

void connectToNetwork() {
 //   pc.printf("# Resetting ESP\r\n");
    strcpy(cmdbuff,"node.restart()\r\n");
    sendCMD();
    wait(1);
    getReply();

    led1=1,led2=0,led3=0;
 //   pc.printf("# Setting Mode\r\n");
    strcpy(cmdbuff, "wifi.setmode(wifi.STATION)\r\n");
    sendCMD();
    getReply();
    wait(1);
    
    
 //   pc.printf("\n---------- Listing Access Points ----------\r\n");
    strcpy(cmdbuff, "function listap(t)\r\n");
        sendCMD();
        wait(1);
        strcpy(cmdbuff, "for k,v in pairs(t) do\r\n");
        sendCMD();
        wait(1);
        strcpy(cmdbuff, "print(k..\" : \"..v)\r\n");
        sendCMD();
        wait(1);
        strcpy(cmdbuff, "end\r\n");
        sendCMD();
        wait(1);
        strcpy(cmdbuff, "end\r\n");
        sendCMD();
        wait(1);
        strcpy(cmdbuff, "wifi.sta.getap(listap)\r\n");
   sendCMD();
    wait(5);
    getReply();

    led1=0,led2=1,led3=0;
  //  pc.printf("# Connecting to AP\r\n");
  //  pc.printf("# ssid = %s\t\tpwd = %s\r\n", ssid, pwd);
    strcpy(cmdbuff, "wifi.sta.config(\"");
    strcat(cmdbuff, ssid);
    strcat(cmdbuff, "\",\"");
    strcat(cmdbuff, pwd);
    strcat(cmdbuff, "\")\r\n");
    sendCMD();
    wait(12);
    getReply();


    wait(2);
    led1=0,led2=0,led3=1;
   // pc.printf("# Get IP Address\r\n");
    strcpy(cmdbuff, "print(wifi.sta.getip())\r\n");
    sendCMD();
    wait(3);
    getReply();
    

    wait(2);
    led1=1,led2=0,led3=0;
   // pc.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");
    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(.5);
    led1=1,led2=0,led3=0;
    strcpy(cmdbuff, "conn:on(\"receive\", function(conn, payload) \r\n");
    sendCMD();
    getReply();

    wait(.5);
    led1=0,led2=1,led3=0;
    strcpy(cmdbuff, "conn:send(\"<h1> Hello, NodeMCU!!! </h1>\"");
    strcat(cmdbuff, ")\r\n");
    sendCMD();
    getReply();
    led1=0,led2=0,led3=1;
    strcpy(cmdbuff, "print(payload)\r\n");
    sendCMD();
    getReply();
    led1=1,led2=0,led3=0;
    strcpy(cmdbuff, "end)\r\n");
    sendCMD();
    getReply();
    led1=0,led2=1,led3=0;
    strcpy(cmdbuff, "end)\r\n");
    sendCMD();
    getReply();
    led1=0,led2=0,led3=0;
  //  pc.printf("# Ready\r\n");
    wait(1);
}




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() {

// 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;
    }

    return;
}