a robot you can talk to when you're lonely

Dependencies:   HALLFX_ENCODER Motor RPCInterface mbed

Revision:
0:1fb00e911fe6
Child:
2:747b84e54088
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Dec 12 14:39:25 2016 +0000
@@ -0,0 +1,422 @@
+#include "mbed.h"
+#include "Car.h"
+#include "mywifi.h"
+#include "Motor.h"
+#include "HALLFX_ENCODER.h"
+#include "mbed_rpc.h"
+
+Serial pc(USBTX, USBRX);
+Serial esp(p28, p27);
+char ssid[32] = "ThugMansion";
+char pwd[32] = "2paclives";
+char port[32] = "1035"; // must be port forwarded
+char timeout[32] = "28800";
+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 left_speed = .5;
+float right_speed = .5;
+float clicksTravelled;
+Motor left_motor(p26,p24,p25);    // pwm, fwd, rev
+Motor right_motor(p21, p23, p22); // pwm, fwd, rev
+HALLFX_ENCODER right_hall(p13);    // left hall effect encoder
+HALLFX_ENCODER left_hall(p14);   // left hall effect encoder
+float encoderFactor = 40;
+RPCFunction rpcTurnRight(&carTurnRight, "turnRight");
+RPCFunction rpcTurnLeft(&carTurnLeft, "turnLeft");
+RPCFunction rpcMoveForward(&carMoveForwardDistance, "moveForward");
+RPCFunction rpcMoveBackward(&carMoveBackwardDistance, "moveBackward");
+RPCFunction rpcTurn(&carTurn, "turn");
+
+int main() {
+    clicksTravelled = 0.0;
+    pc.baud(9600);
+    esp.baud(9600);
+    led1=0,led2=0,led3=0,led4=0;
+    esp.attach(&Rx_interrupt, Serial::RxIrq);
+    esp.attach(&Tx_interrupt, Serial::TxIrq);
+    wait(5);
+    connectToNetwork();
+    char rpc_in[256];
+    char rpc_out[256];
+    while (1) {
+        getReply();
+        memset(&rpc_in[0], 0, sizeof(rpc_in));
+        memset(&rpc_in[0], 0, sizeof(rpc_out));
+        int length = (int)rx_line[3] - 48;
+        if (length > 0 && length < 256) {
+            for (int i = 0; i < length; i++) {
+                rpc_in[i] = rx_line[i+4];
+            }
+            RPC::call(rpc_in, rpc_out);
+            pc.printf("%s\n", rpc_out);
+        }
+        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, reportStatus());
+        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();
+        wait(.5);
+        getReply();
+    }
+    
+}
+
+
+
+
+
+
+
+/* CAR FUNCTIONS */
+
+void carStop() {
+    left_motor.speed(0);
+    right_motor.speed(0);
+}
+
+void carResetEncoders() {
+    left_hall.reset();
+    right_hall.reset();
+    wait(0.1);
+}
+
+void carMoveForwardDistance(Arguments *in, Reply *out) {
+    carResetEncoders();
+    long diff;
+    int dist = in->getArg<int>();
+    float enc_dist = dist * encoderFactor;
+    volatile float left_val= left_hall.read();
+    volatile float right_val = right_hall.read();
+    while (left_val < enc_dist || left_val < enc_dist) {
+        left_val = left_hall.read();
+        right_val = right_hall.read();
+        diff = left_val - right_val;
+        float k = 0.5;
+        if (diff < 0) { // left has moved less than right
+            left_motor.speed(left_speed);
+            right_motor.speed(k*right_speed);
+        } else if (diff > 0)  { // right has moved less than left
+            left_motor.speed(k*left_speed);
+            right_motor.speed(right_speed);
+        } else {
+            left_motor.speed(left_speed);
+            right_motor.speed(right_speed);
+        }
+    }
+    clicksTravelled += left_val;
+    left_motor.speed(0);
+    right_motor.speed(0);
+}
+
+void carMoveBackwardDistance(Arguments *in, Reply *out) {
+    int dist = in->getArg<int>();
+    if (dist > 100) {
+        dist = 100;
+    }
+    carResetEncoders();
+    long diff;
+    float enc_dist = dist * encoderFactor;
+    volatile float left_val= left_hall.read();
+    volatile float right_val = right_hall.read();
+    while (left_val < enc_dist || right_val < enc_dist) {
+        left_val = left_hall.read();
+        right_val = right_hall.read();
+        diff = left_val-right_val;
+        float k = 0.8;
+        if (diff < 0) { // left has moved less than right
+            left_motor.speed(-left_speed);
+            right_motor.speed(-k*right_speed);
+        } else if (diff > 0)  { // right has moved less than left
+            left_motor.speed(-k*left_speed);
+            right_motor.speed(-right_speed);
+        } else {
+            left_motor.speed(-left_speed);
+            right_motor.speed(-right_speed);
+        }
+    }
+    clicksTravelled += left_val;
+    carStop();
+}
+
+void carTurn(Arguments *in, Reply *out) {
+    carResetEncoders();
+    float enc_dist = in->getArg<float>();
+    volatile float left_val= left_hall.read();
+    while (left_val < enc_dist) {
+        left_val = left_hall.read();
+        left_motor.speed(left_speed);
+        right_motor.speed(-right_speed);
+    }
+    carStop();
+}
+
+void carTurnRight(Arguments *in, Reply *out) {
+    carResetEncoders();
+    float enc_dist = 170;
+    volatile float left_val= left_hall.read();
+    while (left_val < enc_dist) {
+        left_val = left_hall.read();
+        left_motor.speed(left_speed);
+        right_motor.speed(-right_speed);
+    }
+    carStop();
+    if (out != NULL) out->putData("GOT HERE");
+}
+
+void carTurnLeft(Arguments *in, Reply *out) {
+    carResetEncoders();
+    float enc_dist = 170;
+    volatile float left_val= left_hall.read();
+    while (left_val < enc_dist) {
+        left_val = left_hall.read();
+        left_motor.speed(-left_speed);
+        right_motor.speed(right_speed);
+    }
+    carStop();
+}
+
+
+
+
+
+
+
+
+
+
+/* WIFI FUNCTIONS */
+
+void connectToNetwork() {
+    pc.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");
+    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);
+    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");
+    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");
+    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(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();
+
+    wait(2);
+    //led1=1,led2=1,led3=1;
+    led1=0,led2=0,led3=0;
+    pc.printf("# Ready\r\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;
+}
+
+char* reportStatus() {
+    char str[30];
+    float inchesTravelled = clicksTravelled / encoderFactor ;
+    sprintf(str, "%.1f", inchesTravelled);
+    return str;
+}
+
+// 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