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

   }

Как правильно обрабатывать состояние? чтобы светодиод постоянно моргал? но также может отключить все светодиоды также, если я могу включать светодиоды вместе, в данный момент я включаю один, затем другой,

Все эти проблемы возникают из-за непонимания того, как обрабатывать состояние внутри и управлять изменениями, поступающими через последовательный порт.

, 👍0

Обсуждение

используйте blueRunning = HIGH; для непосредственного сохранения состояния светодиода.... затем установите все три цвета одновременно без использования оператора if... digitalWrite(blueLED, blueRunning); delay(125) ; digitalWrite(blueLED, LOW);, @jsotola

@jsotola, какой отличный способ сделать это! Спасибо! пожалуйста, сделай это ответом, @manuelBetancurt


2 ответа


1

Я думаю, вы довольно хорошо справляетесь с состоянием, но если вы потратите некоторое время на другие темы, я уверен, что у вас все получится:

  1. Вместо delay везде используйте только одну в конце и убедитесь, что вы обрабатываете все состояния до этой задержки. Это означает, что вы устанавливаете все свои состояния так, как хотите, и эта единственная delay упрощает анализ скетча.

  2. Разделите скетч на отдельные части (внутри функции 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);
,

1

Вот непроверенный код, использующий неблокирующий таймер для мигания светодиодов.

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, ВЫСОКИЙ);
цифровая запись (зеленый светодиод, ВЫСОКИЙ);
цифровая запись (синий светодиод, высокий);
}
}
}
,