Grüße,
zu aller erst: Ich bin neu in der Materie also seid bitte nicht alzu
streng mit mir.
Ich versuche grade Drehencoder auszulesen. An sich hat die Sache mit
einem Drehencoder und dem folgenden Code ohne Probleme funktioniert.
1
/* Encoder Library - Basic Example
2
* http://www.pjrc.com/teensy/td_libs_Encoder.html
3
*
4
* This example code is in the public domain.
5
*/
6
7
#include <Encoder.h>
8
9
// Change these two numbers to the pins connected to your encoder.
10
// Best Performance: both pins have interrupt capability
11
// Good Performance: only the first pin has interrupt capability
12
// Low Performance: neither pin has interrupt capability
13
Encoder myEnc(5, 6);
14
// avoid using pins with LEDs attached
15
16
void setup() {
17
Serial.begin(9600);
18
Serial.println("Basic Encoder Test:");
19
}
20
21
long oldPosition = -999;
22
23
void loop() {
24
long newPosition = myEnc.read();
25
if (newPosition != oldPosition) {
26
oldPosition = newPosition;
27
Serial.println(newPosition);
28
}
29
}
jetzt habe ich das ganze jedoch auf 5 Drehencoder erhöht und meine Werte
springen hin und her. manchmal dreh ich den Encoder nach links und er
bleibt die ganze Zeit auf dem Wert. Er "springt zwar kurz ein 2 Werte
zurück jedoch gleich wieder 2 nach vorne"
So sieht mein Code mit den 5 aus.
wo liegt mein Fehler? ist mein Code zu langsam?
Oder stören die Coder sich gegenseitig weil Sie alle an der Selben masse
hängen?
Wenn ja wie trenne ich die Richtig?
Welchen Drehencoder ich habe kann ich leider nicht sagen... auf den
Dingern steht nix drauf und die Rechnung von Segors find ich natürlich
nicht...
Hoffe ihr könnt mir trotzdem helfen.
Gruß
Martin
PS: Hab versucht mein Code in Spoiler zu setzen, ging aber nicht. Wenn
ihr mir verrattet wie ich spoiler dann editier ich den Thread auch noch
;)
einen text spoilern,
macht man üblicherweise um einen thread übersichtlicher zu gestalten.
Ein Spoiler ist dazu da um einen Text zu verbergen und erst bei einem
klick auf den Spoiler button freizugeben.
Danke fürs verschieben ;)
Das passt schon so, wie es ist.
Das Problem ist eher, dass dir hier keiner groß helfen wird können. Es
sei denn es findet sich noch ein Arduino Spezialist.
Denn: die tatsächlich schwierigen Sachen (wie die Auswertung der
Encoder) sind ja nicht von dir geschrieben, sondern bereits fertige
Bausteine. In deinem Code gibt es da nicht viel, was du falsch machen
kannst.
Wenn du das Gefühl hast, es könnte ein Zeitproblem sein, dann könntest
du mal den Teil schneller machen, der in Relation recht viel Zeit
verbrutzelt: die Ausgabe der Texte. Da muss ja nicht 'Knob' dortstehen.
Kürzerer Text wird aber schneller ausgegeben und damit gewinnst du etwas
Zeit. Einen Versuch ist es wert, aber ehrlich gesagt hab ich da nicht
viel Hoffnung.
Was du probieren kannst, ob der Fehler mit dem Encoder mitwandert, wenn
du die mal hardwaremässig untereinander tauscht oder ob es immer beim
5.ten Encoder im Programm hängt.
Abgesehen davon wirst du dir den Entwickler der Encoder-Klasse suchen
müssen, bzw. ein dezidiertes Arduino Forum. Hier, in diesem Forum
basieren wir unsere Programme normalerweise nicht auf vorgefertigten
Komponenten, deren Code wir nicht sehen.
Danke dir schonmal.
Ich habe mich vill etwas falsch ausgedrückt, das Problem besteht bei
allen Encodern. nicht nur bei nr 5. Auch wenn ich 4 vom steckbrett löse
bleibt das problem bestehen.
Gut ich werd das ganze mal selber schreiben und dann melde ich mich
nochmal :)
vill löst sich das Problem dadurch ja von alleine
Grüße
Martin schrieb:> Ich habe mich vill etwas falsch ausgedrückt, das Problem besteht bei> allen Encodern. nicht nur bei nr 5. Auch wenn ich 4 vom steckbrett löse> bleibt das problem bestehen.
Was heißt 'vom Steckbrett löse'.
Das ist ja eine ganz neue Information, dass da ein Steckbrett mit im
Spiel ist.
In dem Fall tippe ich mal auf Wackelkontakte.
ich habe grade nochmal sämtliche kabel ersetzt problem bleibt bestehen.
Knob 2 = 88
Knob 2 = 87
Knob 2 = 86
Knob 2 = 88
und es kommen ja auch exakt 4 werte an (die andern habe ich jetzt mal
rausgelöscht der übersicht zu liebe)
und das problem besteht auch fast nur beim links drehen.
schnell drehen geht bei mehreren cdern übrigens garnicht mehr da ist ne
komplette umdrehung meist nur 2-3 rasterungen. Daher kam auch meine
vermutung das da was am code faul ist... ich werds wiegesagt mal neu
schreiben
Problem eingrenzen: Mit einem Encoder geht's - mit fünfen nicht.
Probier's mal mit zweien. Wenn die Library die Pins pollen muss, dann
kann die Abfrage bei vielen Encodern leicht zu langsam werden. Gerade
bei Arduinos die evtl. die Eingänge nicht direkt abfragen.
Hallo,
ich fasse noch mal zusammen:
Dein 5 Encoder Code funktioniert nie.
Auch nicht, wenn nur ein Encoder angeschlossen ist und zwar egal,
welcher?
Richtig?
Viele liebe Grüße
Timm
Er funktioniert, aber nicht richtig die Werte sind halt ziemlich buggy
vor allem bei der links drehung.
Auch nicht, wenn nur ein Encoder angeschlossen ist und zwar egal,
welcher?
Richtig, außer ich nutz den ersten Code da funzt alles super.
Mit 2 funktionierts auch noch.
3 & 4 hab ich nicht getestet
?
dein Knopf 5 verwendet Pin 13, das ist normal die LED.
Hängen die Drehencoder mit Pullup (ob int. oder ext. ist egal) gegen
Masse, oder sind die Eingänge "fliegend"?
gruß Mat
bist du auch sicher, dass du die Encoder Bibliothek richtig verwedest?
Poste mal den Link, welche Bibliothek du verwendest.
Sollte das nicht über Interrups gemacht sein, fehlt mir hier irgendwo
ein Encoder.update oder ein Encoder.Poll in der Hauptschleife.
gruß Mat
Hi,
Mat schrieb:> bist du auch sicher, dass du die Encoder Bibliothek richtig verwedest?> Poste mal den Link, welche Bibliothek du verwendest.>> Sollte das nicht über Interrups gemacht sein, fehlt mir hier irgendwo> ein Encoder.update oder ein Encoder.Poll in der Hauptschleife.
natürlich funktioniert das über Interrupts. Und damit ist auch der
Fehler gefunden. Tusch und Helau.
Encoder knob1(4, 5);
Encoder knob2(6, 7);
Encoder knob3(8, 9);
Encoder knob4(10, 11);
Encoder knob5(12, 13);
wie soll das denn wohl gehen?
vlg
Timm
Hallo Martin,
ich gebe den anderen beim Lösungsweg vollkommen Recht.
Bitte schließe zunächst nur einen Drehgeber mit dem nötigen Programm für
die Auswertung eines einzelnen Drehgerbers an dein Board an. Denke an
die 10K Wiederstände gegen Masse in den Signalleitungen.
Ich kenne die Arduino Lib zur Drehgeberauswertung nicht, aber es muss
vermutlich auch hier darauf geachtet werden wie viele "Steps" dein
Drehgeber macht. Meist sind es single-, two- oder four-steps. Wenn du
einen two-step als single-step auswertest könnte das von dir beschriebe
dabei herauskommen.
Gruß
deathfun
PS: Du könntest auch hier mal vorbeischauen:
http://www.mikrocontroller.net/articles/Drehgeber
Danke für die vielen Antworten
also ich nutze diese libary hier:
http://www.pjrc.com/teensy/td_libs_Encoder.html
Mein Arduino ist ein Mega2560
@ Tim
das müsste gehn weil in der libary folgendes mit übergabe parametern
steht
(hab nur ein kleinen teil kopiert)
1
Encoder(uint8_t pin1, uint8_t pin2) {
2
#ifdef INPUT_PULLUP
3
pinMode(pin1, INPUT_PULLUP);
4
pinMode(pin2, INPUT_PULLUP);
5
#else
6
pinMode(pin1, INPUT);
7
digitalWrite(pin1, HIGH);
8
pinMode(pin2, INPUT);
9
digitalWrite(pin2, HIGH);
10
#endif
das mit dem 10k Wiederstand von den Signalleitungen versteh ich noch
nicht ganz, soll ich meine Masse mit pin a und b mithilfe eines 10k
Widerstandes verbinden?
Das mit dem Interrupt versteh ich auch nicht ganz, laut google ist das
ja eine Unterbrechungsanforderung. Soweit eig ganz klar aber wie soll
ich das an einen Encoder vergeben? Das müsste ich ja dann direkt im
Programm machen oder?!
Danke euch für eure Hilfe und sorry für die blöden fragen
ganz vergessen.
Mein Endcoder sind gerastert und machen denke ich 4 sprünge. Jedenfalls
wird pro rasterung der wert um 4 erhöht. Wenn meine vermutung falsch ist
währe es super wenn ihr mir sagen könntet wie ich rausfinde was für
schritte er macht. Da ich wie gesagt leider kein Datenblatt habe :(
Martin schrieb:> Mein Endcoder sind gerastert und machen denke ich 4 sprünge.
Wieso muss man da "Denken"? Ich würde das im Datenblatt nachlesen.
Danach würde ich mit "Denken" anfangen...
> Da ich wie gesagt leider kein Datenblatt habe
Poste mal ein, zwei Fotos von den Encodern (300kB reichen)...
Martin schrieb:> Das mit dem Interrupt versteh ich auch nicht ganz, laut google ist das> ja eine Unterbrechungsanforderung. Soweit eig ganz klar aber wie soll> ich das an einen Encoder vergeben? Das müsste ich ja dann direkt im> Programm machen oder?!
Au Backe. In deinem geposteten Code oben steht doch klar und deutlich:
> // Change these two numbers to the pins connected to your encoder.> // Best Performance: both pins have interrupt capability> // Good Performance: only the first pin has interrupt capability> // Low Performance: neither pin has interrupt capability
Was ist denn daran nicht klar? Du sollst für bessere Performance,
möglichst Pins vergeben die Interruptfähig sind. Hast du das getan?
Grade bei 5 Encondern MUSST du natürlich darauf achten.
cyblord ---- schrieb:> Au Backe. In deinem geposteten Code oben steht doch klar und deutlich:>> // Change these two numbers to the pins connected to your encoder.>> // Best Performance: both pins have interrupt capability
Au Backe...
Lothar Miller schrieb:> Martin schrieb:>> Mein Endcoder sind gerastert und machen denke ich 4 sprünge.> Wieso muss man da "Denken"? Ich würde das im Datenblatt nachlesen.> Danach würde ich mit "Denken" anfangen...
wieso schreibe ich eigentlich das ich kein Datenblatt habe? ...
Lothar Miller schrieb:> cyblord ---- schrieb:>> Au Backe. In deinem geposteten Code oben steht doch klar und deutlich:>>> // Change these two numbers to the pins connected to your encoder.>>> // Best Performance: both pins have interrupt capability> Au Backe...
Wie meinen?
Hmm
Im encoder.h wird heftig von einem makro
ENCODER_USE_INTERRUPTS
Gebrauch gemacht.
Ich hab aber im ganzen Zip-File nirgends eine Stelle gesehen, an der
dieses Makro jemals definiert worden wäre.
So wie das aussieht, wird Interrupt Unterstützung aber nur dann
compiliert, wenn dieses Makro definiert ist.
Dann wird wohl bei einem Mega2560 diese Zuordnung aus
utility/interupt_pins.h gelten
Verstehe ich das richtig?
ein Interrupt pin ist ein Pin der automatisch erkennt wenn sich an
seinem anschluss etwas ändert?
laut arduino.cc hat mein mega 5 dieser pins
Mega2560 2 3 21 20 19 18
also schließe ich dort jeweils einen pin meiner drehencoder an?!
sorry aber wie gesagt ich bin neu ^^
Martin schrieb:> [...] das mit dem 10k Widerstand von den Signalleitungen versteh ich noch> nicht ganz [...]
Hallo Martin.
Das muss natürlich nicht die Regel sein, aber alle Drehgeber die ich
bisher verwendet habe wurd in etwa so angeschlossen (am Beispiel eines
ALPS two-step mit Taster):
a b c (der Drehgeber)
d e (der Taster)
b und d an 5V.
a, c und e an drei Eingänge des uC und zusätzlich mit 10K gegen Masse.
Gruß
deathfun
Also ich sage es ja öfter aber hier sieht man das Problem doch mal
wieder sehr deutlich: Der TE hat keine Ahnung was PullUp/PullDowns sind,
keine Ahnung von Interrupts, keine Anhnung von eigentlich überhaupt
irgendwas relevantem. Aber natürlich schnell mal 5 Encoder anschließen,
weil man hat ja eine lib. Nur leider setzt sogar eine Arduino-lib einige
grundsätzliche Dinge vorraus, die aber nicht da sind. Nun wird sich hier
irgendwas an Infos zusammengestammelt. Ohne Verständis und Plan, ohne
Grundlagen und das wird für immer so bleiben.
gruß cyblord
deathfun schrieb:> Das muss natürlich nicht die Regel sein, aber alle Drehgeber die ich> bisher verwendet habe wurd in etwa so angeschlossen (am Beispiel eines> ALPS two-step mit Taster):
Das mag in deinem System vernünftig gewesen sein, auf einem AVR ist es
das aber nicht.
Drehencoder sind auch nichts anderes als Taster. Nur in einem anderen
Gehäuse.
Und genau so werden sie auch angeschlossen: Wie stink normale Taster.
Sie schalten nach Masse durch.
d.h. der gemeinsame Anschluss führt nach Masse, die Signalleitungen
gehen direkt an die µC-Pins.
Gänzlich ohne irgendwelche zusätzlich notwendigen Pullup oder Pulldown
Widerstände. Denn die sind im AVR schon eingebaut. Der Code im
Konstruktor der Encoder Klasse aktiviert die auch.
@Martin
Vergiss die 10k.
cyblord ---- schrieb:>>>> // Best Performance: both pins have interrupt capability>> Au Backe...> Wie meinen?
Man wertet einen Drehgeber nicht über 2 Interrupts aus. Und man wertet
noch viel weniger 5 Drehgeber über 10 Interrupts aus.
Martin schrieb:> wieso schreibe ich eigentlich das ich kein Datenblatt habe? ...
Wieso schickst du kein Foto? Könnte ja sein, dass schon mal einer
"deinen" Drehgeber gesehen hat. Oder die Zahlen, die draufgedruckt sind,
entschlüsseln kann...
Lothar Miller schrieb:> cyblord ---- schrieb:>>>>> // Best Performance: both pins have interrupt capability>>> Au Backe...>> Wie meinen?> Man wertet einen Drehgeber nicht über 2 Interrupts aus. Und man wertet> noch viel weniger 5 Drehgeber über 10 Interrupts aus.
Richtig aber wenn die lib das so macht und dabei perfomanter ist als
ohne, dann bleibt nicht viel übrig. Es scheint ja dass die mit Polling
nicht besonders gut läuft, zumal bei 5 Stück. Warum auch immer. Das
müsste man den Schreiberling der lib fragen.
cyblord ---- schrieb:> Richtig aber wenn die lib das so macht und dabei perfomanter ist als> ohne, dann bleibt nicht viel übrig. Es scheint ja dass die mit Polling> nicht besonders gut läuft, zumal bei 5 Stück. Warum auch immer. Das> müsste man den Schreiberling der lib fragen.
Das Problem ist weniger die Lib selber, sondern der Code drumherum, der
die Lib benutzt. Wir kennen ja die typische Arduino Schreibe hier im
Forum, die sich einen Dreck um irgendwelche blödsinnigen
Performance-Bottlnecks kümmert. Da wird delayed und per serieller
Schnittstelle auf Teufel komm raus verschickt.
cyblord ---- schrieb:> Also ich sage es ja öfter aber hier sieht man das Problem doch mal> wieder sehr deutlich: Der TE hat keine Ahnung was PullUp/PullDowns sind,> keine Ahnung von Interrupts, keine Anhnung von eigentlich überhaupt> irgendwas relevantem. Aber natürlich schnell mal 5 Encoder anschließen,> weil man hat ja eine lib. Nur leider setzt sogar eine Arduino-lib einige> grundsätzliche Dinge vorraus, die aber nicht da sind. Nun wird sich hier> irgendwas an Infos zusammengestammelt. Ohne Verständis und Plan, ohne> Grundlagen und das wird für immer so bleiben.>> gruß cyblord
Ich weiß was Pullup und PullDowns sind...
Ich habe geschrieben das ich nicht weiß was ein Interrupt ist, habe
gegoogelt und gefragt ob meine Feststellung richtig ist.
Keine ahnung wo genau dein Problem liegt aber ich bin dabei mir eine
Grundlage zu schaffen. Entschuldige bitte vielmals das ich mich erstmal
mit einer libary an die Drecoder rantaste.
und nein es soll nicht für immer so bleiben, ich habe vor mich weiter in
das Thema reinzuarbeiten. Für mich gillt aber learning by doing.
Danke jedoch für deine motivierenden Worte.
B2T:
Ich habe nun die Endcoder an die INterrupts angeschlossen, nun
funktioniert das ganze auch einwandfrei =)
so nochmal zum Verständis, ein INterrupt pin erkennt automatisch oder
schneller wenn sich der anliegende Wert ändert?
Kann ich dann mit attachInterrupt(pin) für jeden Pin einschalten?
Hätte ich also bei meiner bisherigen pin belegung bleiben wollen hätte
ich im void setup
attachInterrupt(pin);
angegeben?
Grüße
Martin
Martin schrieb:> so nochmal zum Verständis, ein INterrupt pin erkennt automatisch oder> schneller wenn sich der anliegende Wert ändert?
Was bedeutet "Interrupt"? Unterbrechung!
Ein Interruptpin kann also (wenn korrekt initialisiert) den normalen
Programmablauf unterbrechen. So wie ein Postbote dich mit einer Klingel
beim Kochen unterbrechen kann. Wenn ihr euch dann an der Tür
vertratscht, dann kocht die Milch halt über und brennt an.
Damit nichts anbrennt muss die Unterbrechung (=Interruptroutine) so kurz
wie möglich sein.
> Kann ich dann mit attachInterrupt(pin) für jeden Pin einschalten?
Kommt auf deinen uC an.
Martin schrieb:> und nein es soll nicht für immer so bleiben, ich habe vor mich weiter in> das Thema reinzuarbeiten. Für mich gillt aber learning by doing.
Das ist schön.
Unterhalb einer gewissen Wissensgrenze aber nicht sinnvoll. Denn im
Moment fällt zu viel auf dich ein, was du nicht mehr sinnvoll
auseinanderklamüsern kannst.
Ein ordentliches Tutorial von Anfang an durchgehen wäre wesentlich
sinnvoller.
> so nochmal zum Verständis, ein INterrupt pin erkennt automatisch oder> schneller wenn sich der anliegende Wert ändert?
Er kann so konfiguriert werden, dass er einen Interrupt auslöst. Ein
interrupt ist eine Programmunterbrechung. Das Hauptprogramm wird
kuzfristig unterbrochen und statt dessen bearbeitet der µC eine
bestimmte Funktion.
D.h. der Pegelwechsel sorgt dafür, dass ein bestimmter Code ausgeführt
wird. Dadurch ist das Programm davon unabhängig geworden, dass der Code
in loop() genau diese Funktion ausführt. Wenn es in loop() mal an
anderer Stelle etwas länger dauert, ist das daher kein Problem mehr.
Dieser 'länger dauernde Code' wird einfach durch den Interrupt
unterbrochen, der Code beabreitet die Änderung an diesen Encoder Pins
und kehrt dann zur Unterbruchstelle zurück.
> Kann ich dann mit attachInterrupt(pin) für jeden Pin einschalten?
Mit attachInterrupt schaltest du übnerhaupt nichts ein. Mit
attachInterrupt wird eine Funktion an den Interrupt gebunden, die im
Falle des Auftretens des Interrupts aufgerufen wird. to attach ==
anknüpfen, anhängen
Wie gesagt: Ein ordentliches Tutorial wäre stark von Nöten.
Mir ist schon klar, dass da jetzt viel auf einmal auf dich hereinbricht.
Genau deshalb ist es wichtig, dass dich ein Tutorial systematisch in die
Materie einführt. Mit anlassbezogenem 'learning by doing' fällst du
maximal auf die SChnauze, weil du immer wieder in Wissenslücken fällst
und es extrem lange dauert, bis sich das globale Bild zu
vervollständigen beginnt. Genau dieses globale Bild, wie die Einzelteile
alle ineinander greifen ist aber eines der wichtigsten Dinge in der
Programmierung.