Go Down

Topic: Hulp bij schoolopdracht - Timer in douche (Read 1 time) previous topic - next topic

kimmieg

Hi!

Ik hoop dat jullie mij willen helpen, omdat ik een beginner ben en ik een opdracht móét halen voor school, maar ik heb er zo verdomd veel moeite mee. De opdracht luidt als volgt:

Zorg ervoor dat een persoon, nadat de douche 10 minuten aan staat, de douche uit wilt zetten. Er brandt standaard een groen lampje en na 10 minuten wil ik dat er een alarm (piezo) afgaat en het groene lampje rood wordt. Ook moet er elke minuut een piepje te horen zijn. Ik heb een watersensor, piezobuzzer en ledlampje.

Ik moet het zelfs filmen om te laten zien dat het allemaal werkt.

Ik ben behoorlijk wanhopig en hoop dat iemand mij wilt helpen, ik ben zelfs bereidt om iemand te betalen om deze code voor mij te schrijven.

Alsjeblieft?! Alvast bedankt.


robtillaart

Hoi Kimmie,

Als je door de basic voorbeelden van de Arduino gaat zoals blink, dan zie je daarin alle bouwstenen die je nodig hebt.

Het moeilijkste is meestal "getting started" dus hier alvast een paar tips.

Je hebt 1 input - watersensor  en twee outputs.
Die hebben allemaal een pin nodig.
Met pinMOde definieer je of ze input of output zijn.
Dit doe je in setup().

In de loop ga je iedere iteratie kijken of je wat moet doen.

void loop()
{
   noteer hoe laat het nu is

   is er 60 seconden verstreken sinds laatste piepje  ==> piep + onthoud de tijd van laatste piepje

   is er water gedetedteert?  ==> onthoud de begintijd

   is er 600 seconden verstreken sinds water detectie? ==> piep continue en zet groen led uit en rode aan

   is er 700 seconden verstreken sinds water detectie? ==> sluit warm water af ;)

 }

de tijd meet je met millis()

Iedere vraag is een if (   )

wat je moet onthouden doe je met variabelen 
(hint gebruik type long daar kunnen voldoende grote getallen in.)

De watersensor kun je met analogRead(A0) uitlezen (moet je hem wel daaraan verbinden natuurlijk.

Leds stuur je aan met digitalWrite()

Buzzer kan met digitalWrite() maar ook met analogWrite()

Probeer nu eens een opzet te maken van een programma dat (voorlopig) alleen detecteert of er water is of niet. Werkt dat niet, post het en zet je vragen erbij.

Success
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

shooter

Prachtig Rob in 20 regels het begin van arduino uitleggen.
paul deelen
shooter@home.nl
making controls with codesys PLC and arduino

shooter

kim ben iets duidelijker in wat je al gedaan hebt, zoals een schema van de hardware en de software.
paul deelen
shooter@home.nl
making controls with codesys PLC and arduino

MAS3

Mee eens, shooter.


Alles wat je weg laat is een obstakel en zal eerder tegenwerken als meewerken.
Zoveel mogelijk informatie dus.
Als je bijvoorbeeld op 1 februari (of nog eerder) klaar moet zijn, dan ben je rijkelijk laat met je vraag.
En dat komt veel vaker voor, dat het te laat is om goed te helpen.
Want het leerproces is heel anders als iemand anders het voor je gaat maken, dus dan leer je niet wat de bedoeling van de opdracht was.

Ik zeg niet dat dat allemaal van toepassing is, want dat kan ik niet weten.
Dus geef zoveel mogelijk informatie als je een vraag stelt, en begin maar eens met Rob's voorstel.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

kimmieg

Hoi Kimmie,

Als je door de basic voorbeelden van de Arduino gaat zoals blink, dan zie je daarin alle bouwstenen die je nodig hebt.

Het moeilijkste is meestal "getting started" dus hier alvast een paar tips.

Je hebt 1 input - watersensor  en twee outputs.
Die hebben allemaal een pin nodig.
Met pinMOde definieer je of ze input of output zijn.
Dit doe je in setup().

In de loop ga je iedere iteratie kijken of je wat moet doen.

void loop()
{
   noteer hoe laat het nu is

   is er 60 seconden verstreken sinds laatste piepje  ==> piep + onthoud de tijd van laatste piepje

   is er water gedetedteert?  ==> onthoud de begintijd

   is er 600 seconden verstreken sinds water detectie? ==> piep continue en zet groen led uit en rode aan

   is er 700 seconden verstreken sinds water detectie? ==> sluit warm water af ;)

 }

de tijd meet je met millis()

Iedere vraag is een if (   )

wat je moet onthouden doe je met variabelen  
(hint gebruik type long daar kunnen voldoende grote getallen in.)

De watersensor kun je met analogRead(A0) uitlezen (moet je hem wel daaraan verbinden natuurlijk.

Leds stuur je aan met digitalWrite()

Buzzer kan met digitalWrite() maar ook met analogWrite()

Probeer nu eens een opzet te maken van een programma dat (voorlopig) alleen detecteert of er water is of niet. Werkt dat niet, post het en zet je vragen erbij.

Success
Hi Rob,

Enorm bedankt!! Je hebt me flink op weg geholpen.

Voor mijn doen ben ik een stuk verder gekomen, alleen snap ik het nog niet helemaal en mijn code klopt dan ook nog lang niet. Hoe zorg ik ervoor dat de watersensor pas gaat meten ná 10 minuten? En tegelijkertijd elke minuut een piepje laat horen? Ik heb mijn code bijgevoegd en hoop dat je me weer een aantal tips wilt geven:).

robtillaart

#6
Jan 26, 2018, 05:39 pm Last Edit: Jan 26, 2018, 05:43 pm by robtillaart
We gaan eerst de minuut biepjes goed krijgen


tip 1: toekenning  versus vergelijking

currentTime = 6000    is een toekenning

currentTime == 6000   is een vergelijking



tip 2: repetende acties met lastTime  en millis constructie

Omdat je iedere 6000 msec iets wil doen kun je dat als volgt:


if (currentTime - lastTimeIDidBeep >= 6000)
{
   lastTimeIDidBeep = currentTime;
   beep();
}

door dit in de loop te zetten kun je een heleboel if(...) opruimen
in je code.

Voor iedere aktie die repeterend moet gebeuren gebruik je een eigen
lastTimeIdid_whatever variabele. Dus als je bv tegelijk ledjes wil laten
knipperen kan dat op deze manier.
Verder kun je bij iedere actie een eigen interval gebruiken door de 6000
aan te passen voor die akite.

Omdat millis() van jet type unsigned long is, moet je deze lastTime.... variabelen
van hetzelfde type maken. Dan gaat er geen (milli)seconde verloren.

Tip 3: header boven je programma

Ik gebruik bijna altijd een header boven mijn programma ter informatie.
Voegt functioneel niets toe maar toch
//
//    FILE: watersensor.ino
//  AUTHOR: Kimmie
// VERSION: 0.0.1
// PURPOSE:
//
// HISTORY:

KIjk of je nu een stap verder komt
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

kimmieg

#7
Jan 27, 2018, 04:56 pm Last Edit: Jan 28, 2018, 11:51 am by kimmieg
We gaan eerst de minuut biepjes goed krijgen


tip 1: toekenning  versus vergelijking

currentTime = 6000    is een toekenning

currentTime == 6000   is een vergelijking



tip 2: repetende acties met lastTime  en millis constructie

Omdat je iedere 6000 msec iets wil doen kun je dat als volgt:


if (currentTime - lastTimeIDidBeep >= 6000)
{
   lastTimeIDidBeep = currentTime;
   beep();
}

door dit in de loop te zetten kun je een heleboel if(...) opruimen
in je code.

Voor iedere aktie die repeterend moet gebeuren gebruik je een eigen
lastTimeIdid_whatever variabele. Dus als je bv tegelijk ledjes wil laten
knipperen kan dat op deze manier.
Verder kun je bij iedere actie een eigen interval gebruiken door de 6000
aan te passen voor die akite.

Omdat millis() van jet type unsigned long is, moet je deze lastTime.... variabelen
van hetzelfde type maken. Dan gaat er geen (milli)seconde verloren.

Tip 3: header boven je programma

Ik gebruik bijna altijd een header boven mijn programma ter informatie.
Voegt functioneel niets toe maar toch
//
//    FILE: watersensor.ino
//  AUTHOR: Kimmie
// VERSION: 0.0.1
// PURPOSE:
//
// HISTORY:

KIjk of je nu een stap verder komt
Hi Rob! Bedankt voor de tips:) Ik heb alle beep stappen verwijderd en eentje toegevoegd, alleen nu begint hij meteen te beepen en elke 10 seconden ongeveer. Mijn code is nu als volgt:

Code: [Select]

//
//    FILE: watersensor.ino
//  AUTHOR: Kimmie
// VERSION: 0.0.1
// PURPOSE: Douchegedrag veranderen
//
// HISTORY:

const int read = A0;
int water;
const int greenLEDPin = D3;
const int redLEDPin = D4;
const int piezoPin = D1;
unsigned long currentTime = 0;
unsigned long lastTimeIDidBeep = 0;

void setup(){
 
  Serial.begin(9600); //Begin serial communication
  pinMode(greenLEDPin, OUTPUT);
  pinMode(redLEDPin, OUTPUT);
  pinMode(piezoPin, OUTPUT);
  beep(); //begonnen met meten
}
 
void loop(){
 
 currentTime = millis();
 water = analogRead(read);

 if (water<=700){
  digitalWrite(greenLEDPin, HIGH);
  digitalWrite(redLEDPin, LOW);
  digitalWrite(piezoPin, LOW);
 }

if (currentTime - lastTimeIDidBeep >= 6000) //na elke minuut een beep
{
   lastTimeIDidBeep = currentTime;
   beep();
}

 else if (water>700 && currentTime > 60000) //na 10 minuten
 
 {
  digitalWrite(greenLEDPin, LOW);
  digitalWrite(redLEDPin, HIGH);
  alarm();
 }

 }

 void alarm(){
        tone(piezoPin, 698);
        delay(600);
        noTone(piezoPin);
        delay(400);
  }

 void beep(){
        tone(piezoPin, 100);
        delay(100);
        noTone(piezoPin);
        delay(1000);
 
}

robtillaart

#8
Jan 27, 2018, 05:03 pm Last Edit: Jan 27, 2018, 05:04 pm by robtillaart
if (currentTime - lastTimeIDidBeep >= 6000)

==>

if (currentTime - lastTimeIDidBeep >= 60000)

Als je code post gebruik aub  [code]....[/code]  tags
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

robtillaart

#9
Jan 27, 2018, 05:05 pm Last Edit: Jan 27, 2018, 05:06 pm by robtillaart
else if (water>700 && currentTime > 60000) //na 10 minuten

60000 milliseconden is 1 minuut, geen 10 ...

TIP CTRL-T in de IDE zorgt dat je code automatisch inspringt.
ziet er netter uit voor leesbaarheid.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

kimmieg

#10
Jan 28, 2018, 12:01 pm Last Edit: Jan 28, 2018, 12:08 pm by kimmieg
else if (water>700 && currentTime > 60000) //na 10 minuten

60000 milliseconden is 1 minuut, geen 10 ...

TIP CTRL-T in de IDE zorgt dat je code automatisch inspringt.
ziet er netter uit voor leesbaarheid.
Het waren dus 6 seconden ipv 60 seconden... got it!

De minuut biepjes doen het nu, maar alles begint meteen te lopen zodra ik het upload. Hoe zorg ik ervoor dat dit pas gebeurt zodra de watersensor in contact komt met water?

Code: [Select]


//
//    FILE: watersensor.ino
//  AUTHOR: Kimmie
// VERSION: 0.0.1
// PURPOSE: Douchegedrag veranderen
//
// HISTORY:

const int read = A0;
int water;
const int greenLEDPin = D3;
const int redLEDPin = D4;
const int piezoPin = D1;
unsigned long currentTime = 0;
unsigned long lastTimeIDidBeep = 0;

void setup() {

  Serial.begin(9600); //Begin serial communication
  pinMode(greenLEDPin, OUTPUT);
  pinMode(redLEDPin, OUTPUT);
  pinMode(piezoPin, OUTPUT);
  beep(); //begonnen met meten
}

void loop() {

  currentTime = millis();
  water = analogRead(read);

  if (water <= 700) {
    digitalWrite(greenLEDPin, HIGH);
    digitalWrite(redLEDPin, LOW);
    digitalWrite(piezoPin, LOW);
  }

  else if (currentTime - lastTimeIDidBeep >= 60000) //na elke minuut een beep
  {
    lastTimeIDidBeep = currentTime;
    beep();
  }

  else if (water > 700 && currentTime > 600000) //na 10 minuten

  {
    digitalWrite(greenLEDPin, LOW);
    digitalWrite(redLEDPin, HIGH);
    alarm();
  }

}

void alarm() {
  tone(piezoPin, 698);
  delay(600);
  noTone(piezoPin);
  delay(400);
}

void beep() {
  tone(piezoPin, 100);
  delay(100);
  noTone(piezoPin);
  delay(1000);

}


robtillaart

Het gaat goed Kimmie!

Quote
De minuut biepjes doen het nu, maar alles begint meteen te lopen zodra ik het upload. Hoe zorg ik ervoor dat dit pas gebeurt zodra de watersensor in contact komt met water?
Daarvoor gaan we een nieuwe variabele introduceren. Deze variabele zetten we de startTijd van het ondekken van water.

Omdat het een tijd weergeeft maken ook daarvan een uint32_t

uint32_t WaterDetectionTime  = 0;

NU spreken we zelf af dat zolang de waarde 0 is de tijd nog niet gezet is. OK?


De variabele WaterDetectionTime  wordt gezet op het moment dat ..... (goed zo ;)

In Nederlands

Als analogRead water aangeeft ==> WaterDetectionTime  = millis();


Daarna kunnen we in de loop ook een conditie toevoegen of er 10 minuten = (??  milliseconden ??)
verstreken zijn,

In Nederlands

Als   millis() - WaterDetectionTime  >=  10 minuten  ==>  laat alle alarmen rinkelen

Echter als WaterDetectionTime == 0 mag het weer niet


Dus de regel wordt wat langer

Als    (millis() - WaterDetectionTime  >=  10 minuten)   &&  (WaterDetectionTime  !=  0)
                     ==>  laat alle alarmen rinkelen


de  &&  if de logische AND operatie, dan moeten beide delen waar zijn.




Als dit werkt moet er nog wat verfijnd worden. Namelijk als er geen water meer gedetecteerd wordt moet
de variabele  WaterDetection  weer op 0 gezet worden.

In Nederlands zou je nu zelf moeten kunnen formuleren


Success!
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

kimmieg

Ik dacht dat ik het goed had gedaan, maar nu gaat het alarm niet aan na 10 minuten en ik snap niet zo goed waarom.

En je zei omdat de nieuwe variabele een tijd weergeeft maak ik hier ook een uint32_t van. Moet ik de andere variabelen die ook tijd weergeven veranderen of staan deze goed?


Code: [Select]


//
//    FILE: watersensor.ino
//  AUTHOR: Kimmie
// VERSION: 0.0.3
// PURPOSE: Douchegedrag veranderen
//
// HISTORY:

const int read = A0;
int water;
const int greenLEDPin = D3;
const int redLEDPin = D4;
const int piezoPin = D1;
unsigned long currentTime = 0;
unsigned long lastTimeIDidBeep = 0;
uint32_t WaterDetectionTime  = 0;

void setup() {

  Serial.begin(9600); //Begin serial communication
  pinMode(greenLEDPin, OUTPUT);
  pinMode(redLEDPin, OUTPUT);
  pinMode(piezoPin, OUTPUT);
}

void loop() {

  currentTime = millis();
  water = analogRead(read);

  if (water <= 700) {
    digitalWrite(greenLEDPin, HIGH);
    digitalWrite(redLEDPin, LOW);
    digitalWrite(piezoPin, LOW);
  }

  else if (currentTime - lastTimeIDidBeep >= 60000) //na elke minuut een beep
  {
    lastTimeIDidBeep = currentTime;
    beep();
  }

  else if (water => 700) // Als analogRead water aangeeft ?? Doe ik dit goed of moet ik deze variabele ergens anders zetten?
{
    WaterDetectionTime  = millis();
}
 
  else if (millis() - WaterDetectionTime  >=  600000 && WaterDetectionTime  !=  0) 

  {
    digitalWrite(greenLEDPin, LOW);
    digitalWrite(redLEDPin, HIGH);
    alarm();
  }


}

void alarm() {
  tone(piezoPin, 698);
  delay(600);
  noTone(piezoPin);
  delay(400);
}

void beep() {
  tone(piezoPin, 100);
  delay(100);
  noTone(piezoPin);
  delay(1000);

}


nicoverduin

#13
Jan 29, 2018, 06:58 pm Last Edit: Jan 29, 2018, 07:19 pm by nicoverduin
Waarom zo moeilijk met al die else-ifs?

Je kan de vraag opdelen in deelvragen:
a) loopt er water
b) is er een minuut voorbij
c) zijn er 10 minuten voorbij

Ad a: Loopt er water
Als er water loopt en er is nog geen timer gestart ( je hebt dus een boolean nodig die aangeeft dat de timer loopt) dan start je de timer EN je reset een eenvoudige counter (tot 10). Eventueel zet je wat LEDS oid aan of uit).

Als er GEEN water loopt zet je die bool op false. Wederom wat ledjes aan of uit.

Meer hoef je dus niet te doen in deze stap


Ad b: Is er een minuut voorbij
Dit hoef je alleen maar te doen als de timer loopt (de bool is true)
Zo ja dan controleer je of millis() - timer > 60000
Zo ja 
   dan zet je de timer weer (timer = millis())
   dan verhoog je de counter
   dan laat je een beep() horen 

Meer hoef je niet te doen


Ad c: zijn er 10 minuten verlopen
Dit hoef je alleen te doen als de timer loopt (bool is true)
Als de counter >= 10 
   Dan gaat je alarm af 
   en wat je nog meer wilt doen

Meer hoef je niet te doen

samenvattend:
Trek het probleem uit elkaar en maak er eenvoudige controles van.
Met vriendelijke groet / kindest regards
Nico Verduin
www.verelec.nl
Do not PM me for personal consultancy unless you are willing to pay for it.

kimmieg

Bedankt voor de hulp, alleen ik vind het erg moeilijk en snap niet veel van booleans. Het klinkt heel makkelijk, maar geen idee hoe ik het moet uitvoeren. Ga ik zo de goede kant op?

Code: [Select]



//
//    FILE: watersensor.ino
//  AUTHOR: Kimmie
// VERSION: 0.0.3
// PURPOSE: Douchegedrag veranderen
//
// HISTORY:

const int read = A0;
int water;
const int greenLEDPin = D3;
const int redLEDPin = D4;
const int piezoPin = D1;
unsigned long currentTime = 0;
unsigned long lastTimeIDidBeep = 0;
uint32_t WaterDetectionTime  = 0;
boolean runTimer;

void setup() {

  Serial.begin(9600); //Begin serial communication
  pinMode(greenLEDPin, OUTPUT);
  pinMode(redLEDPin, OUTPUT);
  pinMode(piezoPin, OUTPUT);
}

void loop() {

  currentTime = millis();
  water = analogRead(read);
  WaterDetectionTime  = millis();

  if (water <= 700) // Als analogRead water aangeeft ?? Doe ik dit goed of moet ik deze variabele ergens anders zetten?{
    digitalWrite(greenLEDPin, HIGH);
  digitalWrite(redLEDPin, LOW);
  digitalWrite(piezoPin, LOW);
  runTimer = false;
}

else if (currentTime - lastTimeIDidBeep >= 6000) //na elke minuut een beep
{
  lastTimeIDidBeep = currentTime;
  beep();
}

else if (millis() - WaterDetectionTime  >=  60000 && WaterDetectionTime  !=  0)

{
  digitalWrite(greenLEDPin, LOW);
  digitalWrite(redLEDPin, HIGH);
  alarm();
  runTimer = true;
}


}

void alarm() {
  tone(piezoPin, 698);
  delay(600);
  noTone(piezoPin);
  delay(400);
}

void beep() {
  tone(piezoPin, 100);
  delay(100);
  noTone(piezoPin);
  delay(1000);

}



Go Up