Anthony Nguyen / eem202a_resolutedreamer_1 Featured

Dependencies:   MODSERIALhacked Convert SLCD mbed-src

Revision:
8:a44d03ecc942
Parent:
7:c81c6968f013
Child:
10:cfd3decff616
--- a/main.cpp	Fri Dec 12 21:59:10 2014 +0000
+++ b/main.cpp	Wed Dec 17 23:26:07 2014 +0000
@@ -1,14 +1,53 @@
 #include "mbed.h"
 #include "convert.h"
+#include "double_buffer.h"
 
-Serial pc(USBTX, USBRX);
+#include "MODSERIAL.h"
+
+#include "sine_table.h"
+
+#define SINE_OUT_FREQ_MASK 3
+#define SINE_OUT_FREQ_1HZ 0
+#define SINE_OUT_FREQ_10HZ 1
+#define SINE_OUT_FREQ_100HZ 2
+#define SINE_OUT_FREQ_1000HZ 3
+
+#define SINE_OUT_ON_MASK 4
+#define SINE_OUT_ON 4
+#define SINE_OUT_OFF 0
+
+#define D_OUT_MASK 8
+#define D_OUT_ON 8
+#define D_OUT_OFF 0
+
+#define ADC_SAMP_FREQ_MASK 48
+#define ADC_SAMP_FREQ_OFF 0
+#define ADC_SAMP_FREQ_1HZ 16
+#define ADC_SAMP_FREQ_10HZ 32
+#define ADC_SAMP_FREQ_100HZ 48
+
+#define SINE_TABLE_SIZE 1000
+
+MODSERIAL pc(USBTX, USBRX);
 
 AnalogIn my_light_sensor(PTE22);
 AnalogIn my_analog_pin(PTB0);
+
+AnalogOut sine_out_pin(PTE30);
+
+InterruptIn d_event_pin(PTA4);
+
 // false == on; true == off for the leds
 DigitalOut myled(LED_GREEN);
 DigitalOut redled(LED_RED);
+DigitalOut hundms_pulse_pin(PTA12);
+DigitalOut d_out_pin(PTD3);
 Timer timer;
+long long offset = 0;
+
+DoubleBuffer<unsigned short, 20> light_sensor_buffer;
+DoubleBuffer<unsigned short, 250> adc_buffer;
+DoubleBuffer<unsigned long long, 100> d_event_buffer;
 
 //initialize variables
 Ticker ticker;
@@ -16,26 +55,123 @@
 char t4_string[31];
 int t2;
 int t3;
-int i = 0;
+//int i = 0;
 bool pulse_value = false;
-float let_there_be_light = 0.0;
-float my_analog_value = 0.0;
+//float let_there_be_light = 0.0;
+//float my_analog_value = 0.0;
 Convert lcd;
-bool read_complete = false;
+
+//int adc_sampling_on = 0;
+int d_out_on = 0;
+int sine_out_on = 0;
+
+int adc_sampling_frequency = ADC_SAMP_FREQ_1HZ;
+int sine_out_frequency = SINE_OUT_FREQ_1000HZ;
+
+#define ANALOG_VALUE_BUFFER_SIZE 500
+
+/*float analog_values[2][ANALOG_VALUE_BUFFER_SIZE];
+int analog_fill_buffer = 0;
+int analog_value0_size = 0;
+int analog_value1_size = 0;*/
+
+//bool read_complete = false;
 
 int tick_count = 0;
+int sine_index = 0;
+
+
+// sets the flags from the website backend
+void set_options(char opt) {
+    adc_sampling_frequency = opt & ADC_SAMP_FREQ_MASK;
+    d_out_on = opt & D_OUT_MASK;
+    sine_out_on = opt & SINE_OUT_ON_MASK;
+    sine_out_frequency = opt & SINE_OUT_FREQ_MASK;
+}
+
+/*void read_adc() {
+    int analog_buffer_size;
+    if (analog_fill_buffer == 0) {
+        if (analog_value0_size >= ANALOG_VALUE_BUFFER_SIZE) {
+            return;
+        }
+        analog_buffer_size = analog_value0_size;
+        analog_value0_size++;
+    }
+    else {
+        if (analog_value1_size >= ANALOG_VALUE_BUFFER_SIZE) {
+            return;
+        }
+        analog_buffer_size = analog_value1_size;
+        analog_value1_size++;
+    }
+    analog_values[analog_fill_buffer][analog_buffer_size] = my_analog_pin.read();
+}*/
+
+/*
+void send_adc_data() {
+    int send_buffer = analog_fill_buffer;
+    int send_buffer_size;
+    // switch the fill buffer
+    if (analog_fill_buffer == 0) {
+        // make sure the new buffer is empty
+        analog_value1_size = 0;
+        analog_fill_buffer = 1;
+        send_buffer_size = analog_value0_size;
+    }
+    else {
+        // make sure the new buffer is empty
+        analog_value0_size = 0;
+        analog_fill_buffer = 0;
+        send_buffer_size = analog_value1_size;
+    }
+    
+    // send the header: the letter 'a' followed by the number of 32-bit floating point numbers
+    pc.putc('a');
+    pc.putc(send_buffer_size);
+    
+    // send the data in the old buffer
+    for(int i = 0; i < send_buffer_size; i++) {
+        pc.putc(analog_values[send_buffer][i]);
+    }
+}*/
+
+// sends unsigned long long in big endian (msb first)
+void send_ull(unsigned long long l) {
+    char* l_array = (char*)&l;
+    for (int i = 7; i >= 0; i--) {
+        pc.putc(l_array[i]);
+    }
+}
+
+void send_int(int integer) {
+    char* i_array = (char*)&integer;
+    for (int i = 3; i >= 0; i--) {
+        pc.putc(i_array[i]);
+    }
+}
+
+void send_us(unsigned short us) {
+    char* us_array = (char*)&us;
+    pc.putc(us_array[1]);
+    pc.putc(us_array[0]);
+}
 
 void systick() {
-    if (tick_count % 10 == 0) {
-        redled = true;
+    //if (tick_count % 20000 == 0) {
+    if (tick_count % 10000 == 0) {
+        //redled = false;
         // set the pulse high for 100ms, .1 s        
         // toggle a led
-        pulse_value = true;
+        pulse_value = false;
         myled = pulse_value;
+        hundms_pulse_pin = false;
         
         // get data from the (2) light sensor (3) analog pin
-        let_there_be_light = my_light_sensor.read();
-        my_analog_value = my_analog_pin.read();
+        //let_there_be_light = my_light_sensor.read();
+        unsigned short light_val = my_light_sensor.read_u16();
+        light_sensor_buffer.write(light_val);
+        //my_analog_value = my_analog_pin.read();
             
         // print the analog values to uart
         //pc.printf("%f,%f\r\n", let_there_be_light, my_analog_value);
@@ -44,16 +180,18 @@
         //lcd.display(1);
                 //wait_ms(100.0f);
     }
-    else if (tick_count % 10 == 1) {
-        redled = false;
+    //else if (tick_count % 20000 == 2000) {
+    else if (tick_count % 10000 == 1000) {
+        //redled = true;
         // set the pulse low for 900 ms, .9 s
         // toggle a led
-        pulse_value = false;
+        pulse_value = true;
         myled = pulse_value; // toggle a led
+        hundms_pulse_pin = true;
         
         // get data from the (2) light sensor (3) analog pin
-        let_there_be_light = my_light_sensor.read();
-        my_analog_value = my_analog_pin.read();
+        //let_there_be_light = my_light_sensor.read();
+        //my_analog_value = my_analog_pin.read();
         
         // print the analog values to uart
         //pc.printf("%f,%f\r\n", let_there_be_light, my_analog_value);
@@ -62,69 +200,303 @@
         //lcd.display(0);
                 //wait_ms(900.0f);
     }
-    else if (tick_count % 30 == 0) {
-        //pc.printf("\r\n\r\n GOT A STRING: %s\r\n\r\n", t1_string);
+    
+    if (sine_out_on == SINE_OUT_ON) {
+        sine_out_pin.write_u16(sine_table[sine_index]);
+        
+        switch (sine_out_frequency) {
+            case SINE_OUT_FREQ_1HZ:
+                // every 10 ticks, increment sine_index
+                if (tick_count % 10 == 0) {
+                    sine_index += 1;
+                }
+                break;
+            case SINE_OUT_FREQ_10HZ:
+                sine_index += 1;
+                break;
+            case SINE_OUT_FREQ_100HZ:
+                sine_index += 10;
+                break;
+            case SINE_OUT_FREQ_1000HZ:
+                sine_index += 100;
+                break;
+        }
+        
+        // uncomment this for 50 us period
+        /*switch (sine_out_frequency) {
+            case SINE_OUT_FREQ_1HZ:
+                // every 10 ticks, increment sine_index
+                if (tick_count % 20 == 0) {
+                    sine_index += 1;
+                }
+                break;
+            case SINE_OUT_FREQ_10HZ:
+                if (tick_count % 2 == 0) {
+                    sine_index += 1;
+                }
+                break;
+            case SINE_OUT_FREQ_100HZ:
+                sine_index += 5;
+                break;
+            case SINE_OUT_FREQ_1000HZ:
+                sine_index += 50;
+                break;
+        }*/
+        
+        if (sine_index >= SINE_TABLE_SIZE) {
+            sine_index = 0;
+        }
+    }
+    else {
+        sine_out_pin.write_u16(0);
+    }
+    
+    switch (adc_sampling_frequency) {
+        case ADC_SAMP_FREQ_1HZ:
+            if (tick_count % 10000 == 0) {
+                //read_adc();
+                adc_buffer.write(my_analog_pin.read_u16());
+            }
+            break;
+        case ADC_SAMP_FREQ_10HZ:
+            if (tick_count % 1000 == 0) {
+                //read_adc();
+                adc_buffer.write(my_analog_pin.read_u16());
+            }
+            break;
+        case ADC_SAMP_FREQ_100HZ:
+            if (tick_count % 100 == 0) {
+                //read_adc();
+                adc_buffer.write(my_analog_pin.read_u16());
+            }
+            break;
+        case ADC_SAMP_FREQ_OFF:
+            // do nothing
+            break;
+    }
+    
+    if (d_out_on == D_OUT_ON) {
+        d_out_pin = false;
+    }
+    else {
+        d_out_pin = true;
     }
+    
+    
+    if (tick_count % 100 == 0) {
+        // update the display every 10 ms
+        long long time_us = ((long long) timer.read_us()) - offset;
+        int time_s = (int) (time_us / 1000000);
+        int time_m = time_s / 60;
+        
+        int display_time = (time_m % 60) * 100 + (time_s % 60);
+        //lcd.display(display_time);
+        //lcd.putc('1');
+        int display_time_ones = display_time % 10;
+        int display_time_tens = (display_time / 10) % 10;
+        int display_time_hund = (display_time / 100) % 10;
+        int display_time_thou = (display_time / 1000) % 10;
+        lcd.putc('0' + display_time_thou);
+        lcd.putc('0' + display_time_hund);
+        lcd.putc('0' + display_time_tens);
+        lcd.putc('0' + display_time_ones);
+    }
+    
     tick_count++;
 }
 
+void send_light_sensor_data() {
+    light_sensor_buffer.swapBuff();
+    unsigned short* sensor_data = light_sensor_buffer.getReadBuffer();
+    int sensor_data_size = light_sensor_buffer.getReadBufferSize();
+    
+    // send header
+    pc.putc('l');
+    send_int(sensor_data_size);
+    
+    for (int i = 0; i < sensor_data_size; i++) {
+        send_us(sensor_data[i]);
+    }
+}
+
+void send_adc_data() {
+    adc_buffer.swapBuff();
+    unsigned short* adc_data = adc_buffer.getReadBuffer();
+    int adc_data_size = adc_buffer.getReadBufferSize();
+    
+    // send header
+    pc.putc('a');
+    send_int(adc_data_size);
+    
+    for (int i = 0; i < adc_data_size; i++) {
+        send_us(adc_data[i]);
+    }
+}
+
+void send_timestamp_event_data() {
+    d_event_buffer.swapBuff();
+    unsigned long long* timestamp_data = d_event_buffer.getReadBuffer();
+    int timestamp_data_size = d_event_buffer.getReadBufferSize();
+    
+    pc.putc('d');
+    send_int(timestamp_data_size);
+    
+    for (int i = 0; i < timestamp_data_size; i++) {
+        //unsigned long long ts = timestamp_data[i];
+        //unsigned int msbs = ((unsigned int) (ts >> 32) & 0xffffffff);
+        //unsigned int lsbs = ((unsigned int) ts & 0xffffffff);
+        send_ull(timestamp_data[i]);
+    }
+}
+
+void systick_attach() {
+    tick_count = 0;
+    sine_index = 0;
+    //ticker.attach_us(&systick, 100000);
+    ticker.attach_us(&systick, 100);
+}
+
+void d_event(){
+    // take timestamp, send it to thingspeak later
+    unsigned long long ts = timer.read_us();
+    d_event_buffer.write(ts);
+}
+
+unsigned long long sync_timestamp;
+
+// take a timestamp, save it in a global if it was an 's' character
+void rx_sync_interrupt(MODSERIAL_IRQ_INFO *q) {
+    sync_timestamp = timer.read_us();
+    
+    
+}
+
 int main()
-{   
+{  
+    redled = true; 
     timer.start();
     //initialize hardware
-    ticker.attach_us(&systick, 100000);
-    pc.baud(115200);
-   
+    systick_attach();
+    d_event_pin.rise(&d_event);
+    pc.baud(57600);
+    
+    // set our interrupt to occur on receiving the sync packet
+    pc.attach(&rx_sync_interrupt, MODSERIAL::RxAutoDetect);
+    pc.autoDetectChar('s');
+    
+    // lower the priority of the systick, since it might interfere with our timestamping
+    NVIC_SetPriority(LPTimer_IRQn, 255);
     
     t1_string[30] = '\0';
     
-    //we start the program
-    pc.printf("Hello World!\n");
+    int i = 0;
     
     while (true) 
     {
+        redled = false;
         char c = pc.getc();
-        t2 = timer.read_us();
+        //redled = true;
+        //pc.printf("got a char %c\r\n", c);
+        //t2 = timer.read_us();
+        t2 = sync_timestamp;
         // make sure we've gotten an 's', which we are using as
         // the sync message. If we get an 's' then t2 is correct.
         if (c != 's') {
             continue;
         }
-        while (c != '\n') {
-            if (i == 30) {
-                break;
-            }
+        //pc.printf("got s\r\n");
+        
+        // we can drop the 's'
+        c = pc.getc();
+        i = 0;
+        while (c != '\n' && i < 30) {
             t1_string[i] = c;
             c = pc.getc();
             i++;
         }
         t1_string[i] = '\0';
         i = 0;
-        char display_time[5];
-        display_time[0] = t1_string[4];
-        display_time[1] = t1_string[5];
-        display_time[2] = t1_string[7];
-        display_time[3] = t1_string[8];
-        display_time[4] = '\0';
-        int display_time_int = atoi(display_time);
-        lcd.display(display_time_int);
-        //lcd.display(t1_string[7]);
-        read_complete = true;
+        
+        
+        
+        //char display_time[5];
+        //display_time[0] = t1_string[3];
+        //display_time[1] = t1_string[4];
+        //display_time[2] = t1_string[6];
+        //display_time[3] = t1_string[7];
+        //display_time[4] = '\0';
+        //int display_time_int = atoi(display_time);
+        //lcd.display(display_time_int);
+        //read_complete = true;
         
         t3 = timer.read_us();
         // sending the delay_req message at time t3
         pc.putc('r');
         
         // get the t4 packet
-        while (c != '\n') {
-            if (i == 30) {
-                break;
-            }
+        c = pc.getc();
+        i = 0;
+        while (c != '\n' && i < 30) {
             t4_string[i] = c;
             c = pc.getc();
             i++;
         }
         t4_string[i] = '\0';
         i = 0;
+        
+        //pc.printf("t4str:  %s\n", t4_string);
+        
+        /*if (t4 == 0) {
+            pc.printf("t4 is zero\n");
+        }
+        else {
+            pc.printf("t4 is not zero\n");
+        }*/
+        
+        //pc.printf("t4: %lld\n", t4);
+        //lcd.display(7);
+        //lcd.display(sizeof(long long) * 100 + sizeof(long));
+        pc.printf("t1_string: %s t2: %d t3: %d t4_string: %s\n", t1_string, t2, t3, t4_string);
+        
+        long long t1 = atoll(t1_string);
+        long long t4 = atoll(t4_string);
+        pc.printf("t1: %lld t2: %d t3: %d t4: %lld\n", t1, t2, t3, t4);
+        offset = (((long long) t2 - t1) - (t4 - (long long) t3)) / 2;
+        pc.printf("offset: %lld\n", offset);
+        
+        //pc.printf("offset: %lld\n", offset);
+
+        long long time_us = ((long long) timer.read_us()) - offset;
+        long long time_s = time_us / 1000000;
+        long long time_m = time_s / 60;
+        long long time_h = time_m / 60;
+        pc.printf("time: %lld:%lld:%lld:%lld\n",  time_h % 24, time_m % 60, time_s % 60, time_us % 1000000);
+        
+        
+        // detach the systick, then reattach at the right time
+        /*long long time_us_roundup = (time_s + 1) * 1000000;
+        while((timer.read_us() - offset) < time_us_roundup) {
+            // wait until the next second
+        }
+        ticker.detach();
+        systick_attach();*/
+        
+        /*char onoff = pc.getc();
+        switch(onoff) {
+            case 'a':
+                redled = false;
+                break;
+            case 'b':
+                redled = true;
+                break;
+        }*/
+        
+        char opts = pc.getc();
+        set_options(opts);
+        
+        // send adc data, timestamp event data, light sensor data
+        send_adc_data();
+        send_light_sensor_data();
+        send_timestamp_event_data();   
     }
 }