Подключение WL101-341 и WL102-341 к Arduino

Рано или поздно, в создаваемых проектах Arduino появится необходимость дистанционного управления. Одним из самых бюджетных решений является использование радиоприемника и радиопередатчика, такими являются WL101-341 и WL102-341. Подключаются WL101-341 и WL102-341 к Arduino очень просто, библиотеки уже существуют (к примеру RadioHead), так что не составит большого труда обмениваться данными между ардуинками. Простейший пример их использования вы найдете в данной статье, а дальше все зависит только от ваших нужд и фантазии.

Установка библиотеки RadioHead

RadioHead Packet Radio — это библиотека для встроенных микропроцессоров. RadioHead предоставляет полную объектно-ориентированную библиотеку для отправки и получения пакетированных сообщений через различные распространенные радиопередачи данных и другие виды транспорта на ряде встроенных микропроцессоров/микроконтроллеров. Установить библиотеки можно следующим образом:

  1. Скачиваем библиотеку с сайта RadioHead, на данный момент последняя версия: RadioHead-1.89.zip;
    Установка библиотеки RadioHead - Скачиваем библиотеку
  2. Распаковываем архив в \Documents\Arduino\libraries;
    Установка библиотеки RadioHead - Распаковываем архив
  3. Библиотека установлена.

Описание методов класса 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

Схема подключения приёмника 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к).

Схема подключения WL102-341 к Arduino

На данном модуле линия EN неактивна, так как на плате установлена перемычка, соединяющая 1-й вывод микросхемы (EN) с линией питания, то есть модуль постоянно работал при подаче питания. Можно отпаять перемычку, чтобы иметь возможность управления передатчиком.
WL102-341 - линия 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);
}

Результат

Отправленные данные:
Подключение WL101-341 к Arduino - Отправленные данные

Полученные данные:
Подключение WL101-341 к Arduino - Полученные данные

Пример передачи данных рандомной длины

Для большего понимания принципа работы библиотеки, создал ещё один пример обмена данными между ардуинками. Передатчик будет отправлять массив данных 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 к Arduino - Полученные рандомных данные

Материалы

WL101-341 и WL102-341 — Обзор супергетеродинного приемника и передатчика
VirtualWire
RadioHead
RF 433 MHz модули SYN115/SYN480R и WL101-341/WL102-341

Похожие записи

Комментарии 191

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *