zonnescherm arduino project

Beste mensen, Ik ben bezig met een project om mijn zonnescherm automatisch te laten werken doormiddel van het toevoegen van een regensensor en ldr. Doordat de regensensor niet goed is heb ik deze even weggelaten. Het gaat mij nu om de ldr. Ik wil graag dat de ldr om de 10 minuten opnieuw wordt uitgelezen met analogread. Weet iemand hoe ik dit kan realiseren? Dus ik wil dat om de 10 minuten analogread opnieuw wordt gedaan in het programma zodat het zonnescherm niet om de paar miliseconde schakelt door een 'wolkje'ofzoiets.

code:


int ldrValue = 0; // variable to store the value coming from the sensor
int rainValue = 0; //variable to store the value coming from the sensor
int ldrPin = A1; // select the input pin for LDR 
int rainPin = A0; //select the input pint for Rainsensor
int zonneschermState;
int relaisOmlaagState;
long timeStampStartOmlaag;
int relaisOmhoogState;
long timeStampStartOmhoog;
//code voor status relais(relais hebben 2 ints).
int IN_ACTIVE = 0;
int ACTIVE_AAN = 1;
int ACTIVE_UIT = 2;
// code voor status zonneschermstate
int ONBEKEND = 0;
int OMLAAG = 1;
int OMHOOG = 2;
int ldrstatus;


int PIN_RELAIS_OMHOOG = 9; //select the output pin for the power switch (UP)
int PIN_RELAIS_OMLAAG = 10; //select the output pin for the power switch (DOWN)
unsigned long previousTime = 0; //begintijd van crystal


void setup() {
Serial.begin(9600); //sets serial port for communication
pinMode(ldrPin, INPUT); //select input pin as INPUT
pinMode(rainPin, INPUT); //select input pin as INPUT
pinMode(PIN_RELAIS_OMHOOG, OUTPUT); //select output pin as OUTPUT
pinMode(PIN_RELAIS_OMLAAG, OUTPUT); //select output pin as OUTPUT
zonneschermState = ONBEKEND; //status zonnescherm is nu onbekend
relaisOmlaagState = IN_ACTIVE; //omlaagrelais is nu niet actief
timeStampStartOmlaag = 0; //timestamp starten voor het omlaagrelais
relaisOmhoogState = IN_ACTIVE; //omhoogrelais is nu niet actief
timeStampStartOmhoog = 0; //timestamp starten voor het omhoogrelais
}

void loop() {
  
long ms;
int gewensteSchermState;
ms = millis();
previousTime = millis();
gewensteSchermState = zonneschermState;
ldrstatus = analogRead(ldrPin);
//if ((ldrValue > 700) && (rainValue > 500)){
if (ldrstatus > 900){
gewensteSchermState = OMLAAG;
Serial.println("zonnescherm omlaag, veel licht");
}

//if (rainValue <500) {
//gewensteSchermState = OMHOOG;
//Serial.println("zonnescherm omhoog, regen");
//} 

if (ldrstatus < 400){
gewensteSchermState = OMHOOG;
Serial.println("zonnescherm omhoog, te weinig licht");
} 

if(gewensteSchermState == OMLAAG)
{ 
//Het scherm moet omlaag, controleer en reset de state van het omhoog relais
  if(relaisOmhoogState != IN_ACTIVE)
  {
  if(relaisOmhoogState == ACTIVE_AAN)
  {
  digitalWrite(PIN_RELAIS_OMHOOG, LOW);
  timeStampStartOmhoog = 0;
}
 relaisOmhoogState = IN_ACTIVE;
  }

   if(relaisOmlaagState == IN_ACTIVE)
      {
        relaisOmlaagState = ACTIVE_AAN;

        timeStampStartOmlaag = ms;
        digitalWrite(PIN_RELAIS_OMLAAG, HIGH);
      }

 else if(relaisOmlaagState == ACTIVE_AAN && ((ms - timeStampStartOmlaag))>1000)
      {
        relaisOmlaagState = ACTIVE_UIT;
        digitalWrite(PIN_RELAIS_OMLAAG, LOW);
      }
} //nu gaat het scherm omlaag, de max timing van de druk op de schakelaar moet nog wel worden gewijzigd

 if(gewensteSchermState == OMHOOG)
    {
      // Het scherm moet omhoog, controleer en reset de state van het omlaag relais
      if(relaisOmlaagState != IN_ACTIVE)
      {
        // Check of het relais omlaag niet bekrachtigd wordt -> zo ja, eerst ontkrachten!!
        if(relaisOmlaagState == ACTIVE_AAN)
        {
          digitalWrite(PIN_RELAIS_OMLAAG,LOW);
          timeStampStartOmlaag = 0;
        }
        relaisOmlaagState = IN_ACTIVE;
      }

      if(relaisOmhoogState == IN_ACTIVE)
      {
        relaisOmhoogState = ACTIVE_AAN;

        timeStampStartOmhoog = ms;
        digitalWrite(PIN_RELAIS_OMHOOG, HIGH);
      }
      else if(relaisOmhoogState == ACTIVE_AAN && ((ms - timeStampStartOmhoog))>1000)
      {
        relaisOmhoogState = ACTIVE_UIT;

        digitalWrite(PIN_RELAIS_OMHOOG, LOW);
      }
    }
}


    

Gewoon alleen de LDR uitlezen als er genoeg milli()'s voorbij zijn gegaan.

En misschien ook de code laten inspringen, dan wordt het een stuk makkelijker om te zien wat er gebeurt.

[Bericht gewijzigd door deKees op woensdag 25 december 2019 18:13:04 (42%)

en gooi verschillende functies in een subroutines, want nu heb je 1 grote blok code waar geen kat aan uit geraakt.

Moeten de relais altijd bekrachtigt blijven?
ik zou dan 1 waarde gebruiken voor het aansturen.
bv

code:

void setup(){
...
}

void loop(){
   if (millis() - previousTime > 600000){ //laatste check meer dan 10min geleden
     checkLDR();
     stuurUitgangen();
     previousTime = millis();             //zet deze tijd als laatste check
   }
}


void checkLDR(){
  ldrstatus = analogRead(ldrPin);
}

void stuurUitgangen(){
....
}

persoonlijk zou ik elke minuut gaan uitlezen, en een gemiddelde nemen over 10min.
want als er 9min geen wolk is, maar de 10de minuut wel, gaat je scherm ook omhoog.

code:


int LDRvalue=0;
int loopA = 0;

void setup(){
...
}

void loop(){
   if (millis() - previousTime > 60000){ //laatste check meer dan 1min geleden
     LDRvalue = LDRvalue + checkLDR();    //tel de gemeten waarde op bij de vorige
     previousTime = millis();             //zet deze tijd als laatste check
     loopA++;                            //teller 1 omhoog
   }

   if (loopA >= 10){
     ldrstatus = LDRvalue / 10;          //gemiddelde van 10 metingen
     loopA = 0;
   }

   if (ldrstatus < 400){
      stuurUitgangen(OMLAAG);
   } 
   if (ldrstatus > 900){
      stuurUitgangen(OMHOOG);
   }
}


int checkLDR(){
  return analogRead(ldrPin);
}

void stuurUitgangen(int status){

  if (status == OMLAAG){                  //scherm moet omlaag
    digitalWrite(PIN_RELAIS_OMHOOG, LOW); //omhoog relais uit 
    delay(200);                         
    digitalWrite(PIN_RELAIS_OMLAAG, HIGH);//omlaag relais aan
  } else {                                  //scherm moet omhoog
    digitalWrite(PIN_RELAIS_OMLAAG, LOW); //omlaag relais uit
    delay(200);  
    digitalWrite(PIN_RELAIS_OMHOOG, HIGH);//omhoog relais aan
  }
}

in deze code kunnen ze nooit samen hoog staan. k heb er nog een delay van 200ms in gestoken om de relais tijd te geven om te schakelen

ik hou van werken ..., ik kan er uren naar kijken

Bedankt, zo kan ik dus een gemiddeld nemen per minuut en dan in de 10e minuut sturen?

Ik was er al uit . Per 10 minuten kijkt hij naar het weer maar neemt niet het gemiddelde per minuut.

Ik ga jouw manier proberen met het gemiddelde, bedankt

idd.
program start op 0min
na 1min meet die, bv 520
op 2min meet die nog eens, bv 480, en telt die op bij 520 (samen 1000)
op 3min nog een meting en optellen
...
na 10min heb je dan pakweg 6200 als waarde. je deelt die dan door 10 krijg je een gemiddelde van 620

je kan ook per minuut natuurlijk meten en daar een gemiddelde uitnemen.
bv elke 10sec een meting, heb je na 1 min
520, 540, 540, 530, 570, 530. gemiddelde na 1minuut is dan 538.

heb je een pak meer metingen, maar met wat nut? ga je binnen die minuut al veel variatie hebben dan?

door het opsplitsen in kleine deelprogrammas (meet de waarde, stuur de uitgang...) blijft je loop kort en overzichtelijk en weet je precies wat je doet.

stel dat jij nu manueel eens een waarde wil testen, dan kan je in de loop een testwaarde zetten om te zien welk resultaat het geeft.

bv

code:


void loop(){
   if (millis() - previousTime > 60000){ //laatste check meer dan 1min geleden
     LDRvalue = LDRvalue + checkLDR();    //tel de gemeten waarde op bij de vorige
     previousTime = millis();             //zet deze tijd als laatste check
     loopA++;                            //teller 1 omhoog
   }

   if (loopA >= 10){
     ldrstatus = LDRvalue / 10;          //gemiddelde van 10 metingen
     loopA = 0;
   }
*****
ldrstatus = 400;
*****
   if (ldrstatus < 400){
      stuurUitgangen(OMLAAG);
   } 
   if (ldrstatus > 900){
      stuurUitgangen(OMHOOG);
   }
}

nu is die 'checkLDR' functie maar absurd voor die ene regel. maar dit geeft in de toekomst nog wel voordelen. Stel nu bv dat je die LDR status als spanning wil zien, ipv een binaire waarde van 0-1023.

dan pas je gewoon aan in die ene functie

code:

float checkLDR(){
  int waarde = analogRead(ldrPin);
  float spanning = (waarde / 1024) * 5;
  return spanning;
}

zou je bv 620 meten binair, dan krijg je hier als resultaat dan 3,03 (volt).
en je hoeft niet in je hele programma te gaan zoeken waar de analogRead nog overal staat.

[Bericht gewijzigd door fcapri op woensdag 25 december 2019 21:45:04 (16%)

ik hou van werken ..., ik kan er uren naar kijken

En na 30 min is het altijd zonnig ;)

Ldrvalue ook maar ergens resetten?

Op 25 december 2019 21:44:26 schreef DK:
En na 30 min is het altijd zonnig ;)

Ldrvalue ook maar ergens resetten?

goeie, typische fout

code:


void loop(){
   if (millis() - previousTime > 60000){ //laatste check meer dan 1min geleden
     LDRvalue = LDRvalue + checkLDR();    //tel de gemeten waarde op bij de vorige
     previousTime = millis();             //zet deze tijd als laatste check
     loopA++;                            //teller 1 omhoog
   }

   if (loopA >= 10){
     ldrstatus = LDRvalue / 10;          //gemiddelde van 10 metingen
     loopA = 0;
     LDRvalue = 0;     //****reset LDR value to zero to start measuring again
   }
*****
ldrstatus = 400;
*****
   if (ldrstatus < 400){
      stuurUitgangen(OMLAAG);
   } 
   if (ldrstatus > 900){
      stuurUitgangen(OMHOOG);
   }
}

ik hou van werken ..., ik kan er uren naar kijken

Bedankt allemaal, topic kan gesloten wordenou

[Bericht gewijzigd door SvenTech op donderdag 26 december 2019 18:00:50 (75%)