Условная конструкция
- Войдите на сайт для отправки комментариев
Чт, 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 страниц и как минимум десяток примеров работающего кода на той же основе, что у вас. Может что-то подберете для себя. Если хотите, я могу переделать часы под ваши желания. но только на платной основе. бесплатно переписывать этот код мне уже надоело, каждый новый новичок вновь приходит с исходной кривой версией. в которую еще и насажал своих ошибок.