MrBlinky / Arduboy-homemade-package

Arduino IDE board package for Arduboy and homemade versions making things easy
Creative Commons Zero v1.0 Universal
109 stars 31 forks source link

Trouble with I2C display #22

Open jaltekruse opened 4 months ago

jaltekruse commented 4 months ago

I have successfully built a homemade arduboy with an SPI display, and the instructions for this package made that really easy.

I bought some more screens online, but I didn't realize the difference between SPI and I2C when I was buying, I just bought another sh1106 screen and thought it would work similar enough to my last one, and with all of the supported screens listed for this package I thought there was a good shot that just about anything would work.

What I have figured out after some testing is that I can successfully drive the screen with non-arduboy code from Adafruit, this code seems to always work when I upload it. After I have this successful display code running the demo animation, I have figured out I can one time do an upload of an arduboy game, swap to the other wires that the arduboy code expects and the screen is driven correctly. As soon as I power off the arduino and power it back on the screen is flickering and the content jumps around like there is a timing issue.

https://github.com/adafruit/Adafruit_SH110x/blob/master/examples/OLED_QTPY_SH1106/SH1106_128x64_i2c_QTPY/SH1106_128x64_i2c_QTPY.ino

The screen running successfully after being uploaded right after the adafruit code https://youtu.be/ECHMi3wUCug

The screen has issues after turning the arduino on and off. https://youtube.com/shorts/Hl-3Etssu1M

I did see that @MrBlinky recommended just getting 7 pin SPI displays on this forum thread - https://community.arduboy.com/t/4-pin-oled-display/7006

I also think I remember seeing somewhere that the lack of a reset pin on these is a real pain, and I thought I saw some manual "resetting instructions" but I can't seem to find those` now. I think I likely will just buy the slightly more expensive 7 pin displays going forward, but I am curios if this repro might help give a shot at improving this package to more reliably support another display type. It seems like the screen can be put in a decent state that hold even after changing the arduino code, but it's not put in that same state by the arduboy code when the screen boots just from that.

MrBlinky commented 4 months ago

The difference must be in the display initialisation then. Try adding the following code after arduboy.begin(); (or arduboy.boot(); )

#define SH110X_DISPLAYOFF 0xAE
#define SH110X_SETDISPLAYCLOCKDIV 0xD5
#define SH110X_SETMULTIPLEX 0xA8
#define SH110X_SETDISPLAYOFFSET 0xD3 
#define SH110X_SETSTARTLINE 0x40
#define SH110X_DCDC 0xAD
#define SH110X_SEGREMAP 0xA0 
#define SH110X_COMSCANDEC 0xC8 
#define SH110X_SETCOMPINS 0xDA
#define SH110X_SETCONTRAST 0x81
#define SH110X_SETPRECHARGE 0xD9
#define SH110X_SETVCOMDETECT 0xDB
#define SH110X_NORMALDISPLAY 0xA6 
#define SH110X_MEMORYMODE 0x20
#define SH110X_DISPLAYALLON_RESUME 0xA4
#define SH110X_DISPLAYON 0xAF

  const PROGMEM uint8_t init[] = {
    SH110X_DISPLAYOFF,               // 0xAE
    SH110X_SETDISPLAYCLOCKDIV, 0x80, // 0xD5, 0x80,
    SH110X_SETMULTIPLEX, 0x3F,       // 0xA8, 0x3F,
    SH110X_SETDISPLAYOFFSET, 0x00,   // 0xD3, 0x00,
    SH110X_SETSTARTLINE,             // 0x40
    SH110X_DCDC, 0x8B,               // DC/DC on
    SH110X_SEGREMAP + 1,             // 0xA1
    SH110X_COMSCANDEC,               // 0xC8
    SH110X_SETCOMPINS, 0x12,         // 0xDA, 0x12,
    SH110X_SETCONTRAST, 0xFF,        // 0x81, 0xFF
    SH110X_SETPRECHARGE, 0x1F,       // 0xD9, 0x1F,
    SH110X_SETVCOMDETECT, 0x40,      // 0xDB, 0x40,
    0x33,                            // Set VPP to 9V
    SH110X_NORMALDISPLAY,
    SH110X_MEMORYMODE, 0x10,         // 0x20, 0x00
    SH110X_DISPLAYALLON_RESUME,
  };

  arduboy.i2c_start(SSD1306_I2C_CMD);
  for (uint8_t i = 0; i < sizeof(init); i++)
    arduboy.i2c_sendByte(pgm_read_byte(init + i));
  arduboy.i2c_stop();

  delay(100);

  arduboy.sendLCDCommand(SH110X_DISPLAYON);