Мигание светодиодов последовательно с классом

Я пытаюсь создать программу, которая принимает четырехзначный пароль с помощью клавиатуры 3*4.

Программа должна начинаться с мигания светодиода 1, а при вводе пароля 1 она переключает этот светодиод и мигает светодиодом 2. Если введен пароль 2, он переключается на LED3 и так далее.

Вот код:

#include <Keypad.h>
#include <TimedBlink.h>

#define Password_Length 5

TimedBlink led1(14);
TimedBlink led2(15);
TimedBlink led3(16);
TimedBlink led4(17);

const unsigned long PERIOD1 = 1000;
char  buffers[4][4] = {{'1', '2', '3', '4'}, {'6', '5', '4', '3'}, {'9', '8', '7', '6'}, {'1', '2', '5', '6'}}; // вот как инициализировать двумерный массив
unsigned long previousMillis[5]; //[x] = количество светодиодов
char Data[Password_Length]; // 6 — это количество символов, которые он может содержать + нулевой символ = 7

byte data_count = 0;
bool Pass_is_good;
char customKey;

const byte ROWS = 4;
const byte COLS = 3;
char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte rowPins[ROWS] = {2, 3, 4, 5}; //подключаемся к распиновке ряда клавиатуры
byte colPins[COLS] = {6, 7, 8}; //подключаем к колонке распиновку клавиатуры
int ledservos[4] = {14, 15, 16, 17};
Keypad customKeypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); // инициализируем экземпляр класса NewKeypad

void setup() {
  pinMode(14, OUTPUT);
  pinMode(15, OUTPUT);
  pinMode(16, OUTPUT);
  pinMode(17, OUTPUT);
  led1.blink(150, 50); // Вкл. на 150 мс, выкл. на 50 мс
  led2.blink(150, 50);
  led3.blink(150, 50); // Вкл. на 150 мс, выкл. на 50 мс
  led4.blink(150, 50);
  Serial.begin(9600);
  Serial.print("Enter Password");
  Serial.println();
}

void loop() {
  led1.blink();
  led2.blink();
  led3.blink();
  led4.blink();
  customKey = customKeypad.getKey();
  if (customKey) {
  // удостоверяемся, что клавиша действительно нажата, равная (customKey != NO_KEY)
    Data[data_count] = customKey; // сохраняем символ в массив данных
    data_count++; // увеличиваем массив данных на 1 для сохранения нового символа, а также отслеживаем количество введенных символов
  }
  if (data_count == Password_Length - 1) {
    // если индекс массива равен количеству ожидаемых символов, сравним данные с мастером
    Serial.print("Password is ");
    for (byte i = 0; i < Password_Length; i++)
      Serial.print(Data[i]);
    for (x = 0; x < 4; x++) { //этот цикл для количества паролей в массиве
      for (y = 0; y < 4; y ++) { // этот цикл для количества символов в каждом из массивов паролей
        if (strcmp(Data[y], buffers[x][y]) != 0) {
          break;
        }
      }
      if (y == 4) {
        break;
      }
    }
    if (x < 4) {
      Serial.print(" Found at index ");
      Serial.println(x);
      switch (x) {
        case 0:
          led1.blinkOff();
          break;
        case 1:
          led2.blinkOff();
          break;
        case 2:
          led3.blinkOff();
          break;
        case 3:
          led4.blinkOff();
          break;
      }
    }
    clearData();
  }
}

void clearData() {
  Serial.println();
  while (data_count != 0) {
    // Это можно использовать для любого размера массива,
    Data[data_count--] = 0; //очистить массив для новых данных
  }
}

void BlinkLed (int led, int interval, int arry) {
  //(long) можно опустить, если вы не планируете мигать светодиодом очень долго, я думаю
  if (((long)millis() - previousMillis[arry]) >= interval) {
    previousMillis[arry] = millis(); //сохраняет значение миллисекунд в выбранном массиве
    digitalWrite(led, !digitalRead(led)); //изменить состояние светодиода
  }
}

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

Вот ссылка на библиотеку TimedBlink.

Я пробовал использовать функцию millis() для мигания светодиодами в следующем коде:

#include <Keypad.h>
#include <Wire.h>

#define buzzer 13
#define greenled 20
#define redled 21
#define Password_Length 5

unsigned long previousMillisLED14 = 0;
unsigned long previousMillisLED15 = 0;
unsigned long previousMillisLED16 = 0;
unsigned long previousMillisLED17 = 0;
// разные интервалы для каждого светодиода
int intervalLED14 = 500;
int intervalLED15 = 600;
int intervalLED16 = 700;
int intervalLED17 = 800;
// каждый светодиод получает переменную состояния
boolean LED14state = false;     // светодиод включится на первой итерации цикла()
boolean LED15state = false;     // нужно посеять свет, чтобы он был выключен
boolean LED16state = false;     // нужно посеять свет, чтобы он был выключен
boolean LED17state = false;     // нужно посеять свет, чтобы он был выключен
const unsigned long PERIOD1 = 1000;
char  buffers[4][4] = {{'1', '2', '3', '4'}, {'6', '5', '4', '3'}, {'9', '8', '7', '6'}, {'1', '2', '5', '6'}}; // вот как инициализировать двумерный массив
unsigned long previousMillis[5]; //[x] = количество светодиодов
byte i, x, y;
char Data[Password_Length]; // 6 — это количество символов, которые он может содержать + нулевой символ = 7
byte data_count = 0;
bool Pass_is_good;
char customKey;
const byte ROWS = 4;
const byte COLS = 3;
char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};
byte rowPins[ROWS] = {2, 3, 4, 5}; //подключаемся к распиновке ряда клавиатуры
byte colPins[COLS] = {6, 7, 8}; //подключаем к колонке распиновку клавиатуры
int ledservos[4] = {14, 15, 16, 17};
Keypad customKeypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); // инициализируем экземпляр класса NewKeypad

void setup() {
  pinMode(14, OUTPUT);
  pinMode(15, OUTPUT);
  pinMode(16, OUTPUT);
  pinMode(17, OUTPUT);
  Serial.begin(9600);
  pinMode(buzzer, OUTPUT);
  pinMode(redled, OUTPUT);
  pinMode(greenled, OUTPUT);
  Serial.print("Enter Password");
  Serial.println();
}

void loop() {
  unsigned long currentMillis = millis();
  if ((unsigned long)(currentMillis - previousMillisLED14) >= intervalLED14) {
    LED14state = !LED14state;
    digitalWrite(14, LED14state);
    // сохраняем текущее время в выводе 12 в предыдущем Millis
    previousMillisLED14 = currentMillis;
  }
  customKey = customKeypad.getKey();
  if (customKey) {
    // удостоверяемся, что клавиша действительно нажата, равная (customKey != NO_KEY)
    Data[data_count] = customKey; // сохраняем символ в массив данных
    data_count++; // увеличиваем массив данных на 1 для сохранения нового символа, а также отслеживаем количество введенных символов
  }
  if (data_count == Password_Length - 1) {
    // если индекс массива равен количеству ожидаемых символов, сравним данные с мастером
    Serial.print("Password is ");
    for (byte i = 0; i < Password_Length; i++)
      Serial.print(Data[i]);
    for (x = 0; x < 4; x++) {
      //этот цикл для количества паролей в массиве
      for (y = 0; y < 4; y ++) {
        //этот цикл для количества символов в каждом массиве паролей
        if (strcmp(Data[y], buffers[x][y]) != 0) {
          break;
        }
      }
      if (y == 4) {
        break;
      }
    }
    if (x < 4) {
      Serial.print(" Found at index ");
      Serial.println(x);
      switch (x) {
        case 0:
          digitalWrite(14, LOW);
          digitalWrite(16, LOW);
          digitalWrite(17, LOW);
          if ((unsigned long)(currentMillis - previousMillisLED15) >= intervalLED15) {
            LED15state = !LED15state;
            digitalWrite(15, LED15state);
            // сохраняем текущее время в выводе 12 в предыдущем Millis
            previousMillisLED15 = currentMillis;
          }
          break;
        case 1:
          digitalWrite(15, LOW);
          digitalWrite(14, LOW);
          digitalWrite(17, LOW);
          if ((unsigned long)(currentMillis - previousMillisLED16) >= intervalLED16) {
            LED16state = !LED16state;
            digitalWrite(16, LED15state);
            // сохраняем текущее время в выводе 12 в предыдущем Millis
            previousMillisLED16 = currentMillis;
          }
          break;
        case 2:
          digitalWrite(15, LOW);
          digitalWrite(14, LOW);
          digitalWrite(16, LOW);
          if ((unsigned long)(currentMillis - previousMillisLED17) >= intervalLED17) {
            LED17state = !LED17state;
            digitalWrite(17, LED17state);
            // сохраняем текущее время в выводе 12 в предыдущем Millis
            previousMillisLED17 = currentMillis;
          }
          break;
        case 3:
          digitalWrite(15, LOW);
          digitalWrite(14, LOW);
          digitalWrite(16, LOW);
          digitalWrite(17, LOW);
          break;
      }
    }
    clearData();
  }
}

void clearData() {
  Serial.println();
  while (data_count != 0) {
    // Это можно использовать для любого размера массива,
    Data[data_count--] = 0; //очистить массив для новых данных
  }
}

Но он мигает только первым светодиодом, затем каждый из следующих светодиодов в зависимости от условия горит постоянно. Я пробовал решение, предложенное Adafruit, использовать класс в коде, но, к сожалению, получил тот же результат, что и предыдущий код.

Вот код:

#include <Keypad.h>
#include <Wire.h>

class Flasher {
    // Переменные члена класса
    // Они инициализируются при запуске
    int ledPin;      // номер вывода светодиода
    long OnTime;     // миллисекунды времени включения
    long OffTime;    // миллисекунды простоя
    // Они поддерживают текущее состояние
    int ledState;                 // ledState используется для установки светодиода
    unsigned long previousMillis;   // запомним время последнего обновления светодиода
    // Конструктор - создает Flasher
    // и инициализирует переменные-члены и состояние
  public:
    Flasher(int pin, long on, long off) {
      ledPin = pin;
      pinMode(ledPin, OUTPUT);
      OnTime = on;
      OffTime = off;
      ledState = LOW;
      previousMillis = 0;
    }
    void Update() {
      // проверяем, не пора ли изменить состояние светодиода
      unsigned long currentMillis = millis();
      if ((ledState == HIGH) && (currentMillis - previousMillis >= OnTime)) {
        ledState = LOW;  // Выключи
        previousMillis = currentMillis;  // Запоминаем время
        digitalWrite(ledPin, ledState);  // Обновить фактический светодиод
      } else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime)) {
        ledState = HIGH;  // включить его
        previousMillis = currentMillis;   // Запоминаем время
        digitalWrite(ledPin, ledState);   // Обновить фактический светодиод
      }
    }
};

Flasher led1(14, 100, 400);
Flasher led2(15, 350, 350);
Flasher led3(16, 100, 400);
Flasher led4(17, 350, 350);

#define buzzer 13
#define greenled 20
#define redled 21
#define Password_Length 5

char  buffers[4][4] = {{'1', '2', '3', '4'}, {'6', '5', '4', '3'}, {'9', '8', '7', '6'}, {'1', '2', '5', '6'}}; // вот как инициализировать двумерный массив
unsigned long previousMillis[5]; //[x] = количество светодиодов
byte i, x, y;
char Data[Password_Length]; // 6 — это количество символов, которые он может содержать + нулевой символ = 7

byte data_count = 0;
bool Pass_is_good;
char customKey;
const byte ROWS = 4;
const byte COLS = 3;
char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};
byte rowPins[ROWS] = {2, 3, 4, 5}; //подключаемся к распиновке ряда клавиатуры
byte colPins[COLS] = {6, 7, 8}; //подключаем к колонке распиновку клавиатуры
int ledservos[4] = {14, 15, 16, 17};
Keypad customKeypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); // инициализируем экземпляр класса NewKeypad

void setup() {
  Serial.begin(9600);
  pinMode(buzzer, OUTPUT);
  pinMode(redled, OUTPUT);
  pinMode(greenled, OUTPUT);
  Serial.print("Enter Password");
  Serial.println();
}

void loop() {
  led1.Update();
  customKey = customKeypad.getKey();
  if (customKey) {
    // удостоверяемся, что клавиша действительно нажата, равная (customKey != NO_KEY)
    Data[data_count] = customKey; // сохраняем символ в массив данных
    data_count++; // увеличиваем массив данных на 1 для сохранения нового символа, а также отслеживаем количество введенных символов
  }
  if (data_count == Password_Length - 1) {
    // если индекс массива равен количеству ожидаемых символов, сравним данные с мастером
    Serial.print("Password is ");
    for (byte i = 0; i < Password_Length; i++)
      Serial.print(Data[i]);
    for (x = 0; x < 4; x++) {
      //этот цикл для количества паролей в массиве
      for (y = 0; y < 4; y ++) {
        //этот цикл для количества символов в каждом массиве паролей
        if (strcmp(Data[y], buffers[x][y]) != 0) {
          break;
        }
      }
      if (y == 4) {
        break;
      }
    }
    if (x < 4) {
      Serial.print(" Found at index ");
      Serial.println(x);
      switch (x) {
        case 0:
          led2.Update();
          digitalWrite(14, LOW);
          digitalWrite(16, LOW);
          digitalWrite(17, LOW);
          break;
        case 1:
          led3.Update();
          digitalWrite(15, LOW);
          digitalWrite(14, LOW);
          digitalWrite(17, LOW);
          break;
        case 2:
          led4.Update();
          digitalWrite(15, LOW);
          digitalWrite(14, LOW);
          digitalWrite(16, LOW);
          break;
        case 3:
          digitalWrite(15, LOW);
          digitalWrite(14, LOW);
          digitalWrite(16, LOW);
          digitalWrite(17, LOW);
          break;
      }
    }
    clearData();
  }
}

void clearData() {
  Serial.println();
  while (data_count != 0) {
    // Это можно использовать для любого размера массива,
    Data[data_count--] = 0; //очистить массив для новых данных
  }
}

Есть идеи, почему это происходит?

, 👍0

Обсуждение

почему бы вам не попробовать определить, почему все светодиоды начинают мигать при запуске программы, @jsotola

на самом деле я пытаюсь получить помощь cz полностью застрял после этого шага, @Amr Ahmed

посмотрите на первую команду в блоке loop() ..... подумайте о ее функции, @jsotola

дорогой, я понимаю, что ты имеешь в виду, но когда я попытался поместить функцию led.blink в случаи переключения, я не получил никаких результатов, хотя они должны были там работать, @Amr Ahmed

Поместите ссылку на библиотеку TimedBlink, которую вы используете, в свой вопрос, а не в ответ на ответ. Вы должны предоставить достаточно информации, чтобы люди, читающие ваш вопрос, могли понять вашу проблему., @Duncan C


1 ответ


1

ИЗМЕНИТЬ

Теперь, когда вы добавили ссылку на библиотеку TimedBlink, я смог взглянуть на нее. Это не очень хорошо написанная библиотека, и ее документация ужасна.

Похоже, что blink(int,int) запускает мигание светодиода TimedBlink, а blinkOff останавливает его. Поэтому вам не следует вызывать LEDx.blink(150,50) для любого из ваших светодиодов, пока вы не захотите, чтобы они начали мигать.

Вам необходимо реорганизовать код, чтобы он вызывал LEDx.blink(150,50) только для одного светодиода за раз. Вероятно, вы хотите, чтобы ваш оператор switch вызывал LEDx.blink(150,50) для светодиода, который вы хотите мигать, и ledOff() для остальных.

,

спасибо 4 ур ответ, это ссылка для мигания по времени [ссылка](https://github.com/lpasqualis/TimedBlink), я попробовал способ, предложенный в вашем ответе, но это не сработало, светодиоды остаются выключенными, @Amr Ahmed

Смотрите редактирование моего ответа. Вам нужно отредактировать свой вопрос и указать ссылку на библиотеку в вопросе, а не в комментарии к моему ответу. Другие люди, читающие эту ветку, захотят получить ту же информацию, и им не придется ее искать. Когда вы готовитесь опубликовать вопрос, остановитесь и подумайте: «Какая информация понадобится читателям моего вопроса, чтобы понять мой вопрос? Я все предоставил?, @Duncan C

я пробовал, но к сожалению безрезультатно, @Amr Ahmed