0

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

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.

1
  • 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
    Commented Sep 28, 2021 at 0:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.