I2C- Übertragung zu einfach gedacht?

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

// 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);
}
/*  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
  }
}

Leider werden die beiden zu übertragenden Werte 4116 und 4117 nicht übertragen, sondern irgendetwas Anderes.

Wire.write(value)
...
value: a value to send as a single byte

Aus: Doku

Fangfrage:
Ist "unsigned int zu = 4116;" ein " single byte" ?

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

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.

Meinst Du so?

Wire.write(zu & 0xff);         // Schaltet die Funksteckdose aus
  Wire.write(zu >> 8);

Gruß Chris

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?

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.

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.

Hab entsprechende Anpassungen im Eröffnungsposting vorgenommen.

Sorry, für die Konfusion.

Gruß Chris

, 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.

Wire.write(zu, 4); führt leider zu einer Fehlermeldung.

Ein einfaches Ausprobieren, ist keine tragfähige Strategie.

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:

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

combie:
..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

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 :wink:

Gruß Tommy

Spitze, danke.

Gruß Chris

Chris72622:
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

Ich danke Dir.

Gruß Chris

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.

hi,

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

oder versteh' ich das falsch?

gruß stefan

HotSystems:
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

Chris72622:
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.

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