This program is an advanced "IoT" thermometer using LM75B component library. It displays the current value to the Serial host in Celcius or Fahrenheit (possible to change using a switch). It also stores an historic and displays it to the user using the LCD screen. Moreover, you can change the orientation of the screen by turning the device, just like a smartphone.
Dependencies: C12832 FXOS8700CQ LM75B mbed
main.cpp
- Committer:
- co838_gtvl2
- Date:
- 2016-02-22
- Revision:
- 6:6c61186c8739
- Parent:
- 5:c5d7fca4d111
- Child:
- 7:e5732637dfd0
File content as of revision 6:6c61186c8739:
/** * This program is an advanced "IoT" thermometer using LM75B component library. * It displays the current value to the Serial host in Celcius or Fahrenheit. * It is possible to change units using SW2 switch or computer's 'c' and 'f' keys. * It also stores a small historic and displays it to the user using the LCD screen. * Moreover, you can change the orientation of the screen by turning the device, just like a smartphone. * * Note that the use of printf in the Ticker or Timeout functions is properly done. * If _DEBUG is defined, it is possible to have a buffer conflict, but not if _DEBUG is undefined. * * * Created by Guillaume Lefrant gtvl2 **/ #include "main.h" #include "ThermalDisplayer.h" #include "MyTimeout.hpp" Serial pc(USBTX, USBRX); // Serial Host LM75B lm_temp(D14, D15); // Thermal Sensor InterruptIn sw2_int(SW2); // SW2 DigitalOut tilt_led(LED1); // Red LED DigitalOut r_led(PTA2); // RGB LED DigitalOut g_led(PTC4); DigitalOut b_led(PTC12); AnalogIn pot(A0); // Potentiometer POT1 MyTimeout process_timeout; // Main timeout used for the whole process volatile bool celcius = true; // Global boolean for unit Celcius / Fahrenheit volatile int refresh_time = 3000; ThermalDisplayer temp_display = ThermalDisplayer(); /* * SW2 handler */ void sw_interrupt(void) { celcius = !celcius; if (celcius) { r_led = 1.0; g_led = 1.0; b_led = 0.0; } else { r_led = 0.0; g_led = 1.0; b_led = 1.0; } } /* * Interrupt that does the same as above but using keyboard of host */ void host_interrupt(void) { #if defined _DEBUG pc.printf("Check if pc key as been pressed\r\n"); #endif if (pc.readable()) { char c = pc.getc(); switch(c) { case 'c': celcius = false; sw_interrupt(); break; case 'f': celcius = true; sw_interrupt(); break; default: break; } } } void process_function(void) { tilt_led = 0.0; // IMPORTANT. Check MyTimeout.hpp for details. process_timeout.detach(); /* * Get temperature using LM75B * and display it to LCD screen */ float temperature = lm_temp.read(); temp_display.addTemp(temperature); temp_display.adjustScale(); temp_display.display(); /* * Display value to host according to unit choosed with SW2. * Could have been a ternary, but it's easier to read like this. * In production (without _DEBUG), this is the only printf executed. */ if (pc.writeable()) { if (celcius) { pc.printf("Temp: %.2f deg Celcius.\r\n", temperature); } else { pc.printf("Temp: %.2f deg Fahrenheit.\r\n", (temperature * 1.8f + 32.0f)); } } /* * Change refresh_time according to POT1's value */ refresh_time = (int) (MIN_REFRESH_TIME + ((1.0f - pot) * (MAX_REFRESH_TIME - MIN_REFRESH_TIME))); tilt_led = 1.0; } int main(void) { pc.baud(38400); if (pc.writeable()) { pc.printf("Hello gtvl2, from FRDM-K64F!\r\nUse POT1 to change the refresh rate, POT2 to change the scale of the graphic and SW2 or keyboard to change the unit.\r\n"); } /* * Thermal unit control */ sw2_int.mode(PullUp); sw2_int.fall(&sw_interrupt); pc.attach(&host_interrupt); r_led = 1.0; g_led = 1.0; b_led = 0.0; // Do once process_function(); wait_ms(1); // Then forever while (true) { if (!process_timeout.hasAttachment()) { #if defined _DEBUG pc.printf("Next value in %.3f seconds\r\n", refresh_time / 1000.0f); #endif process_timeout.attach_us(&process_function, (float) refresh_time * 1000.0f); } #if defined _DEBUG else { pc.printf("Won't attach again the timer.\r\n"); } #endif sleep(); } }