Go Down

Topic: I2C- Übertragung zu einfach gedacht? (Read 4587 times) previous topic - next topic

HotSystems

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.
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

Chris72622

#31
Mar 25, 2017, 05:49 pm Last Edit: Mar 25, 2017, 06:00 pm by Chris72622
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:

Code: [Select]
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
Bilnk wtiohut daley.

Tommy56

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
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

Chris72622

#33
Mar 25, 2017, 08:51 pm Last Edit: Mar 25, 2017, 08:52 pm by Chris72622
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
Bilnk wtiohut daley.

agmue

Hallo, ich schaue jetzt nur auf #31.

Code: [Select]
 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?
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

Chris72622

Stimmt. So sollte es nun passen:

Code: [Select]
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.
Bilnk wtiohut daley.

combie

#36
Mar 26, 2017, 09:18 am Last Edit: Mar 26, 2017, 09:20 am by combie
Quote
Code: [Select]
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


Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

Chris72622

#37
Mar 26, 2017, 12:27 pm Last Edit: Mar 26, 2017, 12:40 pm by Chris72622
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":

Code: [Select]
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
Bilnk wtiohut daley.

combie

Code: [Select]
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
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

Chris72622

#39
Mar 26, 2017, 01:25 pm Last Edit: Mar 26, 2017, 01:27 pm by 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.

Gruß Chris

Anbei für evtl. Interessierte:

Code: [Select]
// 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
}


Code: [Select]
// 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);
  }
}
Bilnk wtiohut daley.

HotSystems

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.
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

Chris72622

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:

Code: [Select]
Serial.println((byte *)&x, sizeof(x));

Gruß Chris
Bilnk wtiohut daley.

combie

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.
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

Chris72622

Was willst du dir denn da anzeigen lassen?
Den Inhalt der übertragenen Bytes.

Gruß Chris
Bilnk wtiohut daley.

Tommy56

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
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

Go Up