Saw this project Three LEDs with Dirty Delay (ESP32) - #21 by Gunner on multi-threading with the ESP32 and thought I have a crack at a non-blocking second thread reading analog and digital inputs
The only trap I found is that ADC1 uses CORE1 and ADC2 uses CORE0. Can’t find documentation on that but I can confirm it is the case (after several hours of hair pulling)
It’s a simple loop with a single 50mS duty to de-bounce the buttons then a counter for 2 second Blynk updates. Works well. Short video and the code below…
Cheers
/* ESP32 Blynk multi threading example
* IE: Blink runs on Core 0, User tasks on core 1
* Tip: ADC's are split acroos the two cores so be warned =)
* Functions:
* 1 x analogRead (10K or larger POT if its an experiment)
* 2 x digitalRead (Button 1 = Count Up, Button 2 = Zero Counter)
* Duty cycle for updates = 2 seconds
*
*/
// Template ID, Device Name and Auth Token are provided by the Blynk.Cloud
// See the Device Info tab, or Template settings
#define BLYNK_TEMPLATE_ID "Your Template ID"
#define BLYNK_DEVICE_NAME "Your Device Name"
#define BLYNK_AUTH_TOKEN "Your Device Token"
// Comment this out to disable prints and save space
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
char auth[] = BLYNK_AUTH_TOKEN;
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "Your WiFi SSID";
char pass[] = "Your WiFi Password";
// Constants
const int countPin = 15, zeroPin = 25, voltPin = 34;
#define DUTY 50L
#define REF_VOLTS (float)3.33
#define ADC_MAX (uint16_t)4095
#define TWO_SEC 40
//Variables
byte ledState = LOW, countState, lastCountState = HIGH,
zeroState, lastZeroState = HIGH;
uint16_t pressCount = 0, dutyCount = 0;
uint32_t prevTime = 0;
bool countPress = false, zeroPress = false;
// Just practicing strings
String calculateVolts(uint16_t i){
float x = ((float)i*(REF_VOLTS/ADC_MAX));
return String(x); // Returns calculated result as a string
}
void loop2(void *pvParameters){ // Core 1 loop - User tasks
while (1){
countState = digitalRead(countPin);
zeroState = digitalRead(zeroPin);
if(countState != lastCountState){
prevTime = millis();
countPress = true;
}
if(zeroState != lastZeroState){
prevTime = millis();
zeroPress = true;
}
if(millis() - prevTime >= DUTY){
prevTime = millis();
dutyCount++;
if(countPress){
if(countState == LOW){
pressCount++;
dutyCount = 0;
countPress = false;
}
}
if(zeroPress){
if(zeroState == LOW){
pressCount = 0;
dutyCount = 0;
zeroPress = false;
}
}
if(dutyCount >= TWO_SEC){
uint16_t reading = analogRead(voltPin);
String volts = calculateVolts(reading);
Blynk.virtualWrite(V0, reading);
Blynk.virtualWrite(V1, volts);
Blynk.virtualWrite(V2, pressCount);
Serial.printf("Reading: %u", reading);
Serial.printf("\tVoltage reading: %s", volts);
Serial.printf("\tPress No: %u", pressCount);
Serial.println("");
dutyCount = 0;
}
}
lastCountState = countState;
lastZeroState = zeroState;
}
}
void loop1(void *pvParameters){ // Core 0 - Blink loop
while (1) {
Blynk.run();
delay(1);
}
}
void setup(){
// Debug console
Serial.begin(115200);
Serial.println("Connecting to Blynk Server\n");
Blynk.begin(auth, ssid, pass);
pinMode(countPin, INPUT_PULLUP);
pinMode(zeroPin, INPUT_PULLUP);
pinMode(voltPin, INPUT);
xTaskCreatePinnedToCore(loop2, "loop2", 4096, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(loop1, "loop1", 4096, NULL, 1, NULL, 0);
Serial.println("");
Serial.println("Connected and Ready - Waiting for Button Press\n");
}
void loop(){}