Бано для модели самолета своими руками

Бано для модели самолета своими руками

Подписываемся на VK

Ежедневные новости, видео и приколы.

YouTube канал


Подбор двигателя

Меню сайта

Магазин

TOP статьи

Оборудование

Плосколеты

Создание авиамоделей

  • Фотоинструкции
  • Cessna 150
  • Cessna 152 +закрылки
  • Сам5Бис2
  • «Рама» для FPV
  • Чирок низкоплан
  • Изготовление Crazy Pig
  • Полукопия DHC-2 Beaver
  • Бутербродный Mustang P-51D
  • Katana 3D
  • Ultron 3D
  • Слойка-С
  • Биплан Manon 3D
  • Биплан Ultimate
  • Птиц — мелколет
  • Тренер в 64 см
  • Минипланер
  • Полукопия Як-3
  • Go-Go Dancer для FPV
  • IKAR1600 для FPV
  • Видеоинструкции
  • 3 авиамодели
  • Авиамодель Тренер
  • Messerschmitt Bf.109
  • Летающий Картинг
  • Обзоры изготовления
  • Бутылочная технология
  • Делаем Slow Stick
  • Фламинго верхнеплан
  • Из микромашинки
  • Мультяшная авиамодель
  • Планер из потолочки
  • Снежинка
  • Shark Bait
  • Shark Bait Биплан
  • Слойка 3D
  • Делаем ЛК
  • ЛК Вжик
  • ШокФлаер Як 55
  • GoGo Dancer 1.2м
  • Alula — слопер из потолочки
  • Моторная Алула
  • Питтс Питон
  • Строим полукопию

Всем привет. Решил поделиться с другими авиамоделистами как сделать аэронавигационные огни самому.

Аэронавигационные огни позволяют сделать модель более заметной в небе(как и больших собратьев), также если вы строите копию или полукопию огни добавят эстетики вашей модели.

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

Огни которые мы будем делать не простые, а имеют два режима работы — простое горение и режим стробоскопов, последний настраивается.

Итак начнем! Что нам потребуется:

1.Микроконтроллер ATtiny13A(или ATtiny13) в корпусе SOIC8, можно взять и в обычном DIP корпусе если не будете использовать мою печатную плату.

2.Резисторы SMD номиналом 10К, опять же можно обычные — 2шт.

4.Транзисторы КТ815, или любые другие аналоги NPN структуры, аналогичные по мощности — 2шт. Если планируете использовать обычные светодиоды, а не 1Вт как я можно более слабые транзисторы.

5.Светодиоды, я взял мощные 1Вт красный и зеленый, но вы можете взять и другие, или например включить в параллель штук 7 обычных.

6.Резисторы 5,6Ом 1Вт — 2шт. Очень важно чтобы резисторы были мощные, если будете использовать 1Вт светодиоды.

Для начала надо прошить микроконтроллер, это не составит труда имея программатор(возможно кто то уже прошивал свою Турнигу9), я прошивал с помощью программатора «5 проводов» http://nsskn.narod.ru/tinyprog/ по ссылке все отлично описано, добавлю лишь что я использовал свою плату для программирования(разводка платы в архиве в конце статьи), прошивку микросхемы в SOIC8 корпусе производил с помощью прищепки:

прошивку контроллера, фьюзы и все остальное можно скачать в конце статьи по ссылке.

Принципиальная схема БАНО для модели:

Питание на огни будет идти непосредственно с приемника от BEC-а.

Вид печатной платы(в архиве):

Я делал плату методом ЛУТ и травлением хлорным железом, обращаю внимание — на плате нет места для резисторов R2 и R4, я их разместил снаружи на проводах.

готовая к монтажу плата:

Хотелось бы отметить — на авторство прошивки и устройства не претендую, спасибо САМОКАТ_ВЕТЕРАНА, у которого я подсмотрел идею http://umat.ru/2013/03/05/ledstrob/ и переработал ее под наши авиамодельные нужды убрав все лишнее.

А теперь немного о управлении устройством. С помощью кнопки «mode» можно зажечь или погасить огни, также длительным нажатием огни переводятся в режим стробоскопов и обратно. Далее цитирую автора: » Моргания светодиодов можно настраивать. настраивается три основных параметра: количество вспышек, длительность каждой вспышки и пауза между вспышками первого и второго канала. То есть получается: моргает левый стробоскоп — пауза — моргает правый стробоскоп — пауза и т.д. Вот ширину этой паузы можно настраивать.Чтобы попасть в режим настроек необходимо нажать и удерживать кнопку управления более пяти секунд. После этого поделка входит в режим настройки, сообщая нам морганием двумя каналами одновременно. Одна моргуля — режим настройки количества вспышек, две моргули — режим настройки ширины каждого импульса вспышки, три моргули — настройка ширины паузы, затем опять одна моргуля — выход из настроек. Для перехода к следующему пункту настроек необходимо так же удерживать нажатой кнопку управления более пяти секунд. Чтобы производить саму настройку, на плате есть две кнопки настройки. Первая кнопка увеличивает параметр, вторая — уменьшает. Короче больше-меньше.»

на сайте автора вы сможете найти видео с описанием настройки устройства (ссылка выше)

вес вместе с диодами — 10г

Также прилагаю видео с демонстрацией работы бано:

Архив с схемой, прошивкой, фьюзами и печатной платой можно скачать тут.

От себя добавлю — вы можете повторить данное устройство в любом виде, хоть навесным монтажом, так как деталей совсем немного!

Всем спасибо за внимание, желаю удачных и КРАСИВЫХ полетов.

Источник

Самодельные БАНО

Леха спасибо , у меня с аккумом turnigy nano-tech 1800mAh в ветренную погоду 38минут полет длился,это в спокойном полете, а так на 29-30 минут. Доволен, потаму как раньше на родном ni-cd аккуме. полет был в районе: максимум 10 минут. А тут смнеил двигатель, был 2S аккум ,но на нем, он не взлетел вообще, при такой же компановке двигателя, а вот заказал этот- 3S 1800mAh и полет получился! Только этот Акуум надулся после второй зарядки , пока держит но не знаю на сколько хватит его и вообще не взорвался бы он !

Алексей, с ардуино слышал, но это надо осваивать, сразу так мне не сделать. Спасибо, обязательно попробую.Только, что такое скетч, мосфет, и прочие словечки надо мне познавать. Я сперва хотел сделать как писал тут Евгений из микроконтроллера ATtiny13А- http://rc-aviation.ru/mtech/46-avtech/1460-bano не нашел у нас в городе данного контроллера, и там на 2 светодиода, а как сделать на 5 не знаю. И прошивальщик надо собирать, вообщем не так просто, но попытаться есть желание.

Человек плату микросхемой обзывает, а вы ему про ардуино.

Для автора статьи — Микросхема там конечно присутствует, только она находится (залита) под белым компаундом.

Источник

Бано для модели самолета своими руками

Сегодня достал attiny13v (та что с пониженным напряжением питания). Сегодня попробую в железе воплотить — на макетке.

Re: БАНО своими руками

Давайте-давайте, у меня есть знакомый, который интересуется программированием таких контроллеров.
А я остальное сам спаяю.

«Ветра бояться — в полях не летать!» «Без шасси — не самолет, без нормальной посадки — не летчик!»

Re: БАНО своими руками

Сегодня впервые проверил «в железе».
Действительно работает )
На видео показана работа диода на ноге «маяк».
[url=

Читайте также:  Интерьер мансарды дома своими руками

Пока проверял без фильтрации питания (без стабилитрона и конденсатора).
Попутно возник вопрос с полевым транзистором 2SK1482.
По схеме устройства и по результатам симуляции в Proteus получается что на светодиодах постоянно есть плюс, а тинька включает/отключает землю на светодиоде с помощью полевика (управляя ногой #3 2SK1482).
У меня же получается что на средней ноге (#2 2SK1482) плюс вместо минуса.

Re: БАНО своими руками

Нормально мигает.
По поводу «плюса» и «минуса» — скорее нужно употреблять термины «плюс» и «земля» — потому как питания однополярное все-таки.
А запускается по сигналу от передатчика или пока «так»?
«Средняя нога» — затвор подразумевается, что ли. Если там постоянно «плюс», получается, что транзистор в исходном состоянии открыт, закрывается на время снижения напряжения на затворе. Там случайно не нужно вешать с затвора на землю резистор килоом этак на 100? Чтобы транзистор надежно закрывался. (не знаю, по какой схеме выполнены выходные каскады управления в микропроцессоре)

«Ветра бояться — в полях не летать!» «Без шасси — не самолет, без нормальной посадки — не летчик!»

Re: БАНО своими руками

Да, корректнее будет употреблять «плюс» и «земля».
Почитал более подробно даташиты и про проверку работоспособности полевиков. Прозвонил мультиметром полевики — открываются/закрываются как положено. Выяснилось что я вешал ногу тиньки на «исток», подключал плюс диода на «сток», а затвор был постоянно на «земле». Каким чудом работало — не знаю, но похоже что светодиод я питал все-таки через тиньку. Так что хорошо что одним диодом проверял, а не гирляндой Удивляет что в Proteus указаны номера ног на полевике, подключал согласно этой нумерации и нумерации ног в даташите на 2SK1482 — «исток» с «затвором» перепутались. Судя по даташитам для аналогов и по результатам прозвонки средняя нога (#2) — всегда сток.

Сейчас подключил «затвор» на тиньку, «сток» на земле, «исток» на земле светодиода.
Проверяю мультиметром — нога на тиньке дрыгается как и прежде (если питать светодиод от нее, то мигает как положено), а вот если подключить минус светодиода к истоку, то светодиод горит постоянно.
Видимо, надо допаивать остальную обвязку.

Работает пока без управления со стороны приемника — я со своими опытами без него остаться могу — рановато еще )

Источник

Контроллер светодиодов для авиамодели

Некоторое время назад мне попалась статья о том, как сделать стробы для авиамодели. Вообще-то мне не очень хотелось ввязываться в электронику, но идея поставить разные моргалки на модель меня, почему то, зацепила. Некоторые не видят в этом смысла — лучше облепить модель светодиодными лентами сверху донизу, и красиво и видно издалека. Но мне больше нравятся копийные модели, а значит все лампочки, стробы, фары и другие огни должны включаться и выключаться так же как и у оригинала.

По ряду причин предложеный вариант мне не подошел. В этой статье я описал свой вариант контроллера моргающих и не моргающих светодиодов для авиамодели.

Контроллер сделан на базе ATTiny13A, т.о. статья будет так же полезна тем, кто разбирается с микроконтроллерами AVR. Я старался все разжевать и разложить по полочкам, так что статья будет интересна в первую очередь новичкам.

Способности железяки можно оценить по этому видео:

Вступление

Когда я начал ковырять этот вопрос и даже спаял плату предложеную в той статье, оказалось что это совсем не то, что мне нужно. Во-первых всего два канала, которые могут моргать только по очереди. Можно подрегулировать тайминги, но алгоритм зашит в прошивке. Во-вторых на плате присутствуют аж 3 кнопки, которые добавляют лишние граммы. Я не собираюсь переставлять моргалку с модели на модель и перепрограммировать светодиоды после каждого полета, а значит эти кнопки мне без надобности. Я согласен один раз напаять провода прямо на контроллер и запрограммировать тот алгоритм, который нужен. И наконец в-третьих прошивка есть только в бинарном виде, без исходников, а значит доработать что либо нельзя.

Задумывая очередную модель я сразу прикинул сколько светодиодов мне нужно и как они будут моргать. В результате «переписи» выяснилось, что мне нужно 4 канала (в каждом канале по 2-3 светодиода):

  • БАНО (Бортовые АэроНавигационные Огни — зеленый и красный фонари на концах крыльев) – эти штуки включены всегда
  • Посадочные фары – будут включаться и выключаться с пульта, т.е. схема должна реагировать на PWM сигнал с приемника
  • Стробы — белые огни которые время от времени моргают короткими и яркими вспышками
  • Проблесковые маячки – красные огни, которые включаются и выключаются плавно, напоминая крутящийся ламповый олдскульный проблесковый маяк.

Модель большая, летает далеко. А значит, что бы светодиоды было видно, они должны быть мощными. На предыдущей модели я делал БАНО на одноваттных светодиодах – их прекрасно видно с расстояния в 50м даже в яркий солнечный день вечер. Значит это мой размерчик.

Вот только оказалось что запитать мощные светодиоды не так то просто. На борту имеется только питание от линейного стабилизатора (на плате регулятора двигателя). Это значит подключив туда даже один мощный светодиод (через резистор, разумеется) получим очень большие потери в тепло. Большие настолько, что термоусадка регулятора плавится до дыр. Подробнее с рассчетами тут

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

Электроника

С требованиями разобрались. Пора браться за паяльник.

Я в электронике, в общем то, новичок. А потому я творчески переработал схему от Acinonyx (который в свою очередь позаимствовал ее у САМОКАТ ВЕТЕРАНА). Мне потребовалось изменить следующее:

  • Выкинуть кнопки
  • Завести PWM вход от приемника
  • 3 ноги ATTiny определить как выходы и подключить к ним светодиодные драйверы
  • Добавить четвертый драйвер, который будет всегда включен (для БАНО)

В общем от оригинала мало что осталось.

В качестве драйвера удачно подошла микросхема ZXLD1350 которая как раз и рассчитана на питание одноваттных светодиодов (ток до 350мА). При чем в каждый канал можно ставить последовательно любое светодиодов, лишь бы все вместе суммарно вкладывались в напряжение питания. Т.е. если я буду запитывать схему от батареи 3S (11.1В) то смогу в каждый канал поставить до 3 светодиодов на кажом из которых падает 3.2В.

Микроконтроллер я запитал отдельно от приемника, тем же проводом что и PWM вход.

Схема. Каждый канал построен по схеме из даташита. Таких каналов на плате 4 штуки (я нарисовал только один). Светодиодов я нарисовал 3, но, как я уже сказал, можно ставить любое количество светодиодов в каждый канал. Можно даже ставить светодиоды разного цвета (на них падает разное напряжение), главное что бы они были рассчитаны на одинаковый ток. Драйвер сам подберет такое напряжение, что бы ток через диоды не превышал 350мА.

Читайте также:  Дженга своими руками размеры брусков

Вход ADJ трех из каналов подключен к выходу контроллера через транзистор. У драйвера ZXLD1350 есть специальный механизм с помощью которого можно включать и выключать светодиод с контроллера. Более того, можно плавно регулировать яркость меняя напряжение на входе или с помощью ШИМ. Вот только рабочее напряжение входа от 0.3В до 2.5В, а с контроллера выдает 5В. Благо даташит рекомендует решение в виде транзистора. Нужно только учесть, что этот транзистор инвертирует логическое состояние – ноль на ноге контроллера будет включать светодиод, а единица выключать. Впрочем, это не проблема пофиксить программно.

В целях экономии веса я решил попробовать сделать двухстороннюю плату. Я так и не подружился с ЛУТом, а вот с фоторезистом все вышло с первого раза. Пробовал еще поиграться с паяльной маской, но нарушил технологию и маска легла плохо (а кое где вообще отвалилась). Ошибки учтены на будущее, а эту попытку оставлю как есть. Для первого раза все равно покатит.

Разводка платы. Крестики по краям это стыковочные метки. Я вырезал текстолит немного с запасом, потом в местах крестиков сверлил отверстия по которым потом совмещал маски. Метализацию отверстий не делал, справился перемычками. Ну и ножки конденсатора тоже в качестве перемычки между сторонами работают.

Готовое изделие. Лишний текстолит обрезал по рамочке. Получилась платка 27х22мм и весом 4г. Ну еще 2г на провода и раземы получилось. К приемнику устройство подключается через стандартный трехпиновый JR разъем. Светодиодные драйверы берут питание с балансировочного разъема батарейки.

Кому 1Вт мало может посмотреть на микросхему ZXLD1360. Она рассчитана на питание 3Вт светодиодов (ток 750мА). Схема включения и цоколевка такие же, так что разводка платы подойдет. Только номиналы некоторых деталей поменять нужно, курите даташит.

Для тех, кто не прокачался еще в травлении двухсторонних плат, я так же выкладываю несколько вариантов односторонних – для 2, 3 и 4 каналов.

Светодиоды купил у китайцев на ебее. Покупал специально без радиатора, который не везде влезет. В качестве радиатора использовал кусочки алюминиевой полосы. Светодиод можно крепить с помощью специального термопроводящего скотча или клея. Вот так это выглядит в тестовом варианте (тут радиатор маленький, греется)

А вот так на предыдущей модели.

Прошивка

Теперь нужно вдохнуть жизнь в эту железяку. Поскольку исходников прошивки от САМОКАТ ВЕТЕРАНА в инете не нашлось, то пришлось делать все самому. Нет, я, конечно, дизассемблировал его прошивку, что бы посмотреть что внутри, но гораздо полезнее было просто прочитать спецификацию на ATTiny13.

Несмотря на то, что в микроконтроллере всего 1Кб флеша, я решил писать на С. Так удобнее и нагляднее. Скетчи ардуино, конечно, в чем то попроще будут, но все что я задумал не влезет в память контроллера. Поэтому пришлось спуститься на более низкий уровень и программировать регистры напрямую. К моему удивлению компилятор (gcc 3.4.2 из Atmel Studio 6) сгенерил довольно хороший код. Было, правда, пару мест, где компилятор действовал неоптимально, но эти места удалось скорректировать.

Архитуктурная проблема прошивки в том, что мне требовалось делать несколько концептуально разных действий одновременно – тут моргать, тут не моргать, тут рыбу заворачивать, тут слушать ШИМ вход, тут генерить ШИМ на выходе.

Приведу классический пример. Что если нам нужно моргать одним светодиодом? Ну тогда наша программа будет выглядеть как то так:

А что если нам нужно мигать двумя светодиодами, да еще и с разной частотой? Ну можно, конечно, извратиться и написать чтото типа такого:

Но скорее всего будет очнь сложно подобрать тайминги и последовтельность включений-выключений. Если получится, конечно (в чем я сомневаюсь). А если нужно тремя диодами моргать? А четырьмя?

Правильное решение — использовать таймеры. Но есть проблема: таймер в микроконтроллере всего 1, да и тот восьмибитный.

На самом деле там где есть один таймер можно сделать скольугодно много софтварных таймеров. Выглядит это так: хардварный таймер тикает с большой частотой. На каждое срабатывание таймера обработчик проверяет а не вышло ли заданное время для програмного таймера. Если вышло, то нужно вызвать обработчик.

Давайте посмотрим, как это будет выглядеть в коде.

Програмный таймер — это счетчик сколько раз должен прокрутиться основной (железный) таймер прежде чем вызвать обработчик. Указатель на обработчик прилагается. Для моих задач вполне достаточно трех таких записей, но на всякий случай я сделал список програмных таймеров размером в 5 элементов.

Вопрос настройки микроконтроллерного таймера я опишу чуть позже. А сейчас про реализацию програмных таймеров. Функция инициализации выглядит просто – обнуляем список таймеров

Для того что бы добавить программный таймер просто ищем пустой слот и вписываем в него значения таймаута плюс указатель на обработчик. Проверка на ошибки отсутствует в целях экономии места в контроллере.

Основной цикл выглядит следующим образом.

Вначале запускаем таймер (об этом чуть ниже, там не все так тривиально). Вместо активного ожидания я использую sleep. В начале каждого цикла процессор переходит в режим Idle. Это означает что сам CPU заснет, но все таймеры (ок, весь, он один!) продолжат работать. Когда таймер досчитает до конца и ресетнется в ноль возникнет прерывание, которое разбудит процессор и программа пойдет дальше. Как раз то, что нам нужно.

Да, в светодиодной моргалке много электричества не сэкономишь, но в будущем тот же каркас можно использовать и в других приложениях где засыпание процессора может быть очень кстати.

Если мы проснулись это означает что пора пройтись по списку програмных таймеров. В каждой записи уменьшаем значение счетчика. Если уже дошли до нуля, то вызываем обработчик, после чего удаляем таймер из списка (записав NULL в указатель на обработчик).

Поскольку все происходит в одном потоке, то никаких мьютексов и локов не требуется.

Что бы поморгать светодиодом с фиксированой частотой, обработчик будет выглядеть так: инвертируем состояние светодиода просим систему вызвать этот же обработчик опять через некоторое время.

Что бы это все заработало, нужно чтобы обработчик как-то вызвался в первый раз. Для этого перед запуском основного цикла — просто положим в очередь сообщение, что пора вызвать обработчик с задеркой 0 мс (т.е. сразу при первой же возможности).

Вначале тут настраивается пин на вывод. Напоминаю что светодиоды у нас подключены через инвертор. Значит для того, что бы выключить светодиод по умолчанию нужно записать единицу в порт.

Читайте также:  Асинхронный двигатель с самозапиткой своими руками

Ну моргать туда-сюда это не интересно. Нельзя ли что нибудь покруче? Например блымнуть раз, потом после паузы моргнуть дважды, потом трижды, повторить, взболтать, не размешивать. Ну это тоже не сложно.

Просто делаем таблицу с таймингами. Обработчик каждый раз меняет состояние светодиода и ждет уремя указаное в таблице.

Для того, что бы моргать несколькими светодиодами одновременно и независимо, просто добавляем несколько аналогичных обработчиков, не забыв настроить порт и добавить в список обработчиков.

Разумеется, к такому стилю программирования еще нужно привыкнуть, но в целом подход работает неплохо. Вспомните, если мы пишем многопоточное приложение для большого компа, обычно каждый поток имеет вечный цикл и, возможно, какой нибудь sleep или wait. Считайте, что представленые выше обработчики — это тело того самого вечного цикла, а вызов addTimer() это тот же самый sleep.

Как часто должен тикать основной таймер? Если он будет тикать редко, то это снизит точность отмеряемых временных отрезков. С другой стороны на каждый цикл таймера нужно будет сделать определенное число полезных действий. И эти действия нужно успеть закончить до следующего цикла таймера. Значит таймер тикать должен и не очень часто так же.

Т.е. не часто и не редко. Но как именно? Ок, для предыдущей задачи диапазон возможных значений достаточно большой. Но нужно так же не забывать про задачу «слушать PWM вход». Конкретнее, там ходят импульсы длительностью 800-2200мкс и эту длину нам прийдется измерять. Для нашей задачи включать/выключать светодиод по команде с пульта будем считать так: если импульс короче чем 1500мкс – светодиод выключен, если длинее – включен.

В переводе на язык микроконтроллеров и таймеров мы будем считать сколько тиков таймера уместится в измеряемом отрезке времени. Проблема возникает когда длительность импульса примерно равна пороговой. Тогда возможны ложные срабатывания и светодиод будет промаргивать при изменении длины импульса. Что бы уменьшить вероятность промаргивания нам нужно точнее измерять длину импульса. Я думаю разрешение таймера должно быть в районе 1-2 мкс – такое разрешение обеспечит достаточную точность измерений.

Раз уж речь зашла про конкретные цифры нужно разобраться с частотой микроконтроллера. Контроллер может тактироваться от внутреннего и от внешнего генератора. Внешний генератор точнее, но это дополнительные детали и вес. Да и не нужна нам точность особо. Из внутренних генераторов доступны 128кГц, 4.8МГц и 9.6МГц. 128кГц маловато будет, будем выбирать между двумя другими вариантами.

Таймер в свою очередь может иметь ту же частоту, что и микроконтроллер, а может задействовать делитель частоты на 8, 64, 256 или 1024. Сам же таймер считает от 0 до 255 и потом сбрасывается в 0. В случае если делитель не используется один тик таймера соответствует одному тику процессора, что в большинстве случаев соответствует одной команде. Мы собирались делать полезную работу каждый полный цикл таймера. Но если нам эту работу нужно будет делать каждые 256 команд, то мы попросту не будем успевать делать эту работу (либо ее должно быть очень очень мало).

Итак, нужно выбирать между частотой 4.8МГц и 9.6Мгц, и делителями 8, 64 и 256. Как по мне, вариант 4.8МГц с делителем 8 довольно удачный. Таймер будет тикать с частотой 4.8МГц / 8 = 600кГц. А это означает, что один тик будет занимать 1.666мкс. Как раз укладывается в искомые 1-2мкс. Полный цикл таймера будет занимать 1,666 * 256 = 426.66 мкс. В качестве програмного таймера мы используем 16-битную переменную, а значит мы способны отмерять отрезки времени 65536 * 426,66мкс = 27,96с (с точностью тех же самых 426,66мкс)

Код запуска таймера:

В коде выше я использовал загадочный макрос TIMEOUT_MS. Пришло время его расшифровать.

Этот макрос определяет количество циклов по 426,6мкс необходимых для отмерения заданого количества милисекунд. К сожалению когда я бахнул туда полную формулу (ту, что в комментарии) то компилятор начал генерить страшные ворнинги с которыми я не справился. Пришлось формулу пересчитать до непонятных теперь 600/256.

Но вернемся к слушанию ШИМ входа. Что бы было чуть понятнее, расскажу еще раз как все работает, но другими словами. Основной 8-битный таймер тикает от 0 до 255. Каждый полный цикл таймера мы процессим список программных таймеров и запускаем обработчики, если нужно. Помимо этого значение самого 8-битного таймера используется в измерение длины импульса на входе. Делается это очень просто: если начался импульс – запоминаем значение таймера. Пока импульс идет таймер продолжает тикать. К моменту когда закончится импульс таймер дотикает до какого то нового значения. Соответственно по разнице значений мы можем вычислить длину импульса просто умножив на время одного тика (1,666мкс)

Стоп! Таймер то у нас 8битный а это означает, что таким способом можно измерить только импульсы длиной до 256 * 1,66 = 426,66мкс, в то время как входящие импульсы длиной до 2200мкс. Не беда! Можно искусственно расширить счетчик таймера добавив столько старших байт сколько нужно. Действует обычная бинарная математика – когда младший байт переполнился инкрементируем старшие байты.

Почти все тоже самое. Добавилась только переменная tcnth – «старший» байт в дополнение к младшему байту внутри таймера. Еще важна последняя строка – она включает прерывание по переполнению таймера. Это прерывание и будет инкрементировать старший байт:

Обратите внимание, что переменная tcnth объявлена как volatile. Без этого ключевого слова компилятор в другой части программы может подумать, что переменная не меняется и оптимизировать лишнего. Он же не в курсе, что переменная изменяется в прерывании (по сути в другом потоке).

Для того, что бы словить начало и конец импульса можно задействовать специально предназначеный для этого pin change interrupt – прерывание, которое вызовется как раз когда значение на входе поменяется. Т.о. не нужно постоянно опрашивать вход – всю работу сделает микроконтроллер. Нам остается только написать обработчик этого прерывания

Первая часть обработчика посвящена вытягиванию значения таймерного счетчика (расширенного дополнительным внешним байтом). К сожалению, вычитывание значения в лоб не работало – время от времени светодиод самопроизвольно помаргивал. Это происходило потому, что 2 прерывания возникали примерно одновременно. А поскольку у прерывания таймера приоритет ниже, то обработчик иногда не вызывался тогда, когда следовало. В результате старший байт оказывался не увеличеным, а значит общее значение оказывалось на 256 единиц меньше. Это существенно.

Решение довольно простое – проверить, а не возникло ли переполнение таймера и если возникло, сделать ту же самую работу, что и обработчик этого переполнения – сделать +1 к старшему байту.

В этом месте я наткнулся на неоптимальность кода, сгенеренного гнусью. Код (tcnth

Источник

Оцените статью