Таймер и ШИМ

GraninDm
Offline
Зарегистрирован: 01.08.2013

SERgunCHIK пишет:

Победило проблему. 

Нет не победило

Вот код из библиотели 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));
}

Наверное нужно так

RTC.dec2bcd(tm.Hour) * 3600 + RTC.dec2bcd(tm.Minute) * 60 + RTC.dec2bcd(tm.Second)

Я с этой библиотекой не работал. Читайте доки.

GraninDm
Offline
Зарегистрирован: 01.08.2013
    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

Вот как нужно в вашем коде делать.

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

У меня мой вариант работает (может он и корявый, но работает).
А на dec2bcd компилятор ругался матом.
Раз Вы так неплохо в коде разбираетесь, моежет не сочтете за наглость просьбу с прерыванием подсказать?
По задумке:
Раз в сутки, условии несработки опр датчиков (это я и сам могу дописать), открываем waterclup, отсчитываем N импульсов, закрываем waterclup. Но держим его открытым не более 150 сек.
Если поможете наброском кода, сразу прошу раскоментировать его.
Заранее спасибо.

GraninDm
Offline
Зарегистрирован: 01.08.2013

SERgunCHIK пишет:
А на dec2bcd компилятор ругался матом.

Я же привел код функции в сообщении. В крайнем случае можно было скопировать его в скетч и все бы скомпилировалось.

По поводу помочь...

Я обычно такие вещи пишу конечным автоматом, а для этого нужно досконально знать процесс.

Мы будем дольше переписываться, чем я скетч писать.

Если это не срочно, то можно попробовать.

У меня просто есть сейчас сбободное время, поэтому на форуме и треплюсь. А как долго у меня оно будет я сказать не могу.

А вообще эту работу можно сделать моим ПЛК V 2.0

http://robocraft.ru/blog/3126.html

По ссылке первая версия, но на гугл диске лежит вторая. Там еще описание не полностью сделано.

При определенной доделке второй версии я могу и освещение с шимом сделать по расписанию.

Можно и аквариумный веб интерфейс нарисовать.

Если дальше есть желание общаться то пишите моеимя кот майл ру

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

Я может и не прав ввиду слабой комреценции, но мне мой вариант больше понравился простотой, к тому же он работает. ПЛК у Вас очень интересный, но крышка аквариума уже собрана именно в этом составе железа и развивать я хочу свою версию. А вообще Ваш ПЛК хороший вариант для другой моей задумки. Есть ли у Вас чтото типа комерческой версии?
Возвращаясь к своим попугаям, повторюсь но очень хотелось - бы поштурмовать мозгом наброски скетча под вышеописанную задачу.

GraninDm
Offline
Зарегистрирован: 01.08.2013

По-поводу коммерческой версии я пока не думал.

Опишите подробно задачу по мылу. Попробую помочь карасям.

Клапауций 001
Offline
Зарегистрирован: 05.09.2015

тема переименовывается в

Таймер и ШИМ - братья навек!

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

Долго я расписывал этот код под 21 канал  ШИМ, пока не уперся в тот факт, что имею всего одну PowerValue. Как - же ее распихать по 21 каналу?

nevkon
Offline
Зарегистрирован: 20.01.2015

Создать массив.

GraninDm
Offline
Зарегистрирован: 01.08.2013

Я не понял че там расписывать

Ставим #define ARRAY_LENGTH 21

вместо #define ARRAY_LENGTH 6

и все...

Так powerValue вычисляется в цикле для каждого шима.

Вычислили powerValue установили шим 

ШИМ.Set(powerValue);

Перешли к следующему вычислению в цикле

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

Так именно " #define ARRAY_LENGTH 21" я и поставил.

Но powerValue то одна, и все каналы работают как один. Как сделать чтото типа ШИМ.Set(powerValue[1]);

 

GraninDm
Offline
Зарегистрирован: 01.08.2013

ШИМ.Set(i, powerValue[1]);

Я же не знаю как у вас шим устанавливается.

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

Вставляю я шим в " ledDriver2.writeLED(0, 4095, ШИМ );

GraninDm
Offline
Зарегистрирован: 01.08.2013

Если 0 это канал, то так

ledDriver2.writeLED(i, 4095, ШИМ );

 

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

ledDriver2.writeLED(канал pca9685, из возможных 4095, даем ШИМ );
Вот в "даем ШИМ" надо чтото задать.

GraninDm
Offline
Зарегистрирован: 01.08.2013
ledDriver2.writeLED(i, 4095, powerValue);

Я с этой библиотеккой не работал, читайте доки. Мне лень читать.

 

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

Доки библиотеки тут не при чем.
В "даем ШИМ" надо дать значение от "0" до "4095", ну или переменную с этим значением.
А переменная на все каналы у меня одна "powerValue". Над этим и ломаю голову.

GraninDm
Offline
Зарегистрирован: 01.08.2013

powerValue вычисляется в ЦИКЛЕ!!!!

Я не зная как еще понятнее объяснить

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

Про в "ЦИКЛЕ" похоже догнал.

Но чтото как то не работает.

Где искать ошибку?

#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);
      }
    }
}*/

 

GraninDm
Offline
Зарегистрирован: 01.08.2013
    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 !!!!!!!!!!!!!

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

... и тут я догнал как я туплю!!!!
Огромное спасибо за терпение и дельные советы.

GraninDm
Offline
Зарегистрирован: 01.08.2013

Еще раз повторяю.

Вы неправильно seconds вычисляете.

И зря игнорируете мое 41 сообщение.

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015



#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 сообщению, я один раз просчитал, вписал и забыл.

GraninDm
Offline
Зарегистрирован: 01.08.2013

Напишите текущее у вас время и seconds, которые он отображает

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

В сериал он шлет:

 
Svet 270
Time 14:21:3
Temperatura1 27.50
Temperatura2 27.50
Coolers 25,25
seconds 51661
270
270
270
270
270
270
270
270
270
270
270
270
270
270
270
270
270
270
270
270
270
 
SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

Заработало под 

 array[0].sunRiseStart = 28800; //480 * 60;     // Белый 1       старт рассвета 8:00
  array[0].sunRiseFinish = 29400; //490 * 60;    //               финиш рассвета 8:10
  array[0].sunSetStart = 73800; //1230 * 60;     //               старт заката   20:30
  array[0].sunSetFinish = 74400; //1240 * 60;    //               финиш заката   20:40
  array[0].power = 2047;
  array[0].inversion = 0;               //               логика прямая

 

GraninDm
Offline
Зарегистрирован: 01.08.2013
seconds = (min0 + min1)*60 + tm.Second;   // Вычисляем количество секунд с начала суток

Делайте это перед циклом

Рад, что заработало.

Про вычисление времени похлже я поторопился.

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

Время вычесляю тут:

 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);

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

Спасибо большое 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 - вода на полу под аквариумом

GraninDm
Offline
Зарегистрирован: 01.08.2013

По #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
}

 

GraninDm
Offline
Зарегистрирован: 01.08.2013

 

#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 и дальнейшее изменение игнорировать?

САМП - это что?

GraninDm
Offline
Зарегистрирован: 01.08.2013

Не... Криво...

Сейчас другой вариант сделаю

GraninDm
Offline
Зарегистрирован: 01.08.2013
#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; // Устанавливаем признак аварии
  }
  
}

Вот так лучше

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

digitalRead (pin 20 ==LOW) приравнять к "время 16:00" - если на датчике "критически низкий уровень воды в САМПе" нет воды, значит (проверив остальные условия) открыть клапан независимо от времени.

САМП - тип фильтра, по сути еще один маленький аквариум, разделенный на несколько фильтрующих секций  (в моем случае в тумбе под аквариумом) в первый отсек САМПа вода сливается с аквариума самотеком, а из последнего помпа поднимает обратно в аквариум.

В начале мой САМП выглядел так: Сейчас многое изменилось.

GraninDm
Offline
Зарегистрирован: 01.08.2013

digitalRead (pin 20 ==LOW) приравнять к "время 16:00" - если на датчике "критически низкий уровень воды в САМПе" нет воды, значит (проверив остальные условия) открыть клапан независимо от времени.

 

Это предложение противоречит самому себе

Ничего не понял :(

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

Думаю с этим моментом сам смогу разобраться. И так все мне популярно разжевали.

Спасибо большое за дельные советы.

По #78 долго пытался, но #80 решило проблему.

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

Блин, беда выходит с 

 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);

не прокатит? как правильно это написать?

GraninDm
Offline
Зарегистрирован: 01.08.2013

Зачет там 4096. Я же уже объяснял, для чего там 1024

А вообще...

Напрягитесь. Если у меня ошибка - исправьте.

Это математика 6 класс.

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

 powerValue = map(powerValue, array[i].sunSetStart, array[i].sunSetFinish, array[i].power, MIN_POWER);

Тот-же самый бред выдает.

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

 С 1024 то-же самое.

 

GraninDm
Offline
Зарегистрирован: 01.08.2013

Опубликуйте полный последний скетч. Я проверю

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015
#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);
}      

 

GraninDm
Offline
Зарегистрирован: 01.08.2013

Вообще - это ваш косяк!

У меня в коде long int powerValue

У вас int powerValue

Нельзя так обращаться с переменными. Нужно думать какие там могут быть значения.

И если вы хотите там получить значения в интервале 0-4096, это еще не значит, что там не может быть переполнения при вычислениях.

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

То есть сменю int na long int powerValue и все должно заработать?
Я про int читал, про long читал.
А какие свойства у long int так и не понял, не подскажете?

GraninDm
Offline
Зарегистрирован: 01.08.2013

Поищите в google типы данных int  long int

Это азы.

Если коротко

Int 2 byte

long 4 byte

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

:) работает!!!

Спасибо большое.

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

Прорабатываю кусок кода, про подмену воды.

Подскажите ктонибудь куда в 

#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

nevkon
Offline
Зарегистрирован: 20.01.2015

У вас счетчик контактный или оптический? Лучше создать функцию опроса с миллис и сделать ее вызов вместо 15 строки. Как быстро крутит счетчик, будет ли успевать срабатывать антидребезг?

Можно поставить аппаратный в виде конденсатора. Номинал правда не подскажу.

SERgunCHIK
Offline
Зарегистрирован: 11.02.2015

Счетчик контактный, крутит не выше 15Гц.
Можно подробнее про функцию опроса с миллис и ее вызов вместо 15 строки?

nevkon
Offline
Зарегистрирован: 20.01.2015

Вот моя функция из одного проекта, правда она для аналога, думаю переделать на цифру труда не составит:

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;
}