Включите мигалку 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