В этой статье мы продолжим изучение программирования беспроводного LoRa контроллера Yotster Alfa и разберём простой, но очень полезный пример асинхронного LoRa передатчика.
Если вы ещё не знакомы с документацией и руководствами по контроллеру Yotster Alfa, то рекомендуем перед чтением этой статьи сначала ознакомиться с Обзором, Спецификациями и Основами программирования Yotster Alfa по указанным ссылкам.
Асинхронный режим работы
В реальных проектах контроллер должен одновременно обслуживать множество различных подсистем, таких как беспроводная связь, получение информации от датчиков, управление актуаторами и т. д. Поэтому ему нельзя надолго «зацикливаться» на выполнении одной задачи, в этом случае остальные просто «подвиснут» и не будут выполняться.
Ранее рассмотренные нами примеры работы Yotster Alfa использовали т. н. «синхронный» режим, когда задачи, например по посылке LoRa пакетов, выполнялись последовательно одна за другой и пока очередная задача не была выполнена, остальные находились в состоянии ожидания.
Для тестов и задач обучения в этом нет ничего страшного, но в реальных проектах этот режим работы неприемлем — наше устройство просто не будет выполнять свои функции.
Поэтому в реальных проектах на микроконтроллерах используется т. н. асинхронный режим, когда выполнение какой-либо функции не блокирует всю остальную работу микроконтроллера. В этой статье мы подробно разберём этот режим работы и неблокирующую посылку LoRa пакетов.
Немного теории и функция LoRa.endPacket()
Посылка LoRa пакетов — это довольно медленная операция по меркам микроконтроллеров. За время такой посылки микроконтроллер может проделать тысячи операций и приостанавливать свою работу на это время — просто непозволительная роскошь в реальных проектах.
LoRa библиотека содержит функцию посылки пакетов LoRa.endPacket() которая может работать в двух режимах — синхронном и асинхронном. В асинхронном режиме эта функция не ждёт окончания передачи пакета в эфир, а сразу возвращает управление и далее в качестве флага используется функция LoRa.beginPacket() — она возвращает true если передатчик готов к посылке пакета в эфир и false, если нет.
Для включения асинхронной передачи пакетов в эфир функции LoRa.endPacket() нужно передать в качестве параметра true
LoRa.endPacket(true)
Если требуется задействовать обычный (синхронный) режим, то функции LoRa.endPacket() в качестве параметра можно ничего не передавать.
LoRa.endPacket()
Скетч LoRa non-blocking Sender for Yotster Alfa
Теперь давайте рассмотрим работу скетча, реализующего асинхронный режим передачи LoRa пакетов на контроллере Yotster Alfa. Полный текст скетча LoRa non-blocking Sender for Yotster Alfa:
/*
LoRa non-blocking Sender for Yotster Alfa
(based on standard example of LoRa Library)
(c)2020 Electromicro
License: GNU GPL 2.1
A simple example of non-blocking sender LoRa packets.
*/
#include <SPI.h>
#include <LoRa.h>
int counter = 0;
void setup() {
SerialUSB.begin(115200);
while (!SerialUSB) { ;}
SerialUSB.println("Start Alfa LoRa non-blocking Sender");
if (!LoRa.begin(868E6)) {
SerialUSB.println("Starting LoRa failed!");
while(1);
}
}
void loop() {
while (LoRa.beginPacket() == 0) {
SerialUSB.print("waiting for radio ... ");
delay(500);
}
SerialUSB.print("Sending packet non-blocking: ");
SerialUSB.println(counter);
LoRa.beginPacket();
LoRa.print("hello ");
LoRa.print(counter);
LoRa.endPacket(true); // true = async/non-blocking mode
counter++;
}
В начале скетча подключаются библиотеки SPI.h (для работы с SPI) и LoRa.h (для поддержки специфических LoRa функций)
#include <SPI.h> #include <LoRa.h>
и объявляется переменная для подсчёта посланных в эфир пакетов.
int counter = 0;
Затем следует функция setup() в которой инициализируется вывод в Serial, только в случае с Yotster Alfa это не Serial, а SerialUSB.
SerialUSB.begin(115200);
Далее добавляется строка для ожидания готовности инициализации SerialUSB
while (!SerialUSB) { ;}
и выводится надпись о старте скетча.
SerialUSB.println("Start Alfa LoRa non-blocking Sender");
Затем инициализируется LoRa объект на частоте 868 МГц (868E6). В случае возникновения проблем выводится сообщение об ошибке и выполнение программы останавливается.
if (!LoRa.begin(868E6)) {
SerialUSB.println("Starting LoRa failed!");
while(1);
}
Если инициализация LoRa модуля прошла успешно, то выполнение передаётся функции loop(), которая представляет собой бесконечный цикл и непрерывно, по кругу, выполняет содержащийся в ней код.
Функция loop()
Функция loop() реализует всю функциональность нашего скетча: асинхронным образом в эфир посылаются LoRa пакеты. Если посылка пакета ещё не завершена, то выводится сообщение «waiting for radio ... » и ожидается 500 миллисекунд.
void loop() {
while (LoRa.beginPacket() == 0) {
SerialUSB.print("waiting for radio ... ");
delay(500);
}
SerialUSB.print("Sending packet non-blocking: ");
SerialUSB.println(counter);
LoRa.beginPacket();
LoRa.print("hello ");
LoRa.print(counter);
LoRa.endPacket(true); // true = async/non-blocking mode
counter++;
}
Разберём работу функции loop() подробно. В SerialUSB выводится надпись об асинхронной посылке LoRa пакета и далее выводится его номер.
SerialUSB.print("Sending packet non-blocking: ");
SerialUSB.println(counter);
Затем формируется пакет и функция LoRa.endPacket(true) включает асинхронный режим его передачи.
LoRa.beginPacket();
LoRa.print("hello ");
LoRa.print(counter);
LoRa.endPacket(true); // true = async/non-blocking mode
Далее функцией LoRa.beginPacket() проверяется готовность к посылке следующего пакета и, если посылка текущего пакета ещё не завершена, то выводится надпись об ожидании и делается задержка на 500 миллисекунд.
while (LoRa.beginPacket() == 0) {
SerialUSB.print("waiting for radio ... ");
delay(500);
}
Ниже представлен вывод в Serial нашего скетча.

А далее вы можете видеть работу нашего скетча в эфире. Видны периодические посылки LoRa пакетов на частоте 868 МГц с периодичностью в 500 миллисекунд.

Итог
Мы познакомились с важным понятием асинхронной работы микроконтроллеров и подробно разобрали пример реализации неблокирующего кода для посылки LoRa пакетов. Поняв принципы, изложенные в этой статье, вы можете создавать свои интересные и полезные проекты на контроллере Yotster Alfa.
Ссылки по теме
Обзор LoRa контроллера Yotster Alfa
Спецификации и подключение Yotster Alfa
Где купить?
Yotster Alfa в магазине «Electromicro»
Техническая поддержка
Мы внимательно относимся к потребностям наших клиентов и осуществляем техническую поддержку всей выпускаемой продукции. Вы можете написать нам письмо с вашим вопросом или позвонить по телефону и специалист нашей компании проконсультирует вас и поможет решить вашу проблему.
- Емейл для вопросов по нашей продукции: electromicro@bk.ru
- Наш телефон: +7 (495) 997-37-74



