From aec88f85c7f7fb5a2acdf35ac34e1d14c210761d Mon Sep 17 00:00:00 2001 From: Aaron Date: Mon, 8 Jun 2020 13:52:50 +0200 Subject: [PATCH] add sketch --- lib/LCD03 | 1 + src/sketch.ino | 199 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 200 insertions(+) create mode 160000 lib/LCD03 create mode 100644 src/sketch.ino diff --git a/lib/LCD03 b/lib/LCD03 new file mode 160000 index 0000000..3739f8f --- /dev/null +++ b/lib/LCD03 @@ -0,0 +1 @@ +Subproject commit 3739f8f176ccf8ba1efaac59d801ceb6043a917c diff --git a/src/sketch.ino b/src/sketch.ino new file mode 100644 index 0000000..22ef9f1 --- /dev/null +++ b/src/sketch.ino @@ -0,0 +1,199 @@ +#include +#include + +#define F_TIMER 1000000 // timer base frequency 10ms +#define AVG_INT 2000 // main interval 2s (2000 * timeroverflow_time) +#define FIFO_SIZE 20 // maximum number of values in the fifo + +LCD03 lcd; // LCD object + +// operational vars +int i = 0; +volatile long cnt = 0; // counter +volatile int interval = 0; // freq of std deviation calc +volatile int timer_0_overflows = 0; // milliseconds +volatile float t_diff = 0; // time difference +volatile bool flag_timer = false; // timer flag +volatile bool flag_send = false; // send flag + +// vars for statistics +volatile float t_fifo[FIFO_SIZE]; +volatile int nfifo = 0; +volatile float average, variance, std_deviation, sum = 0, sum1 = 0; + +/* + * Calculate the std deviation within the fifo. + */ +void std_dev(void) +{ + sum = 0; + sum1 = 0; + + // sum of all elements + for(i = 0; i < FIFO_SIZE; i++){ + sum = sum + t_fifo[i]; + } + + // average + average = sum / FIFO_SIZE; + + // compute variance and std deviation + for(i = 0; i < FIFO_SIZE; i++){ + sum1 = sum1 + pow((t_fifo[i] - average), 2); + } + + variance = sum1 / FIFO_SIZE; + std_deviation = sqrt(variance); +} + +/* + * Push a value into the fifo. + */ +void push_fifo(float t) +{ + t_fifo[nfifo] = t; // push value t to fifo + nfifo = (nfifo + 1) % FIFO_SIZE; // increment fifo index within boundary +} + +/* + * Init the interrupt registers. + */ +void init_interrupt(void) +{ + EICRA = (1 << ISC01) | (1 << ISC00); // INT0 on rising edge + EIMSK = (1 << INT0); // enable INT0 + sei(); // enable the globald interrupt pin +} + +/* + * Init and start timer0 in CTC mode so it will overflow every 1ms. + */ +void start_timer() +{ + TCCR0A = (1< second bit of register + TCCR0B |= (1< third bit of register + OCR0A = 250-1; // set OCR0A = F_CPU/64/1ms^-1 + TIMSK0 |= (1<: "); + lcd.setCursor(4,0); + lcd.print(String(avg_time)); + + lcd.setCursor(0,1); + lcd.print("S: "); + lcd.setCursor(2,1); + lcd.print(String(stddev_time)); + + lcd.setCursor(8,1); + lcd.print("n:"); + lcd.setCursor(10,1); + lcd.print(String(number)); + + // Print data on serial interface (as csv) + Serial.print("AVG:" + String(avg_time)); + Serial.print(','); + Serial.print("STD:" + String(stddev_time)); + Serial.print("\r\n"); +} + +/* + * Interrupt service routine + * for the controllers INT0 pin + */ +ISR(INT0_vect) +{ + int tmp = 0; + cnt++; // increment counter + + if(!flag_send){ + flag_send = true; // set ouput flag + } + + if(!flag_timer){ + start_timer(); // start the timer + flag_timer = true; // set the timer flag + } + else{ + tmp = stop_timer(); // stop timer + + if(tmp <= 1000 && tmp >= 0){ // if the value is greater than 1s but not negative + t_diff = tmp; // write the timer value to t_diff + } + + start_timer(); // restart the timer + } +} + +/* + * Interrupt service routine + * for timer0, gets called each n miliseconds (see timer config) + */ +ISR(TIMER0_COMPA_vect) +{ + timer_0_overflows++; // increment overflows + interval++; // increment interval counter +} + +/* + * Initialize the system + */ +void setup() +{ + lcd.begin(16, 2); // set LCD as 16x2 screen + lcd.backlight(); // set backlight + + Serial.begin(9600); // init serial interface + + // initialize fifo with zeros + for(i = 0; i < FIFO_SIZE; i++){ + t_fifo[i] = 0; + } + + print_values(0,0,0); + flag_timer = false; + flag_send = false; + pinMode(5, OUTPUT); + + init_interrupt(); +} + +/* + * main + */ +void loop() +{ + // each 2 seconds + if(interval == AVG_INT){ + interval = 0; + std_dev(); // calculate stddev + push_fifo(0); // push a zero else the fifo never clears + print_values(average, std_deviation, cnt); // print values + } + + // if there are updated values + if(flag_send){ + flag_send = false; // reset send flag + push_fifo(t_diff); // update list for avg + } +}