#include <Arduino.h> #include <OneWire.h> #include <DallasTemperature.h> #include <Wire.h> #include <LCD.h> #include <LiquidCrystal_I2C.h> #include <Bounce2.h> boolean motoros_szelep_vegallas_el = true; boolean serial_adatok_kikuldese = true; // ************ Hőmérséklet érzékelők Dallasos!!!! ************ #define ONE_WIRE_BUS 3 #define NumberOfDevices 9 // Dallasos hőmérők adatportja // Hőmérők száma //Relék beállításai #define RELAY_ON 0 #define RELAY_OFF 1 #define Relay_1 4 // kazán szivattyú relay no 4 IN4 Arduino Digital I/O pin numbers #define Relay_2 5 // radiátor szivattyú relay no 3 IN3 #define Relay_3 7 // szelep nyit relay no 2 IN2 #define Relay_4 6 // szelep zár relay no 1 IN1 // ************ Gombok ************ #define BUTTON_PIN_1 9 #define BUTTON_PIN_2 10 // Array holding all Device Address arrays. OneWire onewire(one_wire_bus); OneWire devices DallasTemperature sensors(&onewire); // Setup a onewire instance to communicate with any // Pass our onewire reference to Dallas Temperature. // Device Addresses are 8-element byte arrays. byte alladdress [NumberOfDevices][9] = { { 0x28, 0x28, 0xDE, 0x5B, 0x06, 0x00, 0x00, 0x68, { 0x28, 0x98, 0x33, 0x5D, 0x06, 0x00, 0x00, 0x50, { 0x28, 0x67, 0xDF, 0x5C, 0x06, 0x00, 0x00, 0x72, { 0x28, 0xF8, 0x49, 0x5D, 0x06, 0x00, 0x00, 0x43, { 0x28, 0x49, 0x25, 0x5D, 0x06, 0x00, 0x00, 0x43, { 0x28, 0x99, 0x22, 0x5C, 0x06, 0x00, 0x00, 0x59, { 0x28, 0x3E, 0x2C, 0x5C, 0x06, 0x00, 0x00, 0x22, { 0x28, 0xF0, 0x08, 0x5C, 0x06, 0x00, 0x00, 0x49, { 0x28, 0x16, 0x0C, 0x5D, 0x06, 0x00, 0x00, 0x42 //, // { 0x28, 0x2C, 0x11, 0x5D, 0x06, 0x00, 0x00, 0xF0 // tartalék 10. elem ; byte DS18B20resolution [NumberOfDevices] = { 11, 10, 10, 10, 10, 10, 10, 10, 10 ; //felbontás // ************ LCD I2c alapadatok ************ //https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads #define I2C_ADDR 0x27 // <<----- Add your address here. Find it from I2C Scanner #define BACKLIGHT_PIN 3 #define En_pin 2 #define Rw_pin 1 #define Rs_pin 0 #define D4_pin 4 #define D5_pin 5 #define D6_pin 6 #define D7_pin 7
LiquidCrystal_I2C lcd(i2c_addr,en_pin,rw_pin,rs_pin,d4_pin,d5_pin,d6_pin,d7_pin); // initialize the library with the numbers of the interface pins // LiquidCrystal lcd(12, 11, 5, 4, 3, 2); sok pines lcd // LCD háttérvilágítás - ha kell!!!! //int backlight = 13; // pin 13 will control the backlight // ************ Gombok ************ Bounce debouncer1 = Bounce(); Bounce debouncer2 = Bounce(); /* // ---------------------------- próba beálítások ---------------------------- #define kazan_melegedes 3 // kazán melegszik - ég a tűz (a kazán kilépő és visszatérő közti különbség) #define kazan_melegedes_hiszterezis 1 #define kazan_meleg #define kazan_meleg_hiszterezis 1 #define kazan_forro #define kazan_forro_hiszterezis 1 22 // kazán elérte a fűtőhőfokot (kb ESBE védőszelep) 28 // kazán túlhevülés #define futoviz_elmeleti_min 15 // fűtővíz elméleti minimum (ha ennél alacsonyabb, akkor nem kell fűteni) #define futoviz_elmeleti_min_hiszterezis 1 #define futoviz_valos_kazan semmit (feltéve ha a puffer is hideg)) #define futoviz_valos_kazan_hiszterezis 1 22 // kazán hőmérséklet (ha hideg a kazán, akkor nem kell indítani #define futoviz_valos_puff -77 // Puffer hőmérséklet (ha hideg a puffer, akkor nem kell indítani semmit (feltéve ha a kazán is hideg)) (-127*2+23)/3 #define futoviz_valos_puff_hiszterezis 1 // ---------------------------- próba beálítás vége ---------------------------- */ // ---------------------------- Éles beállítás ---------------------------- #define kazan_melegedes 5 // kazán melegszik - ég a tűz (a kazán kilépő és visszatérő közti különbség) #define kazan_melegedes_hiszterezis 2 #define kazan_meleg 45 // kazán elérte a fűtőhőfokot (kb ESBE védőszelep) #define kazan_meleg_hiszterezis 3 #define kazan_forro 92 // kazán túlhevülés #define kazan_forro_hiszterezis 3 #define futoviz_elmeleti_min 30 // fűtővíz elméleti minimum (ha ennél alacsonyabb, akkor nem kell fűteni) #define futoviz_elmeleti_min_hiszterezis 2 #define futoviz_valos_kazan 46 // kazán hőmérséklet (ha hideg a kazán, akkor nem kell indítani semmit (feltéve ha a puffer is hideg)) #define futoviz_valos_kazan_hiszterezis 3 #define futoviz_valos_puff 30 // Puffer hőmérséklet (ha hideg a puffer, akkor nem indítani semmit (feltéve ha a kazán is hideg)) #define futoviz_valos_puff_hiszterezis 2 // ---------------------------- Éles beállítás vége ----------------------------
#define szelep_beavatkozas_min 1000 // szelep beavatkozás #define szelep_beavatkozas_max 3000 #define szelep_varakozas_min 6000 #define szelep_varakozas_max 10000 #define homerseklet_elteres_max 10 // hőmérséklet eltérés (a min és a max közt arányos változik az útidő és a várakozási idő) #define homerseklet_elteres_min 2.5 // ez alatt nincs beavatkozás #define szelep_utido 120000 // szelep útideje ms-ban (120sec az ESBE ARA 661). Ha ezt meghaladja (120sec + bizt), akkor nem kell mozognia a szelepnek #define szelep_utido_d_biztonsag 50000 // biztonsági idő - ennyi túlmozgás után lesz végállásban a szelep a program szerint #define szelep_utido_d_bizt_elso 0 // az induláskori túllendülés biztonsági szorzója - valószínűleg nem kell, mivel a szelep egy közbülső állása a biztonság javára téved #define hiba_hideg_tagtartaly_hom #define hiba_futes_elmaradas_hom #define hiba_futes_magas_hom 2 // +2 C alatt már hidegnek számít, fagyveszélyes -5 // -5 C eltérés esetén hibás a hőmérséklet - alulfűtés +5 // 5 C eltérés esetén hibás a hőmérséklet - túlfűtés float meredekseg_szelep_mozgas_ido ; float meredekseg_szelep_varakozasi_ido ; boolean szivattyu_kazan_do = false; // szivattyú jel kazánköri boolean szivattyu_radiator_do = false; // szivattyú jel radiátorköri boolean motoros_szelep_zarasban = false; boolean motoros_szelep_nyitasban = false; boolean kazan_tulhevules_flag = false; // segédváltozó túlhevülés hiszteréziséhez boolean kazan_melegedes_flag = false; // segédváltozó kazánmelegedés hiszteréziséhez (visszatérő kisebb mint az előremenő) boolean kazan_meleg_flag = false; // segédváltozó kazánmeleg hiszteréziséhez (előremenő > (40~50C) ) boolean futeni_kell_flag = false; // segédváltozó elmeleti radiátor hőmérséklethez (kell-e fűteni, vagy sem) boolean van_melegviz_flag = false; // segédváltozó fűtővíz hőmérséklethez (van-, vagy nincs melegvíz a rendszerben unsigned int szamitott_szelep_mozgas_ido = 0; // szelep mozgásidő ms-ban (1000ms=1sec) unsigned int szamitott_szelep_varakozas_ido = 0; // szelep várakozasidő ms-ban (1000ms=1sec) byte szamitott_szelep_irany = 0; // 0 - nincs mozgas, 1 - nyit, 2 - zár long szamitott_szelep_mozgas_ido_ossz = 0; // összesített szelep mozgásidő ms-ban (1000ms=1sec) - negatív is lehet boolean szamitott_szelep_allas_elkezdodott = false ; boolean szelep_a_vegallasban = false ; float szamitott_szelep_allas = 999; // becsült szelepállás %-ban - csak akkor nullázódik, ha eléri a max szelep utidő + bizt értéket - a kezdeti állapot csak egy jelzőszám - tehát 999% = nincs adat byte szamitott_szelep_irany_utolso = 0; // utolsó szelepmozgás iránya 0 - nincs mozgas, 1 - nyit, 2 - zár byte loop_position = 0; // 0 - kezdet, 1 - szelepmozgás, 2 - várakozás unsigned long last_action_time; unsigned long next_action_time; //boolean gomb_lenyomva_volt = true; // kezdeti LCD világosítás boolean lcd_vilagit = false; unsigned long elsotetedesi_ido = 0; #define vilagitasi_ido 60000 // lcd világítási idő egy gomb megnyomása után ms-ban String homerseklet_szenzorok_beolvasasa_sikeres = "--------" ; int loop_print_position = 0; // hőmérsékletek és flagek kiírása az LCD kijelzőre
segédszám boolean button_pressed = true ; // hogy ne változzon gyorsan a kijelző, egy gomb nyomvatartás figyelés van beépítve. Induláskor mintha lenne egy gombnyomás float homerseklet [11] ; // hőmérsékletek értékei (0-10-ig terjed a skála) float gorbe_szamitas_s = 1.5 ; float gorbe_szamitas_dy = 0 ; int analogin_probauzem_map [2][5] = { { -20, 15, 15, 15, 15, { 30, 105, 105, 105, 105 ; int analogin_gorbe_alapadatok [3][2] = { // S = 0,2-3 ; dy = -10 -> +10 ; AI 4 és AI5 // 1. görbe meredekség // 2. eltolás (10-zel el van osztva a számítás előtt, ezért itt 10-zel kell szorozni - az int miatt) { 2, -100, { 30, 100, { 3, 2 // analog pin bemenet!!! ; #define analog_mintavetel 10 //Hányszor olvassa be az analog ponen az értékeket. Analog in oversample char buffer[16]; // make sure this is large enough for the largest string it must hold - LCD kijelző max 16 karakter //Az LCD kijelzőn lévő adatok 1. sorát (megnevezés) progmem-ként használom, mert különben efogy a memória. 180 szabad byte alatt bizonytalan a program működése #define count_homeronev 11 prog_char homeronev_str_0[] PROGMEM = "t elmeleti"; // "homeronev_str 0" etc are homeronev_strs to store - change to suit. prog_char homeronev_str_1[] PROGMEM = "t kulso"; prog_char homeronev_str_2[] PROGMEM = "t kazan elore"; prog_char homeronev_str_3[] PROGMEM = "t rad elore"; prog_char homeronev_str_4[] PROGMEM = "t kazan vissza"; prog_char homeronev_str_5[] PROGMEM = "t puffer teteje"; prog_char homeronev_str_6[] PROGMEM = "t puffer kozepe"; prog_char homeronev_str_7[] PROGMEM = "t puffer alja"; prog_char homeronev_str_8[] PROGMEM = "t rad vissza"; prog_char homeronev_str_9[] PROGMEM = "t tagulasi"; prog_char homeronev_str_10[] PROGMEM = "t puffer atlag"; #define count_flags 10 prog_char flags_str_0[] PROGMEM = "Kazan sziv megy?"; // "flags_str 0" etc are flags_strs to store - change to suit. prog_char flags_str_1[] PROGMEM = "Rad. sziv megy?"; prog_char flags_str_2[] PROGMEM = "Mot szelep nyit?"; prog_char flags_str_3[] PROGMEM = "Mot szelep zar?"; prog_char flags_str_4[] PROGMEM = "Kazan tulhevul?"; prog_char flags_str_5[] PROGMEM = "Kazan melegszik?"; prog_char flags_str_6[] PROGMEM = "Kazan meleg?"; prog_char flags_str_7[] PROGMEM = "Futes igeny van?"; prog_char flags_str_8[] PROGMEM = "Melegviz van?"; prog_char flags_str_9[] PROGMEM = "Szelep vegallas?"; #define count_hibanev 4 prog_char hibanev_str_0[] PROGMEM = "Fagyveszely"; // "hibanev_str 0" etc are hibanev_strs to store - change to suit. prog_char hibanev_str_1[] PROGMEM = "Kazan forras"; prog_char hibanev_str_2[] PROGMEM = "Elmaradas"; prog_char hibanev_str_3[] PROGMEM = "Tulfutes";
#define count_maradek_kiiras 11 prog_char maradekadat_str_0[] PROGMEM = "Gorbe meredekseg"; // "maradekadat_str 0" etc are maradekadat_strs to store - change to suit. prog_char maradekadat_str_1[] PROGMEM = "Gorbe eltolas"; prog_char maradekadat_str_2[] PROGMEM = "Homers szenzorok"; prog_char maradekadat_str_3[] PROGMEM = "Szelepirany"; prog_char maradekadat_str_4[] PROGMEM = "Szelep mozgasido"; prog_char maradekadat_str_5[] PROGMEM = "Szelep allasido"; prog_char maradekadat_str_6[] PROGMEM = "Szelepallas"; prog_char maradekadat_str_7[] PROGMEM = "Szelep mozg ido"; prog_char maradekadat_str_8[] PROGMEM = "Ido"; prog_char maradekadat_str_9[] PROGMEM = "Kov.beavatk."; prog_char maradekadat_str_10[] PROGMEM = "Szabad memoria"; PROGMEM const char *hibanev_string_table[] = { hibanev_str_0, hibanev_str_1, hibanev_str_2, hibanev_str_3 ; PROGMEM const char *homeronev_string_table[] = { homeronev_str_0, homeronev_str_1, homeronev_str_2, homeronev_str_3, homeronev_str_4, homeronev_str_5, homeronev_str_6, homeronev_str_7, homeronev_str_8, homeronev_str_9, homeronev_str_10 ; PROGMEM const char *flags_string_table[] = { flags_str_0, flags_str_1, flags_str_2, flags_str_3, flags_str_4, flags_str_5, flags_str_6, flags_str_7, flags_str_8, flags_str_9 ; PROGMEM const char *maradekadat_string_table[] = { maradekadat_str_0, maradekadat_str_1, maradekadat_str_2, maradekadat_str_3, maradekadat_str_4, maradekadat_str_5, maradekadat_str_6, maradekadat_str_7, maradekadat_str_8,
maradekadat_str_9, maradekadat_str_10 ; boolean aktualis_hiba [count_hibanev] = { false, false, false, false ; void lcd_aktualis_adat_inc() { loop_print_position += 1; if (loop_print_position >= count_homeronev + count_hibanev + count_flags + count_maradek_kiiras) { loop_print_position = 0; void lcd_aktualis_adat_dec() { loop_print_position -= 1; if (loop_print_position == -1) { loop_print_position = count_homeronev + count_hibanev + count_flags + count_maradek_kiiras - 1; void print_adatok () { if (serial_adatok_kikuldese) { serial_prints(); // ez csak tesztelési célra kell - a program elején van definiálva, hogy kell-e a serial_adatok_kikuldese lcd.clear(); lcd.setcursor(0,0); // ez valószínű nem kell a clear() után lcd.print (LCD_get_string_1(loop_print_position)); lcd.setcursor(0,1); lcd.print (LCD_get_string_2(loop_print_position)); // centigrade jele + C kiírása a hőmérsékletekhez!!! -> C if (loop_print_position < count_homeronev) { lcd.write(223); // - jele - WRITE!!! és nem print lcd.print ("C"); void LCD_kivilagit () { elsotetedesi_ido = millis() + vilagitasi_ido; // következő elsötétedés időpontja - Ha pont az 50.nap-on történik a millis() túlcsordulási idejében, akkor azonnal elfog elsötétedni a képernyő lcd.setbacklight(high); lcd_vilagit = true; void LCD_elsotetul () { lcd.setbacklight(low); lcd_vilagit = false; void setup() { lcd.begin(16, 2); // ez a sokpines és az I2C-s lcd-nél is ugyanaz!!! lcd.setbacklightpin(backlight_pin,positive); // háttérvilágítás inicializálása LCD_kivilagit(); Serial.begin(115200);
// Setup the button with an internal pull-up : pinmode(button_pin_1,input_pullup); pinmode(button_pin_2,input_pullup); // After setting up the button, setup the Bounce instance : debouncer1.attach(button_pin_1); debouncer2.attach(button_pin_2); debouncer1.interval(100); // interval in ms debouncer2.interval(100); // interval in ms // meredkség számítása szelep mozgásidőhöz és várakozási időhöz - az egyszerűség kedvéért // mozgásidő emelkedő, várakozási idő csökkenő (negatív) meredekseg_szelep_mozgas_ido = (szelep_beavatkozas_max - szelep_beavatkozas_min) / (homerseklet_elteres_max - homerseklet_elteres_min) ; meredekseg_szelep_varakozasi_ido = (szelep_varakozas_max - szelep_varakozas_min) / (homerseklet_elteres_max - homerseklet_elteres_min) ; gorbe_potmeterek_beolvasasa; sensors.begin(); /* totaldevices = discoveronewiredevices(); // get addresses of our one wire devices into alladdress array for (byte i=0; i < totaldevices; i++) sensors.setresolution(alladdress[i], 10); */ for (byte i=0; i < NumberOfDevices; i++) sensors.setresolution(alladdress[i], DS18B20resolution[i]); // and set the a to d conversion resolution of each. // To avoid unwanted startings of pumps or valve // Usually (and this practical) 4 relays board is ACTIVE LOW //-------( Initialize Pins so relays are inactive at reset)---- digitalwrite(relay_1, RELAY_OFF); digitalwrite(relay_2, RELAY_OFF); digitalwrite(relay_3, RELAY_OFF); digitalwrite(relay_4, RELAY_OFF); //delay(4000); //Check that all relays are inactive at Reset //---( THEN set pins as outputs )---- pinmode(relay_1, OUTPUT); pinmode(relay_2, OUTPUT); pinmode(relay_3, OUTPUT); pinmode(relay_4, OUTPUT); // delay(4000); //Check that all relays are inactive at Reset /* ------------Dallasos hőmérők DS18B20 címeinek kiírása------------ */ //Jó más OneWire alkatrészekhez is /* byte discoveronewiredevices() { byte j=0; // search for one wire devices and // copy to device address arrays. while ((j < NumberOfDevices) && (onewire.search(alladdress[j]))) { j++; for (byte i=0; i < j; i++) { Serial.print("Device "); Serial.print(i); Serial.print(": "); printaddress(alladdress[i]); // print address from each device address arry.
Serial.print("\r\n"); return j ; // return total number of devices found. */ /* void printaddress(deviceaddress addr) { byte i; for ( i=0; i < 8; i++) { // prefix the printout with 0x Serial.print("0x"); if (addr[i] < 16) { Serial.print('0'); // add a leading '0' if required. Serial.print(addr[i], HEX); // print the actual value in HEX if (i < 7) { Serial.print(", "); Serial.print("\r\n"); */ // Ez nem kell!!! void printtemperature(deviceaddress addr) { float tempc = sensors.gettempc(addr); // read the device at addr. if (tempc == -127.00) { Serial.print("Error getting temperature"); Serial.print(printFloat(tempC, 1)); // and print its value. Serial.print(" C ("); /* Serial.print(DallasTemperature::toFahrenheit(tempC)); Serial.print(" F)"); */ void homerseklet_beolvasas () { sensors.requesttemperatures(); // Initiate temperature request to all devices homerseklet_szenzorok_beolvasasa_sikeres =""; for (byte i=0; i < NumberOfDevices; i++) { homerseklet [i+1] = sensors.gettempc(alladdress[i]);// A 0. az elméleti radiátor előremenő!!! if (homerseklet [i+1] > -125 ) { // Ha az érték -127, akkor nem sikerült lekérdezni a hőmérsékletet! homerseklet_szenzorok_beolvasasa_sikeres += "+"; homerseklet_szenzorok_beolvasasa_sikeres += "-"; void gorbe_potmeterek_beolvasasa () { for (byte i=0; i < 2; i++) { float sum_analogin = 0; float analogin; for (byte j=0; j < analog_mintavetel ; j++) { analogin = analogread(analogin_gorbe_alapadatok[2][i]); sum_analogin += (float)analogin; analogin = sum_analogin / (float)analog_mintavetel ; // +0.5 nem kell, mert nagyon kicsit befolyásol if (i==0) {
gorbe_szamitas_s = map ((int)analogin, 0, 1023, analogin_gorbe_alapadatok[0][i], analogin_gorbe_alapadatok[1][i]); gorbe_szamitas_s = gorbe_szamitas_s / 10; if (i==1) { gorbe_szamitas_dy = map ((int)analogin, 0, 1023, analogin_gorbe_alapadatok[0][i], analogin_gorbe_alapadatok[1][i]); gorbe_szamitas_dy = gorbe_szamitas_dy / 10; /* Serial.print(i); Serial.print(' - '); Serial.println(sum_analogin); */ void homerseklet_beolvasas_probauzem () { // CSAK TESZTELÉSI CÉLLAL - 5 DB POTMETER HŐMÉRŐK HELYETTESÍTÉSÉHEZ // read the input on analog pins: for (byte i=0; i <= 4; i++) { int analogin = analogread(i); homerseklet [i+1] = map (analogin, 0, 1023, analogin_probauzem_map[0][i] * 10, analogin_probauzem_map[1][i] * 10); homerseklet [i+1] = homerseklet [i+1] / 10; homerseklet[6] = 50; homerseklet[7] = 50; homerseklet[8] = 33; homerseklet[9] = 5; homerseklet_szenzorok_beolvasasa_sikeres =""; for (byte i=0; i < NumberOfDevices; i++) { if (homerseklet [i+1] > -125 ) { // Ha az érték -127, akkor nem sikerült lekérdezni a hőmérsékletet! homerseklet_szenzorok_beolvasasa_sikeres += "+"; homerseklet_szenzorok_beolvasasa_sikeres += "-"; // A 0. az elméleti radiátor előremenő!!! // Serial.println(sensorValue); //delay(1); // delay in between reads for stability String LCD_get_string_1 (int print_pos) { String kijelzo; if (print_pos < count_homeronev) { strcpy_p(buffer, (char*)pgm_read_word(&(homeronev_string_table[print_pos]))); kijelzo = buffer; if ( (print_pos >= count_homeronev) && (print_pos < (count_homeronev + count_flags))) { strcpy_p(buffer, (char*)pgm_read_word(&(flags_string_table[print_pos - count_homeronev ]))); kijelzo = buffer; // kijelzo = flags[print_pos - count_homeronev]; if ( print_pos >= (count_homeronev + count_flags) && print_pos < (count_homeronev +
count_flags + count_hibanev)) { strcpy_p(buffer, (char*)pgm_read_word(&(hibanev_string_table[print_pos - count_homeronev - count_flags ]))); kijelzo = buffer; // kijelzo = aktualis_hiba_megnevezese[print_pos - count_homeronev - count_flags]; if ( print_pos >= (count_homeronev + count_flags + count_hibanev) && print_pos < (count_homeronev + count_flags + count_hibanev + count_maradek_kiiras)) { strcpy_p(buffer, (char*)pgm_read_word(&(maradekadat_string_table[print_pos - count_homeronev - count_flags - count_hibanev]))); kijelzo = buffer; // kijelzo = maradek_adat_megnevezese[print_pos - count_homeronev - count_flags -count_hibanev]; return kijelzo; String igen_nem (boolean boo) { if (boo) { return "igen"; else { return "nem"; String LCD_get_string_2 (int print_pos) { String kijelzo; char grade_sign = 223; // jele ASCII-ben if (print_pos < count_homeronev) { kijelzo = printfloat(homerseklet[print_pos], 1); // e tizedesjegy pontosságú mindegyik if ( print_pos >= count_homeronev && print_pos < (count_homeronev + count_flags)) { switch (print_pos - count_homeronev) { case 0: kijelzo = igen_nem (szivattyu_kazan_do); case 1: kijelzo = igen_nem (szivattyu_radiator_do); case 2: kijelzo = igen_nem (motoros_szelep_nyitasban); case 3: kijelzo = igen_nem (motoros_szelep_zarasban); case 4: kijelzo = igen_nem (kazan_tulhevules_flag); case 5: kijelzo = igen_nem (kazan_melegedes_flag); case 6: kijelzo = igen_nem (kazan_meleg_flag);
case 7: kijelzo = igen_nem (futeni_kell_flag); case 8: kijelzo = igen_nem (van_melegviz_flag); case 9: kijelzo = igen_nem (szelep_a_vegallasban); default: // if nothing else matches, do the default // default is optional kijelzo = "???"; ; if ( print_pos >= (count_homeronev + count_flags) && print_pos < (count_homeronev + count_flags + count_hibanev)) { // kijelzo = aktualis_hiba_megnevezese[print_pos - count_homeronev - count_flags]; if (aktualis_hiba[print_pos - count_homeronev - count_flags]) { kijelzo = "fenn all"; kijelzo = "nem all fenn"; if ( print_pos >= (count_homeronev + count_flags + count_hibanev) && print_pos < (count_homeronev + count_flags + count_hibanev + count_maradek_kiiras)) { // kijelzo = maradek_adat_megnevezese[print_pos - count_homeronev - count_flags]-count_hibanev]; switch (print_pos - count_homeronev-count_flags - count_hibanev) { case 0: kijelzo = printfloat(gorbe_szamitas_s,1); case 1: kijelzo = printfloat(gorbe_szamitas_dy,1); case 2: kijelzo = homerseklet_szenzorok_beolvasasa_sikeres; case 3: if (szamitott_szelep_irany == 0) { kijelzo = "Nincs"; else if (szamitott_szelep_irany == 1) { kijelzo = "NYIT"; kijelzo = "ZAR"; case 4: kijelzo = printfloat((float)szamitott_szelep_mozgas_ido / 1000,1) + " sec"; case 5: kijelzo = printfloat((float)szamitott_szelep_varakozas_ido / 1000,1) + " sec"; case 6:
kijelzo = printfloat(szamitott_szelep_allas,0) + " %"; case 7: kijelzo = printfloat((float)szamitott_szelep_mozgas_ido_ossz / 1000,1) + " sec"; case 8: kijelzo = printfloat((float) millis() / 1000, 1) + " sec" ; case 9: kijelzo = printfloat((float) next_action_time / 1000, 1) + " sec" ; case 10: kijelzo = String(freeRam()) + " byte"; default: kijelzo = "???"; return kijelzo; void homerseklet_szamitasok() { //t5 * 40% + t6 * 35% + t7 * 25% = puffer hőmérséklete (arányok a puffer hőmérők eloszlása alapján) // Bernáth Róbert által megadott képlet diagramból //t0 = 0.74 * pow(s * (20-t1) * 5.26, 0.77 ) + 20 // elméleti hőmérséklet kiszámítása if (homerseklet[1] < 20) { // külső hőmérséklettel kapcsolatos! homerseklet[0] = 0.74 * pow( gorbe_szamitas_s * (20-homerseklet[1]) * 5.26, 0.77 ) + 20 + gorbe_szamitas_dy ; // fűtési görbe számítása radiátoros fűtéshez homerseklet[0] = 20 + gorbe_szamitas_dy ; // belső hőmérséklettel kapcsolatos! // puffer átlaghőmérséklet homerseklet[10] = homerseklet[5] * 0.4 + homerseklet[6] * 0.35 + homerseklet[7] * 0.25; // puffer közepes hőmérséklet számítása void loop() { switch (loop_position) { case 0: // hőmérsékletek beolvasása, számítások elvégzése, szivattyúk, szelepek beállítása homerseklet_beolvasas (); // DS18B20 hőmérők //homerseklet_beolvasas_probauzem();// próbaüzem 5db analóg potmeter hőmérő helyett homerseklet_szamitasok(); szivattyu_logika(); // először van a szivattyú logika, utána a szelepmozgás, mert ha nem megy a radiátoros szivattyú, akkor a motoros szelepnek sem kell működnie szelep_mozgas_szamitasa(); hibajegyzek_feltoltese (); set_relays(); //relé kimenetek beállítása
loop_position = 1; next_action_time = millis() + szamitott_szelep_mozgas_ido; if (next_action_time < szamitott_szelep_mozgas_ido ) { // ha túlcsordul az idő számláló, akkor hagyjon ki egy "ütemet" ~50 naponként fordul elő + az induláskor!!! delay(szamitott_szelep_mozgas_ido + szamitott_szelep_varakozas_ido); if (lcd_vilagit) { gorbe_potmeterek_beolvasasa(); // kiíráskor mutassa meg a potméterek értékét // mindig egy kicsit más az ellenállás értéke a potméternek, ezért csak akkor kerül beolvasásra, ha az LCD világít print_adatok(); /* if ( millis() > szamitott_szelep_mozgas_ido) { // ez a feltétel az induláskor kell. Enélkül a szelep ki-be kapcsolgatna, ameddig el nem telik a szamitott_szelep_mozgas_ido -nyi idő loop_position = 1; last_action_time = millis(); next_action_time = millis() + szamitott_szelep_mozgas_ido; serial_prints(); */ case 1: // szelep beavatkozási idő vége, szelepek leállítása if (millis() > next_action_time) { motoros_szelep_nyitasban = false; motoros_szelep_zarasban = false; loop_position = 2; next_action_time = millis() + szamitott_szelep_varakozas_ido; set_relays(); //relé kimenetek beállítása print_adatok(); ; case 2: // várakozás vége, mehet a ciklus elejére if (millis() > next_action_time) { loop_position = 0; //last_action_time = millis(); ; default: // ez üres, ide sohasem juthat el a pogram ; // if nothing else matches, do the default // default is optional //// Gombnyomások figyelése // Get the updated value : debouncer2.update(); int value2 = debouncer2.read(); debouncer1.update(); int value1 = debouncer1.read();
if ( (value1 == LOW value2 == LOW)) { // valamelyik gomb megnyomása if (!button_pressed) { // ha még nem volt nyomva gomb, akkor értékek állítása, kiírása if (lcd_vilagit) { if ( value1 == LOW ) { lcd_aktualis_adat_inc(); if ( value2 == LOW ) { lcd_aktualis_adat_dec(); print_adatok(); button_pressed = true; LCD_kivilagit(); // nincs gomb megnyomva button_pressed = false; if (lcd_vilagit && (millis() > elsotetedesi_ido)) { LCD_elsotetul(); // delay (5); //???????????????????? Ez kell??????????????????? void hibajegyzek_feltoltese () { if ( homerseklet[9] < hiba_hideg_tagtartaly_hom ) { aktualis_hiba[0] = true; aktualis_hiba[0] = false; if ( homerseklet[2] > kazan_forro ) { aktualis_hiba[1] = true; aktualis_hiba[1] = false; if ( homerseklet[3] - homerseklet [0] < hiba_futes_elmaradas_hom ) { aktualis_hiba[2] = true; aktualis_hiba[2] = false; if ( homerseklet[3] - homerseklet [0] > hiba_futes_magas_hom ) { aktualis_hiba[3] = true; aktualis_hiba[3] = false;
void serial_prints() { for (byte i=0; i < count_homeronev + count_hibanev + count_flags + count_maradek_kiiras; i++) { //loop_print_position = i; Serial.print(i); Serial.print("- "); Serial.print(LCD_get_string_1(i)); Serial.print(": "); Serial.print(LCD_get_string_2(i)); Serial.print("\n\r"); void set_relays() { // example digitalwrite(relay_1, RELAY_ON);// set the Relay ON /* boolean szivattyu_kazan_do = false; // szivattyú jel kazánköri boolean szivattyu_radiator_do = false; // szivattyú jel radiátorköri boolean motoros_szelep_zarasban = false; boolean motoros_szelep_nyitasban */ if (szivattyu_kazan_do) { digitalwrite(relay_1, RELAY_ON); digitalwrite(relay_1, RELAY_OFF); if (szivattyu_radiator_do) { digitalwrite(relay_2, RELAY_ON); digitalwrite(relay_2, RELAY_OFF); if (motoros_szelep_nyitasban) { digitalwrite(relay_4, RELAY_OFF); digitalwrite(relay_3, RELAY_ON); digitalwrite(relay_3, RELAY_OFF); if (motoros_szelep_zarasban) { digitalwrite(relay_3, RELAY_OFF); digitalwrite(relay_4, RELAY_ON); digitalwrite(relay_4, RELAY_OFF); void szivattyu_logika() { // kazán szivattyú vezérlés if (kazan_tulhevules_flag) { // kazán forró, túlhevült
//- Ha t2 < (93C) ÉS (TÚLHEVÜLÉS FLAG magas) akkor TÚLHEVÜLÉS FLAG alacsony //Kazánköri szivattyú biztonsági indításának megszüntetése, ha a kazán hűl if (homerseklet [2] < kazan_forro ) { kazan_tulhevules_flag = false; else { //- Ha t2 > (95C) akkor 1-es szivattyú induljon + TÚLHEVÜLÉS FLAG magas //Kazánköri szivattyú biztonsági indítása, ha a kazán túlhevült. if (homerseklet [2] > (kazan_forro + kazan_forro_hiszterezis)) { kazan_tulhevules_flag = true; // túlhevülés else vége if (kazan_melegedes_flag) { // kazán melegszik, ég benne tűz //- Ha t2 < (t4 + 3C) akkor 1-es szivattyú álljon le //Kazánköri szivattyú leállítása, ha a kazán már kialudt, és esetleg a puffer alján keresztül áramlik a víz a kazán irányába if (homerseklet [2] < (homerseklet [4] + kazan_melegedes - kazan_melegedes_hiszterezis )) { kazan_melegedes_flag = false; else { //- Ha t2 > (t4 + 5C) akkor 1-es szivattyú induljon //Kazánköri szivattyú indítása, ha a kazán melegszik (van hőtermelés) if (homerseklet [2] > (homerseklet [4] + kazan_melegedes )) { kazan_melegedes_flag = true; // melegedés else vége if (kazan_meleg_flag) { // kazán meleg // - Ha t2 < 48C, akkor álljon le az 1-es szivattyú //Kazánköri szivattyú leállítása, ha hideg a víz a kazánban if (homerseklet [2] < (kazan_meleg)) { kazan_meleg_flag = false; //- Ha t2 > 50C, akkor induljon az 1-es szivattyú //Kazánköri szivattyú indítása, ha meleg a víz a kazánban if (homerseklet [2] > (kazan_meleg + kazan_meleg_hiszterezis)) { kazan_meleg_flag = true; // kazán meleg else vége if (kazan_tulhevules_flag) { szivattyu_kazan_do = true; // ha kazán túlhevült, akkor induljon a szivattyú goto kazan_szivattyu_logika_vege; else if (!kazan_melegedes_flag) { szivattyu_kazan_do = false; // ha kazán nem melegszik, csak esetleg meleg, akkor álljon le goto kazan_szivattyu_logika_vege; else if (kazan_meleg_flag) { szivattyu_kazan_do = true;
szivattyu_kazan_do = false; kazan_szivattyu_logika_vege: // radiátoros szivattyú vezérlés if (van_melegviz_flag) { // - Ha (t5 ÉS!!! t2 ) < 32C vagy 50 C, akkor 2-es szivattyú álljon le // Ha nincs a rendszerben melegvíz (pufferben, ÉS a kazánban), akkor álljon le a radiátoros szivattyú if ((homerseklet [5] < (futoviz_valos_puff)) && (homerseklet [2] < (futoviz_valos_kazan ))) { van_melegviz_flag = false; // - Ha (t5 VAGY!!! t2 ) > 34C vagy 53C, akkor 2-es szivattyú induljon // Ha van a rendszerben melegvíz (pufferben, VAGY a kazánban), akkor induljon a radiátoros szivattyú if ((homerseklet [5] > (futoviz_valos_puff + futoviz_valos_puff_hiszterezis)) (homerseklet [2] > (futoviz_valos_kazan + futoviz_valos_puff_hiszterezis))) { van_melegviz_flag = true; if (futeni_kell_flag) { // - Ha t0 < 32C, akkor álljon le a 2-es szivattyú // Ha kinn melegszik, akkor álljon le a radiátoros szivattyú if (homerseklet [0] < (futoviz_elmeleti_min)) { futeni_kell_flag = false; //- Ha t0 > 34C, akkor induljon a 2-es szivattyú //Ha kinn hideg van, akkor induljon a radiátoros szivattyú if (homerseklet [0] > (futoviz_elmeleti_min + futoviz_elmeleti_min_hiszterezis)) { futeni_kell_flag = true; // fűteni kell else vége if (!van_melegviz_flag) { szivattyu_radiator_do = false; // ha nincs melegvíz a rendszerben, akkor álljon le goto radiator_szivattyu_logika_vege; else if (futeni_kell_flag) { // ha futeni kell(az elméleti radiátor előremenő hőmérséklet magas), akkor induljon a szivattyú szivattyu_radiator_do = true; szivattyu_radiator_do = false; radiator_szivattyu_logika_vege: szivattyu_radiator_do = szivattyu_radiator_do; // ez kell különben hibát ír ki az ARDUINO fordító!!! // a GOTO-hoz tartozó címke után szükséges még egy utasítás - bug lehet a Compilerben 1.0.6!!!!
void szelep_mozgas_szamitasa() { // homerseklet [0] - elméleti előremenő hőmérséklet // homerseklet [3] - radiátor előremenő hőmérséklet float temp_diff; // szelepirány számítása temp_diff = homerseklet [0] - homerseklet [3]; //pozitív, ha elmaradás van if (temp_diff > 0) { // pozitív szamitott_szelep_irany = 1; //nyit motoros_szelep_nyitasban = true; motoros_szelep_zarasban = false; szamitott_szelep_irany = 2; //zár motoros_szelep_nyitasban = false; motoros_szelep_zarasban = true; // mozgásidő számítása temp_diff = abs(temp_diff); // már nem kell a mozgás iránya if ((temp_diff < homerseklet_elteres_min) (!szivattyu_radiator_do )) { // eltérésen belül van VAGY nem megy a radiátoros szivattyú, akkor nincs szelepmozgás //szamitott_szelep_mozgas_ido = szelep_beavatkozas_min; // ennek nincs értelme itt, mert nem mozdul a szelep szamitott_szelep_varakozas_ido = szelep_varakozas_max; szamitott_szelep_irany = 0; motoros_szelep_nyitasban = false; motoros_szelep_zarasban = false; else if (temp_diff > homerseklet_elteres_max ) { // eltérés a maximumon felül - szelep zár maximum időben, minimum várakozási idővel szamitott_szelep_mozgas_ido = szelep_beavatkozas_max; szamitott_szelep_varakozas_ido = szelep_varakozas_min; // szelepirány korábban meghatározva temp_diff = temp_diff- homerseklet_elteres_min; // itt már csak a minimum eltérés feletti idővel számolunk szamitott_szelep_mozgas_ido = szelep_beavatkozas_min + temp_diff * meredekseg_szelep_mozgas_ido; szamitott_szelep_varakozas_ido = szelep_varakozas_max - temp_diff * meredekseg_szelep_varakozasi_ido ; // ------------ szelepállás becslése ------------ //ha túllépi a biztonsági értéket, akkor végállásban már, és % érték számítása elkezdődhet int temp_indulasi_biztonsagi_tullendules = szelep_utido_d_bizt_elso ; // az első túllendülésnél egy biztonsági szorzó is bekerül if (szamitott_szelep_allas_elkezdodott) { temp_indulasi_biztonsagi_tullendules = 0; if (szamitott_szelep_mozgas_ido_ossz > (1+temp_indulasi_biztonsagi_tullendules) * szelep_utido + szelep_utido_d_biztonsag) { szelep_a_vegallasban = true;
szamitott_szelep_allas_elkezdodott = true; if (szamitott_szelep_mozgas_ido_ossz < (-1) * (1 + temp_indulasi_biztonsagi_tullendules) * szelep_utido - szelep_utido_d_biztonsag) { szelep_a_vegallasban = true; szamitott_szelep_allas_elkezdodott = true; // Ha megfordul a mozgás iránya, akkor kilép a végállásból if ((szamitott_szelep_irany_utolso > 0 && szamitott_szelep_irany > 0) && (szamitott_szelep_irany_utolso!= szamitott_szelep_irany)) { // ha van mozgásirány de nem egyezik if (szelep_a_vegallasban) { //szamitott_szelep_mozgas_ido_ossz = 0; szelep_a_vegallasban = false; if (szamitott_szelep_irany == 1 ) { szamitott_szelep_mozgas_ido_ossz = 0; else if (szamitott_szelep_irany == 2) { szamitott_szelep_mozgas_ido_ossz = szelep_utido; // Ha mozgásidő negatív (el van zárva a szelep), akkor nullázva a szelepállás if (szamitott_szelep_irany == 1 && szamitott_szelep_mozgas_ido_ossz <0 ){ szamitott_szelep_mozgas_ido_ossz = 0; // Ha mozgásidő nagyobb mint az útidő (nyitva van zárva a szelep), akkor a szelepállás 100 %-on, azaz az útidőn if (szamitott_szelep_irany == 2 && szamitott_szelep_mozgas_ido_ossz > szelep_utido ){ szamitott_szelep_mozgas_ido_ossz = szelep_utido; // Mozgási idő összegzése. Nyit +, Zár -!! if ((szamitott_szelep_irany_utolso == szamitott_szelep_irany) && (!szelep_a_vegallasban) && (szamitott_szelep_irany >0)) { if (szamitott_szelep_irany == 1) { szamitott_szelep_mozgas_ido_ossz += szamitott_szelep_mozgas_ido; szamitott_szelep_mozgas_ido_ossz -= szamitott_szelep_mozgas_ido; if (szamitott_szelep_allas_elkezdodott) { // ha túl van az első túllendülésen, akkor tud számolni szelepállást, és korrigálja a %-os értéket if (szamitott_szelep_mozgas_ido_ossz >= szelep_utido) { // ha az útidőn kívül van, akkor végállás szamitott_szelep_allas = 100.0; else if (szamitott_szelep_mozgas_ido_ossz < 0) { // ha az útidőn kívül van, akkor végállás szamitott_szelep_allas = 0.0;
szamitott_szelep_allas = (float)szamitott_szelep_mozgas_ido_ossz / (float)szelep_utido * (float)100; if (szamitott_szelep_irany >0) { szamitott_szelep_irany_utolso = szamitott_szelep_irany; // Szelep "végállás" kapcsoló - ha túl sokszor mozgott egy irányba a szelep, akkor letilt if (motoros_szelep_vegallas_el && szelep_a_vegallasban) { szamitott_szelep_varakozas_ido = szelep_varakozas_max; szamitott_szelep_irany = 0; motoros_szelep_nyitasban = false; motoros_szelep_zarasban = false; // printfloat prints out the float 'value' rounded to 'places' places after the decimal point String printfloat(float value, int places) { // this is used to cast digits int digit; float tens = 0.1; int tenscount = 0; int i; float tempfloat = value; String numberasstring=""; // make sure we round properly. this could use pow from <math.h>, but doesn't seem worth the import // if this rounding step isn't here, the value 54.321 prints as 54.3209 // calculate rounding term d: 0.5/pow(10,places) float d = 0.5; if (value < 0) d *= -1.0; // divide by ten for each decimal place for (i = 0; i < places; i++) d/= 10.0; // this small addition, combined with truncation will round our values properly tempfloat += d; // first get value tens to be the large power of ten less than value // tenscount isn't necessary but it would be useful if you wanted to know after this how many chars the number will take if (value < 0) tempfloat *= -1.0; while ((tens * 10.0) <= tempfloat) { tens *= 10.0; tenscount += 1; // write out the negative if needed if (value < 0) // Serial.print('-'); numberasstring +="-"; if (tenscount == 0)
//Serial.print(0, DEC); numberasstring += "0"; for (i=0; i< tenscount; i++) { digit = (int) (tempfloat/tens); //Serial.print(digit, DEC); numberasstring += digit; tempfloat = tempfloat - ((float)digit * tens); tens /= 10.0; // if no places after decimal, stop now and return if (places <= 0) return numberasstring;; // otherwise, write the point and continue on //Serial.print('.'); numberasstring += "."; // now write out each decimal place by shifting digits one by one into the ones place and writing the truncated value for (i = 0; i < places; i++) { tempfloat *= 10.0; digit = (int) tempfloat; //Serial.print(digit,DEC); numberasstring += digit; // once written, subtract off that digit tempfloat = tempfloat - (float) digit; return numberasstring; int freeram () { extern int heap_start, * brkval; int v; return (int) &v - ( brkval == 0? (int) & heap_start : (int) brkval);