In der letzten Zeit habe ich mit Arduino vor allem herumgespielt, um verschiedene Komponenten kennenzulernen. Das Projekt, das ich hier vorstelle, ist die Weiterentwicklung aus einem Beispiel in meinem Experimentierkit (Hersteller und Bezugsadresse hier).
In diesem Beispiel lässt man einen Gleichstrommotor mit zu- und abnehmender Geschwindigkeit laufen. Da das Gesumse des Motors mich beim Denken störte, ich aber auch nicht ständig das USB-Kabel ein- und ausstecken wollte, war natürlich sofort das Bedürfnis nach einem Schalter da. Also wollte ich die Schaltung mit einem Pushbutton ergänzen. Gesagt, getan. Doch mit meiner Pushbutton-Lösung hatte ich mir gleich zwei neue Probleme eingehandelt:
-
Der Motor spult sein Programm in einem Endlosloop ab, der Button soll diesen Ablauf unterbrechen. Wie macht man das, wenn ein Programm aus einer einzigen Endlosschleife besteht? Richtig, ein Interrupt muss her!
- Auch nach der Programmierung des Interrupts führte ein Tastendruck zu absolut erratischem Verhalten. Mal passierte gar nichts, dann schaltete der Motor ein- und sofort wieder aus, manchmal mehrmals hintereinander. Dieses Phänomen bezeichnet man als Nachfedern oder in Neudeutsch Bouncing. Ein Knopfdruck sendet nicht ein einzelnes sauberes Signal, sondern durch das mechanische Nachfedern werden mehrere Signale hintereinander in kürzestem Zeitabstand ausgelöst. Die Library Bounce ermöglicht es nun, dass ein Arduino-Programm nur auf den ersten Tastendruck einer Serie reagiert.
Den Programmcode stelle ich ohne weitere Erläuterungen ins Netz. Zusammen mit dem Schaltplan, dem Bild und den Kommentaren im Code sollte das Experiment verständlich sein. Wichtig ist höchstens noch, dass debouncer.update nicht nur im loop steht sondern auch innerhalb der for-Schleifen , damit der Motor nicht nur am Ende seines Zyklus unterbrochen werden kann.
/* Weiterentwicklung von Arduino Experimentation Kit Example Code CIRC-03 : Spin Motor Spin * http://ardx.org/src/circ/CIRC03-code.txt * ergänzt mit * - Interrupt-Funktion zum Starten und Stoppen des Motors auf Knopfdruck * http://www.arduino.cc/en/Reference/AttachInterrupt * - Debounce, um Prellen des Buttons abzufangen * siehe: http://arduino.cc/playground/Code/Bounce * * Author: Silvia Rothen, rothen ecotronics, Bern, Switzerland */ #include <Bounce.h> int motorPin = 9; volatile boolean on = false; //debouncing the push button Bounce debouncer = Bounce(2, 20); void setup() { pinMode(motorPin, OUTPUT); //The Arduino Uno has two external interrupts: //numbers 0 (on digital pin 2) and 1 (on digital pin 3) //here the interrupt function is attached attachInterrupt(0, change, LOW); //LOW CHANGE RISING FALLING } void loop() { debouncer.update(); if (on) { motorAcceleration(); } } //this is the interrupt method void change() { //debouncer.update() ist hier nicht erlaubt if (debouncer.read()) { on = !on; } } /* * motorAcceleration() - accelerates the motor to full speed then * back down to zero, if not interrupted by pushbutton */ void motorAcceleration(){ int delayTime = 50; //milliseconds between each speed step int minValue = 100; int maxValue = 200; //Accelerates the motor //goes through each speed from minValue to maxValue for(int i = minValue; i < maxValue; i++){ debouncer.update(); //has the interrupt changed this value? if (!on) { analogWrite(motorPin, 0); //stops the motor break; } analogWrite(motorPin, i); //sets the new speed delay(delayTime); // waits for delayTime milliseconds } //Decelerates the motor for(int i = maxValue; i >= minValue; i--){ debouncer.update(); //has the interrupt changed this value? if (!on) { analogWrite(motorPin, 0); //stops the motor break; } analogWrite(motorPin, i); //sets the new speed delay(delayTime); // waits for delayTime milliseconds } }
Allgemeine Infos und Links zu Arduino wie immer auf meinem Arduino Cheat Sheet.