Go Down

Topic: Debounce Skript erweitern (Read 795 times) previous topic - next topic

Glasreiniger

Servus zusammen,


ich versuche vergeblich das Beispiel "debounce button" mit der Servosteuerung zu kombinieren.

Ziel soll sein, den jetzt entprellten Button zum steuern eines Servos zu benutzen.
Dazu habe ich die servo.h eingebunden.

Mit dem einfachen Button läuft auch alles.

Nur entprellt klappet es nicht.

Ich schnalle nicht, wo ich das Script erweitern kann, damit der Servobefehl ausgeführt wird.

Vielen Dank und sorry für die Anfängerfragen. Ich habe aber kein Beispiel gefunden, wo jemand mehr als die LED verwendet.

Hier mal der Code:

Code: [Select]
/*
  Debounce

  Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
  press), the output pin is toggled from LOW to HIGH or HIGH to LOW. There's a
  minimum delay between toggles to debounce the circuit (i.e. to ignore noise).

  The circuit:
  - LED attached from pin 13 to ground
  - pushbutton attached from pin 2 to +5V
  - 10 kilohm resistor attached from pin 2 to ground

  - Note: On most Arduino boards, there is already an LED on the board connected
    to pin 13, so you don't need any extra components for this example.

  created 21 Nov 2006
  by David A. Mellis
  modified 30 Aug 2011
  by Limor Fried
  modified 28 Dec 2012
  by Mike Walters
  modified 30 Aug 2016
  by Arturo Guadalupi

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/Debounce
*/

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;    // the number of the pushbutton pin
const int ledPin = 12;      // the number of the LED pin

#include <Servo.h> //Die Servobibliothek wird aufgerufen. Sie wird benötigt, damit die Ansteuerung des Servos vereinfacht wird.
Servo servoblau; // Der Servo heisst jetzt ServoBlau

// Variables will change:
int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  servoblau.attach(8); //Das Setup enthält die Information, dass das Servo an der Steuerleitung (gelb) mit Pin 8 verbunden wird. Hier ist natürlich auch ein anderer Pin möglich.
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);

  // set initial LED state
  digitalWrite(ledPin, ledState);
  servoblau.write(0);
}

void loop() {
 
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        ledState = !ledState;
      }
    }
  }

  // set the LED:
  digitalWrite(ledPin, ledState);
  servoblau.write(90);

  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;
}


Gruß
Claus

Glasreiniger

Habe jetzt etwas gefunden, was schon fast passt.

Code: [Select]
int LEDblau=12;
int taster=2;
int tasterstatus=0;
#include <Servo.h>
Servo servoblau; //Name vom Servo


void setup()
{
pinMode(LEDblau, OUTPUT);
pinMode(taster, INPUT);
servoblau.attach(8); //Das Setup enthält die Information, dass das Servo an der Steuerleitung (gelb) mit Pin 8 verbunden wird. Hier ist natürlich auch ein anderer Pin möglich.
}

void loop()
{
tasterstatus=digitalRead(taster);
servoblau.write(90); // Servo auf Anfang
if (tasterstatus == HIGH)
{
digitalWrite(LEDblau, HIGH);
servoblau.write(180); // Servo auslenken
delay (500);
digitalWrite(LEDblau, LOW);
servoblau.write(90); // Servo auf Anfang
}
else
{
digitalWrite(LEDblau, LOW);
//servoblau.write(90); // Servo auf Anfang
}
}


Wie schaffe ich, hier eine Flankenauswertung zu bekommen?


Gruß
Claus

michael_x

Und warum nimmst du nicht den ersten Sketch und machst an der Stelle
  // only toggle the LED if ..
stattdessen mit deinem Servo rum ?

Glasreiniger

Hi,
danke für deine Antwort. Momentan klappt garnichts. Scheint ich habe das Brett gegrillt. Nimmt nichts mehr an und sogar LED mit einfachstem Schalter spinnt.

Melde mich wenn ich es habe oder ein neues Uno habe.

Gruß
Claus

Glasreiniger

#4
Mar 16, 2019, 05:07 pm Last Edit: Mar 16, 2019, 05:13 pm by Glasreiniger
Servus. Es ist vollbracht.

Das erste Projekt nimmt Form an.

Ich habe mich da jetzt reingefuggert und es klappt.

Code: [Select]
/*
  State change detection (edge detection)

  Often, you don't need to know the state of a digital input all the time, but
  you just need to know when the input changes from one state to another.
  For example, you want to know when a button goes from OFF to ON. This is called
  state change detection, or edge detection.

  This example shows how to detect when a button or button changes from off to on
  and on to off.

  The circuit:
  - pushbutton attached to pin 2 from +5V
  - 10 kilohm resistor attached to pin 2 from ground
  - LED attached from pin 13 to ground (or use the built-in LED on most
    Arduino boards)

  created  27 Sep 2005
  modified 30 Aug 2011
  by Tom Igoe

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/ButtonStateChange
*/

// this constant won't change:
const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int ledPin = 13;       // the pin that the LED is attached to
#include <Servo.h>           // Servo Library einbinden
Servo servo1;             //Name vom Servo 1
Servo servo2;             //Name vom Servo 2

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button


void setup() {
  pinMode(buttonPin, INPUT);  // initialize the button pin as a input:
  pinMode(ledPin, OUTPUT);    // initialize the LED as an output:
  Serial.begin(9600);         // initialize serial communication:
  servo1.attach(8);        // Servo 1 mit Pin 8 verbunden
  servo2.attach(9);        // Servo 2 mit Pin 9 verbunden

}


void loop() {
  buttonState = digitalRead(buttonPin);// read the pushbutton input pin:

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
      digitalWrite(ledPin, HIGH);
      servo1.write(180); // Servo auslenken
      delay (700);           // Servo Aktion
      servo1.write(90);   // Servo auf Anfang
      delay (50);             // Zeit zwischen Servos
      servo2.write(180); // Servo auslenken
      delay (700);          // Servo Aktion
      servo2.write(90); // Servo auf Anfang
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
      servo1.write(90);   // Servo auf Anfang
      servo2.write(90);   // Servo auf Anfang
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;
}


Der Button wird ausgewertet und bei steigender Flanke wird der Servo für eine eingestellte Zeit ausgelenkt, danach auf Anfang gefahren. Nach dieser Zeit wird ein zweites Servo ausgelenkt, fährt dann nach seiner Zeit wieder auf Anfang.

Wenn jemand einen Ratschlag hat, was ich noch optimieren kann, dann gerne her damit!

Gibt es Tips, welches Servo was taugt? Haltbar, kein Kraftprotz, einfach ein gutes normales Servo, gerne niedrig im Verbrauch.

Und.... warum tickert das Servo immer da rum? Also es fährt nicht, man hört aber, das es etwas macht. Nicht immer, aber manchmal. Momentan habe ich allerdings auch das billigste Mikro Servo dran. Daran liegt es vielleicht auch.

Das ganze läuft übrigens mit einem Nano auf dem ProtoV3 Board.

Gruß
Claus





michael_x

Glückwunsch erstmal !
Quote
Wenn jemand einen Ratschlag hat, was ich noch optimieren kann, dann gerne her damit!
Mindestens die langen delay(700); sollten bei Erweiterungen raus, und der Programmablauf nach dem BlinkWithoutDelay - Prinzip ( der berühmte Nachtwächter ) gestaltet werden.





Doc_Arduino

Hallo,

mit verlaub, der Sketch macht Null Sinn und die Servos funktionieren auch jetzt nicht richtig.
Die Servos benötigen ca. aller 20ms ihren Sollwert, wenn der nicht kommt stehen sie entweder saft- und kraftlos irgendwo rum oder verhalten sich nicht so wie man das erwartet.

Trenne Taster und Servos auf.

Beide bekommen eine eigene Funktion die ständig ohne delay aufgerufen wird. Nutze millis(). Der Servofunktion übergibts du dann nur entsprechend Tasteraktion die entsprechenden Soll-Werte. Die Servofunktion wird also ohne delay aller 20ms aktiv.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

postmaster-ino

#7
Mar 16, 2019, 06:44 pm Last Edit: Mar 16, 2019, 06:44 pm by postmaster-ino
Hi

Ging ich dann bisher fälschlicher Weise davon aus, daß die Servo-Lib selber dafür sorgt, daß Sie 'ab und zu' aufgerufen wird? - Bzw. der Impuls eben generiert wird, was der Timer auch ganz alleine kann.
Dann bräuchte ich aber eine Methode, Die im normalen Sketch dauernd aufgerufen wird, damit die Lib die Impulse erzeugen kann und nicht nur, wenn eine Positions-Änderung erwünscht ist.
Habe jetzt noch nicht so viel mit Servos gespielt, aber meine mich erinnern zu können, daß ein delay() Diesen völlig egal war - die Position wurde gehalten, die Servos hatten also Kraft.

MfG
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

Doc_Arduino

Hallo,

stimmt, da war doch was gewesen.   :o   Sie nutzt Hardware Timer, wie sie sich selbst aufruft habe ich noch nicht durchblickt. Der write(x) Wert wird in Timer-Ticks gewandelt der wiederum einen Interrupt auslösen soll. Den sehe ich aber noch nicht in der Lib. Wenn du sagst das ein delay keine Wirkung hat dann kann das nicht anders sein.

Davon abgesehen würde ich dennoch die Taster und Servos in getrennten Funktion behandeln. Ohne delay.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Glasreiniger

......und er stand daneben und hatte den Mund offen........

Männers.....

Das könnt Ihr super, das Fachsimpeln.

Es macht auch bestimmt Sinn und ist auch von gehaltvoller Wertigkeit, was ihr hier schreibt.

Ich verstehe es nur noch nicht.

Nicht falsch verstehen, aber ihr wisst es. Würdet ihr es auch beschreiben? Ich kann mit konkreten Hilfen mehr anfangen, als mit Andeutungen, seien sie noch so Sinnhaft.

Mich machen Aussagen wie "macht Null Sinn" nicht happy.
Aber es ist nun mal in Foren so, wie es ist.
Solche Leute, die viel Wissen aber es nicht erklären wollen oder können oder einfach nur von Noobs, wie ich noch einer bin, genervt scheinen.

Der Sketch macht absolut Sinn. Wenn du willst erkläre ich ihn. Das da programmiertechnische Defizite sind, deutete ich an und erbat Hilfe und Anregungen.

Deinen Rat habe ich übrigens befolgt und habe Taster und Servo aufgetrennt. War eine Sauarbeit, bei der ich mich fast geschnitten habe, aber jetzt sehe ich die Innereien. Wie jetzt weiter?

Verstehst du, was ich meine?

Deinen Rat in Ehren, aber wenn du vermutest, ich könnte zu dem jetzigen Zeitpunkt schon etwas mit dieser Erklärung anfangen.... kann ich nicht.

Sonst hätte ich den Rotz hier nicht gepostet, sondern es direkt richtig gemacht.

Danke aber trotzdem.


Gruß
Claus






postmaster-ino

Hi

Dann, Junge, mach den Mund wieder zu und zeige, was Du jetzt hast.
Wenn's dann sogar kompiliert und Dein beschriebener Fehler auch für uns nachvollziehbar ist, könnte vll. was daraus werden.

Vll. solltest Du die Post's, Die Du so nett als 'Fachsimpeln' abgetan hast, lesen?
Vll. wäre Dir dann aufgegangen, daß ich eine etwas andere Meinung bezüglich der Servo-Ansteuerung als Doc_Arduino ha(b/tt)e?

Weiter: Wenn Du etwas nicht verstehst, ist Das noch lange kein Beinbruch - Du darfst ja unwissend sein, aber hier mit Tränen in den Augen und mit dem Fuß aufstampfend eine am besten schon fertig und durch getestete Lösung erhalten zu wollen ... träum weiter.

So, mit diesem Rotz bin ich dann auch durch, schönen Tag noch.

MfG
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

Doc_Arduino

Hallo,

habs mir nochmal am Oszi angeschaut, servo.write taktet wirklich unabhängig von delays. Wieder was gelernt. Jetzt kann man in zwei Richtungen argumentieren. delay weglassen oder doch nur aller ca. 20ms aktualisieren, weil eh nur aller 20ms ein neuer Wert übernommen wird. Ich nenne es Aktualisierungsrate.

@ TO:
Ausgekotzt? Wieder alles cool?
Man sollte keine Beiträge verfassen wenn man in irgendeiner Form wütend ist, aus eigener Erfahrung.
Dieses "Fachsimpeln" wie du es nennst ist ein normaler Vorgang in einem Thread. postmaster hat mich in meiner falschen Annahme korrigiert und damit letztlich auch dir Wissen vermittelt. Jetzt hast du quasi nebenbei mitbekommen wie servo.h intern arbeitet. Nimms einfach mit.

Jetzt hak das ab, zeige deinen Sketch, dann sehen wir weiter.

Theseus erklärt millis()
http://forum.arduino.cc/index.php?topic=400102.msg2752141#msg2752141

GuntherB - BlinkwithoutDelay - Die Nachtwächtererklärung
http://forum.arduino.cc/index.php?topic=423688.0
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Glasreiniger

#12
Mar 17, 2019, 04:32 pm Last Edit: Mar 17, 2019, 05:20 pm by Glasreiniger
 :smiley-grin:

So stelle ich mir das vor!  :smiley-twist:

Das Problem mit euch Brüdern, ihr WISST es, schnallt aber nicht, wo das Wissen des Gegenüber aufhört. :smiley-wink:
Ich kann ein wenig programmieren, habe aber leider von C keine Ahnung.
Daher nehme ich mir Legosteine aus der Tonne und probiere herum. Lego schnitzen, so wie ihr es könnt, kann ich noch nicht.
Also. Ja - Cool.
Und ich war nicht wütend. Es fuxxxt nur. Die Links waren der Schied Unter.

Weiter in Thema.
Das Script ist für einen Ballspender. 
Der soll mit einem Funksignal ausgelöst werden, und es fallen dann Tennisbälle aus einem Rohr, welches 100m weit weg in einem Baum hängt.

Der Ablauf ist, das der Ball fällt, wenn der Haltemechanismus durch den Servo1 gelöst wird. Dazu geht Servo1 in die OFFEN Stellung, wartet dort bis der Ball rausgefallen ist und geht dann wieder in ZU Position. Danach öffnet der zweite Servo den Nachschub und es wird wieder geladen.
Die Delayzeit ist, damit der Ball in Ruhe fallen kann und wird nach Bedarf eingestellt, sicher sind 700 zu lang, es muss aber die Mechanik erst einmal fertig sein.
Dieses Script soll quasi nur der Trigger sein. Idealerweise ist das nachher eine Funktion (Klasse, Methode???) die ich hinterher vom Masterscript aufrufe.
Der Button-Input wird von einem Schaltsignal vom Empfängermodul (433MHz Shield) kommen.
Es soll irgendwann möglich sein von dem Mastergerät noch (habe 4 Kanäle zum schalten) weitere drei Sklaven zu schalten, die mit einem Sender befeuert werden.

Ob ich das schaltungsmäßig hinbekomme, einen Schaltimpuls durch den master zu den Sklaven zu schicken zeigt sich dann, das ist zweitrangig. Der master muss erst einmal laufen.

Bitte keine Fragen warum man so etwas braucht. Frauen wollen, das irgendwo gesteuert Bälle rausfallen, damit Hunde die holen können. So etwas gibt es schon, aber wer will kaufen?

Zu den offenen Punkten:
Servos und Strom - die Öffnung braucht keine Kraft, das Schliessen auch nicht. Einzig das Halten der Bälle in der Nachschubröhre könnte was brauchen.
Zusatzidee: Display mit Ladezustand der Batterie.
Kann man den Stromverbrauch visualisieren? Wäre ein nettes Gimmick. Hier Sinnlos, aber grundsätzlich interessant.
Kann man println() für den Ausgang nutzen? Damit man sieht, wenn der Servo angesteuert wird? Ich habe (noch) nur einen und improvisiere da mit einer LED.

Die Tips und Anregungen arbeite ich noch ein. Ich Arbeite gerade ein Tutorial zum Thema Funktionen durch.

Gruß
Claus

Edith meinte, die Erklärungen mit dem Nachtwächter und den millis() seien gut, aber wie ersetze ich Sinnhaft delay? Es soll doch genau nix passieren. Kein weiterlaufen und so.
Wie kann ich den den Nachtwächter mit servo.write erweitern?

Doc_Arduino

Hallo,

ich dachte du wolltest uns deinen Sketch zeigen?

delay/millis, ich meine Theseus hat das doch sehr anschaulich erklärt.
Du schiebst deine Pizza in den Ofen, bleibst 12min davor stehen bis sie fertig ist.
Das wäre dein delay, du wartest sinnlos 12min und machst nichts weiter außer warten.

Mit millis, deiner Armbanduhr merkst du dir die Zeit als du die Pizza in den Ofen geschoben hast. Du weist das du sie 12min später rausholen musst. Also merkst du dir die Zeit vom reinschieben und vergleichst ab und zu wann die Differenz von 12min zur aktuellen Zeit vorbei ist. In der Zwischenzeit kannst du andere Dinge erledigen. Kaffee kochen, Tisch decken, aufräumen was auch immer.

Mit der Methode kannst du blockierfrei alles zyklisch abfragen, schalten und walten was du möchtest.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

postmaster-ino

Hi

Wenn die Tennisbälle immer Alle gleich groß sind (gehe ich Mal von aus, spiele kein Tennis), könnte man doch in einem Rohr unterhalb der Reservoir eine Stange 'zwischen die Bälle' schieben - dann kann der Obere nicht an der Stange vorbei, ich brauche keine Kraft/keinen Strom, diesen Zustand die nächsten 2 Wochen aufrecht zu halten.
Gleiches unter dem 2.ten Ball unterhalb des 1.ten.
Die untere Stange lässt den darüber wartenden Ball fallen.
Dadurch, daß oberhalb der Weg durch die obere Stange versperrt ist, kommt noch Nichts nach.
Unten wieder zu, oben auf, Bälle fallen nach.
Oben wieder zu, Alles in Ausgangsstellung.

So kannst Du die Servos ggf. auch abschalten (kA, wie sich der Datenpin auf Vdd der Servos auswirkt, ggf. geht Das nicht ganz so einfach) - Das würde Strom sparen.

Anzeige des 'Akku-Füllstand' - entweder übermittelst Du diesen Wert per Funk zurück - Ausgelöst wird ja ebenfalls per Funk, oder Du machst eine Anzeige, Die entweder aktiviert wird (LED-Balken oder so Zeug), oder gehst auf ein E-Paper :) - Das hält den angezeigten Inhalt die nächsten Jahre ohne Versorgungsspannung - dafür ist Es in der Ansteuerung lahm, zwe iSekunden pro Bildaufbau musst Du rechnen.
Dort kannst Du dann noch weiteres Zeug anzeigen lassen - Anzahl der Bälle, Zeitpunkt des letzten Ball, irgend was Unnützes halt - Spaß gehört schließlich dabei.

Wenn dieses Konstrukt für Hunde gedacht ist, warum den Ball dann nicht schießen?
Wobei Das dann nicht mehr mit dem Akku des Arduino möglich ist ... mir schwirrte gerade so eine Tennis-Kanone durch den Kopf und ein halbes Dutzend Hunde, Die den Bällen hinterher jagen ...

... was man aber durchaus erreichen kann, wenn man Deine angedachten 4 Ball-Spender in einiger Entfernung zueinander aufhängt.

MfG

PS: Wie langweilig - wir hatten unseren Altdeutschen mit Schneebällen den Berg rauf und runter gejagt - und Der war noch fit, als uns bereits die Arme ab fielen :)
Ok, Sommer ... kein Schnee - lasse ich gelten ;)
Dein Problem, Dein Sketch, Deine Bilder.
Ob ich ohne Diese an Deinem Problem arbeiten will, entscheide aber immer noch ich.
Große Buchstaben? Immer wieder, neben Punkt und Komma, gerne gesehen.

Go Up