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

Revision:
6:6c61186c8739
Parent:
5:c5d7fca4d111
Child:
7:e5732637dfd0
--- a/main.cpp	Fri Feb 12 09:45:41 2016 +0000
+++ b/main.cpp	Mon Feb 22 19:09:17 2016 +0000
@@ -1,32 +1,43 @@
 /**
  *  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 or computer's 'c' and 'f').
- *  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)
+ *  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 host(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
+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
 
-Ticker rgb_tick;                // Ticker for RGB LED control
-volatile bool celcius = true;   // Global boolean for unit Celcius / Fahrenheit
+volatile bool       celcius = true;             // Global boolean for unit Celcius / Fahrenheit
+volatile int        refresh_time = 3000;
+
+ThermalDisplayer    temp_display = ThermalDisplayer();
 
 /*
- *  RGB LED control
+ *  SW2 handler
  */
-void rgb_handler(void)
+void                sw_interrupt(void)
 {
+    celcius = !celcius;
+
     if (celcius) {
         r_led = 1.0;
         g_led = 1.0;
@@ -39,88 +50,100 @@
 }
 
 /*
- *  SW2 handler
+ *  Interrupt that does the same as above but using keyboard of host
  */
-void sw_handler (void)
-{
-    celcius = !celcius;
-}
-
-/*
- *  Thread that does the same as above
- */
-void host_thread(void const *args)
+void                host_interrupt(void)
 {
-    while (true) {
-        if (host.readable()) {
-            switch(host.getc()) {
-                case 'c':
-                    celcius = true;
-                    break;
-                case 'f':
-                    celcius = false;
-                    break;
-                default:
-                    break;
-            }
+#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;
         }
-        Thread::wait(500);
     }
 }
 
-int main(void)
+void                process_function(void)
 {
-    host.baud(38400);
-    if (host.writeable()) {
-        host.printf("Hello gtvl2, from FRDM-K64F!\r\nUse POT1 to change the refresh rate, POT2 to change the scale of the graphic and SW2 to change the unit.\r\n");
+    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));
+        }
     }
 
-    tilt_led = 0.0;
-    r_led = 1.0;
-    g_led = 0.0;
-    b_led = 1.0;
+    /*
+     * 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 refresh_time = 3000;
+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
      */
-    ThermalDisplayer *temp_display = new ThermalDisplayer();
-    rgb_tick.attach(&rgb_handler, 0.001);
     sw2_int.mode(PullUp);
-    sw2_int.fall(&sw_handler);
-    if (host.readable()) {
-        Thread thread(host_thread);
-    }
+    sw2_int.fall(&sw_interrupt);
+    pc.attach(&host_interrupt);
 
-    while (true) {
-        tilt_led = 0.0;
-        /*
-         * Get temperature using LM75B
-         * and display it to LCD screen
-         */
-        float temperature = lm_temp.read();
-        temp_display->addTemp(temperature);
-        temp_display->adjustScale(host);
-        temp_display->display();
+    r_led = 1.0;
+    g_led = 1.0;
+    b_led = 0.0;
 
-        /*
-         * Display value to host according to unit choosed with SW2.
-         * Could have been a ternary, but it's easier to read like this
-         */
-        if (host.writeable()) {
-            if (celcius) {
-                host.printf("Temp: %.2f deg Celcius.\r\n", temperature);
-            } else {
-                host.printf("Temp: %.2f deg Fahrenheit.\r\n", (temperature * 1.8f + 32.0f));
-            }
+    // 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);
         }
-        
-        /*
-         * Change refresh_time according to POT1's value
-         */
-        tilt_led = 1.0;
-        refresh_time = (int) (MIN_REFRESH_TIME + ((1.0f - pot) * (MAX_REFRESH_TIME - MIN_REFRESH_TIME)));
-        Thread::wait(refresh_time);
+#if defined _DEBUG
+        else {
+            pc.printf("Won't attach again the timer.\r\n");
+        }
+#endif
+        sleep();
     }
 }
\ No newline at end of file