Final version

Dependencies:   mbed Servo Motor

Committer:
kzar
Date:
Sun Dec 09 18:27:35 2018 +0000
Revision:
2:15a043aa08ea
Parent:
1:6d317aa0aae7
Child:
3:25e57f22f970
Sets up a server and then waits for messages from connected devices. The message is then parsed and looks for commands to control the car. Currently only motor speed commands are implemented

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