/*
ESP32_timer_03.ino
https://wokwi.com/projects/422759572332226561
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 ISR_onTimer
function every 1/3 second. The timer can be stopped with button attached to GPIO14
A LED has been linked to GPIO32
This example code is in the public domain.
*/
// Stop button is attached to PIN 0 (IO0)
const uint8_t Gk_pinBttn8 = 14;
const uint8_t Gk_pinLED8 = 32;
//
bool G_blTimerRUNNING = false;
volatile uint32_t Gvlt_isrCntr32 = 0;
volatile uint32_t Gvlt_lastIsrAt32 = 0;
//
volatile SemaphoreHandle_t Gvlt_timerSemaphore;
//
//
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
//
hw_timer_t *timer = NULL;
//
// ******************************************
// ** Functions prototipes declaration ******
//
void ISR_onTimer();
void chk_Bttn();
//
// ******************************************
void ARDUINO_ISR_ATTR ISR_onTimer() {
// Increment the counter and set the time of ISR
portENTER_CRITICAL_ISR(&timerMux);
Gvlt_isrCntr32 = Gvlt_isrCntr32 + 1;
Gvlt_lastIsrAt32 = millis();
portEXIT_CRITICAL_ISR(&timerMux);
// Give a semaphore that we can check in the loop
xSemaphoreGiveFromISR(Gvlt_timerSemaphore, NULL);
//
} // ISR_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(Gk_pinBttn8);
// 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;
//
} else {
// start timer
timerStart(timer); // ok
//G_blTimerRUNNING = true;
//
} // if-else
//
G_blTimerRUNNING = !G_blTimerRUNNING;
//
} // if
//
digitalWrite(Gk_pinLED8, G_blTimerRUNNING);
// update stored state
prvsBttn8 = crrntBttn8;
// now, wait 40 milliseconds (BUT ONLY if using a button...)
vTaskDelay(pdMS_TO_TICKS(40));
//
} // if
//
} // chk_Bttn()
// ******************************************
void setup() {
//
Serial.begin(115200);
// Set Gk_pinBttn8 to input mode
pinMode(Gk_pinBttn8, INPUT_PULLUP);
//
pinMode(Gk_pinLED8, OUTPUT);
// Create semaphore to inform us when the timer has fired
Gvlt_timerSemaphore = xSemaphoreCreateBinary();
// Set timer frequency to 1Mhz (1 micros. resolution)
timer = timerBegin(1000000);
// Attach ISR_onTimer function to our timer.
timerAttachInterrupt(timer, &ISR_onTimer);
// Set alarm to call ISR_onTimer function every half second (value in microseconds).
// Repeat the alarm (third parameter) with unlimited count = 0 (fourth parameter).
timerAlarm(timer, 300000, true, 0);
// to avoid fancy messages, the Timer MUST be stopped
timerStop(timer);
//
digitalWrite(Gk_pinLED8, 0); // LED on (timer stop)
//
} // setup()
void loop() {
// If Timer has fired
if (xSemaphoreTake(Gvlt_timerSemaphore, 0) == pdTRUE) {
uint32_t isrCount = 0, isrTime = 0;
// Read the interrupt count and time
portENTER_CRITICAL(&timerMux);
isrCount = Gvlt_isrCntr32;
isrTime = Gvlt_lastIsrAt32;
portEXIT_CRITICAL(&timerMux);
// Print it
Serial.printf("ISR_onTimer no.%d at %d ms\n", isrCount, isrTime);
}
// check if button is pressed
chk_Bttn();
//
} // loop()