Arduino Forum

International => Deutsch => Topic started by: Chris72622 on Mar 24, 2017, 01:19 pm

Title: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 24, 2017, 01:19 pm
Hallo,

ich habe hier einen Uno und einen ATtiny85, an dem ein billig 433MHz-Chinasender hängt.

Der Sender soll ein vom Uno gesendeten unsigned Int via 433MHz ausgeben.

Der ATtiny85 sendet bei jeder eingehenden Übertragungsaufforderung via 433MHz, was an seiner leuchtenden Status-LED (ledPin) zu erkennen ist. Der Sender ist nicht defekt und I2C Pullups sind verbaut.

Leider werden die beiden zu übertragenden Werte 4116 und 4117 nicht via 433MHz übertragen, sondern irgendwelche anderen Werte. Weiss nun leider nicht wo der Fehler begraben liegt.

Gruß Chris

Code: [Select]
// I2C-SENDER (MASTER)

#include <Wire.h>

unsigned int zu = 4116;
unsigned int auf = 4117;

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

void loop()
{
  Serial.println("zu");
  Wire.beginTransmission(0x26);  // Startet die I2C-Übertragung an 0x26 (ATtiny85)
  Wire.write(zu);                // Schaltet alle Funksteckdosen aus
  Wire.endTransmission();        // Stoppt die I2C-Übertragung
  delay(2000);
  Serial.println("auf");
  Wire.beginTransmission(0x26);  // Startet die I2C-Übertragung an 0x26 (ATtiny85)
  Wire.write(auf);               // Schaltet alle Funksteckdosen aus
  Wire.endTransmission();        // Stoppt die I2C-Übertragung
  delay(2000);
}


Code: [Select]
/*  I2C-EMPFÄNGER (SLAVE)
 *   
 *   Am ATtiny hängt der 433MHz Sender. Der passende 433MHz-Empfänger ist eine Funksteckdose.
 *   
 *   Anschluss des Attiny85 an den Uno:

                    1 |  \/  | 8  5V
                    2 |      | 7  SCL, Arduino A5, 4,7kOhm Pullup
   433MHz TX-Modul  3 |      | 6
               GND  4 |      | 5  SDA, Arduino A4, 4,7kOhm Pullup
 *   
 */

#include "TinyWireS.h"                  // wrapper class for I2C slave routines
#include <RCSwitch.h>

#define I2C_SLAVE_ADDR  0x26            // i2c slave address (38)

// 433MHz Modul

RCSwitch myTx = RCSwitch();

const byte txPin = 4;                   // Ausgang Sender-Daten an ATtiny Pin 3  (kein Tippfehler!)
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
  myTx.setRepeatTransmit(10);           // Anzahl der Sendewiederholungen innerhalb der Library
}

void loop()
{
  if (TinyWireS.available())
  {
    digitalWrite(ledPin, HIGH);                                                       // LED einschalten
    myTx.send(TinyWireS.receive(), 24);
    digitalWrite(ledPin, LOW);                                                        // LED ausschalten
  }
}
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: combie on Mar 24, 2017, 01:27 pm
Quote
Leider werden die beiden zu übertragenden Werte 4116 und 4117 nicht übertragen, sondern irgendetwas Anderes.
Quote
Wire.write(value)
...
value: a value to send as a single byte
Aus: Doku (https://www.arduino.cc/en/Reference/WireWrite)

Fangfrage:
Ist "unsigned int zu = 4116;" ein " single byte" ?
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 24, 2017, 01:37 pm
Nein.

Heisst das im Klartext, dass ich die einzelnen Ziffern des zu sendenden unsigned longs (4, 1, 1 und die 6) zunächst einmal einzeln via TinyWireS.receive() "entgegennehmen" und z.B. in ein Array schreiben muss, bevor ich dieses Array dann wiederum z.B. mit einer for-Schleife auslesen und den Wert dann so via 433MHz senden kann?

Gruß Chris
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: ElCaron on Mar 24, 2017, 01:48 pm
Nein, Du solltest Deine Zahl ganz sicher nicht in Ziffern zerlegen. Das macht für ein binäres System überhaupt keinen Sinn. Eine Möglichkeit wäre, deinen int in ein high und ein low byte zu aufzuteilen und am Ende die beiden zusammenzufügen. Siehe dazu bitshift-Operatoren.
Ob es eine einfachere Möglichkeit gibt, habe ich mangels Blick auf die Lib nicht kontrolliert.

Davon abgesehen würde ich den Code erstmal irgendwohin senden, wo ich das Ergebnis lesen kann. Muss ja kein Tiny sein, sondern kann auch ein anderer Arduino sein.
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 24, 2017, 01:51 pm
Meinst Du so?

Code: [Select]
Wire.write(zu & 0xff);         // Schaltet die Funksteckdose aus
  Wire.write(zu >> 8);


Gruß Chris
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: combie on Mar 24, 2017, 01:56 pm
Deinem Posting entnehme ich, dass du dem Link nicht gefolgt bist, bzw. das dort geschriebene nicht verstanden hast.

Ich versuche es dir mal zu übersetzen:

Wire::write() gibt es mit 3 verschiedenen Signaturen.

Eine Variante habe ich dir schon in der Luft zerrissen.
Eine zweite (string)  scheint mir für eine integer Zahl nicht angemessen.

Eine dritte, und letzte, bleibt übrig.
Was gibt es gegen diese einzuwenden?
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 24, 2017, 01:59 pm
Hi combie, ich habs mir jetzt nochmals genau angeschaut und habe das Problem, dass ich im Bezug auf den dort zu lesenden Text mit dem Begriff "data" nichts anfangen kann.

Gruß Chris

Edit: Wire.write(zu, 4); führt leider zu einer Fehlermeldung.
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: HotSystems on Mar 24, 2017, 02:03 pm
Durch deine Sketch ist ganz schwer durchzusteigen.

Was ist Sender und Empfänger ?

Im Sender sehe ich keinen Funk-Sender, warum heißt es Sender ?

Im Empfänger sehe ich einen Funk-Sender, warum heißt es Empfänger ?

Da solltest du mal aufräumen, damit alle die dir helfen wollen auch sofort klarkommen.

Wenn du von I2C sprichst, nenne es bitte Master und Slave.
Wenn du von Funk sprichst, dann ist es Sender und Empfänger.

Bitte ändere es in deinem Sketch, damit keine Irrtümer entstehen.
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 24, 2017, 02:09 pm
Hab entsprechende Anpassungen im Eröffnungsposting vorgenommen.

Sorry, für die Konfusion.

Gruß Chris
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: combie on Mar 24, 2017, 02:12 pm
Quote
, dass ich im Bezug auf den dort zu lesenden Text mit dem Begriff "data" nichts anfangen kann.
Hmmm....
Dann wäre es kein Fehler, sich mal mit den Grundlagen der Sprache zu beschäftigen, welche du da verwendest.

Denn:
Es ist kontraproduktiv, Dinge auszublenden, nur weil man sie nicht begreift.

Quote
Wire.write(zu, 4); führt leider zu einer Fehlermeldung.
Ein einfaches Ausprobieren, ist keine tragfähige Strategie.


Code: [Select]
Wire.write((byte *)&zu,sizeof(zu));                // Schaltet alle Funksteckdosen aus
Und nein, den Ausdruck erkläre ich dir jetzt nicht.
Das kannst du in jedem beliebigen (halbwegs guten) C/C++ Buch/Tutorial nachlesen.
Und ja!
Das wirst du noch an 1000 Ecken gebrauchen.


--------
wobei, dieses ist auch funktional, nicht schön, aber funktional:
Code: [Select]

Wire.write(zu & 0xff);       
Wire.write(zu >> 8);



Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 24, 2017, 04:32 pm
..den Ausdruck erkläre ich dir jetzt nicht.
Schade, da es sehr schwierig für mich ist herauszufinden wonach ich suchen soll.

Da ich hier ein Buch bzgl. C++ Programmierung liegen habe, könnte ich mir vorstellen, dass mir die Nennung eines Begriff nach dem ich suchen könnte evtl. helfen könnte.

Gruß Chris
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Tommy56 on Mar 24, 2017, 04:35 pm
Also bei > 1250 Postings sollten doch nun langsam mal ein paar Grundlagen hängen geblieben sein. Das Buch ist zum Lesen und Verstehen, nicht nur zum Hinlegen ;)

Gruß Tommy
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 24, 2017, 04:48 pm
Spitze, danke.

Gruß Chris
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: combie on Mar 24, 2017, 04:50 pm
Schade, da es sehr schwierig für mich ist herauszufinden wonach ich suchen soll.

Da ich hier ein Buch bzgl. C++ Programmierung liegen habe, könnte ich mir vorstellen, dass mir die Nennung eines Begriff nach dem ich suchen könnte evtl. helfen könnte.

Du sollst nicht in dem Buch suchen, sondern das Buch lesen!
Ganz!

----------------------

Stichworte?

Gerne:
Adress Operator
Pointer
Cast
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 24, 2017, 04:52 pm
Ich danke Dir.

Gruß Chris
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: HotSystems on Mar 24, 2017, 05:12 pm
Wenn du Probleme hast, 4-stellige Zahlen zu versenden, warum fängst du nicht einfacher an und schickst ein Byte (256) ?
Wenn das funktioniert kannst du dich doch an deine endgültige Version machen.
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Eisebaer on Mar 24, 2017, 05:24 pm
hi,

klar kann man das in C/C++ machen, aber warum nicht das (arduino-) highByte und lowByte?

oder versteh' ich das falsch?

gruß stefan
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 24, 2017, 06:02 pm
Wenn du Probleme hast, 4-stellige Zahlen zu versenden, warum fängst du nicht einfacher an und schickst ein Byte (256) ?
Wenn das funktioniert kannst du dich doch an deine endgültige Version machen.
Weil ich Funksteckdosen habe, die z.B. solch einen Befehl erwarten:

myTx.send(1394004, 24);

Bisher habe ich es so gemacht, dass ich die einzelnen zu sendenden Befehle im ATtiny hinterlegt habe und diese dann bei Empfang einzelner bestimmten Zeichen via 433MHz versendet wurden. Sprich, kam ein 'A' an, wurde "Befehl A" gesendet, usw.

Damit ich nun nicht immer den ATtiny mit neu dazugekommenen Befehlen "füttern" muss, würde ich die zu sendenden "Befehle"/ Zahlen nun gerne direkt via I2C übertragen. Dazu kommt, dass der ATtiny leider etwas verbaut ist und ich es auch so pauschal gerne mal wissen würde, wie "man" das macht.

Gruß Chris
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: HotSystems on Mar 24, 2017, 06:06 pm
Weil ich Funksteckdosen habe, die z.B. solch einen Befehl erwarten:
Ok, dann musst du dich ranmachen und entsprechend der Doku den Code erstellen.
Wobei das nun gut beschrieben ist.
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Eisebaer on Mar 24, 2017, 08:45 pm
hi,

also geht's ja nicht unbedigt um 2 byte, das kann ja laut Deinem beispiel auch länger sein.

wenn Du in google nach arduino longint i2c suchst, findest Du einiges (ich hab' das problem nicht, will nicht wirklich lesen). aber dann ist vielleicht auch das senden als einzelne ziffern eine option.

gruß stefan
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: ElCaron on Mar 25, 2017, 07:54 am
aber dann ist vielleicht auch das senden als einzelne ziffern eine option.
Nochmal: Warum zum Geier sollte man irgendwas in DEZIMALZIFFERN aufteilen? Konvertiert doch gleich ins Sexagesimalsystem, macht auch keinen Sinn, ist aber etwas effizienter.
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 25, 2017, 09:09 am
So, mit einem unsigned int läuft es nun. Hab viel gelernt.

Anbei die Sketche. Zuerst unsigned int, dann unsigned long.

Mit der unsigned long Variante müsste man theoretisch auch kleinere Datentypen als unsigned long via I2C senden können. Dies muss ich jedoch erst noch genauer untersuchen.

Gruß Chris

Code: [Select]
//  I2C-SENDER

#include <Wire.h>

unsigned int zu = 4116;
unsigned int auf = 4117;

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

void loop()
{
  Serial.println("zu");
  Wire.beginTransmission(0x26);  // Startet die I2C-Übertragung an 0x26 (ATtiny85)
 
  // Wire.write(zu >> 8);    // Sendet zuerst das obere Byte des Integers (b00010100, d20) via Bit-Verschiebung
  // Wire.write(zu & 0xff);  // Sendet dann das untere Byte des Integers (b00010000, d16) via Maskierung
 
  Wire.write(highByte(zu));  // Sendet zuerst das obere Byte des Integers
  Wire.write(lowByte(zu));   // Sendet dann das untere Byte des Integers
 
  Wire.endTransmission();        // Stoppt die I2C-Übertragung
  delay(10000);
  Serial.println("auf");
  Wire.beginTransmission(0x26);  // Startet die I2C-Übertragung an 0x26 (ATtiny85)
  // Wire.write((byte *)&auf, sizeof(auf));
  Wire.write(highByte(auf));  // Sendet zuerst das obere Byte des Integers
  Wire.write(lowByte(auf));   // Sendet dann das untere Byte des Integers
  Wire.endTransmission();        // Stoppt die I2C-Übertragung
  delay(10000);
}


Code: [Select]
/*  I2C-EMPFÄNGER

    Anschluss des Attiny85 an den Uno:

                    1 |  \/  | 8  5V
                    2 |      | 7  SCL, Arduino A5, 4,7kOhm Pullup
   433MHz TX-Modul  3 |      | 6
               GND  4 |      | 5  SDA, Arduino A4, 4,7kOhm Pullup

*/

#include "TinyWireS.h"                  // wrapper class for I2C slave routines
#include <RCSwitch.h>

#define I2C_SLAVE_ADDR  0x26            // i2c slave address (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()
{
  unsigned int val = 0;
  if (TinyWireS.available())
  {
    while (TinyWireS.available())
    {
      val = TinyWireS.receive();      // highByte
      val <<= 8;
      val |= TinyWireS.receive();     // lowByte
    }
    digitalWrite(ledPin, HIGH);
    for (int i = 0; i < sendCnt - 1; i++)
    {
      myTx.send(val, 24);
    }
    digitalWrite(ledPin, LOW);
  }
}


..google nach arduino longint i2c suchst
Ja, danke. Sehr interessant (https://thewanderingengineer.com/2015/05/06/sending-16-bit-and-32-bit-numbers-with-arduino-i2c/).

unsigned int-Variante:

Code: [Select]
//  I2C-SENDER

#include <Wire.h>

unsigned long val = 1397079;  // Das zu sendende unsigned long ("Leselampe aus")

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

void loop()
{
  Serial.println("zu");
  Wire.beginTransmission(0x26);  // Startet die I2C-Übertragung an 0x26 (ATtiny85)
 
  byte longArray[4];            // Beinhaltet den unsigned long Wert (aufgeteilt in vier Bytes)

  longArray[0] = val >> 24;     // Das erste Byte des unsigned longs
  longArray[1] = val >> 16;     // Das zweite Byte des unsigned longs
  longArray[2] = val >> 8;      // Das dritte Byte des unsigned longs
  longArray[3] = val & 0xFF;    // Das letzte Byte des unsigned longs

  Wire.write(longArray, 4);     // Sendet das komplette unsigned long (über longArray)

  Wire.endTransmission();        // Stoppt die I2C-Übertragung
  delay(5000);
}


Code: [Select]
/*  I2C-EMPFÄNGER

    Anschluss des Attiny85 an den Uno:

                    1 |  \/  | 8  5V
                    2 |      | 7  SCL, Arduino A5, 4,7kOhm Pullup
   433MHz TX-Modul  3 |      | 6
               GND  4 |      | 5  SDA, Arduino A4, 4,7kOhm Pullup

*/

#include "TinyWireS.h"                  // wrapper class for I2C slave routines
#include <RCSwitch.h>

#define I2C_SLAVE_ADDR  0x26            // i2c slave address (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()
{
  unsigned long val = 0;
  if (TinyWireS.available())
  {
    while (TinyWireS.available())
    {
      val <<= 8;
      val |= TinyWireS.receive();
    }
    digitalWrite(ledPin, HIGH);
    for (int i = 0; i < sendCnt - 1; i++) myTx.send(val, 24);
    digitalWrite(ledPin, LOW);
  }
}
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: HotSystems on Mar 25, 2017, 12:10 pm
Und schon wieder diese merkwürdige Bezeichnung für I2C: "Sender und Empfänger", die gibt es nicht.
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 25, 2017, 12:59 pm
Was ist denn daran merkwürdig?

Der Sender sendet einen I2C-Befehl an den Empfänger dieser Nachricht.
Dieser wiederum hat einen 433MHz-Sender verbaut, der den entsprechenden Befehl umsetzt.

Gruß Chris
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: HotSystems on Mar 25, 2017, 01:11 pm
Was ist denn daran merkwürdig?

Der Sender sendet einen I2C-Befehl an den Empfänger dieser Nachricht.
Dieser wiederum hat einen 433MHz-Sender verbaut, der den entsprechenden Befehl umsetzt.

Gruß Chris
Weil es keinen eindeutigen Sender bzw. Empfänger bei I2C gibt.
Es sind immer noch Master und Slave.
Die können immer beides, senden und empfangen.
Ein Master kann von sich aus senden, ein Slave erst auf Anforderung.

Ich erwähne es nur, damit Anfänger keine falschen Infos erhalten.
Und du hast es doch in deinem Anfangspost auch schon geändert.
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 25, 2017, 01:26 pm
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.

Welchen Sinn macht es eigentlich, dass Slaveadressen meistens (immer?) hexadezimal angegeben werden?

Gruß Chris

Edit: Anbei nun die zwei finalen Sketche, mit denen sich Werte von bool bis unsigned long an einen definierten Slave übertragen lassen. valA bis valD dienen zur testweisen Übertragung vordefinierter Werte. Bzgl. Optimierungspotential bitte ich um Hinweise.

Code: [Select]
// I2C-SENDER (MASTER)

#include <Wire.h>

static unsigned long valA = 1397079;  // Das zu sendende unsigned long ("Leselampe ein")
static unsigned long valB = 1397080;  // Das zu sendende unsigned long ("Leselampe aus")

static unsigned long valC = 4116;  // Das zu sendende unsigned long ("Dunstabzugshaube aus")
static 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(valB, 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)
  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
}


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;

  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);
  }
}
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Eisebaer on Mar 25, 2017, 02:40 pm
hi,

Quote
Welchen Sinn macht es eigentlich, dass Slaveadressen meistens (immer?) hexadezimal angegeben werden?
keinen natürlich...

das einzige, das noch sinnloser ist, ist das:


Quote
static byte id = 0x26;               // ID des ATtiny85
#define I2C_SLAVE_ADDR  0x26            // I2C Slave-Adresse (38)
mal so, mal so, und dann schreibst Du im  kommentar, wie Du es WIRKLICH denkst. dann schreib' es doch gleich dezimal hin.
ist Dein gutes recht, wenn Du dezimal denkst.

wenn man schon länger programmiert, tut man sich binär einfach leichter, weil auch der prozessor/controller so denkt. hex ist dann nur eine kurze schreibweise für binär.

gerade bei der kommunikation ist es extrem hilfreich, immer vor sich zu sehen, was sich "auf der leitung" wirklich abspielt, elektrisch gesehen. ein logic analyser kann einem da die augen öffnen.

gruß stefan
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Serenifly on Mar 25, 2017, 03:03 pm
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.
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Eisebaer on Mar 25, 2017, 03:46 pm
gutes beispiel, fliege. hatten wir erst vorgestern_

http://forum.arduino.cc/index.php?topic=465004.0

gruß stefan
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Eisebaer on Mar 25, 2017, 05:01 pm
hi,

nicht versucht, aber wäre eine union aus unsigned long und einem array hier eine vereinfachende lösung oder unschön?

gruß stefan
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: HotSystems on Mar 25, 2017, 05:23 pm
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.
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 25, 2017, 05:49 pm
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
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Tommy56 on Mar 25, 2017, 06:52 pm
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
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 25, 2017, 08:51 pm
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
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: agmue on Mar 25, 2017, 10:05 pm
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?
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 26, 2017, 08:33 am
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.
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: combie on Mar 26, 2017, 09:18 am
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


Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 26, 2017, 12:27 pm
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
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: combie on Mar 26, 2017, 01:09 pm
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
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 26, 2017, 01:25 pm
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);
  }
}
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: HotSystems on Mar 26, 2017, 03:31 pm
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.
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 26, 2017, 03:35 pm
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
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: combie on Mar 26, 2017, 04:04 pm
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.
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 26, 2017, 07:24 pm
Was willst du dir denn da anzeigen lassen?
Den Inhalt der übertragenen Bytes.

Gruß Chris
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Tommy56 on Mar 26, 2017, 08:01 pm
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
Title: Re: I2C- Übertragung zu einfach gedacht?
Post by: Chris72622 on Mar 26, 2017, 08:07 pm
Ich bin dabei, danke.

Gruß Chris