Приветствую. Имеется 8 светодиодов, подключенных через сдвиговый регистр 74HC595 по схеме. Имеется код, который по очереди зажигает эти светодиоды. Вопрос: как его изменить, чтобы светодиоды зажигались рандомно на какое-то время, а затем гасли. Код: //Пин подключен к 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); }
Приведенный ранее код включает светодиоды не по очереди, а по данным, передаваемым по последовательному порту. Для инициализации ГСЧ 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 (через очень длительное время непрерывной работы)