Can your write to multiple I2C addresses in a neater way than this?

Hello

I have made some remote LED numbers for a local charity.

They basically have an onboard AtTiny1604 processor that reads a single incoming byte and then displays it on the Seven Segment display.

Each PCB has a possible 9x i2c Addresses (more if you change the AtTiny code). I am only daisy chaining 5 anyway, so all is good.

You can control individual segments, Letters or numbers, depending on what byte you send.

....anyway...

If I want to send a number to each display, I am currently doing this:

void drawNumbers() {
  Wire.beginTransmission(1);    // transmit to device #1                                                           // Draw number 1-5 on LED displays
  Wire.write(1);                // sends value
  Wire.endTransmission();       // stop transmitting
  delay(100);
  Wire.beginTransmission(2);    // transmit to device #2
  Wire.write(2);                // sends value
  Wire.endTransmission();       // stop transmitting
  delay(100);
  Wire.beginTransmission(3);    // transmit to device #3
  Wire.write(3);                // sends value
  Wire.endTransmission();       // stop transmitting
  delay(100);
  Wire.beginTransmission(4);    // transmit to device #4
  Wire.write(4);                // sends value
  Wire.endTransmission();       // stop transmitting
  delay(100);
  Wire.beginTransmission(5);    // transmit to device #5
  Wire.write(5);                // sends value
  Wire.endTransmission();       // stop transmitting
}

I am sure don't need a 100ms delay. That was for testing. I might need some kind of delay, but I have yet to work that out.

Is there a 'neater' way of talking to a range of addresses? Or are you bound by the fact that you must open and close each 'channel' first?


each are separate transmission, so you need to begin and end the transmission. but it could be made "neater" if you were using a for loop.

for (byte deviceNb = 1; deviceNb < 6; deviceNb++) {
  Wire.beginTransmission(deviceNb);
  Wire.write(deviceNb); // sends whatever value is required
  Wire.endTransmission();
}

using an array, say call it valueFor, to memorise what is to be sent to which display could help as well

for (byte deviceNb = 1; deviceNb < 6; deviceNb++) {
  Wire.beginTransmission(deviceNb);
  Wire.write(valueFor[deviceNb]); // sends whatever value is required
  Wire.endTransmission();
}

using an array for the address of the target devices would be useful too

const byte deviceAddress[] = {1, 2, 3, 4, 5}; 
const byte deviceCount = sizeof deviceAddress / sizeof * deviceAddress; 
byte valueFor[deviceCount]; 

// fill up valueFor through some algorithm, say here we put a random value
for (byte deviceNb = 0; deviceNb < deviceCount; deviceNb++) {
  valueFor[deviceNb] = random(deviceCount) + 1;
}

// and when it's time to send the data
for (byte deviceNb = 0; deviceNb < deviceCount; deviceNb++) {
  Wire.beginTransmission(deviceAddress[deviceNb] );
  Wire.write(valueFor[deviceNb]); // sends whatever value is required
  Wire.endTransmission();
}
2 Likes

And if you're often writing single bytes to addresses in different places in the code, you can extract it into a function where you pass a std::span of bytes to write and an address.

I've made several projects using nitacku's NI2C library, I had to make a little change to it though but all in all it hasn't let me down in those projects.
I'm not going to start pasting code here but i'm replying just to say "go have a look". It's a nonblocking I2C implementation.
cheers.

Thanks

Yes. I have now implemented a for loop and only a 2ms delay and all seems fine

2ms is a long time even for a 16mHz arduino - roughly the time it takes to send 100 bytes using I2C fast mode

(2ms @ 16Mhz is enough to have 32000 clock cycles, so tens of thousands of low level machines instructions which are typically one or two cycles long)

Well my application seems to work fine at 2ms timing, so no hard leaving it at that.
If speed was an issue, I could reduce it or eliminate it.

If it works then that’s fine

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.