В этой статье мы продолжим изучение программирования беспроводного 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