Hab es rausbekommen. Liegt an dem Variablentyp Byte. Der kann ja nur psitive Zahlen. Wenn ich da eine negative Zahl eingebe, ist der Startwert = 255. Gebe ich da 0 ein Startet er bei 1. Muss dann aber auch null runteregeln bevor ich den Wertebereich 0 bis 23 nutzen kann.
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //Hier wäre Es übersichtlicher, wenn man den
//Zahlen sprechende Namen geben würde, um ein
//Anpassen an andere Pins einfacher zu gestallten
int messungPin1 = HIGH;
int messungPin1Alt = HIGH;
byte encoderWert = 0; // -1 ( eins weniger als 0 ) == 255
//int encoderWertA = encoderWert % 24; // 255 % 24 =15 //Wird im Sketch nicht benutzt - wohl nicht angemeckert, da eine Zuweisung stattfindet
const byte encoderPinA = 10; //Phase A vom Drehencoder
const byte encoderPinB = 11; //Phase B vom Drehencoder
const byte tasterEnter = 12; // Pin an dem der Encoder Taster angeschlossen ist
int wertSpeichern = 0; // gespeicherter Encoderwert
byte encoderGedrueckt = 0; // Statusspeicher ob Encodertaster betätigt wurde
byte encoderTaster = HIGH; // Taster im Encoder
unsigned long encoderDruckzeit; // Zeit wann der Encodertaster betätigt wurde
unsigned long entprellZeit = 200; // Zeit die nach der betätigung eines Tasters gewartet wird
void setup() {
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
pinMode(tasterEnter, INPUT);
Serial.begin(9600);
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Encoder");
lcd.setCursor(0, 1);
lcd.print("Test");
delay (2000);
lcd.clear();
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Wert");
lcd.setCursor(0, 1);
lcd.print(encoderWert);
}
void loop() {
messungPin1 = digitalRead(encoderPinA);
if ((messungPin1 == LOW) && (messungPin1Alt == HIGH)) {
if (digitalRead(encoderPinB) == HIGH) {
if (encoderWert < 23) encoderWert++ ;
} else {
if (encoderWert > 0) encoderWert-- ;
}
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Wert");
lcd.setCursor(0, 1);
lcd.print(encoderWert);
}
{ // <-- ???
encoderTaster = digitalRead(tasterEnter);
if (encoderTaster == LOW)
{
encoderDruckzeit = millis();
encoderGedrueckt = 1;
}
if ((millis() - encoderDruckzeit > entprellZeit) && encoderGedrueckt == 1) {
wertSpeichern = encoderWert;
Serial.println(wertSpeichern);
encoderGedrueckt = 0;
}
} // <-- ???
messungPin1Alt = messungPin1;
}
Compiliert ohne Wqarnungen.
Ich habe mir gestattet, die Pins außerhalb einzustellen und im Code die 'magic numbers' durch sprechende Namen zu ersetzen.
Da sich die Pinzuweisungen wohl während der Laufzeit nicht mehr ändern, sind Diese als const deklariert - der Compiler kann Diese somit fest im Code verbauen - wenn Er mag.
Entfernen unnötiger Leerzeilen und ein STRG+T brachten bessere Lesbarkeit.
Woher hast Du die Klammerung innerhalb loop()? Von mir mit // <-- ?? gekennzeichnet?
Diese Klammerung sollte - überhaupt Nichts - bewirken (lasse mich Da gerne korrigieren)
Ich bin schon ein Schritt weiter. Ich möchte mit dem Encoder Positionen einstellen können die ein Motor zurücklegen (Stepps) muss. Das mit der Berechnung funktioniert schon ganz gut. Nur wie mache ich das, das die Schritte mit einem Hallsensor mittels Magnet am Zahnrad.vergleicht und wenn die Schritte zurückgelegt wurden der Motor abschaltet?
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int messungPin1 = HIGH;
int messungPin1Alt = HIGH;
byte encoderWert = 0; // -1 ( eins weniger als 0 ) == 255
const byte encoderPinA = 10; // Phase A vom Drehencoder
const byte encoderPinB = 11; // Phase B vom Drehencoder
const byte tasterEnter = 12; // Pin an dem der Encoder Taster angeschlossen ist
int wertSpeichern = 0; // gespeicherter Encoderwert
int encoderGedrueckt = 0; // Statusspeicher ob Encodertaster betätigt wurde
int encoderTaster = HIGH; // Taster im Encoder
int gleisAlt = 0; // Scheibe Position alt
int gleisNeu = 0; // Position welche die Scheibe anfahren soll
bool enter = false; // Bestätigung das der Encoder gedrückt wurde
int schritte =0; // Schritte die deer Motor (Hallsensor betätigt) zurücklegen muss
unsigned long encoderDruckzeit; // Zeit wann der Encodertaster betätigt wurde
unsigned long entprellZeit = 200; // Zeit die nach der betätigung eines Tasters gewartet wird
void setup() {
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
pinMode(tasterEnter, INPUT);
Serial.begin(9600);
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Encoder");
lcd.setCursor(0, 1);
lcd.print("Test");
delay (2000);
lcd.clear();
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Wert");
lcd.setCursor(0, 1);
lcd.print(encoderWert);
}
void loop() {
messungPin1 = digitalRead(encoderPinA);
if ((messungPin1 == LOW) && (messungPin1Alt == HIGH)) {
if (digitalRead(encoderPinB) == HIGH) {
if (encoderWert < 24) encoderWert++ ;
} else {
if (encoderWert > 1) encoderWert-- ;
}
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Wert");
lcd.setCursor(0, 1);
lcd.print(encoderWert);
}
{
encoderTaster = digitalRead(tasterEnter);
if (encoderTaster == LOW)
{
encoderDruckzeit = millis();
encoderGedrueckt = 1;
}
if ((millis() - encoderDruckzeit > entprellZeit) && encoderGedrueckt ==1) {
wertSpeichern = encoderWert;
Serial.println(wertSpeichern);
encoderGedrueckt=0;
enter = true;
}
if (enter == true) {
gleisNeu = wertSpeichern;
schritte = gleisNeu - gleisAlt;
Serial.print ("benoetigte Schritte ");
Serial.println(schritte);
gleisAlt = wertSpeichern;
enter = false;
}
//if ((schritte >12)&& (enter== true)) {
// Serial.println("rechts");
//enter = false;
}
// else {
// Serial.println("links");
//enter = false;
//}
//}
messungPin1Alt = messungPin1;
}
DC Motor , Schrittmotor , eine Richtung , zwei Richtungen, wie schnell dreht das Zahnrad, Welche Übersetztung mit Bezug auf die Motorwelle ? Willst du wirklich nur so viel Zähne fahren we Du mit den Werten des Encoders vorgibst ( 0-23)
Jetzt mal ganz grob
Bei einem Schrittmotor macht der Hallsensor keinen Sinn. Bei DC Motor must du halt die Impulse des Hallsensors beim fahren zählen, mit deinem Sollwert vergleichen und dann abschalten. Mit einem DC Motor kannst Du keine kleinen Winkelschritte fahren.
Mit nur einem Hallsensor am Zahnrad weist Du nicht wie die Richtung ist. Dann must Du Dir die aktuelle Position aus den gefahren Impulsen bilden und in einer Variablen abspeichern. Aus der Differenz zwischen neuem Sollwert und Istwert die Richtung bestimmen und abhängig davon den Istwert hoch oder runter zählen. Probleme bekommst Du damit beim starten nach Power on , da Du nicht weist wo du stehst. Ein " Refferenzfahren " währe dazu die Lösung.
Ich danke dir. Also es wird ein DC Motor über Motortreiber angesteuert. Die Bühne wird über ein großes Zahnrad angetrieben. Dieses Zahnrad besitzt 3 Kerben wo bei erreichen ein Stift einrastet. Dieser Stift wird Bei Start zurückgesogen und gibt das Zahnrad frei. Nach ablauf der Schritte, soll der Stift wieder in die entsprechende Kerbe einrasten. Der Weg den die Bühne zurückgelegt hat, wird über den Hallsensor ermittelt. An jeder Kerbe ist ein Magnet angebracht. Jede Kerbe bedeudet einen Gleisabgang. Ich hoffe ich konnte es einigermasen verständlich erklären. Der Start ab Gleis 1 wird immer bei Poweron über eine Referenzfahrt festgelegt.
Ein Zahnrad welches in einem Getriebe eingebaut ist, besitzt einen drei Magneten an unteschiedlichen Stellen. Über den Encoder wähle ich aus welche position das Zahnrad nach betätigung des Encoder Tasters einehmen soll. Über den Hallsensor werden die Schritte gezählt wie oft der Magnet schon am Sensor vorbeikommen ist. Solange die Schritte noch nicht abgelaufen sind, Bekommt der Motor Strom. Wenn die Schritte dann null sind, wird der Motor abgeschalten. Der Motor ist noch nicht im Code eingebaut.
Ich hoffe ich habe etwas Licht ins dunkle gebracht.
in der IDE Hilfe //Referenz da findest Du den grundsätzlichen Syntax zu den einzelnen Funktionen auch mit Beispielen. Es geht um eine Sprache da gibts feste Regeln, leider ist C da besonders streng.
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int messungPin1 = HIGH;
int messungPin1Alt = HIGH;
byte encoderWert = 0; // -1 ( eins weniger als 0 ) == 255
const byte hal = 3;
const byte encoderPinA = 10; // Phase A vom Drehencoder
const byte encoderPinB = 11; // Phase B vom Drehencoder
const byte tasterEnter = 12; // Pin an dem der Encoder Taster angeschlossen ist
int wertSpeichern = 0; // gespeicherter Encoderwert
int encoderGedrueckt = 0; // Statusspeicher ob Encodertaster betätigt wurde
int encoderTaster = HIGH; // Taster im Encoder
int gleisAlt = 0; // Scheibe Position alt
int gleisNeu = 0; // Position welche die Scheibe anfahren soll
bool enter = false; // Bestätigung das der Encoder gedrückt wurde
int schritte = 0; // Schritte die deer Motor (Hallsensor betätigt) zurücklegen muss
unsigned long encoderDruckzeit; // Zeit wann der Encodertaster betätigt wurde
unsigned long entprellZeit = 200; // Zeit die nach der betätigung eines Tasters gewartet wird
void setup() {
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
pinMode(tasterEnter, INPUT);
pinMode(hal, INPUT);
Serial.begin(9600);
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Encoder");
lcd.setCursor(0, 1);
lcd.print("Test");
delay (2000);
lcd.clear();
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Wert");
lcd.setCursor(0, 1);
lcd.print(encoderWert);
}
void loop() {
messungPin1 = digitalRead(encoderPinA);
if ((messungPin1 == LOW) && (messungPin1Alt == HIGH)) {
if (digitalRead(encoderPinB) == HIGH) {
if (encoderWert < 24) encoderWert++ ;
} else {
if (encoderWert > 1) encoderWert-- ;
}
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Wert");
lcd.setCursor(0, 1);
lcd.print(encoderWert);
}
{ //<-- WTF macht diese Klammer???
encoderTaster = digitalRead(tasterEnter);
if (encoderTaster == LOW)
{
encoderDruckzeit = millis();
encoderGedrueckt = 1;
}
if ((millis() - encoderDruckzeit > entprellZeit) && encoderGedrueckt == 1) {
wertSpeichern = encoderWert;
Serial.println(wertSpeichern);
encoderGedrueckt = 0;
enter = true;
}
if (enter == true) {
gleisNeu = wertSpeichern;
schritte = gleisNeu - gleisAlt;
Serial.print ("benoetigte Schritte ");
Serial.println(schritte);
Serial.println(gleisNeu);
Serial.println(gleisAlt);
Serial.println(enter);
}
if ((gleisNeu != gleisAlt) && (enter == true)) {
while (schritte != 0) {
if (digitalRead (hal) == LOW); {
schritte--;
Serial.println("Schritte");
Serial.println(schritte);
delay(2000); //ein Hall-Sensor prellt nicht und hier machst Du ganze 2 Sekunden NICHTS - mir ist bewusst, was Du hier willst
enter = false;
gleisAlt = wertSpeichern;
}
}
}
} // hier WTF-Klammer Nummer 2
messungPin1Alt = messungPin1;
} //DAS war Mal Zeile 128, jetzt 91 8-)
MfG
PS: Ggf., weil schritte ungleich Null ist?
PS²: Ggf. hilft Die hier die serielle Ausgabe weiter - wenn hier die benötigten Schritte <0 sind, hast Du bei Deiner Abfrage ein neues Problem
PPS: STRG+T und entfernen von unnötigen Leerzeilen ... ich wiederhole mich
Was für ein Problem meinst du. Wenn die Schritte 0 sind kann ich die nächste Position wählen und es werden die von der jetzigen Position bis zur neuen Position benötigten Schritte berechnet und ausgeführt.
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int messungPin1 = HIGH;
int messungPin1Alt = HIGH;
byte encoderWert = 0; // -1 ( eins weniger als 0 ) == 255
const byte hal = 3;
const byte encoderPinA = 10; // Phase A vom Drehencoder
const byte encoderPinB = 11; // Phase B vom Drehencoder
const byte tasterEnter = 12; // Pin an dem der Encoder Taster angeschlossen ist
int wertSpeichern = 0; // gespeicherter Encoderwert
int encoderGedrueckt = 0; // Statusspeicher ob Encodertaster betätigt wurde
int encoderTaster = HIGH; // Taster im Encoder
int gleisAlt = 0; // Scheibe Position alt
int gleisNeu = 0; // Position welche die Scheibe anfahren soll
bool enter = false; // Bestätigung das der Encoder gedrückt wurde
int schritte = 0; // Schritte die deer Motor (Hallsensor betätigt) zurücklegen muss
unsigned long encoderDruckzeit; // Zeit wann der Encodertaster betätigt wurde
unsigned long entprellZeit = 200; // Zeit die nach der betätigung eines Tasters gewartet wird
void setup() {
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
pinMode(tasterEnter, INPUT);
pinMode(hal, INPUT);
Serial.begin(9600);
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Encoder");
lcd.setCursor(0, 1);
lcd.print("Test");
delay (2000);
lcd.clear();
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Wert");
lcd.setCursor(0, 1);
lcd.print(encoderWert);
}
void loop() {
messungPin1 = digitalRead(encoderPinA);
if ((messungPin1 == LOW) && (messungPin1Alt == HIGH)) {
if (digitalRead(encoderPinB) == HIGH) {
if (encoderWert < 24) encoderWert++ ;
} else {
if (encoderWert > 1) encoderWert-- ;
}
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Wert");
lcd.setCursor(0, 1);
lcd.print(encoderWert);
}
encoderTaster = digitalRead(tasterEnter);
if (encoderTaster == LOW)
{
encoderDruckzeit = millis();
encoderGedrueckt = 1;
}
if ((millis() - encoderDruckzeit > entprellZeit) && encoderGedrueckt == 1) {
wertSpeichern = encoderWert;
Serial.println(wertSpeichern);
encoderGedrueckt = 0;
enter = true;
}
if (enter == true) {
gleisNeu = wertSpeichern;
schritte = gleisNeu - gleisAlt;
Serial.print ("benoetigte Schritte ");
Serial.println(schritte);
//gleisAlt = wertSpeichern;
Serial.println(gleisNeu);
Serial.println(gleisAlt);
Serial.println(enter);
}
if ((gleisNeu != gleisAlt) && (enter == true)) {
while (schritte != 0) {
if (digitalRead (hal) == LOW); {
schritte--;
Serial.println("Schritte");
Serial.println(schritte);
delay(2000);
enter = false;
gleisAlt = wertSpeichern;
}
}
}
//if ((schritte >12)&& (enter== true)) {
// Serial.println("rechts");
//enter = false;
// else {
// Serial.println("links");
//enter = false;
//}
//}
messungPin1Alt = messungPin1;
}
Die Abfrage des Hallsensors hat doch nichts mit dem While zu tun , richtig ist das die Abfrage des Hallsensors nur erfolgt wenn die while schleife erfüllt ist.
nochmals der Vorschlag zurück zu #19 u #21
was willst Du in der while schleife eigentlich machen , wenn der Sensor belegt ist runter zählen bis 0 , das jedesmal anzeigen und dazwischen 2s warten. ?