cyberman54 / ESP32-Paxcounter

Wifi & BLE driven passenger flow metering with cheap ESP32 boards

Home Page:https://cyberman54.github.io/ESP32-Paxcounter/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

OLED screen initialization failed causing reboot (solved)

LilyGO opened this issue · comments

Regarding the restart caused by the failure of the old initialization, the board model halffile = ttgov21new.h.
The OLED driver may be SSD1306 or SSD1315. Most registers have the same function.
Because there is no definition of SSD1315 in the driver library, we can use SD1306 directly.

The specific code needs to be modified as the obdI2CInit function in OneBitDisplay.cpp


//
// Initializes the OLED controller into "page mode"
//
int obdI2CInit(OBDISP *pOBD, int iType, int iAddr, int bFlip, int bInvert,
               int bWire, int sda, int scl, int reset, int32_t iSpeed) {
  unsigned char uc[32];
  uint8_t u8Len, *s;
  int rc = OLED_NOT_FOUND;

  pOBD->ucScreen = NULL; // reset backbuffer; user must provide one later
  pOBD->type = iType;
  pOBD->flip = bFlip;
  pOBD->invert = bInvert;
  pOBD->wrap = 0; // default - disable text wrap
  pOBD->bbi2c.iSDA = sda;
  pOBD->bbi2c.iSCL = scl;
  pOBD->bbi2c.bWire = bWire;
  pOBD->com_mode = COM_I2C; // communication mode

  I2CInit(&pOBD->bbi2c,
          iSpeed); // on Linux, SDA = bus number, SCL = device address
#ifdef _LINUX_
  pOBD->oled_addr = (uint8_t)scl;
#else
  // Reset it
  if (reset != -1) {
    pinMode(reset, OUTPUT);
    digitalWrite(reset, HIGH);
    delay(50);
    digitalWrite(reset, LOW);
    delay(50);
    digitalWrite(reset, HIGH);
    delay(10);
  }
  // find the device address if requested
  if (iAddr == -1 || iAddr == 0 || iAddr == 0xff) // find it
  {
    I2CTest(&pOBD->bbi2c, 0x3c);
    if (I2CTest(&pOBD->bbi2c, 0x3c))
      pOBD->oled_addr = 0x3c;
    else if (I2CTest(&pOBD->bbi2c, 0x3d))
      pOBD->oled_addr = 0x3d;
    else
      return rc; // no display found!
  } else {
    pOBD->oled_addr = iAddr;
    I2CTest(&pOBD->bbi2c, iAddr);
    if (!I2CTest(&pOBD->bbi2c, iAddr))
      return rc; // no display found
  }

#endif
  // Detect the display controller (SSD1306, SH1107 or SH1106)
  uint8_t u = 0;
  I2CReadRegister(&pOBD->bbi2c, pOBD->oled_addr, 0x00, &u,
                  1); // read the status register
  u &= 0x0f;          // mask off power on/off bit
  if ((u == 0x7 || u == 0xf) && pOBD->type == OLED_128x128) // SH1107
  { // A single SSD1306 display returned 7, so only act on it if the
    // user specified that they're working with a 128x128 display
    rc = OLED_SH1107_3C;
    bFlip =
        !bFlip; // SH1107 seems to have this reversed from the usual direction
  } else if (u == 0x8) // SH1106
  {
    rc = OLED_SH1106_3C;
    pOBD->type = OLED_132x64; // needs to be treated a little differently
  } else if (u == 3 || u == 6 || u == 7 ||
             u == 4) // 7=128x64(rare),6=128x64 display, 3=smaller 4= SSD1315(The registers are roughly the same)
  {
    rc = OLED_SSD1306_3C;
  }

  if (pOBD->oled_addr == 0x3d)
    rc++; // return the '3D' version of the type

  if (iType == OLED_128x32 || iType == OLED_96x16) {
    s = (uint8_t *)oled32_initbuf;
    u8Len = sizeof(oled32_initbuf);
  } else if (iType == OLED_128x128) {
    s = (uint8_t *)oled128_initbuf;
    u8Len = sizeof(oled128_initbuf);
  } else if (iType == OLED_72x40) {
    s = (uint8_t *)oled72_initbuf;
    u8Len = sizeof(oled72_initbuf);
  } else if (iType == OLED_64x128) {
    s = (uint8_t *)oled64x128_initbuf;
    u8Len = sizeof(oled64x128_initbuf);
  } else // 132x64, 128x64 and 64x32
  {
    s = (uint8_t *)oled64_initbuf;
    u8Len = sizeof(oled64_initbuf);
  }

  memcpy_P(uc, s, u8Len);
  _I2CWrite(pOBD, uc, u8Len);
  if (bInvert) {
    uc[0] = 0;    // command
    uc[1] = 0xa7; // invert command
    _I2CWrite(pOBD, uc, 2);
  }
  if (bFlip) // rotate display 180
  {
    uc[0] = 0; // command
    uc[1] = 0xa0;
    _I2CWrite(pOBD, uc, 2);
    uc[1] = 0xc0;
    _I2CWrite(pOBD, uc, 2);
  }
  pOBD->width = 128; // assume 128x64
  pOBD->height = 64;
  if (iType == OLED_96x16) {
    pOBD->width = 96;
    pOBD->height = 16;
  } else if (iType == OLED_64x128) {
    pOBD->width = 64;
    pOBD->height = 128;
  } else if (iType == OLED_128x32)
    pOBD->height = 32;
  else if (iType == OLED_128x128)
    pOBD->height = 128;
  else if (iType == OLED_64x32) {
    pOBD->width = 64;
    pOBD->height = 32;
  } else if (iType == OLED_72x40) {
    pOBD->width = 72;
    pOBD->height = 40;
  }
  return rc;
} /* obdInit() */

@LilyGO thanks.

I opened PR:
bitbank2/OneBitDisplay#26

Are those displays mounted flipped on TTGO 1.6 boards?

@LilyGO PR in the onebitdisplay library was merged today, thus your issue should be solved. Could you please re-test?
Please make sure to have current version of onebitdisplay library.