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

Committer:
co838_gtvl2
Date:
Tue Feb 23 18:13:35 2016 +0000
Revision:
8:6f30f477fa23
Parent:
7:e5732637dfd0
V1.0.1; Updated init of variables and LEDs; Removed unused file

Who changed what in which revision?

UserRevisionLine numberNew contents of line
co838_gtvl2 4:5bf99eb2d740 1 /**
co838_gtvl2 4:5bf99eb2d740 2 * This program is an advanced "IoT" thermometer using LM75B component library.
co838_gtvl2 7:e5732637dfd0 3 * It displays the current value to the Serial host in Celcius (BLUE) or Fahrenheit (GREEN).
co838_gtvl2 6:6c61186c8739 4 * It is possible to change units using SW2 switch or computer's 'c' and 'f' keys.
co838_gtvl2 7:e5732637dfd0 5 * You can use SW3 to pause/resume to data collection or computer's 'p' key.
co838_gtvl2 6:6c61186c8739 6 * It also stores a small historic and displays it to the user using the LCD screen.
co838_gtvl2 6:6c61186c8739 7 * Moreover, you can change the orientation of the screen by turning the device, just like a smartphone.
co838_gtvl2 6:6c61186c8739 8 *
co838_gtvl2 6:6c61186c8739 9 * Note that the use of printf in the Ticker or Timeout functions is properly done.
co838_gtvl2 6:6c61186c8739 10 * If _DEBUG is defined, it is possible to have a buffer conflict, but not if _DEBUG is undefined.
co838_gtvl2 6:6c61186c8739 11 *
co838_gtvl2 4:5bf99eb2d740 12 *
co838_gtvl2 4:5bf99eb2d740 13 * Created by Guillaume Lefrant gtvl2
co838_gtvl2 4:5bf99eb2d740 14 **/
co838_gtvl2 4:5bf99eb2d740 15
co838_gtvl2 1:06713d1b69cf 16 #include "main.h"
co838_gtvl2 1:06713d1b69cf 17 #include "ThermalDisplayer.h"
co838_gtvl2 6:6c61186c8739 18 #include "MyTimeout.hpp"
co838_gtvl2 0:362773c24009 19
co838_gtvl2 6:6c61186c8739 20 Serial pc(USBTX, USBRX); // Serial Host
co838_gtvl2 7:e5732637dfd0 21 LM75B lm_temp(D14, D15); // Temperature Sensor
co838_gtvl2 6:6c61186c8739 22 InterruptIn sw2_int(SW2); // SW2
co838_gtvl2 7:e5732637dfd0 23 InterruptIn sw3_int(SW3); // SW3
co838_gtvl2 6:6c61186c8739 24 DigitalOut tilt_led(LED1); // Red LED
co838_gtvl2 6:6c61186c8739 25 DigitalOut r_led(PTA2); // RGB LED
co838_gtvl2 6:6c61186c8739 26 DigitalOut g_led(PTC4);
co838_gtvl2 6:6c61186c8739 27 DigitalOut b_led(PTC12);
co838_gtvl2 6:6c61186c8739 28 AnalogIn pot(A0); // Potentiometer POT1
co838_gtvl2 6:6c61186c8739 29 MyTimeout process_timeout; // Main timeout used for the whole process
co838_gtvl2 0:362773c24009 30
co838_gtvl2 7:e5732637dfd0 31 volatile bool celcius; // Global boolean for unit Celcius / Fahrenheit
co838_gtvl2 7:e5732637dfd0 32 volatile bool running; // Either the program is running or paused
co838_gtvl2 6:6c61186c8739 33 volatile int refresh_time = 3000;
co838_gtvl2 6:6c61186c8739 34
co838_gtvl2 6:6c61186c8739 35 ThermalDisplayer temp_display = ThermalDisplayer();
co838_gtvl2 0:362773c24009 36
co838_gtvl2 1:06713d1b69cf 37 /*
co838_gtvl2 6:6c61186c8739 38 * SW2 handler
co838_gtvl2 7:e5732637dfd0 39 * Changes the unit and adapts LED to the new one.
co838_gtvl2 1:06713d1b69cf 40 */
co838_gtvl2 7:e5732637dfd0 41 void sw2_interrupt(void)
co838_gtvl2 2:5d0c209e5c61 42 {
co838_gtvl2 6:6c61186c8739 43 celcius = !celcius;
co838_gtvl2 6:6c61186c8739 44
co838_gtvl2 8:6f30f477fa23 45 if (running) {
co838_gtvl2 8:6f30f477fa23 46 if (celcius) {
co838_gtvl2 8:6f30f477fa23 47 r_led = 1.0;
co838_gtvl2 8:6f30f477fa23 48 g_led = 1.0;
co838_gtvl2 8:6f30f477fa23 49 b_led = 0.0;
co838_gtvl2 8:6f30f477fa23 50 } else {
co838_gtvl2 8:6f30f477fa23 51 r_led = 1.0;
co838_gtvl2 8:6f30f477fa23 52 g_led = 0.0;
co838_gtvl2 8:6f30f477fa23 53 b_led = 1.0;
co838_gtvl2 8:6f30f477fa23 54 }
co838_gtvl2 2:5d0c209e5c61 55 }
co838_gtvl2 0:362773c24009 56 }
co838_gtvl2 0:362773c24009 57
co838_gtvl2 1:06713d1b69cf 58 /*
co838_gtvl2 7:e5732637dfd0 59 * SW3 handler
co838_gtvl2 7:e5732637dfd0 60 * Used to pause / resume the data collection and display.
co838_gtvl2 7:e5732637dfd0 61 */
co838_gtvl2 7:e5732637dfd0 62 void sw3_interrupt(void)
co838_gtvl2 7:e5732637dfd0 63 {
co838_gtvl2 7:e5732637dfd0 64 running = !running;
co838_gtvl2 7:e5732637dfd0 65 if (!running) {
co838_gtvl2 7:e5732637dfd0 66 process_timeout.detach();
co838_gtvl2 7:e5732637dfd0 67 r_led = 0.0;
co838_gtvl2 7:e5732637dfd0 68 g_led = 1.0;
co838_gtvl2 7:e5732637dfd0 69 b_led = 1.0;
co838_gtvl2 7:e5732637dfd0 70 } else {
co838_gtvl2 7:e5732637dfd0 71 celcius = !celcius;
co838_gtvl2 7:e5732637dfd0 72 sw2_interrupt();
co838_gtvl2 7:e5732637dfd0 73 }
co838_gtvl2 7:e5732637dfd0 74 }
co838_gtvl2 7:e5732637dfd0 75
co838_gtvl2 7:e5732637dfd0 76 /*
co838_gtvl2 7:e5732637dfd0 77 * Interrupt that does the same as SW2 handler above but using keyboard of host
co838_gtvl2 1:06713d1b69cf 78 */
co838_gtvl2 6:6c61186c8739 79 void host_interrupt(void)
co838_gtvl2 5:c5d7fca4d111 80 {
co838_gtvl2 6:6c61186c8739 81 if (pc.readable()) {
co838_gtvl2 7:e5732637dfd0 82 switch(pc.getc()) {
co838_gtvl2 6:6c61186c8739 83 case 'c':
co838_gtvl2 6:6c61186c8739 84 celcius = false;
co838_gtvl2 7:e5732637dfd0 85 sw2_interrupt();
co838_gtvl2 6:6c61186c8739 86 break;
co838_gtvl2 6:6c61186c8739 87 case 'f':
co838_gtvl2 6:6c61186c8739 88 celcius = true;
co838_gtvl2 7:e5732637dfd0 89 sw2_interrupt();
co838_gtvl2 7:e5732637dfd0 90 break;
co838_gtvl2 7:e5732637dfd0 91 case 'p':
co838_gtvl2 7:e5732637dfd0 92 sw3_interrupt();
co838_gtvl2 6:6c61186c8739 93 break;
co838_gtvl2 6:6c61186c8739 94 default:
co838_gtvl2 6:6c61186c8739 95 break;
co838_gtvl2 5:c5d7fca4d111 96 }
co838_gtvl2 5:c5d7fca4d111 97 }
co838_gtvl2 5:c5d7fca4d111 98 }
co838_gtvl2 5:c5d7fca4d111 99
co838_gtvl2 6:6c61186c8739 100 void process_function(void)
co838_gtvl2 2:5d0c209e5c61 101 {
co838_gtvl2 6:6c61186c8739 102 tilt_led = 0.0;
co838_gtvl2 6:6c61186c8739 103 // IMPORTANT. Check MyTimeout.hpp for details.
co838_gtvl2 6:6c61186c8739 104 process_timeout.detach();
co838_gtvl2 6:6c61186c8739 105
co838_gtvl2 6:6c61186c8739 106 /*
co838_gtvl2 6:6c61186c8739 107 * Get temperature using LM75B
co838_gtvl2 6:6c61186c8739 108 * and display it to LCD screen
co838_gtvl2 6:6c61186c8739 109 */
co838_gtvl2 6:6c61186c8739 110 float temperature = lm_temp.read();
co838_gtvl2 6:6c61186c8739 111 temp_display.addTemp(temperature);
co838_gtvl2 6:6c61186c8739 112 temp_display.adjustScale();
co838_gtvl2 6:6c61186c8739 113 temp_display.display();
co838_gtvl2 6:6c61186c8739 114
co838_gtvl2 6:6c61186c8739 115
co838_gtvl2 6:6c61186c8739 116 /*
co838_gtvl2 6:6c61186c8739 117 * Display value to host according to unit choosed with SW2.
co838_gtvl2 6:6c61186c8739 118 * Could have been a ternary, but it's easier to read like this.
co838_gtvl2 6:6c61186c8739 119 * In production (without _DEBUG), this is the only printf executed.
co838_gtvl2 6:6c61186c8739 120 */
co838_gtvl2 6:6c61186c8739 121 if (pc.writeable()) {
co838_gtvl2 6:6c61186c8739 122 if (celcius) {
co838_gtvl2 6:6c61186c8739 123 pc.printf("Temp: %.2f deg Celcius.\r\n", temperature);
co838_gtvl2 6:6c61186c8739 124 } else {
co838_gtvl2 6:6c61186c8739 125 pc.printf("Temp: %.2f deg Fahrenheit.\r\n", (temperature * 1.8f + 32.0f));
co838_gtvl2 6:6c61186c8739 126 }
co838_gtvl2 5:c5d7fca4d111 127 }
co838_gtvl2 2:5d0c209e5c61 128
co838_gtvl2 6:6c61186c8739 129 /*
co838_gtvl2 6:6c61186c8739 130 * Change refresh_time according to POT1's value
co838_gtvl2 6:6c61186c8739 131 */
co838_gtvl2 6:6c61186c8739 132 refresh_time = (int) (MIN_REFRESH_TIME + ((1.0f - pot) * (MAX_REFRESH_TIME - MIN_REFRESH_TIME)));
co838_gtvl2 6:6c61186c8739 133 tilt_led = 1.0;
co838_gtvl2 6:6c61186c8739 134 }
co838_gtvl2 2:5d0c209e5c61 135
co838_gtvl2 6:6c61186c8739 136 int main(void)
co838_gtvl2 6:6c61186c8739 137 {
co838_gtvl2 6:6c61186c8739 138 pc.baud(38400);
co838_gtvl2 6:6c61186c8739 139 if (pc.writeable()) {
co838_gtvl2 7:e5732637dfd0 140 pc.printf("Hello gtvl2, from FRDM-K64F!\r\nUse POT1 to change the refresh rate, POT2 to change the scale of the graphic, SW2 or keyboard to change the unit and SW3 to pause.\r\n");
co838_gtvl2 6:6c61186c8739 141 }
co838_gtvl2 2:5d0c209e5c61 142
co838_gtvl2 8:6f30f477fa23 143 // Initialize control interrupts
co838_gtvl2 0:362773c24009 144 sw2_int.mode(PullUp);
co838_gtvl2 7:e5732637dfd0 145 sw2_int.fall(&sw2_interrupt);
co838_gtvl2 7:e5732637dfd0 146 sw3_int.mode(PullUp);
co838_gtvl2 7:e5732637dfd0 147 sw3_int.fall(&sw3_interrupt);
co838_gtvl2 8:6f30f477fa23 148 pc.attach(&host_interrupt);
co838_gtvl2 8:6f30f477fa23 149
co838_gtvl2 8:6f30f477fa23 150 // Initialize variables and LEDs
co838_gtvl2 8:6f30f477fa23 151 running = false;
co838_gtvl2 7:e5732637dfd0 152 celcius = true;
co838_gtvl2 8:6f30f477fa23 153 sw3_interrupt();
co838_gtvl2 2:5d0c209e5c61 154
co838_gtvl2 6:6c61186c8739 155 // Do once
co838_gtvl2 6:6c61186c8739 156 process_function();
co838_gtvl2 6:6c61186c8739 157 wait_ms(1);
co838_gtvl2 6:6c61186c8739 158 // Then forever
co838_gtvl2 6:6c61186c8739 159 while (true) {
co838_gtvl2 7:e5732637dfd0 160 if (running && !process_timeout.hasAttachment()) {
co838_gtvl2 6:6c61186c8739 161 #if defined _DEBUG
co838_gtvl2 7:e5732637dfd0 162 pc.printf("Next cycle in %.3f seconds\r\n", refresh_time / 1000.0f);
co838_gtvl2 6:6c61186c8739 163 #endif
co838_gtvl2 6:6c61186c8739 164 process_timeout.attach_us(&process_function, (float) refresh_time * 1000.0f);
co838_gtvl2 0:362773c24009 165 }
co838_gtvl2 6:6c61186c8739 166 #if defined _DEBUG
co838_gtvl2 6:6c61186c8739 167 else {
co838_gtvl2 6:6c61186c8739 168 pc.printf("Won't attach again the timer.\r\n");
co838_gtvl2 6:6c61186c8739 169 }
co838_gtvl2 6:6c61186c8739 170 #endif
co838_gtvl2 6:6c61186c8739 171 sleep();
co838_gtvl2 0:362773c24009 172 }
co838_gtvl2 0:362773c24009 173 }