Die Adresse in Hex macht es leichter lesbar wenn man sie aus der Binärdarstellung ableiten muss. I2C Adressen sind oft aus 3-4 festen Bits und 3-4 über Pins einstellbaren Bits zusammengesetzt.
gutes beispiel, fliege. hatten wir erst vorgestern_
http://forum.arduino.cc/index.php?topic=465004.0
gruß stefan
hi,
nicht versucht, aber wäre eine union aus unsigned long und einem array hier eine vereinfachende lösung oder unschön?
gruß stefan
Chris72622:
Ok, danke für den Hinweis.Achtung Anfänger:
Die Bezeichnungen I2C-SENDER und I2C-EMPFÄNGER innerhalb meiner Sketche beziehen sich ausschließlich auf meinen Anwendungsfall.
Danke, dass du es geändert hast.
Gerne.
Ich hänge hier jetzt mal noch etwas zu dem Thema Passendes an, um nicht einen weiteren Thread zu eröffnen.
Durch das schnelle Wachstum des Projekts ergab sich mittlerweile der Umstand, dass in Zukunft mehrere ATtiny85 (I2C-Slaves) angesprochen werden sollen.
Dies bedingt, dass mit der Speicherung der zu übertragenden Werte zusätzlich nun jeweils die Slave-ID mitgespeichert werden muss.
Um dies zu ermöglichen erstellte ich zwei Arrays, die jeweils auf identische Art und Weise ausgelesen werden. Ich meine damit, dass wenn z.B. beim "unsigned long Wertearray" (im Sketch fifo genannt) der Index 2 ausgelesen wird, ich im "byte Slave-ID-Array" (im Sketch fifoID genannt) ebenfalls den gleichen Index auslese.
Nun frage ich mich, wie ich den folgenden schlecht lesbaren Abschnitt lesbarer machen und evtl. vereinfachen und/oder verbessern/kürzen kann:
void tinySend()
{
Wire.beginTransmission(fidoIDread()); // Startet die I2C-Übertragung an einen definierten ATtiny85
Wire.write(fifoRead()); // Senden des Wertes
Wire.endTransmission(); // Stoppt die I2C-Übertragung
}
byte fidoIDread() // Übergibt die Slave-ID des ATtiny85 an den ein Wert gesendet werden soll
{
return fifoID[fifoReadIndex]; // Slave-ID zum Abschluss aus der Funktion übergeben
}
unsigned long fifoRead() // Lesefunktion
{
unsigned long c; // unsigned long initialisieren
c = fifo[fifoReadIndex]; // Wert aus Ringbuffer lesen
fifoReadIndex++; // Leseindex um eine Stelle erhöhen
if (fifoReadIndex >= FIFOSIZE) fifoReadIndex = 0; // Beim erreichen des Arrayendes den Leseindex auf null zurücksetzen
return c; // Zeichen zum Abschluss aus der Funktion übergeben
}
Es geht hierbei konkret um das Auslesen der beiden o.a. Arrays, gefolgt vom Sendevorgang.
Gruß Chris
Hast Du Dich schon mal in Deinem Buch über struct schlau gemacht und Arrays aus Structs?
Gruß Tommy
PS: "fifo" hat in der IT eine fest definierte Bedeutung, die in Deinem Sketch wohl nicht gegeben ist. Du solltest es anders nennen.
Gruß Tommy
Jein. Von "structs" las ich mal. Arrays aus ihnen sind mir gänzlich fremd. Mein C++ Schmöker liegt nun wieder im Wohnzimmer. Ein zweiter Anlauf sollte vieles nachhaltig klären. Ab heute wird wieder gelesen.
Das fifo-Array funktioniert wie ein Ringpuffer und wurde innerhalb meines Sketches eben deshalb von mir so benannt.
Gruß Chris
Hallo, ich schaue jetzt nur auf #31.
Wire.write(fifoRead());
...
unsigned long fifoRead()
{
unsigned long c;
...
return c;
}
Mit write kannst Du nur ein Byte schicken, unsigned long hat derer vier. Da paßt was nicht, oder?
Stimmt. So sollte es nun passen:
void tinySend()
{
Wire.beginTransmission(fidoIDread()); // Startet die I2C-Übertragung an einen definierten ATtiny85
unsigned long x = fifoRead(); // Laden des unsigned long aus dem fifo-Array
byte longArray[4]; // Beinhaltet den unsigned long Wert (aufgeteilt in vier Bytes)
longArray[0] = x >> 24; // Das erste Byte des unsigned long
longArray[1] = x >> 16; // Das zweite Byte des unsigned long
longArray[2] = x >> 8; // Das dritte Byte des unsigned long
longArray[3] = x & 0xFF; // Das letzte Byte des unsigned long
Wire.write(longArray, 4); // Sendet das komplette unsigned long (über longArray)
Wire.endTransmission(); // Stoppt die I2C-Übertragung
}
byte fidoIDread() // Übergibt die Slave-ID des ATtiny85 an den ein Wert gesendet werden soll
{
return fifoID[fifoReadIndex]; // Slave-ID zum Abschluss aus der Funktion übergeben
}
unsigned long fifoRead() // Lesefunktion
{
unsigned long c; // unsigned long initialisieren
c = fifo[fifoReadIndex]; // Wert aus Ringbuffer lesen
fifoReadIndex++; // Leseindex um eine Stelle erhöhen
if (fifoReadIndex >= FIFOSIZE) fifoReadIndex = 0; // Beim erreichen des Arrayendes den Leseindex auf null zurücksetzen
return c; // Zeichen zum Abschluss aus der Funktion übergeben
}
Werd mich aber trotzdem mal in die structs einlesen.
unsigned long x = fifoRead(); // Laden des unsigned long aus dem fifo-Array
byte longArray[4]; // Beinhaltet den unsigned long Wert (aufgeteilt in vier Bytes)
longArray[0] = x >> 24; // Das erste Byte des unsigned long
longArray[1] = x >> 16; // Das zweite Byte des unsigned long
longArray[2] = x >> 8; // Das dritte Byte des unsigned long
longArray[3] = x & 0xFF; // Das letzte Byte des unsigned long
Wire.write(longArray, 4); // Sendet das komplette unsigned long (über longArray)
unsigned long x = fifoRead(); // Laden des unsigned long aus dem fifo-Array
~~ byte longArray[4]; // Beinhaltet den unsigned long Wert (aufgeteilt in vier Bytes)~~
~~ longArray[0] = x >> 24; // Das erste Byte des unsigned long~~
~~ longArray[1] = x >> 16; // Das zweite Byte des unsigned long~~
~~ longArray[2] = x >> 8; // Das dritte Byte des unsigned long~~
~~ longArray[3] = x & 0xFF; // Das letzte Byte des unsigned long~~
Wire.write((byte *)&x, sizeof(x)); // Sendet das komplette unsigned long x
Hi combie,
ich bekomme das so wie von Dir vorgeschlagen via 433MHz leider nicht gesendet, wenn ich an der Empfängerseite (I2C-Slave) dann so "decodiere":
void i2cReceive()
{
unsigned long val = 0;
if (TinyWireS.available())
{
digitalWrite(ledPin, HIGH);
while (TinyWireS.available())
{
val <<= 8; // Bitshift nach links
val |= TinyWireS.receive(); // Hinzufügen der untersten acht Bits
}
for (int i = 0; i < sendCnt - 1; i++) myTx.send(val, 24);
digitalWrite(ledPin, LOW);
}
}
Gruß Chris
void i2cReceive()
{
unsigned long val = 0;
byte * p = (byte*) &val;
if (TinyWireS.available())
{
digitalWrite(ledPin, HIGH);
for (int i = 0; i < sizeof(val); i++)
*p++ = TinyWireS.receive();
for (int i = 0; i < sendCnt - 1; i++) myTx.send(val, 24);
digitalWrite(ledPin, LOW);
}
}
leider ungetestet
Habe gerade nicht die nötige Infrastruktur im Zugriff
Es funktioniert! Vielen Dank für Deine Hilfe.
Der Code ist nun eine gute Basis für mich zum Üben. Mir ist (noch) nicht klar, was da innerhalb der gesendeten Bytes übertragen wird.
Gruß Chris
Anbei für evtl. Interessierte:
// I2C-SENDER (MASTER)
#include <Wire.h>
const unsigned long valA = 1397079; // Das zu sendende unsigned long ("Leselampe ein")
const unsigned long valB = 1397080; // Das zu sendende unsigned long ("Leselampe aus")
const unsigned long valC = 4116; // Das zu sendende unsigned long ("Dunstabzugshaube aus")
const unsigned long valD = 4117; // Das zu sendende unsigned long ("Dunstabzugshaube ein")
static byte id = 0x26; // ID des ATtiny85
void setup()
{
delay(1000);
Wire.begin(); // Masterdresse optional (wird hier nicht verwendet)
i2cSend(valA, id);
}
void loop()
{
}
void i2cSend(unsigned long x, byte y) // x = zu sendender Wert, y = ID des ATtiny85
{
Wire.beginTransmission(y); // Startet die I2C-Übertragung an 0x26 (ATtiny85)
Wire.write((byte *)&x, sizeof(x)); // Sendet das komplette unsigned long
Wire.endTransmission(); // Stoppt die I2C-Übertragung
}
// I2C-EMPFÄNGER (SLAVE)
#include "TinyWireS.h" // wrapper class for I2C slave routines
#include <RCSwitch.h>
#define I2C_SLAVE_ADDR 0x26 // I2C Slave-Adresse (38)
// 433MHz Modul
RCSwitch myTx = RCSwitch();
const byte txPin = 4; // Ausgang Sender-Daten an ATtiny Pin 3 (kein Tippfehler!)
const byte sendCnt = 4; // max. Anzahl der Aussendungen
const byte ledPin = 3; // Pin 2 (kein Tippfehler!)
void setup()
{
TinyWireS.begin(I2C_SLAVE_ADDR); // init I2C Slave mode
pinMode (txPin, OUTPUT); // 433MHz Modul
pinMode (ledPin, OUTPUT); // LED
myTx.enableTransmit(txPin); // Übertragung ermöglichen
myTx.setPulseLength(375); // Pulsweite
}
void loop()
{
i2cReceive();
}
void i2cReceive()
{
unsigned long val = 0;
byte * p = (byte*) &val;
if (TinyWireS.available())
{
digitalWrite(ledPin, HIGH);
for (int i = 0; i < sizeof(val); i++) *p++ = TinyWireS.receive();
for (int i = 0; i < sendCnt - 1; i++) myTx.send(val, 24);
digitalWrite(ledPin, LOW);
}
}
Chris72622:
Es funktioniert! Vielen Dank für Deine Hilfe.Der Code ist nun eine gute Basis für mich zum Üben. Mir ist (noch) nicht klar, was da innerhalb der gesendeten Bytes übertragen wird
Dann lass dir doch jedes einzelne Byte auf dem seriellen Monitor oder auf einem LCD anzeigen.
Ja, das war auch mein Gedanke. Leider habe ich aber zum Einen nur einen Uno und einen ATtiny85 hier und zum Anderen führte folgende Eingabe nur zu Fehlermeldungen:
Serial.println((byte *)&x, sizeof(x));
Gruß Chris
Was willst du dir denn da anzeigen lassen?
Weiterhin:
Solange du die Sprache, welche du verwendest, nicht beherrscht, bleibt eine Arbeit ein wildes chaotisches stochern im Nebel.
Merksatz:
Nacktes "Ausprobieren" ist keine tragfähige Strategie um stabile, fehlerfreie, Programme zu erstellen.
combie:
Was willst du dir denn da anzeigen lassen?
Den Inhalt der übertragenen Bytes.
Gruß Chris
Ich kann es nur wiederholen: Du verstehst von dem, was Du tust, fast nichts.
Du fragst so lange, bis Dir jemand einen Codeschnipsel gibt, den kopierst Du rein und hast keinerlei Interesse, ihn zu verstehen. Anders kann man das nach knapp 1300 Posts nicht mehr ausdrücken.
Du musst das Buch lesen, das Du immer erwähnst, und verstehen was Du kopierst, nicht nur das Buch irgendwo hin legen und so weiter machen, wie bisher.
Gruß Tommy
Ich bin dabei, danke.
Gruß Chris