lexus2k / ssd1306

Driver for SSD1306, SSD1331, SSD1351, IL9163, ILI9341, ST7735, PCD8544, Nokia 5110 displays running on Arduino/ESP32/Linux (Rasperry) platforms
MIT License
662 stars 127 forks source link

Support for 2nd I2C port (e.g. ATMega328PB) #126

Closed Balze2 closed 2 years ago

Balze2 commented 3 years ago

Hi there,

first of all thank you for creating and maintaining this library!!

I'm currently working on a project with a ATMega328PB (the successor of the popular ATMega328P). This controller has a 2nd hardware I2C bus. I'm using this 2nd bus for a SSD1306.

I locally tweaked your library to my needs, to connect to the second I2C bus.

Maybe you can extend you library with this functionallity. Which I2C should be used could be a parameter of ssd1306_128x64_i2c_init(x); where x might be 0 = SW, 1 = 1st I2C. 2 = 2nd I2C

Thanks and best regards

Balze2

Balze2 commented 3 years ago

Supplement:

Just found that ssd1306_platform_i2cInit() should do this. But it's not fully implemeted for Arduino/AVR platform...

Or am I missing something?

lexus2k commented 3 years ago

Hi,

Thank you for reporting so interesting question. And Yes, Atmega328PB datasheet claims that there are 2 i2c hardware modules in the micro controller. Could you please provide some example on how you initialize and use seconds i2c hardware module? It would be very helpful. I didn't know that by default Arduino IDE allows to use second i2c for atmega328p.

Also, if you send me a diff that you have currently, it would be very nice

Thank you

Balze2 commented 3 years ago

Hi lexus2k,

The default Arduino IDE does not support the ATMega328PB at all. I use the MiniCore from MCUdude for this.

I found, that this core handles the 2nd I2C somewhat different than the Arduino "default" does. I'm discussinig this with MCUdude allready and will be back, if I've got some results.

I'll send you my "workaround" this evening, when I'm back home.

Best regards

Balze

Balze2 commented 3 years ago

Hi lexus2k

I added the changed files as a zip-file. In fact I switched from wire to wire1. So this is no solution to support both I2C busses. 😄

Best regards

Balze

ssd1306difference.zip

lexus2k commented 3 years ago

Thank you, can you send me full gcc line args, when IDE compiles your program. I need to understand, which definitions can use useful to understand, when Wire1 can be used, and when not.

Balze2 commented 3 years ago

Hi lexus2k,

sure! I don't know what exactly you need. This is the arduino output when uploading your ssd1306_demo.ino to my ATMega328PB It's the output to the point where library resolving starts.

If you need anything else, please let me know.

C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\Balze\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\Balze\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Balze\Documents\Arduino\libraries -fqbn=MiniCore:avr:328:bootloader=uart0,eeprom=keep,variant=modelPB,BOD=2v7,LTO=Os,clock=20MHz_external -vid-pid=1A86_7523 -ide-version=10813 -build-path C:\Users\Balze\AppData\Local\Temp\arduino_build_216818 -warnings=all -build-cache C:\Users\Balze\AppData\Local\Temp\arduino_cache_389316 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arduinoOTA.path=C:\Users\Balze\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Users\Balze\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0 -prefs=runtime.tools.avrdude.path=C:\Users\Balze\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino18 -prefs=runtime.tools.avrdude-6.3.0-arduino18.path=C:\Users\Balze\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino18 -prefs=runtime.tools.avr-gcc.path=C:\Users\Balze\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=C:\Users\Balze\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -verbose C:\Users\Balze\Documents\Arduino\libraries\ssd1306\examples\demos\ssd1306_demo\ssd1306_demo.ino C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\Balze\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\Balze\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Balze\Documents\Arduino\libraries -fqbn=MiniCore:avr:328:bootloader=uart0,eeprom=keep,variant=modelPB,BOD=2v7,LTO=Os,clock=20MHz_external -vid-pid=1A86_7523 -ide-version=10813 -build-path C:\Users\Balze\AppData\Local\Temp\arduino_build_216818 -warnings=all -build-cache C:\Users\Balze\AppData\Local\Temp\arduino_cache_389316 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arduinoOTA.path=C:\Users\Balze\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Users\Balze\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0 -prefs=runtime.tools.avrdude.path=C:\Users\Balze\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino18 -prefs=runtime.tools.avrdude-6.3.0-arduino18.path=C:\Users\Balze\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino18 -prefs=runtime.tools.avr-gcc.path=C:\Users\Balze\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=C:\Users\Balze\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -verbose C:\Users\Balze\Documents\Arduino\libraries\ssd1306\examples\demos\ssd1306_demo\ssd1306_demo.ino Using board '328' from platform in folder: C:\Users\Balze\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.1.1 Using core 'MCUdude_corefiles' from platform in folder: C:\Users\Balze\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.1.1 Detecting libraries used... "C:\\Users\\Balze\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -E -CC -mmcu=atmega328pb -DF_CPU=20000000L -DARDUINO=10813 -DARDUINO_AVR_ATmega328 -DARDUINO_ARCH_AVR "-IC:\\Users\\Balze\\AppData\\Local\\Arduino15\\packages\\MiniCore\\hardware\\avr\\2.1.1\\cores\\MCUdude_corefiles" "-IC:\\Users\\Balze\\AppData\\Local\\Arduino15\\packages\\MiniCore\\hardware\\avr\\2.1.1\\variants\\pb-variant" "C:\\Users\\Balze\\AppData\\Local\\Temp\\arduino_build_216818\\sketch\\ssd1306_demo.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE Alternatives for ssd1306.h: [ssd1306@1.8.2] ResolveLibrary(ssd1306.h)

I have been unable to use the U8G2 library aswell (you might know about it). The owner Olikraus pointed out, that the Arduino environment has a define for the number of I2C busses. #define WIRE_INTERFACES_COUNT 2 That wasn't used by Minicore yet. After discussing it with MCUdude (owner of Minicore) I added this line to the pins_arduino.h of the PB variants of the Minicore. Then U8G2 works for me without further changes. He will add this line in coming releases of the MiniCore.

If you need any further informatiion, please let me know.

Best regards

Balze

lexus2k commented 3 years ago

Thank you.

I will check WIRE_INTERFACES_COUNT. Regarding other compiler options, they are the same as for standard Atmega328p support.

lexus2k commented 3 years ago

Hi,

It's me again. Can you check latest commit to 1.8_dev branch? It should allow using second Wire interface if available.

Balze2 commented 3 years ago

Hi lexus2k,

I'll check it when I'm back home and let you know results. Thank you very much for taking care!

Balze

Balze2 commented 3 years ago

Hi, it's me again :)

The compiler is unhappy with the following line in src\ssd1306_hal\arduino\platform.cpp static TwoWire *s_i2c = nullptr_t;

My assumption is it should be: (I'm not the brilliant C/C++ programmer :) static TwoWire *s_i2c = nullptr; I changed it like this and tried on.

You created a new function to support more then one I2C bus. void ssd1306_i2cInitEx2(int8_t busId, int8_t scl, int8_t sda, int8_t sa) but it's called nowhere.

So i tried to call it in void ssd1306_i2cInit() { ssd1306_i2cInitEx2(2,-1, -1, SSD1306_SA); } but to no avail. BTW: how is busId used? how is the numbering? (I tried 0, 1 and 2)

Would it be helpfull if I support you with my hardware (based on ATMega328PB)? If so I can solder it together and send it to you, if you're interested.

lexus2k commented 3 years ago

That should be nice. But delivering will take too much time.

In your case, initialization should be done with 2 lines as:

    ssd1306_i2cInitEx2(1,-1, -1, SSD1306_SA);
    ssd1306_128x64_init();
Balze2 commented 3 years ago

Hey Aleksei

My initialization look like this now:

    ssd1306_i2cInitEx2(1,-1, -1, 0x7B);
    ssd1306_128x64_init();

But it still doesn't work, I'm sorry.

Is my assumption with nullptr correct?

(I'll send you an email regarding the hardware)

lexus2k commented 3 years ago

@Balze2 Yes, you're correct regarding nullptr.

lexus2k commented 3 years ago

Hi. Finally, I've got the library to work on your hardware. The main issue is that MiniCore board package doesn't yet support WIRE_INTERFACES_COUNT macro - it is not yet integrated. I found that micor-USB cable doesn't fit good in the socket (or maybe the socket is unsoldered), I will try to resolder it and let you know.

PS. commit is comming soon

20210531_083847

Balze2 commented 3 years ago

Hey lexus2k,

great to hear! Thank you for your effort.

The WIRE_INTERFACE_COUNT macro will be (or is already?!) added to the Minicore by MCUDude. EDIT: Additional Info: (The macro is in the sources of the master branch, but not yet released!)

I know about the USB-socket issue. It's the same with my board. I checked the soldering over and over again. But it seems to be the socket itself. (Although it's an brand product - Amphenol)

Thanks again and best regards

Balze2

lexus2k commented 3 years ago

Hi

Additional Info: (The macro is in the sources of the master branch, but not yet released!)

Yes, I installed official release, and didn't find the macro. So, then I implemented the macro definition inside the library if it is absent.

Although it's an brand product - Amphenol

Yeah, I checked their site and they say that they are world leading manufacturer of the connectors. Unbelievable