Ersetze den Motor durch eine LED und überzeuge dich davon dass deine Beschreibung nicht mehr zutrifft.
Ich habe das hier aufgebaut und laufen, du kannst mir das ruhig glauben. ![]()
Ersetze den Motor durch eine LED und überzeuge dich davon dass deine Beschreibung nicht mehr zutrifft.
Ich habe das hier aufgebaut und laufen, du kannst mir das ruhig glauben. ![]()
okay, jetzt läuft alles.
Ich habe mit Dämpfungswiderständen die Eingänge auf Masse/LOW gezogen und über die Taster +5V als Signal geschaltet. Scheinbar ist das aber falsch gewesen.
Ich habe jetzt ein dauer HIGH auf den Eingängen und mein Tastendruck ein LOW, jetzt klappt auch alles wie gewünscht.
Ich bin dir echt sehr dankbar.
Werde morgen noch mal probieren den Code besser zu verstehen und anfegen meine Erweiterungen dort mit anzuheften , wie in den ersten versuchen ja schon gesehen.
Wenn du INPUT_PULLUP benutzt, brauchst du keine externen Widerstände und solltest auch keine haben.
Schließen nach GND und gut ist.
Bei Verwendung von Bounce2 ist dann ein Drücken der Taste ein MeinTaste.fell().
Das Angenehme an der Library ist ja nicht nur das Debouncen, sondern auch die State-Change-Detection,
also ob eine Taste gedrückt wurde und nicht ob sie gedrückt ist (was man natürlich auch auswerten kann).
Danke, in meinem Buch habe ich nichts zu Bounche2 gefunden. Im Netz auch keine deutsche Anleitung. Mal sehen ob ich noch was brauchbares finde.
Ich habe wohl völlig falsch gedacht und zu sehr an meinen alten Grundkonzept festgehalten.
Aber die Funktion, wie du es jetzt für mich umgesetzt hast, finde ich sehr interessant.
Der obige Kode testet immer nur die relevanten Tasten, eigentlich sehr gradlinig.
Die Routine die testet ob sich an einer Taste etwas getan hat MeineTaste.update() wird zusätzlich
als Filter benutzt, da uns ja hier nur die Übergänge, also das Drücken und das Loslassen interessieren.
Die Dokumentation steht hier Home · thomasfredericks/Bounce2 Wiki · GitHub.
Ich bins noch mal,
Ich habe heute probiert das ganze zu erweitern. Habe mir mal die <bounche2.h> vorlage genommen, aber irgendwie will das nicht. Die ist vom Code her anders, als du genutzt hast.
Wenn Taste "BlitzTakt" betätigt und nicht "EndschalterRechts" soll der Motor einen Impuls bekommen.
Das ganze dann noch verzögert, je nach Analogwert von A1, aber das habe ich noch nicht eingebaut.
In meinem ersten Code lief das schon, aber da will ich erst später ran, erst mal das Bounche2 verstehen.
Ich hätte gedacht. ich habe die Vorlage verstanden :(
#include <Bounce2.h>
int PotiPin=1; //Analog
int valAnalog=0; //Analog
int PotiZeit5=0; //Analog
int PotiZeit10=0; //Analog
int PotiZeit=0;
int Fakt5=11; // Zeitfaktor 5
int Fakt5Wert=0; // Zeitfaktor Merker
// int pinBlitzTakt = 9; // BlitzTakt eingabe
int pinRichtung = 5; // Endschalter
int Richtung=0;
// int pinEndschalterRechts = 3; // Endschalter
const byte pinGrundstellung = 12; //Grundstellungstaste
const byte pinEndschalterLinks = 4; // Endschalter Links
const byte pinEndschalterRechts = 3; // Endschalter Rechts
const byte pinMotor = 8; // Motor
const byte pinBlitzTakt = 9; // BlitzTakt
const unsigned int MotorPulseLen = 2000;
const unsigned int langeGedrueckt = 2500;
Bounce Grundstellung, EndschalterLinks;
Bounce EndschalterRechts;
Bounce BlitzTakt;
bool motorState;
unsigned long gedrueckt;;
void setup() {
pinMode(pinMotor, OUTPUT);
pinMode(pinBlitzTakt, INPUT_PULLUP);
pinMode(pinEndschalterLinks, INPUT_PULLUP);
BlitzTakt.attach(pinBlitzTakt);
EndschalterRechts.attach(pinEndschalterRechts);
BlitzTakt.interval(5);
EndschalterRechts.interval(5);
Grundstellung.attach(pinGrundstellung, INPUT_PULLUP);
EndschalterLinks.attach(pinEndschalterLinks, INPUT_PULLUP);
pinMode(Richtung, OUTPUT);
Fakt5Wert=digitalRead(Fakt5);
}
void loop() {
BlitzTakt.update();
EndschalterRechts.update();
int value1 = BlitzTakt.read();
int value2 = EndschalterRechts.read();
if ( value1== LOW && value2 == HIGH) {
digitalWrite(pinMotor, HIGH );
delay(2);
digitalWrite(pinMotor, LOW );
}
else {
digitalWrite(pinMotor, LOW );
}
static unsigned long lastBlink;
static unsigned long lastPulse;
if (motorState) {
if (EndschalterLinks.update() && EndschalterLinks.fell()) {
motorState = false;
} else if (Grundstellung.update() && Grundstellung.rose()) {
if (millis() - gedrueckt < langeGedrueckt) {
motorState = false;
}
}
if (!motorState) {
digitalWrite(pinMotor, LOW);
}
} else {
if (Grundstellung.update() && Grundstellung.fell()) {
motorState = true;
gedrueckt = millis();
lastPulse = micros();
lastBlink = millis();
(EndschalterLinks.update() && EndschalterLinks.fell());
digitalWrite(pinRichtung, LOW);
digitalWrite(pinMotor, HIGH);
}
}
if (motorState) {
if (micros() - lastPulse >= MotorPulseLen) {
lastPulse += MotorPulseLen;
digitalWrite(pinMotor, !digitalRead(pinMotor));
}
}
}
Ich versuche mal zusammenzufassen:
Du hast einen Motor mit zwei Endanschlägen, einem Richtungs- und einem Impulseingang.
4 ms lange HIGH/LOW Zyklen bewegen den Motor und der kann 250 Schritte/s aus dem Stand leisten.
Es gibt mehrere Konfigurationsschalter und ein? Poti die eine Zeiteinstellung kontrollieren.
Es gibt mehrere Bedientaster.
Der Flanken-gesteuerte Impulseingang löst eine verzögerte Sequenz aus.
Der Motor kann kontinuierlich, für eine Anzahl von Schritten und u.U. verzögert gestartet werden.
Ich denke du solltest zunächst einmal vollständig zusammenfassen was du wirklich willst,
oder ob ich etwas missverstanden habe, also was genau wann passieren soll.
Was soll die verzögerte Sequenz genau machen?
Welche Tasten sollen unter welchen Umständen was auslösen?
Mit dem Dazustricken und Erweitern wird das nichts.
Leg mal die Karten auf den Tisch.
Okay, ich hätte gedacht ist ist einfacher und ich brauche nur bei einem Abschnitt Hilfe und den Rest selber ran zu basteln. Dem scheint aber nicht so.
Also ich habe:
1 Schrittmotor inkl Steurboard. (Negative Flanke ein Schritt, Rechst/Links, Halb/Vollschritt über Masse gesteuert)
2 Endlagenschalter
1 Grundstellungstaster
1 Impulseingang ( Kontakt ) von Fotoapparat
1 Poti zur Zeiteinstellung
1 Taster für Halb/Vollschritt
Ich bekomme vom Fotoapparat einen Impuls,
dann soll nach PotiZeit ca. 1-10 sek ( muss nicht präzise sein ) ein Puls an den Schrittmotor geschickt werden. Der ist abhängig vom Halb/Vollschritt Taster. Wenn alles am ende angekommen ist (EndlageLinks) bleibt es stehen.
Durch kurzem Druck auf Grundstellung läuft der Motor kurz zurück. Nach längerem Druck, läuft er bis zum EndlageschalterRechts zurück.
Ich hoffe ich habe nichts vergessen.
Das Ganze habe ich schon mal mit Timer ( NE555 ) und vielen Transistoren .... umgesetzt, wollte es jetzt aber gern auf nem Arduino haben.
AtomicIX:
Ich bekomme vom Fotoapparat einen Impuls,
dann soll nach PotiZeit ca. 1-10 sek ( muss nicht präzise sein ) ein Puls an den Schrittmotor geschickt werden. Der ist abhängig vom Halb/Vollschritt Taster. Wenn alles am ende angekommen ist (EndlageLinks) bleibt es stehen.
Ein einstellbarer Puls, der bis zum Ende reicht? Merkwürdig...
Im anderen Modus schickst du fünf Sekunden lang 250 Pulse pro Sekunde.
Es kommt von Fotoapparat ein Impuls, der soll verzögert (Poti ) an den Schrittmotor gegeben werden. Ja nur ein ( Halb/Vollschritt) , die Impulse wiederholen sich immer wieder, gesteuert von der Kamera. das andere ist nur der Rücklauf, da brauche ich halt die Impulse um den Motor / Schlitten wieder in Grundstellung zu Fahren.
Also auf ein Neues.
Ich habe ein paar Motor Funktionalitäten in Routinen gepackt,
damit wird es einfacher zu lesen und zu managen.
Das Blitz-Delay habe ich mal willkürlich auf 5 Sekunden gesetzt.
#include <Bounce2.h>
int valAnalog;
int PotiZeit5;
int PotiZeit10;
int PotiZeit;
int Fakt5Wert;
const byte pinFaktor5 = 11; // Zeitfaktor 5
const byte pinRichtung = 5;
const byte pinPoti = A1;
const byte pinGrundstellung = 12; // Grundstellungstaste
const byte pinEndschalterLinks = 4; // Endschalter Links
const byte pinEndschalterRechts = 3; // Endschalter Rechts
const byte pinMotor = 8; // Motor
const byte pinBlitzTakt = 9; // BlitzTakt
const unsigned int MotorPulseLen = 2000; // µs
const unsigned int langeGedrueckt = 2500; // ms
Bounce Grundstellung;
Bounce EndschalterLinks;
Bounce EndschalterRechts;
Bounce BlitzTakt;
bool motorState;
byte Richtung;
int halfPulses;
unsigned long lastPulse;
unsigned long beauftragt;
unsigned long genugGewartet;
unsigned long grundstellungGedrueckt;
void setup() {
pinMode(pinMotor, OUTPUT);
pinMode(pinRichtung, OUTPUT);
BlitzTakt.attach(pinBlitzTakt, INPUT_PULLUP);
EndschalterRechts.attach(pinEndschalterRechts, INPUT_PULLUP);
Grundstellung.attach(pinGrundstellung, INPUT_PULLUP);
EndschalterLinks.attach(pinEndschalterLinks, INPUT_PULLUP);
Fakt5Wert = digitalRead(pinFaktor5);
}
void motorOn(byte iRichtung, unsigned int forPulses = 0, unsigned long inMillis = 0) {
Richtung = iRichtung;
digitalWrite(pinRichtung, Richtung);
halfPulses = 2 * forPulses;
genugGewartet = inMillis;
if (inMillis) {
beauftragt = millis();
} else {
motorStart();
}
}
void motorStart() {
motorState = true;
lastPulse = micros();
digitalWrite(pinMotor, HIGH);
}
void motorOff() {
digitalWrite(pinMotor, LOW);
halfPulses = 0;
motorState = false;
genugGewartet = 0;
}
void loop() {
if (motorState) {
EndschalterRechts.update();
EndschalterLinks.update();
if ((!EndschalterLinks.read() && !Richtung) ||
(!EndschalterRechts.read() && Richtung)) {
motorOff();
}
if (Grundstellung.update() && Grundstellung.rose()) {
if (millis() - grundstellungGedrueckt < langeGedrueckt) {
motorOff();
}
}
} else {
if (BlitzTakt.update() && BlitzTakt.fell()) {
motorOn(HIGH, 1, 5000);
} else if (Grundstellung.update() && Grundstellung.fell()) {
grundstellungGedrueckt = millis();
motorOn(LOW);
} else if (genugGewartet && (millis() - beauftragt >= genugGewartet)) {
genugGewartet = 0;
motorStart();
}
}
if (motorState) {
if (micros() - lastPulse >= MotorPulseLen) {
lastPulse += MotorPulseLen;
digitalWrite(pinMotor, !digitalRead(pinMotor));
if (halfPulses && --halfPulses == 0) {
motorOff();
}
}
}
}
Super vielen dank bis hier schon mal.
Soweit läuft es. Das Poti habe ich jetzt auch eingebaut und es geht wie gewünscht.
Kann man das so machen, oder ist das doof?
Was nicht geht ist der "EndschalterRechts". Wenn ein neuer "BlitzTakt" kommt, geht der Motor immer einen Schritt weiter, das darf auf keinen Fall passieren.
Wobei das beim "EndschalterLinks" auch passiert. Wenn die Endlage(Grundgstellung) erreicht ist und ich immer wieder Grundgstellung drücke, kommt ein Takt durch, was auf der Seite nicht schlimm ist, aber für die Linke Seite.
Das hat bestimmt was mit der Reihenfolge der Abarbeitung des Programm zutun, oder?
#include <Bounce2.h>
int PotiWert=0;
const byte pinRichtung = 5;
const byte pinPoti = A1;
const byte pinGrundstellung = 12; // Grundstellungstaste
const byte pinEndschalterLinks = 4; // Endschalter Links
const byte pinEndschalterRechts = 3; // Endschalter Rechts
const byte pinMotor = 8; // Motor
const byte pinBlitzTakt = 9; // BlitzTakt
const unsigned int MotorPulseLen = 2000; // µs
const unsigned int langeGedrueckt = 2500; // ms
Bounce Grundstellung;
Bounce EndschalterLinks;
Bounce EndschalterRechts;
Bounce BlitzTakt;
bool motorState;
byte Richtung;
int halfPulses;
unsigned long lastPulse;
unsigned long beauftragt;
unsigned long genugGewartet;
unsigned long grundstellungGedrueckt;
void setup() {
pinMode(pinMotor, OUTPUT);
pinMode(pinRichtung, OUTPUT);
BlitzTakt.attach(pinBlitzTakt, INPUT_PULLUP);
EndschalterRechts.attach(pinEndschalterRechts, INPUT_PULLUP);
Grundstellung.attach(pinGrundstellung, INPUT_PULLUP);
EndschalterLinks.attach(pinEndschalterLinks, INPUT_PULLUP);
}
void motorOn(byte iRichtung, unsigned int forPulses = 0, unsigned long inMillis = 0) {
Richtung = iRichtung;
digitalWrite(pinRichtung, Richtung);
halfPulses = 2 * forPulses;
genugGewartet = inMillis;
if (inMillis) {
beauftragt = millis();
} else {
motorStart();
}
}
void motorStart() {
motorState = true;
lastPulse = micros();
digitalWrite(pinMotor, HIGH);
}
void motorOff() {
digitalWrite(pinMotor, LOW);
halfPulses = 0;
motorState = false;
genugGewartet = 0;
}
void loop() {
if (motorState) {
EndschalterRechts.update();
EndschalterLinks.update();
if ((!EndschalterLinks.read() && !Richtung) ||
(!EndschalterRechts.read() && Richtung)) {
motorOff();
}
if (Grundstellung.update() && Grundstellung.rose()) {
if (millis() - grundstellungGedrueckt < langeGedrueckt) {
motorOff();
}
}
} else {
if (BlitzTakt.update() && BlitzTakt.fell()){
PotiWert = analogRead(pinPoti);
motorOn(HIGH, 1, (PotiWert*8));
} else if (Grundstellung.update() && Grundstellung.fell()) {
grundstellungGedrueckt = millis();
motorOn(LOW);
} else if (genugGewartet && (millis() - beauftragt >= genugGewartet)) {
genugGewartet = 0;
motorStart();
}
}
if (motorState) {
if (micros() - lastPulse >= MotorPulseLen) {
lastPulse += MotorPulseLen;
digitalWrite(pinMotor, !digitalRead(pinMotor));
if (halfPulses && --halfPulses == 0) {
motorOff();
}
}
}
}
Wenn du deinen Code in sinnvolle Fraktionen aufteilen würdest...
Klare Schnittstellen schaffen, zwischen den Bereichen.....
Einige einzelne, scharf abgegrenzte, endliche Automaten.
Dann könnte der Motorbereich BEVOR er einen Schritt tut, die Endschalter abfragen.
Und jetzt der Luxus: Per Rückgabewert könnte der Anwendung mitgeteilt werden, ob der Schritt erfolgreich durchgeführt werden konnte.
Wenn ich jetzt nicht die Endschalter verwechselt habe sollten alles gehen__*__.
#include <Bounce2.h>
const byte pinRichtung = 5;
const byte pinPoti = A1;
const byte pinGrundstellung = 12; // Grundstellungstaste
const byte pinEndschalterLinks = 4; // Endschalter Links
const byte pinEndschalterRechts = 3; // Endschalter Rechts
const byte pinMotor = 8; // Motor
const byte pinBlitzTakt = 9; // BlitzTakt
const unsigned int MotorPulseLen = 2000; // µs
const unsigned int langeGedrueckt = 2500; // ms
Bounce Grundstellung;
Bounce EndschalterLinks;
Bounce EndschalterRechts;
Bounce BlitzTakt;
bool motorState;
byte Richtung;
int halfPulses;
unsigned long lastPulse;
unsigned long beauftragt;
unsigned long genugGewartet;
unsigned long grundstellungGedrueckt;
void setup() {
pinMode(pinMotor, OUTPUT);
pinMode(pinRichtung, OUTPUT);
BlitzTakt.attach(pinBlitzTakt, INPUT_PULLUP);
EndschalterRechts.attach(pinEndschalterRechts, INPUT_PULLUP);
Grundstellung.attach(pinGrundstellung, INPUT_PULLUP);
EndschalterLinks.attach(pinEndschalterLinks, INPUT_PULLUP);
}
void motorOn(byte iRichtung, unsigned int forPulses = 0, unsigned long inMillis = 0) {
Richtung = iRichtung;
digitalWrite(pinRichtung, Richtung);
halfPulses = 2 * forPulses;
genugGewartet = inMillis;
if (inMillis) {
beauftragt = millis();
} else {
motorStart();
}
}
void motorStart() {
motorState = true;
lastPulse = micros();
digitalWrite(pinMotor, HIGH);
}
void motorOff() {
digitalWrite(pinMotor, LOW);
halfPulses = 0;
motorState = false;
genugGewartet = 0;
}
void loop() {
EndschalterRechts.update();
EndschalterLinks.update();
if (motorState) {
if ((!EndschalterLinks.read() && !Richtung) ||
(!EndschalterRechts.read() && Richtung)) {
motorOff();
}
if (Grundstellung.update() && Grundstellung.rose()) {
if (millis() - grundstellungGedrueckt < langeGedrueckt) {
motorOff();
}
}
} else {
if (EndschalterLinks.read() && BlitzTakt.update() && BlitzTakt.fell()) {
int PotiWert = analogRead(pinPoti);
motorOn(HIGH, 1, PotiWert * 8);
} else if (EndschalterRechts.read() && Grundstellung.update() && Grundstellung.fell()) {
grundstellungGedrueckt = millis();
motorOn(LOW);
} else if (genugGewartet && (millis() - beauftragt >= genugGewartet)) {
genugGewartet = 0;
motorStart();
}
}
if (motorState) {
if (micros() - lastPulse >= MotorPulseLen) {
lastPulse += MotorPulseLen;
digitalWrite(pinMotor, !digitalRead(pinMotor));
if (halfPulses && --halfPulses == 0) {
motorOff();
}
}
}
}
* Und das war natürlich der Fall. Man muss immer alles testen.
#include <Bounce2.h>
const byte pinRichtung = 5;
const byte pinPoti = A1;
const byte pinGrundstellung = 12; // Grundstellungstaste
const byte pinEndschalterLinks = 4; // Endschalter Links
const byte pinEndschalterRechts = 3; // Endschalter Rechts
const byte pinMotor = 8; // Motor
const byte pinBlitzTakt = 9; // BlitzTakt
const unsigned int MotorPulseLen = 2000; // µs
const unsigned int langeGedrueckt = 2500; // ms
Bounce Grundstellung;
Bounce EndschalterLinks;
Bounce EndschalterRechts;
Bounce BlitzTakt;
bool motorState;
byte Richtung;
int halfPulses;
unsigned long lastPulse;
unsigned long beauftragt;
unsigned long genugGewartet;
unsigned long grundstellungGedrueckt;
void setup() {
pinMode(pinMotor, OUTPUT);
pinMode(pinRichtung, OUTPUT);
BlitzTakt.attach(pinBlitzTakt, INPUT_PULLUP);
EndschalterRechts.attach(pinEndschalterRechts, INPUT_PULLUP);
Grundstellung.attach(pinGrundstellung, INPUT_PULLUP);
EndschalterLinks.attach(pinEndschalterLinks, INPUT_PULLUP);
}
void motorOn(byte iRichtung, unsigned int forPulses = 0, unsigned long inMillis = 0) {
Richtung = iRichtung;
digitalWrite(pinRichtung, Richtung);
halfPulses = 2 * forPulses;
genugGewartet = inMillis;
if (inMillis) {
beauftragt = millis();
} else {
motorStart();
}
}
void motorStart() {
motorState = true;
lastPulse = micros();
digitalWrite(pinMotor, HIGH);
}
void motorOff() {
digitalWrite(pinMotor, LOW);
halfPulses = 0;
motorState = false;
genugGewartet = 0;
}
void loop() {
EndschalterRechts.update();
EndschalterLinks.update();
if (motorState) {
if ((!EndschalterLinks.read() && !Richtung) ||
(!EndschalterRechts.read() && Richtung)) {
motorOff();
}
if (Grundstellung.update() && Grundstellung.rose()) {
if (millis() - grundstellungGedrueckt < langeGedrueckt) {
motorOff();
}
}
} else {
if (EndschalterRechts.read() && BlitzTakt.update() && BlitzTakt.fell()) {
int PotiWert = analogRead(pinPoti);
motorOn(HIGH, 1, PotiWert * 8);
} else if (EndschalterLinks.read() && Grundstellung.update() && Grundstellung.fell()) {
grundstellungGedrueckt = millis();
motorOn(LOW);
} else if (genugGewartet && (millis() - beauftragt >= genugGewartet)) {
genugGewartet = 0;
motorStart();
}
}
if (motorState) {
if (micros() - lastPulse >= MotorPulseLen) {
lastPulse += MotorPulseLen;
digitalWrite(pinMotor, !digitalRead(pinMotor));
if (halfPulses && --halfPulses == 0) {
motorOff();
}
}
}
}
Super vielen dank. So läuft es ![]()
Jetzt noch mal eine frage, die mir eben noch gekommen ist.
Ist es möglich den "ein Schritt" ausgelöst vom Blitztakt auch zu vervielfältigen?
Habe da an eine Poti Stellung in 3-4 Stufen gedacht oder über ein Register zB durch Tastendruck,
So das nach der Pause "PotiZeit" anstatt 1 Schritt, dann halt 2,3 oder 4 Schritte kommen?
Mein erster Gedanke war da sowas, aber ich denke da bestimmt wieder völlig kompliziert, oder programmiertechnisch nicht korrekt ?
Hier nur ein Auszug vom Code, aber denke das Prinzip ist klar? Gehen tut es jedenfalls
} else {
if (EndschalterRechts.read() && BlitzTakt.update() && BlitzTakt.fell()) {
int PotiWertW = analogRead(pinPotiW);
int PotiWertT = analogRead(pinPotiT);
motorOn(HIGH, PotiWertT/256+1, PotiWertW * 8);
} else if (EndschalterLinks.read() && Grundstellung.update() && Grundstellung.fell()) {
grundstellungGedrueckt = millis();
motorOn(LOW);
} else if (genugGewartet && (millis() - beauftragt >= genugGewartet)) {
genugGewartet = 0;
motorStart();
}
}
Es wurde so konstruiert, dass eine Anzahl von Halbwellen verzögert ausgelöst wird,
die Anzahl von Impulsen sollte egal sein, solange die fertig sind, bevor der nächste Takt kommt.
Danke, dann lasse ich das so.
Dann werde ich Mal die Hardware fertig stellen.