получение пакета данных через прерывание
- Войдите на сайт для отправки комментариев
Добрый день, форумчане.
Создал программу, которая выполняет функцию передатчика, используя ШИМ-код. Всего передается 100 бит. При передачи 1 - длительность high - 70 мкс, а LOW - 30 мкс. При передачи 0 - длительность high - 30 мкс, а LOW - 70 мкс.
Создал приемник, который работает через прерывания и определяет длительность (high и low) сигнала между изменениями его уровней. Приемник определяет все поступившие сигналы с длительностью 30 мкс и 70 мкс плюс или минус 0,5 мкс. Однако с постоянной периодичностью через 19, 20 или 21 прерывание длительность увеличивается до 36 или до 76.
С уверенностью могу сказать, что дело не в передатчике. Полагаю, что это может быть связано с обработчиком прерываний, поскольку значительное увеличение длительности сигнала программой определяется практически на каждлом 10 бите. Например 4, 14, 24 и т.д. В приемнике длительность сигнала определяется с помощью счетчика таймера, которому после каждого считывания присваивается 0. Подскажите, уважаемые гуру, где копать, чтобы решить эту проблемку. Просто не хочется в программе использовать слишком большой интервал для сравнения.
rekrut007, велосипед изобретаете? На самом деле очень полезно, приходит опыт :) Я делал нечто подобное, и сталкивался с аналогичной проблемой. Просто увеличил вренменные рамки с запасом, и всё ок. Причина может быть в таймере0, который строчит прерывания каждые 4uS, разумеется периодически прерывания находят друг на друга, и выстраивается очередь. Ну или отключить таймер0.. со всеми вытекающими.
А если я отключу таймер 0, то кроме delay, что еще перестанет работать?
rekrut007, Serial, millis() micros(), pulsein(), и в многочисленных библиотеках "скрытно" используется ардуиновский delay. Любая библа с такой функции уйдёт в вечное ожидание. В общем не весело будет))
dimax, спасибо. А если на момент считывания поступающих данных таймер0 отключать, а потом восстонавливать в исходное состояние? А то для обработки сигнала с частотой 10 КГц расширенные временные рамки при такой ситуации не критичны. А вот если в 1 бит ШИМ-кода вложить 4 бита данных с минимальной дельтой 5 мкс, то это уже критично.
rekrut007, попробуйте. В любом случае нужно узнать точно -он гадит или нет.
Конечно попробую. Только у меня прога сейчас перестала скетчи в мегу загружать. Пишет неверный дескриптор. На com-порту плата определяется норм, а вот на usb драйвера из соответствующей папки не устанавливаются. Наверное устала от моих экспериментов. Теперь надо косяк устранить, а потом продолжить опыты.
dimax, если я правильно понял из Вашего поста 1, то Вы тоже делали протокол передачи данных по двум проводам (данные и земля). Стоит ли овчинка выделки, если такой протокол сравнить с иными, имеющимися в библах, которые используют в передаче данных через радиомодули с одним входом/выходом для данных? Какие есть подводные камни при создании такого протокола?
rekrut007, я раза 3 писал нечто подобное, но у каждого раза была какая то своя необходимость, т.к. не было точных аналогов того, что было нужно. Вот например, нужно было как можно компактнее, ничего готового не нашёл. Но это всё были простые протоколы. Для радиомодулей без аппаратной коррекции ошибок (я про копеечные 433мгц) есть готовые решения с поддержкой коррекции ошибок, типа библы VirtualWire, и самому такое совсем не просто написать.
Добавил в свой приемник функцию отключения таймера0 при приеме пакета данных. Ничего не поменялось. Все также каждые 19-21 прерывание плюс 6 мкс. При этом для отладки вставил вывод в сериал данных о выключении таймера0 и его включении. Секунд 10 думал, почему не выводится надпись, что таймер0 отключен, а о включении таймера надпись выводится. Думал, что функция attachInterrupt где-то фокус выдает, перешел на управление прерыванием через регистры. Тоже самое.
rekrut007, а передатчик что, вне подозрений? Там тоже нужно отключить всё лишнее.
Мне кажется, в нем и так все просто. На всякий случай выкладываю его часть.
Тем более увеличение длительности происходит не на одних и тех же битах в каждом принятом пакете. Может есть какой-нибудь счетчик прерываний, который при достижении определенного результата, что-то делает?
rekrut007, я посмотрел ваш фрагмент, не вижу никаких причин для того, что б таймер0 не сбивал длительности посылок. В МК единственный вариант сделать полную независимость длины импульса -это сделать на таймере. Что б он поднял свою аппаратную ногу, отсчитал нужное количество времени, и опустил свою ногу. Тем более у вас их в меге полно, зачем простаивать хорошей вещи? У меня есть небольшой набросок для уно. Предлагаю ознакомится. Правда подходящего режима в таймере нет, пришлось немного схитрить. Из функции посылается команда включения таймера и длительность работы. После получания команды таймер поднимает ногу в лог.1, отсчитывает столько времени, сколько запросили, потом делает прерывание и опускает ногу. В прерывании таймер сам себя отключает. В данном варианте плавать будет только длина паузы, но и её при желании можно переделать на таймер, и пауза тоже станет железной. Сам скетч:
Получается вот такая картинка на выходе:
ширина паузы между импульсами гуляет 105-111мкс, ширина импульсов стоит железобетонно.
dimax, спасибо. Вышеописанную проблему я обнаружил, когда в приемнике вместо использования функции micros () стал использовать таймер/счетчик. До этого я не знал с какой стороны к таймеру подходить. Пока изучил про режим счетчика без сравнений и прерываний. По этому в передатчике использовал задержку. Но планирую в будущем использовать таймер. А так программу передатчика планирую использовать в дешевых беспроводных датчика на меге-328(88), поскольку это самый экономичный вариант.
dimax, еще раз огромное спасибо за подсказку в отношении передатчика. Проблема была в нём. Скорее всего какие-то внутренние прерывания. Решил проблему глобальным запретом всех прерываний перед самой отправкой данных и их последующим разрешением. Приемник показывает разброс от -0,25 uS до 0,75 uS. Считаю такую дельту положительным моментом. Теперь буду дальше работать над протоколом. В протоколе имеется, т.к. называемая контрольная сумма, которая равняется общему количеству единиц во всех передаваемых данных. Есть ли смысл, добавить бит четности к каждому передаваемому байту?
rekrut007, да дельта очень хорошая получилась для вашего метода генерации импульсов. По поводу битов чётности итп конечно нужно максимально накрутить коррецию, если вы собираетесь этот протокол дла радиопередачи применять. Но я бы взял готовую либу :)
dimax, как говорится, мы не ищем легких путей. Заодно немного учимся. Закончатся китайские праздники, закажу на ali пару комплектов модулей фирмы NiceRF для своих поделок. Пока будут лететь, буду доводить до ума протокол. Хочу адаптировать приемник для esp-12 и arduino due. Вы не пытались для данных плат адаптировать скетчи по работе с таймерами?