Millis timer onderbreken

algemene C code
Gebruikers-avatar
Berichten: 6
Geregistreerd: 27 Nov 2016, 18:07
Woonplaats: Oost Vlaanderen BE

Millis timer onderbreken

Berichtdoor eds » 27 Nov 2016, 18:39

Hallo allemaal,
Mijn naam is Eddy en ben nieuw hier op het forum. ik heb arduino nog maar pas ontdekt en al gebeten ;)
Ik ben bezig met een projectje om een paarden stapmolen automatisch aan te sturen. Dit lijkt mij op het eerste gezicht een eenvoudig project, echt iets voor beginners zoals ik maar ik loop al tegen de eerste problemen aan.
Opzet van de sturing is de volgende.
je hebt een stappenschakelaar waarmee je een gewenst trainingsprogramma kan instellen. Je hebt 5 programma's (dus 5 standen).
programma 0 is het in- en uitstapprogramma om paarden in de molen te laten in- of uitstappen.
Daarna moet je met de stappenschakelaar een gewenst programma instellen.
Nu heb in een deel van de code geschreven maar struikel over het probleem dat er altijd eerst een programma volledig moet afgewerkt zijn voordat een ander programma kan starten.
Voor de timers werk ik met millis.
Ik zou graag hebben dat op ieder moment als de stappenschakelaar (prog_1, prog_2, enz...) in een andere stand komt, arduino dit gekozen programma dan ook direct uitvoert.
Kan mij iemand zeggen wat ik fout doe?
ps: Code is nog niet klaar en de gekozen tijden zijn voor vlug te testen. Hieronder mijn code.
Alvast bedankt

csharp code
Stapmolen Rev.1.4
Pinmodes:

INPUTS:
22 On_Button

26 Prog_0
28 Prog_1
30 Prog_2
32 Prog_3
34 Prog_4
36 Prog_5

OUTPUTS
40 Led_ON
41 Led_P0
42 Led_P1
43 Led_P2
44 Led_P3
45 Led_P4
46 Led_P5
48 Left
49 Right
50 Speed1
51 Speed2
52 Speed3
*/

unsigned long start_tijd = 0; //zet timer op nul
int interval_1 = 5000;
int interval_2 = 2000;

int On_Button = 22;

int Prog_0 = 26;
int Prog_1 = 28;
int Prog_2 = 30;
int Prog_3 = 32;
int Prog_4 = 34;
int Prog_5 = 36;


int led_On = 40;
int led_P0 = 41;
int led_P1 = 42;
int led_P2 = 43;
int led_P3 = 44;
int led_P4 = 45;
int led_P5 = 46;
int Left = 48;
int Right = 49;
int Speed1 = 50;
int Speed2 = 51;
int Speed3 = 52;



void setup()
{

Serial.begin(9600);


pinMode(led_On, OUTPUT);

pinMode(led_P0, OUTPUT);
pinMode(led_P1, OUTPUT);
pinMode(led_P2, OUTPUT);
pinMode(led_P3, OUTPUT);
pinMode(led_P4, OUTPUT);
pinMode(led_P5, OUTPUT);

pinMode(Left, OUTPUT);
pinMode(Right, OUTPUT);
pinMode(Speed1, OUTPUT);
pinMode(Speed2, OUTPUT);
pinMode(Speed3, OUTPUT);

pinMode(On_Button, INPUT_PULLUP);

pinMode(Prog_0, INPUT_PULLUP);
pinMode(Prog_1, INPUT_PULLUP);
pinMode(Prog_2, INPUT_PULLUP);
pinMode(Prog_3, INPUT_PULLUP);
pinMode(Prog_4, INPUT_PULLUP);
pinMode(Prog_5, INPUT_PULLUP);
//Hieronder de opstart annimatie

delay(3000);
digitalWrite(led_P0, HIGH);
delay(200);
digitalWrite(led_P0, LOW);
digitalWrite(led_P1, HIGH);
delay(200);
digitalWrite(led_P1, LOW);
digitalWrite(led_P2, HIGH);
delay(200);
digitalWrite(led_P2, LOW);
digitalWrite(led_P3, HIGH);
delay(200);
digitalWrite(led_P3, LOW);
digitalWrite(led_P4, HIGH);
delay(200);
digitalWrite(led_P4, LOW);
digitalWrite(led_P5, HIGH);
delay(200);
digitalWrite(led_P5, LOW);
digitalWrite(led_P4, HIGH);
delay(200);
digitalWrite(led_P4, LOW);
digitalWrite(led_P3, HIGH);
delay(200);
digitalWrite(led_P3, LOW);
digitalWrite(led_P2, HIGH);
delay(200);
digitalWrite(led_P2, LOW);
digitalWrite(led_P1, HIGH);
delay(200);
digitalWrite(led_P1, LOW);
digitalWrite(led_P0, HIGH);
delay(200);
digitalWrite(led_P0, LOW);
delay(2000);
digitalWrite(led_On, HIGH);
//Einde van de opstart annimatie
}

void loop()
{
// Hieronder worden de variabele gezet voor programmaknop
int Prog_0Value = digitalRead(Prog_0);
int Prog_1Value = digitalRead(Prog_1);
int Prog_2Value = digitalRead(Prog_2);
int Prog_3Value = digitalRead(Prog_3);
int Prog_4Value = digitalRead(Prog_4);
int Prog_5Value = digitalRead(Prog_5);
//einde

//hieronder starten de gebeurtenissen voor de programma's

//Programmaknop op stand 0:

if (Prog_0Value == LOW)
{
// Plaats hier de gebeurtenissen voor Programmaknop 0

//Hieronder de aansturing van de leds
digitalWrite(led_P0, HIGH);
digitalWrite(led_P1, LOW);
digitalWrite(led_P2, LOW);
digitalWrite(led_P3, LOW);
digitalWrite(led_P4, LOW);
digitalWrite(led_P5, LOW);


// Hieronder de aansturing van de relais


digitalWrite (Left, HIGH);
digitalWrite (Right, LOW);
digitalWrite (Speed1,HIGH);
digitalWrite (Speed2,LOW);
digitalWrite (Speed3,LOW);

}

else
{

}



//Programmaknop op stand 1:

if (Prog_1Value == LOW)
{

// Hieronder de aansturing van de leds
digitalWrite(led_P0, LOW);
digitalWrite(led_P1, HIGH);
digitalWrite(led_P2, LOW);
digitalWrite(led_P3, LOW);
digitalWrite(led_P4, LOW);
digitalWrite(led_P5, LOW);

// Hieronder de aansturing van de relais


start_tijd = millis();
while ((millis() - start_tijd) < interval_1) // <---Pas hier tijd loop 1 aan
{
digitalWrite (Left, HIGH);
digitalWrite (Right, LOW);
digitalWrite (Speed1,HIGH);
digitalWrite (Speed2,LOW);
digitalWrite (Speed3,LOW);

}


start_tijd = millis();
while ((millis() - start_tijd) < interval_1) // <---Pas hier tijd loop 2 aan
{
digitalWrite (Left, HIGH);
digitalWrite (Right, LOW);
digitalWrite (Speed1,LOW);
digitalWrite (Speed2,HIGH);
digitalWrite (Speed3,LOW);

}

start_tijd = millis();
while ((millis() - start_tijd) < interval_1) // <---Pas hier tijd loop 3 aan
{
digitalWrite (Left, HIGH);
digitalWrite (Right, LOW);
digitalWrite (Speed1,HIGH);
digitalWrite (Speed2,LOW);
digitalWrite (Speed3,LOW);

}

start_tijd = millis();
while ((millis() - start_tijd) < interval_1) // <---Pas hier tijd loop 4 aan
{
digitalWrite (Left, LOW);
digitalWrite (Right, HIGH);
digitalWrite (Speed1,HIGH);
digitalWrite (Speed2,LOW);
digitalWrite (Speed3,LOW);
}


start_tijd = millis();
while ((millis() - start_tijd) < interval_1) // <---Pas hier tijd loop 5 aan
{
digitalWrite (Left, LOW);
digitalWrite (Right, HIGH);
digitalWrite (Speed1,LOW);
digitalWrite (Speed2,HIGH);
digitalWrite (Speed3,LOW);

}

start_tijd = millis();
while ((millis() - start_tijd) < interval_1) // <---Pas hier tijd loop 6 aan
{
digitalWrite (Left, LOW);
digitalWrite (Right, HIGH);
digitalWrite (Speed1,HIGH);
digitalWrite (Speed2,LOW);
digitalWrite (Speed3,LOW);

}
}



else
{

}



//Programmaknop stand 2



//Programmaknop stand 3



//Programmaknop stand 4



//Programmaknop stand 5



}

Advertisement

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

Re: Millis timer onderbreken

Berichtdoor shooter » 27 Nov 2016, 21:31

de loop moet eigenlijk alleen de knop hebben, als de knop in een andere stand komt , dan de tijd resetten en dan even naar een routine (functie) waar je al je instellingen doet.
in de loop komt dan de controle van de tijd, en als deze gedaan is dan actie ondernemen. (stopzetten)
kijk ook eens op state machine.
paul deelen
shooter@home.nl

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

Re: Millis timer onderbreken

Berichtdoor Koepel » 27 Nov 2016, 22:03

Mijn eerste gedachte was ook een state machine.
Dan wordt de sketch gestuurd door een variabele die de stand/status/staat bepaald. Die variabele heet vaak 'state'. Dat is handig als je voor iedere 'state' iets anders wilt uitvoeren. Doe je voor de 5 standen van de programmaknop iets heel anders, of hetzelfde met andere getallen ?
Wanneer je eenmaal gewend bent aan een state machine, dan is het heel overzichtelijk en gemakkelijk om iets toe te voegen.

Wat dacht je van arrays ?
Stel dat je eerst de knop leest en bepaald wat de stand is. Daarna uit een array lezen hoe de uitgangen gezet worden.
Dan voorkom je dat je 5 keer hetzelfde doet in de sketch. Dat lijkt misschien niet belangrijk, maar dat is heel belangrijk. Als je 5 keer hetzelfde doet, dan is de kans meer dan 5 keer groter dat er een fout in de code sluipt. Ik weet niet of arrays handig zijn, het lijkt er op dat je de leds zet bij een bepaalde stand van de programmaknop, dan zou dat typisch iets zijn voor in een array.

Je kunt de sketch overzichtelijk houden, door eerst alle invoergegevens te lezen. Pas als je alle 'data' binnen hebt, dan pas dat gaan verwerken. Of een knop aan of uit staat zie ik ook als 'data'.

De beroemde en beruchte millis().
Als je tijdens een delay iets wilt doen, dan heb je millis() nodig. Maar niet om in een while-statement te blijven hangen. De millis() wordt gebruikt om te kijken of het tijd is om iets te gaan doen.

Code: Alles selecteren
void loop()
{
  unsigned long currentMillis = millis();

  if( currentMillis - previousMillis > 5000)
  {
    // It's about time to do something.
  }
}


Begin met structuur aanbrengen. Graag zie ik een enkele variabele die de waarde van het programma aangeeft. Bijvoorbeeld integer 'programmaknop' die een waarde 0 tot en met 5 heeft. Kun je ook nog een extra controle voor een foute invoer toevoegen ?
Code: Alles selecteren
void loop()
{
      // Hieronder worden de variabele gezet voor programmaknop
      int Prog_0Value = digitalRead(Prog_0);
      int Prog_1Value = digitalRead(Prog_1);
      int Prog_2Value = digitalRead(Prog_2);
      int Prog_3Value = digitalRead(Prog_3);
      int Prog_4Value = digitalRead(Prog_4);
      int Prog_5Value = digitalRead(Prog_5);
      //einde

      int programmaknop;

      if ( Prog_0Value == LOW)
        programmaknop = 0;
      else if ( Prog_1Value == LOW)
        programmaknop = 1;
      else if ( ....
}


Dan zou je 'programmaknop' kunnen gebruiken als index van een array om de leds goed te zetten.

Gebruikers-avatar
Berichten: 6
Geregistreerd: 27 Nov 2016, 18:07
Woonplaats: Oost Vlaanderen BE

Re: Millis timer onderbreken

Berichtdoor eds » 28 Nov 2016, 20:43

Bedankt om eventjes mee te denken. Het is zoals hierboven al heb geschreven, ik ben nog een beginner met arduino. Ik moet nog veel ervaring en kennis opdoen.
Ik denk ook dat ik te veel code schrijf voor wat ik wil bereiken. Dit moet veel "eenvoudiger" kunnen. Maar dit komt door gebrek aan ervaring (en kennis ;) ).

Sorry voor mms een domme vraag maar hoe gaat dit dan verder?

Code: Alles selecteren
void loop()
{
      // Hieronder worden de variabele gezet voor programmaknop
      int Prog_0Value = digitalRead(Prog_0);
      int Prog_1Value = digitalRead(Prog_1);
      int Prog_2Value = digitalRead(Prog_2);
      int Prog_3Value = digitalRead(Prog_3);
      int Prog_4Value = digitalRead(Prog_4);
      int Prog_5Value = digitalRead(Prog_5);
      //einde

      int programmaknop;

      if ( Prog_0Value == LOW)
        programmaknop = 0;
      else if ( Prog_1Value == LOW)
        programmaknop = 1;
      else if ( ....
}

Moet ik dan een verwijzing maken, zoals...
while (programmaknop = 0) {doe iets}
while (programmaknop = 1) {doe iets anders}
.....

Maar dan blijf ik toch ergens met een vraag zitten waar ik nog geen antwoord op heb gekregen. Waarom moet nog eerst het programma worden uitgevoerd alvorens naar de programmaknop te kijken, ondanks het gebruik van milis? Op deze manier kan ik toch net zo goed gebruik maken van delay()?

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

Re: Millis timer onderbreken

Berichtdoor Koepel » 28 Nov 2016, 21:54

Ik bedoelde één variabele die de waarde van de programmaknop heeft. Dus die variabele is 0, of 1, of 2, ... 5.

Dan heb je dus eerst een deel dat bekijkt hoe de programmaknop staat, en die variabele gaat naar het tweede deel waar er iets mee gedaan wordt.

Het hoeft natuurlijk niet op die manier, maar het maakt het wat overzichtelijker, en het wordt volgens mij ook eenvoudiger.

En als je millis() gebruikt om in een while-statement te blijven hangen, dan kun je net zo goed delay() gebruiken. Maar daar is millis() dan ook niet voor bedoeld. millis() wordt gebruikt om te kijken of er op dat moment iets gedaan moet worden. Alsof je regelmatig naar de klok kijkt of het al 3 uur geleden is dat je voor het laatst koffie had. Op die manier kun je ook nog andere dingen doen, zoals kijken of de programmaknop veranderd.

Dit vereist toch wel enig programmeerwerk. De programmaknop heeft 5 standen, en per programma een sequence uitvoeren met vertragingen. Het is niet zo eenvoudig voor een beginner.

Gebruikers-avatar
Berichten: 6
Geregistreerd: 27 Nov 2016, 18:07
Woonplaats: Oost Vlaanderen BE

Re: Millis timer onderbreken

Berichtdoor eds » 28 Nov 2016, 22:48

Koepel schreef:Dit vereist toch wel enig programmeerwerk. De programmaknop heeft 5 standen, en per programma een sequence uitvoeren met vertragingen. Het is niet zo eenvoudig voor een beginner.


Ik heb dit blijkbaar een beetje onderschat, maar ga het toch niet te snel opgeven. Dat is de beste leerschool.
In ieder geval al bedankt voor de tips!

Terug naar C code

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 10 gasten