STM32F103C8T6_WIFI_Heating_system

Dependencies:   mbed mbed-STM32F103C8T6 eeprom_flash Watchdog PinDetect DS1820

  1. Bluepill STM32F103C8T6 Heating system
    1. _This project is core part of bigger heating system project!_

Features - Reading temperature from four DS18B20 sensors - Making a decision about switching on/off heater and pomp - Executing simple user commands from UART - Storing state parameters to program memory (EEPROM emulation)

temp_controller/temp_controller.cpp

Committer:
andrewklmn
Date:
2018-09-23
Revision:
49:f9f65a2fc92f
Parent:
48:4ec055c066b4
Child:
50:94730b99ea41

File content as of revision 49:f9f65a2fc92f:

#include "temp_controller.h"

extern Serial pc;
extern Watchdog wd;
extern DigitalOut myled; 
extern DigitalOut pomp_OFF;
extern DigitalOut heater_OFF;
extern EventQueue queue;

extern unsigned int eeprom_config_value;

#define MIN_MEBEL_TEMP 15 
#define MIN_LITOS_TEMP 10 
#define MIN_BACK_WATER_TEMP 10 
#define MAX_HOT_WATER_TEMP 35 

//unsigned int epprom_config_value = 0x0F0A0A23; 
/*
    epprom_config_value:
        1 unsigned char - Min mebel temp        (default +15)
        2 unsigned char   Min litos temp        (default +10)
        3 unsigned char   Min back water temp   (default +10)
        4 unsigned char   Max hot water temp    (default +35)
*/

float temp[5] = {
                    // initial temperature is maximum
                    85, // OUTDOOR
                    85, // LITOS
                    85, // MEBEL
                    85, // HOT WATER
                    85  // BACK WATER
                };
                
float simulated_temp[5] = {
                    // initial temperature for simulator
                    7,  // OUTDOOR
                    10, // LITOS
                    14, // MEBEL
                    33, // HOT WATER
                    18  // BACK WATER
                };
                
int temp_error[5] = {
                        1,1,1,1,1       // initial state is no sensors
                                        // 0 - sensor present
                                        // 1 - no sensor
                                        // 2 - sensor CRC error
                    };
                        
string labels[5] = {
                        "OUTDOOR", 
                        "LITOS", 
                        "MEBEL", 
                        "HOT WATER", 
                        "BACK WATER" 
                    };
    
DS1820  ds1820[5] = { 
                        DS1820(PA_9), // substitute PA_9 with actual mbed pin name connected to the OUTDOOR
                        DS1820(PA_8), // substitute PA_8 with actual mbed pin name connected to the INDOOR LITOS    
                        DS1820(PA_7), // substitute PA_7 with actual mbed pin name connected to the INDOOR MEBEL
                        DS1820(PA_6), // substitute PA_6 with actual mbed pin name connected to the HOT WATER
                        DS1820(PA_5)  // substitute PA_6 with actual mbed pin name connected to the HOT WATER
                    };
                        
unsigned char working_mode = 1; // default mode after powerup is ECO
                                // 0 - OFF - heating off, pomp and heater are OFF
                                // 1 - ECO - eco heating
                                // 2 - STANDART - standart heating
                                // 3 - ECO SIMULATOR - eco simulator mode - work on eco simulated_temp
                                // 4 - SIMULATOR - simulator mode - work on simulated_temp
                                // 5 - POMP - pomp is ON, heater is OFF
                                // 6 - EMERGENCY - pomp and heater are ON
                                
char pomp_was_delayed = 0;
                                
void delayed_pomp_off(){
    if (pomp_was_delayed == 1) {
        pomp_OFF = 1;
    };
    pomp_was_delayed = 0;
    //pc.printf("delayed_pomp_off\r\n"); 
};

void start_temp(){
    
    __disable_irq(); 
    
    for ( int j=0; j < 5; j++ ) {
        if(ds1820[j].begin()) { 
            ds1820[j].startConversion();
            //pc.printf("%s sensor present!\r\n", labels[j].c_str()); 
        };// else {
            //pc.printf("No %s sensor found!\r\n", labels[j].c_str());         
        //};
    };
    __enable_irq(); 
        
};

void check_temp(){
  
       int error_flag = 0;
       myled = 0; // turn the LED on
       
       // kick the watchdog
       wd.Service();
       
       __disable_irq();
       
       for ( int j=0; j < 5; j++ ) {
            temp_error[j] = ds1820[j].read(temp[j]); // read temperature from DS1820 and perform cyclic redundancy check (CRC)
            error_flag += temp_error[j];
            ds1820[j].startConversion();            // start temperature conversion from analog to digital before next reading
        };        
        
        if (error_flag > 0 && ( working_mode==1 || working_mode==2 ) ){
            // set EMERGENCY mode - pomp and heater are ON if sensors are bad
            working_mode = 6;
        };
        
        
        // save new config if it was changed
        if (readEEPROMWord(0)!= eeprom_config_value) {
            save_new_config();
        };
        
        
        
        __enable_irq(); 
        
        myled = 1;      // turn the LED off
};


void process_temp() {    

        //pc.printf("State %d|%d|%d|%d|%d\r\n", temp_error[0], temp_error[1], temp_error[2], temp_error[3], temp_error[4] );
        //pc.printf("Temp %3.1f|%3.1f|%3.1f|%3.1f|%3.1f\r\n", temp[0], temp[1], temp[2], temp[3], temp[4] );
        //pc.printf("RAM_config=%X, FLASH_config=%X\r\n", eeprom_config_value ,readEEPROMWord(0));
        //pc.printf("=======================================");

        switch(working_mode) {
            case 0:
                // 0 - OFF - heating off, pomp and heater are OFF
                pomp_OFF = 1;
                heater_OFF = 1;
                break;
            case 1:
                // 1 - ECO - eco heating
                set_pomp_and_heater_eco_mode(temp);
                break; 
            case 2:
                // 2 - STANDART - standart heating
                set_pomp_and_heater_by(temp);
                break; 
            case 3:
                // 3 - ECO SIMULATOR - simulator mode - work on simulated_temp
                set_pomp_and_heater_eco_mode(simulated_temp);  
                break; 
            case 4:
                // 4 - SIMULATOR - simulator mode - work on simulated_temp
                set_pomp_and_heater_by(simulated_temp);
                break; 
            case 5:
                // 5 - POMP - pomp is ON, heater is OFF
                pomp_OFF = 0;
                heater_OFF = 1;
                break; 
            case 6:
                // 6 - FULL - pomp and heater are ON
                pomp_OFF = 0;
                heater_OFF = 0;
                break;                 
            default:
                pomp_OFF = 1;
                heater_OFF = 1;
        };

};


void save_new_config() {
    
    enableEEPROMWriting();
    writeEEPROMWord(0,eeprom_config_value);    
    disableEEPROMWriting();        
                  
};


unsigned int get_temp_config_value(){
    
    unsigned int v = readEEPROMWord(0);
    if ( v == 0xFFFFFFFF ) {
        // if eeprom config value is not initialized
        // set default value 0x0F0A0A23;
        v =  MIN_MEBEL_TEMP;
        v = ( v << 8 ) | MIN_LITOS_TEMP;
        v = ( v << 8 ) | MIN_BACK_WATER_TEMP;
        v = ( v << 8 ) | MAX_HOT_WATER_TEMP;
    };  
    return v;  
};

void set_pomp_and_heater_by(float * work_temp) {
    // temp config array = outdoor|litos|mebel|hot_water|back_water
    
    /*
    eeprom_config_value:
        1 unsigned char - Min mebel temp        (default +15)
        2 unsigned char   Min litos temp        (default +10)
        3 unsigned char   Min back water temp   (default +10)
        4 unsigned char   Max hot water temp    (default +35)
    */
    unsigned char min_mebel_temp = eeprom_config_value >> 24;
    unsigned char min_litos_temp = ( 0x00FF0000 & eeprom_config_value) >> 16;
    unsigned char min_back_water_temp = ( 0x0000FF00 & eeprom_config_value) >> 8;
    unsigned char max_hot_water_temp = 0x000000FF & eeprom_config_value;
    
    //__disable_irq();
    //pc.printf("Level %d|%d|%d|%d\r\n", min_mebel_temp, min_litos_temp, min_back_water_temp, max_hot_water_temp);
    //__enable_irq();
    
    float outdoor    = *(work_temp);
    float litos      = *(work_temp + 1);
    float mebel      = *(work_temp + 2);
    float hot_water  = *(work_temp + 3);
    float back_water = *(work_temp + 4);
    
    if (outdoor > min_litos_temp) {
        // ============================================= SUMMER MODE
        // system off
        if ( heater_OFF == 0 ) {
            queue.call_in( 10000, delayed_pomp_off );
            pomp_was_delayed = 1;
        } else {
            if ( pomp_was_delayed == 0 ) {
                pomp_OFF = 1;    
            };  
        };
        heater_OFF = 1;
        
    } else if ( outdoor < 3) {
        // ============================================== WINTER MODE
        // pomp is always on
        pomp_OFF = 0;
        
        if (mebel < min_mebel_temp ||
            litos < min_litos_temp ||
            back_water < min_back_water_temp) { 
                // when if somewhere is colder than it must be
                if (hot_water > max_hot_water_temp) {
                    heater_OFF = 1; 
                } else {
                    if ( heater_OFF == 1 ) {
                        if (hot_water < (max_hot_water_temp - 10)) {
                            heater_OFF = 0;
                        } else {
                            heater_OFF = 1;
                        };                        
                    } else {
                        heater_OFF = 0;
                    };
                };
        } else {
            heater_OFF = 1;
        };
        
    } else {
        // ======================================== DEMI SEASON MODE
        
        if (mebel < min_mebel_temp ||
            litos < min_litos_temp ||
            back_water < min_back_water_temp) { 
                // when if somewhere is colder than it must be
                pomp_OFF = 0;
                if ( hot_water > (max_hot_water_temp-10) ) {
                    heater_OFF = 1; 
                } else {
                    if ( heater_OFF == 1 ) {
                        if ( hot_water < (min_back_water_temp + 2) ) {
                            heater_OFF = 0;
                        } else {
                            heater_OFF = 1;
                        };                        
                    } else {
                        heater_OFF = 0;
                    };
                };
        } else {
            heater_OFF = 1;
            if ( hot_water > min_back_water_temp ) {
                pomp_OFF = 0;
            } else {
                pomp_OFF = 1;
            };
        };     
    };
    
    //__disable_irq();
    //pc.printf("Temp %3.1f|%3.1f|%3.1f|%3.1f|%3.1f\r\n", *(work_temp), *(work_temp + 1), *(work_temp + 2), *(work_temp + 3), *(work_temp + 4) );                    
    //__enable_irq();
}; 

void set_pomp_and_heater_eco_mode(float * work_temp){
    
    unsigned char min_mebel_temp = 10;
    unsigned char min_litos_temp = 7;
    unsigned char min_back_water_temp = 7;
    unsigned char max_hot_water_temp = 25;    
    
    float outdoor    = *(work_temp);
    float litos      = *(work_temp + 1);
    float mebel      = *(work_temp + 2);
    float hot_water  = *(work_temp + 3);
    float back_water = *(work_temp + 4);
    
    if (outdoor > min_litos_temp) {
        //============================================ summer mode   
        // system off
        if ( heater_OFF == 0 ) {
            queue.call_in( 10000, delayed_pomp_off );
            pomp_was_delayed = 1;
        } else {
            if ( pomp_was_delayed == 0 ) {
                pomp_OFF = 1;    
            };  
        };
        heater_OFF = 1;
        
    } else if (outdoor < 3) {
        //============================================ winter mode    
        pomp_OFF = 0;
        if (mebel < min_mebel_temp ||
            litos < min_litos_temp ||
            back_water < min_back_water_temp) { 
                // when if somewhere is colder than it must be
                if (hot_water > max_hot_water_temp) {
                    heater_OFF = 1; 
                } else {
                    if ( heater_OFF == 1 ) {
                        if (hot_water < (max_hot_water_temp - 10)) {
                            heater_OFF = 0;
                        } else {
                            heater_OFF = 1;
                        };                        
                    } else {
                        heater_OFF = 0;
                    };
                };
        } else {
            heater_OFF = 1;
        };        

    } else {
        //========================================demi season mode
        if (mebel < min_mebel_temp ||
            litos < min_litos_temp ||
            back_water < min_back_water_temp) { 
                // when if somewhere is colder than it must be
                pomp_OFF = 0;
                if ( hot_water > (max_hot_water_temp - 5) ) {
                    heater_OFF = 1; 
                } else {
                    if ( heater_OFF == 1 ) {
                        if ( hot_water < (min_back_water_temp + 3) ) {
                            heater_OFF = 0;
                        } else {
                            heater_OFF = 1;
                        };                        
                    } else {
                        heater_OFF = 0;
                    };
                };
        } else {
            heater_OFF = 1;
            if ( hot_water > min_back_water_temp ) {
                pomp_OFF = 0;
            } else {
                pomp_OFF = 1;
            };
        };     
        
    };
};