I'm running the Adafruit ESP32 with their Ultimate GPS breakout v3 with the Monochrome 1.3" 128x64 OLED.
The GPS connected via serial2, and is working fine without the OLED.
The OLED connected via I2C, and is working fine without the GPS.
When they are both running simultaneously, eventually it crashes with the following error within esp32-hal-i2c.c:
[E][esp32-hal-i2c.c:1122] i2cCheckLineState(): Bus Invalid State, TwoWire() Can't init
[E][esp32-hal-i2c.c:1041] i2cProcQueue(): Busy Timeout start=0xef54, end=0xef87, =51, max=51 error=4
[E][esp32-hal-i2c.c:1442] i2cDumpI2c(): i2c=0x3ffc1440
[E][esp32-hal-i2c.c:1443] i2cDumpI2c(): dev=0x60013000 date=0x16042000
[E][esp32-hal-i2c.c:1445] i2cDumpI2c(): lock=0x3ffb2590
[E][esp32-hal-i2c.c:1447] i2cDumpI2c(): num=0
[E][esp32-hal-i2c.c:1448] i2cDumpI2c(): mode=1
[E][esp32-hal-i2c.c:1449] i2cDumpI2c(): stage=3
[E][esp32-hal-i2c.c:1450] i2cDumpI2c(): error=4
[E][esp32-hal-i2c.c:1451] i2cDumpI2c(): event=0x3ffb2614 bits=300
[E][esp32-hal-i2c.c:1452] i2cDumpI2c(): intr_handle=0x3ffb2644
[E][esp32-hal-i2c.c:1453] i2cDumpI2c(): dq=0x3ffb25f0
[E][esp32-hal-i2c.c:1454] i2cDumpI2c(): queueCount=1
[E][esp32-hal-i2c.c:1455] i2cDumpI2c(): queuePos=0
[E][esp32-hal-i2c.c:1456] i2cDumpI2c(): byteCnt=0
[E][esp32-hal-i2c.c:1413] i2cDumpDqData(): [0] 7a W STOP buf@=0x3ffc2a92, len=17, pos=17, eventH=0x0 bits=0
[E][esp32-hal-i2c.c:1431] i2cDumpDqData(): 0x0000: @................ 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[E][esp32-hal-i2c.c:1466] i2cDumpInts(): 0 row count INTR TX RX
[E][esp32-hal-i2c.c:1470] i2cDumpInts(): [01] 0x0001 0x0002 0x0012 0x0000 0x0000ef54
[E][esp32-hal-i2c.c:1470] i2cDumpInts(): [02] 0x0001 0x0200 0x0000 0x0000 0x0000ef54
[V][esp32-hal-i2c.c:1362] i2cSetFrequency(): threshold=3
[W][esp32-hal-i2c.c:1106] i2cCheckLineState(): invalid state sda=0, scl=1
Sometimes this error will occur almost straight away, sometimes it'll take a few minutes, but eventually the program will crash, and the OLED will become frozen.
Here are the pins I'm using:
// GPS TX: Huzzah32 RX/16
// GPS RX: Huzzah32 TX/17
// GPS Vin: 3V
// GPS RX: Ground
// OLED Data: Huzzah32 SDA/23
// OLED Clk: Huzzah32 SCL/22
// OLED Rst: Huzzah32 A5/4
// OLED Vin: 3V
// OLED Gnd: Ground
Since the GPS is running on the serial, and the OLED is over I2C, I don't see how they're messing with each other, although admittedly I'm relatively new to electronics.
I've tried a bunch of different code combinations trying to prevent this from happening, including trying to disable the GPS while the OLED was updating via the enable pin, and while using the adafruit GPS library.
Here is a very simple version of the code which replicates the issue:
Code: Select all
// GPS Initialization
#define GPSSerial Serial2
#include <HardwareSerial.h>
// OLED Initialization
#define SSD1306_LCDHEIGHT 64
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET A5
Adafruit_SSD1306 display(OLED_RESET);
void setup() {
// wait for hardware serial to appear
while (!Serial);
// make this baud rate fast enough to we aren't waiting on it
Serial.begin(115200);
// 9600 baud is the default rate for the Ultimate GPS
GPSSerial.begin(9600);
setup_OLEDDisplayer();
}
void setup_OLEDDisplayer() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3D); // initialize with the I2C addr 0x3D (for the 128x64)
display.display(); // adafruit splashscreen.
delay(1000);
}
int timer = millis();
int counter = 0;
void OLEDCounter(){
if(timer>millis()-10) return;
timer = millis();
Serial.println("update display");
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0,0);
display.println(counter);
display.display();
counter++;
}
void loop() {
if (Serial.available()) {
char c = Serial.read();
GPSSerial.write(c);
}
if (GPSSerial.available()) {
char c = GPSSerial.read();
Serial.write(c);
}
OLEDCounter();
}
Does anyone have any suggestions?