Создаем беспроводной термометр на Arduino

Добавлено 22 октября 2016 в 16:00

Узнайте, как использовать RF модуль 433 МГц совместно с ATMega328P-PU. В данной статье мы соберем схему из датчика DHT11 и радиочастотного передатчика. А также соберем приемное устройство с радиоприемником 433 МГц и LCD дисплеем.

Что нам потребуется

Введение

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

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

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

Аппаратная часть

Нам необходимы две структурные схемы. Одна для передающего устройства, вторая для приемного.

Передатчик

Передающая часть беспроводного термометра

Нам необходимы:

  • способ прошивки микроконтроллера → ISP;
  • датчик для измерения температуры и влажности → DHT11;
  • микроконтроллер для обработки данных → ATMega32p;
  • способ беспроводной передачи данных → радиочастотный модуль 433 МГц.

Приемник

Приемная часть беспроводного термометра на Arduino

Нам необходимы:

  • способ приема радиосигнала → радиочастотный модуль 433 МГц;
  • способ обработки принятых данных → Arduino Mega;
  • способ отображения температуры и влажности → 16x2 LCD.

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

Передатчик

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

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

Приемник

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

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

Перечень элементов

Передатчик

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

Приемник

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

Программа

Программа передатчика

Сперва рассмотрим программу передающей части:

// Подключаем необходимые библиотеки
#include <VirtualWire.h>
#include <DHT.h>

// Определение
#define dhtPin 4
#define dhtType DHT11
#define txPowerPin 8

// Использование библиотеки DHT
DHT dht(dhtPin, dhtType);

// Переменные
char msg0[3];
char msg1[3];

int tem = 0;
int hum = 0;

// Функция первоначальной настройки - выполняется только один раз при включении
void setup() 
{
  pinMode(txPowerPin, OUTPUT);
  pinMode(txPowerPin, LOW);
  vw_setup(4800);     // Скорость соединения VirtualWire
  vw_set_tx_pin(9);   // Вывод передачи VirtualWire
}

// Функция цикла - выполняется всегда
void loop() 
{
  digitalWrite(txPowerPin, HIGH);  
  hum = dht.readHumidity();               // Переменная хранит влажность
  tem = dht.readTemperature();            // Переменная хранит температуру
  itoa(hum, msg1, 10);                    // Преобразование влажности в массив char
  itoa(tem, msg0, 10);                    // Преобразование температуры в массив char  
  strcat(msg0, msg1);                     // Сложение/объединение двух массивов
  vw_send((uint8_t *)msg0, strlen(msg0)); // Передача сообщения
  vw_wait_tx();                           // Ждем завершения передачи

  digitalWrite(txPowerPin, LOW);
 
  delay(5000);                            // Ждем 5 секунд и повторяем всё снова

}

Для передачи влажности и температуры в одном сообщении я соединяю их вместе. Сначала данные считываются в переменную как целые числа, потом целые числа преобразовываются в массив символов, а затем они соединяются друг с другом. На приемной стороне данные будут разделены на отдельные символы. Делая это, я ограничиваю себя двумя цифрами градусов. Если датчик находится в среде с температурой менее 10°C, я буду получать на дисплее символы мусора. Например, если температура составляет 20°C, а влажность – 45%, то будет передаваться сообщение 2045, и всё хорошо. Если температура равна 9°C, а влажность – 78%, то передастся сообщение 978x, где «x» – случайный символ. Поэтому, если вы будете собирать данный беспроводной термометр, я советую вам изменить программу для передачи правильных данных, когда температура будет меньше 10°C.

Программа приемника

// Подключаем необходимые библиотеки
#include <VirtualWire.h>
#include <LiquidCrystal.h>

// Определение подключение LCD
#define RS 9
#define E 10
#define D4 5
#define D5 6
#define D6 7
#define D7 8

LiquidCrystal lcd(RS, E, D4, D5, D6, D7);

// Отрисовка символа градусов
byte degreesymbol[8] = {
  B01100,
  B10010,
  B10010,
  B01100,
  B00000,
  B00000,
  B00000,
  B00000  
};

// Переменные
int tem = 0;
int i;

// Функция первоначальной настройки - выполняется только один раз при включении
void setup() 
{
  lcd.begin(16,2);                  // Инициализация LCD
  lcd.createChar(1, degreesymbol);  // Создание символа градусов в месте 1
  Serial.begin(9600);               // Для отладки
  vw_setup(4800);                   // Скорость соединения VirtualWire
  vw_rx_start();                    // Готовность для приема
  vw_set_rx_pin(2);                 // Вывод приема VirtualWiore
  lcd.clear();                      // Очистить LCD
}

// Функция цикла - выполняется всегда
void loop() 
{
  uint8_t buf[VW_MAX_MESSAGE_LEN];      // Переменная для хранения принятых данных
  uint8_t buflen = VW_MAX_MESSAGE_LEN;  // Переменная для хранения длины принятых данных
  lcd.setCursor(0,0);  
  lcd.print("Temp: ");
  if (vw_get_message(buf, &buflen))    // Если данные приняты
  {
    for (i=0;i<2;i++)                  // Получить два первых байта
    {
      Serial.write(buf[i]);            // Для отладки
      lcd.write(buf[i]);               // Вывести первые байты на LCD
    }  
    Serial.println();                  // Для отладки
    lcd.write(1);                      // Вывести символ градусов на LCD
    lcd.print(" C"); 
    lcd.setCursor(0,1);
    lcd.print("Hum:  "); 
    for (i=2;i<4;i++)                  // Получаем последние два байта
    {
      Serial.write(buf[i]);            // Отладка
      lcd.write(buf[i]);               // Вывести последние байты на LCD
    }  
    lcd.print("% RH");      
  }
}

Интересный способ использования библиотеки LiquidCrystal – это создание пользовательских символов. С помощью createChar я создал символ градусов. Таким же способом вы можете создать и свои собственные символы. Чтобы создать пользовательский символ или значок, вам необходимо объявить его, как массив из восьми байт, и «нарисовать», какие пиксели будут включены (1 – включен, 0 – выключен).

В функции setup() вы создаете его с помощью createChar. createChar принимает два аргумента: номер позиции для хранения символа и массив байт, в котором определено, какие пиксели будут отображаться. В нашем случае это lcd.createChar(1, degreesymbol). Затем символ выводится на LCD с помощью функции lcd.write.

Заключение

В данной статье я использовал датчик температуры и влажности DHT11. Температура и влажность были преобразованы в массив символов, а затем переданы с помощью передатчика 433 МГц. На приемной стороне массив символов был разделен на пары и выведен на LCD. Для получения символа градусов я использовал функцию createChar библиотеки LiquidCrystal.

Загрузки

Фото и видео

Передатчик

Передающая часть беспроводного термометра на ATMega328p и Arduino
Передающая часть беспроводного термометра на ATMega328p

Приемник

Приемная часть беспроводного термометра на Arduino
Приемная часть беспроводного термометра на Arduino

Видео


На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.


Сообщить об ошибке