Arduino часы с датчиком температуры и без RTS

Введение

В данной статье я покажу вам, как собрать устройство, которое измеряет температуру и относительную влажность воздуха и посылает измеренные значения с помощью стандартного радиочастотного модуля 433 МГц. Датчик температуры и влажности, используемый в устройстве, – это DHT11.

Существует множество способов передачи небольшого объема данных с помощью Arduino или контроллеров ATMega. Один из них использует уже готовую библиотеку, подобную RCSwitch, Radiohead или VirtualWire. Кроме того, можно отправить необработанные данные с помощью встроенного в микроконтроллер модуля UART. Но использовать встроенный модуль UART не рекомендуется, так как приемник будет собирать и все помехи, и микроконтроллер будет работать не так, как предполагалось. В данной статье для передачи и приема данных я использую библиотеку VirtualWire. Эта библиотека работает с Arduino IDE 1.6.2 и 1.6.5.

Модуль передатчика 433 МГц, когда не передает данные, всё равно излучает радиочастотные колебания и передает шум. Он также может создавать помехи другим радиочастотным устройствам. Чтобы не допустить этого, я включаю его, когда необходимо передать данные, и выключаю его, когда передача закончена.

Принципиальная электрическая схема

На следующей картинке показана принципиальная схема часов Arduino GPS.

Arduino часы с датчиком температуры и без RTS

На картинке выше показана схема подключения, в которой мы подключили контакт TX модуля GPS к контакту D9 платы Arduino, запитываем GPS-модуль через саму плату Arduino.

Код программы для GPS-часов

#include<LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

#include <SoftwareSerial.h>
SoftwareSerial Serial1(9, 10); // RX, TX

char str;
char *test=»$GPRMC»;
int temp,i;

void setup()
{
lcd.begin(16,2);
Serial1.begin(9600);
lcd.setCursor(0,0);
lcd.print(«GPS Updated Clock»);
lcd.setCursor(0,1);
lcd.print(» Circuit Digest «);
delay(300);
}

void loop()
{
serial1Event();
if (temp)
{
lcd.clear();
int str_lenth=i;
int x=0,comma=0;
String UTC_hour=»»;
String UTC_minut=»»;
String UTC_second=»»;
String UTC_date=»»;
String UTC_month=»»;
String UTC_year=»»;
String str1=»»;
while(x<str_lenth)
{
if(str==’,’)
comma++;
if(comma==1)
{
x++;
UTC_hour+=str;
UTC_hour+=str;
UTC_minut+=str;
UTC_minut+=str;
UTC_second+=str;
UTC_second+=str;
comma=2;
}

if(comma==10)
{
x++;
UTC_date+=str;
UTC_date+=str;
UTC_month+=str;
UTC_month+=str;
UTC_year+=str;
UTC_year+=str;
}
x++;
}

int UTC_hourDec=UTC_hour.toInt();
int UTC_minutDec=UTC_minut.toInt();
int Second=UTC_second.toInt();
int Date=UTC_date.toInt();
int Month=UTC_month.toInt();
int Year=UTC_year.toInt();

int Hour=UTC_hourDec+5;
if(Hour>23)
{
Hour-=24;
Date+=1;
}
int Minut=UTC_minutDec+30;
if(Minut>59)
Minut-=60;

// UTC_ind_zone_time
lcd.clear();
lcd.print(«Date: «);
lcd.print(Date);
lcd.print(«/»);
lcd.print(Month);
lcd.print(«/»);
lcd.print(«20»);
lcd.print(Year);

lcd.setCursor(0,1);
lcd.print(«Time: «);
lcd.print(Hour);
lcd.print(«:»);
lcd.print(Minut);
lcd.print(«:»);
lcd.print(Second);
// delay(100);
temp=0;
// j=0;
i=0;
x=0;
str_lenth=0;
// k=0;
}
// delay(1000);
}

void serial1Event()
{
while(1)
{
while (Serial1.available()) //проверка данных с GPS
{
char inChar = (char)Serial1.read();
str= inChar; //хранение данных с GPS в str[]
i++;
if (i < 7)
{
if(str != test) //проверка $GPRMC
{
i=0;
}
}
if(i>65)
{
temp=1;
break;
}
}
if(temp)
break;
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

#include<LiquidCrystal.h>

LiquidCrystal lcd(7,6,5,4,3,2);

 
#include <SoftwareSerial.h>

SoftwareSerial Serial1(9,10);// RX, TX

charstr70;

char*test=»$GPRMC»;

inttemp,i;

voidsetup()

{

lcd.begin(16,2);

Serial1.begin(9600);

lcd.setCursor(,);

lcd.print(«GPS Updated Clock»);

lcd.setCursor(,1);

lcd.print(» Circuit Digest «);

delay(300);

}
 

voidloop()

{

serial1Event();

if(temp)

{

lcd.clear();

intstr_lenth=i;

intx=,comma=;

StringUTC_hour=»»;

StringUTC_minut=»»;

StringUTC_second=»»;

StringUTC_date=»»;

StringUTC_month=»»;

StringUTC_year=»»;

Stringstr1=»»;

while(x<str_lenth)

{

if(strx==’,’)

comma++;

if(comma==1)

{

x++;

UTC_hour+=strx++;

UTC_hour+=strx++;

UTC_minut+=strx++;

UTC_minut+=strx++;

UTC_second+=strx++;

UTC_second+=strx;

comma=2;

}

if(comma==10)

{

x++;

UTC_date+=strx++;

UTC_date+=strx++;

UTC_month+=strx++;

UTC_month+=strx++;

UTC_year+=strx++;

UTC_year+=strx;

}

x++;

}

intUTC_hourDec=UTC_hour.toInt();

intUTC_minutDec=UTC_minut.toInt();

intSecond=UTC_second.toInt();

intDate=UTC_date.toInt();

intMonth=UTC_month.toInt();

intYear=UTC_year.toInt();

intHour=UTC_hourDec+5;

if(Hour>23)

{

Hour-=24;

Date+=1;

}

intMinut=UTC_minutDec+30;

if(Minut>59)

Minut-=60;

// UTC_ind_zone_time

lcd.clear();

lcd.print(«Date: «);

lcd.print(Date);

lcd.print(«/»);

lcd.print(Month);

lcd.print(«/»);

lcd.print(«20»);

lcd.print(Year);

lcd.setCursor(,1);

lcd.print(«Time: «);

lcd.print(Hour);

lcd.print(«:»);

lcd.print(Minut);

lcd.print(«:»);

lcd.print(Second);

//  delay(100);

temp=;

//    j=0;

i=;

x=;

str_lenth=;

//    k=0;

}

// delay(1000);

}
 

voidserial1Event()

{

while(1)

{

while(Serial1.available())//проверка данных с GPS

{

charinChar=(char)Serial1.read();

stri=inChar;//хранение данных с GPS в str[]

i++;

if(i<7)

{

if(stri-1!=testi-1)//проверка $GPRMC

{

i=;

}

}

if(i>65)

{

temp=1;

break;

}

}

if(temp)

break;

}

}

Предварительные причесывания

Начал я с простого — заставил хотя бы собираться библиотеки. Обе библиотеки используют ардуиновские функции, поэтому пришлось внести некоторые изменения. Для начала добавим файл в проект (он будет портом библиотеки OneWire для проекта) и приинклюдим его в файл , а затем начнем причесывание. А именно:

  • OneWire построена таким образом, что ей при создании экземпляра объекта скармливается номер ноги, на которой у тебя будет линия 1-Wire. Это тащит за собой кусочек мрака из недр библиотек Ардуино, поэтому я пошел простым путем и зашил хардкодом в конструктор класса OneWire нужные мне ноги. Да, теряем универсальность, но я пока не вижу применения с двумя шинами 1-Wire (хотя… ну да не сейчас). Исходя из схемы платы, я выбрал ногу PA6, которая выходит на колодку DIGITAL пин 28.

  • OneWire использует задержки в микросекундах для реализации протокола 1-Wire, подсунем библиотечную функцию _delay_us() в файл

  • OneWire любит отключать прерывания во время выполнения очень маленьких задержек (несколько микросекунд), и я ее понимаю. Но сразу же оглянемся и подумаем о том, что у нас все-таки будет ось. А значит, включение прерываний разумнее проредить немного, чтобы случайно не потерять контекст выполнения на неопределенное время. Библиотека использует ардуиновские функции работы с прерываниями, подсунем ей стандартные через файл :

  • В драйвере термодатчика используется задержка, измеряемая в миллисекундах. Тут разумнее использовать вызов функции ОС, особенно учитывая размер этих задержек. Для замены sleep на вызов функции ОС пришлось немного погородить макросов в , комментарии в коде.

Станция с датчиком давления

Следующая модель будет уметь определять:

  • влажность и температуру;
  • уровень высоты;
  • атмосферное давление.

Компоненты

Для сборки потребуются:

  • сенсор DHT22;
  • датчик давления BMP180;
  • плата Ардуино Нано;
  • lcd-экран с блоком I2C;
  • резистор 10 кОм;
  • плата макетная;
  • припой;
  • 40-контактный однорядный разъем;
  • соединительные провода.
Популярные статьи  Мужская купюрница своими руками

Придется паять и работать с контактами, поэтому также необходим паяльник и плоскогубцы.

Сенсор давления

Таковым послужит барометрический датчик с интерфейсом I2C BMP180. Он станет контролировать абсолютное значение параметра вокруг себя.  Падение обычно сигнализирует о приближении грозы и наступлении дождя (поскольку им сопутствует область низкого давления), а увеличение, наоборот, говорит о прохождении области низкого давления и наступлении ясной сухой погоды.

Давление всегда зависит от высоты над уровнем моря и погодных условий в зоне измерения. Но в нашем случае измеряется относительное — как если бы метеостанция находилась на уровне моря.

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

Еще один важный момент — светочувствительность. Благодаря силикону в конструктиве BMP180 он способен улавливать попадающий через отверстие в корпусе микрочипа свет и нагреваться. Максимально точные измерения потребуют изоляции от окружающего света.

BMP180 соединяется через шину I2C по следующей схеме:

A4 — SDA;

A5 — SCL;

3.3V — VCC;

GND — GND.

Сборка

Процесс сборки начинается с монтажа однорядных разъемов для DHT22 и Arduino:

От вывода DATA к GND припаян резистор на 10 кОм.

Далее монтируется разъем для BMP180 (питаться датчик будет от линии 3.3 В). Компоненты соединяются шиной I2C.

На последнем этапе та же шина соединяется с дисплеем.

Так выглядит домашняя метеостанция в сборе:

Пример вывода информации об атмосферном давлении:

Программный код

Для работы понадобятся скетч Ардуино и библиотеки датчиков. Все они доступны в приложениях к статье.

Текст скетча можно скачать здесь: https://cloud.mail.ru/public/piwT/gew8pPv7M

Пример проекта с i2C модулем часов и дисплеем

Проект представляет собой обычные часы, на индикатор будет выведено точное время, а двоеточие между цифрами будет мигать с интервалом раз в одну секунду. Для реализации проекта потребуются плата Arduino Uno, цифровой индикатор, часы реального времени (в данном случае вышеописанный модуль ds1307), шилд для подключения (в данном случае используется Troyka Shield), батарейка для часов и провода.

В проекте используется простой четырехразрядный индикатор на микросхеме TM1637. Устройство обладает двухпроводным интерфейсом и обеспечивает 8 уровней яркости монитора. Используется только для показа времени в формате часы:минуты. Индикатор прост в использовании и легко подключается. Его выгодно применять для проектов, когда не требуется поминутная или почасовая проверка данных. Для получения более полной информации о времени и дате используются жидкокристаллические мониторы.

Модуль часов подключается к контактам SCL/SDA, которые относятся к шине I2C. Также нужно подключить землю и питание. К Ардуино подключается так же, как описан выше: SDA – A4, SCL – A5, земля с модуля к земле с Ардуино, VCC -5V.

Индикатор подключается просто – выводы с него CLK и DIO подключаются к любым цифровым пинам на плате.

Arduino часы с датчиком температуры и без RTS

Скетч. Для написания кода используется функция setup, которая позволяет инициализировать часы и индикатор, записать время компиляции. Вывод времени на экран будет выполнен с помощью loop.


#include <Wire.h>

#include "TM1637.h"

#include "DS1307.h" //нужно включить все необходимые библиотеки для работы с часами и дисплеем.

char compileTime[] = __TIME__; //время компиляции.

#define DISPLAY_CLK_PIN 10

#define DISPLAY_DIO_PIN 11 //номера с выходов Ардуино, к которым присоединяется экран;

void setup()

{

display.set();

display.init(); //подключение и настройка экрана.

clock.begin(); //включение часов.

byte hour = getInt(compileTime, 0);

byte minute = getInt(compileTime, 2);

byte second = getInt(compileTime, 4); //получение времени.

clock.fillByHMS(hour, minute, second); //подготовка для записывания в модуль времени.

clock.setTime(); //происходит запись полученной информации во внутреннюю память, начало считывания времени.

}

void loop()

{

int8_t timeDisp; //отображение на каждом из четырех разрядов.

clock.getTime();//запрос на получение времени.

timeDisp = clock.hour / 10;

timeDisp = clock.hour % 10;

timeDisp = clock.minute / 10;

timeDisp = clock.minute % 10; //различные операции для получения десятков, единиц часов, минут и так далее.

display.display(timeDisp); //вывод времени на индикатор

display.point(clock.second % 2 ? POINT_ON : POINT_OFF);//включение и выключение двоеточия через секунду.

}

char getInt(const char* string, int startIndex) {

return int(string - '0') * 10 + int(string) - '0'; //действия для корректной записи времени в двухзначное целое число. В ином случае на экране будет отображена просто пара символов.

}

После этого скетч нужно загрузить и на мониторе будет показано время.

Программу можно немного модернизировать. При отключении питания выше написанный скетч приведет к тому, что после включения на дисплее будет указано время, которое было установлено при компиляции. В функции setup каждый раз будет рассчитываться время, которое прошло с 00:00:00 до начала компиляции. Этот хэш будет сравниваться с тем, что хранятся в EEPROM, которые сохраняются при отключении питания.

Для записи и чтения времени в энергонезависимую память или из нее нужно добавить функции EEPROMWriteInt и EEPROMReadInt. Они нужны для проверки совпадения/несовпадения хэша с хэшем, записанным в EEPROM.

Можно усовершенствовать проект. Если использовать жидкокристаллический монитор, можно сделать проект, который будет отображать дату и время на экране. Подключение всех элементов показано на рисунке.

Arduino часы с датчиком температуры и без RTS

В результате в коде нужно будет указать новую библиотеку (для жидкокристаллических экранов это LiquidCrystal), и добавить в функцию loop() строки для получения даты.

Алгоритм работы следующий:

  • Подключение всех компонентов;
  • Загрузка скетча;
  • Проверка – на экране монитора должны меняться ежесекундно время и дата. Если на экране указано неправильное время, нужно добавить в скетч функцию RTC.write (tmElements_t tm). Проблемы с неправильно указанным временем связаны с тем, что модуль часов сбрасывает дату и время на 00:00:00 01/01/2000 при выключении.
  • Функция write позволяет получить дату и время с компьютера, после чего на экране будут указаны верные параметры.

Виды датчиков

Для измерения параметров среды часто применяют три вида сенсоров:

  • DHT11;
  • DHT22;
  • SHT1x.

Плюс первого — дешевизна, скорость работы и стабильность сигнала. Из минусов отметим сравнительно слабую программную реализацию библиотеки, высокую погрешность выполняемых измерений и не всегда подходящий диапазон рабочих температур. DHT22 выгодно отличается благодаря:

  • малым погрешностям;
  • высокой дальности сигнала;
  • поддержке дробных значений.

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

Датчики линейки SHT1x быстро срабатывают, имеют весьма низкую погрешность, экономичны и умеют «засыпать» при долгой неактивности. Из недостатков выделим:

  • два цифровых интерфейса;
  • невозможность работы без подключения программной библиотеки и диапазон от 0 до 50 градусов — как в других образцах. Его хватает не всегда.

По стоимости все три варианта примерно одинаковы. Для «домашних» установок чаще берут DHT11-22 за их сравнительную простоту в эксплуатации и настройке.

Часы без RTC

Для начала мы должны понимать, что такое RTC. Из Википедии:

Популярные статьи  Браслет «Замысловатые волны» из бисера и стекляруса

Часы реального времени (ЧРВ, RTC — англ. Real Time Clock) — электронная схема, предназначенная для учёта хронометрических данных (текущее время, дата, день недели и др.), представляет собой систему из автономного источника питания и учитывающего устройства. Чаще всего часы реального времени встречаются в вычислительных машинах, хотя на самом деле ЧРВ присутствуют практически во всех электронных устройствах, которые должны хранить время.

В итоге в данной версии мы сделаем часы без RTC с индикатором температуры и влажности на Arduino с помощью модуля DHT11. Также мы используем 3 кнопки для установки часов.

Комплектующие

Вам понадобятся эти кусочки для этого проекта:

  • Arduino Uno плата
  • Кнопки 3 шт.
  • Потенциометр
  • Модуль LCD 1602
  • Модуль температуры и влажности DHT11
  • Макетная плата
  • Перемычки

Соедините комплектующие часов как на схеме ниже.

Arduino часы с датчиком температуры и без RTS

Код

Вы можете скопировать или скачать код часов на Ардуино ниже.

#include <LiquidCrystal.h>
#include <SimpleDHT.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
volatile int sec, minute = 0, hour = 0;
int b_h = 5;
int b_m = 6;
int pinDHT11 = 2;
int b_startstop = 3;
bool startstop = false;

SimpleDHT11 dht11;

void setup() {

  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);

  lcd.setCursor(0, 0);
  lcd.print("Ahmad Ordikhani");
  lcd.setCursor(0, 1);
  lcd.print("Clk without RTC");
  delay(3000);
  lcd.clear();

  pinMode(b_h, INPUT_PULLUP);
  pinMode(b_m, INPUT_PULLUP);
  pinMode(b_startstop, INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(3), buttons, FALLING);
}

void loop() {

  //Setting the time will stop the clock to set the time
  while (startstop == false)
  {
    lcd.setCursor(0, 1);
    lcd.print("SET");
    delay(100);
    lcd.setCursor(0, 0);
    lcd.print("Time: ");
    if(hour<10)
    {
    lcd.print("0");
    lcd.print(hour);
    }
    else
    lcd.print(hour);
    
    lcd.print(":");
    if(minute<10)
    {
      lcd.print("0");
    lcd.print(minute);
    }
    else
    lcd.print(minute);
    lcd.print(":");
    if(sec<10)
    {
    lcd.print("0");  
    lcd.print(sec);
    }
    else
    lcd.print(sec);
    lcd.print(" ");

    if (digitalRead(b_h) == LOW)
    {
      hour++;
      if (hour > 23)
        hour = 0;
    }

    if (digitalRead(b_m) == LOW)
    {
      minute++;
      if (minute > 59)
        minute = 0;
    }

  }

  //Start the clock
  while (startstop == true)
  {


    // noInterrupts();
    // read with raw sample data.
    byte temperature = 0;
    byte humidity = 0;
    byte data = {0};
    if (dht11.read(pinDHT11, &temperature, &humidity, data)) {
      lcd.setCursor(0, 1);
      lcd.print("Read DHT11 failed");
      return;
    }
    lcd.setCursor(0, 1);
    lcd.print("Temp:");
    lcd.print((int)temperature);
    //lcd.print("*C");
    lcd.print(" ");
    lcd.print("Hum.:");
    lcd.print((int)humidity);
    lcd.print("%");
    //Serial.print((int)temperature); Serial.print(" *C, ");
    // Serial.print((int)humidity); Serial.println(" %");

    lcd.setCursor(0, 0);
    //sec=millis()/1000;
    delay(1000);
    lcd.print("Time: ");
    if (hour < 10)
    {
      lcd.print("0");
      lcd.print(hour);
    }
    else
    {
      lcd.print(hour);
    }
    lcd.print(":");
    if (minute < 10)
    {
      lcd.print("0");
      lcd.print(minute);
    }
    else
    {
      lcd.print(minute);

    } lcd.print(":");
    if (sec < 10)
    {
      lcd.print("0");
      lcd.print(sec);
    }
    else
    {
      lcd.print(sec);
    }
    lcd.print(" ");
    //lcd.print(startstop);
    sec++;
    if (sec > 59)
    {
      minute++;
      sec = 0;
      //lcd.clear();
    }

    if (minute > 59)
    {
      hour++;
      minute = 0;
      //lcd.clear();
    }
    if (hour > 23)
    {
      hour = 0;
      //lcd.clear();

    }
  }
}

//Start/Stop the clock
void buttons()
{
  lcd.clear();
  startstop = !startstop;
}

На этом пока всё. Мы постарались описать все основные варианты реализации часов на Ардуино.

Код для получения времени GPS из строки $ GPRMC

$GPRMC,182306,A,1523.82,N,00022.24,W,173.8,231.8,110120,004.2,W*70

1 $GPRMC,182306,A,1523.82,N,00022.24,W,173.8,231.8,110120,004.2,W*70

В строке выше буква рядом с $ GPRMC представляет всемирное координированное время (UTC)) (« ччммсс .ss »).

Затем буква рядом с номером UTC указывает статус данных.

  • «А» означает, что вы получаете сигнал и что все работает правильно.
  • Буква «V» означает, что ваш GPS-навигатор не подключен ни к одному спутнику.

Эти две цифры после буквы «А» означают широту и долготу.

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

Идентификатор Описание
220516 Время в формате часов, минут, секунд и миллисекунд . ( Hms) 18-23-06
А Статус // A = Активно и V = Нет сигнала
Широта Широта 15 град. 23,82 мин. север
N Направление N = север, S = юг
Долгота Долгота 2 2,24 мин. Запад
W Направление E = Восток, W = Запад
Скорость 173,8 скорость в узлах
Угол 231,8
Дата ДАТА по всемирному координированному времени — 01.11.20
MV Магнитная вариация
W Направление изменения E / W

Мы думаем, что этой информации о приведенной выше строке NMEA достаточно для работы над нашим проектом. Если вы хотите узнать больше об этом формате, перейдите по этой ссылке.

Внедрение агента в банду

Теперь либы собираются, настал черед вкрутить их в код проекта. Как удостовериться, что оно заработало? Элементарно: создаем экземпляр класса OneWire, затем DallasTemperature с параметром шины, на которую подключены термодатчики, и начинаем все это активно использовать.

В проекте уже есть простенький терминал, добавляй туда команду, по которой будет производиться опрос термодатчика и вывод значения в терминал. Для удобства я добавил еще одну команду — поиск термодатчиков, по этой команде опрашивается линия, ответившие термодатчики заносятся в «кеш» библиотеки, после чего для найденных термодатчиков можно получить адреса и вывести их в терминал. Отмечу отдельно алгоритм поиска устройств на линии, очень увлекательный процесс, описан подробно в документации к iButton в разделе Network Capabilities.

Arduino часы с датчиком температуры и без RTSПервый запуск 

Модули часов реального времени в проектах Arduino

Модуль часов представляет собой небольшую плату, содержащей, как правило, одну из микросхем DS1307, DS1302, DS3231.Кроме этого, на плате практически можно найти механизм установки батарейки питания. Такие платы часто  применяется для учета времени, даты, дня недели и других хронометрических параметров. Модули работают от автономного питания – батареек, аккумуляторов, и продолжают проводить отсчет, даже если на Ардуино отключилось питание. Наиболее распространенными моделями часов являются DS1302, DS1307, DS3231. Они основаны на подключаемом к Arduino модуле RTC (часы реального времени).

Часы ведут отсчет в единицах, которые удобны обычному человеку – минуты, часы, дни недели и другие, в отличие от обычных счетчиков и тактовых генераторов, которые считывают «тики». В Ардуино имеется специальная функция millis(), которая также может считывать различные временные интервалы. Но основным недостатком этой функции является сбрасывание в ноль при включении таймера. С ее помощью можно считать только время, установить дату или день недели невозможно. Для решения этой проблемы и используются модули часов реального времени.

Электронная схема включает в себя микросхему, источник питания, кварцевый резонатор и резисторы. Кварцевый резонатор работает на частоте 32768 Гц, которая является удобной для обычного двоичного счетчика. В схеме DS3231 имеется встроенный кварц и термостабилизация, которые позволяют получить значения высокой точности.

Схема на датчике DHT11

Выбор этого средства измерения температуры/влажности обусловлен его популярностью, дешевизной и надежностью — такой набор характеристик делает датчик отличным вариантом для домашнего проекта. DHT11 состоит из:

  • определяющего влажность резистора;
  • измеряющего температуру термистора.

Информация с выходов датчика идет на контроллер, в нашем случае это Ардуино.

Сенсор имеет следующие характеристики:

  • рабочее напряжение — 3–5 В;
  • питание — от источника в 2.5 мА;
  • диапазон измерения влажности окружающей среды — 20–80% с погрешностью в 5%;
  • диапазон измеряемых температур — 0–50 °С с погрешностью в 2%;
  • частота измерений — раз в секунду;
  • габариты — 15 на 15.15 на 5.5 мм.
Популярные статьи  Универсальный удлинитель рожковых ключей своими руками

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

  • DATA;
  • VCC;
  • GND.

В продаже встречаются и датчики DHT11 по отдельности, и в составе готового модуля. Рекомендуется найти последний вариант — он удобнее

В разных модулях внешний вид и конфигурация выходов могут различаться, но принцип везде одинаков, следует лишь обращать внимание на распиновку

Методика взаимодействия

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

Связь происходит по следующему принципу:

  • микроконтроллер отправляет сенсору запрос проверки состояния;
  • DHT11 меняет битовую кодировку и отдает на Arduino результат;
  • если формат запроса-ответа согласован с обеих сторон, на управляющую плату поступает пятибайтовый отчет о влажности и температуре.

Состав отчета:

  • первые два байта — уровень температуры;
  • вторые два — влажность;
  • пятый байт — нужная для предотвращения ошибки измерений и передачи контрольная сумма.

Программная часть

Чтобы собранная метеостанция на базе Ардуино заработала, понадобится подходящий скетч.

Скетч можно скачать здесь: https://cloud.mail.ru/public/JDX7/HJ94PKwoe

Принципиальная схема

Так будет выглядеть схема сборки станции:

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

  • тепловой индекс — HiX;
  • температуру воздуха — Т (temperature, в градусах);
  • влажность — H (Humidity, в процентах).

Используется I2C-дисплей 1602.

Недостатки

Приведенная конструкция имеет один минус — при взаимодействии с экраном цифры округляются до целых. Для домашних вычислений это некритично, но при необходимости получить более точные величины придется заменить датчик на более продвинутый DHT22. Его поддержка в скетче есть по умолчанию.

Теперь рассмотрим образец метеостанции под Ардуино на основе DHT22 и с дополнительной функцией — измерением давления.

Принципиальные схемы

Передатчик

Arduino часы с датчиком температуры и без RTSПередающая часть беспроводного термометра на ATMega328p
(для увеличения масштаба можно кликнуть по картинке правой кнопкой мыши и выбрать «Открыть ссылку/изображение в новой вкладке/новом окне»)

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

Приемник

Arduino часы с датчиком температуры и без RTSПриемная часть беспроводного термометра на Arduino Mega
(для увеличения масштаба можно кликнуть по картинке правой кнопкой мыши и выбрать «Открыть ссылку/изображение в новой вкладке/новом окне»)

Пожалуйста, обратите внимание, что приемник построен на базе платы Arduino Mega, которая не изображена на схеме. Для подключения платы Arduino Mega соедините с ней радиочастотный модуль и LCD дисплей согласно метка на схеме

DS18B20

DS18B20  — цифровой дтчик температуры работающий по протоколу 1-Wire. Это означает, что для связи с Arduino требуется только одна линия данных (и GND).

Каждый датчик температуры DS18B20 имеет уникальный 64-битный серийный код. Это позволяет подключить несколько датчиков к одному проводу передачи данных. Таким образом, вы можете получать температуру от нескольких датчиков, используя всего один цифровой вывод Arduino.

Ниже приведены наиболее важные характеристики датчика температуры DS18B20:

  • Протокол связи:  1-Wire
  • Диапазон питания:  от 3,0 до 5,5 В
  • Диапазон рабочих температур:  от -55ºC до + 125ºC
  • Точность:  +/- 0,5 ºC (в диапазоне от -10ºC до 85ºC)
  • Библиотеки  Arduino:   DallasTemperature, OneWire

Тестер транзисторов / ESR-метр / генератор
Многофункциональный прибор для проверки транзисторов, диодов, тиристоров…

Подробнее

Часы с выводом на экран Nokia 5110

Следующий урок — часы на Arduino, которые также простые для сборки, где вы сможете установить дату и время на последовательном мониторе.

В этом уроке используются лишь несколько компонентов — только перемычки, Arduino и дисплей Nokia 5110/3110.

Arduino часы с датчиком температуры и без RTS

Комплектующие

Детали, используемые в этом проекте ниже.

Оборудование

  • Arduino UNO и Genuino UNO × 1
  • Adafruit дисплей Nokia 5110 × 1
  • Соединительные провода (универсальные) × 1
  • Резистор 221 Ом × 1

Программное обеспечение

Схема соединения

Arduino часы с датчиком температуры и без RTS

Соединяем детали часов на Ардуино как на схеме выше:

  • контакт pin 3 — последовательный тактовый выход (SCLK) // pin 3 — Serial clock out (SCLK)
  • контакт pin 4 — выход серийных данных (DIN) // pin 4 — Serial date out (DIN)
  • контакт pin 5 — дата / выбор команды (D / C) // pin 5 — date/Command select (D/C)
  • контакт pin 6 — выбор ЖК-чипа (CS / CE) // pin 6 — LCD chip select (CS/CE)
  • контакт pin 7 — сброс ЖК (RST) // pin 7 — LCD reset (RST)

Код урока

Код второй версии часов вы можете скачать или скопировать ниже.

#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>

Adafruit_PCD8544 display = Adafruit_PCD8544(3,4,5,6,7);

int second,minute, hour, day, mounth,year; 
unsigned long UtlTime; 

void setup() 
pinMode(2,OUTPUT);
UtlTime=0;   {   

minute=0;   
hour=0;   
day=0;   
mounth=0;   
year=0;   
Serial.begin(9600);   
  display.begin();
  display.setContrast(50); // Adjust the display contrast
  display.clearDisplay();   //Apaga o buffer e o display
  display.setTextSize(1);  //Seta o tamanho do texto
  display.setTextColor(BLACK); //Seta a cor do texto      
   
display.print(" date e hour ");   
display.setCursor(0,10);   
display.print(" com Arduino");   
display.display();
delay (5000); 

//Configura o minute   
display.clearDisplay();   
display.setCursor(0,0);   
display.print("minute: ");
display.display();
Serial.print("\nin between minute:");  
while(minute==0)   {     
if (Serial.available() > 0)     
{       
minute= Serial.parseInt();     
}   
}   
display.print(minute);   
display.display();
delay(1000); 

//Configura a hour   
display.clearDisplay();   
display.setCursor(0,0);   
display.print("hour: ");   
display.display();
Serial.print("\nin between hour:"); 
while(hour==0)   
{     
if (Serial.available() > 0)     
{       
hour= Serial.parseInt();     
}   
}   
display.print(hour);   
display.display();
delay(1000);    

//Configura o day   
display.clearDisplay();   
display.setCursor(0,0);   
display.print("day: ");
display.display();   
Serial.print("\nin between day:");   
while(day==0)   
{     
if (Serial.available() > 0)     
{       
day= Serial.parseInt();     
}   
}   
display.print(day);   
display.display();
delay(1000);    

//Configura o mês   
display.clearDisplay();   
display.setCursor(0,0);   
display.print("mounth: "); 
display.display();  
Serial.print("\nin between mounth:");  
while(mounth==0)   
{     
if (Serial.available() > 0)     
{       
mounth= Serial.parseInt();     
}   
}   
display.print(mounth);  
 display.display();
delay(1000);    

//Configura o year   
display.clearDisplay();   
display.setCursor(0,0);   
display.print("year: ");   
display.display();
Serial.print("\nin between year:");   
while(year==0)   
{     
if (Serial.available() > 0)     
{       
year= Serial.parseInt();     
}   
}   
display.print(year);   

display.display();   
delay(1000);
display.clearDisplay(); 

} 

void loop() 
{   

if(millis()-UtlTime<0)   
{     
UtlTime=millis();   
}   
else   
{     
second=int((millis()-UtlTime)/1000);   
}   
if(second>59)   
{     
second=0;     
minute++;     
UtlTime=millis();     
if(minute>59)     
{       
hour++;       
minute=0;       
if(hour>23)       
{         
day++;         
hour=0;         
if(mounth==1||mounth==3||mounth==5||mounth==7||mounth==8||mounth==10||mounth==12)         
{           
if(day>31)           
{             
day=1;             
mounth++;             
if(mounth>12)             
{               
year++;               
mounth=1;             
}           
}         
}         
else if(mounth==2)         
{           
if(year%400==0)           
{             
if(day>29)             
{               
day=1;               
mounth++;             
}           
}           
else if((year%4==0)&&(year%100!=0))           
{             
if(day>29)             
{              
day=1;               
mounth++;             
}           
}           
else           
{             
if(day>28)             
{               
day=1;               
mounth++;             
}           
}         
}         
else         
{           
if(day>30)           
{             
day=1;             
mounth++;           
}         
}       
}     
}   
}    

display.clearDisplay(); 
delay(1000); 
Serial.print(day);   
Serial.print("/");   
Serial.print(mounth);   
Serial.print("/");   
Serial.print(year);   
Serial.println();      

display.setCursor(0,0);   
display.print("date ");   
display.print(day);   
display.print("/");   
display.print(mounth);   
display.print("/");   
display.print(year);

 
display.display();
Serial.print(hour);   
Serial.print(":");   
Serial.print(minute);   
Serial.print(":");   
Serial.print(second);   
Serial.print("\n");   
Serial.println();      

display.setCursor(0,10);   
display.print("hour ");   
display.print(hour);   
display.print(":");   
display.print(minute);   
display.print(":");   
display.print(second); 
display.display();
char tecla;
tecla = Serial.read();
if(tecla=='1'){
digitalWrite(2,LOW);
}
if(tecla=='2'){
  digitalWrite(2, HIGH);
}

}

Оцените статью
Денис Серебряков
Добавить комментарии

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:

Arduino часы с датчиком температуры и без RTS
Письмо в старинном стиле