My custom thermostat based on: # NUCLEO-F334R8 # DS18B20 # RELAY module # LCD1602 shield

Dependencies:   DS1820 TextLCD mbed

Revision:
0:2ae1c92f5fba
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Jan 17 03:26:10 2016 +0000
@@ -0,0 +1,640 @@
+/**
+
+Temperature control based on:
+    NUCLEO-F334R8 
+    DS18B20 
+    RELAY module 
+    LCD1602 shield
+
+By:       www.emcu.it
+Date:     Dec.2015
+Version:  1.2
+Name:     F334andDS18B20andLCD1602andRELAYdlyCasaV12
+NOTE:     For more info see here: http://www.emcu.it/Mbed/mBed.html#My_mBed_tutorials
+
+THE SOFTWARE AND HARDWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS 
+OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+UART Configuration (It is necessary for see the results, we suggest to use TeraTerm on PC)  
+    Baud Rate:    9600 
+    Data Bit:     8
+    Parity:       NONE
+    Stop Bit:     1
+    Flow Control: NONE
+    
+This SW is ready to use on the NUCLEO-F334R8.
+Connect to the NUCLEO-F334R8 the DS18B20 sensor (A1, see the schematic below), the LCD1602 board and a RELAY board (A5).
+The temperature sampling time is 200 msec, you change this parameter in the TempSamplingTime.
+
+ DS18B20 front view
+    __________
+   |          |
+   |    DS    |
+   |   18B20  |   
+   |          |
+   |__________|
+     |   |   |
+     1   2   3
+    GND  DQ VCC (5V)
+     |   |   |______________ to VCC (5V on the LCD1602 or on the NUCLEO-F334R8)  
+     |   |  _|_
+     |   |  | |
+     |   |  | | 4K7
+     |   |  | |
+     |   |  -|-
+     |   |___|______________ to A1 (on the LCD1602 board or on the NUCLEO-F334R8) 
+     |
+     |
+     |______________________ to GND (on the LCD1602 board or on the NUCLEO-F334R8)   
+
+This SW is just for only one DS18B20 + LCD1602 board
+
+*/
+
+
+// Below there is the Data Pin where is connected the: 
+// pin.2 (DQ) of the DS18B20 ---> A1
+#define DATA_PIN  A1
+
+#include "mbed.h"
+#include "DS1820.h"
+#include "TextLCD.h"
+
+// Define the LED
+DigitalOut myled(LED1);
+// Below there is the RELAY PIN that is ---> A5
+DigitalOut RL1(A5); 
+
+// Define the PC serial Port
+Serial pc(SERIAL_TX, SERIAL_RX);
+
+// Specify the pin of the NUCLEO-F334R8 where is connected 
+// the pin.2 (DQ) of the DS18B20.
+DS1820 probe(DATA_PIN);
+
+// SetUp GPIO for drive the LCD
+//  LCD (RS, E, D4, D5, D6, D7)
+TextLCD lcd(PA_9, PC_7, PB_5, PB_4, PB_10, PA_8); // LCD Shield for Arduino
+AnalogIn button(PA_0);  // board button
+PwmOut backlight(PB_6);
+
+// COSTANTs
+#define ON  1
+#define OFF 0
+#define YES 1
+#define NO  0
+#define tStep  0.1 // Step minimo di Up e Down x le impostazioni dei valori
+#define tUp    1
+#define tDown  2
+#define tRigth 3
+#define tLeft  4
+#define tNone  5
+#define NumConv 4
+#define MaxError 30
+#define TastoSU  15000
+#define TastoGIU 30900
+#define TastoDES DeltaTasti + 2
+#define TastoSIN 48000
+#define DeltaTasti 4000
+#define TempSamplingTime 200    // 200 == 200 mS
+#define DelayTime 4             // It is used in congiunction to DelayLastLine
+#define MaxRelDly 50            // 10 == 10sec... 50 == 50 sec
+
+// VARIABLEs
+uint8_t n = 0;
+uint8_t FlashSeg = 0;
+uint8_t FlashLCDlastLine = 0;
+uint8_t DelayLastLine = 0;
+uint8_t rele = OFF;
+uint8_t TowerTemp  = 0;
+uint8_t TlowerTemp = 0;
+float temperature = 0;
+float DeltaTemp = 0.5; 
+float tempON  = 21.00;
+float tempOFF = tempON + DeltaTemp;
+float temperaturePREVIOUS = 0;
+float temperatureMAX = 0;
+float temperatureMIN = 0;
+float MaxTempError = 0;
+unsigned long value = 0;
+uint8_t PowerON = YES;
+uint8_t LastButtonPressed = tNone;
+uint8_t DelayForOffOnRealy = 30;    /* The OFF will be made if the temperature is exceeded by N seconds consecutively (see TowerTemp)
+                                       The ON will be made if the temperature is less than N seconds consecutively (see TlowerTemp)
+                                       N = 30 value is about 30sec
+                                    */
+
+// FUNCTIONs
+void CalcMed(void);
+void PrintTemperatures(void);
+uint8_t ReadButtonOnLCD1602(void);
+void SetUp(void);
+void ShowSetUp(void);
+void WaitingRightButton(void);
+
+
+int main() 
+{
+    // Configure USART speed
+    pc.baud(9600);
+    
+    // SetUp the resolution of the DS18B20 to 12bit
+    probe.setResolution(12);
+    
+    // StartUp Logo to the PC
+    pc.printf("\r\n\r\nTemperature Control x Casa v.1.2 2015\n\rMade using:\n\r");
+    pc.printf("NUCLEO-F334R8 + DS18B20 (input on A1) + LCD1602 + RELAY (on A5).\n\r");
+    pc.printf("For more info look here:\n\r");
+    pc.printf("   http://www.emcu.it/NUCLEOevaBoards/mBed/QSG-Mbed-Library.pdf\n\r");
+    pc.printf("by: www.emcu.it\n\r\n\r");    
+    
+    // TurnOn the LCD backlight of the LCD1602 board
+    backlight = ON;  // ON: 1, OFF: 0
+    
+    // StartUp Logo to the LCD1602 board
+    lcd.cls();
+    lcd.locate(0,0);
+    lcd.printf("By: www.emcu.it");
+    lcd.locate(0,1);
+    lcd.printf("Ver1.2 2015 Casa");    
+ 
+    // SetUp the temperatures after PowerOn
+    probe.convertTemperature(true, DS1820::all_devices); //Start temperature conversion, wait until ready
+    temperature = probe.temperature('c');
+    // Eliminate the wrong reading
+    CalcMed();   
+    temperaturePREVIOUS = temperature;
+    temperatureMAX = temperature;
+    temperatureMIN = 50.50;
+    wait(1); 
+        
+    while(1) 
+    {
+        // READ BUTTON on LCD board +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+        if (ReadButtonOnLCD1602() == tUp)
+        {
+            backlight = ON;
+            PowerON = NO;
+            lcd.locate(0,1);
+            lcd.printf("Please wait....."); 
+            FlashLCDlastLine = 0;
+        }
+        else if (ReadButtonOnLCD1602() == tDown)
+        {
+            backlight = OFF;
+            PowerON = NO;
+            lcd.locate(0,1);
+            lcd.printf("Please wait.....");           
+            FlashLCDlastLine = 0;         
+        }   
+        else if (ReadButtonOnLCD1602() == tRigth)
+            ShowSetUp();            
+        else if (ReadButtonOnLCD1602() == tLeft)
+            SetUp();
+        else;
+        // END READ BUTTON on LCD board +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+        
+        // READ and DISPLAY the TEMPERATURE and control RELAY +++++++++++++++++++++++++++++++++++++++++++++++
+        probe.convertTemperature(true, DS1820::all_devices); //Start temperature conversion, wait until ready
+        temperature = probe.temperature('c');
+        wait_ms(TempSamplingTime);             
+        // Eliminate the wrong reading
+        CalcMed();
+        
+        // ON/OFF Relè ++++++++++++++++++++++++++++++++++++++++++++
+        if (temperature <= tempON)      // ON Relè
+        {
+            if (rele == OFF)
+                TlowerTemp ++;
+            if (TlowerTemp >= DelayForOffOnRealy)
+            {
+                rele = ON;
+                RL1 = 1;
+                TowerTemp  = 0;
+                TlowerTemp = 0;
+            }
+        }         
+        else if (temperature >= tempOFF)     // OFF Relè
+        {
+            if (rele == ON)
+                TowerTemp ++;
+            if (TowerTemp >= DelayForOffOnRealy)
+            {
+                rele = OFF;
+                RL1 = 0;
+                TowerTemp  = 0;
+                TlowerTemp = 0;
+            }
+        } 
+        else;
+        // END ON/OFF Relè ++++++++++++++++++++++++++++++++++++++++
+        
+        // Display status via Virtual COM
+        PrintTemperatures();
+        
+        // Display Status on the LCD1602 board
+        // lcd.cls();        
+        lcd.locate(0,0);
+        if (rele == ON)
+            lcd.printf("T %2.3f RELEon ", temperature); // probe.temperature('c'));
+        if (rele == OFF)
+            lcd.printf("T %2.3f RELEoff", temperature); // probe.temperature('c'));            
+
+        // END READ and DISPLAY the TEMPERATURE and control RELAY +++++++++++++++++++++++++++++++++++++++++++
+
+
+        // START Flashing * on the LCD ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++        
+        FlashSeg++;
+        if (FlashSeg == 1)
+        {
+            lcd.locate(8,0);
+            lcd.printf(" "); 
+        }
+        if (FlashSeg == 2)
+        {
+            lcd.locate(8,0);
+            lcd.printf("*");
+            FlashSeg = 0; 
+        }                
+        // END START Flashing * on the LCD ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+        // LAST line on the LCD +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++   
+        if (PowerON == YES) // If failed 220Vac, is shown on the LCD
+        {
+            FlashLCDlastLine++;
+            if (FlashLCDlastLine == 1)
+            {
+                backlight = ON;
+                lcd.locate(0,1);
+                lcd.printf("Failed 220Vac   ");
+                pc.printf("\n\rFailed 220Vac\n\r");
+            }
+            if (FlashLCDlastLine == 2)
+            {
+                backlight = OFF;
+                FlashLCDlastLine = 0;
+                lcd.locate(0,1);
+                lcd.printf("Failed 220Vac   "); 
+                pc.printf("\n\rFailed 220Vac\n\r"); 
+            }                        
+        }
+        else // Show the configurations: Max and Min temperature, Relay ON/OFF temperature and Delay before RELAY goes ON or OFF
+        {
+            DelayLastLine++;
+            if (DelayLastLine == DelayTime) // Show Tmax and Tmin
+            {
+                lcd.locate(0,1);
+                lcd.printf("mx%2.3fmi%2.3f", temperatureMAX, temperatureMIN);  
+            }
+            if (DelayLastLine == (DelayTime + DelayTime)) // Show Relay Tmin (tempON) e Tmax (tempOFF)
+            {
+                // DelayLastLine = 0;
+                lcd.locate(0,1);
+                lcd.printf("Rm%2.2f RM%2.2f ", tempON, tempOFF);  
+            } 
+            if (DelayLastLine == (DelayTime + DelayTime + DelayTime)) // Show DelayForOffOnRealy
+            {
+                DelayLastLine = 0;
+                lcd.locate(0,1);
+                lcd.printf("                ");
+                lcd.locate(0,1);
+                lcd.printf("DelayOnOff=%dsec", DelayForOffOnRealy); // ((DelayForOffOnRealy * TempSamplingTime)/1000));  
+            }                      
+        }           
+        // END LAST line on the LCD +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++              
+    }
+}
+
+
+/*
+**** ShowSetUp
+This function use the global variable: 
+    tempON
+    tempOFF
+*/
+void ShowSetUp(void)
+{
+    PowerON = NO;
+    FlashLCDlastLine = 0; 
+    
+    lcd.cls();
+    lcd.locate(0,0);
+    lcd.printf("   www.emcu.it ");
+    WaitingRightButton();  
+    lcd.locate(0,1);
+    lcd.printf("UP DOWN or LEFT ");
+
+    // Awaiting the pressure of Left Button to finish this part
+    while (ReadButtonOnLCD1602() != tLeft)
+    { 
+        // Increase value
+        if (ReadButtonOnLCD1602() == tUp)
+            {
+            rele = ON;
+            RL1 = 1;
+            // Awaiting the release of the tUp Button
+            while (ReadButtonOnLCD1602() == tUp);
+            }
+        // Decrease value
+        if (ReadButtonOnLCD1602() == tDown)
+            {
+            rele = OFF;
+            RL1 = 0;
+            // Awaiting the release of the tDown Button
+            while (ReadButtonOnLCD1602() == tDown);
+            }
+        lcd.locate(0,0);
+        if (rele == ON)
+            lcd.printf("Rele is ON      ");
+        else
+            lcd.printf("Rele is OFF     ");
+    }        
+    // Awaiting the release of the tLeft Button
+    lcd.locate(0,1);    
+    lcd.printf("Release LEFT but");
+    while (ReadButtonOnLCD1602() == tLeft);    
+
+    lcd.cls();
+    lcd.locate(0,0);
+    lcd.printf("Please wait.....");  
+}
+
+
+/*
+**** WaitingRightButton
+This function waiting the Release and Pressure of the Rirght Button
+*/
+void WaitingRightButton(void)
+{
+    // Awaiting the release of the Right Button
+    lcd.locate(0,1);
+    lcd.printf("Release RIGHT bu");    
+    while (ReadButtonOnLCD1602() == tRigth);
+    wait_ms(100);
+    // Awaiting the pressure of the Rigth Button
+    lcd.locate(0,1);    
+    lcd.printf("Press RIGTH but.");   
+    while (ReadButtonOnLCD1602() != tRigth);
+    lcd.locate(0,1);    
+    lcd.printf("                ");        
+}
+
+
+/*
+**** SetUp
+This function use the global variable: 
+    tempON
+    tempOFF
+This function use this definitions:     
+    tUp 
+    tDown  
+    tRigth 
+    tLeft    
+*/
+void SetUp(void)
+{ 
+    PowerON = NO;
+    FlashLCDlastLine = 0;
+    lcd.locate(0,0);
+    lcd.printf("Please wait.....");     
+    
+    // TurnOn the LCD backlight of the LCD1602 board
+    backlight = ON;  // ON: 1, OFF: 0
+    
+    // Show the SetUp related to:
+    // TempMin (tempON) & TempMax (tempOFF)
+    lcd.cls();
+    lcd.locate(0,0);
+    lcd.printf("Rm%2.2f RM%2.2f ", tempON, tempOFF);
+
+    // Awaiting the release of the Left Button
+    lcd.locate(0,1);
+    lcd.printf("Release LEFT but");    
+    while (ReadButtonOnLCD1602() == tLeft);
+    wait_ms(100);
+    // Awaiting the pressure of the Left Button
+    lcd.locate(0,1);    
+    lcd.printf("Press LEFT butt.");
+    // Awaiting the release of the Left Button    
+    while (ReadButtonOnLCD1602() != tLeft);    
+    
+    // Menù for SetUp the TempMin (tempON)
+    lcd.cls();
+    lcd.locate(0,0);
+    lcd.printf("RTempMin %2.2f", tempON);
+    lcd.locate(0,1);
+    lcd.printf("UP DOWN RIGHT");
+    // Awaiting the pressure of Right Button to finish this part
+    while (ReadButtonOnLCD1602() != tRigth)
+    { 
+        // Increase value
+        if (ReadButtonOnLCD1602() == tUp)
+            {
+            tempON = tempON + float(tStep);
+            // Awaiting the release of the tUp Button
+            while (ReadButtonOnLCD1602() == tUp);
+            }
+        // Decrease value
+        if (ReadButtonOnLCD1602() == tDown)
+            {
+            tempON = tempON - float(tStep);
+            // Awaiting the release of the tDown Button
+            while (ReadButtonOnLCD1602() == tDown);
+            }
+        lcd.locate(0,0);
+        lcd.printf("RTempMin %2.2f", tempON);
+    }
+    lcd.locate(0,1);
+    lcd.printf("Release RIGHT");
+    // Awaiting the release of the tRight Button
+    while (ReadButtonOnLCD1602() == tRigth);    
+    wait_ms(100);
+    
+    // Menù for SetUp the TempMax (tempOFF)
+    if (tempOFF <= tempON)
+        tempOFF = tempON + float(tStep) + float(tStep);
+    lcd.cls();
+    lcd.locate(0,0);
+    lcd.printf("RTempMax %2.2f", tempOFF);
+    lcd.locate(0,1);
+    lcd.printf("UP DOWN LEFT");    
+    // Awaiting the pressure of Left Button to finish this part
+    while (ReadButtonOnLCD1602() != tLeft)
+    { 
+        // Increase value
+        if (ReadButtonOnLCD1602() == tUp)
+            {
+            tempOFF = tempOFF + float(tStep);
+            // Awaiting the release of the tUp Button
+            while (ReadButtonOnLCD1602() == tUp);
+            }
+        // Decrease value
+        if (ReadButtonOnLCD1602() == tDown)
+            {
+            tempOFF = tempOFF - float(tStep);
+            // Awaiting the release of the tDown Button
+            while (ReadButtonOnLCD1602() == tDown);
+            // Test tempOFF that must be superior to tempON + 2tStep
+            if (tempOFF <= tempON + (float(tStep) + float(tStep)))
+                {
+                tempOFF = tempON + float(tStep) + float(tStep);
+                lcd.locate(0,0);
+                lcd.printf("TempMax>TempMin");
+                wait(2);
+                }
+            }
+        lcd.locate(0,0);
+        lcd.printf("RTempMax %2.2f ", tempOFF);
+    }        
+    // Awaiting the release of the tLeft Button
+    lcd.locate(0,1);    
+    lcd.printf("Release LEFT but");
+    while (ReadButtonOnLCD1602() == tLeft);
+
+    // Menù for SetUp the Delay before to accept the On/Off of the relay (DelayForOffOnRealy)  
+    lcd.cls();
+    lcd.locate(0,0);
+    lcd.printf("DelayOnOff=%dsec", DelayForOffOnRealy); // ((DelayForOffOnRealy * TempSamplingTime)/1000));
+    lcd.locate(0,1);
+    lcd.printf("UP DOWN RIGHT");
+    // Awaiting the pressure of Right Button to finish this part
+    while (ReadButtonOnLCD1602() != tRigth)
+    { 
+        // Increase value
+        if (ReadButtonOnLCD1602() == tUp)
+            {
+            DelayForOffOnRealy = DelayForOffOnRealy + 10;
+            // Awaiting the release of the tUp Button
+            while (ReadButtonOnLCD1602() == tUp);
+            if (DelayForOffOnRealy >= MaxRelDly)
+                DelayForOffOnRealy = MaxRelDly;
+            }
+        // Decrease value
+        if (ReadButtonOnLCD1602() == tDown)
+            {
+            DelayForOffOnRealy = DelayForOffOnRealy - 10;
+            // Awaiting the release of the tDown Button
+            while (ReadButtonOnLCD1602() == tDown);
+            if (DelayForOffOnRealy <= 10)
+                DelayForOffOnRealy = 10;            
+            }
+        lcd.locate(0,0);
+        lcd.printf("DelayOnOff=%dsec", DelayForOffOnRealy); // ((DelayForOffOnRealy * TempSamplingTime)/1000));
+    }
+    lcd.locate(0,1);
+    lcd.printf("Release RIGHT");
+    // Awaiting the release of the tRight Button
+    while (ReadButtonOnLCD1602() == tRigth);    
+    wait_ms(100);    
+    
+    lcd.cls();
+    lcd.locate(0,0);
+    lcd.printf("Please wait....."); 
+    
+    return;
+}
+
+
+/*
+**** ReadButtonOnLCD1602
+This function Read the button on the LCD1620
+This function use the global variable: 
+    value
+    LastButtonPressed
+This function use this definitions:    
+    TastoSU  
+    TastoGIU 
+    TastoDES 
+    TastoSIN 
+    DeltaTasti 
+    tUp 
+    tDown  
+    tRigth 
+    tLeft  
+    tNone  
+*/
+uint8_t ReadButtonOnLCD1602(void)
+{ 
+    value = button.read_u16();
+    // pc.printf("Button value = %d\n\r",value); 
+    
+    if (value < (TastoSU + DeltaTasti) && value > (TastoSU - DeltaTasti))    // Button UP
+    { 
+        // pc.printf("UP\n\r");
+        return tUp;
+    }
+    else if (value < (TastoGIU + DeltaTasti) && value > (TastoGIU - DeltaTasti))  // Button DOWN
+    { 
+        // pc.printf("DOWN\n\r");    
+        return tDown;   
+    }        
+    else if (value < (TastoDES + DeltaTasti) && value <= (TastoDES - DeltaTasti))  // Button RIGHT
+    { 
+        // pc.printf("RIGHT\n\r");    
+        return tRigth;          
+    }
+    else if (value < (TastoSIN + DeltaTasti) && value > (TastoSIN - DeltaTasti))  // Button LEFT 
+    { 
+        // pc.printf("LEFT\n\r");     
+        return tLeft;   
+    }  
+    else           
+        return tNone;     
+}
+
+
+/*
+This function is use for eliminate the wrong reading and 
+for setup the MAX and MIN temperature we have read.
+This function use the global variable:
+    temperature
+    MaxTempError
+    temperaturePREVIOUS
+    temperatureMAX
+    temperatureMIN
+This function use this definition:
+    MaxError
+*/
+void CalcMed(void)
+{   
+    // Remove a measure that exceed the +- MaxError
+    MaxTempError = (temperature * MaxError) / 100;
+    if (temperature > (temperature + MaxTempError))
+        temperature = temperaturePREVIOUS;
+    else if (temperature < (temperature - MaxTempError))
+        temperature = temperaturePREVIOUS;    
+    else
+        temperaturePREVIOUS = temperature;
+    
+    // SetUp the Max and Min temperature measured
+    if (temperature > temperatureMAX)
+        temperatureMAX = temperature;
+    if (temperature < temperatureMIN)
+        temperatureMIN = temperature;
+}
+
+
+/*
+This function Display temperatures on the PC
+*/
+void PrintTemperatures(void)
+{
+    pc.printf("TEMPERATURE Control v.1.2 2015 Casa\n\rTEMPERATURE is: %2.3f Centigrade/Centigradi\r\n", temperature); 
+    // pc.printf("DeltaTemp = %2.3f\r\n", DeltaTemp); 
+    pc.printf("RELAY - tempON = %2.3f ", tempON); 
+    pc.printf("tempOFF = %2.3f\r\n", tempOFF); 
+    pc.printf("Delay for OFF or ON realy = %d sec.\n\r", DelayForOffOnRealy); // ((DelayForOffOnRealy * TempSamplingTime)/1000));
+    // pc.printf("Temperature MIN measured = %d - Temperature MAX measured = %d\n\r", TlowerTemp, TowerTemp);
+    if (rele == ON)
+        pc.printf("RELAY is ON\n\r");
+    else
+        pc.printf("RELAY is OFF\n\r");
+    pc.printf("MaxTempError = %2.3f\r\n", MaxTempError);
+    pc.printf("temperaturePREVIOUS = %2.3f\r\n", temperaturePREVIOUS); 
+    pc.printf("TEMPERATURE measured - MAX = %2.3f ", temperatureMAX); 
+    pc.printf("MIN = %2.3f\r\n\r\n", temperatureMIN); 
+}
\ No newline at end of file