Рандомное включение светодиодов.

Тема в разделе "Arduino & Shields", создана пользователем AN-Misha, 7 июн 2014.

  1. AN-Misha

    AN-Misha Нуб

    Приветствую. Имеется 8 светодиодов, подключенных через сдвиговый регистр 74HC595 по схеме. Имеется код, который по очереди зажигает эти светодиоды. Вопрос: как его изменить, чтобы светодиоды зажигались рандомно на какое-то время, а затем гасли.
    Безымянный.png
    Код:
    //Пин подключен к ST_CP входу 74HC595
    int latchPin = 8;
    //Пин подключен к SH_CP входу 74HC595
    int clockPin = 12;
    //Пин подключен к DS входу 74HC595
    int dataPin = 11;
    void setup() {
    //устанавливаем режим OUTPUT
    pinMode(latchPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    Serial.begin(9600);
    Serial.println("reset");
    }
    void loop() {
    if (Serial.available() > 0) {
    // Символы от '0' до '9'
    // представлены в ASCII таблице значения от 48 до 57.
    int bitToSet = Serial.read() - 48;
    // Записываем HIGH в позицию соответствующую bitToSet
    registerWrite(bitToSet, HIGH);
    }
    }
    // Этот метот записывает байт в регистр
    void registerWrite(int whichPin, int whichState) {
    // инициализируем и обнуляем байт
    byte bitsToSend = 0;
    //Отключаем вывод на регистре
    digitalWrite(latchPin, LOW);
    // устанавливаем HIGH в соответствующем бите
    bitWrite(bitsToSend, whichPin, whichState);
    // проталкиваем байт в регистр
    shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);
    // "защелкиваем" регистр, чтобы байт появился на его выходах
    digitalWrite(latchPin, HIGH);
    }
     
  2. geher

    geher Гуру

    Приведенный ранее код включает светодиоды не по очереди, а по данным, передаваемым по последовательному порту.

    Для инициализации ГСЧ
    randomSeed(analogRead(0));

    random(2) вернет 0 или 1, который можно рассматривать как состояние для конкретного светодиода.
    Для случайного мигания устанавливаем состояние каждого светодиода в соответствии с результатом персонального для него вызова random(2).
    Если время горения нужно фиксированное, то можно построить таблицу времени переключения состояния каждого светодиода
    примерно так:
    Код (Text):

    #define MAX_LEDS 8
    unsigned long ledtime[MAX_LEDS];
    byte bitsToSend = 0; // байт состояния регистра - сбрасываем все биты
    void setup(){
      randomSeed(analogRead(0));
      for (int i=0;i<MAX_LEDS;i++){
        ledtime[i]=millis()+rand(1,10001); // включить через случайное время
        registerWrite(i, LOW); // при инициализации погасить
      }
    }
    void loop (){
      for (int i=0;i<MAX_LEDS;i++){
        if (millis()>ledtime[i]) {
          if (!bitRead(bitsToSend, i)) { // не горело
            registerWrite(i, HIGH); // зажечь
            ledtime[i]=millis()+5000; //погасить через 5 сек
          } else {
            registerWrite(i, LOW); // погасить
            ledtime[i]=millis()+rand(1,10001); //зажечь через случайное время
          }
        }
      }
    }

    // Этот метот записывает байт в регистр
    void registerWrite(int whichPin, int whichState) {
    //Отключаем вывод на регистре
    digitalWrite(latchPin, LOW);
    // устанавливаем HIGH в соответствующем бите
    bitWrite(bitsToSend, whichPin, whichState);
    // проталкиваем байт в регистр
    shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);
    // "защелкиваем" регистр, чтобы байт появился на его выходах
    digitalWrite(latchPin, HIGH);
    }
     
    Корректность registerWrite не проверял, лишь немного подкорректировал, вынеся байт состояния регистра за пределы функции для сохранения его состояния между вызовами.
    Не проверяется переход значения, возвращаемого millis через 0 (через очень длительное время непрерывной работы)
     
    Последнее редактирование: 7 июн 2014
    AN-Misha нравится это.