Светодиодное кольцо с различными эффектами циклически
Мне нужна помощь с моим небольшим проектом. Я не знаю Arduino, поэтому использовал ChatGPT для написания кода. После нескольких часов тестирования я почти получил то, что мне нужно. Схема следующая: светодиодное кольцо, кнопка и потенциометр. Я использую потенциометр для управления яркостью, а кнопка переключается между различными режимами (эффектами). После попыток выяснить, что происходит, я думаю, что нашел проблему, но я не знаю, как ее исправить.
В коде ниже проблема в функции toggleMode()
. Это выражение: mode = (mode + 1) % 3;
, нарушает правильное выполнение. Все три эффекта могут быть циклически повторены только один раз, а затем он застревает на последнем эффекте. Есть ли какое-либо другое выражение, которое я могу использовать для вычисления «mode»? Вот полный код (также есть несколько строк для отладки, как вы можете видеть):
#include <FastLED.h>
#include <Arduino.h> // Включить основную библиотеку Arduino для поддержки последовательного порта
// Определяем количество светодиодов в светодиодном кольце
#define NUM_LEDS 24
// Определить пин данных
#define DATA_PIN 6
// Определить тип светодиода
#define LED_TYPE WS2812B
// Определить порядок цветов
#define COLOR_ORDER GRB
// Создаем массив объектов CRGB для хранения цветов каждого светодиода
CRGB leds[NUM_LEDS];
// Определить вывод для потенциометра
#define POTENTIOMETER_PIN A0
// Определить пин для кнопки
#define BUTTON_PIN 2
// Определим минимальное и максимальное значения яркости
#define MIN_BRIGHTNESS 0
#define MAX_BRIGHTNESS 255
// Переменная для хранения текущего режима (0: статическая радуга, 1: сверкание)
int mode = 0;
int previousButtonState = HIGH;
void setup() {
// Инициализируем последовательную связь со скоростью 9600 бод
Serial.begin(9600);
mode = 2;
// Инициализируем библиотеку FastLED
FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
// Установить начальную яркость
FastLED.setBrightness(MAX_BRIGHTNESS / 2);
// Установить вывод кнопки как вход с внутренним подтягивающим резистором
pinMode(BUTTON_PIN, INPUT_PULLUP);
}
void loop() {
// Считать значение с потенциометра
int potValue = analogRead(POTENTIOMETER_PIN);
// Сопоставьте значение потенциометра с диапазоном яркости
int brightness = map(potValue, 0, 1023, MIN_BRIGHTNESS, MAX_BRIGHTNESS);
// Установить яркость светодиодного кольца
FastLED.setBrightness(brightness);
// Проверка состояния кнопки с устранением дребезга
int buttonState = digitalRead(BUTTON_PIN);
if (buttonState == LOW && previousButtonState == HIGH) {
// Кнопка нажата в первый раз
// Переключить режим при нажатии кнопки
toggleMode();
}
previousButtonState = buttonState;
// Вызвать соответствующую функцию в зависимости от режима
if (mode == 0) {
Serial.println("Mode: Rainbow");
rainbow();
} else if (mode == 1) {
Serial.println("Mode: Sparkle");
sparkle();
} else if (mode == 2) {
Serial.println("Mode: Static Rainbow Fade");
staticRainbowFade();
}
// Отображение обновленных цветов светодиодов
FastLED.show();
// Задержка для управления скоростью цикла
delay(30);
}
// Функция переключения режима между радугой и блеском
void toggleMode() {
mode = (mode + 1) % 3;
//Отладка кода
Serial.print("Mode toggled: ");
Serial.println(mode);
}
// Функция для создания эффекта радуги
void rainbow() {
// Значение приращения оттенка определяет скорость радуги
static uint8_t hue = 0;
// Заполните светодиодное кольцо цветами
for(int i = 0; i < NUM_LEDS; i++) {
leds[i] = CHSV(hue + (i * 255 / NUM_LEDS), 255, 255);
}
// Увеличиваем значение оттенка для следующей итерации
hue++;
}
// Функция для создания эффекта мерцания с плавным затуханием и изменением цвета
void sparkle() {
// Вероятность загорания светодиода (регулируйте по мере необходимости)
const float sparkleProbability = 0.02; // Отрегулируйте это значение, чтобы изменить плотность блеска
// Проходим по каждому светодиоду
for (int i = 0; i < NUM_LEDS; i++) {
// Проверьте, должен ли светодиод загореться
if (random(0, 1000) < (sparkleProbability * 1000)) {
// Устанавливаем случайный цвет для мерцающего светодиода
CRGB sparkleColor = CHSV(random(0, 255), 255, 255); // Случайный цвет
leds[i] = sparkleColor;
}
// Выключить все светодиоды
leds[i].fadeToBlackBy(10); // Отрегулируйте скорость затухания (более низкое значение затухает быстрее)
}
}
// Функция для создания статического эффекта радуги с плавным появлением и исчезновением
void staticRainbowFade() {
// Заполните светодиодное кольцо цветами радуги
rainbow();
// Постепенное появление
for (int brightness = 0; brightness <= 255; brightness++) {
// Установить яркость всех светодиодов
FastLED.setBrightness(brightness);
// Отображение обновленных цветов светодиодов
FastLED.show();
// Задержка для управления скоростью затухания (регулируйте по мере необходимости для достижения желаемого эффекта)
delay(7); // Отрегулируйте это значение для увеличения скорости
}
// Задержка между появлением и исчезновением
delay(1000); // Отрегулируйте это значение для задержки между появлением и исчезновением
// Плавное затухание
for (int brightness = 255; brightness >= 0; brightness--) {
// Установить яркость всех светодиодов
FastLED.setBrightness(brightness);
// Отображение обновленных цветов светодиодов
FastLED.show();
// Задержка для управления скоростью затухания (регулируйте по мере необходимости для достижения желаемого эффекта)
delay(7); // Отрегулируйте это значение для скорости затухания
}
}
@Niki, 👍0
Обсуждение1 ответ
Строка изменения режима верна. jsotola упоминает альтернативную форму, например:
void toggleMode() {
mode++;
if (mode == 3) {
mode = 0;
}
// Отладочный код
Serial.print("Mode toggled: ");
Serial.println(mode);
}
Но это не ошибка, и это не поможет.
Ошибка в том, что ваш staticRainbowFade()
задерживается примерно на 4,5 секунды. Только после этого времени кнопка считывается.
Соответствующие части приведены здесь в сжатом виде:
void loop() {
//...
int buttonState = digitalRead(BUTTON_PIN);
//...
} else if (mode == 2) {
Serial.println("Mode: Static Rainbow Fade");
staticRainbowFade(); // <=== this takes about 4.5 seconds
}
// ...
}
void staticRainbowFade() {
// ...
for (int brightness = 0; brightness <= 255; brightness++) {
// ...
delay(7);
}
delay(1000);
for (int brightness = 255; brightness >= 0; brightness--) {
// ...
delay(7);
}
}
В качестве немедленного «решения» вы можете оставить кнопку ненажатой примерно на 5 секунд, а затем нажать ее примерно на 5 секунд. Это должно изменить режим.
Однако это всего лишь обходной путь. На самом деле вам следует переделать свой скетч в форму без задержки. Поскольку это требует некоторых усилий, я не представляю его здесь. Вы можете взглянуть на пример Blinky, который не использует delay()
, чтобы получить представление. Другая тема для исследования — это "конечный автомат", который разделяет отдельную логику.
Или - как еще один обходной путь - также считывать кнопку в циклах for внутри staticRainbowFade()
. И по крайней мере уменьшить задержку в 1 с между циклами for. Хотя переписать код без задержки гораздо чище, @chrisl
Я не знаю, что переписать. Мне просто нужно, чтобы это работало так, как я ожидаю. Я не программист (очевидно). Мне интересны многие вещи, и я не могу изучить все, даже если захочу. Вот почему я начал играть с кодированием ChatGPT, и я доволен результатами, но есть некоторые проблемы, которые ИИ не может решить (пока, надеюсь). Спасибо за ответ. Я продолжу читать и постараюсь исправить это., @Niki
Ну, ну. Я не буду постоянно ругать ИИ, но они понятия не имеют о программировании, потому что у них нет _понимания_. ChatGPT и подобные просто хороши в угадывании последовательностей слов, которые не содержат синтаксических ошибок. Вместо этого вам нужен семантически правильный код. -- Вам нужно полное решение, вероятно, с объяснением, которое здесь слишком обширно. Вы изучали предложенный пример? Вы его поняли? Если у вас есть конкретный вопрос об этом Blinky, не стесняйтесь задавать отдельный вопрос здесь. Однако вы можете захотеть дать ссылку на этот вопрос., @the busybee
- Глобальные переменные занимают много места в динамической памяти.
- Ошибка: "'lcd' does not name a type" при использовании библиотеки LiquidCrystal.
- Программирование Arduino Uno R3 для срабатывания реле каждые 24 часа
- Попытка сохранить файлы .wav с новым именем в каждом цикле.
- Как управлять двумя шаговыми двигателями и использовать ультразвуковой датчик вместе?
- Матрица и пространство состояний Реализация Arduino
- Новый код приводит к звуковому шуму
- Передача цвета функции без использования определенного Adafruit_NeoPixel
просто увеличивайте режим
mode++
... затем устанавливайте на0
, если он достигает3
, @jsotolaСпасибо! Это выглядит гораздо более простым решением! Проблема в том, что я не знаю, куда это добавить... Я пытался добавить это в toggleMode(), но ничего не происходит., @Niki
@Niki Ты читал мой ответ? Замена одного рабочего кода на другой рабочий код не исправит твою ошибку, которая имеет не связанную с этим причину., @the busybee
@thebusybee Да, я проверил ссылку Nordic. Я думал, что пример Blinky из примеров Arduino SDK, но теперь я его нашел и проверю., @Niki
@Niki, это может тебе помочь... кое-что, что я написал в качестве демонстрации... https://wokwi.com/projects/362275278547275777, @jsotola