Как сделать программный код потокобезопасным?
Вчера я опубликовал сообщение, в котором столкнулся с проблемой на ESP32, использующем оба ядра на микроконтроллере (с включенным Wi-Fi, если это важно).
Я использую оба ядра для управления двумя полосками Neopixel по отдельности. Я создаю музыкальный визуализатор, и я хочу, чтобы неопиксели реагировали на изменения в музыке как можно быстрее, поэтому я чувствовал, что наличие одного для каждого отдельного ядра было лучшим способом для этого. Проблема, с которой я сталкиваюсь, заключается в том, что при воспроизведении звука функция музыкального визуализатора либо в основном ядре (ядро 1), либо во вторичном ядре (ядро 0) просто полностью зависает. Я попытался устранить неполадки с помощью какого-то серийного номера.Распечатайте инструкции, чтобы понять, где происходит разрыв кода, и, похоже, это происходит вокруг команды setPixelColor. Я думаю, что мой код заблокирован по потоку, и я хотел знать, что я могу сделать, чтобы сделать его потокобезопасным.
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();
}
}
}
}
@Jay, 👍0
1 ответ
Я не уверен, что это связано с безопасностью потоков, но вы должны знать
, что strip.show ()
-это медленная функция, которая блокируется во время
отправки данных. setPixelColor()
, напротив, работает быстро, так как обновляет только
данные в памяти.
Я предлагаю вам изменить musicVisualizer()
таким образом, чтобы он только
покажите()
каждую полосу один раз. Основная часть функции должна быть посвящена
вычислению нужных цветов и их настройке с помощью setPixelColor()
.
Затем, в самом конце функции, покажите()
три полоски.
- ESP32 в Arduino-IDE с FS.h и SPIFFS
- Программаторы для этой платы отсутствуют - Программирование ESP32 Cam с помощью Ardunio IDE
- Установка значения float до двух знаков после запятой
- ESP32-CAM первый: 0x8 TG1WDT_SYS_RESET загрузочный цикл
- esp32 Stack canary watchpoint срабатывает
- Проверка размера во флэш-памяти Esp32
- Ошибка Cast from 'char*' to 'uint8_t {aka unsigned char}' loses precision [-fpermissive]
- WindowsError(31, "Устройство, подключенное к системе, не функционирует") в arduino
Я благодарю вас за это предложение. Я внедрил это в свой код, но это не устранило проблему, с которой я столкнулся, когда одно из ядер замерзло. Я чувствую, что это может быть связано с тем, что они используют один и тот же заголовок библиотеки?, @Jay