Включать реле по таймеру RTC 1307

dinovasya
Offline
Зарегистрирован: 03.10.2013

Схема такая:

  • Arduino Nano
  • RTC 1307 (i2c)
  • AM2320 (i2c) датчик температуры и влажности воткнут по i2c
  • 4 relay modules

Как включать реле на пине D4 каждые 2 часа по часу.

То есть включаем в 12.00 выключаем в 13.00, включаем в 14.00, выключаем в 15.00.

Не понимаю как выдрать из RTC 1307 значения времени и использовать их для включения реле.

 

На данный момент код работает так:

Нашли часы реального времени DS1307 по адресу 0x68
--------Начинаем работать
Температура:  °C  24.50
Влажность:     %  43.00
Температура:  °C  24.50
Влажность:     %  43.00
Дата и время:    2018-06-10T15:11:21
--------=====---------------------
Температура:  °C  24.40
Влажность:     %  43.00
Дата и время:    2018-06-10T15:11:25
--------=====---------------------
Температура:  °C  24.40
Влажность:     %  43.10
Дата и время:    2018-06-10T15:11:29
--------=====---------------------
Температура:  °C  24.40
Влажность:     %  43.10
Дата и время:    2018-06-10T15:11:33
--------=====---------------------
 
И собственно сам код:
/*
 * On start-up the autoprobe feature is used to search the I2C bus to
 * find the first available real-time clock. The sketch indicates
 * which clock type (if any) has been found. If the clock is an
 * MCP7941x device the current calibration setting is printed.
 *
 * The clock can be set by writing the current unixtime (i.e., seconds
 * since 1970-01-01 00:00:00Z) prefixed by the character 'T' to
 * Serial. The string must be terminated by a NULL character, line
 * feed, or carriage return. E.g., "T1343779200" sets the clock to
 * 2012-08-01 00:00:00Z".
 *
 */

#include <Wire.h>
#include <RTCx.h>        // Библиотека часов реального времени 1307
#include <AM2320.h>      // Библиотека датчика AM2320 по шине i2c
AM2320 sensor;            // Обьявляем sensor

void setup(void)
{

   pinMode(6, OUTPUT);  // Пин реле увлажнителя
   pinMode(5, OUTPUT);  // Пин реле обогревателя
   pinMode(4, OUTPUT);  // Пин реле вентилятора
   pinMode(3, OUTPUT);  // Пин реле управляемого таймером- свет
   Serial.begin(9600);
   Wire.begin();
   sensor.begin();
   

  // Автопоиск устройства на шине i2c.
  if (rtc.autoprobe()) {
    // Кажется нашли часы на шине i2c.
    Serial.print("Нашли часы реального времени ");
    Serial.print(rtc.getDeviceName());
    Serial.print(" по адресу 0x");
    Serial.println(rtc.getAddress(), HEX);
    Serial.println("--------Начинаем работать");
  }
  else {
    // Если ничё не найдено на i2c так и напишем что не найдено.
    Serial.println("No RTCx found, невозможно работать с часами");
    while (1)
      ;
  }
  // Enable the battery backup. Ато случается на DS1307
  
  rtc.enableBatteryBackup();
 
  rtc.startClock(); // Убедимся что oscillator запущен

  rtc.setSQW(RTCx::freq4096Hz);
}


const uint8_t bufLen = 30;
char buffer[bufLen + 1] = {'\0'};
uint8_t bufPos = 0;
unsigned long last = 0;
void loop(void)
{

sensor.measure(); 
float h = sensor.getHumidity();  float t = sensor.getTemperature();

    
  
if (t>24) digitalWrite(5, HIGH);      // Включаем реле обогревателя / он находитя в NO

else digitalWrite(5, LOW);           // Выключаем реле обогревателя если температура достигнута

if (h>80) digitalWrite(6, HIGH);      // Включаем реле туманогенератора / он находитя в NO

else digitalWrite(6, LOW);           // Выключаем реле туманогенератора. Влажность достигнута


Serial.print("Температура:  °C  ");
    Serial.println(t);
    Serial.print("Влажность:     %  ");
    Serial.println(h);
   delay(1000);


  struct RTCx::tm tm;
  if (millis() - last > 2000) {
    last = millis();
    rtc.readClock(tm);
   Serial.print("Дата и время:    ");
    RTCx::printIsotime(Serial, tm).println();
//  RTCx::time_t t = RTCx::mktime(&tm);    // Закомментировал- не знаю для чего строка
    

//    Serial.print("unixtime = ");
//    Serial.println(t);
    Serial.println("--------=====----------------------");
     delay(3000);
  }

 
         }

 

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

https://github.com/stevemarple/RTCx/blob/master/src/RTCx.h

	struct tm {
		int tm_sec; // Seconds [0..59]
		int tm_min; // Minutes [0..59].
		int tm_hour; // Hour [0..23].
		int tm_mday; // Day of month [1..31].
		int tm_mon; // Month of year [0..11].
		int tm_year; // Years since 1900.
		int tm_wday; // Day of week [0..6] (Sunday=0).
		int tm_yday; // Day of year [0..365]. (-1=unset).
		int tm_isdst; // Daylight Savings flag (ignored).
	};

 

dinovasya
Offline
Зарегистрирован: 03.10.2013

ого!! нужное направление..  Спасибо.

В итоге хочу получить что-то типа этого:

//------------------------------------------------------------------
058  
059 RTC_DS1307 RTC;    
060  
061 //------------------------------------------------------------------
062 time    cur_time;
063 time    relay_1_on(07, 00, 00);         // Время включения 1-ого реле
064

time    relay_1_off(8, 00, 00);        // Время отключения 1-ого реле 

065 relay   relay_1(RelayChn1);             // Реле 1
066 //------------------------------------------------------------------

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну где то так 

/**/
//----------------------
typedef void(*pDo)();

struct schedule {
  const int hour;
  const int minute;
  const int sec;
  bool flag;
  const pDo Do;
  schedule(int h, int m, int s, const pDo D):
    hour(h), minute(m), sec(s), flag(0), Do(D) {}
} ;

//----------------------------------
void RelON() {
  Serial.println("RelON");
}
void RelOFF() {
  Serial.println("RelOFF");
}
void LedON() {
  Serial.println("LedON");
}
void LedOFF() {
  Serial.println("LedOFF");
}

schedule TABLE[] = {
  {/*час*/0,/*минута*/10,/*секунда*/0,/*обработчик*/&RelON },
  {/*час*/0,/*минута*/20,/*секунда*/0,/*обработчик*/&RelOFF},
  {/*час*/0,/*минута*/30,/*секунда*/0,/*обработчик*/&LedON },
  {/*час*/0,/*минута*/40,/*секунда*/0,/*обработчик*/&RelON },
  {/*час*/0,/*минута*/50,/*секунда*/0,/*обработчик*/&RelOFF},
  {/*час*/1,/*минута*/0,/*секунда*/0,/*обработчик*/&LedOFF}
};
//----------------------------------
void setup() {
  Serial.begin(9600);
}

void loop() {
}
/**/

 

Efim
Offline
Зарегистрирован: 04.05.2018

В вашем случае можно поступить так:

if (time.Hours%2==0) digitalWrite(4, HIGH);
else digitalWrite(4, LOW);

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Efim пишет:

В вашем случае можно поступить так:

if (time.Hours%2==0) digitalWrite(4, HIGH);
else digitalWrite(4, LOW);

 

Тогда уж:

digitalWrite(4, !(time.Hours & 1));

 

Efim
Offline
Зарегистрирован: 04.05.2018

andriano

Точно, так тоже будет работать.

 

Efim
Offline
Зарегистрирован: 04.05.2018

andriano

digitalWrite(4, !(time.Hours & 1));

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Не знаю. В разных языках различный приоритет операций. Чтобы не путаться, я предпочитаю ставить с запасом.

Вот так: отвечал на один вопрос, а пока ответил, он уже изменился.

Первоначально вопрос был о необходимости скобок.

 

Efim
Offline
Зарегистрирован: 04.05.2018

andriano

А я посмотрел что скобки уже стоят и решил удалить вопрос)

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

andriano пишет:

Не знаю. В разных языках различный приоритет операций. Чтобы не путаться, я предпочитаю ставить с запасом.

Вот так: отвечал на один вопрос, а пока ответил, он уже изменился.

Первоначально вопрос был о необходимости скобок.

 

ты жесам пост подправил, было

digitalWrite(4,time.Hours%2 == 0);

 

Efim
Offline
Зарегистрирован: 04.05.2018

xDriver

Побитовый вариант пусть тоже будет.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

xDriver пишет:

ты жесам пост подправил, было

digitalWrite(4,time.Hours%2 == 0);

 

Собственно, я на этот вопрос и отвечал.

А подправить решил потому, что деление (равно как и нахождение остатка) - "тяжелая" операция. Может, конечно, оптимизатор ее и сам на коньюнкцию исправит, но лучше указать явно.

dinovasya
Offline
Зарегистрирован: 03.10.2013

Вот это да, я думал топик будет заброшен, а тут как подключились да ещё такие коды понаписали!! действительно шикарно!

Если б я ещё это в код всё мог правильно впихать ))))

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Efim пишет:

В вашем случае можно поступить так:

if (time.Hours%2==0) digitalWrite(4, HIGH);
else digitalWrite(4, LOW);

 

И теперь в каждый проход в loop будет долбиться или HIGH (LOW) даже если давно уже HIGH (LOW)

Efim
Offline
Зарегистрирован: 04.05.2018

qwone 

Ну тут легко это решаемо так:

if (time.minutes == 00) digitalWrite(4, !(time.Hours & 1));

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

/**/
unsigned long mill;// переменная для millis()
typedef void(*pDo)();
//----------------------
// класс светодиод
class Cl_Led {
  protected:
    const byte pin;
    bool led;
    unsigned long past, time;
    byte state; //0 выкл/ 1 вкл / 2 мигать
    /*установить в состояние*/
    void stand(byte state_) {
      past = mill;
      state = state_;
      switch (state) {
        case 0: // выкл
          digitalWrite(pin, led = LOW);
          break;
        case 1: // вкл
          digitalWrite(pin, led = HIGH);
          break;
        case 2:// мигать
          digitalWrite(pin, led = !led);
          break;
        case 3:// короткое выключение
          digitalWrite(pin, led = LOW);
          break;
        case 4:// короткое включение
          digitalWrite(pin, led = HIGH);
          break;
      }
    }
  public:
    /*конструктор*/
    Cl_Led(byte pin_): pin(pin_) {}
    /*инициализация-вставить в setup()*/
    void init() {
      pinMode(pin, OUTPUT);
      OFF();
    }
    /*работа-вставить в loop()*/
    void run() {
      if (state == 2 && mill - past >= time)stand(2);
      if (state == 3 && mill - past >= time)stand(1);
      if (state == 4 && mill - past >= time)stand(0);
    }
    /*включить*/
    void ON() {
      stand(1);
    }
    /*коротко включить*/
    void ON(unsigned long time_) {
      time = time_;
      stand(4);
    }
    /*выключить*/
    void OFF() {
      stand(0);
    }
    /*коротко выключить*/
    void OFF(unsigned long time_) {
      time = time_;
      stand(3);
    }
    /*мигать*/
    void blink(unsigned long time_ = 200) {
      time = time_;
      stand(2);
    }
};
//----------------------
struct schedule {
  const int hour;
  const int minute;
  const int sec;
  bool flag;
  const pDo Do;
  schedule(int h, int m, int s, const pDo D):
    hour(h), minute(m), sec(s), flag(0), Do(D) {}
} ;
class Cl_Timer {
  protected:
    byte num;
    schedule *TABLE;
  public:
    Cl_Timer(schedule *T, byte n): TABLE(T), num(n) {}
    void init() {}
    void run() {}
};
//-----------Компоновка-----------------------
Cl_Led Led1(/*пин*/13);
Cl_Led Led2(/*пин*/12);
Cl_Led Led3(/*пин*/11);
void Do1() {
  Led1.ON();
  Serial.println("Led1.ON");
}
void Do2() {
  Led1.OFF();
  Serial.println("Led1.OFF");
}
void Do3() {
  Led2.ON();
  Serial.println("Led2.ON();");
}
void Do4() {
  Led2.OFF();
  Serial.println("Led2.OFF");
}
void Do5() {
  Led3.ON();
  Serial.println("Led3.ON();");
}
void Do6() {
  Led3.OFF();
  Serial.println("Led3.OFF");
}
const int num = 6;
schedule TABLE[num] = {
  {/*час*/0,/*минута*/10,/*секунда*/0,/*обработчик*/&Do1 },
  {/*час*/0,/*минута*/20,/*секунда*/0,/*обработчик*/&Do2},
  {/*час*/0,/*минута*/30,/*секунда*/0,/*обработчик*/&Do3 },
  {/*час*/0,/*минута*/40,/*секунда*/0,/*обработчик*/&Do4 },
  {/*час*/0,/*минута*/50,/*секунда*/0,/*обработчик*/&Do5},
  {/*час*/1,/*минута*/ 0,/*секунда*/0,/*обработчик*/&Do6}
};
Cl_Timer Timer(TABLE, num);
//----------------------------------
void setup() {
  Serial.begin(9600);
  Led1.init();
  Led2.init();
  Led3.init();
  Timer.init();
}

void loop() {
  mill = millis();
  Led1.run();
  Led2.run();
  Led3.run();
  Timer.run();
}
/**/

Разумеется туда надо поставить реальные часы

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Efim пишет:

Ну тут легко это решаемо так:

if (time.minutes == 00) digitalWrite(4, !(time.Hours & 1));

 

Флаг надо ввести. Данная функция отработала и больше к ней не обращаться.

Efim
Offline
Зарегистрирован: 04.05.2018

qwone

Я с этой библиотекой не знаком, если это функция то да надо.

dinovasya
Offline
Зарегистрирован: 03.10.2013

Rele1 = (cur_time>=Rele1_on) && (cur_time<Rele1_off);

dinovasya
Offline
Зарегистрирован: 03.10.2013
#include <Wire.h>
#include <RTClib.h>      // Библиотека часов реального времени 1307
#define PWM_MIN 0                                                                            //Если необходим ток покоя на LED - изменить эту константу
#define PWM_MAX 20                                                                          //Если необходимо ограничить максимальную яркость - уменьшить значение
#define PWM_PIN 7
#define rele1 3
#define ReleChn1 8//Пин порта, где будет ШИМ
//#define Rele1 3
//#define Rele2 4
#define ReleObogrev 5   
#define ReleTuman 6
#define mn 60UL                                                                              //Дополнительные константы для удобства
#define hr 3600UL                                                                            //Отражают соответствующие количества секунд 
#define d 86400UL

#include <AM2320.h>      // Библиотека датчика AM2320 по шине i2c
AM2320 sensor;            // Обьявляем sensor



//------------------------------------------------------------------
class time{
public:
        time(unsigned char h=0, unsigned char m=0, unsigned char s=0){
            set_time(h, m, s);
        }
        time&   operator = (time &t){hour = t.hour; min = t.min; sec = t.sec; seconds = t.seconds; return *this;}
        boolean operator ==(time &t){return seconds==t.get_time();}
        boolean operator !=(time &t){return !(*this==t);}
        boolean operator > (time &t){return seconds>t.get_time();}
        boolean operator < (time &t){return seconds<t.get_time();}
        boolean operator >=(time &t){return seconds>=t.get_time();}
        boolean operator <=(time &t){return seconds<=t.get_time();}
        void set_time(unsigned char h, unsigned char m, unsigned char s){
            hour=h; min=m; sec=s;
            seconds=(unsigned long)h*1440 + (unsigned long)m*60 + s;
        }
        unsigned long get_time(){return seconds;};
        void print()    {Serial.print(hour); Serial.print(':');Serial.print(min); Serial.print(':');Serial.println(sec);}
private:
        unsigned char   hour;
        unsigned char   min;
        unsigned char   sec;
        unsigned long   seconds;
};
//------------------------------------------------------------------
class Rele{
public:
    Rele(unsigned char pin){
        pin_num = pin;
        pinMode(pin_num, OUTPUT);
        digitalWrite(pin_num, 1); 
        state=0;
    }
    void operator =(boolean val) {digitalWrite(pin_num, !val); state=val;}
    operator boolean()  {return state;}
private:
    unsigned char   pin_num;
    boolean         state;
};                    
//------------------------------------------------------------------


RTC_DS1307 RTC; 

time    cur_time;
time    Rele1_on(07, 00, 00);         // Время включения 1-ого реле
time    Rele1_off(22, 00, 00);        // Время отключения 1-ого реле  
Rele   Rele1(ReleChn1);             // Реле 1 

char daysOfTheWeek[7][12] = {"Воскр", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void setup(void)
{
       Wire.begin();                                                                               //Инициируем I2C интерфейс
  RTC.begin();                                                                                //Инициирум RTC модуль
  analogWrite(PWM_PIN, PWM_MIN);                                                              //Пишем в порт минимальное значение 
  Serial.begin(9600);                                                                         //Запускаем сом-порт
  delay(3000);                                                                                //Ожидаем открытия консоли

  if (! RTC.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

     // following line sets the RTC to the date & time this sketch was compiled
    // RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2018, 6, 11, 15, 15, 15));    // для установки времени ввести сюда время и расскоментировать

   pinMode(ReleTuman, OUTPUT);  // Пин реле увлажнителя
   pinMode(ReleObogrev, OUTPUT);  // Пин реле обогревателя
//   pinMode(Rele2, OUTPUT);  // Пин реле вентилятора
   pinMode(Rele1, OUTPUT);  // Пин реле управляемого таймером- свет
   Serial.begin(9600);
   Wire.begin();
   sensor.begin();
   
}
  
void loop(void){

// Здесь мы будем считывать с датчика AM2320 температуру и влажность
// и контролировать 2 пина- 5и6 
// Влажность и температура регулируются здесь этими 2мя релюхами

sensor.measure(); 
float h = sensor.getHumidity();  float t = sensor.getTemperature();
if (t>24) digitalWrite(5, HIGH);      // Включаем реле обогревателя / он находитя в NO
else digitalWrite(5, LOW);           // Выключаем реле обогревателя если температура достигнута
if (h>80) digitalWrite(6, HIGH);      // Включаем реле туманогенератора / он находитя в NO
else digitalWrite(6, LOW);           // Выключаем реле туманогенератора. Влажность достигнута
Serial.print("Температура:  °C  ");
    Serial.println(t);
    Serial.print("Влажность:     %  ");
    Serial.println(h);
   delay(1000);
   
// Тут мы окончили опрос датчика и выставили нужные значения ВКЛ и ВЫКЛ на 5и6 пины.
//
// Переходим к часам реального времени
   
 long pwm; 
    DateTime myTime = RTC.now();                          //Читаем данные времени из RTC при каждом выполнении цикла
    long Day_time = myTime.unixtime() % 86400;            //сохраняем в переменную - время в формате UNIX

 DateTime now = RTC.now();
    
    Serial.print(now.day(), DEC);
    Serial.print('.');
    Serial.print(now.month(), DEC);
    Serial.print('.');
    Serial.print(now.year(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    delay(1000);
         
   //  digitalWrite(Rele1,time.Hours%2 == 0);
if (time.minutes == 00) digitalWrite(Rele1, !(time.Hours & 1));

//         static bool state;
//  static unsigned long time;
//  if((millis() - time) > (state ? 10000 : 20000)) // первое число отображает время одного положения в мск, второе число отображает длительность второго состояния реле
// {
//  state = !state;
//  digitalWrite(Rele1, state);
//  time = millis();
// }
// 
//    cur_time.set_time(myTime.hour(), myTime.minute(), myTime.second());  // Устанавливаем часы, минут, секунды в cur_tim
//------------КАНАЛ 1 (Контроль температуры по времени) -------
//    sensor.getTemperature();
//
//    Rele1 = (cur_time>=Rele1_on) && (cur_time<Rele1_off);     // Состояние реле 1 = нахождение текущего времени в диапазоне от relay_1_on до relay_1_off и в диапазоне заданных температур 
}//------------Конец ЦИКЛА-----------------------------

 

dinovasya
Offline
Зарегистрирован: 03.10.2013

выдаёт ошибку exit status 1

expected primary-expression before '.' token
 
оба варианта..
Кстати, 4- это Rele1 теперь 
dinovasya
Offline
Зарегистрирован: 03.10.2013

И этот код можно сократить, почистить?  

Мне pwm не нужен- переделывал другой проект где pwm нужен был- там рассвет, закат был.. там планвно свет зажигался и потухал..

А мне нужно чтоб 

1) реле1 (пин3)  не совсем так уж строго, но по времени чаз через час работал.

Переменные и классы переименовать бы нормально.. Может кто за пару минут в красивый вид привести - причесать  код ))

Efim
Offline
Зарегистрирован: 04.05.2018

Ну смотрите для вашей библиотеки получается так.

if (tm_min == 00) digitalWrite(4, !(tm_hour & 1)); 

Вам же привели пример записи.

Но пока пишите так.

digitalWrite(4, !(tm_hour & 1));

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

qwone пишет:

Efim пишет:

В вашем случае можно поступить так:

if (time.Hours%2==0) digitalWrite(4, HIGH);
else digitalWrite(4, LOW);

 

И теперь в каждый проход в loop будет долбиться или HIGH (LOW) даже если давно уже HIGH (LOW)

В подавляющем большинстве случаев это ни на что не влияет. А в тех немногих случаях, когда это оказывается существенным, digitalWrite следует заменять на что-то менее ресурсоемкое.

И после такой замены это уже точно ни на что вличть не будет, т.к. мы не на intel работаем - здесь запись в регистр ничем не отличается от записи в ячейку памяти.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Efim пишет:

qwone

Ну тут легко это решаемо так:

if (time.minutes == 00) digitalWrite(4, !(time.Hours & 1));

 

Т.е. когда будет "беспрерывно долбиться" в течении целой минуты - это ничего страшного. :)

Efim
Offline
Зарегистрирован: 04.05.2018

andriano

Лично мое мнение пусть хоть весь час "долбит", контроллер должен же чем то быть занят.

А это ~50000000000 долбежок)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Efim пишет:

andriano

Лично мое мнение пусть хоть весь час "долбит", контроллер должен же чем то быть занят.

Поэтому я и не стал править этот фрагмент.

dinovasya
Offline
Зарегистрирован: 03.10.2013

А откуда взялось time.Hours и time.minutes ? Я не вижу их нигде ранее в коде

dinovasya
Offline
Зарегистрирован: 03.10.2013

И не критично попасть именно в 00 минут.  Может лучше цикл while задать или лучше ( (time>12) && (time<13) ) тогда с 12 до 13 будет включено

Efim
Offline
Зарегистрирован: 04.05.2018

dinovasya пишет:

А откуда взялось time.Hours и time.minutes ? Я не вижу их нигде ранее в коде

Да это заначение времени возращаемое библиотекой, чтобы работало я выше написал на что заменить в вашем случае.

dinovasya
Offline
Зарегистрирован: 03.10.2013

'tm_hour' was not declared in this scope

dinovasya
Offline
Зарегистрирован: 03.10.2013

попробовал как в class описано :

digitalWrite(Rele1, !(t.hour & 1));

получил: request for member 'hour' in 't', which is of non-class type 'float'

 

dinovasya
Offline
Зарегистрирован: 03.10.2013

Работает таким образом: 

digitalWrite(Rele1, !(now.hour() & 1));

Топустим сейчас 8 часов, получается на пин Rele1 пойдет !(8 & 1);

Расшифруйте & 

dinovasya
Offline
Зарегистрирован: 03.10.2013

Работает таким образом: 

digitalWrite(Rele1, !(now.hour() & 1));

Топустим сейчас 8 часов, получается на пин Rele1 пойдет !(8 & 1);

Расшифруйте & 

dinovasya
Offline
Зарегистрирован: 03.10.2013

Как я почитал:

Bitwise AND (&)

The bitwise AND operator in C++ is a single ampersand, &, used between two other integer expressions. Bitwise AND operates on each bit position of the surrounding expressions independently, according to this rule: if both input bits are 1, the resulting output is 1, otherwise the output is 0. Another way of expressing this is:

    0  0  1  1    operand1
    0  1  0  1    operand2
    ----------
    0  0  0  1    (operand1 & operand2) - returned result

 Это же не для меня!  Получается что если обе цифры равны 1, то результат будет 1, в противном случае 0.

Значит реле у меня будет включено всего в час ночи )))

 

А восклицательный знак перед этим означает что Только не в час ночи, но все сутки.. так чтоль?

dinovasya
Offline
Зарегистрирован: 03.10.2013

Мне кажется надо сделать так:  Если ЧАСЫ делятся на 2 без остатка, то (Rele1,HIGH) включено. В противном случае (Rele1,LOW)

sadman41
Offline
Зарегистрирован: 19.10.2016

Напишите в столбик 8 и 1 двоичном представлении. Поразрядно сделайте им & и напишите его ниже. Что получилось? Теперь проделайте то же самое с 9 и 1, 10 и 1, 11 и 1.

dinovasya
Offline
Зарегистрирован: 03.10.2013

Или явно указать часы раоты:



if (now.hour()= 0 || now.hour() =2 || now.hour() =4 || now.hour() =6 || now.hour() =8 || now.hour() =10 || now.hour() =12 || now.hour() =14 || now.hour() =16 || now.hour() =18 || now.hour() =20 || now.hour() =22) {

digitalWrite(Rele1, HIGH); else digitalWrite(Rele1, LOW);
}

 

dinovasya
Offline
Зарегистрирован: 03.10.2013

Вот и готовый код:

Serial.print(" сейчас ");
Serial.print(now.hour(), DEC);
Serial.println(" часов. Реле должно быть включено ");
Serial.println();

if ( now.hour()== 0 || now.hour() == 2 || now.hour() == 4 || now.hour() == 6 || now.hour() == 8 || now.hour() == 10 || now.hour() == 12 || now.hour() == 14 || now.hour() == 16 || now.hour() == 18 || now.hour() == 20 || now.hour() == 22) 

digitalWrite(Rele1, HIGH); 
else
digitalWrite(Rele1, LOW);

    

Выдаёт следующее:

сейчас 8 часов. Реле должно быть включено 
 
Температура:  °C  23.30
Влажность:     %  41.10
2018/6/11 (Monday) 8:34:19
 
 сейчас 8 часов. Реле должно быть включено 
 
Температура:  °C  23.30
Влажность:     %  41.10
2018/6/11 (Monday) 8:34:23
 
 сейчас 8 часов. Реле должно быть включено 
 
Температура:  °C  23.20
Влажность:     %  41.20
2018/6/11 (Monday) 8:34:27
 
dinovasya
Offline
Зарегистрирован: 03.10.2013

Бляааа, работать-то удет.. но вот в 9 часов будет писать: Сейчас 9 часов реле должно быть ВКЛючено. ВЫКлючено должно быть ))

dinovasya
Offline
Зарегистрирован: 03.10.2013

это мне больше всего по душе пришлось видимо

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Вот это:

if ( now.hour()== 0 || now.hour() == 2 || now.hour() == 4 || now.hour() == 6 || now.hour() == 8 || now.hour() == 10 || now.hour() == 12 || now.hour() == 14 || now.hour() == 16 || now.hour() == 18 || now.hour() == 20 || now.hour() == 22) 

легко переписывается так:

if ( !(now.hour() % 2)) 

Зацените, насколько короче ;) Перевожу: если текущий час делится на два без остатка - он чётный, или 0. Всё это у вас было расписано простынёй.

Efim
Offline
Зарегистрирован: 04.05.2018

dinovasya пишет:

Как я почитал:

Bitwise AND (&)

The bitwise AND operator in C++ is a single ampersand, &, used between two other integer expressions. Bitwise AND operates on each bit position of the surrounding expressions independently, according to this rule: if both input bits are 1, the resulting output is 1, otherwise the output is 0. Another way of expressing this is:

    0  0  1  1    operand1
    0  1  0  1    operand2
    ----------
    0  0  0  1    (operand1 & operand2) - returned result

 Это же не для меня!  Получается что если обе цифры равны 1, то результат будет 1, в противном случае 0.

Значит реле у меня будет включено всего в час ночи )))

 

А восклицательный знак перед этим означает что Только не в час ночи, но все сутки.. так чтоль?

Все верно вы понимаете, только не все сутки, а час через час. Если хотите инвертировать час включения то просто уберите восклицательный знак.

dinovasya
Offline
Зарегистрирован: 03.10.2013

Update:

Проект бросаю,спалил плату. Всё работает, но компом перестало отображать.

if ( now.hour()== 0 || now.hour() == 2 || now.hour() == 4 || now.hour() == 6 || now.hour() == 8 || now.hour() == 10 || now.hour() == 12 || now.hour() == 14 || now.hour() == 16 || now.hour() == 18 || now.hour() == 20 || now.hour() == 22)
 
digitalWrite(Rele1, HIGH);

else

digitalWrite(Rele1, LOW);

Кстати, этот код не запускает реле- ждал 9 и 10 часов- не запустилось.

sadman41
Offline
Зарегистрирован: 19.10.2016

Какой трагический финал.

dinovasya
Offline
Зарегистрирован: 03.10.2013

щас бы  попробовал if ( !(now.hour() % 2))    но , увы залить не могу )

dinovasya
Offline
Зарегистрирован: 03.10.2013

sadman41 пишет:

Какой трагический финал.

У тебя ник как раз под эту ситуацию подходит ))

dinovasya
Offline
Зарегистрирован: 03.10.2013

Всем спасибо! не только за помощь в данном проекте, самое главное- выучил несколько операторов &&  ||  и даже % понял !!! Спасибо!!!

топик- в топку. пока ардуинка новая не придёт. 

 

А спалил, как ни странно, по инструкции. 

Подал на гнездо VIN  9 вольт с блока питания. 

Запахло чуток жареным, отрубил всё, включаю просто в usb - нет в компе никакой реакции.. даже порта.. а релюхи продолжают мигать в зависимости от влажности и температуры.

А та релюха по таймеру не включается..

Efim
Offline
Зарегистрирован: 04.05.2018

dinovasya

Это потому что у вас строка с дефайном для Rele1 закомментированная.

Пишите так если не умеете пользоватся:

digitalWrite(3, LOW);

 

dinovasya
Offline
Зарегистрирован: 03.10.2013
#define PWM_PIN 7
  #define rele1 3
  #define ReleChn1 8//Пин порта, где будет ШИМ
  //#define Rele1 3
  //#define Rele2 4

Но ведь на 2 строки выше он не комментированный.

Пользоваться я умею, просто на будущее сразу смотрю, называть всё своими именами, дабы не искать по пинам..