Wire.h send Array / struct / but how to receive?

Hey people,

Im going on very well at the moment. But i have a problem to initializie the the recieving function.

Got this code;

Master

void send(){
    struct {  // 2 16-bit integers, 4 bytes total
       int val1 = 5;
       int val2 = 10;
     } str1;

        Wire.beginTransmission(ledChannel);
        Wire.write((uint8_t *)&str1, sizeof(str1));
        Wire.endTransmission();
}

The Slave is now my Problem:

I tried many different ways but it always have the same Error.

  void setup() {
  Wire.begin(LedChannel);
  Wire.onReceive(convertData);
}

void convertData(struct r){
  Serial.println("test recieve");
  Serial.print(r);
  // Array contains {controllerPoti, slave1ButtonState}
  // send from Controller 
  //controllerPoti = receivedData[0];
  //slave1ButtonState = recieveData[1];
  }

Error: void onReceive( void (*)(int) );

I had the function convertData tried in differet ways.

For example:

void convertData(int r){};

void convertData(int[] r){}; // when I tried to send an arrays

void convert ((uint8_t *) r)

void convertData((uint8_t *)&str1)

Nothing works for me.

How do i declare the Variable in the receiveFunction? For me, it works better to send an Arrays with data. like so:

void send(){
   int[] i = {int val1, int val2}; // as i understood 4 bytes so i write:

        Wire.beginTransmission(ledChannel);
        Wire.write(i, 4);
        Wire.endTransmission();
}

But how do I write my:

onReceiveEvent(??? <- )

Greetz

Why do you need to use a struct to send the two values? An array would be far simpler.

The onReceive() function has a pre-defined signature. You can't change the signature.

Paul's correct; the argument to whatever function you use is set in stone and must be an int. Perhaps something like:

 struct {  // 2 16-bit integers, 4 bytes total    MAKE GLOBAL
    int val1 = 5;
    int val2 = 10;
 } str1;

// Setup(), loop(), etc...

void convertData(int bytesToRead){
  int i = 0;
  union myUnion {
     int A;
     int B;
     char buffer[4];
  } mine;

  while(Wire.available())
  {
    mine.buffer[i++] = Wire.read();
  }
  str1.val1 = mine.A;    // You may have to play around with these cuz of Endian problem
  str1.val2 = mine.B;
}

I cannot test this, so it may be completely wrong...

Here are send and receive examples for an integer array with 2 integers.

Send Code

#include <Wire.h>

const byte SlaveDeviceId = 1;
int sendInts[2];

void setup()
{
  // Start I²C bus as master
  Wire.begin();
}
void loop()
{
  sendInts[0] = 456;
  sendInts[1] = 567;
  Wire.beginTransmission(SlaveDeviceId);
  Wire.write((uint8_t*)&sendInts, sizeof(sendInts));
  Wire.endTransmission();

  delay(1000);
}

Receive Code

#include <Wire.h>

const byte SlaveDeviceId = 1;
volatile int receiveInts[2];
volatile boolean newReceiveEvent = false;
volatile boolean errorEvent = false;

void setup()
{
  // Start I²C bus as a slave
  Wire.begin(SlaveDeviceId);
  Wire.onReceive(receiveEvent);//interrupt handler for incoming message

  Serial.begin(9600);
  Serial.println("starting....");
}

void loop()
{
  if (newReceiveEvent == true)
  {
    for (byte j = 0; j < 2; j++)
    {
      Serial.println(receiveInts[j]);
    }
    newReceiveEvent = false;
  }

  if (errorEvent == true)
  {
    Serial.println("I2C Receive Error");
    errorEvent = false;
  }
}

// aCount is the number of bytes received.
void receiveEvent(int aCount)
{
  if (aCount == 4)
  {
    Wire.readBytes((uint8_t*)&receiveInts, 4); 
    newReceiveEvent = true;
  }
  else
  {
    errorEvent = true;
  }
}

I realize this is an old post, but I just stumbled on it, and it's taking care of exactly what I need.

Here's a really stupid question:
If your array only has 2 components (sendInts[0] and sendInts[1]), why does aCount have a value of 4? I'm creating an array of 200 to be transmitted (a bunch of DMX addresses). Each components would be an int between 0 and 256 - what would my aCount be in this case?

Thanks!

// aCount is the number of bytes received.

Each 'int' occupies 2 bytes.

If your array only has 2 components (sendInts[0] and sendInts[1]), why does aCount have a value of 4?

aCount is received bytes, and there are two per integer.

I'm creating an array of 200 to be transmitted (a bunch of DMX addresses). Each components would be an int between 0 and 256 - what would my aCount be in this case?

A byte has value of 0 to 255 inclusive, so I think you are talking about a byte array. Memory is precious on an Arduino, so don't use an int when a byte will do.

You will encounter another problem in that the Wire library for i2c communications is designed for short communications and there is a 32 byte buffer limitation. You will have to break your array into pieces.