Skip to content

I2C NACK error when making two calls to PPS library with less than 100us gap #1

Open

Description

@colintd

Describe the bug

With the latest ESP32 and PPS libraries, the example PPS application hangs on a Core2 in under a minute. After exploration this appears to be due to a bug in the latest ESP32 I2C driver, which has had impacts on a number of projects.

I have created a very simple test app which tight loops on the 4 read functions in the example app, printing their results to Serial instead of the screen. With the latest ESP32 support, this typically hangs on an I2C Hardware NACK in less than 1000 iterations (<5s). With logic added to the library I2C functions to ensure at least 100us of gap, it runs indefinitely (currently over 100M loops).

I will generate a PR for both the test app and the library tweak,

To reproduce

Either:

  • Build and install the stock example using a Core2, and observe the display stops updating in under a minute

or

  • Use the cutdown Serial printf test app (included below), and observe the hang after less than 5s, along with the ESP32-IF driver NACK error message.
// Minimal test app making calls to PPS module in tight loop, printing state to Serial
// Used to verify stability of the I2C interface to the module.
#include <M5Unified.h>
#include "M5ModulePPS.h"

M5ModulePPS pps;

#define OUTPUT_VOLTAGE 5.0f
#define OUTPUT_CURRENT 5.0f

void setup() 
{
    M5.begin();
    Serial.begin(1000000);

    Serial.printf("Attempting to connect to PPS\n");
    
    while (!pps.begin(&Wire, M5.In_I2C.getSDA(), M5.In_I2C.getSCL(), MODULE_POWER_ADDR, 400000U)) 
    {
        Serial.println("Connect error");
        delay(100);
    }

    Serial.printf("PPS connected\n");

    pps.setOutputVoltage(OUTPUT_VOLTAGE);
    pps.setOutputCurrent(OUTPUT_CURRENT);
    pps.setPowerEnable(true);
}

int cycle=0;
void loop() 
{

    float voltage_readback = pps.getReadbackVoltage();
    float current_readback = pps.getReadbackCurrent();
    float vin              = pps.getVIN();
    const char * modestr   = ((pps.getMode() <= 1) ? "CV" : "CC");

    Serial.printf("%d: Vin=%0.3fV Vout=%0.3fV Iout=%0.3fA Mode=%s\n",cycle++,vin,voltage_readback,current_readback,modestr);
}

Expected behavior

The correct behavior is the example app keeps updating the screen, and the Serial tight loop just keeps running.

Screenshots

No response

Environment

  • IDE &IDE Version: Latest Arduino IDE as of 24-Mar-26

Additional context

No response

Issue checklist

  • I searched for previous reports in the issue tracker
  • My report contains all necessary details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions