/*
ESP32_timer_02.ino
https://wokwi.com/projects/422677313923747841
sorce code:
https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/Timer/RepeatTimer/RepeatTimer.ino
# ESPRESSIF project
Repeat timer example
This example shows how to use hardware timer in ESP32. The timer calls onTimer
function every second. The timer can be stopped with button attached to PIN 0
(IO0).
This example code is in the public domain.
*/
// Stop button is attached to PIN 0 (IO0)
const uint8_t BTN_PIN = 14;
const uint8_t RED_LED = 15;
bool G_blTimerRUNNING = false;
//
hw_timer_t *timer = NULL;
volatile SemaphoreHandle_t timerSemaphore;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
volatile uint32_t isrCounter = 0;
volatile uint32_t lastIsrAt = 0;
// ******************************************
void ARDUINO_ISR_ATTR onTimer() {
// Increment the counter and set the time of ISR
portENTER_CRITICAL_ISR(&timerMux);
isrCounter = isrCounter + 1;
lastIsrAt = millis();
portEXIT_CRITICAL_ISR(&timerMux);
// Give a semaphore that we can check in the loop
xSemaphoreGiveFromISR(timerSemaphore, NULL);
// It is safe to use digitalRead/Write here if you want to toggle an output
} // onTimer()
void chk_Bttn() {
//
static uint8_t prvsBttn8 = 1; // as default, button state is HIGH (open contacts)
// read the button state
uint8_t crrntBttn8 = digitalRead(BTN_PIN);
// compare to previous state
if (crrntBttn8 != prvsBttn8) {
// check if the button is pressed
if (crrntBttn8 == 0) {
//
if (G_blTimerRUNNING) {
// stop timer
timerStop(timer);
G_blTimerRUNNING = false;
digitalWrite(RED_LED, G_blTimerRUNNING); // LED off
//
} else {
// start timer
timerStart(timer);
G_blTimerRUNNING = true;
digitalWrite(RED_LED, G_blTimerRUNNING); // LED on
//
} // if-else
//
} // if
// update stored state
prvsBttn8 = crrntBttn8;
// now, wait 25 milliseconds (BUT ONLY if using a button...)
vTaskDelay(pdMS_TO_TICKS(25));
//
} // if
//
} // chk_Bttn()
// ******************************************
void setup() {
//
Serial.begin(115200);
// Set BTN_PIN to input mode
pinMode(BTN_PIN, INPUT_PULLUP);
//
pinMode(RED_LED, OUTPUT);
// Create semaphore to inform us when the timer has fired
timerSemaphore = xSemaphoreCreateBinary();
// Set timer frequency to 1Mhz (1 micros. resolution)
timer = timerBegin(1000000);
// Attach onTimer function to our timer.
timerAttachInterrupt(timer, &onTimer);
// Set alarm to call onTimer function every half second (value in microseconds).
// Repeat the alarm (third parameter) with unlimited count = 0 (fourth parameter).
timerAlarm(timer, 300000, true, 0);
//
digitalWrite(RED_LED, 1); // LED on
//
} // setup()
void loop() {
// If Timer has fired
if (xSemaphoreTake(timerSemaphore, 0) == pdTRUE) {
uint32_t isrCount = 0, isrTime = 0;
// Read the interrupt count and time
portENTER_CRITICAL(&timerMux);
isrCount = isrCounter;
isrTime = lastIsrAt;
portEXIT_CRITICAL(&timerMux);
// Print it
Serial.printf("onTimer no.%d at %d ms\n", isrCount, isrTime);
}
// check if button is pressed
chk_Bttn();
//
} // loop()