Перевод VirtualWire на второй таймер в Uno/Nano/etc.
- Войдите на сайт для отправки комментариев
Недавно, по просьбе одного из коллег, переводил библиотеку 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, который можно использовать с этой константой.