I have just started using ESP32 and tested dual core functionality, which works fine i.e. can blink two leds with different blink intervals parallelly. Also I've tested touch sensors, they also works fine. Problem came when I combined both. Actually I wanted to execute touch detection in one core and control neopixel led strip(WS2812) in another core.
Below is the code I am using:-
#include <Adafruit_NeoPixel.h>
TaskHandle_t ConnectTask;
#define LED_PIN 26
#define LED_COUNT 300
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
int touch[] = {27, 14, 12, 13};
boolean touchStarted[] = {false, false, false, false};
unsigned long touchTime[] = {0, 0, 0, 0};
int threshold = 90;
int touchMinDuration = 100;
void setup() {
Serial.begin(115200);
strip.begin();
strip.show();
strip.setBrightness(50);
xTaskCreatePinnedToCore(Connect, "Connect", 10000, NULL, 1, &ConnectTask, 0);
delay(500);
}
void loop() {
colorWipe(strip.Color(255, 0, 0), 50);
colorWipe(strip.Color( 0, 255, 0), 50);
colorWipe(strip.Color( 0, 0, 255), 50);
theaterChase(strip.Color(127, 127, 127), 50);
theaterChase(strip.Color(127, 0, 0), 50);
theaterChase(strip.Color( 0, 0, 127), 50);
rainbow(10);
theaterChaseRainbow(50);
}
void Connect( void * pvParameters ) {
for (;;) {
checkTouch(); // works fine if comment this
delay(10);
}
}
void checkTouch(){
for (int i = 0; i < 4; i++) {
int t = touchRead(touch[i]);
if (t < threshold && !touchStarted[i]) { // touched
touchStarted[i] = true;
touchTime[i] = millis();
} else if (t >= threshold && touchStarted[i]) { // touched not
if (millis() - touchTime[i] > touchMinDuration)
touched(i);
touchStarted[i] = false;
}
}
}
void touched(int id)
{
switch (id) {
case 0: Serial.println("TOUCH 1"); break;
case 1: Serial.println("TOUCH 2"); break;
case 2: Serial.println("TOUCH 3"); break;
case 3: Serial.println("TOUCH 4"); break;
}
}
void colorWipe(uint32_t color, int wait) {
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, color);
strip.show();
delay(wait);
}
}
void theaterChase(uint32_t color, int wait) {
for (int a = 0; a < 10; a++) {
for (int b = 0; b < 3; b++) {
strip.clear();
for (int c = b; c < strip.numPixels(); c += 3) {
strip.setPixelColor(c, color);
}
strip.show();
delay(wait);
}
}
}
void rainbow(int wait) {
for (long firstPixelHue = 0; firstPixelHue < 5 * 65536; firstPixelHue += 256) {
for (int i = 0; i < strip.numPixels(); i++) {
int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
}
strip.show();
delay(wait);
}
}
void theaterChaseRainbow(int wait) {
int firstPixelHue = 0;
for (int a = 0; a < 30; a++) {
for (int b = 0; b < 3; b++) {
strip.clear();
for (int c = b; c < strip.numPixels(); c += 3) {
int hue = firstPixelHue + c * 65536L / strip.numPixels();
uint32_t color = strip.gamma32(strip.ColorHSV(hue));
strip.setPixelColor(c, color);
}
strip.show();
delay(wait);
firstPixelHue += 65536 / 90;
}
}
}
Problem with this code is that led strip working strangely i.e. strip turn white and starts performing white spiral loop at certain intervals (Let me know if video is needed).
If I comment this line:-
checkTouch();
inside Connect task. Strip animation works as expected. I can't understand why Connect task is interfering with loop() when they are running on separate cores, also Connect task don't have any code for neopixel control, just checking touches (touch functionality is working i.e. prints "TOUCH 1" etc).