Unable to get timers to compile on ESP32 nano

Getting an error trying to use ESP32TimerInterrupt library.

In file included from C:\Users\wrs64\AppData\Local\Arduino15\packages\arduino\hardware\esp32\2.0.13\cores\esp32/Arduino.h:223,
from C:\Users\wrs64\AppData\Local\Temp\arduino\sketches\CB9AF896DEF463909E8A74D6D2DA6498\sketch\Cab1.ino.cpp:1:
C:\Users\wrs64\AppData\Local\Arduino15\packages\arduino\hardware\esp32\2.0.13\cores\esp32/io_pin_remap.h:45:69: error: 'digitalPinToGPIONumber' is not a type
#define detachInterrupt(pin) detachInterrupt(digitalPinToGPIONumber(pin))
^~~~~~~~~~~~~~~~~~~~~~
c:\Users\wrs64\OneDrive\Documents\Arduino\libraries\ESP32TimerInterrupt\src/ESP32TimerInterrupt.hpp:426:10: note: in expansion of macro 'detachInterrupt'
void detachInterrupt()

Has anyone gotten interrupting timers to work on Arduino Nano ESP32? If so, could you post a simple example.

Wayne in NH

don't have a ESP32 Nano but have used ESP32TimerInterrupt library on a number of ESP32 based microcontrollers
have you tried running example code such as File>Examples>ESP32TimerInterrupt>TimerInterruptTest
what Tools>Board did you select?

EDIT: just tried simple test with Tools>Board is ESP32 Dev Module

#define detachInterrupt(pin) detachInterrupt(digitalPinToGPIONumber(pin))

void setup() {
  detachInterrupt(16);
}

void loop() {}

and it compiles and links OK

Thank-you Horace.

The support for Nano ESP32 board has been "Arduinoized" with Nano style pin numbering and probably other stuff. I haven't found an interrupt timer example that will compile with that board setting even though they're listed under Nano ESP32.

I have also gotten it to work on other generic ESP32 boards like the Huzzah32 Feather. Don't think the Nano ESP32 support has been tested thoroughly.

Wayne in NH

what Tools>Board have you selected

today when I attempted to compile File>Examples>ESP32TimerInterrupt>TimerInterruptTest for Tolls>Board ESP32 Dev Module I got the following error

c:\Users\bb\Documents\Arduino\libraries\ESP32TimerInterrupt\src/ESP32TimerInterrupt.hpp:347:23: error: 'TIMER_BASE_CLK' was not declared in this scope
  347 |         _frequency  = TIMER_BASE_CLK / TIMER_DIVIDER;   //1000000;

was compiling and running OK a few weeks ago

the definition of TIMER_BASE_CLK was removed in IDF 5.0 and libraries do not appear to have been updated

as a quick fix I added the definition so

#define TIMER_BASE_CLK 80000000   // TIMER_BASE_CLK was removed in IDF 5.0 - add definition
#include "ESP32TimerInterrupt.h"

and it compiles, starts to run but then gives problems e.g.

Starting TimerInterruptTest on ESP32_DEV
ESP32TimerInterrupt v2.3.0
CPU Frequency = 240 MHz
[TISR] ESP32_TimerInterrupt: _timerNo = 0 , _fre = 1000000
[TISR] TIMER_BASE_CLK = 80000000 , TIMER_DIVIDER = 80
[TISR] _timerIndex = 0 , _timerGroup = 0
[TISR] _count = 0 - 50
[TISR] timer_set_alarm_value = 50.00
E (535) timer_group: timer_init(301): only support Level Interrupt
E (536) timer_group: timer_set_counter_value(92): HW TIMER NEVER INIT ERROR
E (542) timer_group: timer_set_alarm_value(165): HW TIMER NEVER INIT ERROR
E (549) timer_group: timer_enable_intr(230): HW TIMER NEVER INIT ERROR
E (555) timer_group: timer_isr_callback_add(266): HW TIMER NEVER INIT ERROR
E (562) timer_group: timer_start(103): HW TIMER NEVER INIT ERROR
Starting  ITimer0 OK0
0

changes in IDF 5.0 appear to be causing other problems

this guide Migration from Arduino ESP32 core 2.x to 3.0 and Arduino-ESP32 Timer API may help

Thank-you, Horace! I am using the Arduino Nano ESP32 board which is what I selected in the boards area. I think the business about removing the edge parameter from attachInterrupt() is the root of my problem. Looks like ESP32 support is in major flux. I'm going to move on from this - I have other approaches- and revisit things in a few months when Arduino has had a chance to clear this up for Nano32.

Thank-you again, Horace.

Regards

Wayne in NH

have a look at this ESP32 code which measures pulse width and rising edge-to-edge time using timer1 updated to use Arduino ESP32 core 3.0

// ESP32 - measure pulse width and rising edge-to-edge time using timer1 pins 16 and 17

// updated for Arduino ESP32 core 3.0 see
// https://docs.espressif.com/projects/arduino-esp32/en/latest/api/timer.html

hw_timer_t *Timer1_Cfg = NULL;  // timer object

volatile uint64_t pulseWidth = 0, pulseEdge = 0;  // used in interrupt routines

// rising edge interrupt calculate rising edge-to-edge time
void IRAM_ATTR rising() {
  pulseEdge = timerReadMicros(Timer1_Cfg);
  timerRestart(Timer1_Cfg);
}

// falling edge interrupt calculate pulse HIGH width
void IRAM_ATTR falling() {
  pulseWidth = (timerReadMicros(Timer1_Cfg));
}

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.printf("\n\nESP32 measure pins 16 and 17 pulse width and rising edge-to-edge time \n");
  //Timer1_Cfg = timerBegin(0, 80, true);           // API 2.x setup timer for 1uSec
  if ((Timer1_Cfg = timerBegin(10000000)) == NULL)  // API 3.0 setup timer for 1uSec
    Serial.println("timerBegin Failed!!");
  Serial.print("timerBegin() OK frequenmcy ");
  Serial.println(timerGetFrequency(Timer1_Cfg));
  //  setup interrput routines - connect signal to pins 16 and 17
  attachInterrupt(digitalPinToGPIONumber(16), rising, RISING);    // detect rising edge on pin 16
  attachInterrupt(digitalPinToGPIONumber(17), falling, FALLING);  // detect falling edge on pin 17
}

void loop() {  // print information every second
  static unsigned long timer = millis();
  if (millis() - timer >= 1000) {
    timer = millis();
    Serial.printf("pulse HIGH width %luuSec %.3fmSec\n", (unsigned long)pulseWidth, (unsigned long)pulseWidth / 1000.0);
    Serial.printf("rising edge-to-edge time %luuSec %.3fmSec frequency %.3fHz\n", (unsigned long)pulseEdge,
                  (unsigned long)pulseEdge / 1000.0, 1.0e6 / (unsigned long)pulseEdge);
  }
}

serial monitor output for different pulse periods

note with frequency less than 1Hz need to wait for pulse period for result
0.01Hz
pulse HIGH width 50004039uSec 50004.039mSec
rising edge-to-edge time 100008082uSec 100008.082mSec frequency 0.010Hz
pulse HIGH width 50004039uSec 50004.039mSec
rising edge-to-edge time 100008082uSec 100008.082mSec frequency 0.010Hz
pulse HIGH width 50004039uSec 50004.039mSec
rising edge-to-edge time 100008082uSec 100008.082mSec frequency 0.010Hz

0.1Hz pulses
pulse HIGH width 4999999uSec 4999.999mSec
rising edge-to-edge time 10000003uSec 10000.003mSec frequency 0.100Hz
pulse HIGH width 4999999uSec 4999.999mSec
rising edge-to-edge time 10000003uSec 10000.003mSec frequency 0.100Hz
pulse HIGH width 4999999uSec 4999.999mSec
rising edge-to-edge time 10000003uSec 10000.003mSec frequency 0.100Hz

1Hz pulses
pulse HIGH width 499988uSec 499.988mSec
rising edge-to-edge time 999990uSec 999.990mSec frequency 1.000Hz
pulse HIGH width 499988uSec 499.988mSec
rising edge-to-edge time 999986uSec 999.986mSec frequency 1.000Hz
pulse HIGH width 499989uSec 499.989mSec
rising edge-to-edge time 999987uSec 999.987mSec frequency 1.000Hz

10Hz pulses
pulse HIGH width 49997uSec 49.997mSec
rising edge-to-edge time 99997uSec 99.997mSec frequency 10.000Hz
pulse HIGH width 49996uSec 49.996mSec
rising edge-to-edge time 99996uSec 99.996mSec frequency 10.000Hz
pulse HIGH width 49995uSec 49.995mSec
rising edge-to-edge time 99994uSec 99.994mSec frequency 10.001Hz

100Hz
pulse HIGH width 4997uSec 4.997mSec
rising edge-to-edge time 9997uSec 9.997mSec frequency 100.030Hz
pulse HIGH width 4997uSec 4.997mSec
rising edge-to-edge time 9997uSec 9.997mSec frequency 100.030Hz
pulse HIGH width 4997uSec 4.997mSec
rising edge-to-edge time 9997uSec 9.997mSec frequency 100.030Hz

1KHz
pulse HIGH width 496uSec 0.496mSec
rising edge-to-edge time 997uSec 0.997mSec frequency 1003.009Hz
pulse HIGH width 496uSec 0.496mSec
rising edge-to-edge time 997uSec 0.997mSec frequency 1003.009Hz
pulse HIGH width 498uSec 0.498mSec
rising edge-to-edge time 997uSec 0.997mSec frequency 1003.009Hz

10KHz
pulse HIGH width 49uSec 0.049mSec
rising edge-to-edge time 98uSec 0.098mSec frequency 10204.082Hz
pulse HIGH width 46uSec 0.046mSec
rising edge-to-edge time 95uSec 0.095mSec frequency 10526.316Hz
pulse HIGH width 46uSec 0.046mSec
rising edge-to-edge time 95uSec 0.095mSec frequency 10526.316Hz

You can also program the timers using the native IDF APIs:

#include "Arduino.h"
#include "driver/gptimer.h"

void BlinkingTask(void *params);
bool timerCallback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data);

void setup() {
	Serial.begin(115200);
	delay(2000);
	Serial.println("Starting");
	xTaskCreatePinnedToCore(BlinkingTask, "Blinking", 1000, NULL, 5, NULL, ARDUINO_RUNNING_CORE);
}

void loop() {
	vTaskDelete(NULL);
}

void BlinkingTask(void *params) {
	TaskHandle_t myTaskHandle { xTaskGetCurrentTaskHandle() };
	pinMode(4, OUTPUT);
	digitalWrite(4, LOW);

	gptimer_handle_t gptimer = NULL;
	const gptimer_config_t timer_config = {
			.clk_src = GPTIMER_CLK_SRC_DEFAULT,
			.direction = GPTIMER_COUNT_UP,
			.resolution_hz = 1000000, // 1MHz, 1 tick=1us
			};
	assert((gptimer_new_timer(&timer_config, &gptimer)==ESP_OK) && "Failed to Create Timer");

	gptimer_event_callbacks_t cbs = {
			.on_alarm = timerCallback,
	};
	assert((gptimer_register_event_callbacks(gptimer, &cbs, static_cast<void*>(myTaskHandle))==ESP_OK) && "Failed to Register Callback");
	assert((gptimer_enable(gptimer)==ESP_OK) && "Failed to Enable Timer");

	gptimer_alarm_config_t alarm_config ={1000000, 0, true};
	assert((gptimer_set_alarm_action(gptimer, &alarm_config)==ESP_OK) && "Failed to Set Alarm Action");

	assert((gptimer_start(gptimer)==ESP_OK) && "Failed to Start Timer");

	for (;;) {
		ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
		digitalWrite(4, HIGH);
		vTaskDelay(5);
		digitalWrite(4, LOW);
	}
}

bool IRAM_ATTR timerCallback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data) {
	TaskHandle_t handle { static_cast<TaskHandle_t>(user_data) };
	BaseType_t pxHigherPriorityTaskWoken { pdFALSE };
	vTaskNotifyGiveFromISR(handle, &pxHigherPriorityTaskWoken);
	return pxHigherPriorityTaskWoken == pdTRUE;
}

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