Code Passing and array of integers via i2c

Hi, I found a library that allows a teensy to comunicate with an sbus receiver. I need to pass the data received (an array of integers) to another board with I2C. I can see things happening on the board connected to the SBUS receiver but nothing on the board that's supposed to receive the array of data via I2C. Hope that makes sense.

I've also other i2c devices connected to the same bus (don't know if that can cause problems).

Here are the 2 programs:

Transmitter:

#include <Wire.h>

/* SBUS object, reading SBUS */
bfs::SbusRx sbus_rx(&Serial2);
bfs::SbusData data;

const int channelNumber = 16;
int channels[channelNumber];

void setup() {
  /* Serial to display data */
  Serial.begin(115200);
  while (!Serial);
  sbus_rx.Begin();
  Wire.begin();
}

void loop () {
  if (sbus_rx.Read()) {
    /* Grab the received data */
    data = sbus_rx.data();
    /* Display the received data */
    for (int8_t i = 0; i < data.NUM_CH; i++) {
      channels[i] = data.ch[i];
      Serial.print(data.ch[i]);
      Serial.print("\t");
    }
    Serial.println();
  }

  Wire.beginTransmission(8);
  for(int i = 0; i < channelNumber; i++){
    Wire.write(channels[i]);
  }
  Wire.endTransmission();
}```

Receiver:
<#include<Wire.h>

const int channelNumber = 16;
int receiverChannels[channelNumber];

void setup() {
Wire.begin(8);
Wire.onReceive(receiveEvent);
Serial.begin(115200);
while(!Serial);
}

void loop() {
}

void receiveEvent(int byteCount){
  if(Wire.available()){
    byte b = 0;
    for(int i = 0; i < channelNumber; i++){
      b = Wire.read();
      receiverChannels[i] = b;

      Serial.print(receiverChannels[i]); Serial.print(" ");
    }
    Serial.println();
  }
}>

How are they connected? How far apart are they?

The boards share the power source and they are pretty close. The I2C connection is very easy: just SDA with SDA and SCL with SCL

Are there pull-up resistors on the bus?

Have you tried just the I2C connection, without any other devices, with code for each end you did not write or mess with?

It would be best to prove you can send anything at all, and worry later about sending the SBUS data across.

Do the SBUS numbers your transmitting sketch print out make sense and follow the r/c remote that is sending the original signal?

a7

There are not pullup resistors. The i2c is working and has being tested with other devices connect to the same bus. The SBUS data are changing according to the rc

Perhaps those other devices have the pull-ups you need, and not using them means you are without.

a7

Will Wire.write send both bytes of the int?

I don't know what you are thaking about. I am not that expert so you might have to explain.
Thanks

Don't forget the ground connection.

void loop () {
  if (sbus_rx.Read()) {
    /* Grab the received data */
    data = sbus_rx.data();
    /* Display the received data */
    for (int8_t i = 0; i < data.NUM_CH; i++) {
      channels[i] = data.ch[i];
      Serial.print(data.ch[i]);
      Serial.print("\t");
    }
    Serial.println();
  }

  Wire.beginTransmission(8);
  for(int i = 0; i < channelNumber; i++){
    Wire.write(channels[i]);
  }
  Wire.endTransmission();
}

You are sending the data over I2C continuously, every time loop() executes, instead of once after it is received from the sbus.

#include <Wire.h>

const int channelNumber = 16;
int receiverChannels[channelNumber];

void setup() {
  Wire.begin(8); 
  Wire.onReceive(receiveEvent);
  Serial.begin(115200); 
  while(!Serial);
}

void loop() {
}

void receiveEvent(int byteCount){
  if(Wire.available()){
    byte b = 0;
    for(int i = 0; i < channelNumber; i++){
      b = Wire.read();
      receiverChannels[i] = b;

      Serial.print(receiverChannels[i]); Serial.print(" ");
    }
    Serial.println();
  }
}

receiveEvent() is an interrupt handler, you really should not be printing inside that function. Also, if you use the receiverChannels array outside the receiveEvent() function, it should be declared volatile.

As to my previous comment, Wire.write() only sends a single byte, an int is two bytes (on most arduino's), so you are only sending the first byte of the number, anything over 255, or negative, will not be sent correctly.

For transmission, as pointed out above, you need to send bytes.

This should send the entire array, in bytes:

//global
int channels[channelNumber];
int channel_size = sizeof(channels)/sizeof(channels[0]);
...
// in loop()

  Wire.beginTransmission(8);
    Wire.write((uint8_t *)channels, channel_size);
  Wire.endTransmission();

Use the size in bytes, not the number of elements in the array.

  Wire.beginTransmission(8);
  Wire.write((byte*)channels, sizeof(channels));
  Wire.endTransmission();

Need to be careful, the Wire library uses a 32-byte buffer on a lot of the arduino boards. I'm not familiar with the size on a Teensy.

Agreed, this should have been (in post #10):

int channel_size = sizeof(channels);

The variable b is a byte (8-bit), and you are saving it in an int-type array. Is it logical?

Data is already there in the buffer; is it necessary to execute the above code?