Probleempje arduino schoolproject

Arduino specifieke Software
Berichten: 4
Geregistreerd: 09 Dec 2018, 20:07

Probleempje arduino schoolproject

Berichtdoor Martijn1010 » 09 Dec 2018, 20:39

Hallo.
Voor een schoolproject wil ik een poort maken van een fruitveiling die open en toe gaat.
Ik heb een display met een teller, een groen en rood ledje en een servo die als poort dient.
Wanneer er 6 voertuigen in de veiling zijn zal de poort niet meer open gaan, en het rode ledje zal branden.
Wanneer en minder dan 6 voertuigen in de veiling zitten zal de poort open staan en kunnen de voertuigen doorrijden.
cpp code
#include <Servo.h>              
Servo name_servo;

//Initialize the 7 segment pins
int A = 3;
int B = 2;
int C = 4;
int D = 5;
int E = 6;
int F = 8;
int G = 9;
int ledgroen=11;
int ledrood=7;


int switchUpPin = 12;
int switchDownPin = 13;
int counter = 0;
int buttonUpState = 0;
int lastButtonUpState = 0;
int buttonDownState = 0;
int lastButtonDownState = 0;

void setup()
{
name_servo.attach (10);
Serial.begin(9600);

pinMode(A, OUTPUT);
pinMode(B, OUTPUT);
pinMode(C, OUTPUT);
pinMode(D, OUTPUT);
pinMode(E, OUTPUT);
pinMode(F, OUTPUT);
pinMode(G, OUTPUT);
pinMode(ledgroen, OUTPUT);
pinMode(ledrood, OUTPUT);

}

void loop()
{
if(counter <6)

name_servo.write (90);


else if(counter >=6 )
name_servo.write(0);




buttonUpState = digitalRead(switchUpPin);
buttonDownState = digitalRead(switchDownPin);


if (buttonUpState != lastButtonUpState)
{
if (buttonUpState == HIGH)
{

if(counter == 9)
{
counter = -1;
}

counter++;

Serial.println(counter);
changeNumber(counter);
//Delaying by 250 ms
delay(250);
}
else
{
Serial.println("OFF");
}

delay(50);
}


if (buttonDownState != lastButtonDownState)
{
if (buttonDownState == HIGH)
{

if(counter == 0)
{
counter = 10;
}

counter--;

Serial.println(counter);
changeNumber(counter);

delay(250);
}
else
{
Serial.println("OFF");
}

delay(50);
}

changeNumber(counter);
}


void changeNumber(int buttonPress)
{
switch (buttonPress)
{
//number 0
case 0:
digitalWrite(A, HIGH);
digitalWrite(B, HIGH);
digitalWrite(C, HIGH);
digitalWrite(D, HIGH);
digitalWrite(E, HIGH);
digitalWrite(F, HIGH);
digitalWrite(G, LOW);
digitalWrite(ledgroen, HIGH);
digitalWrite(ledrood, LOW);
break;
//number 1
case 1:
digitalWrite(A, LOW);
digitalWrite(B, HIGH);
digitalWrite(C, HIGH);
digitalWrite(D, LOW);
digitalWrite(E, LOW);
digitalWrite(F, LOW);
digitalWrite(G, LOW);
digitalWrite(ledgroen, HIGH);
digitalWrite(ledrood, LOW);
break;
//number 2
case 2:
digitalWrite(A, HIGH);
digitalWrite(B, HIGH);
digitalWrite(C, LOW);
digitalWrite(D, HIGH);
digitalWrite(E, HIGH);
digitalWrite(F, LOW);
digitalWrite(G, HIGH);
digitalWrite(ledgroen, HIGH);
digitalWrite(ledrood, LOW);
break;
//number 3
case 3:
digitalWrite(A, HIGH);
digitalWrite(B, HIGH);
digitalWrite(C, HIGH);
digitalWrite(D, HIGH);
digitalWrite(E, LOW);
digitalWrite(F, LOW);
digitalWrite(G, HIGH);
digitalWrite(ledgroen, HIGH);
digitalWrite(ledrood, LOW);
break;
//number 4
case 4:
digitalWrite(A, LOW);
digitalWrite(B, HIGH);
digitalWrite(C, HIGH);
digitalWrite(D, LOW);
digitalWrite(E, LOW);
digitalWrite(F, HIGH);
digitalWrite(G, HIGH);
digitalWrite(ledgroen, HIGH);
digitalWrite(ledrood, LOW);
break;
//number 5
case 5:
digitalWrite(A, HIGH);
digitalWrite(B, LOW);
digitalWrite(C, HIGH);
digitalWrite(D, HIGH);
digitalWrite(E, LOW);
digitalWrite(F, HIGH);
digitalWrite(G, HIGH);
digitalWrite(ledgroen, HIGH);
digitalWrite(ledrood, LOW);
break;
//number 6
case 6:
digitalWrite(A, HIGH);
digitalWrite(B, LOW);
digitalWrite(C, HIGH);
digitalWrite(D, HIGH);
digitalWrite(E, HIGH);
digitalWrite(F, HIGH);
digitalWrite(G, HIGH);
digitalWrite(ledrood, HIGH);
digitalWrite(ledgroen, LOW);
break;

}
}

Nu zou ik graag willen dat de poort maar 5 seconde open blijft (anders heeft het hele project natuurlijk geen nut) dus heb ik er dit van gemaakt.
cpp code
void loop() 
{
if(counter <6)

{ name_servo.write (90);
delay(5000);
name_servo.write (0);}

else if(counter >=6 )
name_servo.write(0); [/code]
Maar nu werkt de teller niet meer (heel afentoe als ik 100 keer druk, werkt de teller..)
Dus heb ik het nog eens op een andere manier geprobeerd.
[code]void loop()
{

{


if(counter>=6)
myservo.write(90);


else if(counter<6)
myservo.write(0);
Serial.println(0);
delay(5000);
}

Ook hier wil mijn teller niet meer werken, iemand een idee wat ik fout doe?
Gr. Martijn

Advertisement

Gebruikers-avatar
Berichten: 294
Geregistreerd: 15 Nov 2015, 11:54

Re: Probleempje arduino schoolproject

Berichtdoor Gij Kieken » 09 Dec 2018, 23:09

Je moet de delays eruit halen en werken met millis().
Hier op het forum heeft Koepel al heel mooi omschreven hoe je best werkt met millis(), met wat voorbeelden.

Berichten: 2600
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: Probleempje arduino schoolproject

Berichtdoor shooter » 10 Dec 2018, 00:01

Gij heeft natuurlijk gelijk.
verder zie ik dat je ook al is de slagboom dicht je toch nog kunt drukken, dat kan dus eigenlijk niet.
verder zou ik na elke druk de slagboom even open doen en daarna weer dicht voor de volgende, ofwel 1 wagen tegelijk. net zoals in een parkeer garage.
druk eens op CTRL T dan wordt er iets met de vormgeving gedaan.
je programma ziet er overigens best goed uit hoor,
en je drukkknop werkt niet omdat er in de loop een delay van 5 seconden zit elke keer dat de loop rond gaat.
en je dus veel geluk moet hebben om op het goede moment te drukken.
zet die servo(open) in een aparte functie. noteer de tijd (millis() in een variabele.
in de loop kijk je dan of de millis() >(variabele+5000), is dat zo doe dan een andere functie waarin de servo dicht gaat.

uitbreiding van je programma: laat de servo langzaam open/dicht gaan door elke paar millis de stand te verzetten.
zorg er wel voor dat het groene licht uit is, want de volgende wagen moet maar even wachten, net zoals trouwens als er een wagen uitwil.
maak ook voor het uitrijden een lichtconstructie (dus groen/rood)
maak een drukknop als er een wagen stilstaat in de slagboom (normaal is dat dus een lus in de weg).
zet commentaar bij wat er gebeurt, en waar het begin en einde is van een functie.
paul deelen
shooter@home.nl

Berichten: 4
Geregistreerd: 09 Dec 2018, 20:07

Re: Probleempje arduino schoolproject

Berichtdoor Martijn1010 » 10 Dec 2018, 20:41

Bedankt voor de reactie's, ik ben even gaan zoeken hoe ik moet werken met millis maar het wil niet echt lukken.
Heeft er iemand misschien een duidelijk voorbeeld dat lijkt op dat van mij?
Ik heb dit geprobeerd maar dat werkt niet, de slagboom gaat nu open en direct weer toe.
cpp code
unsigned long previousMillisDot;
const unsigned long intervalDot = 5000;


void loop()
{

{


if (counter >= 6)
myservo.write(0);


else if (counter < 6)
myservo.write(0);
Serial.println(0);
{
unsigned long currentMillis = millis ();
if (currentMillis - previousMillisDot >= intervalDot)
{
previousMillisDot = currentMillis;
Serial.print (".");
}

myservo.write(90);
}

}

Gebruikers-avatar
Berichten: 1930
Geregistreerd: 06 Aug 2016, 01:03

Re: Probleempje arduino schoolproject

Berichtdoor Koepel » 10 Dec 2018, 21:14

Zei iemand: "millis" ?
Maar uhm, ik begrijp de bedoeling niet :?

Iets met tijd doen met millis() kun je een software timer noemen.
Stel dat je eenmalig een vertraging wilt inbouwen, dan is dit een voorbeeld: https://gist.github.com/Koepel/01a6088f321eef5ec62f0b470c97a01e.

Het starten gebeurt door de millis() van dat moment te onthouden, en de software timer te starten met een 'bool' variabele.
Code: Alles selecteren
previousMillis = millis();
enabled = true; // turn on software timer


Het laten lopen van de vertraging kun je bijvoorbeeld onderin de Arduino loop() doen.
Als dat eenmalig uitgevoerd is, dan zet die zichzelf weer uit met diezelfde 'bool' variabele.

Berichten: 4
Geregistreerd: 09 Dec 2018, 20:07

Re: Probleempje arduino schoolproject

Berichtdoor Martijn1010 » 10 Dec 2018, 22:01

Koepel schreef:Zei iemand: "millis" ?
Maar uhm, ik begrijp de bedoeling niet :?


Dus de bedoeling is, wanneer de counter lager dan 6 staat moet de servomotor zich 90° gaan verdraaien gedurende 5 seconden. Na die 5 seconden moet de servomotor weer terug naar zijn oude stand.
De code die jij stuurt lijkt me wel redelijk van toepassing op mijn 'project', maar toch wil het mij niet lukken.
Ik heb nu deze code, en de servo gaat meteen open en toe, zonder dat de timer werkt.
cpp code
else if (counter < 6)
{ myservo.write(90);
Serial.println(0);
previousMillis = millis();
enabled = true;
}

if (enabled)
{
if ( millis() - previousMillis >= interval)
{
myservo.write(0);
enabled = false;
}
}
}

Gebruikers-avatar
Berichten: 1930
Geregistreerd: 06 Aug 2016, 01:03

Re: Probleempje arduino schoolproject

Berichtdoor Koepel » 10 Dec 2018, 23:18

De bedoeling is om dat eenmalig te starten. Als je in de loop() steeds opnieuw kijkt of het lager dan zes is, en de software timer steeds opnieuw opstart, dan werkt het niet.

Gebruikers-avatar
Berichten: 1930
Geregistreerd: 06 Aug 2016, 01:03

Re: Probleempje arduino schoolproject

Berichtdoor Koepel » 11 Dec 2018, 04:49

Dat is leuk, de sketch die je laat zien die heb ik hier ook draaiend ;)

Om alvast een aanloop te maken, heb ik een paar tips.

Kun je na Serial.begin(9600) iets schrijven naar de seriële monitor. Dan weet je dat de sketch gestart is. Bijvoorbeeld "Veiling sketch".

Voor de volledigheid kun je de pinnen voor de drukknoppen in setup() als input zetten met pinMode(switchUpPin, INPUT).

De 'buttonUpState' en 'buttonDownState' mag je lokaal in de loop() declareren in plaats van globaal. Kijk maar wat je het mooiste vind.

Ik zou graag de functionaliteit uit elkaar halen. Dus de knoppen los van de 'counter' en de seven-segment display los van de leds :geek:

Het zou beter zijn om de servo alleen te bewegen als de 'counter' verandert. Daarvoor zou het mooi zijn als je de 'counter' op één plek zou verwerken. Dat kan op verschillende manieren:
1) Kijk alleen of een knop is ingedrukt en maak dan een lokale boolean variabele 'true'. Verwerk later in de loop() die boolean variabelen. Het commando van een knop indrukken wordt op die manier doorgegeven naar verderop in de loop().
2) Verhoog of verlaag de 'counter' met de knoppen, doe de check of dat te hoog of te laag is later. Voeg een globale 'last_counter' toe om een verandering te detecteren.
3) Maak een nieuwe lokale variabele en maak die +1 of -1 als de betreffende knop is ingedrukt. Ga dat later verwerken met de 'counter'. Als er niet op een knop is gedrukt, dan is die variabele nul en hoeft de servo niet te draaien. Dit is eigenlijk hetzelfde als 1) maar nu worden beide boolean variabelen in een integer gestopt die drie waarden kan hebben.

Er zijn nog meer mogelijkheden. Kies er maar eentje. Maar niet die ene die ik lelijk vind :lol:

Mag de naam van de functie "changeNumber" anders ? Bijvoorbeeld een algemene functie die een cijfer op het seven-segment display laat zien. De leds aansturen zou ik apart in de sketch zetten en niet in die algemene functie.
Bijvoorbeeld "void zetEenNummerOpHetZevenSegmentenDisplay( int nummer)", maar dat is een misschien een beetje te lang ;)

Wanneer je alleen iets doet als dat nodig is, dan heb je een logische structuur van de code nodig. De eerste stap is om de code er netjes uit te laten zien. Heb je Ctrl+T al geprobeerd zoals @shooter schreef ? En commentaar is ook echt nodig. En het netjes in afzonderlijke blokken zetten.
Bijlagen
veiling.png
Veiling project
veiling.png (58.3 KiB) 802 keer bekeken

Berichten: 4
Geregistreerd: 09 Dec 2018, 20:07

Re: Probleempje arduino schoolproject

Berichtdoor Martijn1010 » 12 Dec 2018, 16:39

Bedankt voor je reactie vol tips, maar weet je ook hoe ik die code met millis moet schrijven?
Ik zou dat graag eerst in orde hebben, zodat alles ongeveer werkt zodat ik daarna de puntjes op de i kan zetten.
Het moet namelijk tegen morgen (donderdag) klaar zijn, dus heb niet zoveel tijd meer.

Gebruikers-avatar
Berichten: 1930
Geregistreerd: 06 Aug 2016, 01:03

Re: Probleempje arduino schoolproject

Berichtdoor Koepel » 12 Dec 2018, 18:46

Wat ik schreef was een aanloop om millis() te gaan gebruiken.

Op dit moment kijk je aan het begin van de loop of het aantal kleiner of gelijk aan zes is. Dat wordt dus heel vaak uitgevoerd. Daarom zou ik je sketch willen ombouwen, zodat er alleen iets gedaan wordt op het moment dat het cijfer verandert. Dat bedoelde ik met een logische sketch maken die alleen doet wat op dat moment nodig is.

Volgende

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 6 gasten