Forum: Mikrocontroller und Digitale Elektronik ATMega328 und ATTiny45 mit I2C verbinden


von Conny G. (conny_g)


Lesenswert?

Hi,

ich möchte die 2 uC verbinden, der ATMega328 ist der Master und 
kommuniziert per RS232 mit einem Raspberry Pi, liefert dort Daten ab, 
die über ein RFM12 Funkmodul hereinkommen und soll auch Daten dort 
abliefern, die ein ATTiny45 einsammelt (ca. 10-15 Bytes alle 30 
Sekunden).
Hätte die beiden jetzt per I2C verbunden, beim ATMega über das TWI 
Interface und beim ATTiny über das USI.

Jetzt hab ich noch eines, was mir unklar ist, was da "best practice" 
ist:
ich würde den ATMega nur dann den ATTiny nach Daten fragen wollen, wenn 
der welche hat.
Macht es Sinn hierfür eine "Interrupt"-Leitung einzurichten, also zwei 
Pins der beiden zu verbinden und der Tiny schaltet die Leitung hoch, 
wenn er was hat und der ATMega weiss somit, wann er nachsehen muss.
Habe noch nicht soviel Erfahrung mit I2C-Bausteinen, ob das die beste 
Methode ist.

Ist das eine sinnvolle Lösung oder gibt es bessere Herangehensweisen?

Könnte ich mir langfristig vorstellen, mehrere solcher kleiner ATTiny 
Schaltungen auf einem I2C Bus zu haben. Wie würde ich es dann am 
elegantesten lösen, wenn mehrere signalisieren wollen, dass sie Daten 
haben?
Mehrere Int-Leitungen oder eine Int-Leitung und dann pollt der Atmega 
die einzelnen Tinys?
Oder einen Input-Muxer, der mit einer Leitung einen State-Change anzeigt 
und der AtMega kann dann nachsehen, welche Leitung(en) sich geändert 
hat/haben?

Vg,
Conny

von Ingo (Gast)


Lesenswert?

Es scheint mir so, als ob zeit bei dir keine Rolle spielt, von daher 
würde ich pollen

von Conny G. (conny_g)


Lesenswert?

Das ist richtig, es ist nicht kritisch, zumindest nicht mit einem 
solchen Slave.
Sollte ich mal mehrere haben, dann würde ich nicht alle durchpollen 
wollen und eine Feedbackleitung wäre mir dann lieber.
Und am liebsten würde ich dann gleich diese Richtung einschlagen, dann 
muss ich bei Erweiterung nicht nochmal rumtun.

von Conny G. (conny_g)


Lesenswert?

Sooo, ich habe das jetzt wie folgt gelöst:

Auf dem ATTiny die Library von Martin Junghans verwendet, die ein EEPROM 
emuliert:
http://www.jtronics.de/avr-projekte/library-i2c-twi-slave-usi.html

Auf dem ATMega das I2C nach diesem Tutorial zusammengebaut und das 
EEPROM abgefragt:
http://www.embedds.com/programming-avr-i2c-interface/

Beim ATTiny - der ist ein selbst programmierter Funkempfänger für alte 
433 Mhz Temperatursender - stelle ich die empfangenen Daten in einen 
Puffer, mit einem Längenbyte vorab, das ist der EEPROM-Speicher.
Dieser Puffer wird von der EEPROM-Lib ausgeliefert.

In der Hauptschleife des AtMega frage ich immer Byte 0 des "EEPROM" ab 
und wenn das Byte > 0 ist hole ich die Bytes ab und habe meine 
Temperaturwerte.

Klappt prima!
Da die Werte von ein paar Sensoren alle paar Minuten kommen habe ich 
eigentlich erstmal keine zeitlichen Bedrängnisse zu befürchten und kann 
mir die vorab überlegte Interrupt-Leitung sparen.

von stefan us (Gast)


Lesenswert?

Interrupt-Leitungen in Kombination mit I2C sind keine Seltenheit.

Alternativ könnte der Master die Adresse 0 (Broadcast) senden, und dann 
antwortet der Slave mit seiner eigenen Adresse, wenn er Daten zum 
Abholen bereit hat.

Nun musst Du nur noch
a) Slave Adressen so wählen, dass die "0" Bits sich nicht überlappen. 
z.B.:
  1111110
  1111101
  1111011
  1110111
  1101111
  1011111
  0111111
  geht also mit maximal 7 Slaves auf diese Art.
oder
b) Die Antwort auf den Broadcast ausnahmsweise "zu Fuß" (ohne TWI oder 
USI) implementieren, um Kollisionen nach der Methode wie beim CAN Bus zu 
verhindern. Kurz zusammengefasst: Der Slave sendet seine eigene Adresse. 
Immer wenn er eine 1 sendet, prüft er, ob der Bus tatsächlich auf 1 
steht. Wenn nicht, dann antwortet gerade ein anderer Busteilnehmer mit 
höherer Priorität, so daß der Slave sofort abbricht und den Bus 
freigibt.

von Conny G. (conny_g)


Lesenswert?

stefan us schrieb:
> Interrupt-Leitungen in Kombination mit I2C sind keine Seltenheit.

Ja, das wollte wissen, danke.

> Alternativ könnte der Master die Adresse 0 (Broadcast) senden, und dann
> antwortet der Slave mit seiner eigenen Adresse, wenn er Daten zum
> Abholen bereit hat.
>
> Nun musst Du nur noch
> a) Slave Adressen so wählen, dass die "0" Bits sich nicht überlappen.
> z.B.:
>   1111110
>   1111101
>   1111011
>   1110111
>   1101111
>   1011111
>   0111111
>   geht also mit maximal 7 Slaves auf diese Art.
> oder
> b) Die Antwort auf den Broadcast ausnahmsweise "zu Fuß" (ohne TWI oder
> USI) implementieren, um Kollisionen nach der Methode wie beim CAN Bus zu
> verhindern. Kurz zusammengefasst: Der Slave sendet seine eigene Adresse.
> Immer wenn er eine 1 sendet, prüft er, ob der Bus tatsächlich auf 1
> steht. Wenn nicht, dann antwortet gerade ein anderer Busteilnehmer mit
> höherer Priorität, so daß der Slave sofort abbricht und den Bus
> freigibt.

Klingt durchaus wie eine clevere Idee.
Das verlässt aber den Standard und wäre eine proprietäre Abwandlung des 
I2C, oder?
D.h. ich bekomme dann Probleme wenn ich auf dem Bus Geräte hätte, die 
ich nicht kontrolliere und die sich nach Standard verhalten?

von Conny G. (conny_g)


Lesenswert?

Das ist nun draus geworden:

https://www.thingspeak.com/channels/8689#

Alte ELV 433 MHz Sensoren von (vor?) 2000 >  433 Mhz Funk > ATTiny45 > 
i2C > Atmega328 > Uart > Raspberry Pi > Python Home Automation 
Controller & Uart Parser > HTTP > ThingSpeak

Habe jetzt auch einen Beta-Account bei Sen.se bekommen, ThingSpeak ist 
ok, aber ziemlich Basic. Und Cosm kostet ja jetzt.

Gibt noch den einen oder anderen Fehlerfall / Exception, den ich im 
Python noch nicht behandle, da kommt auch gestriger Aussetzter her.
Und bis heute Nacht habe ich mich noch nicht um das Vorzeichen- Bit der 
Außentemperatur gekümmert gehabt.

: Bearbeitet durch User
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.