wokwi / wokwi-features

Wokwi Feature requests & Bug Reports
https://wokwi.com
72 stars 17 forks source link

ESP32 interrupts() and noInterrupts() not working correctly with SSD1306 OLED #729

Closed wvsbsp closed 8 months ago

wvsbsp commented 8 months ago

Describe the bug When i disable interrupts on the ESP32 before display.display() the program hangs up

To Reproduce Remove the comment in Line 330, place comment in line 341 https://wokwi.com/projects/388804995646001153

Expected behavior the program should execute the display-functions, even if i disable external interrupts. The program works on real hardware (with Arduino 2.2.1)

Environment (please complete the following information):

Additional context Instead of disabling the interrupts, i could also enable the button-interrupt only after the first polling-event.... Could this be an issue of having one or two CPUs?

urish commented 8 months ago

Hello, thanks for reporting!

Has this code been tested on actual hardware? In most cases, the issue is not a simulation issue, rather an issue with the code or the way a third party library works.

The simulator implements both cores on the ESP32 (this is required for FreeRTOS to function correctly).

geekgarage commented 8 months ago

I have the same issue with this https://wokwi.com/projects/388202397151520769.

I'm sure it will run just fine on real hardware. But when simulated it will crash any complex interrupt.

So this code is set up to play an alarm melody on boot, and that works just fine.

Then it attaches interrupt to the button press on the rotary encoder and to the CLK where i detect left and right turn.

Left and right work just fine playing a single tone, but the button press playing the alarm melody, it instantly crashes the simulation

image

#include <Stepper.h>
#include <pitches.h>
#include <FastLED.h>

//----- Buzzer Setup -----
#define SPEAKER_PIN 0
//----- Buzzer END -----

//----- Encoder BTN Setup -----
#define ENCODER_CLK 2
#define ENCODER_DT 3
#define ENCODER_SW 4
int lastClk = HIGH;
//----- Encoder BTN END -----

//----- LEDs Setup -----
#define NUM_LEDS 4
#define DATA_PIN 1
CRGB leds[NUM_LEDS];
//----- LEDs END -----

//----- Stepper Setup -----
const int stepsPerRevolution = 200*64;  // change this to fit the number of steps per revolution for your motor
// initialize the stepper library on pins 8 through 11:
Stepper redStepper(stepsPerRevolution, 5, 6, 7, 8);
Stepper greenStepper(stepsPerRevolution, 9, 10, 20, 21);
//----- Stepper END -----

void setup() {
  FastLED.addLeds<WS2812, DATA_PIN, GRB>(leds, NUM_LEDS);
  redStepper.setSpeed(60);
  greenStepper.setSpeed(60);
  PlayRedAlarm();
  pinMode(ENCODER_CLK, INPUT);
  pinMode(ENCODER_DT, INPUT);
  pinMode(ENCODER_SW, INPUT);
  attachInterrupt(digitalPinToInterrupt(ENCODER_SW), Ext_INT1_ISR, RISING);
  attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), readEncoder, FALLING);
}

//void IRAM_ATTR Ext_INT1_ISR()
void Ext_INT1_ISR()
{
  //tone(SPEAKER_PIN, 1900, 250);
  PlayRedAlarm();
}

void readEncoder() {
  int dtValue = digitalRead(ENCODER_DT);
  if (dtValue == HIGH) {
    tone(SPEAKER_PIN, 300, 250);
  }
  if (dtValue == LOW) {
    tone(SPEAKER_PIN, 900, 250);
  }
}

void loop() {
  delay(10);
/*
  for (int thisLED = 0; thisLED < NUM_LEDS; thisLED++) {
    leds[thisLED] = CRGB(255, 0, 0);
  }
  FastLED.show();

  while (digitalRead(0) == LOW) {
    //Set stepper to 0 position
    redStepper.step(1);
  }
  for (int thisLED = 0; thisLED < NUM_LEDS; thisLED++) {
    leds[thisLED] = CRGB(0, 0, 0);
  }
  FastLED.show();
  delay(500);

  for (int thisLED = 0; thisLED < NUM_LEDS; thisLED++) {
    leds[thisLED] = CRGB(0, 255, 0);
  }
  FastLED.show();

  while (digitalRead(0) == LOW) {
    //Set stepper to 0 position
    greenStepper.step(1);
  }
  for (int thisLED = 0; thisLED < NUM_LEDS; thisLED++) {
    leds[thisLED] = CRGB(0, 0, 0);
  }
  FastLED.show();
  delay(500);
*/
}
urish commented 8 months ago

Well, we need to be certain it works differently on actual hardware. The process for fixing bugs in the simulator is:

  1. Test that the issue does not happen on the actual hardware, with the same binary, and reproduces in the simulator
  2. In case of a complex program, create a minimal code example that reproduces the issue, preferably one that does not use any third party libraries or hardware.
  3. Once we have a minimal code example that produces different behavior, it usually takes about one hour of work to isolate the bug
  4. Once the bug has been isolated (pinned down to a specific peripheral or CPU behavior that does not match the simulation), the time it takes to fix depends on the complexity. In a recent example (#721), we actually uncovered two different issues that took several hours to fix.
wvsbsp commented 8 months ago

Has this code been tested on actual hardware?

Yes, i copied the code from a running project, that a student gave me. It might be a racing condition in the simulation. display.display() only sends a short command over the I2C-Bus. I assume, the library uses a callback/interrupt when the transmission ends. In real hardware, this process might be finished (just) before noInterrupts() takes effect. In the simulation, the function probably is stuck waiting for the interrupt to happen...

wvsbsp commented 8 months ago

Just checked the problematic code in Wokwi and with real hardware Wokwi Output

start( ) has finished before noInterrputs after noInterrputs display-update 1 display-update 2

But now on the real hardware i get:

start( ) has finished before noInterrputs after noInterrputs display-update 1 display-update 2 Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1).

I see a problem here ;-) The original project definitely ran on this ESP32-board in october 2021... probably changes in the BSP oder Free-RTOS since then. Wehn i move the noInterrupts() past display.disply() everything works in the simulator and the real hardware.

urish commented 8 months ago

Thanks for checking! That's why we always want to check the same binary on the hardware. Unfortunately, source code is not enough for reproducible results - the underlying esp-idf framework evolves over time, the Arduino core for ESP32 is constantly changing, and third-party libraries may also changes.

You can download the binary that is running inside Wokwi by pressing F1 in the code editor and then "Download Compiled Firmware".

wvsbsp commented 8 months ago

I have the same issue with this https://wokwi.com/projects/388202397151520769.

When i try to open your project, i see only a green custom chip instead of the PCF8575 and a message "loading wokwi-custom-board" instead of your cpu-module. Side-question: how do you add a custom graphic to custom chips? Couldn't find any hints in the coumentation.

geekgarage commented 8 months ago

Thanks for checking! That's why we always want to check the same binary on the hardware. Unfortunately, source code is not enough for reproducible results - the underlying esp-idf framework evolves over time, the Arduino core for ESP32 is constantly changing, and third-party libraries may also changes.

You can download the binary that is running inside Wokwi by pressing F1 in the code editor and then "Download Compiled Firmware".

Would love to test with physical hardware but i don't have everything delivered yet, so i can't test it currently

I have the same issue with this https://wokwi.com/projects/388202397151520769.

When i try to open your project, i see only a green custom chip instead of the PCF8575 and a message "loading wokwi-custom-board" instead of your cpu-module. Side-question: how do you add a custom graphic to custom chips? Couldn't find any hints in the coumentation.

It's because I'm currently waiting for my PR to get approved, so I'm using my custom files for a ESP32-C3 board https://github.com/wokwi/wokwi-boards/pull/28

I have no clue regarding custom chip design, but I'm actually looking into it right now as i want to add the PCF8575 chip to the list. I found the code for it to work in another Wokwi project, so i borrowed it to play around, But i like the look of the actual board, so thats my next project I will add to Wokwi PR for new chips. I only think it's the MCU you can do custom graphics currently, but I'm not 100% sure on that.