ich möchte gern an einen Attiny85 einen Reedschalter als Interrupt überwachen. Dabei sollen die Anzahl der Schaltvorgänge so wie die Zeit dazwischen gemessen werden. Diese Variablen, shortesIntervall und durchschnittIntervall, möchte ich circa alle 5 Minuten vom Master (ESP8266) via I2c abfragen lassen. Beide Werte sind Ganzzahlen von 10 bis 2350. Anschließend werden sie zurück gesetzt.
Die Funktion der Überwachung des Reedschalter habe ich schon, nun wollte ich mich mit der Übertragung beschäftigen. Doch leider komme ich da nicht weiter. Bei der Recherche bin ich auf diesen Forum Eintrag gestoßen.
Ich versuchte die Option mit der Union.
Als Ergebnis im Serial Monitor bekomme ich aber nicht die erwartet werte von
Die Verkabelung und das Installieren der Sketche funktioniert. Da das Beispiel Sketch von Attinycore Slaversender und Mastereader funktioniert. Nun weis ich nicht wo der Fehler ist oder sein kann.
sollte Verdacht auf Code fallen, könntest du ihn uns zum Prüfen posten. Beide Sketches.
Und falls du Interesse hast die Schematik zu zeigen, wird sie auch geprüft.
Hast du am Bus Pullup-Widerstände dran und wie lang ist dein Kabel zwischen dem Master und Slave ?
Das wir deine Sketche benötigen, wurde ja schon geschrieben.
#include <Wire.h>
const int SLAVE_ADR = 2;
union data_u
{
struct
{
int value1;
int value2;
int value3;
int value4;
int value5;
};
byte bytes[10];
};
data_u data;
void setup()
{
Serial.begin(9600);
Serial.println("Master");
Wire.begin();
getData();
}
void loop()
{
}
void getData()
{
Wire.requestFrom(SLAVE_ADR, sizeof(data));
for (unsigned int i = 0; i < sizeof(data); i++)
data.bytes[i] = Wire.read();
Serial.println(data.value1);
Serial.println(data.value2);
Serial.println(data.value3);
Serial.println(data.value4);
Serial.println(data.value5);
}
und der Slave Code
#include <Wire.h>
const int SLAVE_ADR = 2;
union data_u
{
struct
{
int value1;
int value2;
int value3;
int value4;
int value5;
};
byte bytes[10];
};
data_u data;
void setup()
{
data.value1 = 1;
data.value2 = 4;
data.value3 = 12;
data.value4 = 30000;
data.value5 = -10000;
Wire.begin(SLAVE_ADR);
Wire.onRequest(requestEvent);
}
void loop()
{
}
void requestEvent()
{
Wire.write(data.bytes, sizeof(data));
}
Das Beispiel sketch das Auch funktioniert ist folgendes.
// Wire Master Reader
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Reads data from an I2C/TWI slave device
// Refer to the "Wire Slave Sender" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#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(8, 6); // request 6 bytes from slave device #8
//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);
}
und
// Wire Slave Sender
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Sends data as an I2C/TWI slave device
// Refer to the "Wire Master Reader" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
void setup() {
Wire.begin(8); // join i2c bus with address #8
Wire.onRequest(requestEvent); // register event
}
void loop() {
delay(100);
}
// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
Wire.write("hellos "); // respond with message of 6 bytes
// as expected by master
}
aktuell ist alles noch auf ein Breakboard daher eher kurze Kabel <10cm
Adressen bis 8 sind reserviert für spezielle Funktionen. Das dürfte der hauptsächliche Grund für die -1 im Seriellen Monitor sein.
Das dürfte beim ATtiny 16 Bit sein, beim NodeMCU mötlicherweise 32 Bit. Bitte unbedingt einen hart typisierten Typ verwenden, also int16_t oder uint16_t.
Also ich habe nun mal in beiden Sketches die int durch int16_t ersetzt. Die Adresse habe ich auf 12 gesetzt.
Ich habe ein Serial.println(sizeof(data)); direkt unter Wire.requestFrom(SLAVE_ADR, sizeof(data)); hinzugefügt.
Kannst du bitte nochmal erklären, wie es mit deinem Schaltbild in Post #4 funktionieren soll ?
Was fehlt habe ich schon geschrieben.
Zeige uns doch bitte ein richtiges, aktuelles Schaltbild.
Bei verschiedenen Microcontroller würde ich die zu übertragenen Bytes eigenhändig der Übertragung zuordnen. Dann weis man wofür welches Byte genutzt wird.
Den Hinweis auf Type punning hat eh schon @combie aufgezeigt.
Das funktioniert bei mir mit einem NodeMCU und einem Nano:
nun läuft die Übertragung. War wohl nicht nur ein Software Problem sondern eher eine Kombination aus Software und Hardware.
Nach dem Tipp von @noiasca bezüglich der Widerstandskraft habe ich diese nochmal nachgemessen. Waren wohl keine 4,7k sondern 47k .
Wenn man unabhängig vom gesendeten immer nur 0xff oder -1 liest, ist das nicht mit undefined behaviour zu erklären.
Wenn man was kriegt, das zwar nach Daten aussieht, aber nicht so recht passt, ist immer noch Zeit, sich über Byte-Reihenfolge und -Anzahl Gedanken zu machen.
Wenn es aber stimmt, braucht man keine Angst vor einer neuen Compiler-Version zu haben.
Ob die Lösung auf anderer Hardware läuft, ist natürlich neu zu prüfen.