BluetoothSerial.h's .println() ruins hardware timer interrupt on other core

I'm using ESP32 Arduino IDE. I have one task at each core. In the core0 task I set up a timer interrupt that signals to the task (through the interruptCounter variable) to toggle a pin every 100 us. On core1 I have a task which sends some gibberish on bluetooth with the SerialBT.println("1") function.

I measured the pin with an oscilloscope. If I delete SerialBT.println("1") function, or use Serial.println("1"), or I don't open the bluetooth serial monitor on Arduino IDE, it works fine and I get a nice 5 kHz square signal. However, if I open the serial monitor on the port associated with bluetooth, the pin toggles at very random intervals, so the frequency changes all the time.

I tried many things, but I still have no idea how one core affects the other in this code.

EDIT: After finding the run/stop button on the oscilloscope, I realised that it still mostly toggles at a regular 100us interval, but every after every few toggle it forgets to toggle for a few ms usually. The interval and the pulses between these glitches seem to be irrergular. So the problem remains, but I just added this info.

#include "BluetoothSerial.h"
#include "esp_task_wdt.h"

volatile int interruptCounter = 0;
hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;

BluetoothSerial SerialBT;

//interrupt routine
void IRAM_ATTR onTimer() {
  portENTER_CRITICAL_ISR(&timerMux);
  interruptCounter++;
  portEXIT_CRITICAL_ISR(&timerMux);
 
}
 
void setup() {
 
  Serial.begin(2000000);
  
  SerialBT.begin("ESP32"); //Bluetooth device name
  Serial.println("The device started, now you can pair it with bluetooth!");
  
  pinMode(26, OUTPUT);

  disableCore0WDT(); 
  disableCore1WDT();
  
  xTaskCreatePinnedToCore(
    adc_read,   /* Function to implement the task */
    "adc_read_task", /* Name of the task */
    1024,       /* Stack size in words */
    NULL,       /* Task input parameter */
    1,          /* Priority of the task */
    NULL,       /* Task handle. */
    0);  /* Core where the task should run */

  xTaskCreatePinnedToCore(
    bl_send,   /* Function to implement the task */
    "bl_send_task", /* Name of the task */
    1024,       /* Stack size in words */
    NULL,       /* Task input parameter */
    2,          /* Priority of the task */
    NULL,       /* Task handle. */
    1);  /* Core where the task should run */
}

 
void loop() {vTaskDelete(NULL);  }

static void  adc_read (void *pvParameters )
{

  //launch the interrupt on core 0
  timer = timerBegin(0, 80, true);
  timerAttachInterrupt(timer, &onTimer, true);
  timerAlarmWrite(timer, 100, true);
  timerAlarmEnable(timer);
  
  for(;;) {

    if (interruptCounter > 0) {     
      portENTER_CRITICAL(&timerMux);
      interruptCounter=0;
      portEXIT_CRITICAL(&timerMux);
              
      digitalWrite(26, !digitalRead(26));
    }  
  }
}

static void bl_send (void *pvParameters )
{
    for( ;; )
    {
      SerialBT.println("1");
    }
}

My understanding is that the bluetooth by default runs in core 0 (PRO). Your task maybe in core1 (APP) but the bluetooth transmission itself will be in core0 and it appears that it conflicts with the timer interrupt.

I think there may be options to move tasks to specific cores, but I have no specific knowledge of how to do this .

I tried switching the cores and I get the same result (with slightly less frequency changing maybe). Also the Bluetooth transmission is much slower on that core.

What happens if you move the timer task to core1 and move blsend to core 0 where the actual send is taking place?

It's the same, as I just said:)

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.