Temperature Control: NUCLEO-F334R8 + DS18B20 + LCD1602 shield + RELAY and see the results on the PC and on the LCD1602. For more info see here: http://www.emcu.it/NUCLEOevaBoards/mBed/QSG-Mbed-Library.pdf

Dependencies:   DS1820 mbed TextLCD

Fork of F334andDS18B20 by Enrico Marinoni

main.cpp

Committer:
emcu
Date:
2015-12-27
Revision:
2:54ef8b27cbaa
Parent:
1:5c2c3c1e5093

File content as of revision 2:54ef8b27cbaa:

/**

Temperature control based on:
    NUCLEO-F334R8 
    DS18B20 
    RELAY module 
    LCD1602 shield

By:       www.emcu.it
Date:     Dec.2015
Version:  1.0
Name:     F334andDS18B20andLDC1602
NOTE:     For more info see here: http://www.emcu.it/NUCLEOevaBoards/mBed/QSG-Mbed-Library.pdf

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 (see the schematic below), the LCD1602 board and a RELAY board.
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
This SW is a derivative of:: https://developer.mbed.org/users/Sissors/code/DS1820_HelloWorld/
On the: https://developer.mbed.org/users/Sissors/code/DS1820_HelloWorld/ there is a multi sensor (DS18B20) example.

*/


// Below there is the Data Pin where is connected the: 
// pin.2 (DQ) of the DS18B20
#define DATA_PIN  A1

#include "mbed.h"
#include "DS1820.h"
#include "TextLCD.h"

// Define the LED
DigitalOut myled(LED1);
DigitalOut RL1(A5);       // Relè n.1

// 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 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

// VARIABLEs
uint8_t n = 0;
uint8_t FlashSeg = 0;
uint8_t rele = OFF;
float temperature = 0;
float DeltaTemp = 0.5; 
float tempON  = 20.00;
float tempOFF = tempON + DeltaTemp;
float temperaturePREVIOUS = 0;
float temperatureMAX = 0;
float temperatureMIN = 0;
float MaxTempError = 0;
unsigned long value = 0;
uint8_t LastButtonPressed = tNone;

// FUNCTIONs
void CalcMed(void);
void PrintTemperatures(void);
uint8_t ReadButtonOnLCD1602(void);
void SetUp(void);
void ShowSetUp(void);
void WaitingRightButton(void);


int main() 
{
    
    // SetUp the resolution of the DS18B20 to 12bit
    probe.setResolution(12);
    
    // StartUp Logo to the PC
    pc.printf("\r\n\r\nTemperature Control made using:\n\r");
    pc.printf("NUCLEO-F334R8 + DS18B20 (input on A1) + LCD1602 + RELAY (output 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("Ver.1.0");    
 
    // 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;
        else if (ReadButtonOnLCD1602() == tDown)
            backlight = OFF;
        else if (ReadButtonOnLCD1602() == tRigth)
            ShowSetUp();            
        else if (ReadButtonOnLCD1602() == tLeft)
            SetUp();
        else;
        // END READ BUTTON on LCD board +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        
        // READ and DISPLAY the TEMPERATURE +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        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è
        {
            rele = ON;
            RL1 = 1;
        } 
        else if (temperature >= tempOFF) // OFF Relè
        {
            rele = OFF;
            RL1 = 0;
        } 
        
        // pc.printf("The Temperature is %2.3f Celsius/Centigradi\r\n", temperature);
        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'));            
        lcd.locate(0,1);
        lcd.printf("TM%2.3fTm%2.3f", temperatureMAX, temperatureMIN);   
        // END READ and DISPLAY the TEMPERATURE +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  

        // START Flashing bar 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 bar on the LCD ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
               
    }
}


/*
**** ShowSetUp
This function use the global variable: 
    tempON
    tempOFF
*/
void ShowSetUp(void)
{
    // 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("Tm%2.2f TM%2.2f ", tempON, tempOFF);
    WaitingRightButton();  

    lcd.cls();
    lcd.locate(0,0);
    lcd.printf("LEFT SetUp Menu ");
    WaitingRightButton(); 
    
    lcd.cls();
    lcd.locate(0,0);
    lcd.printf("By: www.emcu.it ");
    WaitingRightButton();      

    lcd.cls();
    lcd.locate(0,0);
    lcd.printf("By patient....  ", tempON, tempOFF);       
}


/*
**** 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);    
}


/*
**** SetUp
This function use the global variable: 
    tempON
    tempOFF
This function use this definitions:     
    tUp 
    tDown  
    tRigth 
    tLeft    
*/
void SetUp(void)
{ 
    // 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("Tm%2.2f TM%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("TempMin %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("TempMin %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("TempMax %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);
            }
        lcd.locate(0,0);
        lcd.printf("TempMax %2.2f", tempOFF);
    }        
    // 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("By patient....  ", tempON, tempOFF);
    
    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 =====> %2.3f Centigrade/Centigradi\r\n", temperature); 
    // pc.printf("DeltaTemp = %2.3f\r\n", DeltaTemp); 
    pc.printf("tempON  = %2.3f\r\n", tempON); 
    pc.printf("tempOFF = %2.3f\r\n", tempOFF); 
    pc.printf("RELE' is = %d\r\n", rele);
    pc.printf("MaxTempError = %2.3f\r\n", MaxTempError);
    pc.printf("temperaturePREVIOUS = %2.3f\r\n", temperaturePREVIOUS); 
    pc.printf("temperatureMAX = %2.3f\r\n", temperatureMAX); 
    pc.printf("temperatureMIN = %2.3f\r\n\r\n", temperatureMIN); 
}