ESP32 with I2C OLED dropping commands
Posted: Thu Mar 17, 2022 9:15 pm
Hello. I have an ESP-WROOM-32 dev kit with an I2C OLED and one button connected to it. I'm trying to control the display from Core 1. I have a software timer setup to turn the display off after a few seconds. It works once, then it will not turn the display off again after the first time. If I put some code in the button routine to turn the display on and off, it works fine. I've noticed that with the button, the routines are executed on Core 1. With the software timer the routines are executed on core 0. How can I have the software timer execute on Core 1? I've attached some code that recreates my issue. Thanks.
- #include "SSD1306Wire.h"
- #define BUTTON1_PIN 2
- #define I2C_SDA 21
- #define I2C_SCL 22
- SSD1306Wire display(0x3c, I2C_SDA, I2C_SCL);
- static const unsigned long BUTTON_INTERVAL = 25;
- static const unsigned long DISPLAY_INTERVAL = 2500;
- static const unsigned long DISPLAY_ON_INTERVAL = 5000;
- static const TickType_t dimDelay = DISPLAY_ON_INTERVAL / portTICK_PERIOD_MS;
- static TimerHandle_t displayOffTimer = NULL;
- long button1Timer = 0;
- long longPressTime = 1250;
- boolean button1Active = false;
- boolean longPressActive = false;
- void setup() {
- Serial.begin(38400);
- Serial.println("Starting");
- pinMode(BUTTON1_PIN, INPUT_PULLUP);
- display.init();
- // Clear the buffer
- Serial.println("Clearing display");
- display.clear();
- display.setTextAlignment(TEXT_ALIGN_LEFT);
- display.setFont(ArialMT_Plain_16);
- display.drawString(0, 0, "Starting");
- display.drawString(0, 16, "Screen");
- display.drawString(0, 32, "Test");
- display.display();
- delay(2000);
- xTaskCreatePinnedToCore(
- checkButtonValue, // Function to be called
- "checkButtonValue", // Name of task
- 1024,
- NULL, // Parameter to pass to function
- 5, // Task priority (0 to configMAX_PRIORITIES - 1)
- NULL, // Task handle
- 1); // Run on one core
- // // Create a one-shot timer
- // displayOffTimer = xTimerCreate(
- // "displayOff", // Name of timer
- // dimDelay, // Period of timer (in ticks)
- // pdFALSE, // Auto-reload
- // (void *)0, // Timer ID
- // autoDimmerCallback); // Callback function
- xTaskCreatePinnedToCore(
- checkOnDisplay, // Function to be called
- "updateDisplay", // Name of task
- 4096,
- NULL, // Parameter to pass to function
- 2, // Task priority (0 to configMAX_PRIORITIES - 1)
- NULL, // Task handle
- 1); // Run on one core
- vTaskDelete(NULL);
- delay(1000);
- Serial.println("Set up complete");
- }
- void checkOnDisplay(void *parameter) {
- Serial.print("checkOnDisplay running on core ");
- Serial.println(xPortGetCoreID());
- // Create a one-shot timer
- displayOffTimer = xTimerCreate(
- "displayOff", // Name of timer
- dimDelay, // Period of timer (in ticks)
- pdFALSE, // Auto-reload
- (void *)0, // Timer ID
- autoDimmerCallback); // Callback function
- xTimerStart(displayOffTimer, portMAX_DELAY);
- while (1) {
- vTaskDelay(DISPLAY_INTERVAL / portTICK_PERIOD_MS);
- // updateDisplayLogic();
- }
- }
- // Turn off display when timer expires
- void autoDimmerCallback(TimerHandle_t xTimer) {
- Serial.println("display timer expired");
- turnDisplayOff();
- }
- void turnDisplayOff() {
- Serial.print("Turn display off. Core ");
- int codeID = xPortGetCoreID();
- Serial.println(codeID);
- display.displayOff();
- }
- void turnDisplayOn() {
- Serial.print("Turn display on. Core ");
- int codeID = xPortGetCoreID();
- Serial.println(codeID);
- display.displayOn();
- xTimerStart(displayOffTimer, portMAX_DELAY);
- }
- void checkButtonValue(void *parameter) {
- while (1) {
- checkTheButton1();
- vTaskDelay(BUTTON_INTERVAL / portTICK_PERIOD_MS);
- }
- }
- void checkTheButton1() {
- if (digitalRead(BUTTON1_PIN) == LOW) {
- if (button1Active == false) {
- button1Active = true;
- button1Timer = millis();
- }
- if ((millis() - button1Timer > longPressTime) && (longPressActive == false)) { // long press action
- longPressActive = true;
- button1LongFunction();
- }
- } else {
- if (button1Active == true) {
- if (longPressActive == true) {
- longPressActive = false;
- } else {
- button1ShortFunction(); // short press action
- }
- }
- button1Active = false;
- }
- }
- void button1ShortFunction() {
- Serial.println("short press");
- turnDisplayOn();
- }
- void button1LongFunction() {
- Serial.println("long press");
- turnDisplayOff();
- }
- void loop() {
- }