Включите мигалку RGB через последовательный порт
У меня есть bluetooth arduino BLUno на базе uno.
логика вроде работает, к телефону подключаюсь нормально, получаю и отправляю сообщения через синий зуб
но с последовательными данными у меня проблемы с их использованием и с логикой.
Я хочу иметь возможность включать и выключать некоторые RGB-светодиоды, проблема в том, что состояние иногда нестабильно.
вот код
int redLED = 2;
int greenLED = 4;
int blueLED = 3;
static bool redRunning;
static bool greenRunning;
static bool blueRunning;
static bool freq = 34;
void setup() {
Serial.begin(115200); // инициализируем серийный номер
Serial.write("started");
pinMode(redLED, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(blueLED, OUTPUT);
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, HIGH);
digitalWrite(blueLED, HIGH);
redRunning = false;
greenRunning = false;
blueRunning = false;
freq = false;
}
void loop()
{
if (Serial.available() > 0)
f{
String s = Serial.readStringUntil('\n');
// Строка s = Serial.readStringUntil("#"); // До CR (возврат каретки)
// s.replace("#", "");
Serial.println("s:" + s);
if (s == "red_ON")
{
redRunning = true;
}
if (s == "red_OFF")
{
redRunning = false;
} if (s == "green_ON")
{
greenRunning = true;
} if (s == "green_OFF")
{
greenRunning = false;
} if (s == "blue_ON")
{
blueRunning = true;
} if (s == "blue_OFF")
{
blueRunning = false;
}
}
//
if (redRunning) {
// Serial.println("redRunning");
digitalWrite(redLED, LOW);
delay(125);
digitalWrite(redLED, HIGH);
delay(125);
}
if (greenRunning) {
// Serial.println("greenRunning");
digitalWrite(greenLED, LOW);
delay(125);
digitalWrite(greenLED, HIGH);
delay(125);
}
if (blueRunning) {
// Serial.println("blueRunning");
digitalWrite(blueLED, LOW);
delay(125);
digitalWrite(blueLED, HIGH);
delay(125);
}
if (!redRunning && !greenRunning && !blueRunning) {
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, HIGH);
digitalWrite(blueLED, HIGH);
}
}
Как правильно обрабатывать состояние? чтобы светодиод постоянно моргал? но также может отключить все светодиоды также, если я могу включать светодиоды вместе, в данный момент я включаю один, затем другой,
Все эти проблемы возникают из-за непонимания того, как обрабатывать состояние внутри и управлять изменениями, поступающими через последовательный порт.
@manuelBetancurt, 👍0
Обсуждение2 ответа
Я думаю, вы довольно хорошо справляетесь с состоянием, но если вы потратите некоторое время на другие темы, я уверен, что у вас все получится:
Вместо
delay
везде используйте только одну в конце и убедитесь, что вы обрабатываете все состояния до этой задержки. Это означает, что вы устанавливаете все свои состояния так, как хотите, и эта единственнаяdelay
упрощает анализ скетча.Разделите скетч на отдельные части (внутри функции
loop
):- Чтение серийного ввода
- Настройте состояния в соответствии с вашим серийным вводом
- Настройка состояний по времени (для мерцания)
- Настройте контакты GPIO для светодиодов в зависимости от этого состояния.
- Задержка
Что касается состояний, теперь вы используете 3 «рабочих» состояния, по одному для каждого цвета, это хорошо. Вероятно, проще сохранить эти переменные подключенными к последовательному входу (так что, если вы получаете «green_ON», greenRunning всегда
true
, иначеfalse
. Так что вам не нужно всегда устанавливайте их вfalse
в начале функцииloop
, только один раз во время объявления или вsetup
.
Затем вы создаете другую (глобальную) переменную, которая определяет, находится ли (любой) светодиод в ВЫСОКОМ состоянии (если он БУДЕТ работать) в НИЗКОМ состоянии. Эту переменную вы меняете каждые 125 мс (или с любой другой скоростью). Вы можете менять эту переменную каждые 125 мс (ledsOn = !ledsOn
).
Итак, вы получите что-то вроде (# = псевдокод), только для красного цвета, остальное аналогично:
глобально:
bool redRunning = false;
bool ledsOn = false;
в цикле
:
// Чтение последовательного ввода
# Read input
// Установить состояния
# if serial data Red On is received
redRunning = true;
# if serial data Red Off is received
redRunning = false;
ledsOn = !ledsOn;
// Установить светодиоды
digitalWrite(redLED, redRunning && ledsOn ? HIGH : LOW);
// Задерживать
delay(125);
Вот непроверенный код, использующий неблокирующий таймер для мигания светодиодов.
uint8_t красный светодиод = 2; uint8_t зеленый светодиод = 4; uint8_t blueLED = 3; статический uint8_t redRunning = ВЫСОКИЙ; // светодиод гаснет при запуске статический uint8_t greenRunning = ВЫСОКАЯ; статический uint8_t blueRunning = ВЫСОКИЙ; // статическая логическая частота = 34; // не уверен, что это недействительная установка () { Серийный.начать(115200); // инициализируем серийный номер Serial.write("запущено"); pinMode (красный светодиод, ВЫХОД); pinMode (зеленый светодиод, ВЫХОД); pinMode (синий светодиод, ВЫХОД); цифровая запись (красный светодиод, высокий); // светодиод выключен цифровая запись (зеленый светодиод, ВЫСОКИЙ); цифровая запись (синий светодиод, высокий); //частота = ложь; тик = ложь; // сигнал временного интервала светодиодное состояние = ложь; // состояние светодиодного дисплея статический uint32_t ledTicker = millis(); } недействительный цикл () { if (millis() - ledTicker >= 125) { // Один раз каждые 125 мс ledTicker = millis(); тик = правда; // устанавливаем тиковый флаг светодиодное состояние = !ledState; // меняет состояние на каждом тике } если (Серийный.доступный() > 0) { Строка s = Serial.readStringUntil('\n'); // Строка s = Serial.readStringUntil("#"); // До CR (возврат каретки) // s.replace("#", ""); Serial.println("s:" + s); if (s == "red_ON" ) redRunning = LOW ; // иногда этот формат легче читать if (s == "red_OFF" ) redRunning = HIGH; if (s == "green_ON" ) greenRunning = LOW ; if (s == "green_OFF") greenRunning = HIGH; if (s == "blue_ON" ) blueRunning = LOW ; if (s == "blue_OFF" ) blueRunning = HIGH; } // if (tick) { // прошло 125 мс, поэтому обновите светодиоды тик = ложь; // сбрасываем тик, чтобы светодиоды менялись только один раз за тик if (ledState) { // состояние светодиодов на этом тике digitalWrite(redLED, redRunning); цифровая запись (зеленый светодиод, зеленый работает); digitalWrite(blueLED, blueRunning); } else { // на этот раз все выключено digitalWrite(redLED, ВЫСОКИЙ); цифровая запись (зеленый светодиод, ВЫСОКИЙ); цифровая запись (синий светодиод, высокий); } } }
- Ошибка 'Serial' was not declared in this scope
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Ошибка "'Serial' does not name a type"
- Построение графика на Python с использованием Tkinter Canvas
- Отправка последовательных данных в прерывании
- Команда strtok() с Serial связью
- Чтение строки, разделенной запятыми
- Почему люди используют 115200 вместо 9600?
используйте
blueRunning = HIGH;
для непосредственного сохранения состояния светодиода.... затем установите все три цвета одновременно без использования оператораif
...digitalWrite(blueLED, blueRunning);
delay(125) ;
digitalWrite(blueLED, LOW);
, @jsotola@jsotola, какой отличный способ сделать это! Спасибо! пожалуйста, сделай это ответом, @manuelBetancurt