[ARDUINO] Delay() vervangen

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • peertje1010
  • Registratie: Juli 2014
  • Laatst online: 17-07-2024
Hey !


Er vanuitgaande dat mijn topic hier op de juiste plek terecht is gekomen zou ik jullie tweakers graag een vraag willen stellen betreffende een arduino project waar ik mee bezig ben.

Klein beetje achtergrond informatie: voor mijn pws ben ik bezig een spraakgestuurd koffie apparaat te maken. Het apparaat heeft 3 knoppen. Grote koffie, kleine koffie en een aanknop. D.m.v. een relais heb ik een nodeMCU aangesloten op het koffieapparaat. Nu werkt alles goed op bijvoorbeeld een lampje die alleen de status ''aan'' of ''uit'' kent. Zodra ik echter delays ga toevoegen zodat er echt een knopdruk gesimuleerd word (een led zou dan knipperen als het waren) gaat er iets mis. Nu is het gebruik van Delay() nogal omstreden omdat het in conflict is met de rest van de code aangezien je bij delay dus alles pauzeert.

Mijn vraag is; weet er iemand een manier om op de gepresenteerde manier in de code de delay functie om te kunnen schrijven naar iets wat niet ''alles'' stopt. Dus zodat ik gewoon een output signaal hebt wat even aan gaat, dan weer uit en dan weer even aan met de pauzes zoals in de code.

Ik heb hiervoor ook al zelf wat opzoek werk gedaan en gekeken naar de ''blinkwithout delay'' tuturial van arduino. Helaas kan ik hier niet heel veel uit opmaken. Andere tuturials kunnen mij ook niet helpen.

Verder moet aangemerkt worden dat de code die ik voor dit project gebruik niet helemaal zelf geschreven en heb voor een deel van de code al eerder hulp gehad. Mijn expertise op het gebied van Arduino code is daarom ook niet heel groot.

Toch heb ik het idee dat het niet al te moeilijk moet zijn...


Hieronder de code. De delay functies bevinden zich in regel 54 t/m 92. (ik kan de code niet rechtstreeks invoegen volgensmij vandaar de link...

https://create.arduino.cc...acc2-1269726e09a1/preview

Ik hoop dat iemand mij kan helpen, Als ik niet duidelijk genoeg ben geweest of iets fout doe hoor ik het graag. :)

mvg

Thomas

Acties:
  • +1 Henk 'm!

  • Microkid
  • Registratie: Augustus 2000
  • Nu online

Microkid

Frontpage Admin / Moderator PW/VA

Smile

(jarig!)
Je moet een millis() timer gebruiken.
https://playground.arduino.cc/Code/AvoidDelay

4800Wp zonnestroom met Enphase
Life's a waste of time. Time's a waste of life. Get wasted all the time and you'll have the time of your life.


Acties:
  • +1 Henk 'm!

  • Point.Flare
  • Registratie: November 2011
  • Laatst online: 04-06 22:09

Point.Flare

Reverse-Forward Engineer

Een timer is een betere oplossing. Dat zou je code niet moeten vertragen. Al zie ik het probleem niet in jouw geval. Wat gaat er mis? En waarom heb je drie koffiezetapparaten in de code ingebakken?

https://playground.arduino.cc/Code/AvoidDelay

[ Voor 6% gewijzigd door Point.Flare op 06-01-2018 14:29 ]


Acties:
  • 0 Henk 'm!

  • peertje1010
  • Registratie: Juli 2014
  • Laatst online: 17-07-2024
Point.Flare schreef op zaterdag 6 januari 2018 @ 14:28:
Een timer is een betere oplossing. Dat zou je code niet moeten vertragen. Al zie ik het probleem niet in jouw geval. Wat gaat er mis? En waarom heb je drie koffiezetapparaten in de code ingebakken?

https://playground.arduino.cc/Code/AvoidDelay
Bedankt voor je reactie,

Het probleem is dat zodra ik de code uitprobeer op een LED de led niet ''aan en uitgaat'' volgens mijn delay patroon. Wanneer ik de delay's weg haal en dus alleen een output van high heb doet hij dit wel. Waarschijnlijk zorgt de Delay() binnen de callback functie dat er in de handle functie iets misloopt.

Wat betreft de drie koffiezetapparaten is dit eigenlijk één koffieapparaat. De ''Small coffee Machine'' en ''Large coffee machine'' maken een kleine en en grote koffie. De normale ''coffee machine'' zet alleen het apparaat aan.
Dit heb ik zo gedaan omdat ik volgensmij beperkt ben in de spraak commando's omdat ik als het ware een wemo device simuleer. En dan kan ik voor zover ik weet alleen maar de commando's ''Turn (device naam) on'' gebruiken. Ik kan dus niet zeggen ''Give me a small coffee''. Dus als ik een kleine koffie wil moet je zeggen ''Turn the small coffee machine on''.
Ik heb iniedergeval nog geen manier gevonden om het anders te doen.
Hier ga ik even naar kijken dan. Al vind ik het wel lastig dat ze pseudo code gebruiken. Ik ga even wat proberen en kijken of ik er met de timer() uitkom.

Acties:
  • 0 Henk 'm!

  • Microkid
  • Registratie: Augustus 2000
  • Nu online

Microkid

Frontpage Admin / Moderator PW/VA

Smile

(jarig!)

4800Wp zonnestroom met Enphase
Life's a waste of time. Time's a waste of life. Get wasted all the time and you'll have the time of your life.


Acties:
  • 0 Henk 'm!

  • Point.Flare
  • Registratie: November 2011
  • Laatst online: 04-06 22:09

Point.Flare

Reverse-Forward Engineer

Ik zie je niet de state van de D2 en D3 starten in de setup. Wel een Livingroom en een Bedroom. Geven die geen error? Volgens mij zijn die niet declared en die moeten dus een fout gooien.

Klopt de pinout van je NodeMCU met je daadwerkelijke pinout? Ik heb een aantal bordjes waarbij de pinout van de headers anders is dan de interne pinout.

Je IF statement is ook apart in mijn idee. Ik heb nog nooit met jouw bord gewerkt of de library die je include. Alleen waarom zou je een LOW schrijven op het moment dat je hem niet schakelt? Je hebt de staat van de relais geinitialiseerd op LOW. Het voelt raar om daar een LOW overheen te zetten.

Nog iets. Je zet met Alexa de machine aan of uit. Dus zolang jij 'Small coffee' machine aan zet, loopt die code. Dus hij zal koffie blijven zetten, totdat jij de machine met Alexa weer uit zet. Je moet dus Alexa 'Turn Small Cofveve Machine on' en onmiddelijk daarna 'Turn Small Cofveve Machine off'. Kan je niet een momentary announce doen oid?

[ Voor 53% gewijzigd door Point.Flare op 06-01-2018 19:52 ]


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Nu online
Een belangrijk concept om te snappen wil je dit probleem oplossen (en waar hier eigenlijk compleet aan voorbijgegaan wordt) is de statemachine.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • peertje1010
  • Registratie: Juli 2014
  • Laatst online: 17-07-2024
Point.Flare schreef op zaterdag 6 januari 2018 @ 19:39:
Ik zie je niet de state van de D2 en D3 starten in de setup. Wel een Livingroom en een Bedroom. Geven die geen error? Volgens mij zijn die niet declared en die moeten dus een fout gooien.

Klopt de pinout van je NodeMCU met je daadwerkelijke pinout? Ik heb een aantal bordjes waarbij de pinout van de headers anders is dan de interne pinout.

Je IF statement is ook apart in mijn idee. Ik heb nog nooit met jouw bord gewerkt of de library die je include. Alleen waarom zou je een LOW schrijven op het moment dat je hem niet schakelt? Je hebt de staat van de relais geinitialiseerd op LOW. Het voelt raar om daar een LOW overheen te zetten.

Nog iets. Je zet met Alexa de machine aan of uit. Dus zolang jij 'Small coffee' machine aan zet, loopt die code. Dus hij zal koffie blijven zetten, totdat jij de machine met Alexa weer uit zet. Je moet dus Alexa 'Turn Small Cofveve Machine on' en onmiddelijk daarna 'Turn Small Cofveve Machine off'. Kan je niet een momentary announce doen oid?
Die state dat is een goed punt. Die heb ik aangepast. De pinouts kloppen ik heb het geheel namelijk ook al getest zonder delay en simpel met het aan en uit zetten van LED's via de alexa. Dat werkt gewoon. Als ik dus zeg: ''turn the bedroom light on'' , gaat netjes het lampje branden (dan is het device niet coffe emachine maar bedroom light natuurlijk).

Die IF statement is inderdaad ook een beetje raar. Ik denk dat ik die er ook maar even uit ga knikkeren.

Wat betreft het blijven koffie zetten, daar zijn die delays dus voor. Ik wil dus zodra dat ik zeg ''turn the small coffee machine on'' dat hij eerst het apparaat aanzet (dus output high en dan weer low, zodat de aanknop word ''ingedrukt''). Dan wacht hij een aantal seconden tot het water warm is. Dan moet hij als het ware de kleine koffie knop indrukken (dus output Kleinkoffie high -> delay b-> output LOW) dan wacht hij totdat de koffie klaar is (allemaal vooraf getimed), en dan doet hij zich zelf weer uit. ( Aanknop HIGH -_ delay() --> LOW)
Deze is wat at duidelijker voor mij! Alhoewel, als ik hier naar kijk ben ik wel een beetje bang dat dit een hoop code gaat opleveren omdat ik zo veel verschillende delay() intervallen heb. En word het niet snel heel erg ingewikkeld omdat de delays elkaar in mijn code ook nog opvolgen?

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Nu online
peertje1010 schreef op zondag 7 januari 2018 @ 10:56:
[...]
Alhoewel, als ik hier naar kijk ben ik wel een beetje bang dat dit een hoop code gaat opleveren omdat ik zo veel verschillende delay() intervallen heb. En word het niet snel heel erg ingewikkeld omdat de delays elkaar in mijn code ook nog opvolgen?
Zo maar een idee:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
enum State { Idle, Eerste, Tweede, Bijna, Klaar, Fout };

static State state = 0;
static int stateTick;

void setState( State s )
{
    if( s != state ) {
        stateTick = tick;
        state = s;
    }
}

void start( int tick )
{
    if( state != Idle ) {
        return;
    }
    setState( Eerste );
}

void statemachine( int tick )
{
    switch( state ) {
        case Idle:
            break;

        case Eerste:
            if( tick - stateTick > delay ) {
                // Do stuff, perhaps
                setState( Tweede );
            }
            break;

        case Tweede:
            if( tick - stateTick > delay ) {

                // Do more stuff, perhaps
                setState( Derde );
            }
            break;

        ....

        case Bijna:
            if( tick - stateTick > delay ) {

                setState( Klaar );
            }
            break;

        case Klaar:
            break;

        case Fout:
            break;

        default:
            state = Fout;
            break;
    }
}


Valt wel mee toch? Het valt ook prima in een OO manier te gieten, maar dit is de essentie van een statemachine.

[ Voor 3% gewijzigd door farlane op 07-01-2018 14:25 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Point.Flare
  • Registratie: November 2011
  • Laatst online: 04-06 22:09

Point.Flare

Reverse-Forward Engineer

peertje1010 schreef op zondag 7 januari 2018 @ 10:56:

Wat betreft het blijven koffie zetten, daar zijn die delays dus voor. Ik wil dus zodra dat ik zeg ''turn the small coffee machine on'' dat hij eerst het apparaat aanzet (dus output high en dan weer low, zodat de aanknop word ''ingedrukt''). Dan wacht hij een aantal seconden tot het water warm is. Dan moet hij als het ware de kleine koffie knop indrukken (dus output Kleinkoffie high -> delay b-> output LOW) dan wacht hij totdat de koffie klaar is (allemaal vooraf getimed), en dan doet hij zich zelf weer uit. ( Aanknop HIGH -_ delay() --> LOW)
Ja, maar je het de machine "on" gezet in Alexa. Tot zo ver goed. De code wordt doorlopen en er wordt offie gezet. Alleen, je hebt na het koffiezetten naar Alexa geen "off" terug geschreven. Je code draait opnieuw, want de code loopt altijd. De machine staat nog steeds op "on", dus dezelfde code wordt weer uitgevoerd. Dit gaat door tot je zegt " small coffee machine off".

Wat je denk ik hebt gedaan is de code van een verlichting gepakt (een toggle switch) en die verbouwd om een momentary switch te doen. Zo lang je geen feedback of commando kan geven die de machine automatisch weer op "off" zet, zal je het handmatig (met je stem) moeten doen.

Acties:
  • 0 Henk 'm!

Anoniem: 159174

Misschien wat laat, maar een delay in een callback gaat niet met deze library: reactie auteur

De callback kort houden, switch zetten en die in de main loop afhandelen (met een delay() of iets anders)
Pagina: 1