Суточный таймер с DS1307, без экрана

Тема в разделе "Arduino & Shields", создана пользователем yden, 3 май 2016.

  1. yden

    yden Гик

    Здравствуйте.
    Опыта можно сказать 0. Подскажите пожалуйста код. Примеры которые пересмотрел - с использование экрана, у меня без него. А выпилить ненужное - ума не хватает.
    Идея: uno, DS1307 и 4 канальное реле. Нужно каждый день в 20:00 включать реле один канал, в 5 утра выключать. DS1307 - время установлено.
    С остальными каналами буду сам разбираться.

    Спасибо
     
  2. yden

    yden Гик

    Нашел код, почистил, залил, но не фурычит.

    Код (C++):
    #include <DS1307RTC.h>
    #include <Wire.h>
    #define DS1307_I2C_ADDRESS 0x68

    const byte outPin = 7; // выход на реле

    byte setMinClockOn; //
    byte setHorClockOn;
    byte setMinClockOff; //
    byte setHorClockOff;

    /////////// часы ..
    byte decToBcd(byte val){
      return ( (val/10*16) + (val%10) );
    }

    byte bcdToDec(byte val){
      return ( (val/16*10) + (val%16) );
    }

    void setDateDs1307(byte second,        // 0-59
                       byte minute,        // 0-59
                       byte hour,          // 1-23
                       byte dayOfWeek,     // 1-7
                       byte dayOfMonth,    // 1-28/29/30/31
                       byte month,         // 1-12
                       byte year)          // 0-99
    {
       Wire.beginTransmission(DS1307_I2C_ADDRESS);
       Wire.write(0);
       Wire.write(decToBcd(second));  
       Wire.write(decToBcd(minute));
       Wire.write(decToBcd(hour));    
       Wire.write(decToBcd(dayOfWeek));
       Wire.write(decToBcd(dayOfMonth));
       Wire.write(decToBcd(month));
       Wire.write(decToBcd(year));
       Wire.endTransmission();
    }

    void getDateDs1307(byte *second,
              byte *minute,
              byte *hour,
              byte *dayOfWeek,
              byte *dayOfMonth,
              byte *month,
              byte *year)
    {

      Wire.beginTransmission(DS1307_I2C_ADDRESS);
      Wire.write(0);
      Wire.endTransmission();

      Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

      *second     = bcdToDec(Wire.read() & 0x7f);
      *minute     = bcdToDec(Wire.read());
      *hour       = bcdToDec(Wire.read() & 0x3f);
      *dayOfWeek  = bcdToDec(Wire.read());
      *dayOfMonth = bcdToDec(Wire.read());
      *month      = bcdToDec(Wire.read());
      *year       = bcdToDec(Wire.read());
    }


    void setup(){
      Wire.begin();
     
      pinMode(outPin, OUTPUT);
      digitalWrite(outPin, LOW);
     
    }

    void loop()
    {
      byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
      getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
     
     
      // сравниваем время и управляем выходом//
      if (setMinClockOff == minute && setHorClockOff == hour
          && second == 0) digitalWrite(outPin, LOW);
      if (setMinClockOn == minute && setHorClockOn == hour
          && second == 0) digitalWrite(outPin, HIGH);  
    }
     
  3. Tomasina

    Tomasina Сушитель лампочек Модератор

    убери && second ==0, вероятность попасть именно в эту секунду невелика.
     
  4. yden

    yden Гик

    Спасибо.
    А где установить требуемые границы времени: 20 часов и 5 часов?
     
  5. vvr

    vvr Инженерище

    byte setMinClockOn = 0; //
    byte setHorClockOn = 20;
    byte setMinClockOff = 0; //
    byte setHorClockOff = 5;
     
  6. yden

    yden Гик

    Не идет.
     
  7. yden

    yden Гик

    А как проверить какие значения принимает переменная minute, hour ?
     
  8. fogary

    fogary Гик

    Вывести значения переменных в порт.
    В функцию setup добавить строчку:
    Код (C++):
    Serial.begin(9600);
    После присвоения переменных, вставить примерно такой код:
    Код (C++):
    Serial.print("Hour: ");
    Serial.println(hour);
    Serial.print("Minute: ");
    Serial.println(minute);
    После загрузки скетча, открываете Serial Monitor и смотрите значения переменных.

    По поводу Вашего кода. Если не стоит задача установки времени на часах (DS1307), то функции setDateDs1307 и decToBcd можно убрать. Так же, если Вам нужно получать только время (т. е. день недели, число, месяц и год - не требуется), то функцию getDateDs1307 можно сократить:
    Код (C++):
    void getDateDs1307(byte *second, byte *minute, byte *hour)
    {
      Wire.beginTransmission(DS1307_I2C_ADDRESS);
      Wire.write(0);
      Wire.endTransmission();
      Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
      *second     = bcdToDec(Wire.read() & 0x7f);
      *minute     = bcdToDec(Wire.read());
      *hour       = bcdToDec(Wire.read() & 0x3f);
    }
    Если значение секунд, так же не нужно, то так:
    Код (C++):
    void getDateDs1307(byte *minute, byte *hour)
    {
      Wire.beginTransmission(DS1307_I2C_ADDRESS);
      Wire.write(0);
      Wire.endTransmission();
      Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
      Wire.read();
      *minute     = bcdToDec(Wire.read());
      *hour       = bcdToDec(Wire.read() & 0x3f);
    }
    Соответственно уменьшить кол-во переменных:
    Код (C++):
    void loop()
    {
      byte second, minute, hour;
      getDateDs1307(&second, &minute, &hour);
    . . .
     
    Или без секунд:
    Код (C++):
    void loop()
    {
      byte minute, hour;
      getDateDs1307(&minute, &hour);
    . . .