Перевод VirtualWire на второй таймер в Uno/Nano/etc.

Нет ответов
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Недавно, по просьбе одного из коллег, переводил библиотеку VirtualWire на второй таймер для 328-го контроллера (Uno, Nano, и т.п.), т.к. первый был занят библиотекой Servo. Вот решил выложить, вдруг кому ещё пригодится.

Вот здесь лежит библиотека VirtualWire2 – это та же самая VirtualWire, но с возможностью сконфигурировать её для работы со вторым таймером вместо первого. Больше я не менял ничего. Вся конфигурация производится путём внесения изменений в файл VirtualWire2_Config.h. В нём определяются (или не определяются) три константы. В остальном это тот же самый VirtualWire_Config.h, который был в изначальной библиотеке VirtualWire.

Константы там, в принципе, прокомментированы, но я здесь прокомментирую их чуть подробнее.

Константа USE_TIMER2

Если эту константу определить (сейчас в моём архиве она определена), то библиотека будет работать с таймером 2, если же её не определять (закомментировать #define USE_TIMER2), то будет работать оригинальная VirtualWire.

Константа FREQUENCY_CHECK_PIN

Можно определить эту константу, задав любой цифровой пин (сейчас в моём архиве задан пин 2, но всё определение закомментировано). Пин будет сконфигурирован на OUTPUT в vw_setup, а после завершения vw_setup, уровень на нём будет меняться на противоположный всякий раз, когда будет срабатывать прерывание таймера. Это бывает нужно, когда что-то идёт не так и хочется убедиться, что по крайней мере таймер, задающий «часы» протокола работает нормально.

В примерах к библиотеке, есть скетч FrequencyCheck, который можно использовать с этой константой.

Константа REPORT_TIMER_PARAMETERS

Если, например, в приёмнике используется оригинальная VirtualWire на первом таймере, а в передатчике VirtualWire2 на втором таймере, скорее всего у таймеров будут разные делители частоты. Это может создать проблему на некоторых скоростях передачи, т.к. частота таймеров может не точно совпасть, а немного отличаться. Поэтому, прежде, чем что-то запускать, необходимо убедиться, что на выбранной скорости такой проблемы нет.

Для этого и служит данная константа. Ей нужно назначить любой объект, который имеет методы print и println (например, Serial, объект типа SofwareSerial, большинство реализаций объектов LCD и т.п.). Например,

#define REPORT_TIMER_PARAMETERS Serial

Повторяю, вместо Serial можно использовать любой объект, имеющий методы print и println, т.к. используется «утиная типизация».

Перед вызовом vw_setup, указанный в данной константе объект необходимо инициализировать, чтобы он был готов к работе (например, вызвать Serial.begin). Тогда во время выполнения vw_setup в поток будет выведена информация о конфигурации таймера: делитель частоты и количество тиков.

Необходимо запустить это на выбранной скорости передачи с обоими таймерами (с определённой и с неопределённой константой USE_TIMER2) и сравнить результаты. Чтобы программы были совместимы необходимо, чтобы произведения делителя на количество тиков были равны!

Например, при скорости 2 кбит/сек (вызов vw_setup(2000);) настройки получаются:

с таймером 1
     Prescaler: 1
     Ticks : 1000

с таймером 2
     Prescaler: 8
     Ticks : 125

Поскольку 8х125 == 1х1000 - на этой скорости программы будут совместимы.

Если же, при выбранной скорости совместимости не получается, необходимо поменять скорость и добиться совместимости.

В примерах к библиотеке, есть скетч FrequencyCheck, который можно использовать с этой константой.