Wifi controlled robot that uses ESP8266 wifi chip.

Dependencies:   Motordriver Servo mbed-dev mbed-rtos

Fork of ESP8266_wifi_robot by Kairi Kozuma

Revision:
0:df754b773321
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Oct 29 15:35:26 2016 +0000
@@ -0,0 +1,186 @@
+#include "mbed.h"
+#include "Servo.h"
+#include "rtos.h"
+#include "ESP8266.h"
+#include "motordriver.h"
+
+/* Left and right motors */
+Motor motor_l(p22, p11, p12, 1); // pwm, fwd, rev, can brake
+Motor motor_r(p21, p13, p14, 1); // pwm, fwd, rev, can brake
+
+/* Virtual USB serial port */
+RawSerial pc(USBTX, USBRX); // tx, rx
+
+/* ESP8266 wifi chip */
+ESP8266 esp(p28, p27, p26, "SSID", "password"); // tx, rx, reset, SSID, password
+#define RCV_BUF_SIZE 1024
+char rcv[RCV_BUF_SIZE];
+volatile int rcv_tail = 0;
+volatile int rcv_head = 0;
+    
+/* Speaker */
+PwmOut speaker(p24);
+
+/* Servo with IR sensor mounted */
+Servo servo_ir(p23);
+
+/* IR sensor */
+AnalogIn ir_sensor(p20);
+
+/* mbed LEDs */
+DigitalOut led1(LED1);
+DigitalOut led4(LED4);
+
+/* IR sensor thread */
+void ir_thread(void const * args) {
+    while (1) {
+        if (ir_sensor > 0.8) {
+            speaker = 1;
+        } else {
+            speaker = 0;
+        }
+        Thread::wait(50);
+    }
+}
+
+/* Circular buffer to hold commands */
+static int COM_BUF_SIZE = 100;
+volatile char * command_queue;
+volatile int queue_tail = 0;
+volatile int queue_head = 0;
+
+/* Command execute thread */
+void command_exec_thread(void const *args) {
+    while (1) {
+        if (queue_tail < queue_head) {
+            /* Save comand in temporary char variable */
+            char command = command_queue[queue_tail];
+            
+            /* Null the command consumed */
+            command_queue[queue_tail] = '\0';
+            
+            /* Execute the command */
+            switch(command) {
+            case '\0': /* null command */
+                break;
+            case 'F': /* Move forward */
+                motor_r.speed(1); 
+                motor_l.speed(1); 
+                Thread::wait(400);
+                motor_r.stop(1);
+                motor_l.stop(1);
+                break;
+            case 'B': /* Move backwards */
+                motor_r.speed(-1); 
+                motor_l.speed(-1); 
+                Thread::wait(400);
+                motor_r.stop(1);
+                motor_l.stop(1);
+                break;
+            case 'R': /* Move right */
+                motor_l.speed(1); 
+                Thread::wait(400);
+                motor_l.stop(1);
+                break;
+            case 'L': /* Move left */
+                motor_r.speed(1); 
+                Thread::wait(400);
+                motor_r.stop(1);
+                break;
+            case 'S': /* Turn servo right */
+                if (servo_ir > 0.0) {
+                    float val = (servo_ir - .2);
+                    servo_ir = val > 0.0 ? val : 0.0;
+                }
+                break;
+            case 'P': /* Turn servo left */
+                if (servo_ir < 1.0) {
+                    float val = (servo_ir + .2);
+                    servo_ir = val < 1.0 ? val : 1.0;
+                }
+                break;
+            default:
+                break;
+            }
+            /* Increment command index in circular buffer */
+            queue_tail = (queue_tail + 1) % COM_BUF_SIZE;
+        }
+        Thread::wait(200);
+    }
+}
+ 
+ 
+/* Queue command thread*/
+void command_queue_thread(void const *args) {
+    while(1) {
+        if (rcv_tail < rcv_head) {
+            if (rcv[rcv_tail] == 'Z') {
+                /* Loop until valid value found */
+                while (rcv[(rcv_tail + 1) % RCV_BUF_SIZE] == '\0') {
+                    Thread::wait(100);    
+                }
+                char let = rcv[(rcv_tail + 1) % RCV_BUF_SIZE];
+                command_queue[queue_head] = let;
+                queue_head = (queue_head + 1) % COM_BUF_SIZE;   
+            }
+            rcv[rcv_tail] = '\0'; /* Clear value */
+            rcv_tail = (rcv_tail + 1) % RCV_BUF_SIZE;
+        }
+        Thread::wait(10);
+    }
+}
+    
+/* PC receive interrupt routine */
+void pc_recv() {
+    led1 = 1;
+    while(pc.readable()) {
+        /* Print out to ESP8266 hardware */
+        esp.putc(pc.getc());
+    }
+    led1 = 0;
+}
+
+/* ESP83266 receive interrupt routine */
+void dev_recv() {
+    led4 = 1;
+    while(esp.readable()) {
+        char let = esp.getc();
+        /* Echo to pc to see output */
+        pc.putc(let);
+        /* Put in receive buffer */
+        rcv[rcv_head] = let;
+        rcv_head = (rcv_head + 1) % RCV_BUF_SIZE;
+    }
+    led4 = 0;
+}
+ 
+/* Main code */
+int main() {
+    /* Set pc serial baud rate */
+    pc.baud(9600);
+    
+    /* Set up esp */
+    esp.reset();
+    esp.baud(9600);
+    esp.setup();
+    
+    /* Initialize command buffer */
+    command_queue = (char*) calloc(sizeof(char), COM_BUF_SIZE);
+    
+    /* Attach interrupts */
+    pc.attach(&pc_recv, Serial::RxIrq);
+    esp.attach(&dev_recv, Serial::RxIrq);
+    
+    /* Print IP and MAC */
+    esp.getIP();
+    esp.getMAC();
+    
+    /* Start threads */
+    Thread command_exec_thr(command_exec_thread);
+    Thread command_queue_thr(command_queue_thread);
+    Thread ir_thr(ir_thread);
+    
+    while(1) {
+        Thread::wait(10000);
+    }
+}