Moin zusammen, ich bin schon ne Weile dabei mir eine 2in1 Lötstation zu bauen, die Hardware is fertig und soweit fehlerfrei, nur komme ich mit der Firmware nicht weiter. Hatte erst den Drehencoder ohne Library versucht auszulesen, was aber nicht geklappt hat, dann habe ich die Methode von educ8s, einem YouTuber, dessen Vorschläge immer perfekt funktionieren (Bei Interesse verlinke ich das Video) verwendet, das klappt auch, nur leider wird dabei die TimerOne Bibliothek verwendet und diese nutzt einen Interrupt, genau den Interrupt, an dem mein Summer hängt, den von Pin 9, dadurch funktioniert der Encoder nicht mehr sauber und der Summer ist extrem leise. Bis auf die analogen Pins 5, 6 und 7 sind alle vergeben, 3, 5 und 6 nutzt das PCD8544-Display, 10 und 11 schalten die Transistoren für Lötkolben und Heissluft-Lüfter. Meine Frage ist nun, ob ich einen der anderen Pins für den Interrupt nutzen kann, ohne, dass es Probleme gibt? Das könnte ich ja in der TimerOne Bibliothek verändern. Die Lösung wäre es den Drehencoder durch Tasten zu ersetzen, spricht nichts dagegen, aber wäre schon schöner den Encoder zu verwenden, daher dachte ich lieber nochmal hier zu fragen. Lieben Gruß, Willi PS: Ich hänge mal ein Bildchen dran, wie alle mögen Bilderchen :)
Wilson W. schrieb: > wie alle mögen Bilderchen :) Auf so verkleinerten Bildchen kann man eh nichts erkennen. Die Angabe bzw. die URL des MCs, der IDE und der Lib wären erheblich sinnvoller gewesen.
Wilson W. schrieb: > Ich hänge mal ein Bildchen dran, Das ist aber zur Beantwortung der Frage nicht hilfreich. Der Sourcecode würde deutlich sinnvoller sein. asderftttg
Aus deiner Beschreibung ist kaum zu erkennen, was du da hardware- und softwareseitig zusammengebastelt hast. Wenn du den Drehgeber nach althergebrachter Manier einliest, brauchst du - einen Timer, der in regelmäßigen Zeitabständen (in der Größenordnung 0,1ms bis 10ms) einen (internen) Interrupt auslöst und - zwei I/O-Pins, die sich als Input konfigurieren lassen (sie müssen nicht interruptfähig sein). Das sollte auf deinem Arduino-Board, das vermutlichen einen ATmega328 o.ä. enthält, überhaupt kein Problem sein, auch wenn da noch ein Display und ein paar andere Dinge angeschlossen sind.
Wilson W. schrieb: > wird dabei die TimerOne Bibliothek verwendet und diese nutzt einen > Interrupt, genau den Interrupt, an dem mein Summer hängt, den von Pin 9, > dadurch funktioniert der Encoder nicht mehr sauber und der Summer ist > extrem leise. Mir wäre der Encoder wichtiger als der Summer... BTW: es geht auch mit Summer und Encoder auf ein und dem selben Timerinterrupt. Da bin ich mir vollkommen sicher.
Hallo Wilson, komt darauf an, ob noch ein Interruptfähiger Pin frei ist. Was das größte Problem macht, ist das Prellen des Encoders. Kein Mechanischer Schalter geht prellfrei. Also Entweder gut mit Elektronik entprellen oder mit Software. Dahin sollte dein Weg dich führen... Aber wie schon oben genannt Ohne Schaltplan geht gar nichts. Gruß Thomas
Thomas schrieb: > komt darauf an, ob noch ein Interruptfähiger Pin frei ist. Wozu? Der Timer-Interrupt ist völlig ausreichend und benötigt keinen Pin nach außen. Lothar M. schrieb: > BTW: es geht auch mit Summer und Encoder auf ein und dem selben > Timerinterrupt. Da bin ich mir vollkommen sicher. Zudem hat der ATmega328 nicht nur einen, sondern gleich drei Timer, von denen jeder einzelne auch mehrere Funktionen erfüllen kann. Da sollte sich durch irgendeine Lösung finden lassen.
Wilson W. schrieb: > Die Lösung wäre es den Drehencoder durch Tasten zu ersetzen, Du musst überhaupt keine Pins mit Timer-Iterrupts belegen, ausser du willst einen Ton ausgeben für deinen Summer. Nimm einfach einen anderen Timer, ordne dem keinen Pin zu, und lass den per Interrupt jede Millisekunde void ClickEncoder::service(void) aufrufen, fertig. Der Arduino hat 3 Timer.
Lothar M. schrieb: > BTW: es geht auch mit Summer und Encoder auf ein und dem selben > Timerinterrupt. Da bin ich mir vollkommen sicher. logisch Ich hatte mir ja einen 10ms Timer per IRQ gebaut, als ich dann PeDas Drehencoder nutzen wollte war 10ms viel zu lang, ergo auf 1ms gesetzt und jedes mal bis 10 gezählt um wieder zu meinen 10ms zu kommen. Genauso kann man Franks (ukw) IR Auswertung machen, dort wird z.B 15000 Hz abgetastet, also 1/15000s Interrupt, zählt man dort bis 150 hat man wieder den 10ms Timer.
Hier zunächst der Link zur Bibliothek: https://github.com/PaulStoffregen/TimerOne?files=1 Ja, es ist ein minimierter ProMini Clone mit nem atmega328. Mein Sketch ist zur Zeit noch sehr chaotisch, wenn ich den poste fresst ihr mich, das garantiere ich xD Will das Projekt aber teilen, wenns fertig ist, zwar nicht mit Step-by-Step Bildern und Beschreibung, aber schon mit genügend Informationen, dass man es nachbauen kann, es soll dabei auch um Kreativität gehen und wie man aus vermeintlichem Müll was cooles bauen kann, bis auf den uC sind alle Teile auf der Platine aus alter Hardware geerntet hauptsächlich ne Drucker und nem ATX-Netzteil. Jedenfalls hier der originale Sketch von educ8s, darüber meine Pinbelegung, anders genutze klammere ich aus und passe die anderen entsprechend an: Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang Genau das ist das Problem, dass kein interruptfähiger Pin mehr frei ist und ich die Schaltung auch nicht mehr so verändern kann, dass einer frei wird. Mir ist der Summer schon wichtiger als der Encoder, weil ich diesen eben im Fall des Falles durch Taster ersetzen kann, weil ich auch Presets eingebaut habe, muss ich nicht ständig an irgendwas drehen, außer dem Poti für das Gebläse, auch habe ich eingebaut in welchen Schritten die Temperatur eingestellt werden soll. Einen Schaltplan habe ich nie gemacht, angefangen, aber nicht noch nicht zu Ende gemacht, nur entsprechende Berechnungen für den Op-Amp und ein Lochmaster Layout, welches aber im Laufe der Zeit stark abgeändert werden musste. Das mit den internen Interrupts ist doch die richtige Richtung, könnt ihr mich da noch ein bisschen mehr drüber aufklären? Die TimerOne Bibliothek nutzt den Timer1 - OCIE1A Interrupt, der auf Pin 9 liegt, das ist dann wohl ein externen, wie ändere ich den zu einem internen? Ist mein erstes Mal mit Interrupts ...außer früher bei den 2-, 386er PC's... -- Code entfernt und als Dateianhang angefügt -rufus
:
Bearbeitet durch User
Mhhh mir kommt da grad so ein Gedanke... hab ich die Bibliothek nicht richtig verstanden und man kann einfach Timer1.initialize(1000); und Timer1.attachInterrupt(timerIsr); einfach in Timer2 etc. ändern?
Wenn du die PWM Fähigkeit des Timer0 nicht brauchst, kannst du dort deinen Interrupt einhängen. Denn der Timer läuft auf dem Arduino sowieso schon. Du könntest also ISR(TIMER0_COMPA_vect) oder/und ISR(TIMER0_COMPB_vect) nutzen
Viel zu umständlich. Da der Drehgeber ja wohl als User-Interface verwendet wird stört es nicht, wenn der mal einen Impuls übersieht. Also einfach in der Main-Schleife pollen und fertig.
Wilson W. schrieb: > else if (page==2 && menuitem == 4) > { > displayStringMenuPage(menuItem4, difficulty[selectedDifficulty]); > } > else if (page==2 && menuitem == 4) > { > displayStringMenuPage(menuItem4, difficulty[selectedDifficulty]); > } Ich sags zweimal und dann ist es wahr? Da hast du wohl irgendwas doppelt kopiert :-P Und wofür ist denn eine 'difficulty' Einstellung in einer Lötstation? Für leichte und schwere Lötstellen?
Wilson W. schrieb: > Genau das ist das Problem, dass kein interruptfähiger Pin mehr frei ist > und ich die Schaltung auch nicht mehr so verändern kann, dass einer frei > wird. Ich sehe nicht, dass in dem geposteten Code ein externer (also ein an einen Pin gebundener) Interrupt verwendet wird. Der einzige verwendete Interrupt ist der interne Interrupt von Timer1. Insofern sollte es diesbezüglich zunächst keine Probleme geben. Du schriebst aber etwas von einem Summer, der ebenfalls von Timer1 gesteuert wird und deswegen im Konflikt zu dem Encode steht. Wie genau ist dieses Summen softwareseitig realisiert? Wilson W. schrieb: > Timer1.initialize(1000); und > Timer1.attachInterrupt(timerIsr); > > einfach in Timer2 etc. ändern? Wenn die Arduino-Bibliothek für Timer2 dieselben Funktionen (initialize und attachInterrupt) bietet, sollte das so funktionieren. Ansonsten solltest du den Vorschlag vom Arduino Fanboy ausprobieren. Guido Körber schrieb: > Da der Drehgeber ja wohl als User-Interface verwendet wird stört es > nicht, wenn der mal einen Impuls übersieht. Doch. Wird der Encoder wie hier für die Navigation in einem Auswahlmenü eingesetzt, hat ein übersehener Impuls eine ähnlich nervige Wirkung wie verlorengehende Tastendrücke auf einer Tastatur. > Also einfach in der Main-Schleife pollen und fertig. Wenn die Main-Schleife kurz genug ist, kann man das so machen. Mit einem Timer-Interrupt funktioniert der Encoder aber unabhängig davon, was in der Main-Schleife geschieht, weswegen das die zu bevorzugende Lösung ist.
Mhh ja, dann war wohl meine eigene Recherche für den Fehler ganz daneben, es geht eben darum, dass der Summer extrem leise geworden ist und der Encoder Aussetzer hat, wobei ich diesen ohne Summer garnicht ausprobiert habe mit der Lib, seit ich die TimeOne.h eingebunden habe. Der Summer wird so gesteuert:
1 | void beep(unsigned char delayms) { |
2 | analogWrite(buzzerPin, 20); // Any value except of 0 and 255 |
3 | delay(delayms); // wait for a delayms ms |
4 | analogWrite(9, 0); // 0 turns it off |
5 | delay(delayms); // wait for a delayms ms |
6 | }
|
7 | |
8 | // Und so abgerufen(der Begrüßungston aus dem Setup):
|
9 | beep(50); |
10 | beep(50); |
11 | beep(80); |
12 | delay(300); |
Denke so ein paar Delays machen in diesem Fall nichts aus, aber das ist wohl der Konflikt zwischen dem erwähnten Interrupt (OCIE1A) und den Delay, der das Problem auslöst, oder? Ich habe den Interrupt gegooglet und hab gelesen, dass das der Timer1 ist und dieser auf Pin 9 liegt, also da, wo mein Summer ist, deswgen bin ich davon ausgegangen, dass es kein interner Interrupt ist und das Problem auslöst. Den Vorschlag von Arduino Fanboy habe ich nachgeschlagen aber nicht herausfinden können wie ich das konkret umsetze, schlussendlich sollen halt die "up" und "down" bools erhalten bleiben, wenn ich auf eine Library verzichten kann ist umso besser, aber ich verstehe nicht wo ich diese Zeilen wie verwende. Ein Dankeschön zwischendurch :-)
Auf das Risiko hin, dass der ein oder andere nen Hals kriegt, hänge ich mal meinen Sketch dran, der ist halt noch im Aufbau und ich habe keine wirkliche Struktur beim Aufbau, bin halt noch Anfänger und baue es nicht Funktion für Funktion auf sondern springe hin und her, einiges funktioniert noch nicht richtig, das schaffe ich aber alleine zu lösen, nur eine Sache der Ordnung. Dass das Setup und der Loop erst am Ende auftauchen liegt daran, dass ich den Sketch mit der App ArduinoCode auf dem Handy baue und die meckert rum, wenn aufgerufene Funktionen erst nach den Aufruf auftauchen. Und Fotos von der Platine, falls es was bringt, denke eher nicht, der Triac für das Heizelement der Heissluft ist auf einer eigenen Platine.
:
Bearbeitet durch User
Hi, ehrlich gesagt würde ich für solche Zwecke heutzutage eher einen STM32F103 nehmen. Kost nix, die Abmessungen sind vergleichbar und das Ding kann extrem viel mehr. Unter anderem hat er Hardwareencoder für Drehgeber und außer bei der Initialisierung der Hardware hat man gar keine Mühe mehr damit. Auch damit kann man zwar bei günstigen Drehgebern ein Prellen feststellen, in den meisten Fällen stört das aber nicht und Werte lassen sich damit wunderbar in einem UI einstellen. Gruß, Oliver
Oliver R. schrieb: > Hi, > > ehrlich gesagt würde ich für solche Zwecke heutzutage eher einen > STM32F103 nehmen. Kost nix, die Abmessungen sind vergleichbar und das > Ding kann extrem viel mehr. > Unter anderem hat er Hardwareencoder für Drehgeber und außer bei der > Initialisierung der Hardware hat man gar keine Mühe mehr damit. > Auch damit kann man zwar bei günstigen Drehgebern ein Prellen > feststellen, in den meisten Fällen stört das aber nicht und Werte lassen > sich damit wunderbar in einem UI einstellen. > > Gruß, > Oliver Danke für den Tipp, aber das ist ein "very very low to zero budget"-Projekt und zu 99% fertig.
Wilson W. schrieb: > Hatte erst den Drehencoder ohne Library versucht > auszulesen, was aber nicht geklappt hat, dann habe ich die Methode von > educ8s, einem YouTuber, dessen Vorschläge immer perfekt funktionieren > (Bei Interesse verlinke ich das Video) verwendet, das klappt auch, nur > leider wird dabei die TimerOne Bibliothek verwendet und diese nutzt > einen Interrupt, Wozu braucht Drehgeber unbedingt Interrupt? Sowieso gibt es bestimmt irgendwelche Systemzeit, das reicht. https://www.mikrocontroller.net/articles/Drehgeber#Beispielcode_in_C Ich habe die Varianten dort getestet. Da ich billige China-Drehgeber eingelötet habe, sollte ich einiges einstimmen. Die Variante mit Tabelle in Flash war am besten, zwar sollte ich für sichere Arbeit statt
1 | const char table[16] PROGMEM = {0,0,-1,0,0,0,0,1,1,0,0,0,0,-1,0,0}; |
1 | const char table[16] PROGMEM = {0,0,-1,0,0,0,0,1,0,0,0,0,0,0,0,0}; |
verwenden.
1 | volatile signed char enc_delta; |
2 | |
3 | |
4 | void drehgeber_abfrage(void){ // jede 1 ms gemacht |
5 | |
6 | static int8_t last=0; // alten Wert speichern |
7 | last = (last << 2) & 0x0F; |
8 | if (PHASE_A) last |=2; |
9 | if (PHASE_B) last |=1; |
10 | enc_delta += pgm_read_byte(&table[last]); |
11 | }
|
12 | |
13 | signed char encode_read1( void ) // read single step encoders |
14 | {
|
15 | signed char val; |
16 | unsigned char tmp_sreg; // temporaerer Speicher fuer das Statusregister |
17 | tmp_sreg = SREG; // Statusregister (also auch das I-Flag darin) sichern |
18 | cli(); |
19 | val = enc_delta; |
20 | enc_delta = 0; |
21 | |
22 | SREG = tmp_sreg; // Status-Register wieder herstellen |
23 | return val; // counts since last call |
24 | }
|
1 | #define PHASE_A (beliebige PINPORT & (1<<beliebige_PIN))
|
2 | #define PHASE_B (beliebige PINPORT & (1<<beliebige_PIN))
|
Was kann noch einfacher sein?
:
Bearbeitet durch User
Wilson W. schrieb: > en Vorschlag von Arduino Fanboy habe ich nachgeschlagen aber nicht > herausfinden können wie ich das konkret umsetze, Hier ein Blink.ino aus meiner Wühlkiste
1 | volatile unsigned int ticks = 0; |
2 | |
3 | void setup() |
4 | {
|
5 | DDRB |= _BV(PB5); // pinMode(LED_BUILTIN,OUTPUT); |
6 | |
7 | OCR0A = 42; // Wert ist egal |
8 | TIMSK0 |= _BV(OCIE0A); |
9 | TIFR0 |= _BV(OCF0A); |
10 | }
|
11 | |
12 | void loop() {} |
13 | |
14 | |
15 | ISR(TIMER0_COMPA_vect) |
16 | {
|
17 | if(++ticks >= 1000U) // 1000 == 977ms bei 16MHz |
18 | {
|
19 | PINB = _BV(PB5); //digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN));// toggle pin |
20 | ticks = 0; |
21 | }
|
22 | }
|
Ich danke euch vielmals, hab aber wohl noch viel zu wenig Ahnung, die letzten beiden Beiträge verwirren mich noch mehr, hab mich wrst gefreut, weil es eigenständige Funktionen sind, ganz ohne Bibliotheken, aber dann... Muss wohl bei diesem Projekt auf den Encoder verzichten und mich erstmal ne Weile nur damit auseinander setzen. Kapiere halt bei beiden nicht wo ich konkret das "up" und "down", wie im Beispielcode, rausziehen kann, klar, irgendwas passiert und dann kann ich enweder booleans bestimmen oder einfach Integern 1 oder null zuweisen und statt up und down 1 oder 2 nehmen usw., aber was konkret sagt, dass sich der Encoder im oder entgegen dem Uhrzeigersinn dreht, das kapiere ich einfach nicht und je länger und je mehr ich dazu lese, desto schlimmer wird es, Zeichen und undefinierte Zahlen-/Buchstabenkombinationen, wie z.B. |=1 oder _BV oder ++ticks oder 1000U machen mich total wirr, | kenne ich als oder, ++ kenne ich nach nem Wert, dass sich dieser vermehrt und Buchstaben nach der Zahl sind mir völlig neu, gerade Zeichen in Suchmaschinen nachzuschlagen ist praktisch unmöglich. Das ist wohl der Unterschied zwischen richtig lernen und erstmal ewig lang garnichts kapieren und zweckgebunden lernen, also immer dann, wenns nötig ist sich das beibringen. Vielleicht leuchtets mir noch plötzlich ein, aber im Moment ist es wenig erfreulich. Will euch auch nicht weiter mit meiner Noobigkeit nerven ;-) Vielen vielen Dank an alle! Wünsche euch noch einen schönen Abend und viel lecker Schaschlik und so :-)
Ich schätze mal, dass du dir ein gutes C++ Buch anschaffen solltest! > ++ > |= Das Kapitel über Operatoren lesen. > ++ kenne ich nach nem Wert, Dann nennt er sich Postincrement Ich verwende da Preincrement > _BV() Ein Macro namens "BitValue" KA, wo definiert, irgendwo tief im Arduino Core, oder so TIFR0 |= _BV(OCF0A); Ist das gleiche wie TIFR0 |= (1 << OCF0A); > 1000U > 1000UL Das Kapitel über "Konstante Werte" lesen.
Ich glaub auch, denke ich habe auch genug Wissen, dass ich dann nicht das Gefühl habe ein Buch in einer fremden Sprache zu lesen, hatte schon sowas mal als PDF auf dem Handy und konnte rein garnichts damit anfangen, das hatte mich damals sogar davon abgebracht C zu lernen und stattdessen VB, was meiner Meinung nach wenig sinnvoll ist. Danke für die Erklärungen und Stichworte :) Operatoren sind mir nicht ganz fremd, aber die "Kapitel" schlage ich gleich nochmal nach und lese es mir genauer durch. Vielleicht lasse ich das Projekt auch erstmal ruhen. Danke!
Maxim B. schrieb: > Wozu braucht Drehgeber unbedingt Interrupt? Sowieso gibt es bestimmt > irgendwelche Systemzeit, das reicht.... ...eben nicht. Im Gegensatz zu gewöhnlichen Tasten, die man bequem softwaremäßig entprellen kann, weil sie langsam sind und man nur eine Flanke (das Gedrücktwerden) auswerten muß, hat man es bei einem Drehgeber mit etwas ganz anderem zu tun, denn: - man hat 2 Signale - man muß bei einem Signal beide Flanken auswerten - man muß den Zustand des anderen Signals sehr zeitnah zu den Flanken des ersten Signals erfassen. - man muß mit wesentlich höheren Ereignisraten rechnen als beim Taster. Wenn jemand den Knopf mal etwas schnell dreht, dann hat man 9..18 Ereignisse binnen 200 ms, also manchmal alle 10 ms ein Drehereignis. Wenn man das pollen will, dann muß man sehr häufig pollen, also etwa alle 1 ms oder gar noch schneller. Und das für nen popligen Drehgeber. Macht man's langsamer, dann verschluckt er sich. OK, man kann ja an den Knopf dranschreiben "bitte nur LANGSAM drehen und den Knopf gut festhalten, damit er durch die Rastmechanik nicht mit einem kurzen Knack von selbst in die nächste Stellung flutscht". Deutlich besser ist also ein Interrupt auf beide Flanken des einen DG-Signals. Das sollte dasjenige sein, was sich NICHT im Rastpunkt ändert. Aber für den Interrupt muß das per HW entprellt werden. Normalerweise reicht dafür ein 22nF Kondensator aus. W.S.
W.S. schrieb: > Wenn man das pollen will, dann muß man sehr häufig pollen, also etwa > alle 1 ms oder gar noch schneller das ist ja auch kein Problem, hatte man für die Tastenauswertung eine ISR mit 10ms dann pollt man eben für den Drehgeber alle 1ms das genügt dann und die Tasten werden in der ISR danach abgefragt wenn der 1ms ISR Zähler auf 10 steht. ISR 1ms lese Drehencoder Ports zähle den Merker für Tasten hoch ist dieser 10 (oder 9 weil von 0-9 sind genauso 10 wie von 1-10) dann lese die Tasten und gebe es an die Tastenentprellung setze den Merker für Tasten wieder zurück auf 1 (oder 9 weil von 0-9 sind genauso 10 wie von 1-10) ISR Ende
:
Bearbeitet durch User
das Spielchen kann man weitertreiben für IR Dekodierung ISR 1/15 ms lese IR Dekoder zähle den Merker für Drehencoder hoch ist dieser 15 (oder 14 weil von 0-14 sind genauso 15 wie von 1-15) lese Drehencoder Ports setze den Merker für Drehencoder wieder zurück auf 1 (oder 9 weil von 0-9 zähle den Merker für Tasten hoch ist dieser 10 (oder 9 weil von 0-9 sind genauso 10 wie von 1-10) dann lese die Tasten und gebe es an die Tastenentprellung setze den Merker für Tasten wieder zurück auf 1 (oder 9 weil von 0-9 sind genauso 10 wie von 1-10) ISR Ende
:
Bearbeitet durch User
Wilson W. schrieb: > Mein Sketch ist zur Zeit noch sehr chaotisch, wenn ich den poste fresst > ihr mich, das garantiere ich Das Fressen hat mit dem Chaos im Code erstmal gar nichts zu tun. Es reicht schon, dass du seitenlangen Code nicht als ANHANG postest ;-(
Guido Körber schrieb: > Da der Drehgeber ja wohl als User-Interface verwendet wird stört es > nicht, wenn der mal einen Impuls übersieht. Mich würde das bei der Benutzung schon irritieren, wenn ein Auswahlmenü beim Drehen ab und zu erratisch hoch und runter springt.
Beitrag #5396906 wurde vom Autor gelöscht.
Wolfgang schrieb: > Mich würde das bei der Benutzung schon irritieren, wenn ein Auswahlmenü > beim Drehen ab und zu erratisch hoch und runter springt. das macht man dann mit Überabtastung, ich musste auch erst experimentieren, PeDa hat dafür den 4 Impuls ja zur Auswahl gestellt, kann sein das ich nun mehr kurbeln muss aber dafür funktioniert es sicher mit Einrasten auch in der Menüwahl und nichts zappelt. https://www.mikrocontroller.net/attachment/highlight/40597 https://www.mikrocontroller.net/articles/Drehgeber#Beispielcode_in_C
:
Bearbeitet durch User
Vor ein paar Jahren portierte ich Peters Encoder Code unter anderen uC auch auf den Arduino Pro-Mini. Es funktioniert dort genau so einwandfrei wie auf allen anderen uC. Abgetastet werden die zwei Pins bei mir in einer schon vorhandenen 1ms TIMER2 ISR. Ich bin jetzt gerade nicht in der Nähe meines PCs, könnte aber irgendwann später meinen alten Code raussuchen wenn es Dir hilft. Die Routine von Peter ist absolut empfehlenswert und Goldes wert und es lohnt sich auf alle Fälle sich damit zu befassen.
Gerhard O. schrieb: > Die Routine von Peter ist absolut > empfehlenswert und Goldes wert und es lohnt sich auf alle Fälle sich > damit zu befassen. nana. ich bin eher für's Verstehen der zugrundeliegenden Hardware. Nochwas: Ich nehme für Drehencoder schon seit Jahren nur nen Interrupt - und bei mir hat sich das bislang noch nie verzählt, auch dann nicht, wenn mal jemand den Knopf mit nem "Ratsch" durchdreht. Da frag ich mich, wieso hier so viele Leute immer wieder auf Polling herumreiten. Das frißt bloß unnötig Rechenzeit und ist keinen Deut besser. W.S.
W.S. schrieb: > Da frag ich mich, > wieso hier so viele Leute immer wieder auf Polling herumreiten. Das > frißt bloß unnötig Rechenzeit und ist keinen Deut besser. Teufel, Weihwasser?
@Gerhard Na klar, sehr gerne, hab zich Tabs geöffnet mit den einzelnen Stichworten und springe immer wieder zurück hierher und vielleicht kann ich deine Lösung eher nachvollziehen. Dankeschön!
:
Bearbeitet durch User
Wilson W. schrieb: > @Gerhard > > Na klar, sehr gerne, hab zich Tabs geöffnet mit den einzelnen > Stichworten und springe immer wieder zurück hierher und vielleicht kann > ich deine Lösung eher nachvollziehen. > > Dankeschön! Hallo Wilson, im Anhang findest Du mein soeben getestetes Demo Programm. Nach dem Laden öffne ein Terminal Programm auf 9600, N,8,1 gestellt und drehe am Knopf des QE Encoders und die Encoder Schritte werden entsprechend seriell angezeigt. Bei einer ISR Wiederhol-Frequenz von 1ms, kann ich den Decoder so schnell wie mit der Hand möglich drehen ohne Schritte zu verlieren. Es läuft auf einem Pro-Mini Klon mit 16MHz 5V Ausstattung. Der QE Encoder ist in einer Link im Programm beschrieben und hat 30 Schritte pro Umdrehung. DA findest Du auch noch eine anderes Demo Programm. Versuchs dann mal und viel Erfolg. Gerhard
W.S. schrieb: > Gerhard O. schrieb: >> Die Routine von Peter ist absolut >> empfehlenswert und Goldes wert und es lohnt sich auf alle Fälle sich >> damit zu befassen. > > nana. > > ich bin eher für's Verstehen der zugrundeliegenden Hardware. > > Nochwas: Ich nehme für Drehencoder schon seit Jahren nur nen Interrupt - > und bei mir hat sich das bislang noch nie verzählt, auch dann nicht, > wenn mal jemand den Knopf mit nem "Ratsch" durchdreht. Da frag ich mich, > wieso hier so viele Leute immer wieder auf Polling herumreiten. Das > frißt bloß unnötig Rechenzeit und ist keinen Deut besser. > > W.S. Das kommt auf die Anwendung an. Meine Programme haben fast immer eine Zeitbasis mit Timer ISR und da braucht das Pollen kaum CPU Ressourcen. Ich finde diese Methode (für mich) durchaus akzeptabel. Mit ISR kann schon so seine Probleme mit Prellen haben und beansprucht dann auch entsprechende Abwehrmaßnahmen die auch Code verschlingen. Ich finde Peters Algorithmus fuer die Praxis ideal und Ressourcen sparsam. Für Maschinen Q-Auswertung würde ich nur solche Methoden verwenden wollen wie man sie z.B. beim STM32 HW-Counter findet oder die LS7266 Bausteine um Schrittverluste schon von vornherein ausschließen zu können. Software Q- Auswertung hat meiner Meinung nach nur bei langsamen mechanischen Anwendungen wie User Interfaces Sinn wo mögliches sporadisches Fehlverhalten in der Regel keine schlimme Auswirkung hat. Aber da viele Wege nach Rom führen, beanspruche ich nur einen davon:-) Gruß, Gerhard
Gerhard O. schrieb: > Der QE Encoder ist in einer Link im Programm beschrieben und hat 30 > Schritte pro Umdrehung. DA findest Du auch noch eine anderes Demo > Programm. Ich habe soeben das Demo Programm auf der KY-040 Webseite ausprobiert und das funktioniert auch ganz ordentlich. Konnte mit Rumspielen mit dem Knopf kein Fehlverhalten erzwingen. Allerdings verliert es (wie zu erwarten) maechtig Schritte beim Schnelldrehen.
:
Bearbeitet durch User
Vielen Dank Gerhard. Was interessant ist, der Beispiel-Sketch auf der Webseite ist die erste Methode, die ich ausprobiert habe und die ging fast garnicht, im Uhrzeigersinn stieg der Wert meist an, sprang aber immer wieder zurück und gegen den Uhrzeigersinn ist der Wert hin und her gesprungen, meist eher nach oben als nach unten. Aber cool, hab durch deine Variante auch bei den anderen Versionen schonmal verstanden welcher Wert die Drehrichtung ausgibt. Ich muss das ganze als ein eigenständiges Projekt aufarbeiten und mir viel viel Zeit dafür nehmen und denke grad wieder wie praktisch doch ein Android Handy wäre, dann müsste ich nicht stundenlang krumm vorm Lappi hängen und mich am Kopf kratzen, sondern könnte ständig in jeder Situation die Sketche auf den uC laden. Allen ein schönes Wochenende :)
W.S. schrieb: > Da frag ich mich, wieso hier so viele Leute immer wieder auf Polling herumreiten. Das ist einfach: Weil sie mehr wissen als du. W.S. schrieb: > Ich nehme für Drehencoder schon seit Jahren nur nen Interrupt Das kann ja in Ordnung sein - wenn es ein Timer-Interrupt ist. Dass du nicht mal diesen wichtigen Unterschied bemerkst, zeigt, WIE wenig Ahnung du hast.
Hallo Wilson, Deinem Bericht nach stimmt höchstwahrscheinlich etwas mit den Komponenten, bzw Verdrahtung oder sonst irgendwas nicht. Beide Programme funktionieren bei mir absolut einwandfrei wenn man davon absieht, daß das Web Demo Programm beim Schnelldrehen Schritte verliert was bei Peters Version nicht der Fall ist. Arbeite Dich auch durch den Arikel hier im Forum. Pullups (10k) sind absolut notwendig. Auf die aktivierten internen Pullups darfst Du Dich nicht verlassen. Es muß zwecks zuverläßiger Funktion durch die Kontakte idealerweise mindestens ein Strom im mA Bereich fließen. Besser mit dem Oszi überprüfen was da vor sich geht. Der KY-040 hat auf der Bord Pullups die mit der Versorgungsspannung verbunden sein müssen. Bei mir verwende ich bequemerweise den auf HIGH gesetzten D8 Pin. Auch aufpassen, daß der gemeinsame Pin vom Drehgeber nach Masse angeschlossen ist und die Quadraturausgänge tatsächlich zu den designierten Eingängen gehen. Bei mir waren D6 und D7 als Eingänge designiert (Notfalls anpassen). Beim Webdemo waren es andere Eingänge. Also alles akribisch nachprüfen. Bevor Du nicht die Demo Programme so wie angegeben zum Laufen bringst nützt es nichts mit Deinen Projekt weiter zu machen. Du mußt methodisch vorgehen. Gerhard Nachtrag: Schließ wie im Webartikel vorgeschlagen zwei LEDs an den Drehgeberausgängen nach 5V an um die korrekte Sequenz der Ausgänge überprüfen zu können.
:
Bearbeitet durch User
Ich habe den Pulsgeber bloß gegen Ground auf zwei digitale Pins geschaltet. Bin nicht sicher was du mit Demo-Programm meinst, ich meinte den kurzen Beispiel-Sketch unten auf der Seite. Für die Lötstation, zumindest diese Version habe ich mich nun doch für Taster entschieden, spricht aktuell mehr dafür als dagegen, es fühlt sich seltsam an auf dem kleinen Display mit nem Potiknopf was einzustellen, weil für die Wert-Einstellung dreht man den Pulsgeber wie nen Poti, aber für die Menü-Bedienung dreht man in Rastern, mir kam gleich das Nokia 7110 in Erninnerung mit dem Scrollrad, glaub das wäre die Ideallösung. Da ich auch eine Einstellung für die Einstell-Schritte der Soll-Temperaturen und der Presets eingebaut habe, kann ich das dann bequem für die Taster anpassen, mit den drei Presets werde ich auch nicht so viel einstellen müssen, sondern nur auswählen. Und Pulsgeber ansich zu verstehen und richtig auszuwerten wird ein komplett eigenes Projekt, die Dinger sind zu praktisch, als dass man sie einfach überspringt und jedes Mal nach Alternativen sucht. Ein Oszi habe ich leider nicht, bin aber dabei mir eine Hobby-Werkstatt für Low- bis Zero-Budget aufzubauen, hab ein altes Pentium III Laptop, das maximal 60 Watt verbraucht, welches ich dann so umbauen will, dass ich es als Oszi und zum Anzeigen von Schaltplänen nutzen kann, aber da hab ich mir noch keine Gedanken drum gemacht, außer, dass eine Touchfolie o.Ä. sinnvoll wäre. Im Endeffekt gehts um den Spaß und das Lernen beim Aufbau, wirklich brauchen tue ich nichts davon, aber wenn ich es habe, kann ich es auch dafür verwenden komplexere Dinge zu machen als grobe Elektronik und Elektrik zu reparieren und Komponenten bei Handys tauschen.
Wilson W. schrieb: > Ich habe den Pulsgeber bloß gegen Ground auf zwei digitale Pins > geschaltet. Bin nicht sicher was du mit Demo-Programm meinst, ich meinte > den kurzen Beispiel-Sketch unten auf der Seite. Das ist schon in Ordnung. Nur müssen auch Pullups von 10K von 5V auf die Drehgeber Eingänge vorhanden sein. Zumindest sollten die internen Pullups des AVRs aktiviert sein. Auch die vorgeschlagenen LEDs wären zum Testen ohne Oszi nützlich. Ich würde auf alle Fälle den Problemen auf den Grund gehen und zumindestens die Sache zum Laufen zu bringen. Das User Interface kannst Du Dir ja noch überlegen. Also versuch mal die Programme zum richtigen Funktionieren zu bringen.
Wilson W. schrieb: > Und Pulsgeber ansich zu verstehen und richtig auszuwerten wird ein > komplett eigenes Projekt, die Dinger sind zu praktisch, als dass man sie > einfach überspringt und jedes Mal nach Alternativen sucht. nutze die LIB von Dannegger Wilson W. schrieb: > Ein Oszi habe ich leider nicht, ist nicht nötig, ein Nachmittag mit dem Beispiel Code, die verschiedenen Varianten probieren 1 -2 -4 Impulse fertig.
Wilson W. schrieb: > hab ein altes Pentium III Laptop, > das maximal 60 Watt verbraucht, welches ich dann so umbauen will, dass > ich es als Oszi und zum Anzeigen von Schaltplänen nutzen kann Das ist kaum eine gute Idee: falls etwas mit Oszi kaputt geht, hast du gleich deine Schaltpläne verloren! Auch was Frequenzen betrifft, ist ein Laptop-Oszi fragwürdig. Mein Tipp: überall wo nur möglich Geräte benutzen, die ohne Stromnetz arbeiten können. Somit hast du bei Problem mit GND mehr Überlebenschancen für deine Technik und auch für dich selbst.
Mhh, es gibt da doch so Oszi-Programme, mit denen man die Soundkarte auslesen kann und mit einer Schaltung vor der Soundkarte kann man ja Überspannungen etc. verhindern. Der Lappi selbst arbeitet doch mit einem Schaltnetzteil, also ist da doch alles sicher und ich würde damit auch keine Netzspannung messen. Ich synchronisiere eh alle meine Datenträger regelmäßig. Das ist aber auch nur eine Idee, weil ich den Lappi gerne für irgendwas verwenden will und die günstigen Oszi-Bausätze haben halt recht kleine Bildschirme, vielleicht könnte man die auch auslesen und auf einen größeren Schirm übertragen, kein Plan, ich werde mich aber noch genauer damit beschäftigen, hat keine Priorität.
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.