Delgermaa Nergui / Mbed 2 deprecated healt_monitor_ECE4180

Dependencies:   4DGL-uLCD-SE GP-20U7 PinDetect RPCInterface mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // ESP8266 Static page WEB server to control Mbed
00002 
00003 #include "mbed.h"
00004 #include "LSM9DS1.h"
00005 #include "GPS.h"
00006 #include "GPSstuff.h"
00007 #include <string>
00008 #include <iostream>
00009 
00010 Serial pc(USBTX, USBRX);
00011 Serial esp(p28, p27); // tx, rx
00012 GPS gps(p13, p14);
00013 GPSstuff object;
00014 LSM9DS1 IMU(p9, p10, 0xD6, 0x3C);
00015 
00016 char ssid[32] = "AndroidAP";     // enter WiFi router ssid inside the quotes
00017 char pwd [32] = "91d4f66f56c1"; // enter WiFi router passusrname inside the quotes
00018 
00019 char Steps[10];
00020 char Distance_travel[10];
00021 char Calories_burned[10];
00022 
00023 float a, ax, ay, az; //acceleration
00024 int i=0, n=0;
00025 bool flag=0;
00026     
00027 float buffer[4], d, totalDistance=0, threshold=1.1, calories=0, steps=0;
00028 
00029 // things for sending/receiving data over serial
00030 volatile int tx_in=0;
00031 volatile int tx_out=0;
00032 volatile int rx_in=0;
00033 volatile int rx_out=0;
00034 const int buffer_size = 4095;
00035 char tx_buffer[buffer_size+1];
00036 char rx_buffer[buffer_size+1];
00037 void Tx_interrupt();
00038 void Rx_interrupt();
00039 void send_line();
00040 void read_line();
00041 
00042 int DataRX;
00043 int update;
00044 int count;
00045 char cmdbuff[1024];
00046 char replybuff[4096];
00047 char webdata[4096]; // This may need to be bigger depending on WEB browser used
00048 char webbuff[4096];     // Currently using 1986 characters, Increase this if more web page data added
00049 char timebuf[30];
00050 void SendCMD(),getreply(),ReadWebData(),startserver();
00051 void gettime(),setRTC(), getsteps(), getdistance();
00052 char rx_line[1024];
00053 int port        =80;  // set server port
00054 int SERVtimeout =5;    // set server timeout in seconds in case link breaks.
00055 struct tm t;
00056 // manual set RTC values
00057 int minute      =00;    // 0-59
00058 int hour        =12;    // 2-23
00059 int dayofmonth  =26;    // 1-31
00060 int month       =8;     // 1-12
00061 int year        =15;    // last 2 digits
00062 
00063 int main()
00064 {
00065     pc.baud(9600);
00066     esp.baud(9600);
00067     // Setup a serial interrupt function to receive data
00068     esp.attach(&Rx_interrupt, Serial::RxIrq);
00069     // Setup a serial interrupt function to transmit data
00070     esp.attach(&Tx_interrupt, Serial::TxIrq);
00071     if (time(NULL) < 1420070400) {
00072         setRTC();
00073     }
00074     startserver();
00075     DataRX=0;
00076     ReadWebData();
00077     IMU.begin();
00078     if (!IMU.begin()) {
00079         pc.printf("Failed to communicate with LSM9DS1.\n");
00080     }
00081     IMU.calibrate(1);
00082     while(1) {
00083         while(n<26){
00084             getsteps();
00085             wait(0.2);
00086             n++;
00087         }
00088         //if(DataRX==1) {
00089         ReadWebData();
00090         esp.attach(&Rx_interrupt, Serial::RxIrq);
00091         // get new values
00092         gettime();
00093         getdistance();
00094         // send new values
00095         sprintf(cmdbuff, "count,time,steps,distance,calories=%d,\"%s\",\"%s\",\"%s\",\"%s\"\r\n",count,timebuf,Steps,Distance_travel, Calories_burned);
00096 //                sprintf(cmdbuff, "count,time,steps,distance= %d,\"%s\",\"%s\",\"%s\"\r\n",count,timebuf,Steps,Distance_travel);
00097         SendCMD();
00098         getreply(); 
00099         n=0; 
00100     }
00101 }
00102 
00103 // Reads and processes GET and POST web data
00104 void ReadWebData()
00105 {
00106     wait_ms(200);
00107     esp.attach(NULL,Serial::RxIrq);
00108     DataRX=0;
00109     memset(webdata, '\0', sizeof(webdata));
00110     strcpy(webdata, rx_buffer);
00111     memset(rx_buffer, '\0', sizeof(rx_buffer));
00112     rx_in = 0;
00113     rx_out = 0;
00114     // check web data for form information
00115     if( strstr(webdata, "POST") != NULL ) { // set update flag if POST request
00116         update=1;
00117     }
00118     if( strstr(webdata, "GET") != NULL && strstr(webdata, "favicon") == NULL ) { // set update flag for GET request but do not want to update for favicon requests
00119         update=1;
00120     }
00121 }
00122 // Starts webserver
00123 void startserver()
00124 {
00125     gettime();
00126     getsteps();
00127     getdistance();
00128     pc.printf("++++++++++ Resetting ESP ++++++++++\r\n");
00129     strcpy(cmdbuff,"node.restart()\r\n");
00130     SendCMD();
00131     wait(2);
00132     getreply();
00133     
00134     pc.printf("\n++++++++++ Starting Server ++++++++++\r\n> ");
00135 
00136     // initial values
00137     sprintf(cmdbuff, "count,time,steps,distance,calories=%d,\"%s\",\"%s\",\"%s\",\"%s\"\r\n",count,timebuf,Steps,Distance_travel, Calories_burned);
00138     SendCMD();
00139     getreply();
00140     wait(0.5);
00141 
00142     //create server
00143     sprintf(cmdbuff, "srv=net.createServer(net.TCP,%d)\r\n",SERVtimeout);
00144     SendCMD();
00145     getreply();
00146     wait(0.5);
00147     strcpy(cmdbuff,"srv:listen(80,function(conn)\r\n");
00148     SendCMD();
00149     getreply();
00150     wait(0.3);
00151         strcpy(cmdbuff,"conn:on(\"receive\",function(conn,payload) \r\n");
00152         SendCMD();
00153         getreply();
00154         wait(0.3);
00155         
00156         //print data to mbed
00157         strcpy(cmdbuff,"print(payload)\r\n");
00158         SendCMD();
00159         getreply();
00160         wait(0.2);
00161        
00162         //web page data
00163         strcpy(cmdbuff,"conn:send('<!DOCTYPE html><html><body><h1>Mbed IoT Web Controller</h1>')\r\n");
00164         SendCMD();
00165         getreply();
00166         wait(0.4);
00167         strcpy(cmdbuff,"conn:send('<br>Last hit (based on mbed RTC time): '..time..'<br><hr>')\r\n");
00168         SendCMD();
00169         getreply();
00170         wait(0.4);
00171         strcpy(cmdbuff,"conn:send('Steps: '..steps..' <br>Distance: '..distance..' km<br><hr>')\r\n");
00172         SendCMD();
00173         getreply();
00174         wait(0.3);
00175         strcpy(cmdbuff,"conn:send('Calories: '..calories..' kcal<br><hr>')\r\n");
00176         SendCMD();
00177         getreply();
00178         wait(0.3);
00179         strcpy(cmdbuff,"conn:send('<form method=\"POST\"')\r\n");
00180         SendCMD();
00181         getreply();
00182         wait(0.3);
00183         strcpy(cmdbuff,"conn:send('<p><input type=\"submit\" value=\"Update\"></form>')\r\n");
00184         SendCMD();
00185         getreply();
00186         wait(0.3);
00187         // end web page data
00188         strcpy(cmdbuff, "conn:on(\"sent\",function(conn) conn:close() end)\r\n"); // close current connection
00189         SendCMD();
00190         getreply();
00191         wait(0.3);
00192         strcpy(cmdbuff, "end)\r\n");
00193         SendCMD();
00194         getreply();
00195         wait(0.2);
00196     strcpy(cmdbuff, "end)\r\n");
00197     SendCMD();
00198     getreply();
00199     wait(0.2);
00200 
00201     strcpy(cmdbuff, "tmr.alarm(0, 1000, 1, function()\r\n");
00202     SendCMD();
00203     getreply();
00204     wait(0.2);
00205     strcpy(cmdbuff, "if wifi.sta.getip() == nil then\r\n");
00206     SendCMD();
00207     getreply();
00208     wait(0.2);
00209     strcpy(cmdbuff, "print(\"Connecting to AP...\\n\")\r\n");
00210     SendCMD();
00211     getreply();
00212     wait(0.2);
00213     strcpy(cmdbuff, "else\r\n");
00214     SendCMD();
00215     getreply();
00216     wait(0.2);
00217     strcpy(cmdbuff, "ip, nm, gw=wifi.sta.getip()\r\n");
00218     SendCMD();
00219     getreply();
00220     wait(0.2);
00221     strcpy(cmdbuff,"print(\"IP Address: \",ip)\r\n");
00222     SendCMD();
00223     getreply();
00224     wait(0.2);
00225     strcpy(cmdbuff,"tmr.stop(0)\r\n");
00226     SendCMD();
00227     getreply();
00228     wait(0.2);
00229     strcpy(cmdbuff,"end\r\n");
00230     SendCMD();
00231     getreply();
00232     wait(0.2);
00233     strcpy(cmdbuff,"end)\r\n");
00234     SendCMD();
00235     getreply();
00236     wait(0.2);
00237     
00238     pc.printf("\n\n++++++++++ Ready ++++++++++\r\n\n");
00239 }
00240 
00241 
00242 // ESP Command data send
00243 void SendCMD()
00244 {
00245     int i;
00246     char temp_char;
00247     bool empty;
00248     i = 0;
00249 // Start Critical Section - don't interrupt while changing global buffer variables
00250     NVIC_DisableIRQ(UART1_IRQn);
00251     empty = (tx_in == tx_out);
00252     while ((i==0) || (cmdbuff[i-1] != '\n')) {
00253 // Wait if buffer full
00254         if (((tx_in + 1) % buffer_size) == tx_out) {
00255 // End Critical Section - need to let interrupt routine empty buffer by sending
00256             NVIC_EnableIRQ(UART1_IRQn);
00257             while (((tx_in + 1) % buffer_size) == tx_out) {
00258             }
00259 // Start Critical Section - don't interrupt while changing global buffer variables
00260             NVIC_DisableIRQ(UART1_IRQn);
00261         }
00262         tx_buffer[tx_in] = cmdbuff[i];
00263         i++;
00264         tx_in = (tx_in + 1) % buffer_size;
00265     }
00266     if (esp.writeable() && (empty)) {
00267         temp_char = tx_buffer[tx_out];
00268         tx_out = (tx_out + 1) % buffer_size;
00269 // Send first character to start tx interrupts, if stopped
00270         esp.putc(temp_char);
00271     }
00272 // End Critical Section
00273     NVIC_EnableIRQ(UART1_IRQn);
00274     return;
00275 }
00276 
00277 // Get Command and ESP status replies
00278 void getreply()
00279 {
00280     read_line();
00281     sscanf(rx_line,replybuff);
00282 }
00283  
00284 // Read a line from the large rx buffer from rx interrupt routine
00285 void read_line() {
00286     int i;
00287     i = 0;
00288 // Start Critical Section - don't interrupt while changing global buffer variables
00289     NVIC_DisableIRQ(UART1_IRQn);
00290 // Loop reading rx buffer characters until end of line character
00291     while ((i==0) || (rx_line[i-1] != '\r')) {
00292 // Wait if buffer empty
00293         if (rx_in == rx_out) {
00294 // End Critical Section - need to allow rx interrupt to get new characters for buffer
00295             NVIC_EnableIRQ(UART1_IRQn);
00296             while (rx_in == rx_out) {
00297             }
00298 // Start Critical Section - don't interrupt while changing global buffer variables
00299             NVIC_DisableIRQ(UART1_IRQn);
00300         }
00301         rx_line[i] = rx_buffer[rx_out];
00302         i++;
00303         rx_out = (rx_out + 1) % buffer_size;
00304     }
00305 // End Critical Section
00306     NVIC_EnableIRQ(UART1_IRQn);
00307     rx_line[i-1] = 0;
00308     return;
00309 }
00310  
00311  
00312 // Interupt Routine to read in data from serial port
00313 void Rx_interrupt() {
00314     DataRX=1;
00315 // Loop just in case more than one character is in UART's receive FIFO buffer
00316 // Stop if buffer full
00317     while ((esp.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) {
00318         rx_buffer[rx_in] = esp.getc();
00319 // Uncomment to Echo to USB serial to watch data flow
00320         pc.putc(rx_buffer[rx_in]);
00321         rx_in = (rx_in + 1) % buffer_size;
00322     }
00323     return;
00324 }
00325  
00326  
00327 // Interupt Routine to write out data to serial port
00328 void Tx_interrupt() {
00329 // Loop to fill more than one character in UART's transmit FIFO buffer
00330 // Stop if buffer empty
00331     while ((esp.writeable()) && (tx_in != tx_out)) {
00332         esp.putc(tx_buffer[tx_out]);
00333         tx_out = (tx_out + 1) % buffer_size;
00334     }
00335     return;
00336 }
00337 
00338 void gettime()
00339 {
00340     time_t seconds = time(NULL);
00341     strftime(timebuf,50,"%H:%M:%S %a %d %b %y", localtime(&seconds));
00342 }
00343 
00344 void setRTC()
00345 {
00346     t.tm_sec = (0);             // 0-59
00347     t.tm_min = (minute);        // 0-59
00348     t.tm_hour = (hour);         // 0-23
00349     t.tm_mday = (dayofmonth);   // 1-31
00350     t.tm_mon = (month-1);       // 0-11  "0" = Jan, -1 added for Mbed RCT clock format
00351     t.tm_year = ((year)+100);   // year since 1900,  current DCF year + 100 + 1900 = correct year
00352     set_time(mktime(&t));       // set RTC clock
00353 }
00354 // Analog in example
00355 void getsteps(){
00356     while(!IMU.accelAvailable());
00357         IMU.readAccel();
00358         ax=IMU.calcAccel(IMU.ax);
00359         ay=IMU.calcAccel(IMU.ay);
00360         az=IMU.calcAccel(IMU.az);
00361         a=sqrt(pow(ax, 2) + pow(ay, 2) + pow(az, 2));
00362         if (a>=threshold && flag==0){ // if it crosses threshold increment step by one and raise the flag
00363             steps+=1; flag=1; calories=steps/20;
00364             pc.printf("steps: %i\n", steps);
00365         } 
00366 
00367         else if (a < threshold && flag==1){ // if flag is raised and threshold is not crossed , put that flag down.
00368             flag=0;
00369         }
00370         sprintf(Steps,"%2.3f",steps);
00371         sprintf(Calories_burned, "%2.3f", calories);
00372 }
00373 void getdistance(){
00374     if (i==0){
00375         //initial reading made by the GPS
00376         gps.sample();
00377         buffer[i]= gps.longitude;
00378         buffer[i+1] = gps.latitude;
00379         i=i+2;
00380         if (buffer[2]==0 && buffer[3]==0){
00381             //second reading made by GPS
00382             gps.sample();
00383             buffer[2]= gps.longitude;
00384             buffer[3] = gps.latitude;
00385             i=2;
00386             }
00387     }
00388         else if (i==2){
00389             float lat1d = buffer[0];
00390             float lon1d = buffer[1];
00391             float lat2d = buffer[2];
00392             float lon2d = buffer[3];
00393             d = object.distanceEarth(lat1d, lon1d, lat2d, lon2d);
00394             lat1d = buffer[2];
00395             lon1d = buffer[3];
00396             i=0;
00397         }
00398         totalDistance+=d;
00399         sprintf(Distance_travel, "%2.3f", totalDistance);
00400 }