So I made a post yesterday running into an issue on my ESP32 using both cores on the microcontroller (with wifi enabled, incase that is important).
I'm using both cores to control two Neopixel strips individually. I'm making a music visualizer, and I want the neopixels to react to the change in music as quickly as possible, so I felt like having one for every individual core was the best way for that to happen. The issue I am running into is that when audio is playing, the Music Visualizer function either in the primary core (Core 1), or secondary core (Core 0) will just completely freeze. I tried troubleshooting with some Serial.Print statements to understand where the code breaks, and it seems to happen around the setPixelColor command. I think my code is being thread locked, and I wanted to know what I could do to make it thread safe.
void musicVisualizer(void) {
middle_strip.clear();
upper_strip.clear();
middle_strip.show();
upper_strip.show();
// Add code to tell Core 0 to wait until LED's are cleared.
while (vu_meter) {
tweeter_prev = tweeter;
if (analogRead(tweeter_sample) <= 490)
tweeter_adc = 0;
else {
tweeter_adc = (analogRead(tweeter_sample) - 490);
if (tweeter_adc < 0)
tweeter_adc = 0; // Filter for changing reference voltage
else if (tweeter_adc > MIDDLE_LED_COUNT)
tweeter_adc = tweeter_prev; // Filter for if there are intermittent spikes in the adc
}
tweeter_filter.Filter(tweeter_adc);
tweeter = tweeter_filter.Current() * 6; // 6 scaler is for when Alexa is at Volume Level 4
// /* Changing LED Number to improve efficency when turning on LED's */
// if (tweeter > 43)
// LED_COUNT = 65;
// else if (tweeter > 21)
// LED_COUNT = 43;
// else if (tweeter <= 21)
// LED_COUNT = 21;
/* LED's turning on and off in response to audio */
if ((tweeter > tweeter_prev) && (tweeter <= MIDDLE_LED_COUNT)) {
for (int x = tweeter_prev; x < tweeter; x++) {
// middle_strip.setPixelColor(x, color);
middle_strip.setPixelColor(x, 0, 0, middle_strip.gamma32(brightness));
middle_strip.show();
}
}
else if (tweeter_prev > tweeter) {
for (int x = tweeter_prev; x >= tweeter; x--) {
middle_strip.setPixelColor(x, 0, 0, 0);
middle_strip.show();
}
}
}
/* Leaving VU Meter, returning to current lamp color set */
if (led_on) {
if (!color_white) {
for (int i = 0; i < LOWER_LED_COUNT; i++) {
lower_strip.setPixelColor(i, color);
lower_strip.show();
}
for (int i = 0; i < MIDDLE_LED_COUNT; i++) {
middle_strip.setPixelColor(i, color);
middle_strip.show();
}
for (int i = 0; i < UPPER_LED_COUNT; i++) {
upper_strip.setPixelColor(i, color);
upper_strip.show();
}
}
else {
for (int i = 0; i < LOWER_LED_COUNT; i++) {
lower_strip.setPixelColor(i, 0, 0, 0, lower_strip.gamma32(brightness));
lower_strip.show();
}
for (int i = 0; i < MIDDLE_LED_COUNT; i++) {
middle_strip.setPixelColor(i, 0, 0, 0, middle_strip.gamma32(brightness));
middle_strip.show();
}
for (int i = 0; i < UPPER_LED_COUNT; i++) {
upper_strip.setPixelColor(i, 0, 0, 0, upper_strip.gamma32(brightness));
upper_strip.show();
}
}
}
else {
upper_strip.clear();
middle_strip.clear();
lower_strip.clear();
upper_strip.show();
middle_strip.show();
lower_strip.show();
}
}
void vu_meter_sub(void * parameter) {
while (true) {
esp_task_wdt_init(30, false);
if (vu_meter) {
lower_strip.clear();
lower_strip.show();
while (vu_meter) {
sub_prev = sub;
sub_adc = analogRead(sub_sample);
if (sub_adc > LOWER_LED_COUNT)
sub_adc = LOWER_LED_COUNT-1;
sub_filter.Filter(sub_adc);
sub = sub_filter.Current();
// if (sub < 0)
// sub = 0;
Serial.println(sub);
if ((sub > sub_prev) && (sub <= LOWER_LED_COUNT)) {
for (int x = sub_prev; x < sub; x++) {
// lower_strip.setPixelColor(x, color);
lower_strip.setPixelColor(x, 0, lower_strip.gamma32(brightness), 0);
lower_strip.show();
}
}
else if (sub_prev > sub) {
for (int x = sub_prev; x >= sub; x--) {
lower_strip.setPixelColor(x, 0, 0, 0);
lower_strip.show();
}
}
Blynk.run();
}
}
}
}
1 Answer 1
I am not sure this is related to thread-safety, but you should be aware
that strip.show()
is a slow function that blocks while the data is
being sent. setPixelColor()
, in contrast, is fast, as it only updates
the data in memory.
I suggest you modify musicVisualizer()
in such a way that it only
show()
s each strip once. The bulk of the function should be about
computing the colors you want and setting them with setPixelColor()
.
Then, at the very end of the function, show()
the three strips.
-
I thank you for the suggestion. I implemented this into my code, but this did not fix the issue I'm experiencing with one of the cores freezing up. I feel like this might have to do with the fact that they are sharing the same library header?Jay– Jay2021年09月28日 00:13:22 +00:00Commented Sep 28, 2021 at 0:13