drehgeber halbschritt??

Gast #2789480
hallo zusammen...
ich hab grad das problem, dass mein drehgeber jeden halben schritt 
zählt.
was mach ich falsch, dass er nich bei einem ganzen kontaktiert.?

bauteil: 
http://www.reichelt.de/Drehimpulsgeber/STEC12E08/3//index.html?ACTION=3&GROUPID=3714&ARTICLE=73923&SHOW=1&START=0&OFFSET=16&;



code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <avr/pgmspace.h>
4
#include <util/delay.h> 
5
#define XTAL        16e6                 // 16MHz
6
 
7
#define PHASE_A     (PINA & 1<<PA1)     // an Pinbelegung anpassen
8
#define PHASE_B     (PINA & 1<<PA3)     // an Pinbelegung anpassen
9
 
10
#define LEDS_DDR    DDRD
11
#define LEDS        PORTD              // LEDs gegen Vcc geschaltet
12
  
13
volatile int8_t enc_delta;             // Drehgeberbewegung zwischen
14
                                       // zwei Auslesungen im Hauptprogramm
15
 
16
// Dekodertabelle für wackeligen Rastpunkt
17
int8_t table[128] PROGMEM = {0,0,1,0,0,0,0,1,1,0,0,0,0,-1,0,0};  
18

19
ISR( TIMER0_COMP_vect )             // 1ms fuer manuelle Eingabe
20
{
21
    static int8_t last=0;           // alten Wert speichern
22
 
23
    last = (last << 2)  & 0x0F;
24
    if (PHASE_A) last |=2;
25
    if (PHASE_B) last |=1;
26
    enc_delta += pgm_read_byte(&table[last]);
27
}
28
 
29
void encode_init( void )            // nur Timer 0 initialisieren
30
{
31
  TCCR0 = (1<<WGM01) | (1<<CS01) | (1<<CS00);     // CTC, XTAL / 64
32
  OCR0 = (uint8_t)(XTAL / 64.0 * 1e-3 - 0.5);       // 1ms
33
  TIMSK |= 1<<OCIE0;
34
}
35
 
36
int8_t encode_read( void )         // Encoder auslesen
37
{
38
  int8_t val;
39
 
40
  // atomarer Variablenzugriff  
41
  cli();
42
  val = enc_delta;
43
  enc_delta = 0;
44
  sei();
45
  return val;
46
}
47
 
48
int main( void )
49
{
50
  int32_t val = 0;
51
  PORTA=0xff; //...//
52
  DDRB = 0x03;
53
  LEDS_DDR = 0x03;
54
  encode_init();
55
  sei();
56
 
57
  while(1){
58
    val += encode_read();      
59
    LEDS = val;
60
  if (PHASE_A)
61
  {
62
    PORTB &=~ 0x03;
63
    PORTB = 0x01;
64
    _delay_ms(200);
65
    PORTB &= ~0x01; 
66
    
67
  }
68
  else if (PHASE_B)
69
  {
70
    PORTB &=~ 0x03;
71
    PORTB = 0x02;
72
    _delay_ms(200);
73
    PORTB &=~ 0x02;
74
  }
75
  else{
76
    PORTB &=~ 0x03;
77
  }
78
  }
79
}
den code habe ich von hier:
http://www.mikrocontroller.net/articles/Drehgeber

was mach ich falsch.?

mfg axel
Persönliche Seite
Hallo Axel

> ich hab grad das problem, dass mein drehgeber jeden halben schritt
> zählt.
> was mach ich falsch, dass er nich bei einem ganzen kontaktiert>
...

Garnichts.

Schau Dir die verlinkte Seite an.
Dort siehst Du genau, WANN ein Takt erzeugt wird.

Was willst Dui eigentlich genau!?

Gruss

Michael
Gast
Michael Roek schrieb:
> Dort siehst Du genau, WANN ein Takt erzeugt wird.

??



meine vorstellung ist einfach nur, in meinem code sagen zukönnen, "wenn 
ich links drehe"- mache das und das und halt andersrum....
im meinem gesammten projekt ist es, bei meinem glcd in den menues 
rumzuspringen und anderes.
Gast
>was bzw. wo soll ich durch 2 teilen.??

Woran merks Du, das die Software Halbschritte zählt?
Greif da ein und werte nur jeden 2. Halbschritt aus.
So hast Du "Vollschritte".
axel p. schrieb:
> int8_t table[128] PROGMEM = {0,0,1,0,0,0,0,1,1,0,0,0,0,-1,0,0};

Ich sach mal, das ist doppelt Quatsch:
1.
Warum 112 Werte zuviel?

2.
Die 1 und -1 müssen gleich oft sein, sonst zählt er unterschiedlich je 
Richtung.
Für Vollschritt darf nur einmal 1,-1 drin sein, für Halbschritt 2* und 
Viertelschritt 4*.


Peter
Gast
axel p. schrieb:
> aber woher weiß ich, wo die 1 bzw. -1 sein muss.??
Indem du verstehst wozu die Tabelle dient und wie das Programm damit 
funktioniert. Mal dir einfach mal die Signale für CCW- und CW-Drehung 
auf und überleg dir, wie das Programm die verarbeitet.
Gast
axel p. schrieb:
> #include <util/delay.h>
> #define XTAL        16e6                 // 16MHz

Falls du von deinem Programm korrektes Zeitverhalten erwartest, solltest 
du die Reihenfolge der obigen Anweisungen noch mal überdenken und dazu 
ggf. die Warnung von der util.h beachten.
axel p. schrieb:
> int8_t table[16] PROGMEM = {0,0,1,0,0,0,0,0,0,0,0,0,0,-1,0,0};

Der Compiler rechnet auch gerne selber die Länge aus:
1
int8_t table[] PROGMEM = {0,0,1,0,0,0,0,0,0,0,0,0,0,-1,0,0};

axel p. schrieb:
> aber woher weiß ich, wo die 1 bzw. -1 sein muss.??

An irgend einem Wechsel. Sie müssen nur für die selbe Stellung stehen, 
sonst funktioniert die Entprellung nicht.
Z.B.:
00 -> 01: +1
und:
01 -> 00: -1


Peter
Gast
also jetzt macht das programm immer mehr was es will...
jetzt kann ich nur in eine richtung drehen, damit irgendetwas passiert, 
und die andere richtung geht nur mal eine led an, aber auch wieder immer 
nur im halbschritt....
Gast
axel p. schrieb:
> also jetzt macht das programm immer mehr was es will...
> jetzt kann ich nur in eine richtung drehen, damit irgendetwas passiert,
> und die andere richtung geht nur mal eine led an, aber auch wieder immer
> nur im halbschritt....

.??

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.