Как поймать сигнал RF передатчика?
- Войдите на сайт для отправки комментариев
Всем доброго дня!
Контекст такой - есть две Ардуино, которые требуется соединить "в одну сторону" с помощью приемника и передатчика на 433МГц.
Не знаю насколько это принципиально, но использую библиотеки VirtualWire и передаю свою структуру данных длиной 6 байт на скорости 4000 б/с.
Если я в loop() без каких либо перерывов на стороне передатчика отправляю данные, а в loop() на стороне приемника их принимаю (тоже без других подпроцессов) - все хорошо, данные передаются (видимо в какие-то моменты циклы приема передачи совпадают).
Но если я нагружаю приемник и прередатчик какой-то логикой, когда между передачей появляются нерегуляргые задержки, а между сеансами приема - другие нерегулярные задержки, циклы практически не совпадают и пакеты не ловятся. Если хотя бы на одной стороне задержки убрать - ловиться нормально. Значит причина в несинхронности сеансов.
Возможно ли на принимающей стороне повесить сигнал приемника на прерывание (свободный пин с прерыванием есть)? Какую библиотеку для работы с приемником использовать (VirtualWire подойдет)?
без вашего скетча сложно что либо советовать, а в общем случае рекомендуется писать без задержек.
Я пишу без задержек, без delay(), если речь про него.
Вся логика висит на программных таймерах. Любая процедура имеет конечное, но ненулевое время и возврат в loop() происходит спустя некоторое заранее неопределенное время (несколько милисекунд), за это время пакет передачи успевает пройти мимо.
Я выложу конечно код за вычетом бизнес-логики, но чем это поможет? Примеры VirtualWire есть.
Наверно надо было в аппартатную ветку писать с вопросами: Есть ли у RF приемников буфер и какой глубины? Может ли сигнал с RF приемника поднимать прерывание?
KoKaiN . вы видимо что-то курите :) В любой нормальной библиотеке для работы RF433 пин приемника висит на прерывании... например в RFSwitch - и ничего не теряется.
Библиотека VirtualWire не сложная, в принципе переписать ее на прерывания (если их там нет - в чем сомневаюсь) - не должно быть проблемой
Я нюхаю а не курю, это же очевидно...
Код приемника следующий, достаточно простой.
Прием идет нормально, когда прием и передача идут в бесконечных циклах без задержек.
От того что я подключаю приемник к пину с прерыванием само прерывание не появиться. Вызов функции обработки приема внутри цикла, как это описывается в примерах на VW - еще не есть прерывание.
#include <VirtualWire.h> #include <EasyTransferVirtualWire.h> byte unique_device_id = 2; // номер устройства EasyTransferVirtualWire ET; struct SEND_DATA_STRUCTURE { byte device_id; // код отправителя byte destination_id; // код полчателя, 0 - все, 1- мастер, 2-слейв 1,.. byte packet_id; // ID пакета byte command; // тип команды управления, 0 - все выключить, 1 - управление анимацией unsigned int data; // передаваемые данные от 0 до 65535 }; SEND_DATA_STRUCTURE mydata; const int receive_pin = 3; //код для приемника volatile unsigned long previousMillis = 0; // момент последнего изменения состояния void setup() { ET.begin(details(mydata)); vw_set_rx_pin(receive_pin); //код приемника vw_setup(4000); // Скорость приёма vw_rx_start(); // Запуск режима приёма mydata.device_id = unique_device_id; mydata.destination_id = 2; mydata.command = 0; mydata.data = 0; Serial.begin(9600); Serial.println("Started."); randomSeed(analogRead(0)); } void loop() { timer_LED_State(); recMyData(); //код приемника } void recMyData() { if (ET.receiveData()) // получили пакет данных, обрабатываем { Serial.print("Got: "); Serial.print("Device ID: "); Serial.print(mydata.device_id); Serial.print(" Destination ID: "); Serial.print(mydata.destination_id); Serial.print(" Packet ID: "); Serial.print(mydata.packet_id); Serial.print(" Command: "); Serial.print(mydata.command); Serial.print(" Data: "); Serial.print(mydata.data); Serial.println(); } } void timer_LED_State() { int interval = 100; unsigned long currentMillis = millis(); // текущее время в миллисекундах if ((currentMillis - previousMillis) > interval) { previousMillis = currentMillis; // сохраняем последний момент, когда менялось состояние светодиода int d = random(100); delay(d); //тут начинаются процессы, которые я заменил задержкой и которые можно/нужно прервать при поступлении нового сигнала с приемника } }да, глянул библиотеки - в явном виде прерывания там не видно, сл-но все не так просто.
Может кто более опытный подскажет.
Не срастется с VW - буду RFSwitch использовать.
Только мне все равно кажется, что надо обработчик приема вешать на прерывание через attachInterrupt(1, recMyData, CHANGE); ???
А на порту сериала зачем такая маленькая скорость?
Не знаю ))
Можно повысить конечно, но взаимодействие с сериалом идет только при успешном приеме пакета, поэтому я считал что это не критично. Проверю
Не знаю ))
Можно повысить конечно, но взаимодействие с сериалом идет только при успешном приеме пакета, поэтому я считал что это не критично. Проверю
Может и не критично, но в работающих устройствах для этой частоты скорость на порту принята 57600