usedbytes / neopixel_i2c

AVR-based i2c-slave Neopixel driver
GNU General Public License v2.0
31 stars 5 forks source link

[duplicate #5] max number of LEDs limited by 8bit address #6

Closed BastelBaus closed 5 years ago

BastelBaus commented 5 years ago

The address is 8bit, so the maximum addressable LEDs are 84. Can someone confirm ?

usedbytes commented 5 years ago

Yes, you're right. I'd not noticed #5, which is a duplicate of this.

There's a fork there which gives you a workaround. I hadn't considered this case at all, happy to hear suggestions for a good fix.

BastelBaus commented 5 years ago

Thank you very muchfor this very fast reply. I did not notice this since I quite new to github.

I checked it shortly and saw two not to complicated possibilities: a) you transmit only the address/3 b) you use some off the reserved bits for the upper part of the address any preferences ?

Maybe I can also contribute, I locally have ported to the normal arduino .ino files (for those how get the makefile not running under windwos ;-)) and added a global register to fill the RAM w/o updating the registers and then update all LEDs at once.

usedbytes commented 5 years ago

Some of the reserved bits in the CTRL register? That's something I was wondering myself. One slightly annoying snag is the i2c library I wrote really isn't geared up for this (honestly I just never thought about needing more than 256 addresses :disappointed:). The code which handles the address is totally separate from the code which handles the register implementations.

I quite like the multiple-of-three idea. Could add a bit in the CTRL register to enable that perhaps, but it would still mean modifying the underlying i2c library. I feel like the best thing to do might just be to add a build option to the i2c library which enables 16-bit addressing.

What does your global register do? It sounds the same as GLB_R, GLB_G, GLB_B in the existing implementation. You can write a colour to those registers, and set bit 1 in CTRL, and all the LEDs will get set to that colour.

Thanks for your interest in my little project!

BastelBaus commented 5 years ago

I thought a bit more, but found out that my idea was a bit stupid. If you use bits in the control register which changes the address and then you want to change back (by using the controll register at address 0), you cannot since you cannot address 0x00 any more.

Then I though about using the multiple of three which would only be a minor change in the i2c library just multiplying the address by 3. But I did not had an easy solution for the RGBW mode, But I think combining this with your idea to chaneg the multiplication factor by one or more bits in the controll register sounds as a very promising combination.

It could look like this (untested). What do you think?

i2c_slave_defs.h:

#define      CTRL_M0     (1 << 6) // M1:M0 = B00 ==> k=1   // M1:M0 = B01 ==> k=2
#define      CTRL_M1     (1 << 7) // M1:M0 = B10 ==> k=3   // M1:M0 = B00 ==> k=4
#define      GET_CTRL_k  ( ( (REG_CTRL & (M1|M0) ) >>6 )  +1 )

i2c_machine.cpp:

/* Transition d */
i2c_offset = (uint16_t) USIDR * GET_CTRL_k;      

An of course setting i2c_offset and i2c_update to uint16_t.

Your project was the closest one I could find to make an I2C to neopixel gateway from a standard digispark ATTiny85. So thank you a lot for contributing it!

BastelBaus commented 5 years ago

I think I am through. Did change some more things and added a abstraction class to controll the function from the master BastelBaus/neopixel_i2c. Thanks a lot again for this nice basis!