Analog to digital conversion. Reads voltage and prints it in the terminal. Switches on/off the leads depending on the voltage threashold. Uses button for voltage callibration.
Fork of ADCandticker_sample by
Revision 2:26893e7c0068, committed 2018-02-09
- Comitter:
- natgovor
- Date:
- Fri Feb 09 16:31:44 2018 +0000
- Parent:
- 1:126dd2f5fc2d
- Commit message:
- Analog to digital conversion. Reads voltage and displays it in the terminal.
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r 126dd2f5fc2d -r 26893e7c0068 main.cpp --- a/main.cpp Wed Jan 24 21:55:43 2018 +0000 +++ b/main.cpp Fri Feb 09 16:31:44 2018 +0000 @@ -7,13 +7,22 @@ Ticker tick; // Ticker for reading analog AnalogIn ain(A0) ; // Analog input -DigitalOut led1(LED_RED); // Red LED + +const int states_number = 6; // number of leds + 1 +DigitalOut leds[5] = { PTA13, PTD5, PTD0, PTD2, PTD3 }; + +// button setup +DigitalIn button(PTE1, PullUp); +enum buttonPos { up, down, bounce }; // Button positions +buttonPos pos = up ; +int bcounter = 0 ; Serial pc(USBTX, USBRX); // tx, rx, for debugging // Message type typedef struct { uint16_t analog; /* Analog input value */ + bool buttonPressed; } message_t; // Mail box @@ -24,7 +33,33 @@ // Every 10th value is sent to mailbox volatile int samples = 0 ; volatile uint16_t smoothed = 0 ; +volatile bool pressEvent = false; void readA0() { + // Check button state + switch (pos) { + case up : + if (!button.read()) { // now down + pressEvent = true; + pos = down ; + } + break ; + case down : + if (button == 1) { // no longer down + bcounter = 3 ; // wait four cycles + pos = bounce ; + } + break ; + case bounce : + if (button == 0) { // down again - button has bounced + pos = down ; // no event + } else if (bcounter == 0) { + pos = up ; // delay passed - reset to up + } else { + bcounter-- ; // continue waiting + } + break ; + } + smoothed = (smoothed >> 1) + (ain.read_u16() >> 1) ; samples++ ; if (samples == 10) { @@ -32,9 +67,11 @@ message_t *mess = mailbox.alloc() ; // may fail but does not block if (mess) { mess->analog = smoothed ; + mess->buttonPressed = pressEvent; mailbox.put(mess); // fails but does not block if full } samples = 0; + pressEvent = false; } } @@ -48,25 +85,69 @@ s[0] = '0' + (v % 10) ; } +void lightLeds(int threshold_index) { + int leds_number = states_number - 1; + for (int i=0; i<leds_number; i++) { + if (i <= threshold_index - 1) { + leds[i] = 1; + } else { + leds[i] = 0; + } + } +} + +void calculate_thresholds(int max_voltage, int* threshold) { + int interval = max_voltage / states_number; + for (int i = 0; i < states_number; i++) { + if (i == 0) { + threshold[i] = interval; + } else { + threshold[i] = threshold[i-1] + interval; + } + } +} + // Main program // Initialise variables // Attach ISR for ticker // Procss messages from mailbox int main() { - led1 = 1 ; // turn off int volts = 0 ; - const int threshold = 100 ; int counter = 0 ; char vstring[] = "X.XX\r\n" ; + + //int max_voltage = 330; + int threshold[states_number]; + + calculate_thresholds(330, threshold); tick.attach_us(callback(&readA0), 10000); // ticks every 10ms while (true) { osEvent evt = mailbox.get(); // wait for mail if (evt.status == osEventMail) { message_t* mess = (message_t*)evt.value.p ; + bool pressEvent = mess->buttonPressed; + if (pressEvent) { + // recalculate treshold + calculate_thresholds(volts, threshold); + } volts = (mess->analog * 330) / 0xffff ; mailbox.free(mess) ; // free the message space - if (volts > threshold) led1 = 0 ; else led1 = 1 ; + + if (volts < threshold[0]) { + lightLeds(0); + } else if (volts > threshold[0] && volts < threshold[1]) { + lightLeds(1); + } else if (volts > threshold[1] && volts < threshold[2]) { + lightLeds(2); + } else if (volts > threshold[2] && volts < threshold[3]) { + lightLeds(3); + } else if (volts > threshold[3] && volts < threshold[4]) { + lightLeds(4); + } else if (volts > threshold[4]) { + lightLeds(5); + } + vToString(volts, vstring) ; counter++ ; if (counter == 10) { // limit bandwidth of serial