Forum: Mikrocontroller und Digitale Elektronik Drehgeber auslesen, zu einfach gelöst?


von Dave C. (dave_chappelle)


Lesenswert?

Hi Zusammen

Neues Jahr, neue Fragen :)

Ich habe mich hier ein wenig erkundigt bezüglich Drehgeber auslesen, 
habe mich dann aber entschieden mir selber etwas zu überlgen.

Allerdings ist der Code recht knapp geworden und wenn ich so vergleiche 
mit Codebeispielen, kommt mir meine Lösung etwas provisorisch vor.

Der Code funktioniert meiner Meinung nach einwandfrei, die gewünschte 
Funktion wird vollauf erfüllt. Da ich aber in späteren Projekten gerne 
den gleichen Code verwenden will, wollte ich hier mal den Code posten um 
zu sehen ob vielleicht jemand eine potenzielle Fehlerquelle darin 
entdeckt.
1
int bla = 0;  //Variable zur Zeitverzogerung
2
3
    if (forw)  //Drehgeber rechts drehen
4
    {
5
    if (rechts < 128){    
6
    rechts ++;       }
7
    while (forw || backw){
8
                   bla ++;
9
                   bla --;
10
                         }
11
    }
12
    
13
14
15
    if (backw)  //Drehgeber links drehen
16
    {
17
    if (rechts > 0){
18
    rechts--;      } 
19
    while (backw || forw){
20
                   bla ++;
21
                   bla --;
22
                         }
23
    }

Es soll einfach eine Variable rauf und runtergezählt werden (in diesem 
Falle die Variable "rechts").
Auf Interrupt habe ich verzichtet, forw und backw sind einfach die Pins, 
an die der Drehgeber angeschlossen ist.

Ich freue mich auch eure Inputs und Verbesserungsvorschläge.

MFG
Dave

von Karl H. (kbuchegg)


Lesenswert?

Was hast du denn für Drehgeber?

Normalerweise wechseln die Pins ihren Zustand von einer Rastung zur 
nächsten nicht von 00 (über 01, 11, 10 ) wieder zu 00.

D.h. dein Code hängt hier
1
    while (backw || forw){
in der Schleife fest, bis sich der Benutzer dazu entschliesst, dann doch 
bis zur nächsten Rastung weiterzudrehen. Alles was dann nicht über 
Interrupts in deinem Programm gelöst ist (also alles was etwas länger 
dauern wird, wie zb UART AUsgaben, LCD Ausgaben, aufwändigere 
Berechnungen etc) steht dann solange.

Was ist an den bewährten dokumentierten Lösungen falsch, dass du sie 
nicht benutzen willst?

von Dave C. (dave_chappelle)


Lesenswert?

Achso, das habe ich vergessen zu erwähnen.
Ein hängen in dieser Schleife ist (sofern kein Defekt vorliegt) nicht 
möglich, da der Drehgeber nur kurze Impulse gibt, sprich nicht im high 
Zustand hängen bleibt.

Karl Heinz Buchegger schrieb:
> Was ist an den bewährten dokumentierten Lösungen falsch, dass du sie
> nicht benutzen willst?

Falsch ist meines Erachtens nach nichts, aber ich wollte einfach selber 
was ausprobieren, da ich noch in der Ausbildung bin. Der Weg ist das 
Ziel :)

von Falk B. (falk)


Lesenswert?

@  Dave Chappelle (dave_chappelle)

>Ich habe mich hier ein wenig erkundigt bezüglich Drehgeber auslesen,
>habe mich dann aber entschieden mir selber etwas zu überlgen.

Also das Rad neu erfinden, nur sechseckig?

>Allerdings ist der Code recht knapp geworden und wenn ich so vergleiche
>mit Codebeispielen, kommt mir meine Lösung etwas provisorisch vor.

Ist sie auch.

>Der Code funktioniert meiner Meinung nach einwandfrei,

Meinungen gibt es wie Sand am Meer.
Einen WASSERDICHTEN NACHWEIS selten.

>zu sehen ob vielleicht jemand eine potenzielle Fehlerquelle darin
>entdeckt.

Ich hab keine Lust auf dei hunderttausendste Erklärung. Kurz, dein Code 
taugt nix.

>Ein hängen in dieser Schleife ist (sofern kein Defekt vorliegt) nicht
>möglich,

Schöner Satz . . .

> da der Drehgeber nur kurze Impulse gibt, sprich nicht im high
> Zustand hängen bleibt.

Komischer Drehgeber, wahrscheinlich flasch angschlossen oder defekt. 
Oder ein Missverständniss deinerseits, was mir am wahrscheinlichsten 
ist.

>Falsch ist meines Erachtens nach nichts, aber ich wollte einfach selber
>was ausprobieren, da ich noch in der Ausbildung bin.

Prinzipiell richtig, aber nicht wenn es um Grundlagen geht. Die kann 
keiner besser machen. Die sollte man studieren und VERSTEHEN. Dann kann 
man vielleicht was besser machen.

MFG
Falk

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wenn dein Drehgeber einer von der Sorte ist, die Vorwärts-/Rückwärts-
impulse ausgeben (sehr selten), stimmt deine Lösung prinzipiell,
allerdings fehlt eine Entprellung.

Die allermeisten Drehgeber liefern aber nicht direkt die Vorwärts-/Rück-
wärtsimpulse, sondern zwei Rechtecksignale, die unabhängig von der Dreh-
richtung beide phasenversetzt ausgegeben werden. Aus der Reihenfolge
der steigenden bzw. fallenden Flanken beider Signale wird per Software
die Drehrichtung ermittelt. Diese Drehgeber funktionieren — die richtige
Auswertung vorausgesetzt — zuverlässiger. Diejenigen mit Vorwärts-/Rück-
wärtsimpulsen haben prinzipbedingt Schwierigkeiten, wenn der Drehgeber
langsam und mit zitternden Händen von einer Position in die nächste
gedreht werden. Da wird schnell mal eine Raste mehrfach gezählt.

Nimm einen "normalen" Drehgeber, dann hast du dieses Problem nicht, und
du kannst fertigen und getesteten Auswertecode verwenden.

von MaWin (Gast)


Lesenswert?

> Der Code funktioniert meiner Meinung nach einwandfrei

Meiner Meinung nach funktioniert er gar nicht.
Es gibt keine Schleife, nach ein mal forw und
ein mal backw ist der code durchgelaufen und
wird nie wieder ausgeführt. Du hast absichtlich
wichtigen Code drumrum weggelassen, und somit
unterliegt die Verwendung des Codes der Beliebigkeit,
und somit kann er auch falsch verwendet werde.

> jemand eine potenzielle Fehlerquelle darin entdeckt.

Zeitverzögerung ist in Programmen prinzipiell immer schlecht,
im Ergebnis kaufen sich Leute ständig schnellere Prozessoren.

Dein "Drehgeber" ist wie schon die anderen geschrieben haben
offenbar exotisch, er enthält eigentlich schon die
Encoder-Auswertung aus gray-code die forw/backw Impulse zu
formen, und liefert hoffentlich diese Impuls auch entprellt
ab, denn sonst funktioniert dein code eh nicht,
also kein Wunder daß dein Programm keinen wichtigen code
mehr besitzt, es wurde schon alles von der Hardware getan.

Vielleicht hast du deinen Encoder aber auch einfach nur
falsch verstanden.

von Achim M. (minifloat)


Lesenswert?

Poste doch mal deinen gesamten Code. Also wo wird denn dein oben 
abgebildeter Code ausgeführt?

Einen Encoder kann man sich als Statemachine vorstellen. Es gibt vier 
verschiedene Zustände. Nun würde ich die Zustandsübergänge ansehen.
Nun muss, es wie bei einem Mealy-Automaten ist, eine Ausgabe während der 
Zustandsänderung erfolgen. Aus der Folge der Zustände schließt du dann 
auf die Drehrichtung.

Zustandsänderungen gibt es vier:
1
   1 2 3 4 ...usw...
2
   | | | |
3
   V V V V
4
      ___     ___
5
A ___|   |___|    ...usw...
6
    ___     ___
7
B _|   |___|   |_ ...usw...
Links- oder Rechtsherum wird nur durch die Abfolge der Zustände 
definiert.

Um eine Änderung zu erfassen, kann man z.B. so vorgehen:
1
//connections of User Interface
2
#define UI_PORT PORTB
3
#define UI_DDR  DDRB
4
#define UI_PIN  PINB
5
6
#define ENC_A   PB0
7
#define ENC_B   PB1
8
9
//variables for encoder
10
uint8_t ui_oldstate;
11
12
inline void ui_init(void)
13
{
14
   UI_PORT = (1<<ENC_A)|(1<<ENC_B);
15
   ui_oldstate = UI_PIN & ( (1<<ENC_A)|(1<<ENC_B) );
16
}
17
18
int8_t encoder(void)
19
{
20
   //prepare some stuff
21
   uint8_t newstate = UI_PIN      & ( (1<<ENC_A)|(1<<ENC_B) );
22
   uint8_t oldstate = ui_oldstate & ( (1<<ENC_A)|(1<<ENC_B) );
23
   uint16_t buffer = (newstate << 8) | oldstate;
24
   int8_t rtnval;
25
   
26
   //eight cases of interest
27
   switch (buffer)
28
   {
29
      //clockwise
30
      //       new A        new B              old A      old B
31
      case (( (256<<ENC_A)|(  0<<ENC_B) ) | ( (0<<ENC_A)|(0<<ENC_B) )):
32
      case (( (256<<ENC_A)|(256<<ENC_B) ) | ( (1<<ENC_A)|(0<<ENC_B) )):
33
      case (( (  0<<ENC_A)|(256<<ENC_B) ) | ( (1<<ENC_A)|(1<<ENC_B) )):
34
      case (( (  0<<ENC_A)|(  0<<ENC_B) ) | ( (0<<ENC_A)|(1<<ENC_B) )):
35
         rtnval = -1;
36
         break;
37
      
38
      //counter-clockwise
39
      //       new A        new B              old A      old B
40
      case (( (  0<<ENC_A)|(256<<ENC_B) ) | ( (0<<ENC_A)|(0<<ENC_B) )):
41
      case (( (256<<ENC_A)|(256<<ENC_B) ) | ( (0<<ENC_A)|(1<<ENC_B) )):
42
      case (( (256<<ENC_A)|(  0<<ENC_B) ) | ( (1<<ENC_A)|(1<<ENC_B) )):
43
      case (( (  0<<ENC_A)|(  0<<ENC_B) ) | ( (1<<ENC_A)|(0<<ENC_B) )):
44
         rtnval = 1;
45
         break;
46
         
47
      default:
48
         rtnval = 0;
49
         break;
50
   }
51
   
52
   //tidy up
53
   //erase encoder bits
54
   ui_oldstate &= ~( (1<<ENC_A)|(1<<ENC_B) );
55
   //set current bits
56
   ui_oldstate |= newstate & ((1<<ENC_A)|(1<<ENC_B));
57
   
58
   return(rtnval);
59
}

Jedesmal, wenn man den Encoder ausliest(das kann man auch in einen 
Pinchange-Interrupt packen, dann aber die Statusvariable ui_oldstate 
volatile machen, Masken setzen etc.) addiert man den Rückgabewert der 
Funktion auf seine zu modifizierende Variable.
1
uint8_t meine_mod_variable = encoder();

Über Entprellung musste ich mir bei dem obigen Code keine Gedanken 
machen, da der meinige Encoder das schon eingebaut hatte.

Wenn der Encoder mehr Flankenwechsel pro Rastung liefert, kann man das 
in eine zweite Funktion rein tun, die eben geeignet herunterteilt.
1
int8_t encoder_fourstep(void)
2
{
3
   static int8_t enc_state = 0;   
4
5
   enc_state += encoder();
6
   
7
   if (enc_state <= -4)
8
   {
9
      enc_state += 4;
10
      return(-1);
11
   }
12
   
13
   if (enc_state >= 4)
14
   {
15
      enc_state -= 4;
16
      return(1);
17
   }
18
   
19
   return(0);
20
}
mfg mf

von Karl H. (kbuchegg)


Lesenswert?

MaWin schrieb:

> Dein "Drehgeber" ist wie schon die anderen geschrieben haben
> offenbar exotisch, er enthält eigentlich schon die
> Encoder-Auswertung aus gray-code die forw/backw Impulse zu
> formen, und liefert hoffentlich diese Impuls auch entprellt
> ab, denn sonst funktioniert dein code eh nicht,

Ich hab auch so ein Teil, welches tatsächlich Pulse liefert (konnte das 
am Anfang gar nicht glauben bis mir das eine LED gezeigt hat). Es ist 
ein Alps Drehgeber.
Das Problem war dann: Dreht man den Drehgeber eben nicht bis zur 
nächsten Rastung durch sondern 'ruckelt' am Knopf in der Rastposition 
ein wenig rumm, kann man den ganz toll zum Zählen bringen. Der Puls 
kommt und der Benutzer lässt den Knopf aus der minimalen Auslenkung 
wieder in die Rastposition zurückfallen. Eigentlich sollte dann meinem 
Verständnis nach nix gezählt werden. Wird es aber, wenn man es so macht 
wie der TO.

von Dave C. (dave_chappelle)


Lesenswert?

Oke, ich glaube nicht, dass jemand das so verstanden hat wie ich es 
gemeint habe.

Der Drehgeber gibt natürlich immer 2 Signale aus. Und natürlich sind 
auch diese Signale verschoben. Nur bleibt der Encoder einfach nicht im 
High Zustand.

Beispiel ich drehe rechts bis zur ersten Einrasterung:
1
Pin1  _ _ _ - - - _ _ _ 
2
3
Pin2  _ _ _ _ - - - _ _ _

Falk Brunner schrieb:
> Ich hab keine Lust auf dei hunderttausendste Erklärung. Kurz, dein Code
> taugt nix.

Sehe ich nicht so, da er funktioniert.

Falk Brunner schrieb:
> Komischer Drehgeber, wahrscheinlich flasch angschlossen oder defekt.
> Oder ein Missverständniss deinerseits, was mir am wahrscheinlichsten
> ist.

Oder einfach ausserhalb deines Repertoires..

Falk Brunner schrieb:
> Prinzipiell richtig, aber nicht wenn es um Grundlagen geht.

U = R * I ist ne Grundlage.

Yalu X. schrieb:
> allerdings fehlt eine Entprellung.

Da hast du recht, die mache ich aber wahrscheinlich per Hardware, da der 
benötigte IC sowieso schon drauf ist und noch den einen oder anderen 
freien Pin hat.



Ich hoffe ich konnte ein wenig Licht ins Dunkel bringen.


Edit: Habe festgestellt, dass meine Darstellung irgenwie umformatiert 
wurde.
Diese Soll einfach 2 kurze Impulse darstellen, die Phasenverschoben 
sind.

von Karl H. (kbuchegg)


Lesenswert?

Dave Chappelle schrieb:

> Da hast du recht, die mache ich aber wahrscheinlich per Hardware, da der
> benötigte IC sowieso schon drauf ist und noch den einen oder anderen
> freien Pin hat.

Brauchst du nicht, wenn du die Software-Auswertung richtig machst. Die 
Port Abfolge muss 00 01 11 10 00 sein, wenn gedreht wird (bzw. in der 
anderen Reihenfolge in der anderen Richtung) und nur dann, wenn diese 
Folge durchlaufen wird, gilt das auch als um eine Rastung gedreht. 
Klassischer Fall für zb eine kleine State-Maschine. Prellen ändert daran 
genau gar nichts und wird durch die vorgegebene Reihenfolge automatisch 
eliminiert.

von Dave C. (dave_chappelle)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Klassischer Fall für zb eine kleine State-Maschine.

Oke, das habe ich ehrlich gesagt nicht ganz verstanden. Kannst du das 
etwas genäuer ausführen? Wäre mir natürlich auch recht, wenn ich es per 
Software hinbekommen würde :)

von Achim M. (minifloat)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Prellen ändert daran
> genau gar nichts

Hast ja recht. Zappeln würde bei mir auch durch +1 -1 +1... dargestellt. 
Außerdem ist es ja ein 2bit-Graycode.

Was ich vergaß zu meinem Code zu sagen: es ist bestimmt nicht der 
platzsparendste(Flash und RAM), dafür ist es egal, wo auf einem Port die 
beiden Encoderanschlüsse liegen.
mfg mf

PS: Überschneidung -.-

Dave Chappelle schrieb:
> State-Maschine.
>
> Oke, das habe ich ehrlich gesagt nicht ganz verstanden.

Der zuletzt erfasste Zustand wird in einer Variable zwischengespeichert.

Beim erneuten Durchlauf kann man "alt" mit "neu" vergleichen und daraus 
ggf. Drehrichtung und Zählung ableiten. Eine Statemachine ist erstmal 
ein Rückgekoppelter Zustandsspeicher wie eine Reihe paralleler 
D-Flipflops.
Diese Maschine kann eine Reihe vorher festgelegter Zustände einnehmen.
Eine Zustandsübergangs-Funktion oder -Auswertung gibt den Folgezustand 
an.
Zusätzlich gibt es je nach Definition ein "Eingangs-Schaltnetz" und/oder 
ein "Ausgangs-Schaltnetz", das ist nichts weiter als eine Reihe 
logischer Verknüpfungen, die die Zustandsübergänge und die Ausgabedaten 
beeinflussen und/oder bestimmen können.

von Simon K. (simon) Benutzerseite


Lesenswert?

Dave Chappelle schrieb:
> Falk Brunner schrieb:
>> Ich hab keine Lust auf dei hunderttausendste Erklärung. Kurz, dein Code
>> taugt nix.
>
> Sehe ich nicht so, da er funktioniert.

Wenn die Zuordnung zwischen "funktioniert" und "taugt was" so einfach 
wäre, wären viele Probleme im Alltag gelöst.

Entprellung bei einem Drehgeber in Hardware zu machen ist m.M.n. 
peinlich, da es der beste Hinweis auf eine schlechte Software ist. 
Begründungen wurden ja oben schon aufgeführt.

Versteh uns alle hier nicht falsch: Ich habe auch schon mal ganz am 
Anfang sowas programmiert. Sogar mit Interrupts. Das hat auch 
funktioniert. Aber wenn du mal hier herumschaust (Forum, Artikel 
Drehgeber), wirst du feststellen, dass dies die schlechtmöglichste 
Variante ist, um einen Drehgeber auszulesen.
Ich habe also meine Lektion gelernt (Ich hoffe, du machst es auch in 
diesem Fall) und habe mich nach bewiesen robusterem Code umgesehen und 
da gibt es quasi nur die "Standardlösung" von Peter Dannegger, auf die 
dies zutrifft.

Was ich für mich noch getan habe, ist die PeDa Variante nachvollzogen 
(Das hat ein Weilchen gedauert ;-)) und mit meinen "eigenen Worten" in 
Code umgesetzt.

von Achim M. (minifloat)


Lesenswert?

Das stimmt. PeDa ist nicht einfach durchschaubar aber -wie heißt es so 
schön- "Bulletproof" ;)
mfg mf

von Yalu X. (yalu) (Moderator)


Lesenswert?

Dave Chappelle schrieb:
> Der Drehgeber gibt natürlich immer 2 Signale aus. Und natürlich sind
> auch diese Signale verschoben.

Ok, dann ist es also doch ein hundsgewöhnlicher Drehgeber, was schon mal
sehr gut ist. Die Bezeichungen forw und backw für die Signale sind
vielleicht etwas verwirrend.

> Nur bleibt der Encoder einfach nicht im High Zustand.

D.h. die Rastpunkte liegen an den Stellen, wo beide Signale low sind.

Alles spricht also dafür, die Auswertung so zu machen, wie im Artikel
Drehgeber gezeigt. Wie Karl Heinz schon geschrieben hat, kannst du 
dir
dann die externe Entprellung sparen.

> Sehe ich nicht so, da er funktioniert.

Nein, er funktioniert nicht, wenn du den Drehgeber von einer Raste etwa
eine halbe Rastbreite weiter- und dann wieder zurückdrehst. Obwohl er am
Ende an der gleichen Raste steht, ist der Zähler inkrementiert bzw. de-
krementiert worden.

Selbst wenn das richtig gehandhabt würde, wäre der Mikrocontroller immer
so lange in der Schleife gefangen wie der Drehgeber zwischen zwei Rasten
steht. Wird also der Drehgeber sehr langsam gedreht, gibt es längere
Zeitperioden, in denen der Mikrocontroller für andere Aufgaben nicht zur
Verfügung steht.

von MaWin (Gast)


Lesenswert?

> Der Drehgeber gibt natürlich immer 2 Signale aus. Und natürlich sind
> auch diese Signale verschoben. Nur bleibt der Encoder einfach nicht im
> High Zustand.
> Beispiel ich drehe rechts bis zur ersten Einrasterung:
> Pin1   _ _ - - - _  _
> Pin2   _ _ _ - - - _  _

Wie man erkennen kann, ist es also ein ganz normaler Drehgeber mit gray 
code Ausgang, nur hast du seine Funktion nicht verstanden.

Man behandelt ihn mit normalem Programmcode:
1
  int table[4][4]={{0,1,-1,0},{-1,0,0,1},{1,0,0,-1},{0,-1,1,0}}; 
2
  int position=0; // zaehlen wir mal die absolute Position
3
  volatile int quadrature_input; // bit 0 und bit 1 sind Quadratureingaenge
4
  int new_quadrature_value, last_quadrature_value=quadrature_input;
Folgenden Code ausreichend oft wiederholen (in der Programm Hauptscheife 
oder einer Zeitgeber gesteuerten Interrupt Routine):
1
  new_quadrature_value=quadrature_input;
2
  position+=table[last_quadrature_value][new_quadrature_value]; 
3
  last_quadrature_value=new_quadrature_value;
statt mit deinem ellenlangen Programm welches nicht funktioniert, nicht 
entprellt und nicht richtig arbeitet.

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

von Dave C. (dave_chappelle)


Lesenswert?

Mir war von Anfang an klar, dass der oben gennante Code "Bulletproof" 
ist.
Natürlich war mir auch klar, dass dieser um längen besser ist als mein 
"Bastel". Allerdings stehe ich noch am Anfang des Programmierens, habe 
noch nie mit Interrupts gearbeitet und das war es auch was mich 
abgeschreckt hat.

Mir ist bewusst, dass es immer eine bessere Variante gibt aber wenn ich 
nicht verstehe wie der Code funktioniert, nützt er mir momentan nichts, 
da ich nicht einfach ein Bastler sein will, der Schaltungen und Codes 
zusammenklaubt und einfügt ohne wirklich zu verstehen was da so abgeht.

D.h. ich möchte mich gerne "Hocharbeiten" von meinem Provisorium zum 
Niet- und Nagelfestem Code wie oben beschrieben.

So genug gerechtfertigt ich werde mein Projekt mit meiner Bastelweise 
fertigmachen (da ich eh schon nah am Ende bin) und werde danach mal 
einfachste Aufgaben mit Interrupts und richtigen Delays und all dem 
lösen.

Danke für eure Hilfe bis jetzt, ich melde mich wieder wenn ich in meinem 
weiteren Studium Fragen habe (was ziemlich ziemlich sicher der Fall sein 
wird :))

MFG
Dave

von citb (Gast)


Lesenswert?

Yalu X. schrieb:
>> Nur bleibt der Encoder einfach nicht im High Zustand.
>
> D.h. die Rastpunkte liegen an den Stellen, wo beide Signale low sind.

Solange die Rastung korrekt funktioniert.

citb

von MaWin (Gast)


Lesenswert?

> ich werde mein Projekt mit meiner Bastelweise fertigmachen

Wie nannt man eigentlich die Behinderung ?
Lernresistenz ?

von citb (Gast)


Lesenswert?

Ist aber noch nicht als Berufskrankheit annerkannt.
Meist erfolgt ja in hoeherem Alter eine Heilung von selbst.

citb

von Dave C. (dave_chappelle)


Lesenswert?

MaWin schrieb:
> Wie nannt man eigentlich die Behinderung ?
> Lernresistenz ?

Ich glaube akkute Leseschwäche deinerseits.

von Karl H. (kbuchegg)


Lesenswert?

Dave Chappelle schrieb:

> D.h. ich möchte mich gerne "Hocharbeiten" von meinem Provisorium zum
> Niet- und Nagelfestem Code wie oben beschrieben.

Na, dann analysier den 3 Zeiler. Das Geheimnis liegt im 4*4 Array und 
den Zahlenwerten.

Einfach mal mit angenommen Input Port Werten auf dem Papier 
durchspielen. Du kannst einiges dabei lernen.

von testuser (Gast)


Lesenswert?

Kann jemand hier hier mal erklären wie die Werte von 1 bis 4 aus dem 
Quadratureingang zu Stande kommen für das Array-Feld?

von MaWin (Gast)


Lesenswert?

0 bis 3

00
01
10
11

und dazu der vorhergehende Zustand

00
01
10
11

macht zusammen 4*4 = 16.

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.