An embedded server sending sensor information over the network to a remote client side process parsing the data
Dependencies: EthernetInterface NTPClient TimeInterface WebSocketClient mbed-rtos mbed ST_Events-old
data_logger.cpp@7:e9d4a4972e50, 2017-09-17 (annotated)
- Committer:
- thedude35
- Date:
- Sun Sep 17 17:43:20 2017 -0400
- Branch:
- USB-logging
- Revision:
- 7:e9d4a4972e50
- Parent:
- 4:a6ff97cfb57a
- Child:
- 8:e16130691c3b
Added network connection checking within the reporting functions
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
thedude35 | 2:5c9125d3ddae | 1 | //An embedded server sending sensor data to a client side process running on a PC for logging and analysis |
thedude35 | 2:5c9125d3ddae | 2 | //TODO: Add in error handling and timeouts to deal with dropped connections and compile flags for testing |
thedude35 | 2:5c9125d3ddae | 3 | |
thedude35 | 2:5c9125d3ddae | 4 | #include "data_logger.h" |
thedude35 | 2:5c9125d3ddae | 5 | |
thedude35 | 2:5c9125d3ddae | 6 | EthernetInterface eth; |
thedude35 | 2:5c9125d3ddae | 7 | NTPClient ntp; |
thedude35 | 2:5c9125d3ddae | 8 | TimeInterface time_b; |
thedude35 | 2:5c9125d3ddae | 9 | Timer t; |
thedude35 | 2:5c9125d3ddae | 10 | time_t timestamp; //Built-in time class instance |
thedude35 | 2:5c9125d3ddae | 11 | TCPSocketServer server; |
thedude35 | 2:5c9125d3ddae | 12 | TCPSocketConnection client; |
thedude35 | 2:5c9125d3ddae | 13 | EventQueue queue1; |
thedude35 | 2:5c9125d3ddae | 14 | EventQueue queue2; |
thedude35 | 2:5c9125d3ddae | 15 | Thread t1; |
thedude35 | 2:5c9125d3ddae | 16 | Thread t2; |
thedude35 | 2:5c9125d3ddae | 17 | Mutex m; |
thedude35 | 2:5c9125d3ddae | 18 | |
thedude35 | 2:5c9125d3ddae | 19 | //setup |
thedude35 | 2:5c9125d3ddae | 20 | DigitalOut led1(LED1); |
thedude35 | 3:221997836268 | 21 | AnalogIn strainIn(A0); |
thedude35 | 2:5c9125d3ddae | 22 | InterruptIn sig(p5); |
thedude35 | 2:5c9125d3ddae | 23 | |
thedude35 | 2:5c9125d3ddae | 24 | //RtosTimer Timer(send_payload,osTimerPeriodic); |
thedude35 | 2:5c9125d3ddae | 25 | |
thedude35 | 2:5c9125d3ddae | 26 | // main() runs in its own thread in the OS |
thedude35 | 2:5c9125d3ddae | 27 | // (note the calls to Thread::wait below for delays) |
thedude35 | 2:5c9125d3ddae | 28 | |
thedude35 | 2:5c9125d3ddae | 29 | int main(void) |
thedude35 | 2:5c9125d3ddae | 30 | { |
thedude35 | 2:5c9125d3ddae | 31 | eth.init(); //Use DHCP |
thedude35 | 7:e9d4a4972e50 | 32 | eth.setName("DL-test"); //set a hostname |
thedude35 | 7:e9d4a4972e50 | 33 | eth_cxn_status = eth.connect(); //Attempt an ethernet connection and save the status, add retries here in the future |
thedude35 | 7:e9d4a4972e50 | 34 | if(eth_cxn_status == 0) { |
thedude35 | 7:e9d4a4972e50 | 35 | //Bring up the ethernet interface |
thedude35 | 7:e9d4a4972e50 | 36 | printf("Detected Ethernet connection, entering network logging mode \n Server IP Address is %s\n", eth.getIPAddress()); |
thedude35 | 7:e9d4a4972e50 | 37 | server.bind(SERVER_PORT); |
thedude35 | 7:e9d4a4972e50 | 38 | server.listen(); //Wait for the client to connect |
thedude35 | 7:e9d4a4972e50 | 39 | server.accept(client); |
thedude35 | 7:e9d4a4972e50 | 40 | printf("Connection from: %s\n", client.get_address()); |
thedude35 | 7:e9d4a4972e50 | 41 | if (ntp.setTime("0.pool.ntp.org") == 0) //If time retrieval is successful |
thedude35 | 7:e9d4a4972e50 | 42 | { |
thedude35 | 7:e9d4a4972e50 | 43 | printf("Set time successfully\r\n"); |
thedude35 | 7:e9d4a4972e50 | 44 | |
thedude35 | 7:e9d4a4972e50 | 45 | } |
thedude35 | 7:e9d4a4972e50 | 46 | else |
thedude35 | 7:e9d4a4972e50 | 47 | { |
thedude35 | 7:e9d4a4972e50 | 48 | printf("Unable to set time, error\r\n"); |
thedude35 | 7:e9d4a4972e50 | 49 | } |
thedude35 | 7:e9d4a4972e50 | 50 | }; |
thedude35 | 7:e9d4a4972e50 | 51 | else { |
thedude35 | 7:e9d4a4972e50 | 52 | printf("Entering USB logging mode"); |
thedude35 | 7:e9d4a4972e50 | 53 | }; |
thedude35 | 7:e9d4a4972e50 | 54 | |
thedude35 | 2:5c9125d3ddae | 55 | printf("board is up"); |
thedude35 | 2:5c9125d3ddae | 56 | |
thedude35 | 2:5c9125d3ddae | 57 | timestamp = time(NULL); |
thedude35 | 3:221997836268 | 58 | queue1.call_every(RATE,&idle_report); |
thedude35 | 2:5c9125d3ddae | 59 | t1.start(callback(&queue1, &EventQueue::dispatch_forever)); //Start the thread for periodic basline value reporting |
thedude35 | 2:5c9125d3ddae | 60 | sig.rise(queue2.event(&cycle_time_isr_rise)); |
thedude35 | 2:5c9125d3ddae | 61 | sig.fall(queue2.event(&cycle_time_isr_fall)); |
thedude35 | 2:5c9125d3ddae | 62 | t2.start(callback(&queue2, &EventQueue::dispatch_forever)); //Start the cycle time and peak value calculation thread |
thedude35 | 2:5c9125d3ddae | 63 | |
thedude35 | 2:5c9125d3ddae | 64 | } |
thedude35 | 2:5c9125d3ddae | 65 | |
thedude35 | 2:5c9125d3ddae | 66 | void cycle_time_isr_rise(void) { |
thedude35 | 7:e9d4a4972e50 | 67 | t.start(); //Start the timer |
thedude35 | 7:e9d4a4972e50 | 68 | m.lock(); //Lock the mutex to prevent the baseline reporting thread from writing to the application buffer |
thedude35 | 2:5c9125d3ddae | 69 | /*for(i=0;i<1023;i++) { |
thedude35 | 2:5c9125d3ddae | 70 | samples[i] = pressureIn.read(); |
thedude35 | 2:5c9125d3ddae | 71 | //add a mean and peak pressure calculation here and you may want to slow down the sample rate |
thedude35 | 2:5c9125d3ddae | 72 | i++; |
thedude35 | 2:5c9125d3ddae | 73 | }*/ |
thedude35 | 2:5c9125d3ddae | 74 | //p_press = pressIn.read(); |
thedude35 | 7:e9d4a4972e50 | 75 | p_strain = strainCalc(); //Calculate strain while the machine is crushing |
thedude35 | 2:5c9125d3ddae | 76 | } |
thedude35 | 2:5c9125d3ddae | 77 | |
thedude35 | 2:5c9125d3ddae | 78 | void cycle_time_isr_fall(void) { |
thedude35 | 2:5c9125d3ddae | 79 | t.stop(); //Stop the timer |
thedude35 | 2:5c9125d3ddae | 80 | cycle_time = t.read(); |
thedude35 | 2:5c9125d3ddae | 81 | t.reset(); //reset the timer |
thedude35 | 7:e9d4a4972e50 | 82 | if(eth_cxn_status) == 0 { |
thedude35 | 7:e9d4a4972e50 | 83 | sprintf(appbuffer,"<payload><time>%s</time><cy_time>%f</cy_time><p_strain>%f</p_strain></payload>",time_b.ctime(×tamp), cycle_time, p_strain); |
thedude35 | 7:e9d4a4972e50 | 84 | }; |
thedude35 | 7:e9d4a4972e50 | 85 | else { |
thedude35 | 7:e9d4a4972e50 | 86 | printf("Cycle time is: %f \n Strain detected during cycle is: %f% \r", cycle_time, p_strain); |
thedude35 | 7:e9d4a4972e50 | 87 | }; |
thedude35 | 2:5c9125d3ddae | 88 | sprintf(appbuffer,"\0"); //Nullify the string |
thedude35 | 2:5c9125d3ddae | 89 | m.unlock(); //Unlock the mutex |
thedude35 | 7:e9d4a4972e50 | 90 | }; |
thedude35 | 2:5c9125d3ddae | 91 | |
thedude35 | 3:221997836268 | 92 | void idle_report(void) { |
thedude35 | 2:5c9125d3ddae | 93 | m.lock(); //Attempt to lock the mutex here |
thedude35 | 3:221997836268 | 94 | id_strain = strainCalc(); //Calculate strain while the machine is idle |
thedude35 | 7:e9d4a4972e50 | 95 | if (eth_cxn_status) == 0 { //Log data based on the available connection |
thedude35 | 7:e9d4a4972e50 | 96 | sprintf(appbuffer,"<payload><time>%s</time><id_strain>%f</id_strain></payload>",time_b.ctime(×tamp), id_strain); |
thedude35 | 7:e9d4a4972e50 | 97 | } |
thedude35 | 7:e9d4a4972e50 | 98 | else { |
thedude35 | 7:e9d4a4972e50 | 99 | printf("Strain while machine is idle: %f%",id_strain ); |
thedude35 | 7:e9d4a4972e50 | 100 | }; |
thedude35 | 7:e9d4a4972e50 | 101 | |
thedude35 | 2:5c9125d3ddae | 102 | sprintf(appbuffer,"\0"); //Nullify the buffer |
thedude35 | 2:5c9125d3ddae | 103 | m.unlock(); //Unlock the mutex |
thedude35 | 2:5c9125d3ddae | 104 | } |
thedude35 | 3:221997836268 | 105 | |
thedude35 | 3:221997836268 | 106 | float strainCalc(void) { |
thedude35 | 3:221997836268 | 107 | float deltaR = strainIn/CURRENT; //Calculate Delta R |
thedude35 | 3:221997836268 | 108 | float strain = (1/GAUGE_FACTOR)*(deltaR/NOMINAL_R); //Calculate strain, see equation reference in docs |
thedude35 | 3:221997836268 | 109 | return strain; |
thedude35 | 3:221997836268 | 110 | } |
thedude35 | 2:5c9125d3ddae | 111 |