String stringOne = rtc.getTimeStr();
int long h = t.hour;
int long m = t.min;
int long s = t.sec;
time_all = RTC.dec2bcd(h) * 3600 + RTC.dec2bcd(m) * 60 + RTC.dec2bcd(s );
У меня мой вариант работает (может он и корявый, но работает).
А на dec2bcd компилятор ругался матом.
Раз Вы так неплохо в коде разбираетесь, моежет не сочтете за наглость просьбу с прерыванием подсказать?
По задумке:
Раз в сутки, условии несработки опр датчиков (это я и сам могу дописать), открываем waterclup, отсчитываем N импульсов, закрываем waterclup. Но держим его открытым не более 150 сек.
Если поможете наброском кода, сразу прошу раскоментировать его.
Заранее спасибо.
Я может и не прав ввиду слабой комреценции, но мне мой вариант больше понравился простотой, к тому же он работает. ПЛК у Вас очень интересный, но крышка аквариума уже собрана именно в этом составе железа и развивать я хочу свою версию. А вообще Ваш ПЛК хороший вариант для другой моей задумки. Есть ли у Вас чтото типа комерческой версии?
Возвращаясь к своим попугаям, повторюсь но очень хотелось - бы поштурмовать мозгом наброски скетча под вышеописанную задачу.
Доки библиотеки тут не при чем.
В "даем ШИМ" надо дать значение от "0" до "4095", ну или переменную с этим значением.
А переменная на все каналы у меня одна "powerValue". Над этим и ломаю голову.
struct Day { // В этой структуре храниться информация о сутках
long sunRiseStart; // Начало рассвета в секундах от начала суток
long sunRiseFinish; // Конец рассвета
long sunSetStart; // Начало заката
long sunSetFinish; // Конец заката
int power; // Полная мощность излучения днем
int currentPower; // Текущая мощность
bool inversion; // инверсия Это я не знаю для чего нужно. Было в другой теме
} Day;
В цикле после вычисления powerValue
if (powerValue != array[i].currentPower) {
ledDriver2.writeLED(i, 4095, powerValue);
array[i].currentPower = powerValue
}
digitalRead (pin 20 ==LOW) приравнять к "время 16:00" - если на датчике "критически низкий уровень воды в САМПе" нет воды, значит (проверив остальные условия) открыть клапан независимо от времени.
САМП - тип фильтра, по сути еще один маленький аквариум, разделенный на несколько фильтрующих секций (в моем случае в тумбе под аквариумом) в первый отсек САМПа вода сливается с аквариума самотеком, а из последнего помпа поднимает обратно в аквариум.
В начале мой САМП выглядел так:Сейчас многое изменилось.
digitalRead (pin 20 ==LOW) приравнять к "время 16:00" - если на датчике "критически низкий уровень воды в САМПе" нет воды, значит (проверив остальные условия) открыть клапан независимо от времени.
То есть сменю int na long int powerValue и все должно заработать?
Я про int читал, про long читал.
А какие свойства у long int так и не понял, не подскажете?
У вас счетчик контактный или оптический? Лучше создать функцию опроса с миллис и сделать ее вызов вместо 15 строки. Как быстро крутит счетчик, будет ли успевать срабатывать антидребезг?
Можно поставить аппаратный в виде конденсатора. Номинал правда не подскажу.
Победило проблему.
Нет не победило
Вот код из библиотели 1307
// Convert Decimal to Binary Coded Decimal (BCD) uint8_t DS1307RTC::dec2bcd(uint8_t num) { return ((num/10 * 16) + (num % 10)); } // Convert Binary Coded Decimal (BCD) to Decimal uint8_t DS1307RTC::bcd2dec(uint8_t num) { return ((num/16 * 10) + (num % 16)); }Наверное нужно так
Я с этой библиотекой не работал. Читайте доки.
String stringOne = rtc.getTimeStr(); int long h = t.hour; int long m = t.min; int long s = t.sec; time_all = RTC.dec2bcd(h) * 3600 + RTC.dec2bcd(m) * 60 + RTC.dec2bcd(s );Для sinnpriest
Вот как нужно в вашем коде делать.
У меня мой вариант работает (может он и корявый, но работает).
А на dec2bcd компилятор ругался матом.
Раз Вы так неплохо в коде разбираетесь, моежет не сочтете за наглость просьбу с прерыванием подсказать?
По задумке:
Раз в сутки, условии несработки опр датчиков (это я и сам могу дописать), открываем waterclup, отсчитываем N импульсов, закрываем waterclup. Но держим его открытым не более 150 сек.
Если поможете наброском кода, сразу прошу раскоментировать его.
Заранее спасибо.
Я же привел код функции в сообщении. В крайнем случае можно было скопировать его в скетч и все бы скомпилировалось.
По поводу помочь...
Я обычно такие вещи пишу конечным автоматом, а для этого нужно досконально знать процесс.
Мы будем дольше переписываться, чем я скетч писать.
Если это не срочно, то можно попробовать.
У меня просто есть сейчас сбободное время, поэтому на форуме и треплюсь. А как долго у меня оно будет я сказать не могу.
А вообще эту работу можно сделать моим ПЛК V 2.0
http://robocraft.ru/blog/3126.html
По ссылке первая версия, но на гугл диске лежит вторая. Там еще описание не полностью сделано.
При определенной доделке второй версии я могу и освещение с шимом сделать по расписанию.
Можно и аквариумный веб интерфейс нарисовать.
Если дальше есть желание общаться то пишите моеимя кот майл ру
Я может и не прав ввиду слабой комреценции, но мне мой вариант больше понравился простотой, к тому же он работает. ПЛК у Вас очень интересный, но крышка аквариума уже собрана именно в этом составе железа и развивать я хочу свою версию. А вообще Ваш ПЛК хороший вариант для другой моей задумки. Есть ли у Вас чтото типа комерческой версии?
Возвращаясь к своим попугаям, повторюсь но очень хотелось - бы поштурмовать мозгом наброски скетча под вышеописанную задачу.
По-поводу коммерческой версии я пока не думал.
Опишите подробно задачу по мылу. Попробую помочь карасям.
тема переименовывается в
Таймер и ШИМ - братья навек!
Долго я расписывал этот код под 21 канал ШИМ, пока не уперся в тот факт, что имею всего одну PowerValue. Как - же ее распихать по 21 каналу?
Создать массив.
Я не понял че там расписывать
Ставим #define ARRAY_LENGTH 21
вместо #define ARRAY_LENGTH 6
и все...
Так powerValue вычисляется в цикле для каждого шима.
Вычислили powerValue установили шим
ШИМ.Set(powerValue);
Перешли к следующему вычислению в цикле
Так именно " #define ARRAY_LENGTH 21" я и поставил.
Но powerValue то одна, и все каналы работают как один. Как сделать чтото типа ШИМ.Set(powerValue[1]);
ШИМ.Set(i, powerValue[1]);
Я же не знаю как у вас шим устанавливается.
Вставляю я шим в " ledDriver2.writeLED(0, 4095, ШИМ );
Если 0 это канал, то так
ledDriver2.writeLED(i, 4095, ШИМ );
ledDriver2.writeLED(канал pca9685, из возможных 4095, даем ШИМ );
Вот в "даем ШИМ" надо чтото задать.
Я с этой библиотеккой не работал, читайте доки. Мне лень читать.
Доки библиотеки тут не при чем.
В "даем ШИМ" надо дать значение от "0" до "4095", ну или переменную с этим значением.
А переменная на все каналы у меня одна "powerValue". Над этим и ломаю голову.
powerValue вычисляется в ЦИКЛЕ!!!!
Я не зная как еще понятнее объяснить
Про в "ЦИКЛЕ" похоже догнал.
Но чтото как то не работает.
Где искать ошибку?
#include <Wire.h> // Библиотека I2C #include <PCA9685.h> // Бибилиотека регистров #include <Time.h> // Библиотека часов #include <DS1307RTC.h> // Библиотека часов #include <OneWire.h> // Библиотека шины 1wire #include <DallasTemperature.h> // Библиотека термометров #define ONE_WIRE_BUS 19 // вход датчиков 18b20 (в меге будет 19) #define SQW 18 // SQW ds1307 на всякий случай OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); DeviceAddress sensor1 = {0x28, 0x0, 0xFB, 0x5F, 0x6, 0x0, 0x0, 0x5B}; // Заранее известный адрес датчика 1 DeviceAddress sensor2 = {0x28, 0xE70, 0x66, 0x60, 0x6, 0x0, 0x0, 0x4A}; // Заранее известный адрес датчика 2 #define MoonPin A0 // Фоторезистор подключен 0-му аналоговому входу #define WaterBank 22 // датчик перебора воды в аквариуме #define WaterSumpInHi 24 // датчик перебора воды во входной секции сампа #define WaterSumpOutHi 26 // датчик перебора воды в основной секции сампа #define WaterSumpOutNorm 28 // датчик нормального уровня воды в основной секции сампа #define WaterSumpOutLow 30 // датчик критически низкого уровня воды в сампе #define WaterInSump 2 // счетчик воды, подаваемой из водопровода #define WaterPres 32 // Датчик давления воды в водопроводе #define WATERPUMP 34 // Реле включения помпы, подающей из сампа в аквариум #define WaterClap 36 // Реле клапана, подачи воды из водопровода в самп int cool1; // переменная оборотов вентилятора 1 int cool2; // переменная оборотов вентилятора 2 int powerValue; PCA9685 ledDriver1; // шильд ШИМ 1 PCA9685 ledDriver2; // шильд ШИМ 2 struct Day { // В этой структуре храниться информация о сутках long sunRiseStart; // Начало рассвета в секундах от начала суток long sunRiseFinish; // Конец рассвета long sunSetStart; // Начало заката long sunSetFinish; // Конец заката int power; // Полная мощность излучения днем bool inversion; // инверсия Это я не знаю для чего нужно. Было в другой теме } Day; int led; #define ARRAY_LENGTH 21 // Количество каналов ШИМ #define MIN_POWER 20 // Минимальная мощность для всех каналов struct Day array[ARRAY_LENGTH]; // Массив структур для управления каналами long seconds; void setup() { Serial.begin(9600); // Старт сериала (для отладки) Serial.println("start"); Wire.begin(); // Старт I2C sensors.begin(); sensors.setResolution(sensor1, 10); // температура радиаторов света sensors.setResolution(sensor2, 10); // температура радиаторов света ledDriver1.begin(B000000); // адрес шильда ШИМ 1 (перемычек нет) ledDriver1.init(); ledDriver2.begin(B000001); // адрес шильда ШИМ 2 (перемычка 1) ledDriver2.init(); pinMode(WaterBank, INPUT); pinMode(WaterSumpInHi, INPUT); pinMode(WaterSumpOutHi, INPUT); pinMode(WaterSumpOutNorm, INPUT); pinMode(WaterSumpOutLow, INPUT); pinMode(WaterPres, INPUT); pinMode(WATERPUMP, OUTPUT); pinMode(WaterClap, OUTPUT); array[0].sunRiseStart = 480 * 60; // Белый 1 старт рассвета 8:00 array[0].sunRiseFinish = 490 * 60; // финиш рассвета 8:10 array[0].sunSetStart = 1230 * 60; // старт заката 20:30 array[0].sunSetFinish = 1240 * 60; // финиш заката 20:40 array[0].power = 2047; array[0].inversion = 0; // логика прямая array[1].sunRiseStart = 485 * 60; // Белый 2 старт рассвета 8:05 array[1].sunRiseFinish = 495 * 60; // финиш рассвета 8:15 array[1].sunSetStart = 1235 * 60; // старт заката 20:35 array[1].sunSetFinish = 1245 * 60; // финиш заката 20:45 array[1].power = 2047; // яркость 50% array[1].inversion = 0; // логика прямая array[2].sunRiseStart = 490 * 60; // Белый 3 старт рассвета 8:10 array[2].sunRiseFinish = 500 * 60; // финиш рассвета 8:20 array[2].sunSetStart = 1240 * 60; // старт заката 20:40 array[2].sunSetFinish = 1250 * 60; // финиш заката 20:50 array[2].power = 2047; // яркость 50% array[2].inversion = 0; // логика прямая array[3].sunRiseStart = 495 * 60; // Белый 4 старт рассвета 8:15 array[3].sunRiseFinish = 515 * 60; // финиш рассвета 8:35 array[3].sunSetStart = 1245 * 60; // старт заката 20:45 array[3].sunSetFinish = 1265 * 60; // финиш заката 21:05 array[3].power = 2047; // яркость 50% array[3].inversion = 0; // логика прямая array[4].sunRiseStart = 510 * 60; // Белый 5 старт рассвета 8:30 array[4].sunRiseFinish = 520 * 60; // финиш рассвета 8:40 array[4].sunSetStart = 1260 * 60; // старт заката 21:00 array[4].sunSetFinish = 1270 * 60; // финиш заката 21:10 array[4].power = 2047; // яркость 50% array[4].inversion = 0; // логика прямая array[5].sunRiseStart = 515 * 60; // Белый 6 старт рассвета 8:35 array[5].sunRiseFinish = 525 * 60; // финиш рассвета 8:45 array[5].sunSetStart = 1265 * 60; // старт заката 21:05 array[5].sunSetFinish = 1275 * 60; // финиш заката 21:15 array[5].power = 2047; // яркость 50% array[5].inversion = 0; // логика прямая array[6].sunRiseStart = 520 * 60; // Белый7 старт рассвета 8:40 array[6].sunRiseFinish = 530 * 60; // финиш рассвета 8:50 array[6].sunSetStart = 1270 * 60; // старт заката 21:10 array[6].sunSetFinish = 1280 * 60; // финиш заката 21:20 array[6].power = 2047; // яркость 50% array[6].inversion = 0; // логика прямая array[7].sunRiseStart = 500 * 60; // Белый центр старт рассвета 8:20 array[7].sunRiseFinish = 510 * 60; // финиш рассвета 8:30 array[7].sunSetStart = 1250 * 60; // старт заката 20:50 array[7].sunSetFinish = 1260 * 60; // финиш заката 21:10 array[7].power = 2047; // яркость 50% array[7].inversion = 0; // логика прямая array[8].sunRiseStart = 480 * 60; // Красный 1 array[8].sunRiseFinish = 490 * 60; array[8].sunSetStart = 820 * 60; array[8].sunSetFinish = 880 * 60; array[8].power = 1023; array[8].inversion = 0; array[9].sunRiseStart = 480 * 60; // Красный 2 array[9].sunRiseFinish = 490 * 60; array[9].sunSetStart = 820 * 60; array[9].sunSetFinish = 880 * 60; array[9].power = 1023; array[9].inversion = 0; array[10].sunRiseStart = 480 * 60; // Красный 3 array[10].sunRiseFinish = 490 * 60; array[10].sunSetStart = 820 * 60; array[10].sunSetFinish = 880 * 60; array[10].power = 1023; array[10].inversion = 0; array[11].sunRiseStart = 480 * 60; // Красный 4 array[11].sunRiseFinish = 490 * 60; array[11].sunSetStart = 820 * 60; array[11].sunSetFinish = 880 * 60; array[11].power = 1023; array[11].inversion = 0; array[12].sunRiseStart = 480 * 60; // Зеленый 1 array[12].sunRiseFinish = 490 * 60; array[12].sunSetStart = 820 * 60; array[12].sunSetFinish = 880 * 60; array[12].power = 1023; array[12].inversion = 0; array[13].sunRiseStart = 480 * 60; // Зеленый 2 array[13].sunRiseFinish = 490 * 60; array[13].sunSetStart = 820 * 60; array[13].sunSetFinish = 880 * 60; array[13].power = 1023; array[13].inversion = 0; array[14].sunRiseStart = 480 * 60; // Зеленый 3 array[14].sunRiseFinish = 490 * 60; array[14].sunSetStart = 820 * 60; array[14].sunSetFinish = 880 * 60; array[14].power = 1023; array[14].inversion = 0; array[15].sunRiseStart = 480 * 60; // Зеленый 4 array[15].sunRiseFinish = 490 * 60; array[15].sunSetStart = 820 * 60; array[15].sunSetFinish = 880 * 60; array[15].power = 1023; array[15].inversion = 0; array[16].sunRiseStart = 480 * 60; // Синий 1 array[16].sunRiseFinish = 490 * 60; array[16].sunSetStart = 820 * 60; array[16].sunSetFinish = 880 * 60; array[16].power = 1023; array[16].inversion = 0; array[17].sunRiseStart = 480 * 60; // Синий 2 array[17].sunRiseFinish = 490 * 60; array[17].sunSetStart = 820 * 60; array[17].sunSetFinish = 880 * 60; array[17].power = 1023; array[17].inversion = 0; array[18].sunRiseStart = 480 * 60; // Синий 3 array[18].sunRiseFinish = 490 * 60; array[18].sunSetStart = 820 * 60; array[18].sunSetFinish = 880 * 60; array[18].power = 1023; array[18].inversion = 0; array[19].sunRiseStart = 480 * 60; // Синий 4 array[19].sunRiseFinish = 490 * 60; array[19].sunSetStart = 820 * 60; array[19].sunSetFinish = 880 * 60; array[19].power = 1023; array[9].inversion = 0; array[20].sunRiseStart = 480 * 60; // Ультрафиолет array[20].sunRiseFinish = 490 * 60; array[20].sunSetStart = 820 * 60; array[20].sunSetFinish = 880 * 60; array[20].power = 1023; array[20].inversion = 0; } void printTemperature(DeviceAddress deviceAddress) { float tempC = sensors.getTempC(deviceAddress); Serial.println(tempC); } void loop() { tmElements_t tm; RTC.read(tm); // Получаем текущее время long min0 = tm.Hour * 60; long min1 = tm.Minute; seconds = (min0 + min1)*60 + tm.Second; // Вычисляем количество секунд с начала суток int Moon = analogRead(MoonPin); // считываем значение с фоторезистора Serial.print("Svet "); Serial.println(Moon); Serial.print("Time "); Serial.print(tm.Hour); Serial.write(':'); Serial.print(tm.Minute); Serial.write(':'); Serial.print(tm.Second); Serial.println(); sensors.requestTemperatures(); Serial.print("Temperatura1 "); printTemperature(sensor1); Serial.print("Temperatura2 "); printTemperature(sensor2); cool1 = (sensors.getTempC(sensor1) - 25.00) * 10; // расчитываем ШИМ для вентилятора 1 if (cool1 <= 20) cool1 = 0; else if (cool1 >= 100) cool1 = 100; cool2 = (sensors.getTempC(sensor2) - 25.00) * 10; // расчитываем ШИМ для вентилятора 2 if (cool2 <= 20) cool2 = 0; else if (cool2 >= 100) cool2 = 100; Serial.print ("Coolers "); Serial.print(cool1 ); Serial.print (","); Serial.println(cool2); Serial.print("seconds "); Serial.println(seconds); if(digitalRead(WaterSumpOutLow)== LOW) digitalWrite(WATERPUMP, LOW); else if((digitalRead(WaterSumpOutLow)== HIGH)&&(digitalRead(WaterSumpOutNorm)== HIGH)) digitalWrite(WATERPUMP, HIGH); ledDriver2.setLEDDimmed(9, cool1); //(вторая плата PCA9685 канал 9) вентилятор 1 ledDriver2.setLEDDimmed(10, cool2); //(вторая плата PCA9685 канал 9) вентилятор 2 for (byte i = 0; i < ARRAY_LENGTH; i++){ if (seconds < array[i].sunRiseStart || seconds > array[i].sunSetFinish ) { powerValue = MIN_POWER; } else if (seconds > array[i].sunRiseFinish && seconds < array[i].sunSetStart) { powerValue = array[i].power; } else if (seconds > array[i].sunRiseStart && seconds < array[i].sunRiseFinish) { // set proportional sun rise long int powerValue = (seconds - array[i].sunRiseStart) * 1024 / (array[i].sunRiseFinish - array[i].sunRiseStart ) * (array[i].power - MIN_POWER); powerValue = powerValue / 1024 + MIN_POWER; } else if (seconds > array[i].sunSetStart && seconds < array[i].sunSetFinish) { // set proportional sun set long int powerValue = (seconds - array[i].sunSetStart) * 1024 / (array[i].sunSetFinish - array[i].sunSetStart) * (array[i].power - MIN_POWER); powerValue = array[i].power - powerValue / 1024; } // if(led != powerValue) ledDriver2.writeLED(0, 4095, powerValue); //белый, центр // led = powerValue; Serial.println(led); // if(led != powerValue) ledDriver2.writeLED(1, 4095, powerValue); //белый 1 // led = powerValue; // if(led != powerValue) ledDriver2.writeLED(2, 4095, powerValue); //белый 2 // led = powerValue; // if(led != powerValue) ledDriver2.writeLED(3, 4095, powerValue); //белый 3 // led = powerValue; // if(led != powerValue) ledDriver2.writeLED(4, 4095, powerValue); //белый 3 // led = powerValue; // if(led != powerValue) ledDriver2.writeLED(5, 4095, array[4].power ); //белый 5 // led = powerValue; // if(led != powerValue) ledDriver2.writeLED(6, 4095, powerValue); //белый 6 // led = powerValue; // if(led != powerValue) ledDriver2.writeLED(7, 4095, powerValue); //белый 7 // led = powerValue; } Serial.println(); Serial.println("."); delay(1000); } /* { // ledDriver2.setLEDDimmed(8,1023); // ультрафиолет //ledDriver2.setLEDDimmed(11,1023); // не используется //delay(50); //ledDriver2.setLEDDimmed(12,1023); // не используется //delay(50); //ledDriver2.setLEDDimmed(13,1023); // не используется //delay(50); //ledDriver2.setLEDDimmed(14,1023); // не используется //delay(50); //ledDriver2.setLEDDimmed(15,1023); // не используется //delay(100); ledDriver1.writeLED(0, 1023, 10); // синий 1 delay(50); ledDriver1.writeLED(1, 1023, 1018); // зеленый 1 delay(50); ledDriver1.writeLED(2, 1023, 1022); // красный 1 delay(50); ledDriver1.writeLED(3, 1023, 1018); // синий 2 delay(50); ledDriver1.writeLED(4, 1023, 1018); // зеленый 2 delay(50); ledDriver1.writeLED(5, 1023, 1022); // красный 2 delay(50); ledDriver1.writeLED(6, 1023, 1018); // синий 3 delay(50); ledDriver1.writeLED(7, 1023, 1018); // зеленый 3 delay(50); ledDriver1.writeLED(8, 1023, 1022); // красный 3 delay(50); ledDriver1.writeLED(9, 1023, 1018); // синий 4 delay(50); ledDriver1.writeLED(10, 1023, 1018); // зеленый 4 - delay(50); ledDriver1.writeLED(11, 1023, 1022); // красный 4 //delay(500); //ledDriver1.setLEDDimmed(12,1023); //delay(50); //ledDriver1.setLEDDimmed(13,1023); //delay(50); //ledDriver1.setLEDDimmed(14,1023); //delay(50); //ledDriver1.setLEDDimmed(15,1023); //delay(100); } else { ledDriver2.writeLED(0, 1023, 10); //белый, центр delay(50); ledDriver2.setLEDDimmed(1, 1023); //белый 1 - delay(50); ledDriver2.setLEDDimmed(2, 1023); //белый 2 delay(50); ledDriver2.setLEDDimmed(3, 1023); //белый 3 - delay(50); ledDriver2.setLEDDimmed(4, 1023); //белый 4 delay(50); ledDriver2.setLEDDimmed(5, 1023); //белый 5 delay(50); ledDriver2.setLEDDimmed(6, 1023); //белый 6 delay(50); ledDriver2.setLEDDimmed(7, 1023); //белый 7 delay(50); // ledDriver2.setLEDDimmed(8,1023); // не используется //delay(50); //ledDriver2.setLEDDimmed(9,1023); // не используется //delay(50); //ledDriver2.setLEDDimmed(10,1023); // не используется //delay(50); //ledDriver2.setLEDDimmed(11,1023); // не используется //delay(50); //ledDriver2.setLEDDimmed(12,1023); // не используется //delay(50); //ledDriver2.setLEDDimmed(13,1023); // не используется //delay(50); //ledDriver2.setLEDDimmed(14,1023); // не используется //delay(50); //ledDriver2.setLEDDimmed(15,1023); // не используется //delay(100); ledDriver1.writeLED(0, 1023, 10); // синий 1 delay(50); ledDriver1.writeLED(1, 1023, 1018); // зеленый 1 delay(50); ledDriver1.writeLED(2, 1023, 1022); // красный 1 delay(50); ledDriver1.writeLED(3, 1023, 1018); // синий 2 delay(50); ledDriver1.writeLED(4, 1023, 1018); // зеленый 2 delay(50); ledDriver1.writeLED(5, 1023, 1022); // красный 2 delay(50); ledDriver1.writeLED(6, 1023, 1018); // синий 3 delay(50); ledDriver1.writeLED(7, 1023, 1018); // зеленый 3 delay(50); ledDriver1.writeLED(8, 1023, 1022); // красный 3 delay(50); ledDriver1.writeLED(9, 1023, 1018); // синий 4 delay(50); ledDriver1.writeLED(10, 1023, 1018); // зеленый 4 - delay(50); ledDriver1.writeLED(11, 1023, 1022); // красный 4 delay(50); ledDriver1.writeLED(12, 1023, 1022); // ультрафиолет //delay(50); //ledDriver1.setLEDDimmed(13,1023); //delay(50); //ledDriver1.setLEDDimmed(14,1023); //delay(50); //ledDriver1.setLEDDimmed(15,1023); //delay(100); } } }*/for (byte i = 0; i < ARRAY_LENGTH; i++){ if (seconds < array[i].sunRiseStart || seconds > array[i].sunSetFinish ) { powerValue = MIN_POWER; } else if (seconds > array[i].sunRiseFinish && seconds < array[i].sunSetStart) { powerValue = array[i].power; } else if (seconds > array[i].sunRiseStart && seconds < array[i].sunRiseFinish) { // set proportional sun rise long int powerValue = (seconds - array[i].sunRiseStart) * 1024 / (array[i].sunRiseFinish - array[i].sunRiseStart ) * (array[i].power - MIN_POWER); powerValue = powerValue / 1024 + MIN_POWER; } else if (seconds > array[i].sunSetStart && seconds < array[i].sunSetFinish) { // set proportional sun set long int powerValue = (seconds - array[i].sunSetStart) * 1024 / (array[i].sunSetFinish - array[i].sunSetStart) * (array[i].power - MIN_POWER); powerValue = array[i].power - powerValue / 1024; } ledDriver2.writeLED(i, 4095, powerValue); // НЕ 0 А ПЕРЕМЕННАЯ i //ledDriver2.writeLED(0, 4095, powerValue); }Я же в 64 и 66 написал i !!!!!!!!!!!!!
... и тут я догнал как я туплю!!!!
Огромное спасибо за терпение и дельные советы.
Еще раз повторяю.
Вы неправильно seconds вычисляете.
И зря игнорируете мое 41 сообщение.
#include <Wire.h> // Библиотека I2C #include <PCA9685.h> // Бибилиотека регистров #include <Time.h> // Библиотека часов #include <DS1307RTC.h> // Библиотека часов #include <OneWire.h> // Библиотека шины 1wire #include <DallasTemperature.h> // Библиотека термометров #define ONE_WIRE_BUS 19 // вход датчиков 18b20 (в меге будет 19) #define SQW 18 // SQW ds1307 на всякий случай OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); DeviceAddress sensor1 = {0x28, 0x0, 0xFB, 0x5F, 0x6, 0x0, 0x0, 0x5B}; // Заранее известный адрес датчика 1 DeviceAddress sensor2 = {0x28, 0xE70, 0x66, 0x60, 0x6, 0x0, 0x0, 0x4A}; // Заранее известный адрес датчика 2 #define MoonPin A0 // Фоторезистор подключен 0-му аналоговому входу #define WaterBank 22 // датчик перебора воды в аквариуме #define WaterSumpInHi 24 // датчик перебора воды во входной секции сампа #define WaterSumpOutHi 26 // датчик перебора воды в основной секции сампа #define WaterSumpOutNorm 28 // датчик нормального уровня воды в основной секции сампа #define WaterSumpOutLow 30 // датчик критически низкого уровня воды в сампе #define WaterInSump 2 // счетчик воды, подаваемой из водопровода #define WaterPres 32 // Датчик давления воды в водопроводе #define WATERPUMP 34 // Реле включения помпы, подающей из сампа в аквариум #define WaterClap 36 // Реле клапана, подачи воды из водопровода в самп int cool1; // переменная оборотов вентилятора 1 int cool2; // переменная оборотов вентилятора 2 int powerValue; PCA9685 ledDriver1; // шильд ШИМ 1 PCA9685 ledDriver2; // шильд ШИМ 2 struct Day { // В этой структуре храниться информация о сутках long sunRiseStart; // Начало рассвета в секундах от начала суток long sunRiseFinish; // Конец рассвета long sunSetStart; // Начало заката long sunSetFinish; // Конец заката int power; // Полная мощность излучения днем bool inversion; // инверсия Это я не знаю для чего нужно. Было в другой теме } Day; int led; long seconds; #define ARRAY_LENGTH 21 // Количество каналов ШИМ #define MIN_POWER Moon // Минимальная мощность для всех каналов struct Day array[ARRAY_LENGTH]; // Массив структур для управления каналами void setup() { Serial.begin(9600); // Старт сериала (для отладки) Serial.println("start"); Wire.begin(); // Старт I2C sensors.begin(); sensors.setResolution(sensor1, 10); // температура радиаторов света sensors.setResolution(sensor2, 10); // температура радиаторов света ledDriver1.begin(B000000); // адрес шильда ШИМ 1 (перемычек нет) ledDriver1.init(); ledDriver2.begin(B000001); // адрес шильда ШИМ 2 (перемычка 1) ledDriver2.init(); pinMode(WaterBank, INPUT); pinMode(WaterSumpInHi, INPUT); pinMode(WaterSumpOutHi, INPUT); pinMode(WaterSumpOutNorm, INPUT); pinMode(WaterSumpOutLow, INPUT); pinMode(WaterPres, INPUT); pinMode(WATERPUMP, OUTPUT); pinMode(WaterClap, OUTPUT); array[0].sunRiseStart = 480 * 60; // Белый 1 старт рассвета 8:00 array[0].sunRiseFinish = 490 * 60; // финиш рассвета 8:10 array[0].sunSetStart = 1230 * 60; // старт заката 20:30 array[0].sunSetFinish = 1240 * 60; // финиш заката 20:40 array[0].power = 2047; array[0].inversion = 0; // логика прямая array[1].sunRiseStart = 485 * 60; // Белый 2 старт рассвета 8:05 array[1].sunRiseFinish = 495 * 60; // финиш рассвета 8:15 array[1].sunSetStart = 1235 * 60; // старт заката 20:35 array[1].sunSetFinish = 1245 * 60; // финиш заката 20:45 array[1].power = 2047; // яркость 50% array[1].inversion = 0; // логика прямая array[2].sunRiseStart = 490 * 60; // Белый 3 старт рассвета 8:10 array[2].sunRiseFinish = 500 * 60; // финиш рассвета 8:20 array[2].sunSetStart = 1240 * 60; // старт заката 20:40 array[2].sunSetFinish = 1250 * 60; // финиш заката 20:50 array[2].power = 2047; // яркость 50% array[2].inversion = 0; // логика прямая array[3].sunRiseStart = 495 * 60; // Белый 4 старт рассвета 8:15 array[3].sunRiseFinish = 515 * 60; // финиш рассвета 8:35 array[3].sunSetStart = 1245 * 60; // старт заката 20:45 array[3].sunSetFinish = 1265 * 60; // финиш заката 21:05 array[3].power = 2047; // яркость 50% array[3].inversion = 0; // логика прямая array[4].sunRiseStart = 510 * 60; // Белый 5 старт рассвета 8:30 array[4].sunRiseFinish = 520 * 60; // финиш рассвета 8:40 array[4].sunSetStart = 1260 * 60; // старт заката 21:00 array[4].sunSetFinish = 1270 * 60; // финиш заката 21:10 array[4].power = 2047; // яркость 50% array[4].inversion = 0; // логика прямая array[5].sunRiseStart = 515 * 60; // Белый 6 старт рассвета 8:35 array[5].sunRiseFinish = 525 * 60; // финиш рассвета 8:45 array[5].sunSetStart = 1265 * 60; // старт заката 21:05 array[5].sunSetFinish = 1275 * 60; // финиш заката 21:15 array[5].power = 2047; // яркость 50% array[5].inversion = 0; // логика прямая array[6].sunRiseStart = 520 * 60; // Белый7 старт рассвета 8:40 array[6].sunRiseFinish = 530 * 60; // финиш рассвета 8:50 array[6].sunSetStart = 1270 * 60; // старт заката 21:10 array[6].sunSetFinish = 1280 * 60; // финиш заката 21:20 array[6].power = 2047; // яркость 50% array[6].inversion = 0; // логика прямая array[7].sunRiseStart = 500 * 60; // Белый центр старт рассвета 8:20 array[7].sunRiseFinish = 510 * 60; // финиш рассвета 8:30 array[7].sunSetStart = 1250 * 60; // старт заката 20:50 array[7].sunSetFinish = 1260 * 60; // финиш заката 21:10 array[7].power = 2047; // яркость 50% array[7].inversion = 0; // логика прямая array[8].sunRiseStart = 480 * 60; // Красный 1 array[8].sunRiseFinish = 490 * 60; array[8].sunSetStart = 820 * 60; array[8].sunSetFinish = 880 * 60; array[8].power = 1023; array[8].inversion = 0; array[9].sunRiseStart = 480 * 60; // Красный 2 array[9].sunRiseFinish = 490 * 60; array[9].sunSetStart = 820 * 60; array[9].sunSetFinish = 880 * 60; array[9].power = 1023; array[9].inversion = 0; array[10].sunRiseStart = 480 * 60; // Красный 3 array[10].sunRiseFinish = 490 * 60; array[10].sunSetStart = 820 * 60; array[10].sunSetFinish = 880 * 60; array[10].power = 1023; array[10].inversion = 0; array[11].sunRiseStart = 480 * 60; // Красный 4 array[11].sunRiseFinish = 490 * 60; array[11].sunSetStart = 820 * 60; array[11].sunSetFinish = 880 * 60; array[11].power = 1023; array[11].inversion = 0; array[12].sunRiseStart = 480 * 60; // Зеленый 1 array[12].sunRiseFinish = 490 * 60; array[12].sunSetStart = 820 * 60; array[12].sunSetFinish = 880 * 60; array[12].power = 1023; array[12].inversion = 0; array[13].sunRiseStart = 480 * 60; // Зеленый 2 array[13].sunRiseFinish = 490 * 60; array[13].sunSetStart = 820 * 60; array[13].sunSetFinish = 880 * 60; array[13].power = 1023; array[13].inversion = 0; array[14].sunRiseStart = 480 * 60; // Зеленый 3 array[14].sunRiseFinish = 490 * 60; array[14].sunSetStart = 820 * 60; array[14].sunSetFinish = 880 * 60; array[14].power = 1023; array[14].inversion = 0; array[15].sunRiseStart = 480 * 60; // Зеленый 4 array[15].sunRiseFinish = 490 * 60; array[15].sunSetStart = 820 * 60; array[15].sunSetFinish = 880 * 60; array[15].power = 1023; array[15].inversion = 0; array[16].sunRiseStart = 480 * 60; // Синий 1 array[16].sunRiseFinish = 490 * 60; array[16].sunSetStart = 820 * 60; array[16].sunSetFinish = 880 * 60; array[16].power = 1023; array[16].inversion = 0; array[17].sunRiseStart = 480 * 60; // Синий 2 array[17].sunRiseFinish = 490 * 60; array[17].sunSetStart = 820 * 60; array[17].sunSetFinish = 880 * 60; array[17].power = 1023; array[17].inversion = 0; array[18].sunRiseStart = 480 * 60; // Синий 3 array[18].sunRiseFinish = 490 * 60; array[18].sunSetStart = 820 * 60; array[18].sunSetFinish = 880 * 60; array[18].power = 1023; array[18].inversion = 0; array[19].sunRiseStart = 480 * 60; // Синий 4 array[19].sunRiseFinish = 490 * 60; array[19].sunSetStart = 820 * 60; array[19].sunSetFinish = 880 * 60; array[19].power = 1023; array[9].inversion = 0; array[20].sunRiseStart = 480 * 60; // Ультрафиолет array[20].sunRiseFinish = 490 * 60; array[20].sunSetStart = 820 * 60; array[20].sunSetFinish = 880 * 60; array[20].power = 1023; array[20].inversion = 0; } void printTemperature(DeviceAddress deviceAddress) { float tempC = sensors.getTempC(deviceAddress); Serial.println(tempC); } void loop() { tmElements_t tm; RTC.read(tm); // Получаем текущее время long min0 = tm.Hour * 60; long min1 = tm.Minute; int Moon = analogRead(MoonPin); // считываем значение с фоторезистора Serial.print("Svet "); Serial.println(Moon); Serial.print("Time "); Serial.print(tm.Hour); Serial.write(':'); Serial.print(tm.Minute); Serial.write(':'); Serial.print(tm.Second); Serial.println(); sensors.requestTemperatures(); Serial.print("Temperatura1 "); printTemperature(sensor1); Serial.print("Temperatura2 "); printTemperature(sensor2); cool1 = (sensors.getTempC(sensor1) - 25.00) * 10; // расчитываем ШИМ для вентилятора 1 if (cool1 <= 20) cool1 = 0; else if (cool1 >= 100) cool1 = 100; cool2 = (sensors.getTempC(sensor2) - 25.00) * 10; // расчитываем ШИМ для вентилятора 2 if (cool2 <= 20) cool2 = 0; else if (cool2 >= 100) cool2 = 100; Serial.print ("Coolers "); Serial.print(cool1 ); Serial.print (","); Serial.println(cool2); Serial.print("seconds "); Serial.println(seconds); if(digitalRead(WaterSumpOutLow)== LOW) digitalWrite(WATERPUMP, LOW); else if((digitalRead(WaterSumpOutLow)== HIGH)&&(digitalRead(WaterSumpOutNorm)== HIGH)) digitalWrite(WATERPUMP, HIGH); ledDriver2.setLEDDimmed(9, cool1); //(вторая плата PCA9685 канал 9) вентилятор 1 ledDriver2.setLEDDimmed(10, cool2); //(вторая плата PCA9685 канал 9) вентилятор 2 for (byte i = 0; i < ARRAY_LENGTH; i++){ seconds = (min0 + min1)*60 + tm.Second; // Вычисляем количество секунд с начала суток if (seconds < array[i].sunRiseStart || seconds > array[i].sunSetFinish ) { powerValue = MIN_POWER; } else if (seconds > array[i].sunRiseFinish && seconds < array[i].sunSetStart) { powerValue = array[i].power; } else if (seconds > array[i].sunRiseStart && seconds < array[i].sunRiseFinish) { // set proportional sun rise long int powerValue = (seconds - array[i].sunRiseStart) * 1024 / (array[i].sunRiseFinish - array[i].sunRiseStart ) * (array[i].power - MIN_POWER); powerValue = powerValue / 1024 + MIN_POWER; } else if (seconds > array[i].sunSetStart && seconds < array[i].sunSetFinish) { // set proportional sun set long int powerValue = (seconds - array[i].sunSetStart) * 1024 / (array[i].sunSetFinish - array[i].sunSetStart) * (array[i].power - MIN_POWER); powerValue = array[i].power - powerValue / 1024; } if(i<=8){ if(led != powerValue) ledDriver2.writeLED(i, 4095, powerValue); } else if(i>15) ledDriver1.writeLED(i-16, 4095, powerValue); Serial.println(powerValue); } led = powerValue; delay(1000); }Отображает в сериал секунды он правильно, но почему-то powerValue всегда равен MIN_POWER
а по 41 сообщению, я один раз просчитал, вписал и забыл.
Напишите текущее у вас время и seconds, которые он отображает
В сериал он шлет:
Заработало под
Делайте это перед циклом
Рад, что заработало.
Про вычисление времени похлже я поторопился.
Время вычесляю тут:
seconds = (min0 + min1)*60 + tm.Second; // Вычисляем количество секунд с начала суток for (byte i = 0; i < ARRAY_LENGTH; i++){ if (seconds < array[i].sunRiseStart || seconds > array[i].sunSetFinish ) { powerValue = MIN_POWER; } else if (seconds > array[i].sunRiseFinish && seconds < array[i].sunSetStart) { powerValue = array[i].power; } else if (seconds > array[i].sunRiseStart && seconds < array[i].sunRiseFinish) { // set proportional sun rise long int powerValue = (seconds - array[i].sunRiseStart) * 1024 / (array[i].sunRiseFinish - array[i].sunRiseStart ) * (array[i].power - MIN_POWER); powerValue = powerValue / 1024 + MIN_POWER; } else if (seconds > array[i].sunSetStart && seconds < array[i].sunSetFinish) { // set proportional sun set long int powerValue = (seconds - array[i].sunSetStart) * 1024 / (array[i].sunSetFinish - array[i].sunSetStart) * (array[i].power - MIN_POWER); powerValue = array[i].power - powerValue / 1024;Сейчас бьюсь над тем, чтобы без изменения powerValue лишний раз не дергать ledDriver2.writeLED(i, 4095, powerValue);
Спасибо большое GraninDm за подсказки и терпение при написании кода "заката" и "рассвета".
Подскажите пожалуйста кто-нибудь как организовать алгоритм:
if digitalRead(pin 21 == LOw)
{
if (digitalRead(pin 16 == LOW) && digitalRead(pin 17 == LOW) && digitalRead(pin 18 == HIGH)) // ну это все просто
в (допустим) 16:00 (57600 сек) pin 19 = HIGH
считаем c pin 2 импульсы
и при достижении 5 импульсов, но не позднее 16 : 01 (57660 сек)
pin 19 = LOW.
так-же хочется digitalRead (pin 20 ==LOW) приравнять к "время 16:00"
}
Если для кого важно поясню.
pin 16 - уровень воды в аквариуме (проверить, что не превышен)
pin 17 - уровень воды в САМПе (проверить, что не превышен)
pin 18 - датчик наличия давления воды в подводящей трубе (проверить, что достаточное)
pin 2 - счетчик воды, подаваемой в аквариум (вероятно с хардверным фильтром дребезга) (залить 5 литров)
pin 19 - реле клапана подачи воды в аквариум (нормально закрытый клапан)
pin20 - критически низкий уровень воды в САМПе
pin21 - вода на полу под аквариумом
По #78
struct Day { // В этой структуре храниться информация о сутках long sunRiseStart; // Начало рассвета в секундах от начала суток long sunRiseFinish; // Конец рассвета long sunSetStart; // Начало заката long sunSetFinish; // Конец заката int power; // Полная мощность излучения днем int currentPower; // Текущая мощность bool inversion; // инверсия Это я не знаю для чего нужно. Было в другой теме } Day; В цикле после вычисления powerValue if (powerValue != array[i].currentPower) { ledDriver2.writeLED(i, 4095, powerValue); array[i].currentPower = powerValue }#define SENSOR_WATER_LEVEL_OK 16 #define SENSOR_SAMP_LEVEL_OK 17 #define SENSOR_WATER_PRESSURE_OK 18 #define SENSOR_SAMP_LEVEL_LOW 20 #define SENSOR_CATACLYSM 21 #define SENSOR_WATER_COUNTER 2 #define PUMP_COUNTER_LIMIT 5 #define RELAY_WATER_PUMP 19 bool testFinished; unsigned long seconds; unsigned long lastSeconds; byte pumpCounter; int pumpCounterCuttentValue; int pumpCounterLastValue; void setup() { // put your setup code here, to run once: testFinished = false; lastSeconds = 0; pumpCounter = 0; pumpCounterCuttentValue = 0; pumpCounterLastValue = 0; } void loop() { ... seconds = //вычисляем количество секунд ... if (seconds < lastSeconds){ // переход через полночь testFinished = false; // сбрасываем признак обработки событий pumpCounter - o; // сбрасываем счетчик насоса } lastSeconds = seconds; if(seconds > 57600 && seconds < 57660 && !testFinished && digitalRead(SENSOR_WATER_LEVEL_OK) == LOW && digitalRead(SENSOR_SAMP_LEVEL_OK) == LOW && digitalRead(SENSOR_WATER_PRESSURE_OK) == HIGH && digitalRead(SENSOR_SAMP_LEVEL_LOW) == LOW && digitalRead(SENSOR_CATACLYSM) == LOW) { if(pumpCounter < PUMP_COUNTER_LIMIT ) { pumpCounterCuttentValue = digitalRead(SENSOR_WATER_COUNTER); if (pumpCounterCuttentValue == 1 && pumpCounterLastValue = 0) { pumpCounter++; digitalWrite(RELAY_WATER_PUMP, HIGH); //Включваем насос } pumpCounterLastValue = pumpCounterCurrentValue; } else { digitalWrite(RELAY_WATER_PUMP, LOW); //Выключаем насос testFinished = true; } } }Писал по-быстрому без проверки.
так-же хочется digitalRead (pin 20 ==LOW) приравнять к "время 16:00"
Не понял, проверить только один раз в 16:00 и дальнейшее изменение игнорировать?
САМП - это что?
Не... Криво...
Сейчас другой вариант сделаю
#define SENSOR_WATER_LEVEL_OK 16 #define SENSOR_SAMP_LEVEL_OK 17 #define SENSOR_WATER_PRESSURE_OK 18 #define SENSOR_SAMP_LEVEL_LOW 20 #define SENSOR_CATACLYSM 21 #define SENSOR_WATER_COUNTER 2 #define PUMP_COUNTER_LIMIT 5 #define RELAY_WATER_PUMP 19 bool testFinished; unsigned long seconds; unsigned long lastSeconds; byte pumpCounter; int pumpCounterCuttentValue; int pumpCounterLastValue; bool alert; void setup() { // put your setup code here, to run once: testFinished = false; lastSeconds = 0; pumpCounter = 0; pumpCounterCutternValue = 0; pumpCounterLastValue = 0; alert = false; } void loop() { ... seconds = //вычисляем количество секунд ... if (seconds < lastSeconds){ // переход через полночь testFinished = false; // сбрасываем признак обработки событий pumpCounter - o; // сбрасываем счетчик насоса } lastSeconds = seconds; if (digitalRead(SENSOR_WATER_LEVEL_OK) == LOW && digitalRead(SENSOR_SAMP_LEVEL_OK) == LOW && digitalRead(SENSOR_WATER_PRESSURE_OK) == HIGH && digitalRead(SENSOR_SAMP_LEVEL_LOW) == LOW && digitalRead(SENSOR_CATACLYSM) == LOW) { alert = false; if (seconds >= 57600 && seconds =< 57660 && !testFinished) { if(pumpCounter < PUMP_COUNTER_LIMIT ) { pumpCounterCutternValue = digitalRead(SENSOR_WATER_COUNTER); if (pumpCounterCuttentValue == 1 && pumpCounterLastValue = 0) { // если сигнал счетчика перешел из 0 а 1 pumpCounter++; // увеличиваем сччетчик digitalWrite(RELAY_WATER_PUMP, HIGH); //Включваем насос } pumpCounterLastValue = pumpCounterCuttentValue; } else { digitalWrite(RELAY_WATER_PUMP, LOW); //Выключаем насос при достижении счетчика testFinished = true; } } else { digitalWrite(RELAY_WATER_PUMP, LOW); //Выключаем насос по времени testFinished = true; } } else { digitalWrite(RELAY_WATER_PUMP, LOW); //Выключаем насос alert = true; // Устанавливаем признак аварии } }Вот так лучше
digitalRead (pin 20 ==LOW) приравнять к "время 16:00" - если на датчике "критически низкий уровень воды в САМПе" нет воды, значит (проверив остальные условия) открыть клапан независимо от времени.
САМП - тип фильтра, по сути еще один маленький аквариум, разделенный на несколько фильтрующих секций (в моем случае в тумбе под аквариумом) в первый отсек САМПа вода сливается с аквариума самотеком, а из последнего помпа поднимает обратно в аквариум.
В начале мой САМП выглядел так:

Сейчас многое изменилось.
digitalRead (pin 20 ==LOW) приравнять к "время 16:00" - если на датчике "критически низкий уровень воды в САМПе" нет воды, значит (проверив остальные условия) открыть клапан независимо от времени.
Это предложение противоречит самому себе
Ничего не понял :(
Думаю с этим моментом сам смогу разобраться. И так все мне популярно разжевали.
Спасибо большое за дельные советы.
По #78 долго пытался, но #80 решило проблему.
Блин, беда выходит с
powerValue = (seconds - array[i].sunSetStart) * 4096 / (array[i].sunSetFinish - array[i].sunSetStart) * (array[i].power - MIN_POWER); powerValue = array[i].power - powerValue / 4096;непонятный неадекват выдает во время заката, рассвета.
что-то типа
powerValue = map(powerValue, array[i].sunSetStart, array[i].sunSetFinish, array[i].power, MIN_POWER);
не прокатит? как правильно это написать?
Зачет там 4096. Я же уже объяснял, для чего там 1024
А вообще...
Напрягитесь. Если у меня ошибка - исправьте.
Это математика 6 класс.
powerValue = map(powerValue, array[i].sunSetStart, array[i].sunSetFinish, array[i].power, MIN_POWER);
Тот-же самый бред выдает.
С 1024 то-же самое.
Опубликуйте полный последний скетч. Я проверю
#include <Wire.h> // Библиотека I2C #include <PCA9685.h> // Бибилиотека регистров #include <Time.h> // Библиотека часов #include <DS1307RTC.h> // Библиотека часов #include <OneWire.h> // Библиотека шины 1wire #include <DallasTemperature.h> // Библиотека термометров #define ONE_WIRE_BUS 19 // вход датчиков 18b20 #define SQW 18 // SQW ds1307 на всякий случай OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); DeviceAddress sensor1 = {0x28, 0x0, 0xFB, 0x5F, 0x6, 0x0, 0x0, 0x5B}; // Заранее известный адрес датчика 1 DeviceAddress sensor2 = {0x28, 0xE70, 0x66, 0x60, 0x6, 0x0, 0x0, 0x4A}; // Заранее известный адрес датчика 2 #define MoonPin A0 // Фоторезистор подключен 0-му аналоговому входу #define WaterBank 22 // датчик перебора воды в аквариуме #define WaterSumpInHi 24 // датчик перебора воды во входной секции сампа #define WaterSumpOutHi 26 // датчик перебора воды в основной секции сампа #define WaterSumpOutNorm 28 // датчик нормального уровня воды в основной секции сампа #define WaterSumpOutLow 30 // датчик критически низкого уровня воды в сампе #define WaterInSump 2 // счетчик воды, подаваемой из водопровода #define WaterPres 32 // Датчик давления воды в водопроводе #define WATERPUMP 34 // Реле включения помпы, подающей из сампа в аквариум #define WaterClap 36 // Реле клапана, подачи воды из водопровода в самп int cool1; // переменная оборотов вентилятора 1 int cool2; // переменная оборотов вентилятора 2 int powerValue; PCA9685 ledDriver1; // шильд ШИМ 1 PCA9685 ledDriver2; // шильд ШИМ 2 struct Day { // В этой структуре храниться информация о сутках long sunRiseStart; // Начало рассвета в секундах от начала суток long sunRiseFinish; // Конец рассвета long sunSetStart; // Начало заката long sunSetFinish; // Конец заката int power; // Полная мощность излучения днем long currentPower; // Текущая мощность bool inversion; // инверсия Это я не знаю для чего нужно. Было в другой теме } Day; long seconds; #define ARRAY_LENGTH 21 // Количество каналов ШИМ #define MIN_POWER 10// Moon // Минимальная мощность для всех каналов struct Day array[ARRAY_LENGTH]; // Массив структур для управления каналами void setup() { Serial.begin(9600); // Старт сериала (для отладки) Serial.println("start"); Wire.begin(); // Старт I2C sensors.begin(); sensors.setResolution(sensor1, 10); // температура радиаторов света sensors.setResolution(sensor2, 10); // температура радиаторов света ledDriver1.begin(B000000); // адрес шильда ШИМ 1 (перемычек нет) ledDriver1.init(); ledDriver2.begin(B000001); // адрес шильда ШИМ 2 (перемычка 1) ledDriver2.init(); pinMode(WaterBank, INPUT); pinMode(WaterSumpInHi, INPUT); pinMode(WaterSumpOutHi, INPUT); pinMode(WaterSumpOutNorm, INPUT); pinMode(WaterSumpOutLow, INPUT); pinMode(WaterPres, INPUT); pinMode(WATERPUMP, OUTPUT); pinMode(WaterClap, OUTPUT); array[0].sunRiseStart = 28800; // Белый 1 старт рассвета 8:00 array[0].sunRiseFinish = 29400; // финиш рассвета 8:10 array[0].sunSetStart = 73800; // старт заката 20:30 array[0].sunSetFinish = 74400; // финиш заката 20:40 array[0].power = 2047; // яркость 50% array[0].inversion = 0; // логика прямая array[1].sunRiseStart = 29100; // Белый 2 старт рассвета 8:05 array[1].sunRiseFinish = 29700; // финиш рассвета 8:15 array[1].sunSetStart = 74100; // старт заката 20:35 array[1].sunSetFinish = 74700; // финиш заката 20:45 array[1].power = 2047; // яркость 50% array[1].inversion = 0; // логика прямая array[2].sunRiseStart = 29400; // Белый 3 старт рассвета 8:10 array[2].sunRiseFinish = 30000; // финиш рассвета 8:20 array[2].sunSetStart = 74400; // старт заката 20:40 array[2].sunSetFinish = 75000; // финиш заката 20:50 array[2].power = 2047; // яркость 50% array[2].inversion = 0; // логика прямая array[3].sunRiseStart = 29700; // Белый 4 старт рассвета 8:15 array[3].sunRiseFinish = 30900; // финиш рассвета 8:35 array[3].sunSetStart = 74700; // старт заката 20:45 array[3].sunSetFinish = 75900; // финиш заката 21:05 array[3].power = 2047; // яркость 50% array[3].inversion = 0; // логика прямая array[5].sunRiseStart = 30600; // Белый 5 старт рассвета 8:30 array[5].sunRiseFinish = 31200; // финиш рассвета 8:40 array[5].sunSetStart = 75600; // старт заката 21:00 array[5].sunSetFinish = 76200; // финиш заката 21:10 array[5].power = 2047; // яркость 50% array[5].inversion = 0; // логика прямая array[6].sunRiseStart = 30900; // Белый 6 старт рассвета 8:35 array[6].sunRiseFinish = 31500; // финиш рассвета 8:45 array[6].sunSetStart = 75900; // старт заката 21:05 array[6].sunSetFinish = 76500; // финиш заката 21:15 array[6].power = 2047; // яркость 50% array[6].inversion = 0; // логика прямая array[7].sunRiseStart = 31200; // Белый7 старт рассвета 8:40 array[7].sunRiseFinish = 31800; // финиш рассвета 8:50 array[7].sunSetStart = 76200; // старт заката 21:10 array[7].sunSetFinish = 76800; // финиш заката 21:20 array[7].power = 2047; // яркость 50% array[7].inversion = 0; // логика прямая array[4].sunRiseStart = 30000; // Белый центр старт рассвета 8:20 array[4].sunRiseFinish = 30600; // финиш рассвета 8:30 array[4].sunSetStart = 75000; // старт заката 20:50 array[4].sunSetFinish = 75600; // финиш заката 21:00 array[4].power = 2047; // яркость 50% array[4].inversion = 0; // логика прямая array[8].sunRiseStart = 28800; // Красный 1 array[8].sunRiseFinish = 490 * 60; array[8].sunSetStart = 820 * 60; array[8].sunSetFinish = 880 * 60; array[8].power = 1023; array[8].inversion = 0; array[9].sunRiseStart = 480 * 60; // Красный 2 array[9].sunRiseFinish = 490 * 60; array[9].sunSetStart = 820 * 60; array[9].sunSetFinish = 880 * 60; array[9].power = 1023; array[9].inversion = 0; array[10].sunRiseStart = 480 * 60; // Красный 3 array[10].sunRiseFinish = 490 * 60; array[10].sunSetStart = 820 * 60; array[10].sunSetFinish = 880 * 60; array[10].power = 1023; array[10].inversion = 0; array[11].sunRiseStart = 480 * 60; // Красный 4 array[11].sunRiseFinish = 490 * 60; array[11].sunSetStart = 820 * 60; array[11].sunSetFinish = 880 * 60; array[11].power = 1023; array[11].inversion = 0; array[12].sunRiseStart = 480 * 60; // Зеленый 1 array[12].sunRiseFinish = 490 * 60; array[12].sunSetStart = 820 * 60; array[12].sunSetFinish = 880 * 60; array[12].power = 1023; array[12].inversion = 0; array[13].sunRiseStart = 480 * 60; // Зеленый 2 array[13].sunRiseFinish = 490 * 60; array[13].sunSetStart = 820 * 60; array[13].sunSetFinish = 880 * 60; array[13].power = 1023; array[13].inversion = 0; array[14].sunRiseStart = 42800; // Зеленый 3 array[14].sunRiseFinish = 43100; array[14].sunSetStart = 43200; array[14].sunSetFinish = 43260; array[14].power = 1023; array[14].inversion = 0; array[15].sunRiseStart = 52000; // Зеленый 4 array[15].sunRiseFinish = 52600; array[15].sunSetStart = 52660; array[15].sunSetFinish = 52780; array[15].power = 1023; array[15].inversion = 0; array[16].sunRiseStart = 31200; // Синий 1 Старт рассвета 8:40 array[16].sunRiseFinish = 32400; // Финиш рассвета 9:00 array[16].sunSetStart = 73800; // Старт заката 20:30 array[16].sunSetFinish = 75000; // Финиш заката 20:50 array[16].power = 1024; // Яркость 25% array[16].inversion = 0; array[17].sunRiseStart = 31200; // Синий 2 Старт рассвета 8:40 array[17].sunRiseFinish = 32400; // Финиш рассвета 9:00 array[17].sunSetStart = 73800; // Старт заката 20:30 array[17].sunSetFinish = 75000; // Финиш заката 20:50 array[17].power = 1024; // Яркость 25% array[17].inversion = 0; array[18].sunRiseStart = 33600; // Синий 3 Старт рассвета 9:20 array[18].sunRiseFinish = 34800; // Финиш рассвета 9:40 array[18].sunSetStart = 75000; // Старт заката 20:50 array[18].sunSetFinish = 76200; // Финиш заката 21:10 array[18].power = 1024; // Яркость 25% array[18].inversion = 0; array[19].sunRiseStart = 33600; // Синий 4 Старт рассвета 9:20 array[19].sunRiseFinish = 34800; // Финиш рассвета 9:40 array[19].sunSetStart = 75000; // Старт заката 20:50 array[19].sunSetFinish = 76200; // Финиш заката 21:10 array[19].power = 1024; // Яркость 25% array[9].inversion = 0; array[20].sunRiseStart = 480 * 60; // Ультрафиолет array[20].sunRiseFinish = 490 * 60; array[20].sunSetStart = 820 * 60; array[20].sunSetFinish = 880 * 60; array[20].power = 1023; array[20].inversion = 0; } void printTemperature(DeviceAddress deviceAddress) { float tempC = sensors.getTempC(deviceAddress); Serial.println(tempC); } void loop() { tmElements_t tm; RTC.read(tm); // Получаем текущее время long min0 = tm.Hour * 60; long min1 = tm.Minute; int Moon = analogRead(MoonPin); // считываем значение с фоторезистора Serial.print("Svet "); Serial.println(Moon); Serial.print("Time "); Serial.print(tm.Hour); Serial.write(':'); Serial.print(tm.Minute); Serial.write(':'); Serial.print(tm.Second); Serial.println(); sensors.requestTemperatures(); Serial.print("Temperatura1 "); printTemperature(sensor1); Serial.print("Temperatura2 "); printTemperature(sensor2); cool1 = (sensors.getTempC(sensor1) - 25.00) * 10; // расчитываем ШИМ для вентилятора 1 if (cool1 <= 20) cool1 = 0; else if (cool1 >= 100) cool1 = 100; cool2 = (sensors.getTempC(sensor2) - 25.00) * 10; // расчитываем ШИМ для вентилятора 2 if (cool2 <= 20) cool2 = 0; else if (cool2 >= 100) cool2 = 100; Serial.print ("Coolers "); Serial.print(cool1 ); Serial.print (","); Serial.println(cool2); Serial.print("seconds "); Serial.println(seconds); if(digitalRead(WaterSumpOutLow)== LOW) digitalWrite(WATERPUMP, LOW); else if((digitalRead(WaterSumpOutLow)== HIGH)&&(digitalRead(WaterSumpOutNorm)== HIGH)) digitalWrite(WATERPUMP, HIGH); ledDriver2.setLEDDimmed(9, cool1); //(вторая плата PCA9685 канал 9) вентилятор 1 ledDriver2.setLEDDimmed(10, cool2); //(вторая плата PCA9685 канал 9) вентилятор 2 seconds = (min0 + min1)*60 + tm.Second; // Вычисляем количество секунд с начала суток for (byte i = 0; i < ARRAY_LENGTH; i++){ if (seconds < array[i].sunRiseStart || seconds > array[i].sunSetFinish ) { powerValue = MIN_POWER; } else if (seconds > array[i].sunRiseFinish && seconds < array[i].sunSetStart) { powerValue = array[i].power; } else if (seconds > array[i].sunRiseStart && seconds < array[i].sunRiseFinish) { // set proportional sun rise powerValue = (seconds - array[i].sunRiseStart) * 1024 / (array[i].sunRiseFinish - array[i].sunRiseStart ) * (array[i].power - MIN_POWER); powerValue = powerValue / 1024 + MIN_POWER; // powerValue = map(array[i].currentPower, array[i].sunRiseStart, array[i].sunRiseFinish, MIN_POWER, array[i].power); } else if (seconds > array[i].sunSetStart && seconds < array[i].sunSetFinish) { powerValue = (seconds - array[i].sunSetStart) * 1024 / (array[i].sunSetFinish - array[i].sunSetStart) * (array[i].power - MIN_POWER); powerValue = array[i].power - powerValue / 1024; // powerValue = map(powerValue, array[i].sunSetStart, array[i].sunSetFinish, array[i].power, MIN_POWER); } if (powerValue != array[i].currentPower) { if(i<=8){ ledDriver2.writeLED(i, 4095, powerValue); } else if(i>8) ledDriver1.writeLED(i-8, 4095, powerValue); } array[i].currentPower = powerValue; Serial.print("can"); Serial.print(i); Serial.print("-"); Serial.print(powerValue); Serial.print("; "); if(i==10) Serial.println(); } Serial.println(); Serial.println("."); delay(1000); }Вообще - это ваш косяк!
У меня в коде long int powerValue
У вас int powerValue
Нельзя так обращаться с переменными. Нужно думать какие там могут быть значения.
И если вы хотите там получить значения в интервале 0-4096, это еще не значит, что там не может быть переполнения при вычислениях.
То есть сменю int na long int powerValue и все должно заработать?
Я про int читал, про long читал.
А какие свойства у long int так и не понял, не подскажете?
Поищите в google типы данных int long int
Это азы.
Если коротко
Int 2 byte
long 4 byte
:) работает!!!
Спасибо большое.
Прорабатываю кусок кода, про подмену воды.
Подскажите ктонибудь куда в
#define schetchik 2 #define clapan 4 int schetCounter = 0; int schetState = 0; int lastschetState = 0; void setup() { pinMode(schetchik, INPUT_PULLUP); pinMode(clapan, OUTPUT); Serial.begin(9600); } void loop() { schetState = digitalRead(schetchik); if (schetState != lastschetState) { if (schetState == HIGH) { schetCounter++; Serial.println("doliv vodu"); Serial.print("litrov "); Serial.println(schetCounter); } } lastschetState = schetState; if (schetCounter % 4 == 0) { digitalWrite(clapan, HIGH); } else { digitalWrite(clapan, LOW); } }и как дописать защиту от дребезга, не применяя delay
У вас счетчик контактный или оптический? Лучше создать функцию опроса с миллис и сделать ее вызов вместо 15 строки. Как быстро крутит счетчик, будет ли успевать срабатывать антидребезг?
Можно поставить аппаратный в виде конденсатора. Номинал правда не подскажу.
Счетчик контактный, крутит не выше 15Гц.
Можно подробнее про функцию опроса с миллис и ее вызов вместо 15 строки?
Вот моя функция из одного проекта, правда она для аналога, думаю переделать на цифру труда не составит:
byte get__pressed_button() { int button_value = analogRead(A6); unsigned long millis_now = millis(); if (!(between(button_value, last_button_value - 15, last_button_value + 15))) { button_debounce = millis_now; } last_button_value = button_value; if (millis_now - button_debounce > 20) { if (button_value < 100) { return BUTTON_RIGHT; } else if (button_value < 200) { return BUTTON_UP; } else if (button_value < 400){ return BUTTON_DOWN; } else if (button_value < 600){ return BUTTON_LEFT; } else if (button_value < 800){ return BUTTON_SELECT; } } return BUTTON_NONE; }