2 Arduinos synchronisieren

Ich möchte eine Schaltung aufbauen, in der ein ATTiny85 in der Initialisierung Daten über den I2C-Bus von einem ATMEGA328P bekommt.

Hintergrund ist einfach der, dass für die eigentliche Steuerung der Tiny völlig ausreicht und dessen Stromverbrauch gerade noch akzeptabel niedrig ist (1,5mA), während sein 'grosser Bruder' zu stromhungrig ist (dessen Stromverbrauch in vertretbare Größenordnungen zu reduzieren ist ein aussichtsloses Unterfangen; unter 3 mA ist der nicht zu bringen).

Allerdings benötigt der Tiny für sein Programm 2 Integervariablen, die über 2 einfache 2-Byte-Hexacodierungen (also insgesamt 8 Hexadezimal-Schalter) vom 328 eingelesen werden und über den I2C-Bus dem Tiny zugeschickt werden sollen. Anschließend knipst der Tiny dem 328 den Strom aus und kann stundenlang seine eigentliche Steuerung durchziehen.

Also meine Frage: wie bekommt der Tiny die beiden Integer vom 328?

Hat jemand evtl. ein paar Codeschnipsel, aus denen ich den grundsätzlichen Kommunikationsverlauf ersehen kann?

Hast Du für die Steuerungsaufgabe auf dem Tiny noch genug Pins, wenn Du 2 für die I2C-Schnittstelle abgeben musst?

Das Prinzip ist auf Nick Gammons Seite (Gammon Forum : Electronics : Microprocessors : I2C - Two-Wire Peripheral Interface - for Arduino) gut erklärt und mit Code-Beispielen versehen.
In Deinem Fall musst Du aber auf dem Slave die Wire-Bibliothek durch die TinyWireS-Bibliothek ersetzen, da der Tiny andere Hardware verwendet.

Hier findest du mehrere Beispiele des I2C in Verbindung mit Atmega und ATtiny.

I2C-Beispiele

Einen Teil der Elektronik abzuschalten braucht es einiges an Aufmerksamkeit. Wenn Du einen ATmega328 abschalten willst mußt Du auch sicherstellen daß an keinem seine I/O Pins Spannung anliegt weil ansonsten der ATmega über die Schutzdioden mit Strom versorgt wird und weiter Strom zieht. Also einfach 5V abschalten geht nicht. Da ist es schon besser und einfacher den ATmega in sleep zu schicken und angeschalten lassen.

Grüße Uwe

Erst mal besten Dank Euch allen! Ich bin mittlerweile schon über die TinyWireM-Bibliothek gestolpert, werde mir aber Eure Links genau anschauen.

@pylon: Ja habe ich. Ich brauche nur 2 Output-Pins, damit habe ich CLK, MOSI, MISO und RESET frei.

@uwefed: ich wollte mittels PhotoMOS sowohl die Versorgungsspannung des 328 als auch die Hex-Eingangsschalter des 328 vor dem Init mit +5V versorgen, nach dem Init (und natürlich dem Datentransfer) einfach umschalten auf Masse.

Der Sleepmodus bringt mir nix, weil der 328 im aufgewachten Zustand trotzdem zuviel Strom zieht, und dieser Modus auch mal ein paar Stunden anhalten kann.

Alternativ schwebt noch vor, 2 MCP23017-E/SP (16-bit-IO-Expander) auszulesen. Die sind ja eigentlich genau dafür gebaut, was ich machen will. Nur mal sehen, wie ich die adressieren kann... Das Auslesen sollte dann ja kein Zauberwerk sein.

zappa2:
Ich brauche nur 2 Output-Pins, damit habe ich CLK, MOSI, MISO und RESET frei.

Warum liest Du die Schalter dann nicht einfach über SPI ein? 2 CMOS-Schieberegister brauchen fast keinen Strom und eine Adressierung brauchst Du in dem Fall auch nicht.

Der Sleepmodus bringt mir nix, weil der 328 im aufgewachten Zustand trotzdem zuviel Strom zieht, und dieser Modus auch mal ein paar Stunden anhalten kann.

Verstehe ich nicht. Was ist Deiner Meinung der Unterschied zwischen Sleep und Versorgungsspannung weg?

Der Sleepmodus bringt mir nix, weil der 328 im aufgewachten Zustand trotzdem zuviel Strom zieht, und dieser Modus auch mal ein paar Stunden anhalten kann.

Das verstehe ich nun gar nicht!

Du kannst ihn nicht schlafen schicken, aber abschalten....
Ist das logisch?

Ich bin mittlerweile schon über die TinyWireM-Bibliothek gestolpert

M = Master. Wenn der Atmega unaufgefordert Senden soll, dann muss auf den Tiny TinyWireS. TinyWireM brauchst du wenn der Tiny Master sein soll und von einem Slave Daten anfordert

Hier habe ich gezeigt wie man verschiedene Multi-Byte Darentypen über I2C austauscht:

Mit zwei Atmegas. Also Wire auf beiden Enden. Das könnte aber auch ein ATtiny mit TinyWire sein.

Das ist Test/Demo-Code! Es wird gezeigt wie der Master Daten an den Slave schickt. Aber auch wie der Master vom Slave Daten anfordert. In dem Beispiel schickt der Master zwei Zahlen, der Slave inkrementiert sie und der Master liest sie sofort wieder zurück. Praktisch musst du dich für eine Variante entscheiden!

1.) Master schickt Daten an den Slave:
Auf dem Master writeValues() nehmen und auf dem Slave den Receive Event Handler

2.) Master fordert Daten vom Slave an (analog zu I2C Sensoren):
Auf dem Master getValues() verwenden und auf dem Slave den Request Event Handler

Du willst hier warscheinlich Variante 1

Das ist für zwei Werte. Für nur einen Integer kann das anonyme struct entfallen:

union Data
{
  byte asArray[sizeof(unsigned int)];
  unsigned int value;
};

Wobei TinyWire glaube ich nicht diese Beschränkung hat dass man im Event Handler nur einmal write() machen kann. Man kann aber so oder so entweder ein Byte oder ein Array senden. Man kann nicht direkt Multi-Byte Variablen verschicken. Daher sind Unions sind sehr praktisch hierfür.

Ihr seid in diesem Forum hier ja richtig hilfsbereit! Super und 1000 Dank!

Ich habe mich sicher dämlich ausgedrückt. Ich wollte mit 2 Arduinos arbeiten: der Tiny schaltet nur 2 Ausgänge nach einem bestimmten Algorithmus (abhängig von den beiden im Init einzulesenden Integerwerten) ein und aus.

Der 328 sollte die Integerwerte holen und per I²C an den ATTiny abgeben, anschließend wird er nicht mehr benötigt.

Im eigentlichen Programm wird nix mehr an diesen beiden Werten geändert, d.h. ich brauche den Init wirklich nur ein einziges Mal.

Ich werde das mal mit den MCP23017 testen, die sind super preiswert (1,50 pro IC) und genau auf das reduziert, was ich brauche.

Trotzdem erst mal allen ein Dankeschön!

Leider sagtst du nicht worum es überhaupt geht.

Darum kann ich/wir dir auch keine "vernünftigen" Vorschläge machen.

Übrigens:
Das mit dem Ein und Aus schalten, hört sich falsch an.
Meine Glaskugel schreit: Dumme Idee!

Der 328 sollte die Integerwerte holen und per I²C an den ATTiny abgeben, anschließend wird er nicht mehr benötigt.

Ich glaube, wir haben das kapiert, aber Du hast nicht verstanden, was Dir uwefed mit dem Schlafenschicken sagen wollte. Du kannst den ATmega328p nicht so einfach ausschalten, jedenfalls nicht mit der Schaltung, die Du im Text skizzierst. Deshalb hat er Dir geraten, ihn anstatt abzuschalten einfach schlafen zu schicken. Im Tiefschlaf braucht er ein paar wenige µA und Du brauchst keine aufwendige Schaltung, die ihm den Strom komplett abschneidet (inkl. der I2C-Leitungen). Aber die Lösung mit den Schieberegistern wäre einfach zu realisieren, Deine MCP23017 sollten aber auch funktionieren.

Nochmal zum Grundanliegen: Wenn der Tiny in seinem Setup die Daten vom 328 anforden soll, muss der Tiny nach meiner Ansicht der Master sein. Der 328 weiß ja nicht, wann der Tiny die Daten braucht.

Gruß Tommy

Tommy56:
Nochmal zum Grundanliegen: Wenn der Tiny in seinem Setup die Daten vom 328 anforden soll, muss der Tiny nach meiner Ansicht der Master sein. Der 328 weiß ja nicht, wann der Tiny die Daten braucht.

Gruß Tommy

Tommy, das kannst du doch auch über einen IRQ o.ä. steuern.
So löse ich es doch auch im Sketch für die ATtiny85-Platinen.

Ok, das geht auch.

Gruß Tommy