В данной статье мы рассмотрим управление светодиодами по радиоканалу с помощью платы Raspberry Pi и радиочастотных модулей. Аналогично на основе данного проекта вы можете создать пульты дистанционного управления на основе радиочастотных модулей для любых устройств. На нашем сайте мы уже рассматривали следующие аналогичные проекты:
- связь двух микроконтроллеров AVR ATmega8 через радиочастотные модули;
- умная трость для слабовидящих людей на основе Arduino;
- лодка с дистанционным управлением на Arduino и радиочастотных модулях 433 МГц.
Необходимые компоненты
Передающая часть
- Радиочастотный передатчик (ASK Hybrid Transmitter) (купить на AliExpress).
- Микросхема HT12E (купить на AliExpress).
- Кнопка – 4 шт.
- Резистор 750 кОм (купить на AliExpress).
- Батарейка 9 В.
Приемная часть
- Плата Raspberry Pi (купить на AliExpress).
- ЖК дисплей 16x2 (купить на AliExpress).
- Резисторы 1 кОм (5 шт.) и 10 кОм (4 шт.) (купить на AliExpress).
- Резистор 33 кОм (купить на AliExpress).
- Потенциометр 10 кОм (купить на AliExpress).
- Микросхема HT12D (купить на AliExpress).
- Радиочастотный приемник (ASK Hybrid Receiver) (купить на AliExpress).
- Светодиод – 5 шт. (купить на AliExpress).
- Источник питания.
- Макетная плата.
- Соединительные провода.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Радиочастотные модули
В данном проекте мы будем использовать гибридные передатчики и приемники с амплитудной манипуляцией (ASK Hybrid Transmitter and receiver), работающие на частоте 433 МГц. В своем составе они содержат кварцевый генератор для поддержания хорошей стабильности частоты. В нашем проекте нам понадобится всего одна внешняя антенна для этого модуля. Внешний вид данных модулей представлен на следующем рисунке.
Также широко распространены варианты не с 8 контактами у приемника (как на рисунке), а с 4.
Данные модули достаточно дешево стоят, что обусловило их широкое применение в разнообразных устройствах. Для подобных модулей не используется технология передачи данных к компьютеру или микроконтроллеру с помощью последовательного порта связи (UART), поскольку в данном случае сигнал оказывается сильно зашумлен, поэтому общепринятой практикой в этом случае является использование кодера и декодера, которые позволяют защитить сигнал от шумов.
При максимально возможном напряжении питания дальность связи этих радиочастотных модулей составляет примерно 100 метров, при использовании напряжения питания 5 В и простой штыревой антенны длиной 17 см дальность связи с помощью данных модулей составит примерно 50-60 метров.
Технические характеристики радиочастотного передатчика:
- рабочая частота: 433 МГц;
- выходная мощность: 4-16 дБм;
- напряжение питания: 3-12 В постоянного тока.
Назначение контактов (распиновка) модуля передатчика:
1. GND – общий провод (земля).
2. Data In – по этому контакту модуль принимает последовательные данные от кодера (encoder).
3. Vcc – на этот контакт подается питающее напряжение +5 В.
4. Antenna – к этому контакту подключается внешняя антенна.
Технические характеристики радиочастотного приемника:
- чувствительность: -105 дБм;
- промежуточная частота: 1 МГц;
- низкое потребление энергии;
- потребляемый ток: 3,5 мА;
- напряжение питания: 5 В.
Назначение контактов (распиновка) модуля приемника:
1. GND – общий провод (земля).
2. Data In – по этому контакту передаются последовательные данные декодеру.
3. Data In – по этому контакту передаются последовательные данные декодеру.
4. Vcc – на этот контакт подается питающее напряжение +5 В.
5. Vcc – на этот контакт подается питающее напряжение +5 В.
6. GND – общий провод (земля).
7. GND – общий провод (земля).
8. Antenna – к этому контакту подключается внешняя антенна.
Объяснение работы проекта
Принцип работы нашего проекта достаточно прост. В передающей части проекта (фактически это пульт дистанционного управления) мы использовали 4 кнопки для управления 4 светодиодами в приемной части. Когда мы нажимаем одну из этих кнопок, то микросхема кодера (Encoder IC) кодирует этот сигнал и передает его радиочастотному передатчику, который излучает его в окружающее пространство. Модуль приемника принимает этот сигнал и декодирует его с помощью микросхемы декодера HT12D, которая затем передает его в 4-битном режиме плате Raspberry Pi. Плата Raspberry Pi считывает эти биты и выполняет соответствующие задачи (зажигает соответствующий светодиод). При нажатии на любую кнопку зуммер звучит на одну секунду. На ЖК дисплее 16x2 отображаются сообщения ‘ON’ или ‘OFF’, показывающие статус подключенных светодиодов.
В этом проекте мы использовали 4 светодиода для демонстрации возможностей проекта, аналогичным образом вместо светодиодов можно использовать любые другие исполнительные устройства, например, реле или драйверы двигателей. То есть на основе платы Raspberry Pi и данного проекта удаленного управления устройствами по радиоканалу мы можем повторить многие проекты автоматизации дома на основе платы Arduino, которые мы раньше рассматривали на сайте.
Схема проекта
Схема управления светодиодами по радиоканалу с помощью Raspberry Pi представлена на следующем рисунке.
На представленной схеме плата Raspberry Pi управляет ЖК дисплеем, считывает данные, поступающие из радиоканала, и выполняет соответствующие команды по управлению светодиодами. В нашем проекте мы использовали плату Raspberry Pi 3, но любая другая модель платы Raspberry Pi также подойдет.
В приемной части схемы контакты ЖК дисплея rs, en, d4, d5, d6, d7 подключены к контактам ввода/вывода (GPIO) 11, 10, 6, 5, 4, 1 платы Raspberry Pi. Таким образом, ЖК дисплей подключен в 4-битном режиме. Приемник принимает сигнал, переданный радиочастотным передатчиком и передает его на микросхему HT12D, которая декодирует его. Контакты D8, D9, D10, D11 микросхемы HT12D непосредственно подключены к контактам 25, 24, 23 и 22 платы Raspberry Pi. Выходные светодиоды подключены к контактам 26, 27, 28 и 29 платы. Зуммер подключен к контакту GPIO 0 платы.
Схема передатчика содержит микросхему кодера HT12E и 4 кнопки. В микросхемах кодера и декодера все адресные линии замкнуты на землю.
Установка библиотеки wiringPi в Raspberry Pi
Если мы пишем программу для Raspberry Pi на Python, то мы используем в ней команду вида "import RPi.GPIO as IO" для того чтобы иметь возможность работы с контактами ввода/вывода (GPIO Pins). Поскольку в этом проекте мы будем писать программу на языке C, то аналогичным образом нам необходимо подключить библиотеку wiringPi чтобы работать с контактами ввода/вывода (GPIO Pins) на языке C. Эту библиотеку можно установить вводя последовательно команды (одну за другой), приведенные ниже. Вы можете вводить эти команды непосредственно в терминале или с помощью SSH клиента, например, Putty.
sudo apt-get install git-core
sudo apt-get update
sudo apt-get upgrade
git clone git://git.drogon.net/wiringPi
cd wiringPi
git pull origin
cd wiringPi
./build
Проверить правильность установки библиотеки wiringPi можно с помощью следующих команд:
gpio -v
gpio readall
Объяснение программы для Raspberry Pi
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
Первым делом в программе мы подключим необходимые библиотеки, зададим (определим) необходимые контакты и объявим необходимые переменные.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include<wiringPi.h> #include <wiringSerial.h> #include<stdio.h> #include <string.h> #define RS 11 #define EN 10 #define D4 6 #define D5 5 #define D6 4 #define D7 1 #define led1 26 #define led2 27 #define led3 28 #define led4 29 #define buzz 0 #define d1 25 #define d2 24 #define d3 23 #define d4 22 int flag1=0,flag2=0,flag3=0,flag4=0; |
После этого в функции void setup() мы зададим режимы работы используемых контактов и выполним другие необходимые операции.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
void setup() { if (wiringPiSetup () == -1) { clear(); print("Unable to start"); setCursor(0,1); print("wiringPi"); } pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); pinMode(led4, OUTPUT); ... ...... .... ...... |
В коде программы мы будем использовать функцию digitalRead для считывания выходных значений с микросхемы декодера и функцию digitalWrite для управления состоянием подключенных светодиодов.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
.... .... ..... .... while(1) { setCursor(0,0); print("D1 D2 D3 D4"); if(digitalRead(d1)==0) { flag1++; setCursor(0,1); if(flag1%2==1) { print("ON "); digitalWrite(led1,HIGH); } .... .... ..... .... |
Также в коде программы мы будем использовать ряд других функций:
- функция void lcdcmd будет использоваться для передачи команд на ЖК дисплей;
- функция void write будет использоваться для передачи данных на ЖК дисплей;
- функция void clear() будет использоваться для очистки экрана ЖК дисплея;
- функция void setCursor будет использоваться для установки позиции курсора на экране ЖК дисплея;
- функция void print будет использоваться для передачи строки на ЖК дисплей;
- функция void begin будет использоваться для инициализации ЖК дисплея в 4-битном режиме;
- функция void buzzer() будет использоваться для включения сигнала зуммера.
Исходный код программы на C
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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
#include<wiringPi.h> #include <wiringSerial.h> #include<stdio.h> #include <string.h> #define RS 11 #define EN 10 #define D4 6 #define D5 5 #define D6 4 #define D7 1 #define led1 26 #define led2 27 #define led3 28 #define led4 29 #define buzz 0 #define d1 25 #define d2 24 #define d3 23 #define d4 22 int flag1=0,flag2=0,flag3=0,flag4=0; void lcdcmd(unsigned int ch) { int temp=0x80; digitalWrite(D4, temp & ch<<3); digitalWrite(D5, temp & ch<<2); digitalWrite(D6, temp & ch<<1); digitalWrite(D7, temp & ch); digitalWrite(RS, LOW); digitalWrite(EN, HIGH); delay(10); digitalWrite(EN, LOW); digitalWrite(D4, temp & ch<<7); digitalWrite(D5, temp & ch<<6); digitalWrite(D6, temp & ch<<5); digitalWrite(D7, temp & ch<<4); digitalWrite(RS, LOW); digitalWrite(EN, HIGH); delay(10); digitalWrite(EN, LOW); } void write(unsigned int ch) { int temp=0x80; digitalWrite(D4, temp & ch<<3); digitalWrite(D5, temp & ch<<2); digitalWrite(D6, temp & ch<<1); digitalWrite(D7, temp & ch); digitalWrite(RS, HIGH); digitalWrite(EN, HIGH); delay(10); digitalWrite(EN, LOW); digitalWrite(D4, temp & ch<<7); digitalWrite(D5, temp & ch<<6); digitalWrite(D6, temp & ch<<5); digitalWrite(D7, temp & ch<<4); digitalWrite(RS, HIGH); digitalWrite(EN, HIGH); delay(10); digitalWrite(EN, LOW); } void clear() { lcdcmd(0x01); } void setCursor(int x, int y) { int set=0; if(y==0) set=128+x; if(y==1) set=192+x; lcdcmd(set); } void print(char *str) { while(*str) { write(*str); str++; } } void begin(int x, int y) { lcdcmd(0x02); lcdcmd(0x28); lcdcmd(0x06); lcdcmd(0x0e); lcdcmd(0x01); } void buzzer() { digitalWrite(buzz, HIGH); delay(1000); digitalWrite(buzz, LOW); } void setup() { if (wiringPiSetup () == -1) { clear(); print("Unable to start"); setCursor(0,1); print("wiringPi"); } pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); pinMode(led4, OUTPUT); pinMode(buzz, OUTPUT); pinMode(RS, OUTPUT); pinMode(EN, OUTPUT); pinMode(D4, OUTPUT); pinMode(D5, OUTPUT); pinMode(D6, OUTPUT); pinMode(D7, OUTPUT); pinMode(d1, INPUT); pinMode(d2, INPUT); pinMode(d3, INPUT); pinMode(d4, INPUT); digitalWrite(led1, LOW); digitalWrite(led2, LOW); digitalWrite(led3, LOW); digitalWrite(led4, LOW); digitalWrite(buzz, LOW); begin(16,2); } //void loop() void main() { setup(); clear(); print(" RF Module "); setCursor(0,1); print(" Interfacing "); delay(2000); clear(); print("Raspberry Pi"); setCursor(0,1); print("Circuit Digest"); delay(2000); clear(); print("System Ready"); delay(1000); clear(); setCursor(0,1); print("OFF OFF OFF OFF"); while(1) { setCursor(0,0); print("D1 D2 D3 D4"); if(digitalRead(d1)==0) { flag1++; setCursor(0,1); if(flag1%2==1) { print("ON "); digitalWrite(led1,HIGH); } else { print("OFF"); digitalWrite(led1,LOW); } buzzer(); while(digitalRead(d1)==0); } else if(digitalRead(d2)==0) { flag2++; setCursor(4,1); if(flag2%2==1) { print("ON "); digitalWrite(led2,HIGH); } else { print("OFF"); digitalWrite(led2,LOW); } buzzer(); while(digitalRead(d2)==0); } else if(digitalRead(d3)==0) { flag3++; setCursor(8,1); if(flag3%2==1) { print("ON "); digitalWrite(led3,HIGH); } else { print("OFF"); digitalWrite(led3,LOW); } buzzer(); while(digitalRead(d3)==0); } else if(digitalRead(d4)==0) { flag4++; setCursor(12,1); if(flag4%2==1) { print("ON "); digitalWrite(led4,HIGH); } else { print("OFF"); digitalWrite(led4,LOW); } buzzer(); while(digitalRead(d4)==0); } } } |