Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MODSERIALhacked Convert SLCD mbed-src
main.cpp
- Committer:
- jhaugen
- Date:
- 2014-12-17
- Revision:
- 8:a44d03ecc942
- Parent:
- 7:c81c6968f013
- Child:
- 10:cfd3decff616
File content as of revision 8:a44d03ecc942:
#include "mbed.h"
#include "convert.h"
#include "double_buffer.h"
#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;
char t1_string[31];
char t4_string[31];
int t2;
int t3;
//int i = 0;
bool pulse_value = false;
//float let_there_be_light = 0.0;
//float my_analog_value = 0.0;
Convert lcd;
//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 % 20000 == 0) {
if (tick_count % 10000 == 0) {
//redled = false;
// set the pulse high for 100ms, .1 s
// toggle a led
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();
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);
// display 1
//lcd.display(1);
//wait_ms(100.0f);
}
//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 = 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();
// print the analog values to uart
//pc.printf("%f,%f\r\n", let_there_be_light, my_analog_value);
// display 0
//lcd.display(0);
//wait_ms(900.0f);
}
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
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';
int i = 0;
while (true)
{
redled = false;
char c = pc.getc();
//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;
}
//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[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
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();
}
}
