Автор Тема: Розетка-таймер на Ардуино  (Прочитано 16477 раз)

Оффлайн Nordainthium

Re: Розетка-таймер на Ардуино
« Ответ #20 : 07 Февраль 2018, 01:16:51 »
Твердотельные надо ставить, они совсем никаких звуков не издают.
А эти релюхи  громко щелкают? Спать  мешать не будут?  Или есть тихие варианты?
Довольно ощутимо, в соседней комнате слышно.  Кроме того, надежность существенно ниже требований NASA, у меня буквально недавно один канал залип на несколько дней. Хорошо, хоть не на помпе. Поэтому на важные узлы лучше твердотельные ставить.
Спасибо.  Помпу заказал,  хочу немного разобраться с этой системой и сделать "по уму".

У меня ситуация совсем запущенная -  "Глаза боятся, руки из ж@пы,  но я не сдаюсь"...  ;D

Я так понял "модуль реального времени" решит проблему  с перезапуском  ардуино  по утрам?
« Последнее редактирование: 07 Февраль 2018, 01:19:23 от Nordainthium »

Оффлайн sFiret

Re: Розетка-таймер на Ардуино
« Ответ #21 : 07 Февраль 2018, 11:01:42 »
а Я вот такую схему пока что рассматриваю.
#include <Wire.h>

#define Sh1 3  // Первый канал ШИМ
#define Sh2 5  // Второй канал ШИМ
#define Rel 7  // Канал управления реле
#define DS3231_I2C_ADDRESS 0x68 // SDA A4, SCL A5

int i;                   // переменная цикла
byte MyStep;             // номер в массиве
byte MyStep_old;         // старый номер в массиве
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;  // данные с DS3231
int min_sum;             // минуты с начала дня
int min_sum_ras;         // минуты с начала дня по расписанию

byte minute_old;

// Массивы таймеров вкл/выкл
// рабочие дни
// 00:00    Sh1-Off, Sh2-Off,  Rel-Off, dimming1,2 = 0 sec
// 06:15    Sh1-0n,  Sh2-Off,  Rel-Off, dimming1 = 240 sec
// 08:00    Sh1-0n,  Sh2-On,   Rel-Off, dimming2 = 240 sec
// 09:00    Sh1-Off, Sh2-Off,  Rel-On,  dimming = 0 sec
// 12:00    Sh1-0n,  Sh2-0n,   Rel-Off, dimming = 0 sec
// 14:00    Sh1-Off, Sh2-Off,  Rel-On,  dimming = 0 sec
// 21:00    Sh1-0n,  Sh2-On,   Rel-Off, dimming1,2 = 0 sec
// 21:20    Sh1-0n,  Sh2-Off,  Rel-Off, dimming2 = 240 sec
// 21:30    Sh1-Off, Sh2-Off,  Rel-Off, dimming1 = 240 sec

// выходные дни
// 00:00    Sh1-Off, Sh2-Off,  Rel-Off, dimming1,2 = 0 sec
// 08:00    Sh1-0n,  Sh2-Off,  Rel-Off, dimming1 = 240 sec
// 08:30    Sh1-0n,  Sh2-On,   Rel-Off, dimming2 = 240 sec
// 09:00    Sh1-Off, Sh2-Off,  Rel-On,  dimming = 0 sec
// 21:00    Sh1-0n,  Sh2-On,   Rel-Off, dimming1,2 = 0 sec
// 21:20    Sh1-0n,  Sh2-Off,  Rel-Off, dimming2 = 240 sec
// 21:30    Sh1-Off, Sh2-Off,  Rel-Off, dimming1 = 240 sec

// рабочие дни
byte Hr[9] =   {0,  6, 8, 9, 12, 14, 21, 21, 21};    // часы вкл/выкл
byte Min[9]  = {0, 15, 0, 0,  0,  0,  0, 20, 30};    // минуты вкл/выкл
byte DimT1[9]  = {0, 240, 0, 0, 0, 0, 0, 0, 240};    // время димера первого канала
byte DimT2[9]  = {0, 0, 240, 0, 0, 0, 0, 240, 0};    // время димера второго канала
boolean Sh_K1[9] = {false, true,  true, false, true, false, true,  true,  false};  // состояние первого канала
boolean Sh_K2[9] = {false, false, true, false, true, false, true,  false, false};  // состояние второго канала
boolean Sh_R1[9] = {false, false, false, true, false, true,  false, false, false};  // состояние канала реле

// выходные дни
byte Hr_V[7] =   {0, 8, 8,  9, 21, 21, 21};      // часы вкл/выкл
byte Min_V[7]  = {0, 0, 30, 0, 0, 20, 30};       // минуты вкл/выкл
byte DimT1_V[7]  = {0, 240, 0, 0, 0, 0, 240};    // время димера первого канала
byte DimT2_V[7]  = {0, 0, 240, 0, 0, 240, 0};    // время димера второго канала
boolean Sh_K1_V[7] = {false, true,  true, false, true,  true,  false};  // состояние первого канала
boolean Sh_K2_V[7] = {false, false, true, false, true,  false, false};  // состояние второго канала
boolean Sh_R1_V[7] = {false, false, false, true, false, false, false};  // состояние канала реле

// ---------------------------
void setDateDs3231(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(DS3231_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 setup() {
  Wire.begin();
  // инициализация каналов
  pinMode(Sh1, OUTPUT); 
  pinMode(Sh2, OUTPUT);
  pinMode(Rel, OUTPUT);
  analogWrite(Sh1, 0); 
  analogWrite(Sh2, 0);
  digitalWrite(Rel, LOW);
  // сброс первоночальных значений (чтобы при первом обращении к этим переменным сработало обновление по минутам и суткам)
  minute_old = 255;
  MyStep_old = 255;
  MyStep = 0;
 
  //Первоночальная установка времени
  //setDateDs3231(00, 07, 17, 2, 6, 2, 18); //second, minute, hour, dayOfWeek, dayOfMonth, month, year
 
  //----------------------
  // включить для отладки
  Serial.begin(9600);
  //----------------------
}


//**********************************************
// Основной цикл
void loop()
{
  getDateDs3231(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); // Читаем время
  if (minute != minute_old)       // изменились минуты
    {
    //-------------------------------------------------------
    SerialTimeDate();               // включить для отладки
    //-------------------------------------------------------
    min_sum = hour * 60 + minute; // подсчитываем минуты с начала дня
    minute_old = minute;          // сохраняем минуты
    // проверяем расписание
    if (dayOfWeek < 6)            // рабочие дни
      { 
      MyStep = Schedule_Working();
      if (MyStep != MyStep_old)   // изменилось расписание
        {
        digitalWrite(Rel, (Sh_R1[MyStep])? HIGH:LOW); // включаем/выключаем канал реле (Sh_R1[MyStep]==true возвращает HIGH, если истина)
        if (Sh_R1[MyStep] != Sh_R1[MyStep_old]) SerialKanal(3, 0, 0, 0) ;  // включить для отладки
        dimmer1();                // управляем 1 каналом ШИМ
        dimmer2();                // управляем 2 каналом ШИМ
        MyStep_old = MyStep;      // отработали действие в расписании
        }
      }
    else                          // выходные дни
      {
      MyStep = Schedule_Weekend();
      if (MyStep != MyStep_old)   // изменилось расписание
        {
        digitalWrite(Rel, (Sh_R1_V[MyStep])? HIGH:LOW); // включаем/выключаем канал реле (Sh_R1[MyStep]==true возвращает HIGH, если истина)
        if (Sh_R1[MyStep] != Sh_R1[MyStep_old]) SerialKanal(3, 0, 0, 0) ;  // включить для отладки
        dimmer1_V();               // управляем 1 каналом ШИМ
        dimmer2_V();               // управляем 2 каналом ШИМ
        MyStep_old = MyStep;       // отработали действие в расписании
        }
      }
    }
}
// *******************************************************************
byte Schedule_Working(void)
{
for (i = 0; i<9; i++) //опрашиваем массив расписаний
  {
  min_sum_ras = Hr[i] * 60 + Min[i]; // подсчитываем минуты с начала дня по расписанию
  if (min_sum >= min_sum_ras) MyStep = i;
  }
return MyStep;
}
// *******************************************************************
byte Schedule_Weekend(void)
{
for (i = 0; i<7; i++) //опрашиваем массив расписаний
  {
  min_sum_ras = Hr_V[i] * 60 + Min_V[i]; // подсчитываем минуты с начала дня по расписанию
  if (min_sum >= min_sum_ras) MyStep = i;
  }
return MyStep;
}
// *******************************************************************
void dimmer1 (void)      // ШИМ 1 канала (рабочие дни)
{
byte Start_D;            // стартовое значение ШИМ канала
byte Stop_D;             // конечное значение ШИМ канала
int Sleep_D;           // задержка
if (DimT1[MyStep] != 0)  // если нужно плавно включить/выключить ШИМ канал
  {
  Start_D = (Sh_K1[MyStep_old]) ? 255:0; // вычисляем стартовое значение ШИМ канала (предыдущее состояние)
  Stop_D = (Sh_K1[MyStep]) ? 255:0;      // вычисляем конечное значение ШИМ канала (расписание)
  Sleep_D = DimT1[MyStep] * 3.9216;    // вычисляем задержку в мс. 3.9216 = 1000/255
  //--------------------------------------------------------------------
  SerialKanal(1, Start_D, Stop_D, Sleep_D); // включить для отладки
  //--------------------------------------------------------------------
  if (Start_D != Stop_D)                 // если изменилось
    {
    if (Start_D < Stop_D)
      {
      for (i=Start_D; i<Stop_D; i++)     // увеличиваем яркость
          {
          analogWrite(Sh1, i);
          delay (Sleep_D);
          }
      }
    else
      {
      for (i=Start_D; i>Stop_D; i--)     // уменьшаем яркость
          {
          analogWrite(Sh1, i);
          delay (Sleep_D);
          }
      }
    }
  }
digitalWrite(Sh1, (Sh_K1[MyStep])? HIGH:LOW); // записываем конечное значение
}
// *******************************************************************
void dimmer2 (void)      // ШИМ 2 канала  (рабочие дни)
{
byte Start_D;            // стартовое значение ШИМ канала
byte Stop_D;             // конечное значение ШИМ канала
int Sleep_D;           // задержка
if (DimT2[MyStep] != 0)  // если нужно плавно включить/выключить ШИМ канал
  {
  Start_D = (Sh_K2[MyStep_old]) ? 255:0; // вычисляем стартовое значение ШИМ канала (предыдущее состояние)
  Stop_D = (Sh_K2[MyStep]) ? 255:0;      // вычисляем конечное значение ШИМ канала (расписание)
  Sleep_D = DimT2[MyStep] * 3.9216;      // вычисляем задержку в мс. 3.9216 = 1000/255
  //--------------------------------------------------------------------
  SerialKanal(2, Start_D, Stop_D, Sleep_D); // включить для отладки
  //--------------------------------------------------------------------
  if (Start_D != Stop_D)                 // если изменилось
    {
    if (Start_D < Stop_D)
      {
      for (i=Start_D; i<Stop_D; i++)     // увеличиваем яркость
          {
          analogWrite(Sh2, i);
          delay (Sleep_D);
          }
      }
    else
      {
      for (i=Start_D; i>Stop_D; i--)     // уменьшаем яркость
          {
          analogWrite(Sh2, i);
          delay (Sleep_D);
          }
      }
    }
  }
digitalWrite(Sh2, (Sh_K2[MyStep])? HIGH:LOW); // записываем конечное значение
}
// *******************************************************************
void dimmer1_V (void)      // ШИМ 1 канала (выходные дни)
{
byte Start_D;              // стартовое значение ШИМ канала
byte Stop_D;               // конечное значение ШИМ канала
int Sleep_D;             // задержка
if (DimT1_V[MyStep] != 0)  // если нужно плавно включить/выключить ШИМ канал
  {
  Start_D = (Sh_K1_V[MyStep_old]) ? 255:0; // вычисляем стартовое значение ШИМ канала (предыдущее состояние)
  Stop_D = (Sh_K1_V[MyStep]) ? 255:0;      // вычисляем конечное значение ШИМ канала (расписание)
  Sleep_D = DimT1_V[MyStep] * 3.9216;      // вычисляем задержку в мс. 3.9216 = 1000/255
  //--------------------------------------------------------------------
  SerialKanal(1, Start_D, Stop_D, Sleep_D); // включить для отладки
  //--------------------------------------------------------------------
  if (Start_D != Stop_D)                   // если изменилось
    {
    if (Start_D < Stop_D)
      {
      for (i=Start_D; i<Stop_D; i++)       // увеличиваем яркость
          {
          analogWrite(Sh1, i);
          delay (Sleep_D);
          }
      }
    else
      {
      for (i=Start_D; i>Stop_D; i--)       // уменьшаем яркость
          {
          analogWrite(Sh1, i);
          delay (Sleep_D);
          }
      }
    }
  }
digitalWrite(Sh1, (Sh_K1_V[MyStep])? HIGH:LOW); // записываем конечное значение
}
// *******************************************************************
void dimmer2_V (void)      // ШИМ 2 канала  (выходные дни)
{
byte Start_D;              // стартовое значение ШИМ канала
byte Stop_D;               // конечное значение ШИМ канала
int Sleep_D;             // задержка
if (DimT2_V[MyStep] != 0)  // если нужно плавно включить/выключить ШИМ канал
  {
  Start_D = (Sh_K2_V[MyStep_old]) ? 255:0; // вычисляем стартовое значение ШИМ канала (предыдущее состояние)
  Stop_D = (Sh_K2_V[MyStep]) ? 255:0;      // вычисляем конечное значение ШИМ канала (расписание)
  Sleep_D = DimT2_V[MyStep] * 3.9216;      // вычисляем задержку в мс. 3.9216 = 1000/255
  //--------------------------------------------------------------------
  SerialKanal(2, Start_D, Stop_D, Sleep_D); // включить для отладки
  //--------------------------------------------------------------------
  if (Start_D != Stop_D)                   // если изменилось
    {
    if (Start_D < Stop_D)
      {
      for (i=Start_D; i<Stop_D; i++)       // увеличиваем яркость
          {
          analogWrite(Sh2, i);
          delay (Sleep_D);
          }
      }
    else
      {
      for (i=Start_D; i>Stop_D; i--)       // уменьшаем яркость
          {
          analogWrite(Sh2, i);
          delay (Sleep_D);
          }
      }
    }
  }
digitalWrite(Sh2, (Sh_K2_V[MyStep])? HIGH:LOW); // записываем конечное значение
}

// *******************************************************************
// Подпрограммы для DS3231
// *******************************************************************
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}
// ---------------------------
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

// ---------------------------
void getDateDs3231(byte *second,
          byte *minute,
          byte *hour,
          byte *dayOfWeek,
          byte *dayOfMonth,
          byte *month,
          byte *year)
{

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

  Wire.requestFrom(DS3231_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 SerialTimeDate(void)
{
if (hour<10) Serial.print("0");
Serial.print(hour);
Serial.print(":");
if (minute<10) Serial.print("0");
Serial.print(minute);
Serial.print(":");
if (second<10) Serial.print("0");
Serial.print(second);
Serial.print(" ");

if (dayOfMonth<10) Serial.print("0");
Serial.print(dayOfMonth);
Serial.print(":");
if (month<10) Serial.print("0");
Serial.print(month);
Serial.print(":20");
Serial.print(year);
Serial.print(" DayW=");
Serial.print(dayOfWeek);

Serial.print("  Step=");
Serial.print(MyStep);
Serial.print(" SH1=");
Serial.print((Sh_K1[MyStep])? "HIGH ":"LOW ");
Serial.print(" SH2=");
Serial.print((Sh_K2[MyStep])? "HIGH ":"LOW ");
Serial.print(" Relay=");
Serial.print((Sh_R1[MyStep])? "HIGH ":"LOW ");

Serial.print("\n");
}
// ---------------------------
void SerialKanal(byte kan, byte s_t, byte s_p, int s_l)
{
SerialTimeDate();
if (kan <= 2)
  {
  Serial.print("Dimmer SH");
  Serial.print(kan);
  Serial.print(" Start=");
  Serial.print(s_t);
  Serial.print("  Stop=");
  Serial.print(s_p);
  Serial.print("  Sleep=");
  Serial.print(s_l);
  Serial.print("\n");
  }
}
// ---------------------------
Правда Ann на скетч сказал фу но чуть подучусь перепишем. По свету 2 канала димируемых и реле скажем на помпу и все это по часикам.



пруф

Большое спасибо Chi-chi, КВН и Mr. Smet за семена.

Оффлайн Ann

  • Глобальный модератор
  • Habanero
  • *****
  • Сообщений: 1847
  • Лайков: 10
    • Просмотр профиля
Re: Розетка-таймер на Ардуино
« Ответ #22 : 07 Февраль 2018, 12:20:51 »
Я так понял "модуль реального времени" решит проблему  с перезапуском  ардуино  по утрам?
В этой схеме не нужно стартовать Ардуину каждое утро. Стартануть нужно только один раз, чтоб внутренний счетчик времени начал отсчет с утра, далее она будет работать сама.
Модуль часов разумеется точнее и удобней.

Оффлайн eddy

  • Habanero
  • *****
  • Сообщений: 1378
  • Лайков: 2
  • 300 не надо хватит и одного
    • Просмотр профиля
Re: Розетка-таймер на Ардуино
« Ответ #23 : 19 Март 2018, 11:04:35 »
Камрады! с DS3231 будьте внимательны многие сделаны для работы с аккумулятором lir2032 и с элементом cr2032 не дружат. Если нет возможности приобрести аккумулятор, то разорвите зарядную цепь и будет прекрасно работать с дешевым элементом cr2032.
 Вот эту коричневую хрень выкусить или сковырнуть аккуратненько.
« Последнее редактирование: 19 Март 2018, 11:16:44 от eddy »
Опыт - самый лучший учитель. Берет правда дорого, но зато объясняет доходчиво.

Оффлайн Alekseyem

Re: Розетка-таймер на Ардуино
« Ответ #24 : 19 Март 2018, 11:26:51 »
а выпаять?

Оффлайн eddy

  • Habanero
  • *****
  • Сообщений: 1378
  • Лайков: 2
  • 300 не надо хватит и одного
    • Просмотр профиля
Re: Розетка-таймер на Ардуино
« Ответ #25 : 19 Март 2018, 11:55:47 »
а выпаять?

 :D :D Думаешь где нибудь пригодится? "Скрипач не нужен, он только лишнее топливо жрет". Только время терять. Ыыы хотя первый раз сам выпаивал ;)
« Последнее редактирование: 19 Март 2018, 13:22:03 от eddy »
Опыт - самый лучший учитель. Берет правда дорого, но зато объясняет доходчиво.

Оффлайн Alekseyem

Re: Розетка-таймер на Ардуино
« Ответ #26 : 19 Март 2018, 13:47:05 »
ну такое. если можно сделать аккуратно(выпаять), я сделаю аккуратно. всяко лучше, чем варварством заниматься. если что, можно будет припаять обратно

Оффлайн Selvetarm

Re: Розетка-таймер на Ардуино
« Ответ #27 : 21 Март 2018, 14:29:53 »
А кому-нибудь будет интересен контроллер на базе stm32f103? Я просто сейчас ковыряю потихоньку этот контроллер в сопряжении с BME280 и ESP8266. Дособирал погодную станцию с выводом на 1602, теперь думаю куда двигаться дальше.