Richard-Gemmell / teensy4_i2c

An I2C library for the Teensy 4. Provides slave and master mode.
MIT License
92 stars 20 forks source link

Slave compile issue #40

Closed craigyjp closed 1 month ago

craigyjp commented 1 month ago

Hi, I'm testing your wire slave receiver with two T4.1 devices, when I compile the code and set it up for Wire2, I can happily receive the data from my master and process the 4 integers I have sent. However, when I take this setup of Wire2 and the same processing code into my main sketch I get the following errors on compilation.

In file included from N:\Arduino\ST7789_MIDI_to_Display\ST7789_MIDI_to_Display.ino:13: n:\Arduino\libraries\Teensy4_I2C\src/i2c_driver_wire.h:159:22: error: conflicting declaration 'I2CDriverWire Wire' 159 | extern I2CDriverWire Wire; // Pins 19 and 18; SCL0 and SDA0 | ^~~~ In file included from C:\Users\Craig\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0\libraries\Wire/Wire.h:26, from n:\Arduino\libraries\Adafruit_BusIO/Adafruit_I2CDevice.h:5, from n:\Arduino\libraries\Adafruit_GFX_Library/Adafruit_GFX.h:12, from N:\Arduino\ST7789_MIDI_to_Display\ST7789_MIDI_to_Display.ino:10: C:\Users\Craig\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0\libraries\Wire/WireIMXRT.h:195:16: note: previous declaration as 'TwoWire Wire' 195 | extern TwoWire Wire; | ^~~~ In file included from N:\Arduino\ST7789_MIDI_to_Display\ST7789_MIDI_to_Display.ino:13: n:\Arduino\libraries\Teensy4_I2C\src/i2c_driver_wire.h:160:22: error: conflicting declaration 'I2CDriverWire Wire1' 160 | extern I2CDriverWire Wire1; // Pins 16 and 17; SCL1 and SDA1 | ^~~~~ In file included from C:\Users\Craig\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0\libraries\Wire/Wire.h:26, from n:\Arduino\libraries\Adafruit_BusIO/Adafruit_I2CDevice.h:5, from n:\Arduino\libraries\Adafruit_GFX_Library/Adafruit_GFX.h:12, from N:\Arduino\ST7789_MIDI_to_Display\ST7789_MIDI_to_Display.ino:10: C:\Users\Craig\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0\libraries\Wire/WireIMXRT.h:196:16: note: previous declaration as 'TwoWire Wire1' 196 | extern TwoWire Wire1; | ^~~~~ In file included from N:\Arduino\ST7789_MIDI_to_Display\ST7789_MIDI_to_Display.ino:13: n:\Arduino\libraries\Teensy4_I2C\src/i2c_driver_wire.h:161:22: error: conflicting declaration 'I2CDriverWire Wire2' 161 | extern I2CDriverWire Wire2; // Pins 24 and 25; SCL2 and SDA2 | ^~~~~ In file included from C:\Users\Craig\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0\libraries\Wire/Wire.h:26, from n:\Arduino\libraries\Adafruit_BusIO/Adafruit_I2CDevice.h:5, from n:\Arduino\libraries\Adafruit_GFX_Library/Adafruit_GFX.h:12, from N:\Arduino\ST7789_MIDI_to_Display\ST7789_MIDI_to_Display.ino:10: C:\Users\Craig\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0\libraries\Wire/WireIMXRT.h:197:16: note: previous declaration as 'TwoWire Wire2' 197 | extern TwoWire Wire2; | ^~~~~ In file included from N:\Arduino\ST7789_MIDI_to_Display\ST7789_MIDI_to_Display.ino:13: n:\Arduino\libraries\Teensy4_I2C\src/i2c_driver_wire.h:164:7: error: conflicting declaration 'using TwoWire = class I2CDriverWire' 164 | using TwoWire = I2CDriverWire; | ^~~ In file included from C:\Users\Craig\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0\libraries\Wire/Wire.h:26, from n:\Arduino\libraries\Adafruit_BusIO/Adafruit_I2CDevice.h:5, from n:\Arduino\libraries\Adafruit_GFX_Library/Adafruit_GFX.h:12, from N:\Arduino\ST7789_MIDI_to_Display\ST7789_MIDI_to_Display.ino:10: C:\Users\Craig\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0\libraries\Wire/WireIMXRT.h:41:7: note: previous declaration as 'class TwoWire' 41 | class TwoWire : public Stream | ^~~

Richard-Gemmell commented 1 month ago

Hi Craig, It's possible that some other library you're using is pulling in the default implementation of the Wire library. If you haven't done so already, please have a look at the Replacing Wire.h section of the readme.

If you can't find it easily, then you could create a stripped down version of your code with no other libraries. Add your dependencies in one at a time until it fails. That'll tell you which library brings in Wire. You can then modify the dependency to fix it.

cheers, Richard

craigyjp commented 1 month ago

Hi Richard and thanks for the reply, yes that was my thoughts too that something was interfering with Wire, I'm using SPI to drive 9 screens, midi to receive sysex, although that would have been replaced by the i2c and also a roxmux library to talk to shift registers to turn LEDs on. If I get time I will try to disable these operations and start to build up the code. I wanted to move the RoxMux led drivers to the master teensy anyway, but I'm running out of pins.

Richard-Gemmell commented 1 month ago

I had another look at the stack trace. The Adafruit_BusIO library appears to be the culprit. https://github.com/adafruit/Adafruit_BusIO/blob/15fbda592d1b237b0a92cfb91841adb01a34efd9/Adafruit_I2CDevice.h#L5

If you change line 5 to import i2c_driver_wire.h instead then it should work.

craigyjp commented 1 month ago

Ok, I doubt I would have found that myself, I will give it a go tomorrow as it's getting late here.

Many thanks

craigyjp commented 1 month ago

Hi Richard, I edited that file and I got another compilation error, I tracked that down to the Adafruit GFX lib and made a simililar modification, that fixed it and the origonal code compiles now and I can see data. But then when I compiled the sender code it complained again so I had to modify the roxmux libraries to use your code.

Perhaps for this application it might be better to copy these libs locally to the application folder so that I don't overwrite them with updates.

But then I ran into buffer issues, I want to send 70x16 bit integers, so that's 140 bytes, but I understand the i2c buffer is limited to 32 bytes. I can send in chunks I guess, but I was lazily scanning through your code and I think you have some buffer settings that I can use, is that possible?

Richard-Gemmell commented 1 month ago

I'm glad you're making progress.

Re buffers; yes. The buffer size is set in i2c_driver_wire.h. You can increase it up to 255 bytes if I remember correctly. There are 2 buffers. One to transmit and one to receive. They can have different values.

I2C doesn't do much in the way of error correction. You might like to add a checksum to your messages so the receiver can reject ones that have been corrupted in transit. I've seen error rates of around 1 per million bytes on a good connection.

craigyjp commented 1 month ago

yeah, that seems to have done the trick, many thanks for your help. I was beginning to give up on Sysex and i2C as working protocols.

Richard-Gemmell commented 1 month ago

That's good to hear. Good luck with your project.