Tiny85->Duemilanove->I2C brauche Denkanstoß!!!

Hallo@all,
Ich bin hier schon seit 2 Tagen drann mit I2C zu spielen und verzweifle bald.

Ich möchte von einem Tiny85 Daten erhalten und Blick hier einfach nicht durch.

Der Tiny soll als Infrarot empfänger immer dann den Tastenwert an den Duemilanove schicken wenn er sich ändert.

Für den Tiny habe ich folgende Library gefunden GitHub - rambo/TinyWire: My modifications to TinyWire Arduino libs

und am Duemilanove nehm ich Wire.h

Aber ich bekomme es nichteinmal hin das ich einfach nur einen Zahl vom Tiny anfordern kann.

Irgendwo fehlt mir hier der Einstieg. Aus den Beispielen werde ich auch nicht schlau.

Mir würde es schon mal reichen wenn der tiny alle 5 sekunden einen Wert von "1234" schickt und der Duemilanove den dann in ne Variable packt.

Hat jemand von euch schon einen Tiny als I2C Slave verwendet und so Abgefragt?

Danke und Gruß derRobert

Ich habe jetzt noch einmal in der Library für den Tiny gestöbert und festgestellt das es keinen onRequest Handler gibt. Aber das wäre doch eigentlich der korrekte weg oder?

Master (Duemilanove) sendet Request an Slave(Tiny) und Tiny sendet dann was er soll und der Master empfängt mittels while(Wire.available())

Wie bewerkstellige ich das jetzt ohne die onRequestfunktion?????

Danke und Gruß
derRobert

Ich habe hier noch mal einen Schaltplan gemalt um zu Zeigen wie ich das ganze verkabelt habe.

Das sollte für den Master doch funktionieren oder?
(Ist ja aus einem Beispiel)

#include <Wire.h>

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}

void loop()
{
  Wire.requestFrom(0x26, 6);    // request 6 bytes from slave device 0x26

  while(Wire.available())    // slave may send less than requested
  { 
    char c = Wire.read(); // receive a byte as character
    Serial.print(c);         // print the character
  }

  delay(500);
}

Aber wie mache ich es jetzt das der Slave sich angesprochen fühlt und dann auch was sendet?

Gruß derRobert

Hast Du Dir die Beispiele (im Speziellen "attiny85_i2c_slave.ino") angeschaut? Da gibt es onRequest und onReceive Handler.

Dein Schaltplan ist im Übrigen so klein, dass ich wirklich nichts erkennen kann (und ich habe keine schlechten Augen :slight_smile: ).

Zu Deinem Master-Beispiel-Code: Ja, das könnte funktionieren, aber meist wird ein Register-Modell angewandt, worin der Master zuerst die Register-Adresse an den Slave schickt und dann er die Anzahl Bytes nachfragt. Das ist aber nur einer von vielen möglichen Umsetzungen, aber einer, der sich bewährt hat.

Keiner ne Idee? oder ist diese Frage keiner Antwort würdig???

Dann muss ich also davon ausgehen, dass Du meine Antwort nicht mal gelesen hast?

Wenn du das Bespiel anschaust was pylon erwähnt hat dann hast du eigentlich alles. Der onRequest Handler indem Beispiel ist genau das was du suchst. Du schreibst vom Master einen Request mit der Aresser des Tiny Slaves mit der Menge der angeforderten bytes und der Tiny schickt dir dann die Bytes, wobei du dich drum kümmern musst was der Atiny dem Master schreibt.

Gruß
Der Dani

@ pylon

Leider habe ich deine Antwort nicht gesehen. Sollte wahrscheinlich öfter mal auf Reload drücken. Hatte den Tab noch offen

Jetzt wo du es sagst.... dort steht was von onRequest.

Werde mir das näher ansehen. Aber warum steht dann in der Beschreibung

"TODO: (by others!)

  • onReceive and onRequest handlers are not implimented.
  • merge this class with TinyWireM for master & slave support in one library"

Danke ich werde dann mal weiter versuchen. Und melde mich ganz bestimmt bald wieder

Da stellt sich gleich noch ne Frage....

Wenn ich nun einen Slave erstelle also meinen Tiny der wirklich nur den wert einer Variable übergeben soll. muss ich da mit registern arbeiten? bzw wie würde ich das überhaupt anstellen? Gibts da evtl ne gute Anleitung?

Gruß derRobert

Wenn ich nun einen Slave erstelle also meinen Tiny der wirklich nur den wert einer Variable übergeben soll. muss ich da mit registern arbeiten? bzw wie würde ich das überhaupt anstellen? Gibts da evtl ne gute Anleitung?

Wenn Du nur genau ein Byte als Wert zurückliefern willst und auch für die Zukunft keine Erweiterungen geplant sind, dann kannst Du Dir die Register-Sache sparen. Allerdings ist der Aufwand nur sehr gering und wenn auch nur die Möglichkeit besteht, dass in Zukunft vielleicht noch ein anderes Byte übertragen werden könnte, dann würde ich jetzt schon ein simples Register-Modell implementieren.

Eine Anleitung kenne ich nicht, das ganze ist auch sehr elementar. Der Master sendet die Register-Adresse, beim nächsten Read-Request wird der Inhalt des entsprechenden Registers retourniert. Was daran hast Du noch nicht verstanden, bzw. wo sind noch Unklarheiten?

In welcher art und weise ich ein Register Erstelle/Definiere. Also wie das auf dem Slave aus zu sehen hat. Das ist mir unklar.

Auch wenn der Tiny nie etwas anderes machen soll als die eine Variable zu senden würde ich das ganze doch richtig machen wollen. Damit ich das ganze mal lerne.

EDIT:

Öhm ja. Die Antwort könnte Lauten "Das steht in dem genanneten Beispiel, du Depp"

Ich seh da aber kein Stich. Ich brauch da ne Antwort for Dummies

Ich erkläre es Dir anhand des Beispiel-Codes.

Der onReceive-Handler nimmt als Erstes die Register-Nummer entgegen. Das erste Byte, das geschrieben wird, ist also immer die Adresse des Registers. Werden mehr als ein Byte geschrieben, sind die restlichen Bytes Inhalt. Es wird also das nächste Byte gelesen, in das adressierte Register geschrieben und die Register-Adresse eins hochgezählt. Damit wird solange fortgefahren, bis alle übertragenen Bytes aufgebraucht sind (oder das Ende der Register erreicht ist).

Der onRequest-Handler nimmt den Inhalt des addressierten Registers (die Adresse wurde beim vorangegangenen onReceive-Aufruf gesetzt) und schreibt ihn auf den Bus. Danach wird die Register-Adresse hochgezählt, damit ein vielleicht gleich folgender Lese-Zugriff den Inhalt des nächsten Registers zurückliefert.

Ein Schreibzugriff besteht also in der Regel aus dem Übermitteln der Register-Adresse und dem Senden des Register-Inhalts, wobei "abgekürzt" werden kann, indem aufeinanderfolgende Register in einem Wische geschrieben werden.
Ein Lesezugriff besteht in der Regel aus einen Schreibzugriff, der nur aus der Register-Adresse besteht und einem darauffolgenden Lesezugriff, in welchem der Slave den Inhalt dieses Registers rausschreibt. Auch hier können gleich mehrere aufeinanderfolgende Register auf einmal gelesen weden.

Ich Danke dir für deine Geduld. ich muss das jetzt erstmal irgendwie verdauen und immer wieder dein Geschriebenes und das Beispiel hoch und runter lesen.

Eventuell machts dann mal klick oder ich sollte mir ein anderes Hobby suchen :wink:

Bis jetzt verstehe ich nur Bahnhof und weis auch nicht wo das Problem genau liegt.

Ich werde mal mit den codeschnippseln spielen und sehen was passiert. (Hoffentlich sehe ich was)

EDIT: Ach ja der Schaltplan wurde Vergrößert

Wollte grad noch mal bissel spielen und jetzt weis ich wieder warum ich darauf gekommen bin das es keine onrequest handler gibt.

beim versuch zu kompilieren bekomme ich diese Meldung: error: 'class USI_TWI_S' has no member named 'onRequest'

#define I2C_SLAVE_ADDRESS 0x26 
#include <TinyWireS.h>
#ifndef TWI_RX_BUFFER_SIZE
#define TWI_RX_BUFFER_SIZE ( 16 )
#endif


void setup()
{
    TinyWireS.begin(I2C_SLAVE_ADDRESS);
    TinyWireS.onRequest(requestEvent);


    
    
}
void requestEvent()
{
  Wire.write("hello ");
}

void loop()
{
   delay(100) 
}

In der Version auf gitHub ist sie aber vorhanden:

// sets function called on slave write
void USI_TWI_S::onReceive( void (*function)(uint8_t) )
{
  usi_onReceiverPtr = function;
}

Kann es sein, dass Du eine alte Version verwendest?

ich hatte die genutzt die ich oben auch verlinkt habe. Ich werd wohl mal alles löschen und dann die libs neu downloaden. so viele sinds ja noch nicht.

kann gut sein das da was schief gelaufen ist da ich anfang des Jahres schon mal mit der Tiny I2C Geschichte experimentiert habe. Im sommer verschwindet die Bastelei allerdings in Kisten und im Herbst steht man dann erneut vor den Angefangenen Sachen :wink:

nur um auf nummer sicher zu gehen, Bitte poste mal den Link deiner Bezugsquelle.
und dann versuche ich meine zu löschen und deine dann ein zu fügen

Danke derRobert

Ich benutzte Deinen Link. Das ist ein GIT-Repository somit können dort laufend Änderungen eingespielt werden. Wenn Deine Version vom Frühling ist, dann ist das auch der Fall, denn die letzte Änderung wurde vor ca. 2 Monaten gemacht.

Bei mir steht aber auch

// sets function called on slave read
void USI_TWI_S::onRequest( void (*function)(void) )
{
  usi_onRequestPtr = function;
}

in der TinyWireS.cpp

Ich versteh die Welt nicht mehr....

Habe natürlich schon vor paar Tagen die alte gelöscht und die neue gedownloadet.