Объявление

Внимание!
Данный форум предназначен только для радиолюбителей!
Никакие прочие объявления, реклама товаров либо услуг невозможны!


Любой спам на нашем форуме запрещён!
Разрешаются только ссылки по темам! 3а нарушения БАН.


Часы, будильник, таймер, метеостанция с реле на Arduino

Правила форума
Внимание! Любой спам на нашем форуме запрещён!
Коммерческая реклама сайтов, ссылки, спам запрещены. Так же запрещены ссылки на сайты в профилях новичков.
Бан без предупреждений.

Часы, будильник, таймер, метеостанция с реле на Arduino

Сообщение admin » 22 дек 2016, 23:47

Изображение

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

Спецификация набора

CR1225, Элемент питания литиевый (1шт) 3В
Troyka-Temperature Humidity Sensor DHT11, Цифровой датчик температуры и влажности
0.96inch OLED (A), OLED дисплей с разрешением 128х64px, интерфейсы SPI/I2C
Joystick, 3D-джойстик
Пьезодинамик 4кГц 80дБ
Релейный модуль на основе RTD14005 10А/250В (7А/30В)
Часы реального времени на оcнове DS1307
Программируемый контроллер на базе ATmega328 (аналог Arduino Mini)

0.96inch OLED - это встраиваемый двухцветный (желтый/синий) OLED дисплей с интерфейсом I2C/SPI. Разрешение экрана 128х64 пикселей, а угол обзора более 160 градусов.
Размеры платы 29мм х 33 мм.

Arduino Mini — полноценная Arduino-платформа, только маленькая: всего 33×20 мм.

Обратите внимание, что на плате нет собственного USB-порта.
Поэтому для её прошивки понадобится посредник!
Им может быть другой контроллер Arduino

Характеристики Arduino Mini
— Микроконтроллер: ATmega328
— Тактовая частота: 16 МГц
— Флеш-память: 32 КБ (2 КБ используются загрузчиком)
— Оперативная память SRAM: 2 КБ
— Энергонезависимая память EEPROM: 1 КБ
— Рабочее напряжение: 5 В
— Входное напряжение: 5,3–12 В
— Портов ввода-вывода общего назначения: 20
— Портов с поддержкой ШИМ: 6
— Портов, подключённых к АЦП: 8 (4 из них на нераспаянных выводах)
— Разрядность АЦП: 10 бит
— Аппаратные интерфейсы: UART, SPI, I²C (на нераспаянных выводах)
— Максимальный ток одного вывода: 40 мА
— Максимальный ток с пина +5V: 150 мА

Цифровой датчик температуры и влажности DHT11
Данные температуры и влажности датчик отдаёт по одному проводу в виде цифрового сигнала. Это позволяет передавать данные на расстояние до нескольких десятков метров.
В сердце модуля — популярная среди любителей сенсорная сборка DHT11. Он работает по собственному протоколу. На борту модуля — популярная среди любителей сенсорная сборка DHT11.

Характеристики
— Напряжение питания: 3–5 В
— Потребляемый ток при запросе данных: 2,5 мА
— Потребляемый ток в ожидании: 100 мкА
— Диапазон температур: 0–50 °С
— Погрешность температуры: ±2 °С
— Диапазон влажности: 20–90%
— Погрешность влажности: ±5%
— Габариты: 25×25 мм

Joystick - сделает управление нашим устройством быстрым и удобным.
Модуль-джойстик схож с «грибочком» на манипуляторах PlayStation и XBox. Он комбинирует в себе двухосный джойстик и тактовую кнопку. В нейтральном положении аналоговый сигнал соответствует половине напряжения питания. При перемещении джойстика в одну сторону напряжение будет нарастать, а при движении джойстика в другую сторону — падать. Таким образом, можно получать точное положение ручки джойстика и реагировать на угол наклона, а не только на сам факт наклона ручки. Хотя в этом проекте мы используем только факт наклона.

Характеристики
— Напряжение питания: 3–5 В
— Интерфейс по осям X, Y: аналоговый, линейный
— Интерфейс кнопки: цифровой, бинарный
— Габариты: 25×25 мм

Управление джойстиком

Нажатие влево - вход в меню настроек
изменяемое значение подсвечивается
нажатие вверх - изменение значения
нажатие вправо - переход к следующему значению
при настройки будильника слева появляется значок "а"
нажатие влево - выход из меню с сохранением изменений
время будильника сохраняется в энергонезависимой памяти.
Нажатие вниз - вкл/откл будильника.
Когда сработал будильник
первое нажатие на кнопку - отключение пищалки
второе нажатие на кнопку - отключение реле.

Пьезодинамик

Характеристики
— Номинальная частота: 4 кГц
— Интенсивность: 80 дБ
— Номинальное рабочее напряжение: 5 В
— Габариты: 25,4×25,4 мм

Релейный модуль

Модуль Relay это просто механический рубильник, которым можно управлять при помощи микроконтроллера, такого как Arduino. С помощью реле можно включать и выключать электроприборы, которые подключены к бытовой электросети 220 В. На модуле расположен светодиод, который всегда подскажет — замкнуто реле или нет.
У этого реле есть есть не только нормально разомкнутый (NO) контакт, но и нормально замкнутый (NC). Это удобно.

Характеристики
— Номинальное напряжение питания: 5 В
— Номинальное напряжение сигнала: 3–5 В
— Максимальный ток коммутации: 10 А
— Коммутируемое переменное напряжение (пиковое): 250 В
— Потребляемый ток: 87 мА
— Рабочая температура: −40…+85 °C
— Магнитная система катушки: моностабильная
— Рекомендованная частота переключения: до 1 Гц
— Электрическая износостойкость (NO) контакта: 30×10³ переключений
— Электрическая износостойкость (NC) контакта: 10×10³ переключений
— Габариты: 50,8×25,4 мм

Часы реального времени Модуль RTC - сделан на основе популярного чипа DS1307. Он общается с управляющей электроникой по протоколу I²C / TWI.
Слот предназначен для часовой батарейки размера CR1225 на 3В. Без неё модуль не работает даже с внешним питанием.

Характеристики
Напряжение внешнего питания: 4,5–5,5 В
Напряжение питания батарейки: 2–3,5 В
Потребляемый ток: 500 нА (≈6 месяцев на батарейке)
Выходной интерфейс: I²C
Габариты: 25,4×25,4 мм

Элемент питания

CR1225 – литиевая батарейка

Характеристики
— Напряжение: 3В
— Типоразмер cr1225

Технические параметры нашей конструкции: Индикация Дата, месяц, часы, минуты, температура, влажность
Точность времени, секунд/сутки 2
Диапазон температур 0–50 °С
Погрешность температуры ±2 °С
Диапазон влажности 20–90%
Погрешность влажности ±5%
Максимальный ток коммутации 10 А
Коммутируемое переменное напряжение (пиковое) 250 В
Номинальное напряжение питания 5 В

Электрическая схема
Изображение

Скетч программы

Код: выделить все
#include <DS1307RTC.h>
#include <Time.h>
#include <Wire.h>
#include <PinChangeInt.h>
#include <EEPROM.h>
#include "clock.h"
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <TroykaDHT11.h>
#include <TimerOne.h>
#include <Tone.h>


volatile boolean JoyStickZPressFlag = false;
byte AlarmHour = 7;
byte AlarmMinute = 0;
boolean AlarmFlag;
boolean AlarmSetFlag;
volatile boolean UpdateScreenFlag = false;
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
DHT11 dht(TEMP_SEN_PIN);
Tone Buzzer;


void setup()
{
  digitalWrite(JOYSTICK_Z_PIN, HIGH);
  PCintPort::attachInterrupt(JOYSTICK_Z_PIN, &JOYSTICK_Z_PIN_ISR, FALLING);

  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);

  //pinMode(BUZZER_PIN, OUTPUT);
  //digitalWrite(BUZZER_PIN, LOW);
  Buzzer.begin(BUZZER_PIN);

  AlarmHour = EEPROM.read(ALARM_HOUR_ADR);
  if (AlarmHour > 23)
    AlarmHour = 7;

  AlarmMinute = EEPROM.read(ALARM_MINT_ADR);
  if (AlarmMinute > 59)
    AlarmMinute = 0;

  AlarmFlag = EEPROM.read(ALARM_FLAG_ADR);
  if (AlarmFlag > 1)
    AlarmFlag = ALARM_FLAG_DEFAULT;
   

  Wire.begin();
  tmElements_t CurTime;
  RTC.read(CurTime);
 
  dht.begin();
 
  display.begin(SSD1306_SWITCHCAPVCC);
  UpdateScreenFlag = true;

  //период обновления экрана по прерыванию таймера
  Timer1.initialize(8000000);
  Timer1.attachInterrupt(TimerOne_ISR);
}
//---------------------------------
void loop()
{   
  static tmElements_t CurrentTime;

  if (UpdateScreenFlag) //если обновление экрана
  {
    RTC.read(CurrentTime); //чтение времени с RTC
    display.clearDisplay(); //очистка дисплея
    UpdateTime(&CurrentTime); //обновление времени
    UpdateDate(&CurrentTime); //обновление даты
    UpdateTemp(); //обновление показаний температуры и влажности
    if (AlarmFlag) //если включен будильник
    {//отображение символа "а"
      display.setTextSize(ALARM_SIZE);
      display.setCursor(ALARM_HOR_POS, ALARM_VER_POS);
      display.print("a");
    }
   
    display.display(); //отображение на дисплее обновленной информации

    if (AlarmFlag) //если включен будильник
      CheckAlarm(&CurrentTime); //проверка времени

    UpdateScreenFlag = false; //стирание флага обновления экрана
  }

  switch(ScanJoyStick()) //проверка нажатия джойстивка
  {
    case JOYSTICK_LEFT_: //если влево
      ChangeSettings(); //меню настроек
    break;

    case JOYSTICK_DOWN_: //если вниз
      ChangeAlarmState(&CurrentTime); //вкл/откл будильник
    break;

    default:
    break;
  }
   
  if ((JoyStickZPressFlag) && (digitalRead(RELAY_PIN))) //если нажата кнопка джойстика
  {
    delay(100);
    if (!digitalRead(JOYSTICK_Z_PIN))
    {
      static byte JoyStickZPressCnt = 0;
     
      if (JoyStickZPressCnt == 0) //если первое нажатие
      {
        //digitalWrite(BUZZER_PIN, LOW);
        Buzzer.stop(); //выключение пищалки
        JoyStickZPressCnt++;
      }
      else if (JoyStickZPressCnt == 1) //если второе нажатие
      {
        digitalWrite(RELAY_PIN, LOW); //выключение реле
        JoyStickZPressCnt = 0;
      }
     
      JoyStickZPressFlag = false; //стирание флага нажатия кнопки джойстика
    }
  }
}
//---------------------------------
void UpdateTime(tmElements_t* TimeVal)
{
  display.setTextColor(WHITE); //установка неинверсного отображения
  display.setTextSize(TIME_SIZE); //установка размера текста
  display.setCursor(HOUR_HOR_POS, HOUR_VER_POS); //установка курсора
  //вывод времени
  if (TimeVal->Hour < 10)
    display.print("0");
  display.print(TimeVal->Hour);
  display.print(":");

  if (TimeVal->Minute < 10)
    display.print("0");
  display.print(TimeVal->Minute);
}
//---------------------------------
void UpdateDate(tmElements_t* TimeVal)
{
  display.setTextColor(WHITE);
  display.setTextSize(TEMP_SIZE);
  display.setCursor(DATE_HOR_POS, DATE_VER_POS);
 //вывод даты
  if (TimeVal->Day < 10)
    display.print("0");
  display.print(TimeVal->Day);
  display.print("/");

  if (TimeVal->Month < 10)
    display.print("0");
  display.print(TimeVal->Month);
}
//---------------------------------
void UpdateTemp()
{
  display.setTextColor(WHITE);
  display.setTextSize(TEMP_SIZE);
  display.setCursor(TEMP_HOR_POS, TEMP_VER_POS);
 
  if (dht.read() == DHT_OK) //если чтение данных без ошибок
  { //вывод температуры и влажности
    display.print("t ");
    display.print(dht.getTemperatureC());
    display.print("C");
    display.print("  h ");
    display.print(dht.getHumidity());
    display.print("%");
  }

  else //иначе
  { //вывод надписи "Chip & Dip"
    display.print("Chip & Dip");
  }
}
//---------------------------------
void CheckAlarm(tmElements_t* TimeVal)
{ //если будильник не включен и совпадение времени будильника с текущим временем
  if ((!AlarmSetFlag) && (TimeVal->Hour == AlarmHour) && (TimeVal->Minute == AlarmMinute))
  {
    digitalWrite(RELAY_PIN, HIGH); //включение реле
    //digitalWrite(BUZZER_PIN, HIGH);
    Buzzer.play(NOTE_A3); //включение пищалки
    AlarmSetFlag = true; //установка флага включения будильника
  }
  //иначе
  else if ((AlarmSetFlag) && ((TimeVal->Hour != AlarmHour) || (TimeVal->Minute != AlarmMinute)))
    AlarmSetFlag = false; //стирание флага включения будильника
}
//---------------------------------
void ChangeSettings()
{
    tmElements_t tm;
    RTC.read(tm);
   
    byte TimeParts[6] = {tm.Hour, tm.Minute, AlarmHour, AlarmMinute, tm.Day, tm.Month};
    byte TimeMAXVals[6] = {23, 59, 23, 59, 31, 12};
    byte CurTimePart = 0;
    boolean ExitSetUp = false;

    //отображение начального экрана настроек:
    //значение часов отображается инверсно
    display.clearDisplay();
    UpdateTemp();
    UpdateDate(&tm);
    display.setTextSize(TIME_SIZE);
    display.setCursor(HOUR_HOR_POS, HOUR_VER_POS);
    display.setTextColor(BLACK, WHITE); //инверсное отображение

    if (TimeParts[0] < 10)
      display.print("0");
    display.print(TimeParts[0]);

    display.setTextColor(WHITE);
    display.print(":");

    if (TimeParts[1] < 10)
      display.print("0");
    display.print(TimeParts[1]);
   
    display.display();

    delay(500);

    //цикл меню настроек
    while (!ExitSetUp)
    {
      delay(150);
     
      switch(ScanJoyStick()) //проверка нажатия джойстивка
      {
        case JOYSTICK_UP_: //если вверх
        { //изменение значения на один
          TimeParts[CurTimePart]++;
          if (TimeParts[CurTimePart] > TimeMAXVals[CurTimePart])
          {
            TimeParts[CurTimePart] = 0;

            if (CurTimePart > 3)
              TimeParts[CurTimePart] = 1;
          }
        }
        break;

        case JOYSTICK_RIGHT_: //если вправо
        { //переход к следующему значению
          CurTimePart++;
          if (CurTimePart > 5)
            CurTimePart = 0;
        }
        break;
       
        case JOYSTICK_LEFT_: //если влево
          ExitSetUp = true; //выход из меню
        break;
      }
      //отображение на экране
      //изменяемое значение отображается инверсно
      //при настройке будильника отображается символ "а"
      //изменяемое значение определяет переменная CurTimePart:
      //CurTimePart = 0 - часы времени
      //CurTimePart = 1 - минуты времени
      //CurTimePart = 2 - часы будильника
      //CurTimePart = 3 - минуты будильника
      //CurTimePart = 4 - день
      //CurTimePart = 5 - месяц, см. определение массива TimeParts[]
      display.clearDisplay();
     
      if (CurTimePart <= 3)
      {
        UpdateTemp();
        display.setCursor(DATE_HOR_POS, DATE_VER_POS);
        if (TimeParts[4] < 10)
            display.print("0");
        display.print(TimeParts[4]);
        display.print("/");
        if (TimeParts[5] < 10)
          display.print("0");
        display.print(TimeParts[5]);
        display.setTextSize(TIME_SIZE);
        display.setCursor(HOUR_HOR_POS, HOUR_VER_POS);
     
        if ((CurTimePart%2) == 0)
        {
          display.setTextColor(BLACK, WHITE); //инверсное отображение
          if (TimeParts[CurTimePart] < 10)
            display.print("0");
          display.print(TimeParts[CurTimePart]);

          display.setTextColor(WHITE);
          display.print(":");

          if (TimeParts[CurTimePart + 1] < 10)
            display.print("0");
          display.print(TimeParts[CurTimePart + 1]);
        }

        else
        {
          if (TimeParts[CurTimePart - 1] < 10)
            display.print("0");
          display.print(TimeParts[CurTimePart - 1]);
          display.print(":");
          display.setTextColor(BLACK, WHITE); //инверсное отображение
          if (TimeParts[CurTimePart] < 10)
            display.print("0");
          display.print(TimeParts[CurTimePart]);
        }
      }

      else
      {
        display.setTextColor(WHITE);
        display.setTextSize(TIME_SIZE);
        display.setCursor(HOUR_HOR_POS, HOUR_VER_POS);
        if (TimeParts[2] < 10)
          display.print("0");
        display.print(TimeParts[2]);
        display.print(":");
        if (TimeParts[3] < 10)
          display.print("0");
        display.print(TimeParts[3]);
        UpdateTemp();

        display.setCursor(DATE_HOR_POS, DATE_VER_POS);

        if (CurTimePart == 4)
        {
          display.setTextColor(BLACK, WHITE); //инверсное отображение
          if (TimeParts[CurTimePart] < 10)
            display.print("0");
          display.print(TimeParts[CurTimePart]);

          display.setTextColor(WHITE);
          display.print("/");
          if (TimeParts[CurTimePart + 1] < 10)
            display.print("0");
          display.print(TimeParts[CurTimePart + 1]);
        }

        else
        {
          if (TimeParts[CurTimePart - 1] < 10)
            display.print("0");
          display.print(TimeParts[CurTimePart - 1]);
          display.print("/");
          display.setTextColor(BLACK, WHITE); //инверсное отображение
          if (TimeParts[CurTimePart] < 10)
            display.print("0");
          display.print(TimeParts[CurTimePart]);
        }
      }

      if (CurTimePart > 1)
      {
        display.setTextColor(WHITE);
        display.setTextSize(ALARM_SIZE);
        display.setCursor(ALARM_HOR_POS, ALARM_VER_POS);
        display.print("a");
      }

      display.display();
    }

    //будильник
    AlarmHour = TimeParts[2];
    AlarmMinute = TimeParts[3];
    //запись в память
    EEPROM.write(ALARM_HOUR_ADR, AlarmHour);
    EEPROM.write(ALARM_MINT_ADR, AlarmMinute);
   
    //установка времени в RTC
    tm.Second = 0;   
    tm.Minute = TimeParts[1];
    tm.Hour = TimeParts[0];
    tm.Day = TimeParts[4];
    tm.Month = TimeParts[5];
    tm.Year = 16;
    RTC.write(tm);

  UpdateScreenFlag = true; //установка флага обновления экрана
  delay(500);
}
//---------------------------------
void ChangeAlarmState(tmElements_t* TimeVal)
{
  display.clearDisplay();
 
  if (!AlarmFlag) //если будильник выключен
  {
    AlarmFlag = true; //установка флага включения будильника
    //отображение символа "а"
    display.setTextSize(ALARM_SIZE);
    display.setCursor(ALARM_HOR_POS, ALARM_VER_POS);
    display.print("a");
  }

  else //иначе
  {
    AlarmFlag = false; //стирание флага включения будильника
  }

  EEPROM.write(ALARM_FLAG_ADR, AlarmFlag); //запись состояния будильника в память

  UpdateTemp();
  UpdateDate(TimeVal);
  UpdateTime(TimeVal);
  display.display();

  delay(500);
}
//---------------------------------
byte ScanJoyStick()
{
  byte Direction = JOYSTICK_RELEASED;
  unsigned int X_Val = analogRead(JOYSTICK_X_PIN);
  unsigned int Y_Val = analogRead(JOYSTICK_Y_PIN);
 
  if ((Y_Val >= 900) && (X_Val >= 400))
  {
    Direction = JOYSTICK_UP_;
  }
  else if ((Y_Val <= 400) && (X_Val >= 400))
  {
    Direction = JOYSTICK_DOWN_;
  }
  else if ((Y_Val >= 400) && (X_Val >= 900))
   {
    Direction = JOYSTICK_RIGHT_;
   }
  else if ((Y_Val >= 400) && (X_Val <= 400))
  {
    Direction = JOYSTICK_LEFT_;
  }
 
  return Direction;
}
//---------------------------------
void JOYSTICK_Z_PIN_ISR()
{
  JoyStickZPressFlag = true; //установка флага нажатия кнопки джойстика
}
//---------------------------------
void TimerOne_ISR()
{
  UpdateScreenFlag = true; //установка флага обновления экрана
}


Техническая документация:

Relay Module http://lib.chipdip.ru/165/DOC001165590.pdf
Arduino Mini http://lib.chipdip.ru/176/DOC001176746.pdf
Часы реального времени http://lib.chipdip.ru/423/DOC001423693.pdf
dht11 http://lib.chipdip.ru/426/DOC001426894.pdf
Joystick -Подключение и настройка http://lib.chipdip.ru/484/DOC001484478.pdf
0.96inch-OLED-UserManual http://lib.chipdip.ru/490/DOC001490735.pdf

Библиотеки:

TroykaDHT11-master http://lib.chipdip.ru/495/DOC001495147.zip
Adafruit_SSD1306-master http://lib.chipdip.ru/495/DOC001495440.zip
Adafruit-GFX-Library-master http://lib.chipdip.ru/495/DOC001495442.zip
Arduino-Library-Tone http://lib.chipdip.ru/495/DOC001495443.zip
DS1307RTC http://lib.chipdip.ru/495/DOC001495444.zip
PinChangeInt http://lib.chipdip.ru/495/DOC001495445.zip
Time http://lib.chipdip.ru/495/DOC001495446.zip
TimerOne-r11 http://lib.chipdip.ru/495/DOC001495447.zip
clock http://lib.chipdip.ru/546/DOC001546960.zip

Описание проекта:
http://www.chipdip.ru/product0/9000318627/
admin
Администратор
 
Сообщений: 56
Зарегистрирован: 27 ноя 2016, 18:21
ТегиЧасы, будильник, таймер, метеостанция с реле на Arduino

Часы будильник таймер метеостанция с реле на Arduino

Сообщение CharlesJen » 23 фев 2017, 01:24

Мне очень нравиться что такой многофункциональный часы-будильник, показывает температуру в комнате. Очень важная функция.

.
CharlesJen
 
Сообщений: 1
Зарегистрирован: 16 фев 2017, 03:55
Откуда: Latvia


Вернуться в Для новичков. Азы.

Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

cron
/