Бесспорно заслуженный и замечательный дуэт харда с софтом. Однако, есть одна маленькая тонкость, которую необходимо знать и учитывать. Вот всем известный пример кода ресивера: Код (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; Я убил несколько часов чтобы найти причину глюков и исправить ситуацию. И теперь делюсь опытом со всеми желающими.
Это документированная особенность -- есть информация на сайте, а так же в комментарии в исходном коде к функции "vw_get_message". Другое дело, что функция реализована не шаблонно. Обычно функции принимают размер буфера на вход, а возвращают количество принятых данных. А авторы библиотеки решили немного поизвращаться.
Я убил кучу времени, чтобы найти где об этом сказано авторами раелизации или хотя бы пользователями, но так и не нашел. Пришлось рыться в библиотеке и проводить собственные изыскания. Не пойму зачем такой геморой изобрели, если так проще было сделать без него.
Здесь, я полностью с Вами согласен -- авторы отошли от принятого шаблона проектирования, что стало причиной траты драгоценного времени при использовании их библиотеки. Может пользуемся разными сайтами. Источники, которыми я пользуюсь: 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" длина буфера передаётся не прямо, а по ссылке, т.е. адрес переменной, где храниться длина буфера. Обычно таким образом передают переменные, если предполагается, что их значение будет меняться каким-либо образом внутри функции и эти изменения должны быть "видны" снаружи функции.