Hallo Ich will einen Drehencoder auswerten mit nur einem Interruptpin. zur anzeige werden 2 LEDs angesteuert. bei Linksdrehung leuchtet die eine bei rechtsdrehung die andere Mit setup ... attachInterrupt(0,ISR,RISING); ... loop ... void ISR() { detachInterrupt(0); if (digitalRead(4)==HIGH) { digitalWrite(22,HIGH); digitalWrite(23,LOW); } else { digitalWrite(23,HIGH); digitalWrite(22,LOW); } attachInterrupt(0,ISR,RISING); } } funzt es zwar aber mehr schlecht als recht. Die LEDs zittern mir zu viel sprich da sind false erkennungen dazwischen. Ich vermute es liegt an der digitalRead() Funktion weil die recht langsam ist. Also direkte Portmanioulation die IF bedingung ersetzt durch if (PIND & B0001000==B00010000) Beim Kompilieren keinen Fehler aber funzt nun garnicht mehr. zumindest leichtet egal welche richtung ich drehe nur die LED auf Pin 23 sprich die, wenn die Bedingung nicht erfüllt ist seht ihr vielleicht was da falsch bei mir ist? ist übrigens ein Arduino Mega
key-board schrieb: > seht ihr vielleicht was da falsch bei mir ist? Lass wenigstens mal die automatische Formatierung über deinen Code laufen. Dann sähe das schon viel übersichtlicher aus. key-board schrieb: > Ich vermute es liegt an der digitalRead() Funktion weil die > recht langsam ist. So langsam ist die nun auch wieder nicht - kommt natürlich etwas auf die Prozessortaktfrequenz und die Pulsfrequenz vom Inkrementalgeber drauf an. Und wenn dein Geber prellt, kannst du mit Interruptsteuerung viel "Freude" haben.
key-board schrieb: > seht ihr vielleicht was da falsch bei mir ist? Also erstens zind die Einrückungen eine Katastrophe, darum geht es jetzt aber nicht, und zweitens: key-board schrieb: > if (PIND & B0001000==B00010000) Das Gleiche nochmal mit einem Zeilenumbruch, fällt dir was auf?
1 | |
2 | if (PIND & B0001000== |
3 | B00010000) |
Das kann gar nicht gleich sein. Das ==B00010000 ist auch überflüssig, schreib einfach if(PIND & B0001000) oder noch besser if(PIND & (1<<3))
sorry hab in Zeile if (PIND & B0001000==B00010000) einen Tippfehler if (PIND & B00010000==B00010000) muss es heißen der fehler ist im code NICHT drin
key-board schrieb: > der fehler ist im code NICHT drin Warum zeigst du dann nicht deinen Code, sondern irgend etwas anderes?
key-board schrieb: > sorry hab in Zeile > if (PIND & B0001000==B00010000) > einen Tippfehler Womit wir schon beim nächsten Fehler sind: Quellcode nicht abtippen, copy 'n' paste oder als Anhang. Sieh dir das mal an: https://de.wikibooks.org/wiki/C-Programmierung:_Liste_der_Operatoren_nach_Priorit%C3%A4t '==' hat höhere Priorität als das '&', setzt PIND & B0001000 in Klammern oder lass das ==B00010000 ganz weg. Was sicher auch nicht schadet ist wenn du dir das entsprechende Kapitel im AVR-GCC-Tutorial anschaust: https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Eing.C3.A4nge_.28Wie_kommen_Signale_in_den_.C2.B5C.29
:
Bearbeitet durch User
ja das mit dem einrücken seh ich ein dass sieht in meiner software schöner aus. (ordentlich eingerückt) hab eure Nachichten erst gelesen als ich meine berichtigung abgeschikt habe. Wie gesagt der Tippfehler ist im Code nicht mit drin. @C-liker die Varianten if(PIND & (1<<5)) und (5 weil Input an Pin mit Nummer 4 PIND von 0 bis 7 und da ist das pin 4 das 5. bit.) if(PIND & B00010000) hab ich auch schon beide probiert. nix geht... wie gesagt nehme ich digitalRead(4) funzt das ganze. Um das Prellen wollte ich mich kümmern wenn das mit PIND auch kein zufrieden stellendes Ergebniss bringt, aber die leds sollten zumindest hin und her flackern wenn der encoder prellt. das tun sie bei digitalRead ja auch, aber es passiert ja nix... leuchtet nur stuhr die LED welche im else zweig gesetzt wird.
key-board schrieb: > if(PIND & (1<<5)) und (5 weil Input an Pin mit Nummer 4 PIND von 0 bis 7 > und da ist das pin 4 das 5. bit.) > if(PIND & B00010000) Das stimmt jetzt aber nicht zusammen; (1<<5) = B0010'0000 zum vergleich PIND & B0001'0000 Welchen Arduino hast du eigentlich?
void setup() { // put your setup code here, to run once: pinMode (4,INPUT); pinMode (3,INPUT); pinMode (2,INPUT); pinMode (22,OUTPUT); pinMode (23,OUTPUT); attachInterrupt(0,dir,RISING); attachInterrupt(1,off,RISING); } byte x=0; void loop() { // put your main code here, to run repeatedly: } void dir() { detachInterrupt(0); if((PIND & B0001000)) { digitalWrite(22,HIGH); digitalWrite(23,LOW); } else { digitalWrite(23,HIGH); digitalWrite(22,LOW); } attachInterrupt(0,dir,RISING); } void off() { digitalWrite(23,LOW); digitalWrite(22,LOW); } so hier der komplette code :) mit den letzten änderungsvorschlägen aber immer noch... nur LED auf Pin 23 leuchtet egal in welche Richtung ich drehe :(
Max H. schrieb: > Welchen Arduino hast du eigentlich? Sry, ich hab's überlesen, ist der "Arduino Mega"
boar jetzt hatte ich schonwieder den "tippfehler" drin da ich den vorschlag aus "'==' hat höhere Priorität als das '&', setzt PIND & B0001000 in Klammern oder lass das ==B00010000 ganz weg. " einfach übernommen hatte... aber auch berichtigt gehts nicht:( Exakt ist es der SainSmart MEGA 2560
Schau dir mal hier das Pin Mapping des MEGAs an: http://www.arduino.cc/en/Hacking/PinMapping2560 Pin 4 ist nicht mir PORTD bit 4 verbunden, du fragst den falschen IO ab. BTW: Für C (ähnlichen) Code bitte die Formatierung verwenden:
1 | [c]C-Code[/c] |
Damit ist der Code um einiges angenehmen zu lesen.
:
Bearbeitet durch User
müsste es nicht der PG5 sein? Pinnummer 1(auf dem Prozessor), Pinname PG5, MappedPinName Digital pin 4 (PWM) jedenfalls danke. das War der entscheidende Tipp :) mit
1 | if((PING & B00100000)) |
funktioniert es. hab diese Liste vorher nie gefunden. nach sowas in der art gesucht hab ich schon... naja jedenfalls danke auch für den Tipp wie ich code hervorheben kann
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.