Forum: Mikrocontroller und Digitale Elektronik I2C Bus und Drehgeber


von Bert (Gast)


Lesenswert?

Hallo
sicher wird es wieder einen Aufschrei geben, das es nicht geht. Warum 
eigentlich nicht?
Habe mit einem ATm 128 und einem direkt angeschlossenen Drehgeber mit 
dem Programm von Peter es umgesetzt.
1
void encode_init( void )
2
  {
3
  int8_t new;
4
  new = 0;
5
  if( PHASE_A ) new = 3;  
6
  if( PHASE_B ) new ^= 1;        // convert gray to binary
7
  last = new;              // power on state
8
  enc_delta = 0;
9
  }
10
11
ISR( TIMER0_COMPA_vect )        // 1ms for manual movement
12
  {
13
  int8_t new, diff;
14
  new = 0;
15
  if( PHASE_A ) new = 3;
16
  if( PHASE_B ) new ^= 1;        // convert gray to binary
17
  diff = last - new;          // difference last - new
18
  if( diff & 1 ) 
19
    {                  // bit 0 = value (1)
20
    last = new;            // store new as next last
21
    enc_delta += (diff & 2) - 1;  // bit 1 = direction (+/-)
22
    }
23
  }
24
25
int8_t encode_read1( void )      // einzel Schritt Encoder
26
  {
27
  int8_t val;
28
  cli();
29
  val = enc_delta;
30
  enc_delta = 0;
31
  sei();
32
  return val;                   
33
  }
34
35
int8_t encode_read2( void )      // zwei Schritt Encoder
36
  {
37
  int8_t val;
38
  cli();
39
  val = enc_delta;
40
  enc_delta = val & 1;
41
  sei();
42
  return val >> 1;
43
  }
44
45
int8_t encode_read4( void )      // vier Schritt Encoder
46
  {
47
  int8_t val;
48
  cli();
49
  val = enc_delta;
50
  enc_delta = val & 3;
51
  sei();
52
  return val >> 2;
53
  }
54
55
void timer_init()          // Timer 1ms
56
  {
57
  TCCR0A = (1<<WGM01);
58
  TCCR0B = (1<<CS01)|(1<<CS00);
59
  OCR0A = 249;
60
  TIMSK0 |=(1<<OCIE0A);
61
  }
Das ist ein Teil meines Programmes. Die Auswertung fehlt noch. Es geht 
ohne Probleme. Wie kann ich das zum I2C Bus umsetzen?
Habe einen ATtiny 44 genommen, den Drehgeber nach der gleich Beschaltung 
wie beim 128. Dieser Attiny soll die Auswertung machen und nur die 
Angabe links oder rechts über USI zum 128 übertragen.
Hat jemand eine Idee dazu oder es schon mal gemacht?
Würde mich über jede Hilfe freuen.

LG Bert

von m.n. (Gast)


Lesenswert?

Bert schrieb:
> Hat jemand eine Idee dazu oder es schon mal gemacht?

Schon mal gemacht, aber mit ATtiny25: 
Beitrag "mini Quadraturdekoder + 32 Bit Zähler + TWI, Attiny25"

von Bert (Gast)


Lesenswert?

Danke für deine Info. Das sieht gut aus. Habe es mir angesehen. Dein 
Code ist in HEX. Da ich einen anderen Prozessor verwende muss ich 
einiges ändern. Hast was in C dazu?

von Frank L. (Firma: Flk Consulting UG) (flk)


Lesenswert?

Hallo Bert,

das wird so ohne weiteres nicht gehen.

Ich gehe mal davon aus, dass Du Deinen ATm 128 als Master und den Tiny44 
als Slave laufen lassen willst.

Wenn Du Deinen ATm 128 nicht ständig den I2C Bus pollen lassen willst, 
musst Du Dir einen zusätzlichen PIN für einen IRQ vom Tiny 
konfigurieren.

Dann kann der Tiny ein Signal senden und der ATM holt die Daten über I2C 
ab. Alles in allem nicht sehr schön, vor allem dann, wenn Du sehr 
schnell drehst.
Warum also den Drehgeber nicht direkt am ATm?

Gruß
Frank

von Bert (Gast)


Lesenswert?

Hallo Frank
ein Drehgeber direkt am Atm habe ich bereits. Möchte das jetzt auf den 
Ati44 übertragen. Leider gibt es nichts fertiges.
Muss ich den bei verwendung eines Prozessors jede Drehbewegung zum 
Master übertragen? Es reicht doch aus, wenn ich nur "sage" hoch oder 
runter. Da brauch ich weniger Zeit.

von Stefan F. (Gast)


Lesenswert?

> Es reicht doch aus, wenn ich nur "sage" hoch oder runter.

Dann würde ich einen Wipptaster verwenden. Der Sinn eines Drehgebers ist 
doch, dass der Computer dem Drehwinkel und der Geschwindigkeit exakt 
folgt. Nur daraus ergibt doch ihr Bedienkomfort.

von Frank L. (Firma: Flk Consulting UG) (flk)


Lesenswert?

Dann formuliere ich es anders, wie oft benötigst Du den 
Richtungswechsel?

Gruß
Frank

von spess53 (Gast)


Lesenswert?

Hi

>ein Drehgeber direkt am Atm habe ich bereits. Möchte das jetzt auf den
>Ati44 übertragen. Leider gibt es nichts fertiges.

Warum? Der ATMega128 hat doch ausreichend Pins.

MfG Spess

von Maxim B. (max182)


Lesenswert?

Bert schrieb:
> Wie kann ich das zum I2C Bus umsetzen?
> Habe einen ATtiny 44 genommen, den Drehgeber nach der gleich Beschaltung
> wie beim 128. Dieser Attiny soll die Auswertung machen und nur die
> Angabe links oder rechts über USI zum 128 übertragen.
> Hat jemand eine Idee dazu oder es schon mal gemacht?
> Würde mich über jede Hilfe freuen.

ATtiny als Master, 128 als Slave. Jede z.B. 100 ms enc_delta prüfen, 
falls (enc_delta), per I2C enc_delta-Wert schicken.

1
/*** Programm ***/
2
3
   int8_t dreh_puff;
4
5
   dreh_puff = encode_read1();
6
   if(dreh_puff) send_i2c(dreh_puff);
7
8
9
/******/

: Bearbeitet durch User
von Bert (Gast)


Lesenswert?

Der Atmega hat genug Ppins ist klar. Möchte aber externe Station oder 
Modul zur Bedienung haben. Ein Wippschalter ist wohl zu primitiv. Der 
Slave soll ja nur die Auswertung des Drehgebers übernehmen und einfach 
Master sagen hoch oder runter. Eine Veränderung der Werte kann auch 
durch Int angezeigt werden.

von Frank L. (Firma: Flk Consulting UG) (flk)


Lesenswert?

Hallo Bert,

sorry, wenn ich es so hart formuliere...

Ein Slave ist immer passiv! Der Master bekommt von den Änderungen Deines 
Slave nichts mit! Wenn Du Deine Konzept beibehalten willst, musst Du Dir 
eine andere Kommunikationsmethode überlegen.

1. Möglichkeit ist, Master und Slave zu vertauschen. ATM = Slave und 
Tiny = Master. Willst Du noch andere I2C Geräte ansprechen, geht das 
dann nur über den Tiny.

2. Möglichkeit, wäre den ATM als Master und als Slave zu positionieren. 
Sehr aufwendig und kritisch.

3. Möglichkeit, anstelle von I2C zwei Leitungen vom Tiny zum ATM. Auf 
dem ATM werden diese beiden PINs mit je einem Interrupt (PIN Change) 
belegt. Dann kannst Du unabhängig reagieren. in diesem Fall kannst Du 
aber den Drehencoder direkt anschließen.

4. Möglichkeit, der ATM ist Master und pollt den I2C Bus in einem 
TimerInterrupt.

Gruß
Frank

von m.n. (Gast)


Lesenswert?

Frank L. schrieb:
> Warum also den Drehgeber nicht direkt am ATm?

Es kommt auf den Drehgeber an. Ein lansamer, mechanischer Drehgeber ist 
unproblematisch im Hintergrund abzufragen. Wenn es allerdings um 
Impulsfrequenzen mit 100 kHz geht, ist ein separater Slave-µC besser.

Bert schrieb:
> Da ich einen anderen Prozessor verwende muss ich
> einiges ändern.

Wenn er nur um diese eine Funktion geht, könntest Du Dir auch einen 
ATtiny25 mit dem .hex-Code programmieren und den Punkt abhaken.
Dieses USI-Interface, wie es auch der ATtiny44 hat, ist für mich nicht 
das Gelbe vom Ei. Ein richtiges IIC-Interface ist mir wesentlich lieber 
und funktioniert auch stabil. Dafür nehme ich gerne einen ATmega48: 
http://mino-elektronik.de/mt12_iic/mt12_iic.htm
Aber auch ein neuerer ATtiny841 im 14-pol. Gehäuse bietet ein 
IIC-Interface, was stabil laufen sollte.

von Klars (Gast)


Lesenswert?

Hast du eine Möglichkeit gefunden?

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.