posjirka
Vytvořené odpovědi
-
AutorPříspěvky
-
posjirkaÚčastník
// dohoreni //--------- dohoreni(); //} - #1 chyba - navic 1x slozena zavorka } else { Serial.println("Prostorovy termostat vypnut"); // ladici seriova komunikace }
posjirkaÚčastníkodstranil jsem 1 chybu kterou jsem našel a arduino mi jej normálně skompiluje.
Chyba byla v prebytecne zavorce v setup().// REGULACE PELETKOVEHO KOTLE // author. Johnyhol & by JP // v 14_5_2016 // changelog // v 13_11_2016 // zrusena reakce na prostorovy termostat -> není potreba, reseno jiz v kotli // v 10_11_2016 // uprava seriove komunikace -> pridani casovacu jednotlivych funkci // v 5_11_2016 // zmena casu - upraveno pro realny provoz // v 4_11_2016 // zmena vsech vystupu na rele // v 14_5_2016 // precislovani pinu // zmena funkce fotobunky z digitalu na analog // dolpneni seriove komunikace o hodnotu fotobunky // v 30_3_2016 // oprava funkce tlacitka kvitace poruchy -> HIGH->LOW // umazani parametru "long cas=13000;" -> jiz neni potreba // umazani parametru "//delay(84000); //pockej 84s" u funkce dohoreni -> jiz neni potreba // umazani parametru "//delay(12000); //po dobu 12s" u funkce davkovani zapalovaci davky pelet -> jiz neni potreba // umazani parametru "//if(digitalRead(prostorovyTermostat) == LOW || digitalRead(kotlovyTermostat) == LOW){ // prostorovy nebo kotlovy termostat vypne" u funkce zapaleni // drobne upravy textu/popisu jednotlivych parametru/funkci // v 27_3_2016 // uprava procesu zapalovani - nebude reagovat na prostorovy termostat // uprava dlouhych delayu na smycky, pro vyuziti watchdogu - autoreset pri zaseknuti procesou - doba nez se resetuje = 8s // nastaveni definice poruch pro pozdejsi vyuziti // v22_3_2016 // uprava ladicich textu pro termostaty // v21_3_2016 // presunuti testuPlamene pouze do smycky udrzuj horeni // doplneni textu do testu horeni // oprava textu zprav // zruseni diakritiky // zapnuti alarmu pri vyskytu poruchy // v20_3_2016 // slouceni podminenych funkci // vypnuti zhaveni pri rozepnuti termostatu (kotlovy nebo prostorovy) // rozdeleni funkci do vlastnich funkcnich bloku // zapojeni seriove komunikace pro odladeni funkci // v16_3_2016 // uprava podminky smycek (zruseno =) // posun zpozdeni 5s z procesu zapaleni na jeho konec // doplnena podminka reakce na termostaty (kotlovy/prostorovy) v procesu zapaleni // upravena doba na 1 zapalovaci proces - nastavitelna trimrem na analog.vstupu A0. v rozsahu 60 - 600 s = 1 - 10 min. - nastaveni pouze v dobe necinosti kotle // nastaveni poruchy a jeji kvitance tlacitkem na pinu 9 // definice poruch // bit funkce // 0 prehrati kotle pri zapalovani // 1 ztrata plamene pri horeni // 2 volne // 3 volne // 4 volne // 5 volne // 6 volne // 7 volne // knihovna watchdogu #include <avr/wdt.h> #define davkovaniPelet 2 //davkovani pelet snek #define spirala 3 //zapalovaci spirala #define ventilator 5 //ventilator #define alarm 6 //signalizace poruchy #define kotlovyTermostat 8 //kotlovy termostat #define fotobunka 15 //fotobunka pro kontrolu plamene DI15 = A1 pro arduino UNO #define trimr1 14 // nastaveni doby zapaleni DI14 = A0 pro arduino UNO #define tlacitkoKvitance 9 // pin tlacitka kvitance poruchy int smycka1 = 0; // pomocna smycka - zapaleni int smycka1max = 600; // max.pomocne smycky - ted jiz nastavitelne trimrem na A0 60-600s int smycka2 = 0; // pomocna smycka - udrzeni horeni int smycka2max = 2; // max.pomocne smycky int smycka3 = 0; // pomocna smycka - pocet pokusu o zapaleni int smycka3max = 2; // max.pomocne smycky int smycka4 = 0; // pomocna smycka - davkovani zapalne davky pelet int smycka4max = 10; // max.pomocne smycky int smycka5 = 0; // pomocna smycka - rozhoreni int smycka5max = 5; // max.pomocne smycky int smycka6 = 0; // pomocna smycka - dohoreni int smycka6max = 840; // max.pomocne smycky byte porucha = 0; // promenna pro zaznam poruchy int ldr = 1; //analogovy pin kde je pripojen fotorezistor int ldr_value = 0; //promenna pro zaznam hodnot z fotorezistoru void setup() { // nastav seriovou komunikaci na rychlost 9600 bd Serial.begin(9600); Serial.println("Nastavuji vstupy/vystupy"); // ladici seriova komunikace pinMode(davkovaniPelet, OUTPUT); pinMode(spirala, OUTPUT); pinMode(ventilator, OUTPUT); pinMode(alarm, OUTPUT); pinMode(kotlovyTermostat, INPUT); pinMode(fotobunka, INPUT); pinMode(trimr1, INPUT); pinMode(tlacitkoKvitance, INPUT); // vsechno vypni vypniVse(); // nastav watchdog na 8s wdt_enable(WDTO_8S); } void loop() { wdt_reset(); // resetuj watchdog ldr_value = analogRead(ldr); //čte hodnoty LDR Serial.print("HODNOTA FOTOBUNKY = "); Serial.println(ldr_value); //zobrazí hodnoty LDR na seriove lince Serial.println("Cekam na sepnuti termostatu ..."); // ladici seriova komunikace smycka1max = map(analogRead(trimr1), 0, 1024, 60, 600); // nastaveni doby zapaleni trimrem na A0 if(digitalRead(kotlovyTermostat) == HIGH){ // kotlovy termostat je zapnuty Serial.println("Kotlovy termostat zapnut"); // ladici seriova komunikace // startovaci davka pelet //------------------------ zapalovaciDavkaPelet(); // proces zapaleni //---------------- zapaleni(); // test poruchy // ----------------- //testPlamene(); // udrzeni horeni //-------------- udrzujHoreni(); // dohoreni //--------- dohoreni(); //} - #1 chyba - navic 1x slozena zavorka } else { Serial.println("Prostorovy termostat vypnut"); // ladici seriova komunikace } // kvitence pripadne poruchy //------------------------------- kvitancePoruchy(); } void vypniVse() { // funkce vypni vse Serial.println("Vypinam vsechny rele ..."); // ladici seriova komunikace digitalWrite(davkovaniPelet, HIGH); //vypni davkovani digitalWrite(spirala, HIGH); //vypni zhaveni digitalWrite(ventilator, HIGH); //vypni ventilator } void zapalovaciDavkaPelet() { // prvotni davkovani pelet pro zapaleni Serial.println("Davkuji pelety pro zapaleni ... 110s"); // ladici seriova komunikace digitalWrite(davkovaniPelet, LOW); //davkuj pelety for (smycka4 = 0; smycka4 < smycka4max; smycka4 ++){ delay(1000); wdt_reset(); // resetuj watchdog Serial.print("Stav: "); Serial.print(smycka4); Serial.print("s/"); Serial.print(smycka4max); Serial.println("s "); } digitalWrite(davkovaniPelet, HIGH); //potom vypni davkovani digitalWrite(ventilator, LOW); //zapni ventilator digitalWrite(spirala, LOW); //zapni zhaveni } void zapaleni() { // funkce zapaleni pelet // 2 pokusy o zapaleni Serial.println("Spoustim zapaleni ..."); // ladici seriova komunikace for (smycka3 = 0; smycka3 < smycka3max; smycka3 ++){ // smycka "1-10" minut zapalovani for (smycka1 = 0; smycka1 < smycka1max; smycka1 ++){ wdt_reset(); // resetuj watchdog Serial.print("Pokus o zapaleni "); // ladici seriova komunikace Serial.print(smycka3); // ladici seriova komunikace Serial.print("/"); // ladici seriova komunikace Serial.println(smycka3max); // ladici seriova komunikace Serial.print("Stav: "); // ladici seriova komunikace Serial.print(smycka1); // ladici seriova komunikace Serial.print("s/"); // ladici seriova komunikace Serial.print(smycka1max); // ladici seriova komunikace Serial.println("s "); // ladici seriova komunikace if(digitalRead(kotlovyTermostat) == LOW){ // kotlovy termostat vypne digitalWrite(spirala, HIGH); //vypni zhaveni smycka1 = smycka1max; // ukonci smycku1 smycka3 = smycka3max; // ukonci smycku3 Serial.println("Rozepnuti termostatu ..."); // ladici seriova komunikace bitSet(porucha,0); // nastav poruchu bit c.0 na "1" } if(analogRead(fotobunka) <= 500){ //pokud fotobunka vidi plamen digitalWrite(spirala, HIGH); //vypni zhaveni smycka1 = smycka1max; // ukonci smycku1 smycka3 = smycka3max; // ukonci smycku3 Serial.println(" hori ..."); // ladici seriova komunikace Serial.println("Rozhoreni ... 50s "); } else { Serial.println(" nehori ..."); // ladici seriova komunikace } delay(1000); } for (smycka5 = 0; smycka5 < smycka5max; smycka5 ++){ delay(1000); wdt_reset(); // resetuj watchdog Serial.print("Stav: "); Serial.print(smycka5); Serial.print("s/"); Serial.print(smycka5max); Serial.println("s "); } //delay(5000); //cekej 5s } } void udrzujHoreni() { // funkce udrzeni horeni ldr_value = analogRead(ldr); //čte hodnoty LDR Serial.print("HODNOTA FOTOBUNKY = "); Serial.println(ldr_value); //zobrazí hodnoty LDR na seriove lince Serial.println("Udrzeni horeni ..."); // ladici seriova komunikace for (smycka2 = 0; smycka2 < smycka2max; smycka2 ++){ wdt_reset(); // resetuj watchdog smycka2 = 0; // vynuluj smycku if(digitalRead(kotlovyTermostat) == HIGH){ // kotlovy termostat je zapnuty if(analogRead(fotobunka) <= 500){ //pokud fotobunka vidi plamen Serial.println("Test plamene ... hori"); // ladici seriova komunikace Serial.println("Davkuji pelety ... "); digitalWrite(davkovaniPelet, LOW); //davkuj pelety delay(4000); //pockej 4s wdt_reset(); // resetuj watchdog delay(4000); //pockej 4s wdt_reset(); // resetuj watchdog //Serial.print("s/"); //Serial.print(davkovaniPelet, LOW); //Serial.print("s "); Serial.println("Pauza ... "); digitalWrite(davkovaniPelet, HIGH); //vypni davkovani delay(5000); //pockej 5s wdt_reset(); // resetuj watchdog delay(5000); //pockej 5s wdt_reset(); // resetuj watchdog } else { delay(1000); // pocekej jeste 1s a zkus to znovu if(analogRead(fotobunka) >= 500){ //pokud fotobunka nevidi plamen Serial.println("Test plamene ... porucha"); // ladici seriova komunikace smycka2 = smycka2max; // ukonci smycku //porucha = 1; // nastav poruchu bitSet(porucha,1); // nastav poruchu bit c.1 na "1" digitalWrite(alarm, LOW); // zapni alarm } } } else { smycka2 = smycka2max; // ukonci smycku } } } void dohoreni() { // funkce dohoreni Serial.println("Dohoreni ... 840s "); // ladici seriova komunikace digitalWrite(davkovaniPelet, HIGH); //vypni davkovani pelet digitalWrite(spirala, HIGH); //vypni zhaveni - pro jistotu for (smycka6 = 0; smycka6 < smycka6max; smycka6 ++){ Serial.print("Stav: "); Serial.print(smycka6); Serial.print("s/"); Serial.print(smycka6max); Serial.println("s "); delay(1000); wdt_reset(); // resetuj watchdog } digitalWrite(ventilator, HIGH); //vypni ventilator } void kvitancePoruchy() { // funkce kvitance poruchy if(porucha > 0 ){ // kdyz je porucha aktivni Serial.println("Kvitance poruchy ..."); // ladici seriova komunikace // vypni vse vypniVse(); while (digitalRead(tlacitkoKvitance) == LOW) { // zapni alarm a cekej na stisk tlacitka digitalWrite(alarm, LOW); // zapni alarm Serial.println("Porucha ... cekam na kvitanci"); // ladici seriova komunikace wdt_reset(); // resetuj watchdog } Serial.println("Porucha kvitovana ..."); // ladici seriova komunikace digitalWrite(alarm, HIGH); // vypni alarm porucha = 0; // vynuluj poruchu } else { // jinak Serial.println("Zadna porucha ..."); // ladici seriova komunikace digitalWrite(alarm, HIGH); // vypni alarm } }
posjirkaÚčastníksuper …
posjirkaÚčastníkjohny, johny …. já tě chápu ale obávám se že je to pouze 1smerná komunikace. Nevím jak jinak ti to vysvětlit. Spočítal sis kolik je 8s + 1s ?
posjirkaÚčastníka kde máš to resetování watchdogu? 🙂
digitalWrite(davkovaniPelet, LOW); //davkuj pelety delay(4000); //pockej 4s wdt_reset(); // resetuj watchdog delay(4000); //pockej 4s wdt_reset(); // resetuj watchdog digitalWrite(davkovaniPelet, HIGH); //vypni davkovani delay(1000); //pockej 1s wdt_reset(); // resetuj watchdog
posjirkaÚčastníkco to znamená, že to nejde ? Nevím co měníš … hoď sem kod …
posjirkaÚčastníkten watchdog je ochranná funkce … jak jsem již psal …
celá funkce watchdog se skládá z:– vložení knihovny:
#include <avr/wdt.h>
– aktivace watchdogu v setupu :wdt_enable(WDTO_8S);
– průběžný reset :wdt_reset();
a 8s je pro něj maximum:
https://tushev.org/articles/arduino/5/arduino-and-watchdog-timer
add.2. – ano ten kod musíš napsat všude, kde bude čas delší než 8s. Radši méně, když máš pak víc funkcí nemusel by uplně všechno včas stíhat a omylem by se procesor sám resetoval.když chceš pauzu 10s tak jí rozděl na 2x 5s a pokaždé resetuj watchdog….
u 15s to rozděl na 3x 5s a opět pokaždé resetuj watchdog …posjirkaÚčastníkproblém je v tom, že je tu použit tzv. watchog. ten je nastaven na určitý čas (8s což je jeho maximum). když se nezresetuje včas watchdog a přeteče tak se resetuje celý procesor. To je ta halvní výhoda celéhe řešneí. Když se někde kousne procesor tak se sám resetuje a pokračuje dál . Je to odpově´d na otázku, proč nejde nastavit čas delší než 8s.
1. nepoužívej čas delší než 4-5s ať máš nějákou rezervu.
2. Pro delší čas použij více postupných pauz:delay(3000); wdt_reset(); // resetuj watchdog delay(3000); wdt_reset(); // resetuj watchdog delay(4000); wdt_reset(); // resetuj watchdog
celý kod je řešen opravdu primitivně. Tak jsem ho i bral aby s ena něm dalo dobře naučit jak co funguje. I proto jen jej rozdělil na funkce, které jsou zkoumat postupně. Mrkni na to a kdybys něco nepobíral, tak určitě napovíme ….
posjirkaÚčastníkjo sorry, já jsem si to zkusil na simulatoru a pak jsem to na hulvata prasknul do tvého kodu … jinak svetlo a svetlo1 jsou rozdílné proměnné. svetlo je doba za jak dlouho ma prejit z 0 na 255 (v minutách) a svetlo1 je pin kde je PWM výstup.
Ještě me pak napadlo jiné řešení, jednodušší a pro nastavení v menu jednodušší ale nevím kdy se na ně dostanu. …posjirkaÚčastníksouhasl s vojtěchem. dej si proměnnou „chyba=0“ a „close_time = 0“ pro záznam času při spuštění povelu k zavření. Tam si zapiš čas při zavření a změř si jak dlouho jede motor. Když to překročí čas, všechno vypni a zapiš si chybu + signalizuj chybu…
posjirkaÚčastníkto nasranek:
onečně jsem dokopal k tomu abych někde ukazal jak jsem myslel linearni rozložení rozsvěcení/zhasnutí na základě času. Trachu jsem upravil/zjednodušil tvůj program a mírně z přeházel některé funkce. Ta uprava co jsem udělal by měla odstranit ten neduh o zpožděné reakci v důsledku dlouhého delay(). Zjednodušil jse to proto aby bylo poznat co se tam měnilo. Jestli máš chut tak to prosím vyzkoušej. krok se mění 1x za minutu a funkcí map() se přepočítává na rozsah 0-255.#include <Wire.h> #include <DS3231.h> #define DS3231_I2C_ADDRESS 0x68 DS3231 rtc(SDA, SCL); int svetlo1 = 11;//pwm vystup int den = 9*60; // od kdy je den int noc = 21*60;// od kdy je noc int svetlo = 42; // doba rozsveceni/zhasnuti int cas = 0; // nasobek aktualnich hodin a minut byte jas = 0; // velikost jasu 0-255 byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; void setup() { rtc.begin(); lcd.clear();//smaže obrazovku lcd.setContrast(30);//nastavení kontrastu je to individuální, mám jich několik a každý chce něco jiného ale je to v rozmezí 30-60 Wire.begin(); pinMode(svetlo1, OUTPUT); } byte decToBcd(byte val){ return ( (val / 10 * 16) + (val % 10) ); } byte bcdToDec(byte val){ return ( (val / 16 * 10) + (val % 16) ); } void readDS3231time(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year) { Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(0); // set DS3231 register pointer to 00h Wire.endTransmission(); Wire.requestFrom(DS3231_I2C_ADDRESS, 7); *second = bcdToDec(Wire.read() & 0x7f); *minute = bcdToDec(Wire.read()); *hour = bcdToDec(Wire.read() & 0x3f); *dayOfWeek = bcdToDec(Wire.read()); *dayOfMonth = bcdToDec(Wire.read()); *month = bcdToDec(Wire.read()); *year = bcdToDec(Wire.read()); } void loop() { delay(1000); byte s, m, h, dvt, dvm, mesic, r; readDS3231time(&s, &m, &h, &dvt, &dvm, &mesic, &r); analogWrite(svetlo1, brightness); cas = h*m; // nasobek minut a hodin if (cas < den) { jas = 0; // jeste neni den tak nesvit } else { if(cas < (den+svetlo)}{ jas = map(cas, den, (den+svetlo), 0, 255); // rozsveceni } } if (cas > (noc + svetlo)) { jas = 0; // jeste neni den tak nesvit } else { if (cas > noc){ jas = map(cas, noc, (noc+svetlo), 255, 0); // zhasnuti } } }
posjirkaÚčastníkno já si myslim, že je to způsobeno použitím. měnit referenci a přitom mít zapojené na jiném analog.vstupu vyšší hodnotu je už z principu špatně. zkus zajet joystickem na s´tranu k zemi a zkus to . Případně dej Joystick na stejný potenciál jako je refernční napětí (nepoužívej interní) ….
posjirkaÚčastníkpánové ,proč to řešíte tak složitě ….
vezměte si, že budete mít konstantní zdroj 0,7V (dioda).
Když necháme refenreční napětí = napájecí napětí tak při 5V to bude třeba hodnota 200, když klesne napětí baterie na 3,5V tak to bude hodnota 400 (té konstaktny 0,7V) …posjirkaÚčastníkjak jsem psal, místo odporu 100k použij nějáký pevný stabilizátor. …. pro začátek třeba tu mojí zatracovanou diodu … obyč. dioda 1b4001 katodou na zem, anodou na analogový pin.
posjirkaÚčastníkneuvádíš jak je to zapojený …. máš tam stabilizator pro napájení mikroprocesoru, nebo přímo z baterie ?
Pokud ze satbilizátoru tak bych baterii dal přes odporový dělič a měřil výsledke. Doporučuju vyopočítat pro napětí tak 2/3 reference. Tady se počítá s tím, že s emění napětí baterie a refernční napětí zůstává stejné.
Druhá varinata je , že napájíš mikroprocesor přímo z baterie a tím pádem se ti mění i refernční napětí. v tom případě na baterii použij nějáký stabilizátor pro přesné refernční napětí (jen ne diodu ta je dost teplotně závislá), v nouzovém případě i klasický stabilizátor 7803 pro 3V. Pak budeš mít obrácenou logiku : snížení hodnoty analogvého pinu indikuje snížení napětí bateri / referenční napětí …Posuvník jako termín nechápu, předpokládám, že je to nějáký potenciometr připojený mezi zem a refenreční napětí, pak ti neovlivńuje funkci měření …
-
AutorPříspěvky