Рано или поздно, в создаваемых проектах Arduino появится необходимость дистанционного управления. Одним из самых бюджетных решений является использование радиоприемника и радиопередатчика, такими являются WL101-341 и WL102-341. Подключаются WL101-341 и WL102-341 к Arduino очень просто, библиотеки уже существуют (к примеру RadioHead), так что не составит большого труда обмениваться данными между ардуинками. Простейший пример их использования вы найдете в данной статье, а дальше все зависит только от ваших нужд и фантазии.
- 1 Установка библиотеки RadioHead
- 2 Описание методов класса RH_ASK
- 2.1 RH_ASK ()
- 2.2 virtual bool init()
- 2.3 virtual bool available()
- 2.4 virtual bool recv (uint8_t *buf, uint8_t *len)
- 2.5 virtual bool send(const uint8_t *data, uint8_t len)
- 2.6 virtual uint8_t maxMessageLength()
- 2.7 void setModeIdle()
- 2.8 void setModeRx()
- 2.9 void setModeTx()
- 2.10 void handleTimerInterrupt()
- 2.11 uint16_t speed()
- 3 Подключение WL101-341 и WL102-341 к Arduino
- 4 Пример передачи данных рандомной длины
- 5 Материалы
- 6 Похожие записи
Установка библиотеки RadioHead
RadioHead Packet Radio — это библиотека для встроенных микропроцессоров. RadioHead предоставляет полную объектно-ориентированную библиотеку для отправки и получения пакетированных сообщений через различные распространенные радиопередачи данных и другие виды транспорта на ряде встроенных микропроцессоров/микроконтроллеров. Установить библиотеки можно следующим образом:
- Скачиваем библиотеку с сайта RadioHead, на данный момент последняя версия: RadioHead-1.89.zip;

- Распаковываем архив в
\Documents\Arduino\libraries;

- Библиотека установлена.
Описание методов класса RH_ASK
Для работы с данными радиомодулями будет использован класс RH_ASK. RH_ASK работает с рядом недорогих РЧ трансиверов ASK (амплитудная манипуляция), таких как RX-B1 (также известный как ST-RX04-ASK); Передатчик TX-C1 и приемопередатчик DR3100; Приемопередатчик FS1000A / XY-MK-5V; HopeRF RFM83C / RFM85. Поддерживает ASK (OOK).
RH_ASK ()
Конструктор. В настоящее время поддерживается только один экземпляр RH_ASK на скетч.
RH_ASK::RH_ASK (uint16_t speed = 2000, uint8_t rxPin = 11, uint8_t txPin = 12, uint8_t pttPin = 10, bool pttInverted = false )
Параметры:
speed — Желаемая скорость в битах в секунду
rxPin — Пин, который используется для получения данных от приемника
txPin — Пин, который используется для отправки данных на передатчик
pttPin — Пин, который подключен к EN передатчика. Будет установлено ВЫСОКОЕ состояние, чтобы включить передатчик (по умолчания pttInverted = true).
pttInverted — true, если вы хотите, чтобы pttin был инвертирован, чтобы НИСКОЕ состояние включило передатчик.
virtual bool init()
Инициализирует драйвер. Убедитесь, что драйвер настроен правильно перед вызовом init().
bool RH_ASK::init()
Возвращает:
истина, если инициализация прошла успешно.
virtual bool available()
Проверяет, доступно ли новое сообщение из драйвера. Также переводит драйвер в режим RHModeRx до тех пор, пока сообщение не будет фактически получено транспортом, когда оно будет возвращено в RHModeIdle. Это может быть вызвано несколько раз в цикле ожидания.
bool RH_ASK::available()
Возвращает:
true, если новое, полное, безошибочное несобранное сообщение доступно для извлечения с помощью recv().
virtual bool recv (uint8_t *buf, uint8_t *len)
Включает приемник, если он еще не включен. Если доступно допустимое сообщение, копирует его в buf и возвращает true, иначе возвращает false. Если сообщение копируется, *len устанавливается длина (Внимание, сообщения 0 длины разрешены). Вы должны вызывать эту функцию достаточно часто, чтобы не пропустить ни одного сообщения. Рекомендуется вызывать ее в основном цикле.
bool RH_ASK::recv(uint8_t * buf, uint8_t * len)
Параметры:
buf — место для копирования полученного сообщения
len — указатель на доступное пространство в буфере. Устанавливает фактическое количество скопированных октетов.
Возвращает:
true, если действительное сообщение было скопировано в buf.
virtual bool send(const uint8_t *data, uint8_t len)
Ожидание завершения передачи любого предыдущего передаваемого пакета с помощью waitPacketSent(). Затем загружает сообщение в передатчик и запускает передатчик. Обратите внимание, что длина сообщения 0 НЕ допускается.
bool RH_ASK::send(const uint8_t * data, uint8_t len)
Параметры:
data — массив данных для отправки
len — Количество байтов данных для отправки (> 0)
Возвращает:
истина, если длина сообщения была правильной, и оно была правильно поставлена в очередь для передачи
virtual uint8_t maxMessageLength()
Возвращает максимальную длину сообщения, доступную в этом драйвере.
uint8_t RH_ASK::maxMessageLength()
Возвращает:
Максимальная допустимая длина сообщения
void setModeIdle()
Если текущий режим — Rx или Tx, он переключается в режим ожидания. Если передатчик или приемник работает, отключает их.
void INTERRUPT_ATTR RH_ASK::setModeIdle()
void setModeRx()
Если текущий режим Tx или Idle, изменяет его на Rx. Запускает приемник в RF69.
void RH_ASK::setModeRx()
void setModeTx()
Если текущий режим Rx или Idle, изменяет его на Rx. F Запускает передатчик в RF69.
void RH_ASK::setModeTx()
void handleTimerInterrupt()
не вызывайте этот метод, он используется обработчиком прерываний
uint16_t speed()
Возвращает текущую скорость в битах в секунду.
uint16_t RH_ASK::speed()
Возвращает:
Текущая скорость в битах в секунду
Подключение WL101-341 и WL102-341 к Arduino
Схема подключения WL101-341 к Arduino
| Arduino | WL101-341 |
|---|---|
| 3.3В | Vin |
| GND | GND |
| 11 | DO |
Пример скетча для приёмника
Приёмник будет получать числа от 0 до 255 по нарастающей. Если ожидаемое число получено не будет, тогда выводим в терминал ‘*’.
/*
Добавляем необходимые библиотеки
*/
#include <RH_ASK.h>
#define SPEED (uint16_t)1200
#define RX_PIN (uint8_t)11
#define TX_PIN (uint8_t)12
#define PTT_PIN (uint8_t)10
#define PTT_INVERTED false
/*
Создаём экземпляр класса RH_ASK приёмника
*/
RH_ASK driver(SPEED, RX_PIN, TX_PIN, PTT_PIN, PTT_INVERTED);
void setup() {
/*
задаем скорость общения с компьютером
*/
Serial.begin(115200);
/*
Инициализируем приёмник
*/
if (! driver.init()) {
Serial.println(F("RF init failed!"));
while (true) {
delay(1);
}
}
/*
Настройка встроенного светодиода
*/
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
static uint8_t estdata;
uint8_t data;
uint8_t buflen = sizeof(data);
/*
Проверяем наличие новых данных
*/
if (driver.recv((uint8_t*)&data, &buflen)) {
/*
Гасим светодиод
*/
digitalWrite(LED_BUILTIN, LOW);
/*
Выводим в терминал '*' если полученные данные не совпадают с ожидаемыми
*/
if (data != estdata) {
Serial.print('*');
}
/*
Выводим в терминал полученные данные
*/
Serial.print("RX: ");
Serial.println(data);
/*
Инкрементируем значение
*/
estdata = data + 1;
/*
Включаем светодиод
*/
digitalWrite(LED_BUILTIN, HIGH);
}
}
Схема подключения WL102-341 к Arduino
Вывод данных WL102-341 не толерантный к 5 вольтам поэтому, если вы используете пятивольтовую arduino, то подать 3.3 вольта можно через резистивный делитель (R1 = 1к, R2 = 2к).
На данном модуле линия EN неактивна, так как на плате установлена перемычка, соединяющая 1-й вывод микросхемы (EN) с линией питания, то есть модуль постоянно работал при подаче питания. Можно отпаять перемычку, чтобы иметь возможность управления передатчиком.

| Arduino | WL102-341 |
|---|---|
| GND | GND / — |
| 3.3В | Vin / + |
| DAT | 12 |
| EN | 10 |
Пример скетча для передатчика
Передатчик будет отправлять числа от 0 до 255 по нарастающей.
/*
Добавляем необходимые библиотеки
*/
#include <RH_ASK.h>
#define SPEED (uint16_t)1200
#define RX_PIN (uint8_t)11
#define TX_PIN (uint8_t)12
#define PTT_PIN (uint8_t)10
#define PTT_INVERTED false
/*
Создаём экземпляр класса RH_ASK передатчика
*/
RH_ASK driver(SPEED, RX_PIN, TX_PIN, PTT_PIN, PTT_INVERTED);
void setup() {
/*
задаем скорость общения с компьютером
*/
Serial.begin(115200);
/*
Инициализируем передатчик
*/
if (!driver.init()) {
Serial.println(F("RF init failed!"));
while (true) {
delay(1);
}
}
/*
Настройка встроенного светодиода
*/
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
static uint8_t data = 0;
/*
Гасим светодиод
*/
digitalWrite(LED_BUILTIN, LOW);
/*
Передаём данные
*/
driver.send((uint8_t*)&data, sizeof(data));
/*
Ждем пока передача будет окончена
*/
driver.waitPacketSent();
/*
Выводим в терминал отправленные данные
*/
Serial.print("TX: ");
Serial.println(data);
/*
Инкрементируем значение
*/
++data;
/*
Включаем светодиод
*/
digitalWrite(LED_BUILTIN, HIGH);
/*
Ждём
*/
delay(100);
}
Результат
Пример передачи данных рандомной длины
Для большего понимания принципа работы библиотеки, создал ещё один пример обмена данными между ардуинками. Передатчик будет отправлять массив данных uint8_t data[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; с интервалом в одну секунду. Количество отправленных байт будет неизвестно, потому что применяется функция random(1, 10). Принимающая сторона принимает эти данные и выводит их и их количество в терминал.
Скетч для передатчика
/*
Добавляем необходимые библиотеки
*/
#include <RH_ASK.h>
#define SPEED (uint16_t)2000
#define RX_PIN (uint8_t)11
#define TX_PIN (uint8_t)12
#define PTT_PIN (uint8_t)10
#define PTT_INVERTED false
/*
Создаём экземпляр класса RH_ASK передатчика
*/
RH_ASK driver(SPEED, RX_PIN, TX_PIN, PTT_PIN, PTT_INVERTED);
void setup() {
/*
задаем скорость общения с компьютером
*/
Serial.begin(115200);
/*
Инициализируем передатчик
*/
if (! driver.init()) {
Serial.println(F("RF init failed!"));
while (true) {
delay(1);
}
}
/*
Настройка встроенного светодиода
*/
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
/*
Буфер данных для отправки
*/
uint8_t data[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
/*
Гасим светодиод
*/
digitalWrite(LED_BUILTIN, LOW);
/*
Передаём массив данных случайной длины (от 1 до 10)
*/
driver.send(data, random(1, 10));
/*
Ждем пока передача будет окончена
*/
driver.waitPacketSent();
/*
Включаем светодиод
*/
digitalWrite(LED_BUILTIN, HIGH);
/*
Ждём секунду
*/
delay(1000);
}
Скетч для приёмника
/*
Добавляем необходимые библиотеки
*/
#include <RH_ASK.h>
#define SPEED (uint16_t)2000
#define RX_PIN (uint8_t)11
#define TX_PIN (uint8_t)12
#define PTT_PIN (uint8_t)10
#define PTT_INVERTED false
/*
Создаём экземпляр класса RH_ASK приёмника
*/
RH_ASK driver(SPEED, RX_PIN, TX_PIN, PTT_PIN, PTT_INVERTED);
void setup() {
/*
задаем скорость общения с компьютером
*/
Serial.begin(115200);
/*
Инициализируем передатчик
*/
if (! driver.init()) {
Serial.println(F("RF init failed!"));
while (true) {
delay(1);
}
}
/*
Настройка встроенного светодиода
*/
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
/*
Буфер полученных данных
*/
uint8_t data[16];
/*
Размер полученных данных
*/
uint8_t buflen = sizeof(data);
uint8_t i;
/*
Проверяем наличие новых данных
*/
if (driver.recv(data, &buflen)) {
/*
Гасим светодиод
*/
digitalWrite(LED_BUILTIN, LOW);
/*
Выводим в терминал полученные данные
*/
Serial.print("Size: ");
Serial.print(buflen);
Serial.println();
Serial.print("Data: ");
for (i = 0; i < buflen; i++) {
Serial.print((char)data[i]);
Serial.print(' ');
}
Serial.println();
/*
Включаем светодиод
*/
digitalWrite(LED_BUILTIN, HIGH);
}
}
Результат
Материалы
WL101-341 и WL102-341 — Обзор супергетеродинного приемника и передатчика
VirtualWire
RadioHead
RF 433 MHz модули SYN115/SYN480R и WL101-341/WL102-341




