Tijd programmeren

Arduino specifieke Software
Gebruikers-avatar
Berichten: 700
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Tijd programmeren

Berichtdoor pjh » 11 Feb 2013, 20:52

Ik moest eens een knipper patroon van een LED op een alarmsysteem uitlezen met de arduino voor iemand.
Ik heb het signaal op een interrupt-pin van de arduino gezet (pin 2 of 3) en telkens wanneer de LED-lamp van status veranderde, liet ik de interrupt een timer resetten. Op deze manier was de duur van de laatste episode HIGH of LOW, steeds beschikbaar in de loop.
Wanneer je absoluut niet begrijpt wat ik bedoel, zal ik een voorbeeld sketch maken. Groet. Paul

Advertisement

Berichten: 10
Geregistreerd: 11 Jan 2013, 13:08

Re: Tijd programmeren

Berichtdoor martinus » 11 Feb 2013, 23:36

hoi,

Absoluut niet begrijpen wat je bedoeld is het niet, maar het is wel allemaal nieuw voor mij,
een voorbeeld zou verhelderend kunnen zijn , maar op pin 2, 3, 4 en 5 heb ik al een lcd 16 * 2 aangesloten.

Martien.

Gebruikers-avatar
Berichten: 700
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Tijd programmeren

Berichtdoor pjh » 12 Feb 2013, 22:45

De Button-sketch die standaard bij de Arduino-IDE onder [Bestand]-[Voorbeeld]-[02 Digital]-[Button] staat, laat een ledje branden als je een knopje indrukt.

Code: Alles selecteren
// http://www.arduino.cc/en/Tutorial/Button

const int buttonPin = 2;
const int ledPin =  13;
int buttonState = 0;

void setup() {
  pinMode(ledPin, OUTPUT);     
  pinMode(buttonPin, INPUT);     
}

void loop(){
  buttonState = digitalRead(buttonPin);

  if (buttonState == HIGH) {     
    digitalWrite(ledPin, HIGH); 
  }
  else {
    digitalWrite(ledPin, LOW);
  }
}


Hieronder mijn versie van hetzelfde programma, maar nu met een interrupt.
Code: Alles selecteren
volatile boolean AU=0;

void setup() {
  pinMode(13, OUTPUT);     
  attachInterrupt(0, AanUit, CHANGE);
}

void loop(){
}

void AanUit(){
  AU = 1-AU;
  digitalWrite(13, AU);
}


Met de opdracht attachInterrupt, verbind ik de pin van interrupt 0 ( = pin 2 op de arduino) met het stukje code onder AanUit. Dat gebeurt zo, dat als de toestand op pin 2, dus interrupt 0, verandert, AU van 0 naar 1 gaat, of van 1 naar 0. Op deze manier houd je je loop vrij. Dit opent de mogelijkheid te gaan tellen hoe lang de pin HIGH of LOW is geweest. Overigens moeten alle variabelen die vanuit een interrupt-routine worden aangesproken, vooraf worden gegaan door het woord volatile. Om tijd weer te geven hebben we niks aan een led. Dus verander deze LED naar een Seriele output.
Code: Alles selecteren
volatile boolean AU=0;

void setup() {
  Serial.begin(9600);
  attachInterrupt(0, AanUit, CHANGE);
}

void loop(){
}

void AanUit(){
  AU = 1-AU;
  Serial.println(AU);
}

Zoals je zult merken wanneer je de sketch uitvoert, is er geen zogenaamde debounce is geimplementeerd. Daardoor krijg je bij één druk op de knop, soms toch meermaals een response. Hier kom ik verderop op terug (denk ik :?: ).
Nu de tijd meten dat de pin HIGH of LOW staat. Hiervoor gebruiken we de interne counter die zich in een sketch laat vangen met millis(). Deze functie geeft het aantal miliseconden dat de Arduino na reset of opstart aan is. Telt dus mooi de miliseconden. Wanneer we in de interrupt-routine een andere variabele gelijk zetten aan deze tijd, weten we hoe lang het geleden was, dat de laatste keer op de knop werd gedrukt. Hier een voorbeeld:
Code: Alles selecteren
volatile unsigned long tijdVanLaatsteDruk;

void setup() {
  Serial.begin(9600);
  attachInterrupt(0, AanUit, CHANGE);
}

void loop(){
  Serial.println(millis()-tijdVanLaatsteDruk);
}

void AanUit(){
  tijdVanLaatsteDruk = millis();
}


Hieronder de output van deze sketch. Het is een hele lange lijst, die ik integraal neerzet, omdat het 't 'bouncing' van de button goed laat zien. Ik druk maar één keer op het knopje, toch zie je de tijdVanLaatsteDruk 2x gereset worden.
52567
52574
52581
52589
52596
52604
52611
52618
52625
2
5
8
12
16
20
25
29
33
37
41
45
49
54
58
62
66
70
74
78
82
86
91
96
100
105
110
115
120
125
130
135
141
2
5
8
12
16
20
.......

Verder kun je uit de lijst aflezen dat het 5-7 ms duurt voor een waarde, om op de seriele monitor te verschijnen. Ik heb daarom de zelfde sketch uitgevoerd op 115200 baud. Dan ziet het er zo uit:
13118
13119
13119
13120
13120
13121
13122
13122
13123
0
1
1
1
1
2
2
2

Dus meerdere outputs per miliseconden. Precies wat je verwacht.
Hieronder de finale sketch, waar alles samen komt. Kan vast beter. Misschien kun je zelf achterhalen hoe die werkt. Ander hoor ik het wel.

Code: Alles selecteren
volatile unsigned long tijdVanLaatsteDruk;
volatile unsigned long duurVanLaatsteDruk;
volatile unsigned long duur;

void setup() {
  Serial.begin(9600);
  attachInterrupt(0, AanUit, CHANGE);
}

void loop(){
}

void AanUit(){
  duur = millis()-tijdVanLaatsteDruk;
  if (duur > 50){
    duurVanLaatsteDruk = duur;
    tijdVanLaatsteDruk = millis();
    Serial.println(duurVanLaatsteDruk);
  }
}

Gebruikers-avatar
Berichten: 700
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Tijd programmeren

Berichtdoor pjh » 12 Feb 2013, 23:11

Deze sketch geeft ook aan of de knop aan of uit was.
Code: Alles selecteren
volatile boolean AU;
boolean AUoud;
volatile unsigned long tijdVanLaatsteDruk;
volatile unsigned long duurVanLaatsteDruk;
volatile unsigned long duur;
String aanuit[] = {"Aan : ",   "Uit : " };

void setup() {
  Serial.begin(9600);
  attachInterrupt(0, AanUit, CHANGE);
}

void loop(){
  if (AU != AUoud){
    Serial.print(aanuit[AU]);
    Serial.println(duurVanLaatsteDruk);
    AUoud = AU;
  }   
}

void AanUit(){
  duur = millis()-tijdVanLaatsteDruk;
  if (duur > 50){
    AU = 1 - AU;
    duurVanLaatsteDruk = duur;
    tijdVanLaatsteDruk = millis();
  }
}


Berichten: 10
Geregistreerd: 11 Jan 2013, 13:08

Re: Tijd programmeren

Berichtdoor martinus » 13 Feb 2013, 00:30

hoi,
bedankt voor de sketches,
ik ga mij er in verdiepen donderdag avond.
maar zo te zien heb ik meerdere avonden nodig.
ik moet zoiets altijd lang op mij laten inwerken.
als er schot in het zaakje komt reageer ik wel weer.

Martien

Gebruikers-avatar
Berichten: 700
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Tijd programmeren

Berichtdoor pjh » 13 Feb 2013, 10:45

gewoon lekker de tijd nemen. Aarzel echter niet bij onduidelijkheden je vraag te posten. Kunnen we er allemaal van leren. :P

Vorige

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 20 gasten