Forum: Mikrocontroller und Digitale Elektronik Encoder macht zu viele Schritte


von Sonke A. (soeni)


Angehängte Dateien:

Lesenswert?

Hallo,

ich hab mal wieder ein Problem und zwar benutze ich den Encoder von 
Reichelt mit der Nummer: STEC12E08. Diesen möchte ich zur Menüführung an 
einem ATMEGA128 benutzen. Soweit funktioniert das fast, denn es werden 
meist zwei Impulse pro Rastung gelistet, obwohl ich den Encoder schon 
zig mal unterentprelle. Zuerst hab ich die normale 
Graycodeentschlüsselung:
1
  // Interruptrutine Encoder Abfrage
2
  SIGNAL (SIG_OVERFLOW0){
3
  
4
    static char enc_last = 0x01;
5
    char i = 0;
6
7
    if( PHASE_A )
8
      i = 1;
9
10
    if( PHASE_B )
11
      i ^= 3;          // Graycode in Binär codieren
12
    i -= enc_last;      // Dofferenz zwischen Neuem und Leztem bilden
13
14
    if( i & 1 ){        // bit 0 = value (1)
15
  
16
      enc_last += i;          // Neues als Leztes speichern
17
      enc_delta += (i & 2) - 1;   // bit 1 = Richtung (+/-)
18
    }
19
  }

enc_delta müsste eigentlich schon das Richtige liefern, aber weit 
gefehlt. Meist werden bis zu 5 Impulse pro Rastung losgelassen. (Laut 
Reichelt soll ich einen Encoder mit 24/24 haben, also eine Rastung = ein 
Impuls).

So, nun hab ich das so gemacht, dass ich einfach nach einer bistimmten 
Zeit (0,5 sec oder Länger) die Encodervariable abgefragt habe und wenn 
diese positiv war einen Schitt nach oben gezählt habe und andersherrum.

Hier der Code:
1
  // Funktion zum Encoder abfragen
2
  uint8_t enc_count(uint8_t co){
3
4
  if(enc_delta>0){     // wenn Drehung nach rechts
5
6
    count++;
7
    co++;
8
      
9
  }else if(enc_delta<0){  // wenn Drehung nach links
10
    
11
    count--;
12
    co--;
13
14
  }

So nun konnte ich das soweit eindämmen, dass nunoch maximal 2 Impulse 
kommen. diese Bekomme ich auch bei einer Abfragerate von > 2 sec nicht 
weg, da stimmt doch was nicht oder???

Kann das am Encoder liegen?? ist der zu "Billig??" stimmt was mt der 
Hardware nicht??


Danke schonmal vorweg

PS: rechts der Block das soll der Encoder sein.

von Falk B. (falk)


Lesenswert?

@ Sönke Paschko (soeni)

>ich hab mal wieder ein Problem und zwar benutze ich den Encoder von
>Reichelt mit der Nummer: STEC12E08.

Drehgeber

Dort steht ales drin.

>    if( PHASE_A )
>      i = 1;

>    if( PHASE_B )
>      i ^= 3;          // Graycode in Binär codieren

Unsinnig und falsch. Man muss beide Phasen gleichzeitig erfassen. 
Umrechen in binär ist Unsinn.

MFg
Falk

von Sonke A. (soeni)


Lesenswert?

daher hab ich doch die Rutine für den Encoder hier: 
http://www.mikrocontroller.net/attachment/highlight/1971 hab ich so 
übernommen. Was ist daran falsch?

von Gerd B. (silicat) Benutzerseite


Lesenswert?

Die sicherste, schnellste und beste Methode bei Drehgebern ist immer die 
Auswertung über Zustandswechsel.

Aus PHASE_A und PHASE_B hast Du ja 4 verschiedene Zustaände: 00,01,10 
und 11.
Jetzt stellt man aus den 2 aktuellen Bits und den vorherigen 2 Bits 
einen 4 Bit-Wert zusammen und geht damit in einen 4-Bit=16-Tabelle. Dort 
steht drin, ob eine Drehung nach links oder rechts erfolgte.

Damit hast Du alle Probleme erschlagen. Es gibt kein Doppelzählen oder 
5fach-Zählen.
1
//Auswertung Drehgeber
2
BIT_CHAR tabindex;
3
4
enum DREHGEBER_STATES
5
  {
6
  KEIN_SCHRITT,
7
  SCHRITT_RECHTS,
8
  SCHRITT_LINKS,
9
  SCHRITT_FEHLER
10
  };
11
12
//Tabelle Zustandsänderung->Drehrichtungserkennung
13
const unsigned char Drehgeber_tab[16]={
14
  KEIN_SCHRITT,    // 00->00 keine Änderung 
15
  SCHRITT_RECHTS,  // 00->01 Schritt 1 nach rechts 
16
  SCHRITT_LINKS,   // 00->10 Schritt 1 nach links 
17
  SCHRITT_FEHLER,  // 00->11 Schritt Übersprungen 
18
19
  SCHRITT_LINKS,   // 01->00 Schritt 1 nach links 
20
  KEIN_SCHRITT,    // 01->01 keine Änderung 
21
  SCHRITT_FEHLER,  // 01->10 Schritt Übersprungen 
22
  SCHRITT_RECHTS,  // 01->11 Schritt 1 nach rechts 
23
24
  SCHRITT_RECHTS,  // 10->00 Schritt 1 nach rechts 
25
  SCHRITT_FEHLER,  // 10->01 Schritt Übersprungen 
26
  KEIN_SCHRITT,    // 10->10 keine Änderung 
27
  SCHRITT_LINKS,   // 10->11 Schritt 1 nach links 
28
29
  SCHRITT_FEHLER,  // 11->00 Schritt Übersprungen 
30
  SCHRITT_LINKS,   // 11->01 Schritt 1 nach links 
31
  SCHRITT_RECHTS,  // 11->10 Schritt 1 nach rechts 
32
  KEIN_SCHRITT     // 11->11 keine Änderung 
33
};
34
35
36
void Drehgeber_abfragen(void)
37
{
38
   //Bit 3: letzter   Zustand PHASE_A
39
   //Bit 2: letzter   Zustand PHASE_B
40
   //Bit 1: aktueller Zustand PHASE_A
41
   //Bit 0: aktueller Zustand PHASE_B
42
43
   tabindex._bit._2=tabindex._bit._0;  //letzten Zustand merken
44
   tabindex._bit._3=tabindex._bit._1;  //letzten Zustand merken
45
46
   tabindex._bit._0=PHASE_B;
47
   tabindex._bit._1=PHASE_A;
48
49
50
   switch (Drehgeber_tab[tabindex._byte])//aus vorherigem und aktuellem Phasensignal Drehrichtung erkennen
51
   {
52
      case SCHRITT_RECHTS:
53
      {
54
         position++;
55
         break;
56
      }
57
58
      case SCHRITT_LINKS:
59
      {
60
         position--;
61
         break;
62
      }
63
64
   }
65
}

Gruß, siliCAT

von Sonke A. (soeni)


Lesenswert?

Und diese Funktion rufe ich per Timer Interrupt auf? wenn ja, wie oft?


PS: wenn mein verwendeter Code falsch ist, kann dieser doch aus dem 
Tutorial Drehimpulsgeber gelöscht werden oder?

von Simon K. (simon) Benutzerseite


Lesenswert?

Falk Brunner wrote:
> Dort steht ales drin.
>
>>    if( PHASE_A )
>>      i = 1;
>
>>    if( PHASE_B )
>>      i ^= 3;          // Graycode in Binär codieren
>
> Unsinnig und falsch. Man muss beide Phasen gleichzeitig erfassen.
> Umrechen in binär ist Unsinn.

Das ist ziemlich genau Peter Danneggers Code, wenn ich mich nicht irre.

von Peter D. (peda)


Lesenswert?

Falk Brunner wrote:
> @ Sönke Paschko (soeni)

>>    if( PHASE_A )
>>      i = 1;
>
>>    if( PHASE_B )
>>      i ^= 3;          // Graycode in Binär codieren
>
> Unsinnig und falsch. Man muss beide Phasen gleichzeitig erfassen.
> Umrechen in binär ist Unsinn.

Warum erzählst Du solchen Quatsch?

Versuch doch erstmal den Code zu verstehen.
Man kann sie garnicht gleichzeitig erfassen, da es in der Praxis keine 
exakte Gleichzeitigkeit gibt.

Für den Algorithmus ist es gleichzeitig genug, wenn dazwischen keine 2 
Phasenwechsel auftreten. Außerdem muß der Timerinterrupt schnell genug 
erfolgen, daß zwischen 2 Aufrufen keine 2 Phasenwechsel auftreten.
Dann arbeitet der Algorithmus völlig fehlerfrei.


> Umrechen in binär ist Unsinn.

Natürlich ist das kein Unsinn, sonst hätte ich es ja nicht gemacht.
Wenn man von Binärzahlen die Differenz bildet, ist sie immer richtig, 
auch bei einem Überlauf. Damit habe ich also Richtung und Schrittweite 
der Änderung und kann sie bequem zu dem alten Zählerstand addieren.

Und das trifft auf Graycode eben nicht zu. Daher ist die Umwandlung 
notwendig. Oder ich bräuchte einen erheblich aufwendigeren Code mit 
Tabelle oder vielen if/else.


Peter

von Falk B. (falk)


Lesenswert?

@Sönke Paschko (soeni)

>Und diese Funktion rufe ich per Timer Interrupt auf?

Ja.

> wenn ja, wie oft?

Oft genug. Kommt drauf an wie schnell dein User den Knopf drehen kann. 
Wenn wir mal von 10 U/s ausgehen (schon SEHR schnell), macht das 240 
Codes/s. D.h. du musst mit mind. 240 Hz abtasten, besser mehr.

>PS: wenn mein verwendeter Code falsch ist, kann dieser doch aus dem
>Tutorial Drehimpulsgeber gelöscht werden oder?

Ich durschaue den Trick der Routine im Moment nicht so ganz. Aber sie 
richt mir verdächtig nach Sparvariante. Solide ist auf jeden Fall die 
Auswertung als Graycode, wie im DSE FAQ angegeben.

MFG
Falk

von Sonke A. (soeni)


Lesenswert?

Danke für die Antwort, werds gleich ausprobieren. Leider Meckert der 
Compiler bei BIT_CHAR tabindex; Ich hab mit Tabellen noch nie 
gearbeitet, muss man da noch ne Headerdatei einbinden??

von Peter D. (peda)


Lesenswert?

Sönke Paschko wrote:

> enc_delta müsste eigentlich schon das Richtige liefern, aber weit
> gefehlt. Meist werden bis zu 5 Impulse pro Rastung losgelassen. (Laut
> Reichelt soll ich einen Encoder mit 24/24 haben, also eine Rastung = ein
> Impuls).

Wie wertest Du denn enc_delta aus?
Du mußt es atomar auslesen und löschen, d.h. unter Interruptsperre.

Wenn Du es willkürlich rücksetzt, funktioniert die Entprellung nicht 
mehr.


Peter

von Sonke A. (soeni)


Lesenswert?

zu meinem jetzigen Code, wenn ich die Richtung nicht erfasse (mit meinem 
Rücksezten), wird unaufhörlich in eine Richtung gezählt.

Nüzt es was, wenn ich den gesamten Code poste?? sind mehrere Seiten.

Zum anderen Code, benötigt BIT_CHAR tabindex; irgenwas?? Mein Compiler 
meckert da immer rum und spuckt Fehler.

von Gerd B. (silicat) Benutzerseite


Lesenswert?

1
/*Makro zum Anlegen einer 8-Bit Struktur */
2
struct  BITS_8 {
3
        unsigned char _7:1;
4
        unsigned char _6:1;
5
        unsigned char _5:1;
6
        unsigned char _4:1;
7
        unsigned char _3:1;
8
        unsigned char _2:1;
9
        unsigned char _1:1;
10
        unsigned char _0:1;
11
};
12
13
typedef union    {
14
                   struct BITS_8  _bit  ;
15
                   unsigned char  _byte ;
16
                 } BIT_CHAR ;

je nach Prozessor muss man Bit 0 bis 7 vertauschen.

von Sonke A. (soeni)


Lesenswert?

So jezt geht garnix mehr. Ich poste mal den Code:
Die Initialisierung
1
    // Interruptvorbereitungen
2
    TCCR0 = 1<<CS01;      // divide by 8 * 256
3
      TIMSK = 1<<TOIE0;     // enable timer interrupt
4
5
      
6
  
7
   
8
    DDRD = 0xFF      ;   // PORT D als Ausgang (Notation ist 7,6,5,4,3,2,1,0 also genau umgekert)  
9
    DDRE = 0b00010111;   // PORT C als Ausgang/Eingang
10
11
    sei();         // für Interrupts
12
    beep_short();      // Initialisierung quitten
13
  
14
15
  // LC Display initialisieren
16
  lcd_init();

Die Encodervorbereitung:
1
/*Makro zum Anlegen einer 8-Bit Struktur */
2
struct  BITS_8 {
3
        unsigned char _7:1;
4
        unsigned char _6:1;
5
        unsigned char _5:1;
6
        unsigned char _4:1;
7
        unsigned char _3:1;
8
        unsigned char _2:1;
9
        unsigned char _1:1;
10
        unsigned char _0:1;
11
};
12
13
typedef union    {
14
                   struct BITS_8  _bit  ;
15
                   unsigned char  _byte ;
16
                 } BIT_CHAR ;
17
18
19
//Auswertung Drehgeber
20
BIT_CHAR tabindex;
21
22
enum DREHGEBER_STATES
23
  {
24
  KEIN_SCHRITT,
25
  SCHRITT_RECHTS,
26
  SCHRITT_LINKS,
27
  SCHRITT_FEHLER
28
  };
29
30
//Tabelle Zustandsänderung->Drehrichtungserkennung
31
const unsigned char Drehgeber_tab[16]={
32
  KEIN_SCHRITT,    // 00->00 keine Änderung 
33
  SCHRITT_RECHTS,  // 00->01 Schritt 1 nach rechts 
34
  SCHRITT_LINKS,   // 00->10 Schritt 1 nach links 
35
  SCHRITT_FEHLER,  // 00->11 Schritt Übersprungen 
36
37
  SCHRITT_LINKS,   // 01->00 Schritt 1 nach links 
38
  KEIN_SCHRITT,    // 01->01 keine Änderung 
39
  SCHRITT_FEHLER,  // 01->10 Schritt Übersprungen 
40
  SCHRITT_RECHTS,  // 01->11 Schritt 1 nach rechts 
41
42
  SCHRITT_RECHTS,  // 10->00 Schritt 1 nach rechts 
43
  SCHRITT_FEHLER,  // 10->01 Schritt Übersprungen 
44
  KEIN_SCHRITT,    // 10->10 keine Änderung 
45
  SCHRITT_LINKS,   // 10->11 Schritt 1 nach links 
46
47
  SCHRITT_FEHLER,  // 11->00 Schritt Übersprungen 
48
  SCHRITT_LINKS,   // 11->01 Schritt 1 nach links 
49
  SCHRITT_RECHTS,  // 11->10 Schritt 1 nach rechts 
50
  KEIN_SCHRITT     // 11->11 keine Änderung 
51
};
52
53
54
  // Funktion zum Encoder abfragen
55
  uint8_t enc_count(uint8_t co){
56
57
  if(enc_delta>0){     // wenn Drehung nach rechts
58
59
    count++;
60
    co++;
61
      
62
  }else if(enc_delta<0){  // wenn Drehung nach links
63
    
64
    count--;
65
    co--;
66
67
  }
68
69
  //enc_delta=0; // Speicher zurücksetzen
70
71
  return enc_delta;
72
  }

Inclusive meiner abgeänderten Abfragerutine

Und die Interrupstrutine
1
 SIGNAL (SIG_OVERFLOW0){
2
  
3
     //Bit 3: letzter   Zustand PHASE_A
4
   //Bit 2: letzter   Zustand PHASE_B
5
   //Bit 1: aktueller Zustand PHASE_A
6
   //Bit 0: aktueller Zustand PHASE_B
7
8
   tabindex._bit._2=tabindex._bit._0;  //letzten Zustand merken
9
   tabindex._bit._3=tabindex._bit._1;  //letzten Zustand merken
10
11
   tabindex._bit._0=PHASE_B;
12
   tabindex._bit._1=PHASE_A;
13
14
15
   switch (Drehgeber_tab[tabindex._byte])//aus vorherigem und aktuellem Phasensignal Drehrichtung erkennen
16
   {
17
      case SCHRITT_RECHTS:
18
      {
19
         enc_delta++;
20
         break;
21
      }
22
23
      case SCHRITT_LINKS:
24
      {
25
         enc_delta--;
26
         break;
27
      }
28
29
   }
30
}

von 123 (Gast)


Lesenswert?

Wo hast du denn PHASE_B und PHASE_A definiert?

von Gerd B. (silicat) Benutzerseite


Lesenswert?

Dreh auch mal die Reihenfolge in der BITS_8 Definition um.
So dass _0 oben und _7 unten ist.

von Sonke A. (soeni)


Lesenswert?

in main.h
1
  // Definitionen für Encoder
2
  #define PHASE_A (PIND & 1<<PIND2)   // PINC.0 für Interrupt Encoder
3
    #define PHASE_B (PIND & 1<<PIND3)   // PINC.1 für Interrupt Encoder
4
  #define ENCODERTAST PIND & (1<<PIND5) // Taster Encoder

von Sonke A. (soeni)


Lesenswert?

Das mit dem Umdrehen hab ich auch schon versucht.
Ist der Code denn OK?

von Peter D. (peda)


Lesenswert?

Falk Brunner wrote:
> Ich durschaue den Trick der Routine im Moment nicht so ganz. Aber sie
> richt mir verdächtig nach Sparvariante.

Sie riecht nicht nur so, sie spart wirklich Zeit und Code gegenüber 
anderen Versionen.

Woran sie allerdings nicht spart, ist an Funktionalität.
Da ein 2Bit-Graycode nur aus 4 Zuständen besteht, kann man das leicht 
nachprüfen.

Der Mehraufwand der Tabellenmethode kommt dadurch zustande, daß sie mehr 
Register benötigt (16Bit Indexberechnung), die der Interrupthandler 
zusätzlich PUSHen/POPen muß.


> Solide ist auf jeden Fall die
> Auswertung als Graycode, wie im DSE FAQ angegeben.

Aber nicht solider als meine Version.


Peter

von Peter D. (peda)


Lesenswert?

Sönke Paschko wrote:
> So jezt geht garnix mehr.

Warum wohl überrascht mich das überhaupt nicht?

Ein Programmierer kann den Fehlern nicht davonlaufen, er muß sie finden.

Gib doch einfach mal die Pins wieder auf LEDs aus und drehe langsam, ob 
alle 4 Phasen zu sehen sind.
Viele Leute schließen die Encoder einfach nur falsch an.


> Ich poste mal den Code:

Dann aber als Anhang und nicht scheibchenweise, sondern so, daß die 
Funktion auch compilierbar ist.


Peter

von Falk B. (falk)


Lesenswert?

@  Peter Dannegger (peda)

>> Solide ist auf jeden Fall die
>> Auswertung als Graycode, wie im DSE FAQ angegeben.

>Aber nicht solider als meine Version.

OK, du hast Recht. Ich hab mir die Routine nochmal in Ruhe angesehen, 
sollte wasserdicht sein. Clever gemacht!

MFg
Falk

von Sonke A. (soeni)


Lesenswert?

Tut mir leid, aber ich komm gerade garnicht klar. Ich hab das besagte 
Problem, dass mein Encoder nicht funktioniert. Den zugehörigen Code hab 
ich gepostet, ebenso die Schaltung. Die beiden Pins des Encoders gehen 
auf Interruptpins des atmega128. Wenn es notwendig ist, kann ich den 
gesammten Code posten, leider ist der aber ziemlich groß und würde 
meiner Meinung nach nur verwirren.

Also wass kann ich nun tun, um das Problem zu beheben?
Zum Test mit den LEDs, wie soll das gehen, da sieht man doch nichts, 
dass ist doch zu schnell.

von Falk B. (falk)


Lesenswert?

@ Sönke Paschko (soeni)

>ich gepostet, ebenso die Schaltung. Die beiden Pins des Encoders gehen
>auf Interruptpins des atmega128.

Ist unnötig, geht mit jedem X-beliebigen Pin.

>gesammten Code posten, leider ist der aber ziemlich groß und würde
>meiner Meinung nach nur verwirren.

Na hoffentlich verwirrt er dich nicht ;-)

>Also wass kann ich nun tun, um das Problem zu beheben?
>Zum Test mit den LEDs, wie soll das gehen, da sieht man doch nichts,
>dass ist doch zu schnell.

Das geht doch nicht ! Das geht doch nicht ! Das geht doch nicht ! Das 
geht doch nicht ! Das geht doch nicht ! Das geht doch nicht ! Das geht 
doch nicht ! Das geht doch nicht ! Das geht doch nicht ! Das geht doch 
nicht ! Das geht doch nicht ! Das geht doch nicht !

Bleib mal ruhig.
Schleisse an zwei freie Pins über 1KOhm zwei LEDs an. Die IOs 
logischerweise als Ausgang definieren. Dann kopierst du in einer 
Endlosschleife zu Testzwecken deine beiden Eingangspins vom Encoder auf 
die LEDs. Wenn du nun den Encoder festhaälst und langsam drehst dann 
solltest du die Codes in der entsprechenden Reihenfolge sehen, wei im 
Artikel Drehgebr zu sehen. Wenn nicht, hast du dort schonmal ein 
Problem.

Wenn das klappt, dann mach die Kopieraktion im Timer-Interrupt. Wenn das 
dann auch klappt nutze die Routine aus dem link und es sollte gehen.

MFG
Falk

von Gerhard. (Gast)


Lesenswert?

Ich habe vor ein paar Monaten Peter's Drehgeber Codebeispiel auf einem 
PIC
adaptiert. und es funktioniert absolut einwandfrei. Ich kann den 
Drehgeber mit der Hand so schnell drehen wie ich nur kann und es sind 
bis jetzt noch nie Schritte verlorengegangen. Ich bin sehr zufrieden mit 
der Leistung und Zuverlaessigkeit. Ich verwende diese Funktion fuer die 
Frequenzeinstellung eines Amateurfunkgeraets.

Habe ueberigens den Code auf fuenf Drehgeber und 16-Bit ausgebaut und 
alle Kanele  funktionieren 100%.

Sogar mit billigen mechanischen Drehgebern funktioniert das super.

Ich bin der Ansicht dass Peter's Beispielcode einfach Spitzenklasse ist 
und in seiner Einfachkeit und Zuverlaesigkeit nicht leicht zu 
uebertreffen ist.

Nochmals vielen Dank an Peter.

Gruss,
Gerhard

von M. K. (kichi)


Lesenswert?

> Ich habe vor ein paar Monaten Peter's Drehgeber Codebeispiel auf einem PIC
> adaptiert. und es funktioniert absolut einwandfrei. Ich kann den Drehgeber
> mit der Hand so schnell drehen wie ich nur kann und es sind bis jetzt noch
> nie Schritte verlorengegangen. Ich bin sehr zufrieden mit der Leistung und
> Zuverlaessigkeit.

> Ich bin der Ansicht dass Peter's Beispielcode einfach Spitzenklasse ist und
> in seiner Einfachkeit und Zuverlaesigkeit nicht leicht zu uebertreffen ist.

> Nochmals vielen Dank an Peter.

Dasselbe hier - allerdings nicht auf einem PIC, sondern einem 
TMS320F2812...

von 123 (Gast)


Lesenswert?

@ Michael K.
Du weißt aber, dass der F2812 nen Hardware Quadratur Encoder drin hat?

von Gerhard. (Gast)


Lesenswert?

"enc_delta müsste eigentlich schon das Richtige liefern, aber weit
gefehlt. Meist werden bis zu 5 Impulse pro Rastung losgelassen. (Laut
Reichelt soll ich einen Encoder mit 24/24 haben, also eine Rastung = ein
Impuls)."

Ich errinnerte mich daran, dass ich auch einen mechanischen Drehgeber 
besitze welcher pro Rastung 2 Pulse liefert. Die sind aus irgendeinen 
Grund so gebaut nehme ich an. Bevor man dem Micro die Schuld gibt sollte 
man nach Moeglichkeit die Hardware testen (Speicheroszi) und den 
Drehgeber mal auf den Puls zu fuehlen. Auf dem Oszu muessen die 
Rechtecksignale beim Drehen schoen gleichmaesig aussehen (Bei konstanter 
Geschwindigkeit ca. 50% Impulsverhaeltnis)

Ein Bekannter von mir hatte jede Menge Schwierigkeiten mit bestimmten 
Drehgebern von Digi-Key. Die lieferten alles andere als Graycode und 
waren meiner Ansicht nach defekt.

Die Moral von der Geschicht: Kenne Deinen Hardware genau: -)

Gruss,
Gerhard

von M. K. (kichi)


Lesenswert?

> Du weißt aber, dass der F2812 nen Hardware Quadratur Encoder drin hat?
Ja - der bringt aber nur was wenn der Hardware-Entwickler das auch 
berücksichtigt und die Encoder nicht an irgendwelche GPIOs anschließt...

von Simon K. (simon) Benutzerseite


Lesenswert?

Michael K. wrote:
>> Du weißt aber, dass der F2812 nen Hardware Quadratur Encoder drin hat?
> Ja - der bringt aber nur was wenn der Hardware-Entwickler das auch
> berücksichtigt und die Encoder nicht an irgendwelche GPIOs anschließt...
> Ich war nur für die SW zuständig.

Schlag in den Nacken dann gehts beim nächsten Mal.

von Sonke A. (soeni)


Angehängte Dateien:

Lesenswert?

Also ich hab nochmal gaaaanz von forne angefangen.jezt hängt nix anderes 
mehr dran außer nem LCD einem Port per Dioden ausgeführt und dem 
Encoder. als Pins benutze ich PortB Pin 0 und 1 nun, da ich keine 
Interruptpins mehr nehme geht garnix mehr. er zappelt zwar immer, fängt 
sich aber immer bei -2.

Code im Anhang

von Falk B. (falk)


Lesenswert?

@  Sönke Paschko (soeni)

Sag mal, bist du so lernresistent oder tust du nur so?
Wenn du sämtliche Hinweis immer so galant ignorierst, dann frag nicht 
nochmal nach!

Mann O Mann.

von Sonke A. (soeni)


Lesenswert?

welche Hinweise denn? ich habe das mit den Dioden ausprobiert. man kann 
in jedem Fall sehen, das die Zustände richtig aufgefasst werden. Das mit 
dem Einpendeln hab ich gelöst, da war nen fehler, jezt "funktioniert" es 
genauso wie vorher mit vielen Sprüngen.

Was hab ich den für Hinweise überhöhrt??

von Falk B. (falk)


Lesenswert?

@ Sönke Paschko (soeni)

>welche Hinweise denn?

u.a. diese

Beitrag "Re: Encoder macht zu viele Schritte"

> ich habe das mit den Dioden ausprobiert. man kann
>in jedem Fall sehen, das die Zustände richtig aufgefasst werden.

Das hast du aber nicht geschrieben!

> Das mit
>dem Einpendeln hab ich gelöst, da war nen fehler, jezt "funktioniert" es
>genauso wie vorher mit vielen Sprüngen.

Quelltext?

Mfg
Falk

von Sonke A. (soeni)


Angehängte Dateien:

Lesenswert?

Sorry mein Fehler. Versteht mich nicht falsch, ich Find es gut, dass man 
hier Hilfe bekommt. Quelltext ist der Gleiche wie oben nur mit anderen 
Pins.

Nochmal im Anhang

von Frank B. (frankman)


Lesenswert?

Also ich würd´s noch einfacher machen:


PHASE_A--> auf Interrupt-Pin legen
PHASE_B--> auf Port-Pin legen

int enc=0; // Variable für Encoderwert

// Interruptroutine
get_enc {
if (PHASE_B ==1) enc++;
else enc--;
_waitms(was weiss ich wie lange, zum Entprellen);// Warteschleife
}


Funktion:
Wenn auf Phase A ein Impuls erkannt wird
schaue ich ob Phase B positiv oder negativ ist und zähle dann rauf oder 
runter.
Wenn man sich die zwei Phasen A und B mal aufmalt, merkt man was. Hab 
selbst relativ lange gebraucht, um das zu checken, aber es geht!


Ansonsten gibt es noch die Alternative bei US Digital, die haben einen 
Chip im SO8 für wenig Geld, der macht die Decodierung in Hardware, dann 
bekommt man ein Signal für Takt und eines für die Richtung, dann gehts 
noch einfacher....

von Michael H* (Gast)


Lesenswert?

http://www.altron.de/_pdf/ddm/427z1.pdf
auf der letzten seite sind beide möglichkeiten der auswertung als 
sinnfließbild dargestellt. die linke dürfte recht genau peters variante 
sein, wenn ich das auf die schnelle erkannt habe. vielleicht hilft dir 
das, den code zu verstehen und den fehler zu finden.
den weg über den externen interrupt kannst du dir aber eigentlich 
sparen, weil peters code wirklich klasse funktioniert.

von Falk B. (falk)


Lesenswert?

@ Frank B. (frankman)

>Also ich würd´s noch einfacher machen:


>PHASE_A--> auf Interrupt-Pin legen
>PHASE_B--> auf Port-Pin legen

Das sollte man nicht machen. Wieso?
Siehe Drehgeber.

>Ansonsten gibt es noch die Alternative bei US Digital, die haben einen
>Chip im SO8 für wenig Geld, der macht die Decodierung in Hardware,

Wenn er das nicht debuggt bekommt, kann er auch gleich das Hobby 
wechseln.

MFG
Falk

von Peter D. (peda)


Lesenswert?

Frank B. wrote:

> // Interruptroutine
> ...
> _waitms(was weiss ich wie lange, zum Entprellen);// Warteschleife

Ich vermute, Du programmierst noch nicht sehr lange bzw. nicht sehr 
erfolgreich.

Die UART wird Dir dabei hoffnungslos überlaufen, Timer werden nach dem 
Mond gehen, Software-PWM kannste vergessen usw.

Warum willst Du absichtlich einen MC auf die Leistung eines 
Relais-Rechners abbremsen?

Interrupts mit _waitms sind schlichtweg verboten !!!


Peter

von Sonke A. (soeni)


Angehängte Dateien:

Lesenswert?

AAAAAAAAAAAAAAAAAAAAAAAaarggg. Da ist irgendwie sowas von der Wurm drin.

Ich hab nochmal ganz von forne angefangen. Neuer Controller, neue 
Hardware.

Ich benutze jezt einen atmega8515 mit der Pheripherie des STK500. 
Hierbei nutze ich die Dioden und die Eingänge für den Encoder. 
Schaltplan im Anhang


Hier der Code
1
//###################                 Includes                   ###################
2
 
3
  #include <avr/interrupt.h>
4
  #include <avr/io.h>
5
  
6
7
//###############  Definitionen ##############################################
8
9
10
11
12
    // Definitionen für Encoder
13
  #define PHASE_A (PIND & 1<<PIND0)   // PINC.0 für Interrupt Encoder
14
    #define PHASE_B (PIND & 1<<PIND2)   // PINC.1 für Interrupt Encoder
15
16
17
  volatile char  enc_delta=0;    // -128 ... 127
18
19
20
21
22
int main(){
23
24
25
26
  DDRB = 0xFF;  // Port A als Ausgang setzen (LED)
27
  DDRD = 0x00;  // Port B als Eingang setzen
28
  
29
30
  //PORTD = 0xFF;  // Pullups aktivieren
31
32
33
  
34
  
35
    TCCR0 = 1<<CS01;      //divide by 8 * 256
36
    TIMSK = 1<<TOIE0;      //enable timer interrupt
37
38
  sei();
39
40
41
42
    while(1){
43
44
45
       PORTB = enc_delta;
46
  //   PORTB = PIND; // Ausgabe LED
47
  }
48
49
50
return 0;
51
}
52
53
54
55
56
57
58
59
60
SIGNAL (SIG_OVERFLOW0)
61
{
62
  static char enc_last = 0x01;
63
  char i = 0;
64
65
  if( PHASE_A )
66
    i = 1;
67
68
  if( PHASE_B )
69
    i ^= 3;        // convert gray to binary
70
71
  i -= enc_last;      // difference new - last
72
73
  if( i & 1 ){        // bit 0 = value (1)
74
    enc_last += i;      // store new as next last
75
76
    enc_delta += (i & 2) - 1;    // bit 1 = direction (+/-)
77
  }
78
79
  //PORTB = PIND;  // Ausgabe LED
80
}

von Falk B. (falk)


Lesenswert?

@Sönke Paschko (soeni)

>AAAAAAAAAAAAAAAAAAAAAAAaarggg. Da ist irgendwie sowas von der Wurm drin
Kann sein.

>Ich hab nochmal ganz von forne angefangen. Neuer Controller, neue
>Hardware.

Neues Glück ;-)

>Ich benutze jezt einen atmega8515 mit der Pheripherie des STK500.
>Hierbei nutze ich die Dioden und die Eingänge für den Encoder.

Welche Dioden? Ach so, LEDs! Dann SAG DAS AUCH SO!

>Schaltplan im Anhang

Deine Pull-Downs müssen doch eher Pull-Ups sein, oder?
Oder ist VTG die Betriebsspannung? Kann man machen, ist aber eher 
unüblich.

Und wie reagiert dein Aufbau?

MFg
Falk

von Sonke A. (soeni)


Lesenswert?

Er reagiert garnicht.
VTG ist Betriebsspannung wie sollte es denn sonst realisiert werden?? 
ich kann leider keine Beispielbeschaltung finden.

Auch den LED Test habe ich gemacht, hier werden die Zustände auch wieder 
einwandfrei Abgebildet. Auch in der Timerinterruptrutine.

von spess53 (Gast)


Angehängte Dateien:

Lesenswert?

Hi

Aus deine Schaltung ist der Anschluss (VCC/GND) nicht so richtig zu 
erkennen.
Schliess doch mal den Decoder wie im angehängten Datenblatt an. Dann 
hast du wenigstens eine kleine Hardwareentprellung.

MfG Spess

von Sonke A. (soeni)


Lesenswert?

Danke hab ich gemacht. Gleiches Bild wie ebend. Da die Phasen doch 
erkannt werden, muss doch die Software falsch sein oder? ich meiner da 
blinkt lediglich die erste LED, der Zählt noch nichtmal irgendwie. sind 
denn meine Phasen korekt??

von Michael H* (Gast)


Lesenswert?

der enkoder ist falsch angeschlossen. schau doch mal ins datenblatt. der 
soll nach masse schalten, was auch recht viel mehr sinn macht, wenn du 
pullUPs verbaust.
du kannst das ganze auch andersrum aufbaun, dann aber konsequent mit 
pull-downs.

von Falk B. (falk)


Lesenswert?

@Sönke Paschko (soeni)

>Danke hab ich gemacht. Gleiches Bild wie ebend. Da die Phasen doch
>erkannt werden,

Werden sie das? Blinke abwechselnd die LEDs, wenn du die Phasen direkt 
auf die LEDs kopierst?

> muss doch die Software falsch sein oder?

Ich seh erstmal keinen Fehler.

> ich meiner da blinkt lediglich die erste LED,

Klingt fast so, als ob eine Phase nicht erkannt wird.

MFG
Falk

von Sonke A. (soeni)


Lesenswert?

Also wenn ich folgenden Code nehme:
1
//###################                 Includes                   ###################
2
 
3
  #include <avr/interrupt.h>
4
  #include <avr/io.h>
5
  
6
7
//###############  Definitionen ##############################################
8
9
10
11
12
    // Definitionen für Encoder
13
  #define PHASE_A (PIND & 1<<PIND0)   // PINC.0 für Interrupt Encoder
14
    #define PHASE_B (PIND & 1<<PIND2)   // PINC.1 für Interrupt Encoder
15
16
17
  volatile char  enc_delta=0;    // -128 ... 127
18
19
20
21
22
int main(){
23
24
25
26
  DDRB = 0xFF;  // Port A als Ausgang setzen (LED)
27
  DDRD = 0x00;  // Port B als Eingang setzen
28
  
29
  
30
    TCCR0 = 1<<CS01;       //divide by 8 * 256
31
    TIMSK = 1<<TOIE0;      //enable timer interrupt
32
33
  sei();
34
35
36
37
    while(1){
38
39
  //  PORTB = enc_delta;
40
  //   PORTB = PIND; // Ausgabe LED
41
  }
42
43
44
return 0;
45
}
46
47
48
49
50
51
52
53
54
SIGNAL (SIG_OVERFLOW0)
55
{
56
  static char enc_last = 0x01;
57
  char i = 0;
58
59
  if( PHASE_A )
60
    i = 1;
61
62
  if( PHASE_B )
63
    i ^= 3;        // convert gray to binary
64
65
  i -= enc_last;      // difference new - last
66
67
  if( i & 1 ){        // bit 0 = value (1)
68
    enc_last += i;      // store new as next last
69
70
    enc_delta += (i & 2) - 1;    // bit 1 = direction (+/-)
71
  }
72
73
  PORTB = PIND;  // Ausgabe LED
74
}

Dann kann ich die Phasen ablesen. (Hardware ist wie im Datenblatt 
beschrieben umgesetzt auf einem Steckbrett)

wenn ich mir die Zahl in enc_delta auf den Port ausgeben lassen will 
(Anzeige über LED) nehme ich folgenden Code:
1
//###################                 Includes                   ###################
2
 
3
  #include <avr/interrupt.h>
4
  #include <avr/io.h>
5
  
6
7
//###############  Definitionen ##############################################
8
9
10
11
12
    // Definitionen für Encoder
13
  #define PHASE_A (PIND & 1<<PIND0)   // PINC.0 für Interrupt Encoder
14
    #define PHASE_B (PIND & 1<<PIND2)   // PINC.1 für Interrupt Encoder
15
16
17
  volatile char  enc_delta=0;    // -128 ... 127
18
19
20
21
22
int main(){
23
24
25
26
  DDRB = 0xFF;  // Port A als Ausgang setzen (LED)
27
  DDRD = 0x00;  // Port B als Eingang setzen
28
  
29
  
30
    TCCR0 = 1<<CS01;       //divide by 8 * 256
31
    TIMSK = 1<<TOIE0;      //enable timer interrupt
32
33
  sei();
34
35
36
37
    while(1){
38
39
    PORTB = enc_delta;
40
  //   PORTB = PIND; // Ausgabe LED
41
  }
42
43
44
return 0;
45
}
46
47
48
49
50
51
52
53
54
SIGNAL (SIG_OVERFLOW0)
55
{
56
  static char enc_last = 0x01;
57
  char i = 0;
58
59
  if( PHASE_A )
60
    i = 1;
61
62
  if( PHASE_B )
63
    i ^= 3;        // convert gray to binary
64
65
  i -= enc_last;      // difference new - last
66
67
  if( i & 1 ){        // bit 0 = value (1)
68
    enc_last += i;      // store new as next last
69
70
    enc_delta += (i & 2) - 1;    // bit 1 = direction (+/-)
71
  }
72
73
  //PORTB = PIND;  // Ausgabe LED
74
}

von spess53 (Gast)


Lesenswert?

Hi

Bin zwar kein C-Programmierer, aber irgendwie sehe ich nicht wie du 
einen Zustandswechsel erkennen willst. Da fehlt mir irgendwie eine 
globale Variable mit dem letzten Zustand.

MfG Spess

von Michael H* (Gast)


Lesenswert?

das macht die deklaration mit static in der ISR.
ich bin trotzdem noch der meinung, dass die hardware falsch 
angeschlossen ist und eine seite aus zufall funktioniert.

von Falk B. (falk)


Lesenswert?

@ spess53 (Gast)

>einen Zustandswechsel erkennen willst. Da fehlt mir irgendwie eine
>globale Variable mit dem letzten Zustand.

Nöö, static char enc_last = 0x01;

@Sönke Paschko (soeni)

>Also wenn ich folgenden Code nehme:

schnipp schnapp

>    while(1){
>
>  //  PORTB = enc_delta;
>  //   PORTB = PIND; // Ausgabe LED
>  }

Mit diesem Code siehst du GAR NICHTS! Wenn doch, hast du einen 
Verdrahtungsfehler!

MFG
Falk

von Sonke A. (soeni)


Lesenswert?

in der Interruptrutine
1
...
2
 }
3
4
  PORTB = PIND;  // Ausgabe LED
5
}

hier ist die Ausgabe, wobei es egal ist, ob ich Dort gucke oder in der 
Hauptschleife.

von spess53 (Gast)


Lesenswert?

Hi

>ich bin trotzdem noch der meinung, dass die hardware falsch
>angeschlossen ist und eine seite aus zufall funktioniert.

Dann mach doch einfach ein kleines Programm, mit dem du den Zustand am 
Eingangsport auf deine Leds ausgibst.

MfG Spess

von Sonke A. (soeni)


Lesenswert?

Hab ich doch schon. Siehe oben. Die Signale kommen richtig rein. 
(Optisch zumindest)

von Peter D. (peda)


Lesenswert?

Probier mal folgendes:
1
int main(){
2
  DDRB = 0xFF;  // Port A als Ausgang setzen (LED)
3
  DDRD = 0x00;  // Port B als Eingang setzen
4
  while(1){
5
    char i = 0;
6
7
    if( PHASE_A )
8
      i = 1;
9
10
    if( PHASE_B )
11
      i |= 2;
12
13
    switch( i ){
14
      case 0: PORTB = 1; break;
15
      case 1: PORTB = 2; break;
16
      case 3: PORTB = 4; break;
17
      case 2: PORTB = 8; break;
18
    }
19
  }
20
}

Dann mußt Du ein Lauflicht (4 LEDs an PORTB0..3) sehen, wenn Du am 
Encoder drehst.


Peter

von Sonke A. (soeni)


Lesenswert?

Ja lauflicht funktioniert.

Rechtsdrehend: 3,4,1,2,3
Linksdrehend:  3,2,1,4,3

von Sonke A. (soeni)


Lesenswert?

hat jemand vielleicht ne schaltung mit nem atmega (erstmal egal welcher) 
mit einem Encoder, die er Mir samt funktionierendem Programm zur 
Verfügung stellen kann?? ich habe, was Schaltungen angeht eigentlich 
garnix gefunden.

von Kachel-Heinz (Gast)


Lesenswert?

Wenn Peters Lauflicht funktioniert, dann ist die Beschaltung doch 
schonmal richtig. Nun analysiere Peters Code und ändere ihn auf Deine 
eigenen Bedürfnisse ab. Einfacher kannst Du nicht zum Ziel kommen...

KH

von Sonke A. (soeni)


Lesenswert?

Das versuche ich doch schon die ganze Zeit.

von Gerhard. (Gast)


Lesenswert?

Ich habe den Eindruck dass man oft vielleicht versucht zu Vieles auf 
einmal zum funktionieren zu bekommen. Bei Mikrocontrollers kommen dann 
noch die Probleme der Firmware dazu. Deshalb denke ich dass man 
vielleicht ganz einfach etwas methodischer vorgehen soll. Hardware und 
Firmware gleichzeitig Fehler suchen zu muesen ist zuviel verlangt.

Auch sollte man niemals annehmen dass die Hardware notwendigerweise 
funktioniert. Deshalb zuerst mit entsprechenden Messmitteln (Oszi, Logic 
Probe, LEDs usw.) feststellen ob z.B. der Drehgeber die richtigen 
Ausgangssignale erzeugt. (Es gibt schadhafte neue D.G. wie ein Bekannter 
von mir festellen musste). Beim Drehen muessen die A/B Ausgangsleitungen 
entsprechend nach Datenblatt umschalten.

Dann vergewissern ob die Mikro Portleitungen tatsaechlich als Eingaenge 
konfiguriert sind und nachpruefen (LED,Oszi..). Dann wuerde ich in der 
main loop ein ganz kurzes Programm erstellen welches die LEDS als Echo 
an zwei anderen Portleitungen mit LEDS (oder Oszi) ausgibt. Jetzt weiss 
man dass die H.W. richtig funktioniert. Als naechstes wurde ich dann die 
Timer Interrupt Routine einfuegen und einen Port Pin damit steuern, 
damit man weiss dass der Timer Interrupt richtig funktioniert.

Dann....

Also schrittweise vorgehen damit man nichts Wichtiges uebersieht. Jeder 
wird warscheinlich seine eigene Methode haben.

Haltet mich bitte nicht altmodisch, aber so eine Vorgehensweise hat sich 
bei mir zumindestens oft gelohnt um am Ende schneller ans Ziel zu 
kommen.

Damals hat bei mir Peter's Drehgeber Algorithm bei meiner Anpassung zu 
einem PIC innerhalb einer Viertelstunde funktioniert.


Gruss,
Gerhard

P.S. Bitte jetzt keine Steine werfen - dass tut weh ; -)

von Kachel-Heinz (Gast)


Lesenswert?

> Bitte jetzt keine Steine werfen

Warum sollten man??
Ist doch soweit alles richtig, was Du da schreibst. Das könnte nur noch 
durch den Satz ergänzt werden, dass man versuchen soll, zu verstehen, 
was man tut. Aber auch das hat mit der von Dir erwähnten systematischen 
Vorgehensweise zu tun.

KH

von Sonke A. (soeni)


Lesenswert?

Nach einem erneuten schrittweiisem Aufbau muss ich feststellen, dass das 
Datenblatt von Reichelt leider falsch sein muss. Pro Rastung werden nun 
4 Schritte hochgezählt, anstatt der von Reichelt angegebenen 1 Schritt 
pro Rastung.  Nun muss ich das nur durch 4 teilen und schon ist alles 
ok.

Danke für eure Hilfe

von Gerd B. (silicat) Benutzerseite


Lesenswert?

Das ist in Ordnung. 1 mechanischer Schritt sind immer 4 elektrische.

von Gerhard. (Gast)


Lesenswert?

Ich moechte uebriegenes noch den Einsatz (Anschaffung) einer Logic Probe 
waermstens empfehlen. Wenn man gerade keinen Osczi zur Verfuegung hat 
ist es extrem nuetzlich da man sofort sehen kann ob:

Port Eingaenge offen sind (als Eingang oder Ausgang geschaltet)
Statischer Zustand von Port Pins (High/Low)
Impulsverhaeltnis und Groessenordnung von aktiven Ausgaengen.

Wenn z.B. ein Ausgang mit PWM getaktet ist, sieht man durch die 
Helligkeit des LEDs sofort in welchem Bereich die PWM gerade ist.

Nur bei seriellen Datenuebertragungsproblemen ist die L.P. nur begrenzt 
nuetzlich, obwohl man schoen sehen kann ob z.B. das CS entsprechend 
pulsiert, und Datenaktivaet periodisch festzustellen ist.

Ist oft auch weniger Arbeit als LEDs an die Schaltung anzuschliessen und 
auch bei SMD kommt man sehr gut an die IC Anschluesse ran.

Ich kaufte mir vor vielen Jahren die "LP1" von SCS. Ich glaube die gibt 
es noch.

Jedenfalls hat sich meine L.P. bei mir schon viele Jahre bei der 
Fehlersuche vieler Schaltungen sehr bewaehrt. Mit gezielten 
Debugbefehlen in der FW kann man viel Einsicht in das Verhalten der 
Sache bekommen. Ein (Digitaler Speicher) Oszi ist eine feine Sache, aber 
oft fuer Viele am Anfang der Laufbahn unerschwinglich. (Mir ging es 
zumnindestens so).

Wenn man es sich leisten kann, ein USB Logicanalyzer wie der LA1034A ist 
eine feine Sache fuer den Preis und dekodiert auch I2C, SPI, UART Daten. 
Wenn ma den einmal hat will man es nicht mehr vermissen.

Gruss,
Gerhard

von Michael H* (Gast)


Lesenswert?

ahja, das datenblatt des herstellers ist mal wieder falsch... wie das 
nur so oft passieren kann...

von Micha (Gast)


Lesenswert?

> Nach einem erneuten schrittweiisem Aufbau muss ich feststellen, dass das
> Datenblatt von Reichelt leider falsch sein muss. Pro Rastung werden nun
> 4 Schritte hochgezählt, anstatt der von Reichelt angegebenen 1 Schritt
> pro Rastung.  Nun muss ich das nur durch 4 teilen und schon ist alles
> ok.
Ich würde mal behaupten das Datenblatt ist richtig. Es steht zumindest 
drin, dass pro Rastung 4 Schritte gemacht werden...

von Frank B. (frankman)


Lesenswert?

ich poste hier noch mal die HARDWARELÖSUNG, die funktioniert wenigstens 
sofort... :-)

http://www.usdigital.com/assets/general/111_lfls7084-s_datasheet_1.pdf


Und kostet nur 3,2 Dollar....


@Falk: Ich stimme Dir zu, die Lösung von mir ist nicht die beste, aber 
einfach.... für den Anfang...

von Simon K. (simon) Benutzerseite


Lesenswert?

NUR 3,2 Dollar. Haha!

von spess53 (Gast)


Lesenswert?

Hi

Man könnte natürlich auch auf den ATXMega warten. Die haben so etwas 
eingebaut.

MfG Spess

von Michael H* (Gast)


Lesenswert?

oder sich nicht so wie hier anstellen ^^

von Falk B. (falk)


Lesenswert?

@ Gerd B. (Firma siliCAT.de) (silicat) Benutzerseite

>Das ist in Ordnung. 1 mechanischer Schritt sind immer 4 elektrische.

Wo steht das? Das kann und macht jeder Hersteller nach Belieben.


@ Gerhard. (Gast)

>Ich moechte uebriegenes noch den Einsatz (Anschaffung) einer Logic Probe
>waermstens empfehlen. Wenn man gerade keinen Osczi zur Verfuegung hat
>ist es extrem nuetzlich da man sofort sehen kann ob:

Genau. Und für unsere Hobbybastler kann man das sogar selber bauen.

http://www.geocities.com/Jacquesmartini/digital/logiktester/logiktester.html

MFg
Falk

von Kachel-Heinz (Gast)


Lesenswert?

Prima Link, aber der Link zum Schaltplan funktioniert nicht, womit der 
Link wertlos wird...

KH

von Falk B. (falk)


Lesenswert?

@ Kachel-Heinz (Gast)

>Prima Link, aber der Link zum Schaltplan funktioniert nicht, womit der
>Link wertlos wird...

Ist gefixt.

MFG
Falk

von Micha (Gast)


Lesenswert?

> Prima Link, aber der Link zum Schaltplan funktioniert nicht, womit der
> Link wertlos wird...
Bei mir funktioniert es...

von Kachel-Heinz (Gast)


Lesenswert?

>> Prima Link, aber der Link zum Schaltplan funktioniert nicht, womit der
>> Link wertlos wird...
>Bei mir funktioniert es...

Bei mir funktioniert es inzwischen auch, denn Falk hat den Fehler ja 
behoben, wofür ich ihm im Namen der Nachnutzer (Ich verfüge bereits über 
einen Logiktester) herzlich danke.

KH

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.