Как поймать сигнал RF передатчика?

KoKaiN
Offline
Зарегистрирован: 15.11.2018

Всем доброго дня!

Контекст такой - есть две Ардуино, которые требуется соединить "в одну сторону" с помощью приемника и передатчика на 433МГц.

Не знаю насколько это принципиально, но использую библиотеки VirtualWire и передаю свою структуру данных длиной 6 байт на скорости 4000 б/с.

Если я в loop() без каких либо перерывов на стороне передатчика отправляю данные, а в loop() на стороне приемника их принимаю (тоже без других подпроцессов) - все хорошо, данные передаются (видимо в какие-то моменты циклы приема передачи совпадают).

Но если я нагружаю приемник и прередатчик какой-то логикой, когда между передачей появляются нерегуляргые задержки, а между сеансами приема - другие нерегулярные задержки, циклы практически не совпадают и пакеты не ловятся. Если хотя бы на одной стороне задержки убрать - ловиться нормально. Значит причина в несинхронности сеансов.

Возможно ли на принимающей стороне повесить сигнал приемника на прерывание (свободный пин с прерыванием есть)? Какую библиотеку для работы с приемником использовать (VirtualWire подойдет)?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

без вашего скетча сложно что либо советовать, а в общем случае рекомендуется писать без задержек.

KoKaiN
Offline
Зарегистрирован: 15.11.2018

Я пишу без задержек, без delay(), если речь про него.

Вся логика висит на программных таймерах. Любая процедура имеет конечное, но ненулевое время и возврат в loop() происходит спустя некоторое заранее неопределенное время (несколько милисекунд), за это время пакет передачи успевает пройти мимо.

Я выложу конечно код за вычетом бизнес-логики, но чем это поможет? Примеры VirtualWire есть.

Наверно надо было в аппартатную ветку писать с вопросами: Есть ли у RF приемников буфер и какой глубины? Может ли сигнал с RF приемника поднимать прерывание?  

b707
Offline
Зарегистрирован: 26.05.2017

KoKaiN . вы видимо что-то курите :) В любой нормальной библиотеке для работы RF433 пин приемника висит на прерывании... например в RFSwitch - и ничего не теряется.

Библиотека VirtualWire не сложная, в принципе переписать ее на прерывания (если их там нет - в чем сомневаюсь) - не должно быть проблемой

KoKaiN
Offline
Зарегистрирован: 15.11.2018

Я нюхаю а не курю, это же очевидно...
Код приемника следующий, достаточно простой.
Прием идет нормально, когда прием и передача идут в бесконечных циклах без задержек.
От того что я подключаю приемник к пину с прерыванием само прерывание не появиться. Вызов функции обработки приема внутри цикла, как это описывается в примерах на 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); //тут начинаются процессы, которые я заменил задержкой и которые можно/нужно прервать при поступлении нового сигнала с приемника
  }
}

 

 

b707
Offline
Зарегистрирован: 26.05.2017

да, глянул библиотеки - в явном виде прерывания там не видно, сл-но все не так просто.

Может кто более опытный подскажет.

KoKaiN
Offline
Зарегистрирован: 15.11.2018

Не срастется с VW - буду RFSwitch использовать.

Только мне все равно кажется, что надо обработчик приема вешать на прерывание через attachInterrupt(1, recMyData, CHANGE);  ???

 
ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

А на порту сериала зачем такая маленькая скорость?

 

KoKaiN
Offline
Зарегистрирован: 15.11.2018

Не знаю ))
Можно повысить конечно, но взаимодействие с сериалом идет только при успешном приеме пакета, поэтому я считал что это не критично. Проверю

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

KoKaiN пишет:

Не знаю ))
Можно повысить конечно, но взаимодействие с сериалом идет только при успешном приеме пакета, поэтому я считал что это не критично. Проверю

Может и не критично, но в работающих устройствах для этой частоты скорость на порту принята 57600