Ok hier mal was rein für Wire. Es werden alle Werte auf einmal übertragen. Dadurch spart man sich erst mal einen Index zu setzen.
Master:
#include <Wire.h>
const int SLAVE_ADR = 5;
const unsigned int NUMBER_OF_VALUES = 2;
union data_u
{
unsigned int i[NUMBER_OF_VALUES];
byte b[sizeof(i)];
};
data_u values;
void setup()
{
Serial.begin(9600);
Serial.println("Master");
Wire.begin();
getData();
}
void loop()
{
}
void getData()
{
Wire.requestFrom(SLAVE_ADR, sizeof(values.b));
for (byte i = 0; i < sizeof(values.b); i++)
values.b[i] = Wire.read();
Serial.println(values.i[0]);
Serial.println(values.i[1]);
}
Slave:
#include <Wire.h>
const int SLAVE_ADR = 5;
const unsigned int NUMBER_OF_VALUES = 2;
union data_u
{
unsigned int i[NUMBER_OF_VALUES];
byte b[sizeof(i)];
};
data_u values;
void setup()
{
Wire.begin(SLAVE_ADR);
Wire.onRequest(requestEvent);
values.i[0] = 123;
values.i[1] = 45678;
}
void loop()
{
}
void requestEvent()
{
Wire.write(values.b, sizeof(values.b));
}
Der Master fordert einfach das gesamte Array an und der Slave sendet das gesamte Array.
Die Union ist nötig weil man im Request Event Handler nur einmal write() machen kann. Also kann man ein Byte Array auf einmal senden. Auf dem Empfänger schreibt man auch in eine union und hat so direkt den Integer Wert.
______________________________________________________________________
Achtung: der I2C Puffer hat nur 32 Byte! Wenn man also wie hier innerhalb der Grenzen bleibt geht es so einfach (also 16 ints oder 8 longs/floats). Wenn man mehr auf einmal übertragen will, dann kann erst mal vom Master den Index des gesuchten Integers an den Slave senden und dann pro Request nur einen Integer übertragen
Das geht so:
Master:
#include <Wire.h>
const int SLAVE_ADR = 5;
const unsigned int NUMBER_OF_VALUES = 10;
union data_u
{
unsigned int i;
byte b[sizeof(i)];
};
data_u values[NUMBER_OF_VALUES];
void setup()
{
Serial.begin(9600);
Serial.println("Master");
Wire.begin();
getData();
}
void loop()
{
}
void getData()
{
for (byte i = 0; i < NUMBER_OF_VALUES; i++)
{
Wire.beginTransmission(SLAVE_ADR);
Wire.write(i);
Wire.endTransmission();
Wire.requestFrom(SLAVE_ADR, sizeof(values[0].i));
for (byte j = 0; j < sizeof(values[0].i); j++)
values[i].b[j] = Wire.read();
}
for (byte i = 0; i < NUMBER_OF_VALUES; i++)
Serial.println(values[i].i);
}
Slave:
#include <Wire.h>
const int SLAVE_ADR = 5;
const unsigned int NUMBER_OF_VALUES = 10;
union data_u
{
unsigned int i;
byte b[sizeof(i)];
};
data_u values[NUMBER_OF_VALUES];
byte index;
void setup()
{
values[0].i = 1;
values[1].i = 4;
values[2].i = 12;
values[3].i = 45;
values[4].i = 123;
values[5].i = 456;
values[6].i = 1234;
values[7].i = 12345;
values[8].i = 1000;
values[9].i = 10000;
Wire.begin(SLAVE_ADR);
Wire.onRequest(requestEvent);
Wire.onReceive(receiveEvent);
}
void loop()
{
}
void receiveEvent(int)
{
index = Wire.read();
}
void requestEvent()
{
Wire.write(values[index].b, sizeof(values[0].b));
}
Dabei beachten, dass die Datenstruktur etwas anders ist. Die Union hat nur einen Integer und man hat ein Array aus unions. Das macht die Sache mit dem Index leichter lesbar. Ansonsten müsste man den Index im Byte Array berechnen.
Der Master schickt erst den Index des Integers und fordert dann einen Integer an. Der Slave sendet alle Bytes dieses Integers.