Řízení kogenerační jednotky na dřevoplyn

Automatizace, řízení, měření, logování a programování s využitím platformy Arduino.
Rams
Příspěvky: 69
Registrován: pát srp 12, 2011 1:56 pm
Reputace: 5

Re: Řízení kogenerační jednotky na dřevoplyn

Příspěvek od Rams »

Už jsem začal znovu :D

Kód: Vybrat vše

    int trigPin01 = 8;  //snimac nasypky
    int echoPin01 = 9;  //snimac nasypky
    int echoPin02 = 4;  //snimac horaku
    int trigPin02 = 3;  //snimac horaku
    int Rele01 = 5; //rele nasypky

    int Rele01State = LOW;  //vichozi hodnota na pinu Rele01

    unsigned long previousMillis01 = 0; //posledni cas mereni paliva
    unsigned long previousMillis02 = 0; //posledni cas sepnuti Rele01
    long mereniPaliva = 15100;  //interval mereni paliva
    long casovacRele01 = 3100;  //interval sepnuti rele

    #include <SPI.h>
    int duration01,distance01,duration02,distance02,percentage,heightTank,deviation;
    
void setup() {
          Serial.begin (9600);
          pinMode(trigPin01,OUTPUT);
          pinMode(echoPin01,INPUT);
          pinMode(trigPin02,OUTPUT);
          pinMode(echoPin02,INPUT);
          pinMode(Rele01,OUTPUT);

}

void loop() {
      unsigned long currentMillis = millis();
      if (currentMillis - previousMillis01 >= mereniPaliva){
        int duration01,distance01,duration02,distance02,percentage,heightTank,deviation;
          heightTank=40;
          deviation=5;

          digitalWrite(trigPin01,LOW);
          delayMicroseconds(2);
          digitalWrite(trigPin01,HIGH);
          delayMicroseconds(10);
          digitalWrite(trigPin01,LOW);     
          duration01=pulseIn(echoPin01,HIGH);
          distance01=(duration01/2)/29.1;
          percentage=100-(((distance01-deviation)*100)/heightTank);

          Serial.println("_________________________");
          Serial.println();
          Serial.println("Stav nasypky:");
          Serial.print(percentage);
          Serial.println("% naplneni");
          Serial.print(distance01);
          Serial.println("cm od okraje");
          Serial.println();

          digitalWrite(trigPin02,LOW);
          delayMicroseconds(2);
          digitalWrite(trigPin02,HIGH);
          delayMicroseconds(10);
          digitalWrite(trigPin02,LOW);     
          duration02=pulseIn(echoPin02,HIGH);
          distance02=(duration02/2) / 29.1;
     
          Serial.println("Stav spalovaci komory:");
          Serial.print("palivo je ");
          Serial.print(distance02);
          Serial.println("cm od okraje");
          Serial.println();
          previousMillis01 = currentMillis;
      }

}
Rams
Příspěvky: 69
Registrován: pát srp 12, 2011 1:56 pm
Reputace: 5

Re: Řízení kogenerační jednotky na dřevoplyn

Příspěvek od Rams »

...začal, ale už o5 skončil..vůbec netuším jak tohle pořešit. Když je porušená jedna z podmínek na řádku 67, vypíší se jen stavy měření. Když jsou obě podmínky na řádku true, dojede program do konce, vypíše vše, ale nepočká 3000ms s vypnutím relé. Relé jen sepne a hned vypne.

Kód: Vybrat vše

        int trigPin01 = 8;  //snimac nasypky
        int echoPin01 = 9;  //snimac nasypky
        int echoPin02 = 4;  //snimac horaku
        int trigPin02 = 3;  //snimac horaku
        int Rele01 = 5; //rele nasypky

        int Rele01State = LOW;  //vichozi hodnota na pinu Rele01

        unsigned long previousMillis01 = 0; //posledni cas mereni paliva
        unsigned long previousMillis02 = 0; //posledni cas sepnuti Rele01
        long mereniPaliva = 6100;  //interval mereni paliva
        long casovacRele01 = 3000;  //interval sepnuti rele

        #include <SPI.h>
        int duration01,distance01,duration02,distance02,percentage,heightTank,deviation;
       
    void setup() {
              Serial.begin (9600);
              pinMode(trigPin01,OUTPUT);
              pinMode(echoPin01,INPUT);
              pinMode(trigPin02,OUTPUT);
              pinMode(echoPin02,INPUT);
              pinMode(Rele01,OUTPUT);

    }

    void loop() {
          unsigned long currentMillis = millis();
          if (currentMillis - previousMillis01 >= mereniPaliva){
            int duration01,distance01,duration02,distance02,percentage,heightTank,deviation;
              heightTank=40;
              deviation=5;

              digitalWrite(trigPin01,LOW);
              delayMicroseconds(2);
              digitalWrite(trigPin01,HIGH);
              delayMicroseconds(10);
              digitalWrite(trigPin01,LOW);     
              duration01=pulseIn(echoPin01,HIGH);
              distance01=(duration01/2)/29.1;
              percentage=100-(((distance01-deviation)*100)/heightTank);

              Serial.println("_________________________");
              Serial.println();
              Serial.println("Stav nasypky:");
              Serial.print(percentage);
              Serial.println("% naplneni");
              Serial.print(distance01);
              Serial.println("cm od okraje");
              Serial.println();

              digitalWrite(trigPin02,LOW);
              delayMicroseconds(2);
              digitalWrite(trigPin02,HIGH);
              delayMicroseconds(10);
              digitalWrite(trigPin02,LOW);     
              duration02=pulseIn(echoPin02,HIGH);
              distance02=(duration02/2) / 29.1;
         
              Serial.println("Stav spalovaci komory:");
              Serial.print("palivo je ");
              Serial.print(distance02);
              Serial.println("cm od okraje");
              Serial.println();
              previousMillis01 = currentMillis;
    
    if ((distance02 >= 20)&&(percentage >= 5)){
           Rele01State = HIGH;
           digitalWrite(Rele01, Rele01State);
          Serial.println("Zapinam podavac paliva... ");
          Serial.print("Rele podavace ve stavu: ");
          Serial.println(digitalRead(Rele01));
          Serial.println("-------------------------");
          Serial.println();
   
    // if (currentMillis - previousMillis02 > casovacRele01){
       if ((Rele01State == HIGH)&&(currentMillis - previousMillis02 > casovacRele01)){
           Rele01State = LOW;
           digitalWrite(Rele01, Rele01State);
           previousMillis02 = currentMillis;
          Serial.println("Vypinam podavac paliva... ");
          Serial.print("Rele podavace ve stavu: ");
          Serial.println(digitalRead(Rele01));
          Serial.println("-------------------------");
          Serial.println();
          }
    }
          }
    }
Rams
Příspěvky: 69
Registrován: pát srp 12, 2011 1:56 pm
Reputace: 5

Re: Řízení kogenerační jednotky na dřevoplyn

Příspěvek od Rams »

Pokud někdo ví jak toto opravit, moc bych byl vděčný, už fakt nevím jak z toho ven... Co se týká těch dalších funkcí programu, zmíněných výše ve vlákně, mám je dát před tento kód, nebo za něj? Podle mě je to jedno, ale jak vidno, nejsem v programování žádný guru a může existovat nějaké pravidlo pro skladbu o kterém nemám tušení. Myslím, že (ano, myslet znamená ho..o vědět) by to mohlo být asi nějak takhle:
{ zmer palivo a nasypku { zapni podavac podle mereni { vypni podavac }}} { mer RPM { toc servem }} { ovladej otacky ventilatoru } { hlidej kour }
Uživatelský avatar
rottenkiwi
Příspěvky: 5451
Registrován: pát úno 13, 2015 2:24 pm
Reputace: 285
Lokalita: SO, SK
Bydliště: SO, SK

Re: Řízení kogenerační jednotky na dřevoplyn

Příspěvek od rottenkiwi »

Treba ísť na to postupne, zvnútra cyklov/podmienok, otestovať, okomentovať každú zatvorku,
čo k čomu patrí a patrične formátovať text, lebo ak sa v tom ani ako autor nevyznám, ťažko to pochopí
bez komentárov a prísnej štruktúry syntaxe /iný/ človek, stroju je to jedno, može to byť aj jeden riadok kodu. :)

Prečo sú tam 2x deklarované tie isté premenné, raz v globálne a raz lokálne v nejakom inom bloku ?
Premenné sa vytvárajú na stacku a na heape, príp su v registroch CPU a treba vedieť, čo kedy kde
ako je v RAM a v CPU, čo je LIFO, FIFO atď.

Treba mať aj okomentované všetky volania funkcií/procedúr/metód, aby som vedel, čo posielam
ako referenciu, resp. čo ide cez registre/stack , aký je rámec platnosti deklarovaných premenných,
lebo sa potom može stať, že premmná "i" v jednom "scope of declaration" je iná ako premenná "i" v inom.

Keď nemám žiadny debugger, tak si musím metodiku "odvšivenia" urobiť sám, cez výpisy/kontrolné premenné.
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Rams
Příspěvky: 69
Registrován: pát srp 12, 2011 1:56 pm
Reputace: 5

Re: Řízení kogenerační jednotky na dřevoplyn

Příspěvek od Rams »

:celebrate1: už to maká :celebrate2:
Rams
Příspěvky: 69
Registrován: pát srp 12, 2011 1:56 pm
Reputace: 5

Re: Řízení kogenerační jednotky na dřevoplyn

Příspěvek od Rams »

teď to vypadá takhle:

Kód: Vybrat vše

    int trigPin01 = 8;  //nasypka
    int echoPin01 = 9;  //nasypka
    int echoPin02 = 4;  //spalovaci komora
    int trigPin02 = 3;  //spalovaci komora
    int Rele01 = 5; //rele podavace
    int bypass_tlacitko = 10; //tlacitko pro rucni plneni nasypky
    
    int Rele01State = LOW;  //vychozi stav rele v promenne
     
    #include <SPI.h>
    int duration01,distance01,duration02,distance02,percentage,heightTank,deviation;
    unsigned long previousMillis = 0;
             long interval01 = 10000; //cas za jak dlouho probehne mereni nasypky a spalovaci komory
             long interval02 = 3100;  //cas jak dlouho bude sepnute rele podavace
             long interval03 = 1500;  //cas vypisu bypass stavu
         
    void setup(){
          Serial.begin (9600);
          pinMode(trigPin01,OUTPUT);
          pinMode(echoPin01,INPUT);
          pinMode(trigPin02,OUTPUT);
          pinMode(echoPin02,INPUT);
          pinMode(Rele01,OUTPUT);
          pinMode(bypass_tlacitko, INPUT);
          heightTank=40;  //hloubka nasypky
          deviation=5;  //vzdalenost cidla od horni hladiny paliva v nasypce        
    }

    void loop(){  //1A
          unsigned long currentMillis = millis();
       if (currentMillis - previousMillis > interval01){  //2A - pokud je rozdil mezi aktualnim casem a casem predeslym vetsi nez hodnota intervalu, proved nasledujici:
          previousMillis = currentMillis; //aktualizuj cas
          digitalWrite(trigPin01,LOW);  //zacatek procesu mereni nasypky         
          delayMicroseconds(2);
          digitalWrite(trigPin01,HIGH);
          delayMicroseconds(10);
          digitalWrite(trigPin01,LOW);     
          duration01=pulseIn(echoPin01,HIGH); //konec procesu mereni nasypky
          distance01=(duration01/2)/29.1; //vypocitej vzdalenost mezi cidlem a hladinou paliva v cm
          percentage=100-(((distance01-deviation)*100)/heightTank); //vypocitej vzdalenost mezi cidlem a hladinou paliva v procentech, po odectu vzdalenosti cidla od max. hladiny paliva

          Serial.println("_________________________");  //zacatek vypisu na seriovou linku stavu predesleho mereni a vypoctu   
          Serial.println();
          Serial.println("Stav nasypky:");
          Serial.print(percentage);
          Serial.println("% naplneni");
          Serial.print(distance01);
          Serial.println("cm od okraje");
          Serial.println(); //konec vypisu na seriovou linku

          digitalWrite(trigPin02,LOW);  //zacatek procesu mereni spalovaci komory
          delayMicroseconds(2);
          digitalWrite(trigPin02,HIGH);
          delayMicroseconds(10);
          digitalWrite(trigPin02,LOW);     
          duration02=pulseIn(echoPin02,HIGH); //konec procesu mereni
          distance02=(duration02/2) / 29.1; //vypocet vzdalenosti v cm
     
          Serial.println("Stav spalovaci komory:"); //zacatek vypisu na seriovou linku stavu predesleho mereni a vypoctu
          Serial.print("palivo je ");
          Serial.print(distance02);
          Serial.println("cm od okraje");
          Serial.println(); //konec vypisu na seriovou linku
        
       if ((distance02 >= 20)&&(percentage >= 5)){   //3A - pokud je hladina paliva ve spalovaci komore vyssi nebo rovno 20cm a v nasypce je 5% a vice paliva proved nasledujici
          Rele01State = HIGH; //sepni rele podavace
          digitalWrite(Rele01, Rele01State);  //zapis stav rele do promenne 
          Serial.println("Zapinam podavac paliva... "); //vypis cinnosti na seriovou linku
          Serial.print("Rele podavace ve stavu: ");
          Serial.println(digitalRead(Rele01));
          Serial.println("-------------------------");
          Serial.println(); //konec vypisu  
        } //3B
          
  else if (Serial.println("Cekam na dalsi mereni... ")){  //4A - pokud se predesly blok neprovedl, vypis stav rele na seriovou linku
          Serial.print("Rele podavace ve stavu: ");
          Serial.println(digitalRead(Rele01));
          Serial.println("-------------------------");
          Serial.println();    
        } //4B
       }  //2B
          
       if ((digitalRead(Rele01) == HIGH)&&(currentMillis - previousMillis >= interval02)&&(digitalRead(bypass_tlacitko) == LOW)){  //5A - pokud je rele sepnute a cas od posledniho zapisu je vetsi nebo stejny nez hodnota intervalu02 a tlacitko bypassu neni sepnute, proved nasledujici:
          previousMillis = currentMillis; //aktualizuj cas
          Rele01State = LOW;  //vypni rele podavace
          digitalWrite(Rele01, Rele01State);  //zapis stav rele do promenne
          Serial.println("Vypinam podavac paliva... "); //vypis cinnosti na seriovou linku
          Serial.print("Rele podavace ve stavu: ");
          Serial.println(digitalRead(Rele01));
          Serial.println("-------------------------");
          Serial.println(); //konec vypisu na seriovou linku
        } //5B

       if ((digitalRead(bypass_tlacitko))&&(currentMillis - previousMillis >= interval03)){ //6A - (rucni spinani rele) pokud je na pinu tlacitka napeti
          previousMillis = currentMillis; //aktualizuj cas
          Rele01State = HIGH; //sepni rele podavace
          digitalWrite(Rele01, Rele01State);  //zapis stav rele do prommene
          Serial.println("Provadim rucni plneni... "); //vypis cinnosti na seriovou linku
          Serial.print("Rele podavace ve stavu: ");
          Serial.println(digitalRead(Rele01));
          Serial.println("-------------------------");
          Serial.println(); //konec vypisu na seriovou linku
        } //6B     

       } //1B 
Rams
Příspěvky: 69
Registrován: pát srp 12, 2011 1:56 pm
Reputace: 5

Re: Řízení kogenerační jednotky na dřevoplyn

Příspěvek od Rams »

Tak ne, v předešlém kódu byla procesní chyba, ikdyž vše zdánlivě fungovalo. Konkrétně tady:

Kód: Vybrat vše

       if ((digitalRead(bypass_tlacitko))&&(currentMillis - previousMillis >= interval03)){ //6A - (rucni spinani rele) pokud je na pinu tlacitka napeti
          previousMillis = currentMillis; //aktualizuj cas
          Rele01State = HIGH; //sepni rele podavace
          digitalWrite(Rele01, Rele01State);  //zapis stav rele do prommene
          Serial.println("Provadim rucni plneni... "); //vypis cinnosti na seriovou linku
          Serial.print("Rele podavace ve stavu: ");
          Serial.println(digitalRead(Rele01));
          Serial.println("-------------------------");
          Serial.println(); //konec vypisu na seriovou linku
        } //6B
Upravil jsem takto:

Kód: Vybrat vše

       if (digitalRead(bypass_tlacitko)){ //6A - pokud napeti na pinu tlacitka    
          Rele01State = HIGH; //sepni rele podavace
          digitalWrite(Rele01, Rele01State);  //zapis stav rele do prommene
        } //6B
        
       if ((digitalRead(bypass_tlacitko))&&(currentMillis - previousMillis >= interval03)){ //7A - pokud napeti na pinu tlacitka a cas od posledniho zapisu je vetsi nez interval03
          previousMillis = currentMillis; //aktualizuj cas
          Serial.println("Provadim rucni plneni... "); //vypis cinnosti na seriovou linku
          Serial.print("Rele podavace ve stavu: ");
          Serial.println(digitalRead(Rele01));
          Serial.println("-------------------------");
          Serial.println(); //konec vypisu na seriovou linku
        } //7B
Může být?

Odpovědět
  • Podobná témata
    Odpovědi
    Zobrazení
    Poslední příspěvek