Final version

Dependencies:   mbed Servo Motor

Committer:
kzar
Date:
Tue Dec 11 21:22:30 2018 +0000
Revision:
3:25e57f22f970
Parent:
2:15a043aa08ea
ye

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kzar 0:60cec426fad9 1 // This mbed code starts up a server on the esp8266 and then updates it according to inputs from the controller
kzar 0:60cec426fad9 2 // The car will host the server, the controller will send commands to the server
kzar 0:60cec426fad9 3
kzar 0:60cec426fad9 4 #include "mbed.h"
kzar 2:15a043aa08ea 5 #include "Motor.h"
kzar 3:25e57f22f970 6 #include "Servo.h"
kzar 0:60cec426fad9 7
kzar 3:25e57f22f970 8 // Construt serial objects
kzar 0:60cec426fad9 9 Serial pc(USBTX, USBRX);
kzar 0:60cec426fad9 10 Serial esp(p28, p27); // tx, rx
kzar 3:25e57f22f970 11 // Construct motor objects
kzar 2:15a043aa08ea 12 Motor left_motor(p25, p6, p5); // pwm, fwd, rev
kzar 2:15a043aa08ea 13 Motor right_motor(p26, p11, p10); //pwm, fwd, rev
kzar 3:25e57f22f970 14 // Construct servo objects
kzar 3:25e57f22f970 15 Servo servo_x(p22);
kzar 3:25e57f22f970 16 Servo servo_y(p23);
kzar 0:60cec426fad9 17
kzar 0:60cec426fad9 18 // Standard Mbed LED definitions
kzar 0:60cec426fad9 19 DigitalOut led1(LED1);
kzar 0:60cec426fad9 20 DigitalOut led2(LED2);
kzar 0:60cec426fad9 21
kzar 0:60cec426fad9 22 // things for sending/receiving data over serial
kzar 0:60cec426fad9 23 volatile int tx_in=0;
kzar 0:60cec426fad9 24 volatile int tx_out=0;
kzar 0:60cec426fad9 25 volatile int rx_in=0;
kzar 0:60cec426fad9 26 volatile int rx_out=0;
kzar 0:60cec426fad9 27 const int buffer_size = 4095;
kzar 0:60cec426fad9 28 char tx_buffer[buffer_size+1];
kzar 0:60cec426fad9 29 char rx_buffer[buffer_size+1];
kzar 0:60cec426fad9 30 void Tx_interrupt();
kzar 0:60cec426fad9 31 void Rx_interrupt();
kzar 0:60cec426fad9 32 void read_line();
kzar 0:60cec426fad9 33
kzar 0:60cec426fad9 34 int DataRX;
kzar 0:60cec426fad9 35 char cmdbuff[1024];
kzar 0:60cec426fad9 36 char replybuff[4096];
kzar 0:60cec426fad9 37 char webdata[4096]; // This may need to be bigger depending on WEB browser used
kzar 0:60cec426fad9 38 char webbuff[4096]; // Currently using 1986 characters, Increase this if more web page data added
kzar 2:15a043aa08ea 39 void SendCMD(),getreply(),getcmd(),startserver();
kzar 0:60cec426fad9 40 char rx_line[1024];
kzar 0:60cec426fad9 41
kzar 2:15a043aa08ea 42 // buffers used for taking float values from string commands
kzar 2:15a043aa08ea 43 char lm_buff[8];
kzar 2:15a043aa08ea 44 char rm_buff[8];
kzar 3:25e57f22f970 45 char xsv_buff[8];
kzar 3:25e57f22f970 46 char ysv_buff[8];
kzar 2:15a043aa08ea 47 char* lm;
kzar 2:15a043aa08ea 48 char* rm;
kzar 3:25e57f22f970 49 char* xsv;
kzar 0:60cec426fad9 50
kzar 0:60cec426fad9 51 int main()
kzar 0:60cec426fad9 52 {
kzar 3:25e57f22f970 53 // Change huzzah baud rate, wait for x amout of time, then set pc/esp.baud
kzar 0:60cec426fad9 54 pc.baud(9600);
kzar 0:60cec426fad9 55 esp.baud(9600);
kzar 3:25e57f22f970 56 led1=0,led2=0;
kzar 3:25e57f22f970 57 left_motor.speed(0);
kzar 3:25e57f22f970 58 right_motor.speed(0);
kzar 3:25e57f22f970 59 servo_x = 0;
kzar 3:25e57f22f970 60 servo_y = 0;
kzar 0:60cec426fad9 61 // Setup a serial interrupt function to receive data
kzar 0:60cec426fad9 62 esp.attach(&Rx_interrupt, Serial::RxIrq);
kzar 0:60cec426fad9 63 // Setup a serial interrupt function to transmit data
kzar 0:60cec426fad9 64 esp.attach(&Tx_interrupt, Serial::TxIrq);
kzar 0:60cec426fad9 65 // Start up the server
kzar 0:60cec426fad9 66 startserver();
kzar 3:25e57f22f970 67 // Indicates the server is set up
kzar 3:25e57f22f970 68 led1 = 1;
kzar 2:15a043aa08ea 69
kzar 0:60cec426fad9 70 // Everything is interrupt driven, infinite loop
kzar 0:60cec426fad9 71 while(1) {
kzar 0:60cec426fad9 72 // Read data if its available
kzar 0:60cec426fad9 73 if(DataRX==1) {
kzar 3:25e57f22f970 74 led2=!led2;
kzar 2:15a043aa08ea 75 getcmd();
kzar 0:60cec426fad9 76 esp.attach(&Rx_interrupt, Serial::RxIrq);
kzar 0:60cec426fad9 77 }
kzar 0:60cec426fad9 78 }
kzar 0:60cec426fad9 79 }
kzar 0:60cec426fad9 80
kzar 0:60cec426fad9 81 // Reads and processes GET and POST web data
kzar 2:15a043aa08ea 82 void getcmd()
kzar 0:60cec426fad9 83 {
kzar 3:25e57f22f970 84 //wait_ms(100);
kzar 0:60cec426fad9 85 esp.attach(NULL,Serial::RxIrq);
kzar 0:60cec426fad9 86 DataRX=0;
kzar 0:60cec426fad9 87 memset(webdata, '\0', sizeof(webdata));
kzar 0:60cec426fad9 88 strcpy(webdata, rx_buffer);
kzar 0:60cec426fad9 89 memset(rx_buffer, '\0', sizeof(rx_buffer));
kzar 0:60cec426fad9 90 rx_in = 0;
kzar 0:60cec426fad9 91 rx_out = 0;
kzar 0:60cec426fad9 92
kzar 2:15a043aa08ea 93 //Print command for debug
kzar 2:15a043aa08ea 94 pc.printf(webdata);
kzar 0:60cec426fad9 95 // Modify this to check for our commands
kzar 0:60cec426fad9 96 // check web data for form information
kzar 3:25e57f22f970 97 lm = strstr(webdata, "l=");
kzar 3:25e57f22f970 98 rm = strstr(webdata, "r=");
kzar 3:25e57f22f970 99 xsv = strstr(webdata, "x=");
kzar 3:25e57f22f970 100
kzar 2:15a043aa08ea 101 if(lm != NULL ) {
kzar 3:25e57f22f970 102 lm = lm + 2;
kzar 2:15a043aa08ea 103 for (int i = 0; i < 8; ++i){
kzar 3:25e57f22f970 104 lm_buff[i] = lm[i];
kzar 2:15a043aa08ea 105 }
kzar 2:15a043aa08ea 106 // Convert the lm_buff to a float value and clear buffer
kzar 2:15a043aa08ea 107 left_motor.speed(atof(lm_buff));
kzar 2:15a043aa08ea 108 memset(lm_buff, '\0', sizeof(lm_buff));
kzar 0:60cec426fad9 109 }
kzar 2:15a043aa08ea 110 if( rm != NULL) {
kzar 3:25e57f22f970 111 rm = rm + 2;
kzar 3:25e57f22f970 112 for (int i = 0; i < 8; ++i) {
kzar 3:25e57f22f970 113 rm_buff[i] = rm[i];
kzar 2:15a043aa08ea 114 }
kzar 2:15a043aa08ea 115 // Convert the rm_buff to a float value and clear buffer
kzar 2:15a043aa08ea 116 right_motor.speed(atof(rm_buff));
kzar 2:15a043aa08ea 117 memset(rm_buff, '\0', sizeof(rm_buff));
kzar 0:60cec426fad9 118 }
kzar 2:15a043aa08ea 119
kzar 3:25e57f22f970 120 if(xsv != NULL ) {
kzar 3:25e57f22f970 121 xsv = xsv + 2;
kzar 3:25e57f22f970 122 for (int i = 0; i < 8; ++i){
kzar 3:25e57f22f970 123 xsv_buff[i] = xsv[i];
kzar 3:25e57f22f970 124 }
kzar 3:25e57f22f970 125 // Convert the lm_buff to a float value and clear buffer
kzar 3:25e57f22f970 126 servo_x = atof(xsv_buff);
kzar 3:25e57f22f970 127 memset(xsv_buff, '\0', sizeof(xsv_buff));
kzar 3:25e57f22f970 128 }
kzar 3:25e57f22f970 129
kzar 0:60cec426fad9 130 }
kzar 0:60cec426fad9 131 // Starts webserver
kzar 0:60cec426fad9 132 void startserver()
kzar 0:60cec426fad9 133 {
kzar 0:60cec426fad9 134 // Reset the ESP8266
kzar 0:60cec426fad9 135 pc.printf("++++++++++ Resetting ESP ++++++++++\r\n");
kzar 0:60cec426fad9 136 strcpy(cmdbuff,"node.restart()\r\n");
kzar 0:60cec426fad9 137 SendCMD();
kzar 3:25e57f22f970 138 wait(1);
kzar 0:60cec426fad9 139
kzar 0:60cec426fad9 140 // Set up WiFi connection
kzar 2:15a043aa08ea 141 pc.printf("++++++++++ Connecting to WiFi ++++++++++\r\n");
kzar 0:60cec426fad9 142
kzar 1:6d317aa0aae7 143 strcpy(cmdbuff,"wifi.setmode(wifi.STATIONAP)\r\n");
kzar 0:60cec426fad9 144 SendCMD();
kzar 3:25e57f22f970 145 wait(1);
kzar 0:60cec426fad9 146
kzar 3:25e57f22f970 147 strcpy(cmdbuff,"wifi.ap.config({ssid=\"Marlon's iPhone\",pwd=\"feelsbadman\"})\r\n");
kzar 0:60cec426fad9 148 SendCMD();
kzar 3:25e57f22f970 149 wait(1);
kzar 0:60cec426fad9 150
kzar 1:6d317aa0aae7 151 strcpy(cmdbuff,"print(\"Server IP Address: \", wifi.ap.getip())\r\n");
kzar 0:60cec426fad9 152 SendCMD();
kzar 3:25e57f22f970 153 wait(1);
kzar 0:60cec426fad9 154
kzar 0:60cec426fad9 155 // Start up the server
kzar 0:60cec426fad9 156 pc.printf("\n++++++++++ Starting Server ++++++++++\r\n> ");
kzar 0:60cec426fad9 157
kzar 0:60cec426fad9 158 //create server
kzar 1:6d317aa0aae7 159 strcpy(cmdbuff, "srv=net.createServer(net.TCP)\r\n");
kzar 0:60cec426fad9 160 SendCMD();
kzar 3:25e57f22f970 161 wait(1);
kzar 0:60cec426fad9 162 // Set the sever to listen (named conn)
kzar 0:60cec426fad9 163 strcpy(cmdbuff,"srv:listen(80,function(conn)\r\n");
kzar 0:60cec426fad9 164 SendCMD();
kzar 3:25e57f22f970 165 wait(1);
kzar 0:60cec426fad9 166 // Define receive function
kzar 1:6d317aa0aae7 167 strcpy(cmdbuff,"conn:on(\"receive\", function(conn, receivedData)\r\n");
kzar 0:60cec426fad9 168 SendCMD();
kzar 3:25e57f22f970 169 wait(1);
kzar 0:60cec426fad9 170
kzar 0:60cec426fad9 171 //print data to mbed
kzar 1:6d317aa0aae7 172 strcpy(cmdbuff,"print(\"Received Data: \" .. receivedData)\r\n");
kzar 0:60cec426fad9 173 SendCMD();
kzar 3:25e57f22f970 174 wait(1);
kzar 0:60cec426fad9 175
kzar 0:60cec426fad9 176 // End receive function
kzar 0:60cec426fad9 177 strcpy(cmdbuff,"end)\r\n");
kzar 0:60cec426fad9 178 SendCMD();
kzar 3:25e57f22f970 179 wait(1);
kzar 0:60cec426fad9 180
kzar 0:60cec426fad9 181 // Define sent function
kzar 0:60cec426fad9 182 strcpy(cmdbuff,"conn:on(\"sent\",function(conn)\r\n");
kzar 0:60cec426fad9 183 SendCMD();
kzar 3:25e57f22f970 184 wait(1);
kzar 0:60cec426fad9 185
kzar 0:60cec426fad9 186 //print data to mbed
kzar 0:60cec426fad9 187 strcpy(cmdbuff,"collectgarbage()\r\n");
kzar 0:60cec426fad9 188 SendCMD();
kzar 3:25e57f22f970 189 wait(1);
kzar 0:60cec426fad9 190
kzar 0:60cec426fad9 191 // End sent function
kzar 0:60cec426fad9 192 strcpy(cmdbuff,"end)\r\n");
kzar 0:60cec426fad9 193 SendCMD();
kzar 3:25e57f22f970 194 wait(1);
kzar 0:60cec426fad9 195
kzar 0:60cec426fad9 196 // End server listening
kzar 0:60cec426fad9 197 strcpy(cmdbuff,"end)\r\n");
kzar 0:60cec426fad9 198 SendCMD();
kzar 1:6d317aa0aae7 199 wait(2);
kzar 0:60cec426fad9 200 }
kzar 0:60cec426fad9 201
kzar 0:60cec426fad9 202
kzar 0:60cec426fad9 203 // ESP Command data send
kzar 0:60cec426fad9 204 void SendCMD()
kzar 0:60cec426fad9 205 {
kzar 0:60cec426fad9 206 int i;
kzar 0:60cec426fad9 207 char temp_char;
kzar 0:60cec426fad9 208 bool empty;
kzar 0:60cec426fad9 209 i = 0;
kzar 0:60cec426fad9 210 // Start Critical Section - don't interrupt while changing global buffer variables
kzar 0:60cec426fad9 211 NVIC_DisableIRQ(UART1_IRQn);
kzar 0:60cec426fad9 212 empty = (tx_in == tx_out);
kzar 0:60cec426fad9 213 while ((i==0) || (cmdbuff[i-1] != '\n')) {
kzar 0:60cec426fad9 214 // Wait if buffer full
kzar 0:60cec426fad9 215 if (((tx_in + 1) % buffer_size) == tx_out) {
kzar 0:60cec426fad9 216 // End Critical Section - need to let interrupt routine empty buffer by sending
kzar 0:60cec426fad9 217 NVIC_EnableIRQ(UART1_IRQn);
kzar 0:60cec426fad9 218 while (((tx_in + 1) % buffer_size) == tx_out) {
kzar 0:60cec426fad9 219 }
kzar 0:60cec426fad9 220 // Start Critical Section - don't interrupt while changing global buffer variables
kzar 0:60cec426fad9 221 NVIC_DisableIRQ(UART1_IRQn);
kzar 0:60cec426fad9 222 }
kzar 0:60cec426fad9 223 tx_buffer[tx_in] = cmdbuff[i];
kzar 0:60cec426fad9 224 i++;
kzar 0:60cec426fad9 225 tx_in = (tx_in + 1) % buffer_size;
kzar 0:60cec426fad9 226 }
kzar 0:60cec426fad9 227 if (esp.writeable() && (empty)) {
kzar 0:60cec426fad9 228 temp_char = tx_buffer[tx_out];
kzar 0:60cec426fad9 229 tx_out = (tx_out + 1) % buffer_size;
kzar 0:60cec426fad9 230 // Send first character to start tx interrupts, if stopped
kzar 0:60cec426fad9 231 esp.putc(temp_char);
kzar 0:60cec426fad9 232 }
kzar 0:60cec426fad9 233 // End Critical Section
kzar 0:60cec426fad9 234 NVIC_EnableIRQ(UART1_IRQn);
kzar 0:60cec426fad9 235 return;
kzar 0:60cec426fad9 236 }
kzar 0:60cec426fad9 237
kzar 0:60cec426fad9 238
kzar 0:60cec426fad9 239 // Get Command and ESP status replies
kzar 0:60cec426fad9 240 void getreply()
kzar 0:60cec426fad9 241 {
kzar 0:60cec426fad9 242 read_line();
kzar 0:60cec426fad9 243 sscanf(rx_line,replybuff);
kzar 0:60cec426fad9 244 }
kzar 0:60cec426fad9 245
kzar 0:60cec426fad9 246 // FUNCTIONS BELOW ARE FOR RX AND TX INTERUPTS (NOT WEB STUFF)
kzar 0:60cec426fad9 247
kzar 0:60cec426fad9 248 // Read a line from the large rx buffer from rx interrupt routine
kzar 0:60cec426fad9 249 void read_line() {
kzar 0:60cec426fad9 250 int i;
kzar 0:60cec426fad9 251 i = 0;
kzar 0:60cec426fad9 252 // Start Critical Section - don't interrupt while changing global buffer variables
kzar 0:60cec426fad9 253 NVIC_DisableIRQ(UART1_IRQn);
kzar 0:60cec426fad9 254 // Loop reading rx buffer characters until end of line character
kzar 0:60cec426fad9 255 while ((i==0) || (rx_line[i-1] != '\r')) {
kzar 0:60cec426fad9 256 // Wait if buffer empty
kzar 0:60cec426fad9 257 if (rx_in == rx_out) {
kzar 0:60cec426fad9 258 // End Critical Section - need to allow rx interrupt to get new characters for buffer
kzar 0:60cec426fad9 259 NVIC_EnableIRQ(UART1_IRQn);
kzar 0:60cec426fad9 260 while (rx_in == rx_out) {
kzar 0:60cec426fad9 261 }
kzar 0:60cec426fad9 262 // Start Critical Section - don't interrupt while changing global buffer variables
kzar 0:60cec426fad9 263 NVIC_DisableIRQ(UART1_IRQn);
kzar 0:60cec426fad9 264 }
kzar 0:60cec426fad9 265 rx_line[i] = rx_buffer[rx_out];
kzar 0:60cec426fad9 266 i++;
kzar 0:60cec426fad9 267 rx_out = (rx_out + 1) % buffer_size;
kzar 0:60cec426fad9 268 }
kzar 0:60cec426fad9 269 // End Critical Section
kzar 0:60cec426fad9 270 NVIC_EnableIRQ(UART1_IRQn);
kzar 0:60cec426fad9 271 rx_line[i-1] = 0;
kzar 0:60cec426fad9 272 return;
kzar 0:60cec426fad9 273 }
kzar 0:60cec426fad9 274
kzar 0:60cec426fad9 275
kzar 0:60cec426fad9 276 // Interupt Routine to read in data from serial port
kzar 0:60cec426fad9 277 void Rx_interrupt() {
kzar 0:60cec426fad9 278 DataRX=1;
kzar 0:60cec426fad9 279 //led3=1;
kzar 0:60cec426fad9 280 // Loop just in case more than one character is in UART's receive FIFO buffer
kzar 0:60cec426fad9 281 // Stop if buffer full
kzar 0:60cec426fad9 282 while ((esp.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) {
kzar 0:60cec426fad9 283 rx_buffer[rx_in] = esp.getc();
kzar 0:60cec426fad9 284 // Uncomment to Echo to USB serial to watch data flow
kzar 0:60cec426fad9 285 pc.putc(rx_buffer[rx_in]);
kzar 0:60cec426fad9 286 rx_in = (rx_in + 1) % buffer_size;
kzar 0:60cec426fad9 287 }
kzar 0:60cec426fad9 288 //led3=0;
kzar 0:60cec426fad9 289 return;
kzar 0:60cec426fad9 290 }
kzar 0:60cec426fad9 291
kzar 0:60cec426fad9 292
kzar 0:60cec426fad9 293 // Interupt Routine to write out data to serial port
kzar 0:60cec426fad9 294 void Tx_interrupt() {
kzar 0:60cec426fad9 295 //led2=1;
kzar 0:60cec426fad9 296 // Loop to fill more than one character in UART's transmit FIFO buffer
kzar 0:60cec426fad9 297 // Stop if buffer empty
kzar 0:60cec426fad9 298 while ((esp.writeable()) && (tx_in != tx_out)) {
kzar 0:60cec426fad9 299 esp.putc(tx_buffer[tx_out]);
kzar 0:60cec426fad9 300 tx_out = (tx_out + 1) % buffer_size;
kzar 0:60cec426fad9 301 }
kzar 0:60cec426fad9 302 //led2=0;
kzar 0:60cec426fad9 303 return;
kzar 0:60cec426fad9 304 }