Условная конструкция
- Войдите на сайт для отправки комментариев
Чт, 09/07/2020 - 14:15
/*------------------------ Leds used here are WS2812B, 3 leds by segment total = (3*7)* 4numbers + 2 dots = 86 leds Led controlled with FastLeds Lib on Pin 6 Brightness sensor on A3 Temperature sensor on A2 RTC Modul on A4 A5 I'm using 5V 3A Power supply Используются 2 цвета: красный-часы, зеленый-дата, желтый-температура + динамическая яркость светодиодов Buzzer D2 */ #include <DS3232RTC.h> #include <Time.h> #include <Wire.h> #include <FastLED.h> #include <OneWire.h> #include <DS18B20.h> #include "GyverTimer.h" #define NUM_LEDS 86 //3*7*4 +2 Number of LED controles (remember I have 3 leds / controler #define LED_TYPE WS2812B #define BRIGHTNESS_DEFAULT 230 //яркость дисплея по умолчанию #define IMPULSE_TONE 500 // продолжительность звучания\паузы гудка #define LED_PIN 6 //пин подключения светодиодной ленты #define ONE_WIRE_BUS A2 //пин подключения датчика температуры #define BUZZER 2 //пин подключения реле звукового оповещения #define PHOTOCELL A3 //пин подключения фоторезистора char incoming_command = 'H'; int brightness = 0; int auto_brightness = 1; //brightness int photocellReading; // the analog reading from the analog resis int led_on = 1; //LEDS COLORS volatile boolean animate = true; volatile long animation_change_timeout; unsigned long previousMillis1 = 0; // будет хранить последний раз, когда реле был обновлен const long intervalVision = 5000; // интервал отображения Temp and date unsigned long previousMillis2 = 0; // будет хранить последний раз, когда был обновлен счетчик гудка const long intervalSong = 3000; //интервал звучания гудка //ТЕМПЕРАТУРА OneWire oneWire(ONE_WIRE_BUS); DS18B20 sensor(&oneWire); int temperatureOutdoor; // Глобальная переменная для хранения значение температуры с датчика DS18B20 long lastUpdateTime = 0; // Переменная для хранения времени последнего считывания с датчика const int TEMP_UPDATE_TIME = 1000; // Определяем периодичность проверок //ТАЙМЕРЫ GTimer_ms tempTimer(30000); // таймер вывода температуры ( GTimer_ms dateTimer(60000); // таймер вывода даты //ГУДОК int signalRabDay [8] = {830, 1014, 1015, 1230, 1315, 1500, 1515, 1715}; // массив цифр определяющих время сработки //звукового оповещения в рабочие дни int signalHolyDay [8] = {800, 1000, 1015, 1200, 1230, 1500, 1515, 1600}; //время сработки в выходные дни bool relayState = false; //состояние реле подачи звука bool Flag_1; //флаг совпадения элемента массива с тек временем bool Flag_2; //флаг выполнения условия секунды от 0-3 int sec; //глобальная переменная хранения секунд CRGB leds[NUM_LEDS]; // Define LEDs strip // 10 digit :0...10, each digit is composed of 7 segments of 3 leds byte digits[10][21] = { //2-мерный массив цифр on 7 segment // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // Digit 0 { 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 }, // Digit 1 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, // Digit 2 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 }, // Digit 3 { 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1 }, // Digit 4 { 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 }, // Digit 5 { 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // Digit 6 { 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 }, // Digit 7 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, // Digit 8 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 } // Digit 9 }; bool Dot = true; //Dot state int last_digit = 0; long dotsLedColor = CRGB::Red;; // Цвет отображени точек (in hex) long timeLedColor = CRGB::Red; // Цвет отображения времени (in hex) long dateLedColor = CRGB::Green; // Цвет отображения даты (in hex) long tempLedColor = CRGB::Yellow; // Цвет отображения температуры (in hex) void setup() { Serial.begin(9600); Wire.begin(); FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS); FastLED.setBrightness( BRIGHTNESS_DEFAULT ); sensor.begin(); pinMode (BUZZER, OUTPUT); } // Проверьте датчик освещенности и установите яркость соответственно void BrightnessCheck() { const byte brightnessLow = 20; // Low brightness value const byte brightnessHigh = 70; // High brightness value int sensorValue = analogRead(PHOTOCELL); // Read sensor sensorValue = map(sensorValue, 0, 1023, 230, 10); constrain (sensorValue, 230, 10); // Serial.print("Sensor is: ");Serial.println(sensorValue); LEDS.setBrightness(sensorValue); }; // Получение времени в одну цифру int GetTime() { tmElements_t Now; RTC.read(Now); //time_t Now = RTC.Now();// Получение текущего времени и его сохранение в объекте DateTime int hour = Now.Hour; int minutes = Now.Minute; int second = Now.Second; sec = second; //используйте это, чтобы мигать ваши точки каждую секунду if (second % 2 == 0) { Dot = false; } else { Dot = true; }; //легко манипулировать 2250, а не часами = 10 минут = 50 return (hour * 100 + minutes); } //функция вывода дня и месяца int DayMonth() { tmElements_t Now; RTC.read(Now); int day = Now.Day; int month = Now.Month; // int weekday = Now. return (day * 100 + month); } // Конвертировать время в массив, необходимый для отображения void TimeToArray() { int Now = GetTime(); // Получить время // Serial.print ("Time now = "); // Serial.println (Now); int cursor = 86; if (Dot) { leds[42] = dotsLedColor; leds[43] = dotsLedColor; } else { leds[42] = 0x000000; leds[43] = 0x000000; }; for (int i = 1; i <= 4; i++) { int digit = Now % 10; // Получить последнюю цифру времени if (i == 1) { cursor = 65; for (int k = 0; k <= 20; k++) { if (digits[digit][k] == 1) { leds[cursor] = timeLedColor; } else if (digits[digit][k] == 0) { leds[cursor] = 0x000000; }; cursor ++; }; // fin for if (digit != last_digit) { // DateToArray(); // Temp(); // fadefonction(); // ledColor = ColorTable[random(2)]; } last_digit = digit; }// fin if else if (i == 2) { cursor = 44; for (int k = 0; k <= 20; k++) { if (digits[digit][k] == 1) { leds[cursor] = timeLedColor; } else if (digits[digit][k] == 0) { leds[cursor] = 0x000000; }; cursor ++; }; // Serial.println(); } else if (i == 3) { cursor = 21; for (int k = 0; k <= 20; k++) { if (digits[digit][k] == 1) { leds[cursor] = timeLedColor; } else if (digits[digit][k] == 0) { leds[cursor] = 0x000000; }; cursor ++; }; } else if (i == 4) { cursor = 0; for (int k = 0; k <= 20; k++) { if (digits[digit][k] == 1) { leds[cursor] = timeLedColor; } else if (digits[digit][k] == 0) { leds[cursor] = 0x000000; }; cursor ++; }; }; Now /= 10; }; }; // Конвертировать дату в массив, необходимый для отображения void DateToArray() { FastLED.clear(); unsigned long currentMillis = millis(); while (millis() - currentMillis < intervalVision) { FastLED.show(); int Now = DayMonth(); // Get time int cursor = 86; //116 for (int i = 1; i <= 4; i++) { int digit = Now % 10; // получение последней цифры из времени if (i == 1) { cursor = 65; //82 for (int k = 0; k <= 20; k++) { if (digits[digit][k] == 1) { leds[cursor] = dateLedColor; } else if (digits[digit][k] == 0) { leds[cursor] = 0x000000; }; cursor ++; }; // fin for }// fin if else if (i == 2) { cursor = 44; for (int k = 0; k <= 20; k++) { if (digits[digit][k] == 1) { leds[cursor] = dateLedColor; } else if (digits[digit][k] == 0) { leds[cursor] = 0x000000; }; cursor ++; }; } else if (i == 3) { cursor = 21; for (int k = 0; k <= 20; k++) { if (digits[digit][k] == 1) { leds[cursor] = dateLedColor; } else if (digits[digit][k] == 0) { leds[cursor] = 0x000000; }; cursor ++; }; } else if (i == 4) { cursor = 0; for (int k = 0; k <= 20; k++) { if (digits[digit][k] == 1) { leds[cursor] = dateLedColor; } else if (digits[digit][k] == 0) { leds[cursor] = 0x000000; }; cursor ++; }; }; Now /= 10; }; } }; //пока не используется void TimeAdjust() { int buttonH = digitalRead(5); int buttonM = digitalRead(4); if (buttonH == LOW || buttonM == LOW) { delay(500); tmElements_t Now; RTC.read(Now); int hour = Now.Hour; int minutes = Now.Minute; if (buttonH == LOW) { if (Now.Hour == 24) { Now.Hour = 1; } else { Now.Hour += 1; }; } else { if (Now.Minute == 59) { Now.Minute = 0; } else { Now.Minute += 1; }; }; RTC.write(Now); } } /******IR check**** Проверьте команду на последовательном порту, отправленную другой Arduino в зависимости от нажатой кнопки */ void IR_Check() { if (Serial.available() > 0) { // read the incoming byte: incoming_command = Serial.read(); unsigned long startTime = 0; switch (incoming_command) { //colors case 'R' : //Serial.println("RED"); timeLedColor = CRGB::Red; break; case 'B' : timeLedColor = CRGB::Blue; break; case 'G' : timeLedColor = CRGB::Green; break; case 'W' : timeLedColor = CRGB::White; break; case 'I' : timeLedColor = CRGB::OrangeRed; break; case 'J' : timeLedColor = CRGB::GreenYellow; break; case 'K' : timeLedColor = CRGB::MediumSlateBlue; break; case 'L' : timeLedColor = CRGB::Pink; break; case 'M' : timeLedColor = CRGB::DarkOrange; break; case 'N' : timeLedColor = CRGB::Aqua; break; case 'P' : timeLedColor = CRGB::DarkSlateBlue; break; case 'Q' : timeLedColor = CRGB::LightPink; break; case 'S' : timeLedColor = CRGB::LightSalmon; break; case 'U' : timeLedColor = CRGB::LightSeaGreen; break; case 'V' : timeLedColor = CRGB::Purple; break; case 'X' : timeLedColor = CRGB::Yellow; break; case 'Y' : timeLedColor = CRGB::Teal; break; case 'Z' : timeLedColor = CRGB::PaleVioletRed; break; case '*' : timeLedColor = CRGB::PaleTurquoise; break; case 'F' : //pick a random color but not working yet timeLedColor = CRGB( random8(), 100, 50); break; case '+' : //brighter brightness += 10; if (brightness > 255) brightness = 255; FastLED.setBrightness( brightness ); auto_brightness = 0; break; case '-' : brightness -= 10; if (brightness < 10) brightness = 10; FastLED.setBrightness( brightness ); auto_brightness = 0; break; case 'O' : //auto brightness if (led_on) { brightness = 0; led_on = 0; } else { brightness = BRIGHTNESS_DEFAULT ; led_on = 1; } FastLED.setBrightness( brightness ); break; case 'T' : //Temp TempOutdoor(); break; case 'a' : //Date DateToArray(); break; case 'A' : auto_brightness = 1; break; default: break; //Serial.println("error"); }//switch // say what you got: //Serial.print("I received: "); //Serial.println(incoming_command); } }; //вывод внутренней температуры /* void TempIndoor() { FastLED.clear(); int cursor = 21; //65 float t = RTC.temperature(); int celsius = t / 4.0; Serial.print(celsius); unsigned long currentMillis = millis(); while (millis() - currentMillis < interval) { FastLED.show(); int cursor = 21; //65 float t = RTC.temperature(); int celsius = t / 4.0; for (int i = 1; i <= 2; i++) { int digit = celsius % 10; // get last digit in time Serial.print("digit"); Serial.println(digit); if (i == 1) { for (int k = 0; k <= 20; k++) { if (digits[digit][k] == 1) { leds[cursor] = tempLedColor; } else if (digits[digit][k] == 0) { leds[cursor] = 0x000000; }; cursor ++; }; // fin for FastLED.show(); }// fin if else if (i == 2) { cursor = 0; for (int k = 0; k <= 20; k++) { if (digits[digit][k] == 1) { leds[cursor] = tempLedColor; } else if (digits[digit][k] == 0) { leds[cursor] = 0x000000; }; cursor ++; }; } celsius /= 10; FastLED.show(); } for (int m = 44; m < 56; m++) { leds[m] = tempLedColor; } for (int m = 72; m < 83; m++) { leds[m] = tempLedColor; } FastLED.show(); //check_for_input(); }//fin while animate }; */ //Температура на улице void TempOutdoor() { FastLED.clear(); int cursor = 21; //65 if (millis() - lastUpdateTime > TEMP_UPDATE_TIME) { sensor.requestTemperatures(); temperatureOutdoor = sensor.getTempC(); Serial.print("Temp: "); Serial.println(temperatureOutdoor); // Выводим полученное значение температуры // Т.к. переменная temperature имеет тип int, дробная часть будет просто отбрасываться } unsigned long currentMillis = millis(); while (millis() - currentMillis < intervalVision) { FastLED.show(); int cursor = 21; //65 // float t = RTC.temperature(); int celsius = temperatureOutdoor; for (int i = 1; i <= 2; i++) { int digit = celsius % 10; // get last digit in time if (i == 1) { for (int k = 0; k <= 20; k++) { if (digits[digit][k] == 1) { leds[cursor] = tempLedColor; } else if (digits[digit][k] == 0) { leds[cursor] = 0x000000; }; cursor ++; }; // fin for FastLED.show(); }// fin if else if (i == 2) { cursor = 0; for (int k = 0; k <= 20; k++) { if (digits[digit][k] == 1) { leds[cursor] = tempLedColor; } else if (digits[digit][k] == 0) { leds[cursor] = 0x000000; }; cursor ++; }; } celsius /= 10; FastLED.show(); } for (int m = 44; m < 56; m++) { leds[m] = tempLedColor; } for (int m = 72; m < 83; m++) { leds[m] = tempLedColor; } FastLED.show(); //check_for_input(); }//fin while animate } //пока не используется void check_for_input() { if (animation_change_timeout > 100) { if (Serial.available() > 0) { // read the incoming byte: incoming_command = Serial.read(); // say what you got: Serial.print("I received: "); Serial.println(incoming_command); animate = false; } } } void BuzzerSound() { int Now = GetTime(); // Получить время // Serial.println (sec); for (int p = 0; p <= 7; p++) { // перебор массива данных времени int value = signalRabDay [p]; // Serial.print ("value= "); // Serial.println (value); // Serial.print ("Now= "); // Serial.println (Now); // if ( value == Now ) { unsigned long currentMillis = millis(); while (millis() - currentMillis < intervalSong) { Flag_1 = true; //если есть совпадение по массиву поднимаем флаг на период intervalSong } } } // Serial.print ("Flag_1 "); // Serial.println (Flag_1); if (sec <= 3) Flag_2 = true; //поднимаем флаг_2 на 3 секунды в начале каждой минуты, тем самым задаем продолжительность звучания сигнала else if (sec > 3) { Flag_1 = false; Flag_2 = false; } // Serial.print ("Flag_2 "); // Serial.println (Flag_2); unsigned long currentMillis = millis(); if (currentMillis - previousMillis1 > IMPULSE_TONE) { previousMillis1 = currentMillis ; if (relayState == LOW) relayState = HIGH; else relayState = LOW; } if (Flag_1 && Flag_2) digitalWrite (BUZZER, relayState); //включаем пин реле если Флаг_1 и Флаг_2 = тру else if ( !Flag_1 || !Flag_2 ) { digitalWrite (BUZZER, LOW); //выключаем если хотя один из флагов опущен relayState = LOW; } } void loop() { BrightnessCheck(); // Check brightness TimeToArray(); // Получить массив светодиодов с необходимой конфигурацией if (tempTimer.isReady()) TempOutdoor(); if (dateTimer.isReady()) DateToArray(); BuzzerSound(); IR_Check(); FastLED.show(); // Показать массив светодиодов }
Здравствуйте! Прошу помощи добрые люди. Имеем часы на адресной светодиодной ленте с выводом даты и температурой на улице. Необходимо прикрутить оповещатель срабатывающий в определенное время заданное массивом signalRabDay. И тут вот никак не могу сообразить каким образом при условии сработки одного из элементов массива в течении 3 секунд должна подача высокого уровня на пин реле D2, при этом чтобы сигнал звучал прерывисто с частотой 2 Герц. Моя интерпретация алгоритма в скетче заключена в функции BuzzerSound(). Строки с 635 по 674. Иногда срабатывает как нужно, иногда нет. Знаю что налепил ерунды и это можно переделать в несколько строчек. ноне знаю как. Подскажите пожалуйста.
del
И тут вот никак не могу сообразить каким образом при условии сработки одного из элементов массива в течении 3 секунд должна подача высокого уровня на пин реле D2, при этом чтобы сигнал звучал прерывисто с частотой 2 Герц.
Код длинный, скобки не выравнены - разбираться трудно.
Но почему в 647 - 649 строке вы крутитесь в цикле 3 секунды ничего не делая кроме установки флага? Фактически вы просто пропускаете 3 секунды и устанавливаете флаг.
while (millis() - currentMillis < intervalSong) {
Flag_1 = true; //если есть совпадение по массиву поднимаем флаг на период intervalSong
}
О, очередная реинкарнация бессмертного кода вот из этой ветки:
http://arduino.ru/forum/programmirovanie/bolshie-nastennye-chasy-na-arduino
Марат, покопайтесь там, в ветке 14 страниц и как минимум десяток примеров работающего кода на той же основе, что у вас. Может что-то подберете для себя. Если хотите, я могу переделать часы под ваши желания. но только на платной основе. бесплатно переписывать этот код мне уже надоело, каждый новый новичок вновь приходит с исходной кривой версией. в которую еще и насажал своих ошибок.