Forum: Mikrocontroller und Digitale Elektronik PCF8574 rotary Encoder


von TR.OLL (Gast)


Lesenswert?

Hallo,

kennt jemand eine Lösung wie man mit einem 
[[https://www.mikrocontroller.net/articles/Port-Expander_PCF8574]] 
(bevorzugt mit dieser Library https://github.com/xreef/PCF8574_library) 
einen rotary Encoder auslesen kann?

von Max D. (max_d)


Lesenswert?

https://www.mikrocontroller.net/articles/Drehgeber

statt PHASE_A und PHASE_B nimmst du die Ausgabe deines PCF

von OMG (Gast)


Lesenswert?

TR.OLL schrieb:
> einen rotary Encoder auslesen kann?

Eine Von-hinten-durch-die-Brust-Ins-Auge-Lösung.

Zu träge bzw. zu viel Last für den Prozessor.

von Manfred (Gast)


Lesenswert?

TR.OLL schrieb:
> einen rotary Encoder auslesen kann

TROLL am Freitag, sein Name ist Programm!

Einen Drehencoder an einen I2C-Baustein hängen zu wollen klingt einfach 
nur dämlich.

von TR.OLL (Gast)


Lesenswert?

OMG schrieb:
> TR.OLL schrieb:
>> einen rotary Encoder auslesen kann?
>
> Eine Von-hinten-durch-die-Brust-Ins-Auge-Lösung.
>
> Zu träge bzw. zu viel Last für den Prozessor.

Ich nutze den Interrupt des PCF8574,  deswegen sollte ich keine Probleme 
mit der hohen Last des Prozessors haben, weil ich den PCF8574 immer dann 
auslese, wenn der InterruptPin auf LOW ist.

von pegel (Gast)


Lesenswert?


von TR.OLL (Gast)


Lesenswert?

pegel schrieb:
> Die Suche liefert einiges. Z.B.:
>
> 
https://www.thecoderscorner.com/products/arduino-libraries/io-abstraction/rotary-encoder-switches-interrupt-pcf8574/

Ich habe diese Library schon ausprobiert. Aber erfolglos...

von Joachim B. (jar)


Lesenswert?

Manfred schrieb:
> TROLL am Freitag, sein Name ist Programm!

weiss gerade nicht wer trollt,
Ich kann jedenfalls im 1ms Raster im IRQ einen Encoder lesen ohne 
Probleme.
Auch einen PCF8574 der braucht nur µs, bei 400kHz die der 8574 auch noch 
schafft evtl. 100µs.

OMG schrieb:
> Zu träge bzw. zu viel Last für den Prozessor.

mag sein, ohne Pollen gehts ja auch

TR.OLL schrieb:
> Ich nutze den Interrupt des PCF8574,

egal kann klappen, muss aber nicht.

von pegel (Gast)


Lesenswert?

TR.OLL schrieb:
> ausprobiert. Aber erfolglos

Deshalb bin ich kein Ardu*-Fanboy.

von MaWin (Gast)


Lesenswert?

TR.OLL schrieb:
> Ich nutze den Interrupt des PCF8574,

Wozu ?

Ein Drehencoder wird in zeitlich festem Raster ausgelesen, da hilft ein 
Interrupt genau gar nichts.

http://dse-faq.elektronik-kompendium.de/dse-faq.htm#F.29

Doch ein typischer TR.OLL, fachlich auf dem Holzweg.

Nein, für Arduino kenne ich nichts vorgefertigtes, ich programmiere noch 
an statt shields zusammenzuklicken.

von Beo Bachta (Gast)


Lesenswert?

MaWin schrieb:
> Ein Drehencoder wird in zeitlich festem Raster ausgelesen, da hilft ein
> Interrupt genau gar nichts.

Dein Absolutismus grenzt an Grössenwahn.

Du kannst schreiben dass du es so machen würdest, aber es "wird"
nicht generell so gemacht.

Insbesondere macht es keinen Sinn einen Drehencoder dauernd
abzufragen wenn dort gar nichts passiert.

von MaWin (Gast)


Lesenswert?

Beo Bachta schrieb:
> Dein Absolutismus grenzt an Grössenwahn

Mein Grössenwahn besteht ausschliesslich darin, dass ich für eine 
Schraube einen Schraubendreher verwende.

Du einen Hammer.

Das ist blöd, wenn man nur einen Hammer hat, überall nur Nägel zu sehen. 
Eine genagelte Schraube mag schneller drin sein, hält aber nicht.

Ein pin change interrupt ausgelesener Drehencoder funktioniert genau so 
wenig.

Beo Bachta schrieb:
> Insbesondere macht es keinen Sinn einen Drehencoder dauernd
> abzufragen wenn dort gar nichts passiert

Was bitte soll der Prozessor denn sonst tun, wenn sich am Drehencoder 
nichts tut ? Er kann nichts sinnvolles tun, denn er muss jederzeit die 
Rechenzeit übrig haben, um ein plötzliches Drehen doch auswerten zu 
können.  Dann kann ef sie gleich dauerhaft dafür einsetzen statt dumm 
rum zu warten.

Du hast also wirklich auf dämlichste Art getrollt. Nun schlaf deinen 
Rausch aus.

von Beo Bachta (Gast)


Lesenswert?

MaWin schrieb:
> Ein pin change interrupt ausgelesener Drehencoder funktioniert genau so
> wenig.

Dann bin ich ein echter Wunderheiler. Denn meine Pin Change IRQ
Programmierung funktioniert "seltsamerweise". Wunder gibt es
immer wieder (Katja Ebstein).

MaWin schrieb:
> Du hast also wirklich auf dämlichste Art getrollt.

Du reihst dich übrigens nahtlos in die übrigen Dämlichmacher
hier im Forum ein. Leider hilft das Vorhalten eines Spiegels
bei dir gar nichts mehr, da ist Hopfen und Malz verloren.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Naja, diese ewige Diskussion wird den TE nicht weiterbringen. Ich würde 
ja empfehlen, die Wire Library erstmal so zum Laufen zu brigen, das der 
PCF erkannt und ausgelesen werden kann. Dann kann man sich immer noch 
überlegen, welche Strategie hier die sinnvollere ist.
Denn zuerst muss ja I²C laufen, bevor es weitergeht.

von MaWin (Gast)


Lesenswert?

Beo Bachta schrieb:
> Denn meine Pin Change IRQ
> Programmierung funktioniert "seltsamerweise".

Genau so gut wie die in vielem kommerziellen Geräten deren Entwickler 
genau so arrogant dumm waren wie du es bist und die die Kunden damit zur 
Weissglut bringen weil der Knopf nicht so spurt wie sie erwarten.

Merke: Verfahren, die schon in der Theorie ihre Schwächen zeigen und 
nicht funktionieren, funktionieren in der Praxis erst recht nicht, 
selbst wenn beim Entwicklertest erst alles ok erscheint.


Beo Bachta schrieb:
> Du reihst dich übrigens nahtlos in die übrigen Dämlichmacher

Alles Geisterfahrer. Dabei ist das Thema hinreichend durchdiskutiert, du 
hättest nur mal zuhören müssen.

von Stefan F. (Gast)


Lesenswert?

TR.OLL schrieb:
> weil ich den PCF8574 immer dann
> auslese, wenn der InterruptPin auf LOW ist.

Tust du nicht, zwischen dem Signal und dem Auslesen vergeht signifikant 
Zeit - genau das wird Dein Problem werden.

Joachim B. schrieb:
> Auch einen PCF8574 der braucht nur µs, bei 400kHz die der 8574 auch noch
> schafft evtl. 100µs.

Sonst hat dein µC nichts anderes zu tun? Dann kann das klappen.

von Peter D. (peda)


Lesenswert?

Manfred schrieb:
> Einen Drehencoder an einen I2C-Baustein hängen zu wollen klingt einfach
> nur dämlich.

Warum denn?
Für Handbetrieb überhaupt kein Problem.
Das I2C sollte dafür allerdings als Interrupt erfolgen, damit die 
CPU-Last gering ist.

Ich würde jedoch SPI mit 74HC165 bevorzugen. Mit der UART als SPI-Master 
(AVR) kann man so je Interrupt 2 Stück 74HC165 auslesen, d.h. 8 Encoder, 
bzw. 5 Encoder mit Taste.

von Joachim B. (jar)


Lesenswert?

Stefan ⛄ F. schrieb:
> Joachim B. schrieb:
>> Auch einen PCF8574 der braucht nur µs, bei 400kHz die der 8574 auch noch
>> schafft evtl. 100µs.
>
> Sonst hat dein µC nichts anderes zu tun? Dann kann das klappen.

ja, so viel RAM hat der nano ja nicht und deswegen hat er viel Zeit, ich 
benutze den ja nicht wenn ich office starten will und für kleine Anzeige 
von Uhrzeit, Temperatur, Feuchtigkeit in den Zimmern hat er ja sonst 
nichts zu tun.
In der wordclock12h hat er auch noch Zeit IR entgegenzunehmen, Uhr zu 
lesen, 114 WS anzusteuern und DCF77 auszuwerten.
Was soll er noch machen, viel Pause.

von Stefan F. (Gast)


Lesenswert?

Joachim B. schrieb:
> deswegen hat er viel Zeit ... in der wordclock12h

Ja das wird das wohl kein Problem sein. Wer es schafft, einen µC mit so 
einer Anwendung auszulasten, hat ganz andere Probleme.

von TR.OLL (Gast)


Lesenswert?

Matthias S. schrieb:
> Dann kann man sich immer noch
> überlegen, welche Strategie hier die sinnvollere ist.
> Denn zuerst muss ja I²C laufen, bevor es weitergeht.

Das I2C geht schon und den PCF8574 kann ich ansprechen

von TR.OLL (Gast)


Lesenswert?

Auslesen kann ich die Daten von einem Inkrementaldrehgeber jetzt aber es 
fehlt noch der Teil, der auswertet in welche Richtung der 
Quadraturencoder gedreht worden ist.

Code der nicht geht:
1
  if(di.p1 == true){
2
      button_last_pressed = 1;
3
    }
4
     if(di.p3 == true){
5
      button_last_pressed = 4;
6
    }
7
  /*   if(di.p2 == true){
8
      button_last_pressed = 3;
9
    }
10
     if(di.p3 == true){
11
      button_last_pressed = 4;
12
    }*/
13
    changed = false;
14
    Serial.println(button_last_pressed);
15
/*
16
     encoderPinANow = di.p2;
17
     if ((encoderPinALast == HIGH) && (encoderPinANow == LOW)) {
18
      if (di.p1 == HIGH) {
19
       button_last_pressed = 3;
20
       Serial.println("up");
21
      } else {
22
        button_last_pressed = 2;
23
        Serial.println("down");
24
      }
25
  }
26
  encoderPinALast = encoderPinANow;
27
*/
28
  encoderPinANow = di.p2;
29
  if(encoderPinANow == HIGH && encoderPinALast == LOW){
30
    if(di.p1 == LOW){
31
      button_last_pressed = 3;
32
      Serial.println("up");
33
    }
34
    if(di.p1 == HIGH){
35
      button_last_pressed = 2;
36
      Serial.println("down");
37
    }
38
  }
39
 if(encoderPinANow == LOW && encoderPinALast == HIGH){
40
    if(di.p1 == HIGH){
41
      //button_last_pressed = 3;
42
      Serial.println("up");
43
    }
44
    if(di.p1 == LOW){
45
      //button_last_pressed = 2;
46
      Serial.println("down");
47
    }
48
  }
49
  encoderPinALast = encoderPinANow;

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

TR.OLL schrieb:
> Code der nicht geht:
Wundert mich nicht, dass der Compiler da nichts Brauchbares 
herausbekommt....

> Auslesen kann ich die Daten von einem Inkrementaldrehgeber jetzt
Du kannst also eine Positionvariable (nennen wir sie mal pakt für 
Position_Aktuell) hoch und runterzählen?
> aber es fehlt noch der Teil, der auswertet in welche Richtung der
> Quadraturencoder gedreht worden ist.
Dann geht das Auswerten der Drehrichtung dr mit Hilfe einer vorher 
gespeicherten "alten" Position palt etwa so:
1
enum {STILLSTAND, HOCH, RUNTER} dr;
2
:
3
:
4
dr = STILLSTAND;
5
if pakt > palt then dr = HOCH;
6
if pakt < palt then dr = RUNTER; 
7
palt = pakt;
Diese Zeilen kommen geschickterweise direkt nach der Gebeauswertung.

: Bearbeitet durch Moderator
von MaWin (Gast)


Lesenswert?

TR.OLL schrieb:
> Code der nicht geht

Du hast offenbar in di die Anschlüsse A und B des Encoders.

Dein Code wertet bei Flankenwechsel von A die Spur B aus und wandelt das 
in einen Tastendruck up oder down um.
Warum zum Schluss auskommentiert, weiss der Geier

Diese Methode des Flankenwechsels funktioniert nicht, wie schon 
geschrieben. Das Prellen beim übergang produziert dutzende Tastendrücke.

Warum glaubst du den Code unbedingt selbst noch mal falsch entwerfen zu 
müssen, an statt einfach bekannt funktionierende Beispiele abzuschreiben 
?

Ja, wenn man JEDE Position des Drehencoders nutzen will, gibt es 
heftiges Geflatter an den Übergängen. Daher haben die meisten Encoder 2 
Übergänge zwischen den Rastpositionen.

Nutzt man nur jede 2. Position, kann man nämlich up/down ohne Geflatter 
erzeugen.

http://dse-faq.elektronik-kompendium.de/dse-faq.htm#F.29
1
  int table[4][4]={{0,1,0,0},{0,0,0,0},{0,0,0,-1},{0,0,0,0}}; 
2
3
  new_quadrature_value=di.p1+2*di.p2;
4
  switch(table[last_quadrature_value][new_quadrature_value])
5
  {
6
  case 1:
7
     // up
8
     break;
9
  case -1:
10
     // down
11
     break;
12
  }
13
  last_quadrature_value=new_quadrature_value;

von TR.OLL (Gast)


Lesenswert?

Jetzt geht der Code.

Danke für die Hinweise!

von TR.OLL (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe jetzt aber noch folgendes Problem:

Wenn ich den PCF8574 über auslese zeigt das LCD2004 (mit I2C) zufällige 
Zeichen an (siehe Bild als Anhang). Kennt jemand eine Lösung für das 
Problem?

Danke im Vorraus.

von Tippgeber (Gast)


Lesenswert?

TR.OLL schrieb:
> Wenn ich den PCF8574 über auslese

Ich rate: Du hast zwei PCF8574 mit derselben Adresse.

von TR.OLL (Gast)


Lesenswert?

Tippgeber schrieb:
> TR.OLL schrieb:
>> Wenn ich den PCF8574 über auslese
>
> Ich rate: Du hast zwei PCF8574 mit derselben Adresse.

Nein, der PCF8574 der den Encoder ausliest hat die Adresse 0x20 und der 
PCF8574 am Display hat die Adresse 0x3F.

von spess53 (Gast)


Lesenswert?

Hi

>Wenn ich den PCF8574 über auslese zeigt das LCD2004 (mit I2C) zufällige
>Zeichen an (siehe Bild als Anhang). Kennt jemand eine Lösung für das
>Problem?

Wahrscheinlich benutzen beide PCF8574 die gleiche Adresse. Also must du 
einen über A0..2 eine neue Adresse geben.

MfG Spess

von John Doe (Gast)


Lesenswert?

Und da schreib nochmal einer, die ARM Cortex-M3/4/7 wären so 
kompliziert.
Auf nem STM32 schreibe ich eine Handvoll Config-Bits und kann dann schön 
das Zähler-Register auslesen - Interrupt geht natürlich auch. Alles in 
Hardware.
Einfacher geht es nicht.
Spart übrigens auch externe Bausteine...

von TR.OLL (Gast)


Lesenswert?

John Doe schrieb:
> Und da schreib nochmal einer, die ARM Cortex-M3/4/7 wären so
> kompliziert.
> Auf nem STM32 schreibe ich eine Handvoll Config-Bits und kann dann schön
> das Zähler-Register auslesen - Interrupt geht natürlich auch. Alles in
> Hardware.
> Einfacher geht es nicht.
> Spart übrigens auch externe Bausteine...

Und was hat das mit der eigentlichen Frage zutun?



spess53 schrieb:
> Hi
>
>>Wenn ich den PCF8574 über auslese zeigt das LCD2004 (mit I2C) zufällige
>>Zeichen an (siehe Bild als Anhang). Kennt jemand eine Lösung für das
>>Problem?
>
> Wahrscheinlich benutzen beide PCF8574 die gleiche Adresse. Also must du
> einen über A0..2 eine neue Adresse geben.
>
> MfG Spess

Die haben unterschiedliche Adressen.

von Tippgeber (Gast)


Lesenswert?

TR.OLL schrieb:
> Nein, der PCF8574 der den Encoder ausliest hat die Adresse 0x20 und der
> PCF8574 am Display hat die Adresse 0x3F.

Dann liegt der Fehler in Deiner Software.

von TR.OLL (Gast)


Lesenswert?

Tippgeber schrieb:
> TR.OLL schrieb:
>> Nein, der PCF8574 der den Encoder ausliest hat die Adresse 0x20 und der
>> PCF8574 am Display hat die Adresse 0x3F.
>
> Dann liegt der Fehler in Deiner Software.

Ja, aber wo?

von Axel S. (a-za-z0-9)


Lesenswert?

TR.OLL schrieb:
> Tippgeber schrieb:
>>
>> Dann liegt der Fehler in Deiner Software.
>
> Ja, aber wo?

In Zeile 42. Wie immer.

von TR.OLL (Gast)


Lesenswert?

Axel S. schrieb:
> TR.OLL schrieb:
>> Tippgeber schrieb:
>>>
>>> Dann liegt der Fehler in Deiner Software.
>>
>> Ja, aber wo?
>
> In Zeile 42. Wie immer.

Jetzt stellt sich nur die Frage in welcher Datei?

von m.n. (Gast)


Lesenswert?

TR.OLL schrieb:
> Wenn ich den PCF8574 über auslese zeigt das LCD2004 (mit I2C) zufällige
> Zeichen an (siehe Bild als Anhang). Kennt jemand eine Lösung für das
> Problem?

Wenn Du den 8574 durch einen ATtiny25 ersetzt, hast Du nicht nur das 
Problem mit der IIC-Adressierung gelöst: 
Beitrag "mini Quadraturdekoder + 32 Bit Zähler + TWI, Attiny25"
Probiere es doch einfach aus.

von Renzo M. (renzo_m)


Lesenswert?


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
Noch kein Account? Hier anmelden.