Hallo inka,
sorry diese WE ist bei mir volles Programm.
Ich habe das Ganze nochmal auf einen Motor und Encoder heruntergebrochen. Das Programm zeigt nach dem alles initialisiert ist im Wechsel "Regeln" und "andere Aktion" an. Wobei Letzteres mehrfach hintereinander vorkommen kann.
Wie Du sehen kannst wird die Ticker Variable dabei hochgezählt, ohne das Du Dich darum weiter kümmern mußt. Genau das ist das Praktische mit Interrupts, Aktionen laufen quasi paralel ab und Du kannst in Deiner loop Dich mit anderen Aktionen beschäftigen. Hoffe dieses Beispiel ist verständlicher als der andere uberfrachtete Sketch.
Code:
#include <AFMotor.h>
// Motor
AF_DCMotor motor(4);
// Die Anzahl der Flankenwechsel
volatile unsigned long ticks = 0;
// passender Encode Pin für den Motor
static const uint8_t enc_pin = 18;
/*
* Die Interrupt Routine die beim Flankenwechsel aufgerufen wird
*/
void motor_isr(void){
ticks++;
}
/*
* Serial und den Pin initialisieren, die Interrupt Routine
* zuordnen.
*/
void setup() {
Serial.begin(9600);
pinMode(enc_pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(enc_pin), motor_isr, CHANGE);
Serial.println("setup fertig");
}
void loop() {
unsigned long start_zeit, regel_zeit, aktions_zeit;
/*
* Ticks beschreiben, dabei wollen wir nicht von einem
* Interrupt unterbrochen werden
*/
noInterrupts();
ticks = 0;
interrupts();
motor.setSpeed(130);
motor.run(FORWARD);
Serial.println("ticks initialisiert und Motor laeuft");
/*
* Fuer 10 sec "Regeln" und eine andere Aktion parallel
* dazu ausführen.
*/
start_zeit = regel_zeit = aktions_zeit = millis();
while(start_zeit + 10000 > millis() ) {
/*
* Motor "regeln" alle 0,5sec
*/
static const unsigned long rdiff = 500;
if(regel_zeit + rdiff <= millis()) {
regel_zeit = rdiff + millis(); // nächstes Intervall setzen.
Serial.print(millis());
Serial.print(": Regeln ");
/*
* Wir lesen unseren Zaehler und wollen nicht
* von Interrupts gestört werden
*/
noInterrupts();
unsigned long tmp = ticks;
interrupts();
Serial.println(tmp);
}
/*
* Die andere Aktion die Parallel zum "Regeln" ausgeführt wird
* und nur unterbrochen wird, wenn ein Interrupt auftritt.
*/
static const unsigned long adiff = 333;
if(aktions_zeit + adiff <= millis()) {
aktions_zeit = adiff + millis(); // Nächste Intervall setzen
// Hier irgendetwas anderes machen
Serial.print(millis());
Serial.println(": andere Aktion");
}
}
Serial.println("Motor stop");
motor.setSpeed(0);
motor.run(RELEASE);
delay(2000);
}
Grüße
Chris
Lesezeichen