Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
wvsbsp opened this issue Feb 4, 2024 · 8 comments
Closed
Labels
bug Something isn't working

Comments

@wvsbsp
Copy link

wvsbsp commented Feb 4, 2024

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):

  • OS: Windows 11
  • Browser Chrome
  • Version 120

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?

@wvsbsp wvsbsp added the bug Something isn't working label Feb 4, 2024
@urish
Copy link
Contributor

urish commented Feb 4, 2024

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
Copy link

geekgarage commented Feb 4, 2024

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
Copy link
Contributor

urish commented Feb 4, 2024

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 (HTTPS / TLS requests not completing on ESP32-C3 #721), we actually uncovered two different issues that took several hours to fix.

@wvsbsp
Copy link
Author

wvsbsp commented Feb 4, 2024

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
Copy link
Author

wvsbsp commented Feb 4, 2024

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
Copy link
Contributor

urish commented Feb 4, 2024

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
Copy link
Author

wvsbsp commented Feb 4, 2024

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
Copy link

geekgarage commented Feb 4, 2024

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
wokwi/wokwi-boards#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.

@wvsbsp wvsbsp closed this as completed Feb 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants