433МГц & VirtualWire

Тема в разделе "Проводная и беспроводная связь", создана пользователем DrProg, 5 янв 2016.

  1. DrProg

    DrProg Вечный нерд

    Бесспорно заслуженный и замечательный дуэт харда с софтом. Однако, есть одна маленькая тонкость, которую необходимо знать и учитывать.

    Вот всем известный пример кода ресивера:
    Код (C++):
    // receiver.pde
    //
    // Simple example of how to use VirtualWire to receive messages
    // Implements a simplex (one-way) receiver with an Rx-B1 module
    //
    // See VirtualWire.h for detailed API docs
    // Author: Mike McCauley (mikem@airspayce.com)
    // Copyright (C) 2008 Mike McCauley
    // $Id: receiver.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $
    #include <VirtualWire.h>
    void setup()
    {
    Serial.begin(9600); // Debugging only
    Serial.println("setup");
    // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2000); // Bits per sec
    vw_rx_start(); // Start the receiver PLL running
    }
    void loop()
    {
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
    if (vw_get_message(buf, &buflen)) // Non-blocking
    {
    int i;
    digitalWrite(13, true); // Flash a light to show received good message
    // Message with a good checksum received, dump it.
    Serial.print("Got: ");
    for (i = 0; i < buflen; i++)
    {
    Serial.print(buf[i], HEX);
    Serial.print(" ");
    }
    Serial.println("");
    digitalWrite(13, false);
    }
    }
    Работает замечательно в идеальных условиях. То есть в отсутствии помех, незваных источников сигналов и сообщений одинаковой длины.

    Недокументированная особенность заключается в том, что переменная длины буфера, в данном примере buflen при заполнении буфера изменяется на длину принятого сигнала. Например, если изначально буфер был назначен размером в 10 символов, то после приема сигнала из 8 символов в следующий заход цикла будет принято не более 8 символов. Если случайная помеха распознается в виде 1 символа (как чаще всего и бывает), то из цепи символов с этого момента будет приниматься только первый. Если же код составлен таким образом, что символы собираются в строку String, то работа с такой строкой с высокой степенью вероятности приведет к перезагрузке МК.

    Для исправления ситуации, достаточно в начале каждой итерации цикла принудительно устанавливать значение переменной:
    Код (C++):
    buflen = VW_MAX_MESSAGE_LEN;
    Я убил несколько часов чтобы найти причину глюков и исправить ситуацию. И теперь делюсь опытом со всеми желающими.
     
    DetSimen, BGreen, Karabas и ещё 1-му нравится это.
  2. AlexU

    AlexU Гуру

    Это документированная особенность -- есть информация на сайте, а так же в комментарии в исходном коде к функции "vw_get_message".

    Другое дело, что функция реализована не шаблонно. Обычно функции принимают размер буфера на вход, а возвращают количество принятых данных. А авторы библиотеки решили немного поизвращаться.
     
  3. DrProg

    DrProg Вечный нерд

    Я убил кучу времени, чтобы найти где об этом сказано авторами раелизации или хотя бы пользователями, но так и не нашел. Пришлось рыться в библиотеке и проводить собственные изыскания. Не пойму зачем такой геморой изобрели, если так проще было сделать без него.
     
    ИгорьК нравится это.
  4. AlexU

    AlexU Гуру

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

    Может пользуемся разными сайтами.
    Источники, которыми я пользуюсь:
    https://www.pjrc.com/teensy/td_libs_VirtualWire.html
    http://www.airspayce.com/mikem/arduino/VirtualWire/ -- здесь есть ссылка на API (программный интерфейс) http://www.airspayce.com/mikem/arduino/VirtualWire/VirtualWire_8h.html

    Так же на что стоило обратить внимание (может пригодиться в будущем) -- это то, что в функцию "vw_get_message" длина буфера передаётся не прямо, а по ссылке, т.е. адрес переменной, где храниться длина буфера. Обычно таким образом передают переменные, если предполагается, что их значение будет меняться каким-либо образом внутри функции и эти изменения должны быть "видны" снаружи функции.
     
  5. DrProg

    DrProg Вечный нерд

    То и смутило, что параметр передается по ссылке. И не зря, как выяснилось.
     
    ИгорьК нравится это.