Beste mensen.
Wij hebben thuis een zonnescherm op een elektromotor. Deze werkt heel simpel. Door de schakelaar omhoog te doen gaat hij omhoog en door de schakelaar omlaag te doen gaat hij naar beneden. Ik wil nu deze zonnescherm automatisch laten lopen door hem aan te laten sturen door een ldr, een regensensor en een arduino nano. Ik heb hiervoor ook een ontwerp gemaakt en laten maken. alles is werkend. De printplaat heeft 2 relais en de ene relais bediend de bovenste knop en het andere relais bediend de onderste knop. Wanneer het zonnescherm omhoog gaat moet relais 1 uit staan en relais 2 aan.
Wanneer het zonnescherm omlaag gaat moet relais 1 aan staan en relais 2 uit.
[attachment=0]
Dit werkt tot nu toe heel erg goed . Het zonnescherm gaat omhoog wanneer er zon is en geen regen.
Het zonnescherm gaat omlaag wanneer er regen is (en zon).
Wat nu mijn probleem is is dat de printplaat de hele dag het zonnescherm omhoog of omlaag moet houden wat betekent dat 1 relais de hele tijd is bekrachtigd. Ik wil zelf dat ze even schakelen en daarna allebei uit gaan. Want ik hoef ook maar 1 keer te drukken op de bovenste knop (500ms) en dan gaat het zonnescherm omhoog of omlaag en blijft hij ook omlaag.
dus even moet relais 1 uit staan en relais 2 uit (omhoog). En dan weer uit na 500 ms.
Ik had al een delay gezet van 500 ms en daarna allebei de relais op low gezet maar wanneer de arduino dan de ldr en de regensensor uitleest gaat hij weer de relais opnieuw aan en uit doen na 500 ms.
Hij blijft dus in een loop.
Weten jullie hiervoor een oplossing.
ik hoop dat jullie mij hiermee kunnen helpen.
Me vriendelijke groeten,
Sven
zie bijlage
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 switch_1 = 9; //select the output pin for the power switch (UP)
int switch_2 = 10; //select the output pin for the power switch (DOWN)
void setup() {
Serial.begin(9600); //sets serial port for communication
pinMode(switch_1, OUTPUT);
pinMode(switch_2, OUTPUT);
}
void loop() {
//inlezen LDR
ldrValue = analogRead(ldrPin); // read the value from the ldr sensor
Serial.println(ldrValue); //prints the values coming from the sensor on the screen
delay(100);
//inlezen Rainsensor
rainValue = analogRead(rainPin); // read the value form the rain sensor
rainValue = analogRead(rainPin); // read the value from the rain sensor
Serial.println(rainValue); //prints the values coming from the sensor to the screen
delay(100);
/* Het is de bedoeling dat het zonnescherm omlaag gaat bij geen regen en veel licht
* Het is de bedoeling dat het zonnescherm omhoog gaat bij regen
* Het is de bedoeling dat het zonnescherm omhoog gaat bij weinig licht
*/
//hoofdcode
if ((ldrValue > 700) && (rainValue > 500)){
digitalWrite(switch_1, HIGH); //zonnescherm gaat omlaag bij geen regen en veel licht
digitalWrite(switch_2, LOW);
Serial.println("zonnescherm omlaag");
}
if (rainValue <500) {
digitalWrite(switch_1, LOW); //zonnescherm gaat omhoog bij veel regen
digitalWrite(switch_2, HIGH);
Serial.println("zonnescherm omhoog, regen");
}
if (ldrValue < 500){
digitalWrite(switch_1, LOW); //zonnescherm gaat omhoog bij weinig licht
digitalWrite(switch_2, HIGH);
Serial.println("zonnescherm omhoog, te weinig licht");
}
}buckfast_beekeeper
Van Lambiek wordt goede geuze gemaakt.
Je code tussen code tags maakt het een stuk leesbaarder.
Waarom lees je de regensensor 2 keer in? Niet dat dit je grootste probleem is.
In je tekst zet je het ook net omgekeerd met je code. Regen is scherm naar beneden in je tekst en naar boven in je code.
Je zal moeten bijhouden hoe je scherm staat en hoe je het wil. Pas als beide verschillen moet je de betreffende relais iets meer dan 500ms aansturen. Bijvoorbeeld variabele schermDicht 0= open (zon) 1= dicht. Dan in pseudo code
code sluiten
als regen en schermDicht = 0
sluiten uitgang aan
wacht x ms
uitgang uit
schermDicht = 1
code openen
als zon en schermDicht = 1
openen uitgang aan
wacht x ms
uitgang uit
schermDicht = 0
Zijn de standaard schakelaars momentschakelaars of hebben die ook een continu stand? Indien het laatste, hoe reageert de installatie als bijvoorbeeld de up toets vast aan is en je schakelt je relais om te dalen? Indien je relais aan blijft heb je hetzelfde probleem met je toetsen als met de toets die vast aan is.
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Tja, zo'n programma moet je toch echt zelf maken. Als je het eenvoudig wilt houden kun je het met een delay(x) functie doen. In de loop bekijk je steeds je sensoren. Als je besluit dat het scherm omhoog moet spring je naar een functie omhoog() waarin je de motor omhoog zet en dan 10 seconden wacht (dan zal ie wel omhoog zijn). Daarna zet je de motor uit en verlaat je de functie. Dan kom je in de loop terug en ga je weer kijken of je iets moet doen.
[edit] Ja inderdaad, je zult moeten bijhouden hoe je scherm staat. Als ie al omhoog is hoef je niet opnieuw omhoog te gaan.
[Bericht gewijzigd door flipflop op (12%)]
Progger
GMT+1
zet je code even in "code tags", dat leest stukken beter.
wat je kunt doen is het volgende. een "edge trigger" maken die schakelt, wanneer een waarde is veranderd ten opzichte van de vorige cyclus. hierdoor voer je een actie maar 1x uit.
uiteraard heb je nog wat filtering op je waarde nodig, anders zul je bij iedere wolk rond schemering op en neer gaan.
if ((ldrValue > 700) && (rainValue > 500)){
setpoint = 1; //zonnescherm gaat omlaag bij geen
}
if (rainValue <500) {
setpoint = 0; //zonnescherm gaat omhoog bij veel regen
}
if (ldrValue < 500){
setpoint = 0; //zonnescherm gaat omhoog bij weinig licht
}
if (setpoint != oldsetpoint) //deze code wordt eenmaal uitgevoerd als het setpoint wijzigd
{
if (setpoint==1)
{
digitalWrite(switch_1, HIGH);// omhoog
digitalWrite(switch_2, LOW);
delay(500);
}else{
digitalWrite(switch_1, LOW);// omlaag
digitalWrite(switch_2, HIGH);
delay(500);
}
}else{ //het setpoint is niet gewijzigd
digitalWrite(switch_1, LOW);// stil
digitalWrite(switch_2, LOW);
}
oldsetpoint=setpoint; //kopieer altijd setpoint, om de waarde te bewaren
[Bericht gewijzigd door Progger op (14%)]
beste progger,
Dit lijkt me een goede code. hoe kan ik old setpoint en setpoint declareren aan het begin?
Het is toch ook mogelijk om zonder te kijken of het zonnescherm omlaag of omhoog staat de relais 500 ms te schakelen. De schakelaar om het zonnescherm te bedienen is geen continu schakelaar want je hoeft maar 500 ms te drukken en dan gaat ie omhoog totdat hij omhoog is.
Ik zit pas net een halfjaar in het programmeren en ik begin steeds meer dingen te leren. super bedankt allemaal voor de snelle reacties
Je kunt een bi-stabiel relais gebruiken. Dat hoef je alleen maar een korte puls te geven en dan blijft hij in de gekozen stand staan.
Er bestaan in de handel kant en klare systemen voor dit doel. Die kijken niet alleen naar regen, maar ook naar windsnelheid. Als het te hard waait gaat het scherm omhoog.
Progger
GMT+1
het setpoint is een wenswaarde, niet de huidige status.
dus als setpoint van 0 naar 1 veranderd voert hij de "omhoog" code 1x uit, dus ook de delay (die heb ik tijdens mijn edit toegevoegd. ik weet niet of je die al had gezien)
je kan wenswaarde als een byte of int definieren, daar waar je ook de rainvalue definieert.
Of als je zeker weet dat "omhoog" en "omlaag" de enige waarden zijn als bool.
(dan geef je de waarden true en false, ipv 0 en 1)
https://www.arduino.cc/reference/en/language/variables/data-types/bool…
ik heb nu dit vor de setup. Hij zegt nu alleen dat oldsetpoint nog moet worden gedeclareerd. Kan ik deze nu ook gewoon als 0 declareren aan het begin?
:
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 setpoint = 0;
int ldrPin = A1; // select the input pin for LDR
int rainPin = A0; //select the input pint for Rainsensor
int switch_1 = 9; //select the output pin for the power switch (UP)
int switch_2 = 10; //select the output pin for the power switch (DOWN)Modedit: Eventjes tussen code tags geëpibreerd
[Bericht gewijzigd door Sine op (0%)]
Er bestaan in de handel kant en klare systemen voor dit doel. Die kijken niet alleen naar regen, maar ook naar windsnelheid. Als het te hard waait gaat het scherm omhoog.
Met geld kun je altijd alles kopen. Ook een lakei huren die dag en nacht bij het scherm staat om het te bedienen. Kost alleen een paar centen.
Hier is een uitdaging om het zelf te maken. En ik kan me daar de lol wel van inzien.
Maar aan de TS: Ik zou er inderdaad ook een windsnelheids meter en misschien een barometer bij implementeren.
zakt de luchtdruk ineens en af en toe een windvlaag dan scherm omhoog en omhoog laten zolang de luchtdruk laag blijft. Ik heb wel eens gezien dat op een gebouw de schermen de hele dag op en neer aan het gaan zijn. En juist bij plotselinge rukwinden omlaag blijven met alle gevolgen van dien.
[Bericht gewijzigd door Ex-fietser op (33%)]
Ik heb nu dit als volledige code. Hij blijft nog steeds bekrachtigd wanneer ik dit als code heb. Niet na 500 ms gaan de relais op rust. Kan iemand mij hiermee helpen?
{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 setpoint = 0;
int oldsetpoint=setpoint; //kopieer altijd setpoint, om de waarde te bewaren
int switch_1 = 9; //select the output pin for the power switch (UP)
int switch_2 = 10; //select the output pin for the power switch (DOWN)
void setup() {
Serial.begin(9600); //sets serial port for communication
pinMode(switch_1, OUTPUT);
pinMode(switch_2, OUTPUT);
}
void loop() {
//inlezen LDR
ldrValue = analogRead(ldrPin); // read the value from the ldr sensor
Serial.println(ldrValue); //prints the values coming from the sensor on the screen
delay(100);
//inlezen Rainsensor
rainValue = analogRead(rainPin); // read the value form the rain sensor
rainValue = analogRead(rainPin); // read the value from the rain sensor
//Serial.println(rainValue); //prints the values coming from the sensor to the screen
delay(100);
/* Het is de bedoeling dat het zonnescherm omlaag gaat bij geen regen en veel licht
* Het is de bedoeling dat het zonnescherm omhoog gaat bij regen
* Het is de bedoeling dat het zonnescherm omhoog gaat bij weinig licht
*/
//hoofdcode
if ((ldrValue > 700) && (rainValue > 500)){
digitalWrite(switch_1, HIGH); //zonnescherm gaat omlaag bij geen regen en veel licht
digitalWrite(switch_2, LOW);
setpoint = 1; //zonnescherm gaat omlaag bij geen regen en veel licht
Serial.println("zonnescherm omlaag");
}
if (rainValue <500) {
digitalWrite(switch_1, LOW); //zonnescherm gaat omhoog bij veel regen
digitalWrite(switch_2, HIGH);
setpoint = 0; //zonnescherm gaat omhoog bij veel regen
Serial.println("zonnescherm omhoog, regen");
}
if (ldrValue < 500){
digitalWrite(switch_1, LOW); //zonnescherm gaat omhoog bij weinig licht
digitalWrite(switch_2, HIGH);
setpoint = 0; //zonnescherm gaat omhoog bij weinig licht
Serial.println("zonnescherm omhoog, te weinig licht");
}
if (setpoint != oldsetpoint) //deze code wordt eenmaal uitgevoerd als het setpoint wijzigd
{
if (setpoint==1)
{
digitalWrite(switch_1, HIGH);// omhoog
digitalWrite(switch_2, LOW);
delay(500);
}else{
digitalWrite(switch_1, LOW);// omlaag
digitalWrite(switch_2, HIGH);
delay(500);
}
}else{ //het setpoint is niet gewijzigd
digitalWrite(switch_1, LOW);// stil
digitalWrite(switch_2, LOW);
}
}
edit: hoe doen jullie code tags
Modedit: zo 
Meer handigheid staat hier: https://www.circuitsonline.net/forum/faq/2
[Bericht gewijzigd door Sine op (2%)]
buckfast_beekeeper
Van Lambiek wordt goede geuze gemaakt.
if (setpoint != oldsetpoint){ //deze code wordt eenmaal uitgevoerd als het setpoint wijzigd
if (setpoint==1){
digitalWrite(switch_1, HIGH);// omhoog
digitalWrite(switch_2, LOW);
delay(500);
digitalWrite(switch_1, LOW);
}
else{
digitalWrite(switch_1, LOW);// omlaag
digitalWrite(switch_2, HIGH);
delay(500);
digitalWrite(switch_2, LOW);
}
}
else{ //het setpoint is niet gewijzigd
digitalWrite(switch_1, LOW);// stil
digitalWrite(switch_2, LOW);
}
Persoonlijk zou ik in if setpoint==1 high en low wisselen van plaats. Als switch 2 nog hoog is en je schakelt switch 1 hoog, heb je mogelijk miserie. Ik zou de tijd ook net iets langer nemen. Kwestie van zeker een halve seconde te hebben.
Waarom kijk je 2 keer na elkaar naar je regensensor?
rainValue = analogRead(rainPin); // read the value form the rain sensor
rainValue = analogRead(rainPin); // read the value from the rain sensor
Good practice is ook je code te laten inspringen. Zo zie je direct van waar tot waar een bepaalde scope loopt. Je zal dan ook sneller zien als er bijvoorbeeld een } te veel of te weinig is.
Op 1 augustus 2019 22:01:01 schreef KlaasZ:
Je kunt een bi-stabiel relais gebruiken. Dat hoef je alleen maar een korte puls te geven en dan blijft hij in de gekozen stand staan.
Er bestaan in de handel kant en klare systemen voor dit doel. Die kijken niet alleen naar regen, maar ook naar windsnelheid. Als het te hard waait gaat het scherm omhoog.
Bistabiel zou ik niet nemen. Moet je eigenlijk gaan controleren hoe je relais staat. Stel je relais staat in de aan stand en je elektriciteit valt weg. Je µC weet nu niet meer hoe je relais staat. Wat is een halve seconde een relais trekken?
My two cents:
Laat de loop telkens een minuut wachten. Mocht er een knippersituatie ontstaan door wolken, vogels of reflecties dan krijg je nooit zeer snelle wisselingen en is de kans groot dat je de situatie helemaal mist.
Voor wind: haal de waarde via internet op bij KNMI. Geen dure molentjes en toestanden én je kan zelfs iets verzinnen zodat je bij slechte verwachting,winterse of lage temperaturen het zonnetje lekker binnenlaat, als je de wifi shield dan toch hebt maak je de boel meteen regelbaar met een mobiel.
Bedankt voor jullie reacties.
Hoe declareer ik nu setpoint en oldsetpoint aan het begin van de code om hem te testen?
Groeten sven
het probleem zit dat je de relais 2x bekrachtigt . 1 keer als je de condities controlleert en de set points zet,
if ((ldrValue > 700) && (rainValue > 500)){
digitalWrite(switch_1, HIGH); //zonnescherm gaat omlaag bij geen regen en veel licht
digitalWrite(switch_2, LOW);en 1keer onderaan met die IF loops
if (setpoint != oldsetpoint) //deze code wordt eenmaal uitgevoerd als het setpoint wijzigd
{
if (setpoint==1)
{
digitalWrite(switch_1, HIGH);// omhoog
digitalWrite(switch_2, LOW);deze 2 stukken zetten switch1 hoog en er is NIKS van code die het weer omlaag brengt. want die else onderaan wordt niet uitgevoerd als de if voldaan werd.
tip 1: houd je functies veel korter. de loop is VEEEL TE LANG en onoverzichtelijk.
even snel wat ingekort, geen idee of het direct werkt, maar een idee om te geven hoe je sneller en makkelijker leesbaar programmeert
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 setpoint = 0;
int oldsetpoint = setpoint; //kopieer altijd setpoint, om de waarde te bewaren
int switch_1 = 9; //select the output pin for the power switch (UP)
int switch_2 = 10; //select the output pin for the power switch (DOWN)
void setup() {
Serial.begin(9600); //sets serial port for communication
pinMode(switch_1, OUTPUT);
pinMode(switch_2, OUTPUT);
digitalWrite(switch_1,LOW); //dwing alle uitgangen uit
digitalWrite(switch_2,LOW);
}
void inlezenData() {
//inlezen LDR
ldrValue = analogRead(ldrPin); // read the value from the ldr sensor
Serial.println(ldrValue); //prints the values coming from the sensor on the screen
delay(100);
//inlezen Rainsensor
rainValue = analogRead(rainPin); // read the value form the rain sensor
//Serial.println(rainValue); //prints the values coming from the sensor to the screen
delay(100);
}
void controlleerCondities() {
if ((ldrValue > 700) && (rainValue > 500)) {
setpoint = 1; //zonnescherm gaat omlaag bij geen regen en veel licht
Serial.println("zonnescherm omlaag");
} //******************* hier kan misschien een else? als het niet omlaag moet, dan moet het omhoog, niet???
if ((rainValue < 500) || (ldrValue < 500)) {
setpoint = 0; //zonnescherm gaat omhoog bij veel regen of weinig zonlicht
Serial.println("zonnescherm omhoog, regen of weinig licht");
}
}
void bekrachtigRelais(int relais){
digitalWrite(relais,HIGH);
delay(500);
digitalWrite(relais,LOW);
}
void loop() {
/* Het is de bedoeling dat het zonnescherm omlaag gaat bij geen regen en veel licht
* Het is de bedoeling dat het zonnescherm omhoog gaat bij regen
* Het is de bedoeling dat het zonnescherm omhoog gaat bij weinig licht
*/
inlezenData(); //lees de sensoren in
controlleerCondities(); //controlleer of er actie moet gedaan worden
if (setpoint != oldsetpoint) { //situatie anders dan voorheen?=> doe iets
if (setpoint == 1){
bekrachtigRelais(switch_1)
}else{
bekrachtigRelais(Switch_0)
}
}
}
de code van 'bekrachtigRelais' is de enige die relais zal aansturen.
en die werkt als volgt.
uw loop roept aan:
bekrachtigRelais(switch_1)
dan zal die functie nu switch 1 even hoog maken, 500ms wachten en weer laag maken. en het is afgelopen
geeft de loop nu echter de andere op om te bekrachtigen, zelfde spelletje.
beste fcapri,
heb jouw code erin gezet. Nu blijft het relais steeds omhoog gaan(relais blijft 1 en na 500 ms weer 0.
Ik heb een filmpje gemaakt om het te verduidelijken. Groene led is omhoog, Rode led is omlaag.
Wat is hiervoor de oplossing en wat klopt er niet in de code?
groeten Sven
Op 1 augustus 2019 22:28:54 schreef Ex-fietser:
Met geld kun je altijd alles kopen. Ook een lakei huren die dag en nacht bij het scherm staat om het te bedienen. Kost alleen een paar centen.Hier is een uitdaging om het zelf te maken. En ik kan me daar de lol wel van inzien.
Ik zeg ook niet dat hij een commercieel product moet kopen. Ik zeg alleen maar dat die commerciële apparaten ook naar de windsnelheid kijken. Dat zou TS in zijn bouwsel kunnen meenemen.
Op 2 augustus 2019 18:16:48 schreef SvenTech:
beste fcapri,heb jouw code erin gezet. Nu blijft het relais steeds omhoog gaan(relais blijft 1 en na 500 ms weer 0.
Ik heb een filmpje gemaakt om het te verduidelijken. Groene led is omhoog, Rode led is omlaag.
Wat is hiervoor de oplossing en wat klopt er niet in de code?
groeten Sven
wat geeft die in terminal window? zegt die altijd 'zonnescherm omhoog of te weinig licht'? dan is die if loop altijd actief. de loop is ook heel snel nu. 100ms voor sensor uit te lezen, 100ms voor de 2de en 500ms voor de delay. dus elke 0,7sec ga je door de loop. kan je gerust vertragen naar 5sec ofzo.
2de punt: zijn de meting van de sensor stabiel? voor in mijn auto de brandstof te meten, meet ik 10metingen en maak daar een gemiddelde van
je kan ook die if's eens omzeilen door een vaste waarde te geven
ofwel verander je hier:
void controlleerCondities() {
ldrValue = 600;
rainValue = 400;
if ((ldrValue > 700) && (rainValue > 500)) {
setpoint = 1; //zonnescherm gaat omlaag bij geen regen en veel licht
Serial.println("zonnescherm omlaag");
} //******************* hier kan misschien een else? als het niet omlaag moet, dan moet het omhoog, niet???
if ((rainValue < 500) || (ldrValue < 500)) {
setpoint = 0; //zonnescherm gaat omhoog bij veel regen of weinig zonlicht
Serial.println("zonnescherm omhoog, regen of weinig licht");
}
}
je kan daar nu alle waardes zetten ipv 600 en 400 om te testen
[Bericht gewijzigd door fcapri op (51%)]
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Ik heb niet alle details meer gelezen, maar ik krijg het gevoel dat de TS aan het verzuipen is. TS, probeer je code eens een stuk uit te kleden. Bv, laat alleen de code zitten die de screen omhoog of omlaag kan zetten. Je kunt evt een knop aan een ongebruikte pin zetten om het teken "omhoog" of "omlaag" te geven zodat je sneller kunt testen. Dat uitlezen van sensoren laat je eerst nog weg.
Omhoog of omlaag bewegen is blijkbaar een kwestie van een van de relais even kort te activeren, dus dat moet heel simpel zijn. Als dat werkt, voeg je de sensors weer toe en dan werkt het in 1 keer.