Ардуино проект реверсивный счетчик на led индикаторах. Подключаем Arduino к счетчику электроэнергии

3

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

Atmel AVR, что большинство Arduinos основаны на оборудовании счетчика/таймера, которое будет считать импульсным во входном штыре напрямую. Все, что вам нужно сделать, это настроить аппаратное обеспечение для работы счетчика и прочитать регистр счетчика. Существует небольшая сложность для 16-битных счетчиков на 8-битном устройстве, но это легко преодолеть. Arduino настраивает таймеры для операций PWM по умолчанию, но это можно переопределить, как описано (подробнее см. Руководство пользователя AVR) - вам нужно использовать таймер/счетчик в режиме CTC.

ARM на базе Arduninos и почти любой другой микроконтроллер будут иметь аналогичные аппаратные средства; некоторые из них обладают большей гибкостью, благодаря чему штыри могут использоваться для подсчета оборудования.

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

В вашем случае вам, вероятно, необходимо прочитать количество импульсов в регулярный период, который меньше времени, в течение которого счетчик будет переполняться с максимальной ожидаемой частотой пульса. Так, например, если вы использовали 8-битный счетчик, а максимальная частота пульса составляла 1 кГц, вам нужно было бы опросить каждые 256/1000 секунд или меньше, но наибольшую точность можно получить, сделав этот период как можно дольше. Так, например, вы могли бы иметь что-то вроде следующего (это не реальный код, и только фрагмент):

For(;;) { delayMS(250) ; frequency = 4 * readCounter() ; }

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

For(;;) { int start = getMillisec() ; while(!counterOVF()) { // Do nothing (or something useful but quick) } int t = getMillisec() - start ; frequency = 256 * t/1000 ; }

0

Большое спасибо за ваш вопрос. Если я правильно понял, ваша первая идея состоит в том, чтобы отключить импульсы с помощью аппаратного обеспечения, а второй - все время, когда процессор занят. Проблема в том, что мой микроконтроллер полностью загружен (поэтому простой ISR, увеличивающий счетную переменную, не будет работать) и не может быть опросом, поскольку он должен выполнять другие задачи.Кроме того, у меня больше нет аппаратных счетчиков. Есть ли другие альтернативы? Я слышал, что это возможно, используя аналоговые порты (полагаясь на сходство с PWM). Большое спасибо - manatttta 28 авг. 14 2014-08-28 08:16:36

0

В обоих случаях счетчик аппаратных средств выполняет подсчет, во втором примере мой опрос проверяет флаг переполнения, но это просто для демонстрации принципа, это не фундаментальное решение; он может в равной степени быть обработчиком прерываний - преимущество состоит в том, что вы получаете одно прерывание для каждых 256 импульсов (при условии 8 бит счетчика), а не каждый импульс, поэтому накладные расходы прерывания намного ниже. - Clifford 28 авг. 14 2014-08-28 11:10:07

0

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

В этой статье собраны все данные про счетчик электричества на основе Ардуино, в том числе приведены схемы, прошивки, комментарии по поводу доработки текущей версии прошивки и конструкции.

Вот так оно выглядит в конечном итоге.

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

Часть 1. Идея, проектирование и мысли вслух.

Некоторое время назад я установил двухзонный счетчик электроенергии, чтобы воспользоваться более выгодным ночным тарифом(50% с 2300 до 0800). Оказалось, что 45% электрики мы потребляем ночью. Но ответа как происходит потребление в разрезе мест потребления. конечно это устройство не дает.

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

  1. Текущую мощность нагрузки
  2. Потребление с начала суток
  3. Потребление с начала месяца
  4. Процент ночного потребления в %

Также устройство должно передавать, на настраиваемый интернет-адрес, данные о потреблении за последние 24-ре часа, в виде 24-х отсчетов. Интервал передачи — устанавливается в минутах 1…120.

Задаваемые в меню параметры:

  1. Час в RTC
  2. Минуту вRTC
  3. День в RTC
  4. Месяц в RTC
  5. Год в RTC
  6. Интервал отсчета 1…120
  7. сетевой адрес c указанием позиционно символов: «a-z0-9_-/: «.Редактируемый символ должен быть выделен, чтобы было понятно что именно редактируется.

Первоначальный вариант устройства будет сделан на основе следующего набора модулей:

  1. ( уточнение по поводу подключения индикатора к мега 2560)

Прибор интересует для уточнения сколько потребляет мастерская, медиа-приспособления, кухонные принадлежности. В итоге надо получить данные в виде графиков, в Интернете или на локальном сетевом сервере ()

Начальная схема подключения узла измерения.

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

Беру макетную плату, ищу подходящий трансформатор, для замера напряжения (беру от дежурки АТХ), и вперед.

UPD. Измерительный узел

Часть 2.1 Заметки про удивительные особенности ENC28J60

Удивительная вещь. Начал сегодня копать модуль работы с езернетом, для проекта «счетчик». Кто бы сомневался, было весело, и все в итоге заработало.

По подключению. Смотрим где находить SPI интерфейс с Ардуино «Мега», ну или вашей. Подключаем. Вывод CS (выбор чипа) вешаем куда нам угодно, он потом задается отдельно в инициализации библиотеки. Я «повешал» его на 42-й вывод, у вас может быть какой-то другой. Остальные MOSI/MISO/SS/OV/3.3V подключаются к соответствующим выводам Ардуины.

Оказалось, что для уменьшения использования памяти разработчик «замечательной» библиотеки EtherCard решил, и отправил некоторые строки для GET запроса в память программы. То есть, представьте, некий программист-фрилансер решил вдруг сделать себе счетчик. Чтобы все было умно он решил сделать там редактирование строки-URL, куда отправляются данные. И даже это сделал сегодня:

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

Ничего, быстро слазил в библиотеку, нашел место где заполняется запрос, исковырял его, забрал все «лишнее» на мой взгляд, конечно. В итоге отлично все работает.

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

По ходу проекта остается решить только проблему с измерительной частью, все остальное уже решено. Наиболее сложным в программе — было редактирование строки URL.

Особенность подключения — только DHCP, я не собираюсь делать задания статического ip и выбора, все работает достаточно корректно, и нет никакой необходимости добавлять ненужный мне функционал.

Часть 3. Начальная отладка программного обеспечения счетчика

Сегодня немного повозился с отладкой ПО счетчика. Дело в том, что ошибочно не установил понижающий резистор, на СТ-датчик и в итоге на вход проникало слишком большое напряжение, равно как и слишком много помех. Поправил, припаял 150 ом параллельно СТ-датчику, в общем вышло около 100 ом.

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

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

На дисплее не поместилась буква h после kW, но следует понимать что она там есть. Число показывает расход с начала текущего часа. В конце часа передается на сервер и сбрасывается в ноль. Потом, наверное сделаю чтобы сбрасывалось раз в сутки.

ПО счетчика, в текущем виде —

Часть 4. Делаем первую часть корпуса

Сделал сегодня корпус, материал, такой же как и в прошлый раз — капролон 11 мм. Крепление правда на имбусных винтах М4, в прошлый раз было м3 везде. Это слабовато для корпуса.

Для масштаба положил мышку «эйр» вовнутрь.

Остается сделать переднюю панель, закрепить модули, сделать выфрезеровки под USB и питание 12В. В случае с этим приборчиком, достаточно, наверное 0,7А будет, то есть можно применить нечто малогабаритное.

Часть 5 Делаем переднюю панель

Часть 9. Обновлено ПО, по результатам эксплуатации устройства

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

Upd 2015-09-23. Написал сегодня интерфейс для просмотра данных мониторинга. Заодно и оптимизировал прошивку, нашел ошибочек в ней. Поднял внутренний ДНС сервер, на « » это минуты дело.

Просто показал последние 48-м часов (потер статистику, поэтому там меньше на графике) в виде заглаженного графика. Всплеск — это начало работы стиралки, по У — цена в гривнах за текущий час, с учетом ночного тарифа, конечно. По Х — дата/время.

Теперь можно немного посмотреть что происходит. Маленький нюанс — расположил все в домашней сети, для большей устойчивости.

Ранее уже писал, что попробовал одно стандартное ПО, чтобы показывать расход электрики (emoncms). Непонятная мне парадигма и подход. Там раз в три секунды отсылает на сервер данные, и показывает что-то. Я сделал по другому — устройство накапливает данные 1 час, потом отсылает за последние 24-ре часа. Веб=-сервер на запустил, это NAS, с низким энерго-потреблением.

UPD. Выяснилось, что это не Интернет у меня такой, это устройство иногда не передает данные. Не понятно, с чем связано, и отловить сложновато, поэтому пошел другим путем — подсчетом промежуточных показаний на основании текущего расхода. За сутки гдето 1-2 раза происходит сбой. Такая схема позволяет отказаться от хранения почасовых данных в еепром, которое также почему-то работает не совсем корректно.

UPD. Доделал немного ПО сайта показывающего данные. Теперь там есть вольтаж по часам, почасовой и посуточный расходы.

Подумываю над размещением ПО на гитхабе. Наверное. так оно и будет.

Нет, эта статья не об очередном способе обмануть этот злосчастный прибор. Здесь пойдет речь о том, как с помощью Arduino и среды LabView превратить свой счетчик электроэнергии в средство мониторинга потребляемой мощности или даже в амперметр!


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

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

Принцип работы не сильно изменился - в данном случае диск заменен электроникой, которая генерирует импульсы в соответствии с величиной потребляемой электроэнергии. Как правило, в большинстве приборов эти импульсы показывает светодиодный индикатор. Соответственно, чем быстрее мигает эта лампочка - тем больше сжигается драгоценных кВт.
Кроме того, на лицевой панели любого устройства есть передаточное соотношение счетчика А - число импульсов на 1 кВт*ч. Как видно из фото, у подопытного А=12800. Из этой информации можно сделать следующие выводы:

С каждым импульсом счетчик фиксирует потребление, равное 1/12800 части от 1 кВт*ч. Если включить к счетчику нагрузку и начать просто считать импульсы, то потом легко получить потребленное ею количество электроэнергии (кВт*ч), разделив количество импульсов на передаточное соотношение.

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

вот они

Воистину, передаточное число счетчика - великая вещь, так как зная ее можно выразить как мощность так и ток:
Составим пропорцию из нашего передаточного соотношения (А=12800 имп/кВт*ч) и неизвестного передаточного соотношения, которое будет при нагрузке X и за время одного единственного импульса (моргания лампочки):

Здесь X - неизвестная мощность, а t - время одного импульса. Выражаем отсюда неизвестную мощность и вот оно:

Ток считается с применением следующей пропорции передаточных соотношений и токов известных и неизвестных при нагрузке X.:


Что в общем-то приводит к идентичной формуле, но для тока (ток измеряется в Амперах а индексы означают нагрузку, при которой будет данный ток):

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


Таким образом, все упирается в измерение времени одного импульса (моргания индикатора). В своих изысканиях я опирался на этот отличный проект . Некий итальянец сделал в среде Labview интерфейс для мониторинга мощности и придумал схему для измерения импульсов. Но в его проекте красовалась огромная недоработка - он подходил только лишь для счетчиков с передаточным соотношением 1000 имп/кВт*ч.

Верхний график - средняя мощность за 5 минут, нижний - в реальном времени. Интерфейс довольно гибкий и легко модифицируется под свои нужды. Если Вы еще не имели дела со средой LabView - рекомендую познакомиться.

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

Выглядит это следующим образом


Казалось бы просто, но до этого надо еще додуматься!

Итак, если Вы все-таки решите реализовать мониторинг мощности, то есть два варианта:

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

Схема для бесконтактного снятия импульсов


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

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

Схема для подключения к телеметрическому выходу


В моем случае - доступ полный, поэтому заморачиваться я особо не стал. Устанавливаем LabView и вперед измерять! Все графики представляют собой мощность (Вт) в реальном времени.
Первым под раздачу попал многострадальный чайник. Крышечка гласит что мощность у него 2,2 кВт, однако судя по графику, исправно потребляет лишь 1700 Вт. Обратите внимание, что потребление более-менее постоянно во времени. Это означает что нагревательный элемент (скорее всего нихром) очень слабо изменяет свое сопротивление в течении всего процесса вскипячивания.

Совсем другое дело клеевой пистолет - заявленная мощность 20 Вт.Он ведет себя в соответствии с законами физики - при нагреве сопротивление нагревателя увеличивается, а ток соответственно уменьшается. Проверял мультиметром - все так и есть.

Старый радиоприемник «Весна». Здесь график ушел вверх в начале из-за того, что я запустил измерение во время импульса, соответственно это повлияло на данные. Горки на графике показывают, как я крутил ручку громкости. Чем громче - тем больше радио кушает.

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

А теперь самое интересное. Я провел небольшой эксперимент со своим стареньким ноутбуком, результат которого приведен на картинке:

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

  • Tutorial

Задача на сегодня: как определить угол поворота инкрементального энкодера?

Сегодня в серии публикаций про ардуино головного мозга коротенькая статья с небольшим экспериментом и парой рецептов. В комментариях к одной из моих прошлых статей меня обвинили в том, что ардуиной подсчитывать импульсы энкодера - фу так делать:
Оптически энкодер 1000/оборот и ATMega не имеющая аппаратной схемы работы с энкодером (как у серий STM32, например) - это тупик.
Дальше в комментариях было много теоретизирования, которое лучше пропустить. Давайте лучше попробуем протестировать в железе, насколько это тупик. Для начала, что такое инкрементальный энкодер? Тот, кто помнит эпоху до-оптических мышек, ответ знает точно. Внутри энкодера есть диск с прорезями, вот для наглядности я сделал фотографию диска с пятьюстами прорезями:


С одной стороны этого диска помещают светодиод, с другой фотодиод:

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

Как же определяется направление вращения? Очень просто: в датчике не одна, а две пары светодиод-фотодиод. Давайте нарисуем наш диск, точки A и B показывают положение фотодатчиков. При вращении вала энкодера снимаем два сигнала с этих фотодатчиков:

Датчики поставлены на таком расстоянии, чтобы при вращении с постоянной скоростью генерировался меандр, свинутый на четверть периода. Это означает, что когда фотодатчик А стоит напротив середины прорези, то фотодатчик B стоит ровно на границе прорези. Когда датчик крутится (условно) по часовой стрелке, то при восходящем фронте на сигнале B сигнал A равен единице. Когда же датчик крутится в обратную сторону, то при восходящем фронте на сигнале B а равен нулю.

Это всё прекрасно, но что мне копипейстить в мой проект?

Вот это:

Volatile long angle = 0; volatile char ABprev = 0; const int increment = {0,-1,1,0, 1,0,0,-1, -1,0,0,1, 0,1,-1,0}; ISR (PCINT0_vect) { // D8 or D9 has changed char AB = PINB & 3; angle += increment; ABprev = AB; } void setup() { pinMode(8, INPUT); // A pinMode(9, INPUT); // B PCICR |= (1 << PCIE0); // interrupt will be fired on any change on pins d8 and d9 PCMSK0 |= 3; ABprev = PINB & 3; Serial.begin(115200); } void loop() { Serial.println(angle); delay(100); }
Давайте объясню, как этот код работает. Я тестирую код на ATmega328p (Arduino nano), выходы энкодера поставлены на пины d8 и d9 arduino nano. В терминах ATmega328p это означает, что младшие два бита порта PINB дают текущее состояние энкодера. Функция ISR будет вызвана при любом изменении в этих двух битах. Внутри прерывания я сохраняю состояние энкодера в переменную AB:

Char AB = PINB & 3; // Внимание, ардуиновский digitalRead() противопоказан, // когда нам критична скорость работы
Для чего? Давайте посмотрим на предыдущий график, в нём пунктирными линиями обозначены моменты вызова прерывания (любой фронт на любом сигнале). Для каждого вызова прерывания цифры внизу - это состояние переменной AB:

Видно, что при вращении по часовой стрелке переменная AB меняется с периодом в четыре значения: 23102310 2310. При вращении против часовой стрели переменная AB меняется 01320132 0132.

Если у нас оба фотодатчика были перекрыты (переменная AB=0), а при вызове прерывания AB становится равной 2, то датчик вращается по часовой стрелке, добавим к счётчику единицу. Если же AB переходит от 0 к 1, то датчик вращается против часовой стрелки, отнимем единицу от счётчика. То же самое и с другими изменениями переменной AB, давайте составим таблицу:

Обратите внимание, что таблица заполнена не до конца. Что вставить на месте вопросительных знаков? Например, по идее, главная диагональ таблицы не должна использоваться никогда, прерывание вызывается при изменении переменной AB, поэтому перехода 0->0 случаться не должно. Но жизнь штука тяжёлая, и если микроконтроллер занят, то он может пропустить несколько прерываний и таки вызваться. В таком случае предлагаю ничего не прибавлять и не отнимать, так как нам явно не хватает данных; заполним недостающие клетки нулями, вот наша таблица:

Const int increment = {0,-1,1,0, 1,0,0,-1, -1,0,0,1, 0,1,-1,0};
Теперь, надеюсь, код понятен полностью.

В итоге на один период сигнала A у нас вызывается четыре прерывания, что при вращении датчика в одну сторону увеличит счётчик не на 1, но на 4. То есть, если на инкрементальном энкодере написано 2000PPR (две тысячи прорезей на диске), то реальное его разрешение составляет 1/8000 оборота.

Постойте, а что с дребезгом?

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

Сигнал A постоянный, поэтому согласно нашей табличке, на восходящем фронте сигнала B мы добавляем единицу, а на нисходящем вычитаем. В итоге, если мы сумеем отработать все фронты нашего дребезга, то наш алгоритм его прекрасно проглотит. И вот тут становится интересно, а сможет ли наша ардуинка отработать такие прелести? Теоретизировать можно долго, давайте ставить эксперимент.

От теории к практике

Считать импульсы будем тремя способами:
  • Софтверно на ATmega328p
  • ATmega328p, опрашивающая хардверный счётчик
Все три способа считают импульсы абсолютно одинаково, но, разумеется, хардверные способы имеют существенно большую скорость опроса сигналов. Энкодер используется Omron E6B2-CWZ6C (2000PPR).

Подключение

Софтверный счётчик

Подключение простейшее, достаточно два провода от энкодера завести на ноги d8 и d9 ардуины.

HCTL-2032

Подключение hctl-2032 к ардуине выглядит примерно вот так:

Чтобы не занимать все ноги ардуины, я поставил ещё 74hc165.

BeagleBone Blue


BeagleBone Blue имеет встроенный квадратурный декодер, поэтому 3.3В энкодеры можно просто завести на соответствующий коннектор. У меня энкодер имеет 5В логику, поэтому я добавил двусторонний преобразователь уровней на bss138 :

Эксперимент первый

Я взял свой стенд с маятником, который уже описывал :

Каретка ездить не будет, просто повешу три счётчика на энкодер маятника. Почему именно маятник? Потому что сила тяжести даёт неуплывающий маркер: каждый раз, как маятник успокаивается в нижем положении, счётчики должны показывать число, кратное 8000 (у меня энкодер 2000ppr).

Вот три счётчика, подключенные параллельно, сверху вниз: биглбон, софтверный счётчик, hctl2032. ШИМ-драйвер для двигателя каретки в данном тесте не используется:

Начало испытаний, маятник неподвижен, два монитора последовательных портов и счётчик биглбона, запущенный по ssh:

Рукой делаю один полный поворот маятника, жду, пока он снова успокоится в нижнем положении:

Все три счётчика показывают ровно 8000, как и положено! Хорошо, из комментариев мы вынесли, что из-за дребезга софтверный счётчик должен сильно ошибаться при низких скоростях маятника. Десять раз повторяю процедуру: качаю маятник так, чтобы он сделал один оборот, а затем жду, пока полностью успокоится. Затем снова качаю, жду, покуда успокоится. Трение низкое, одна итерация занимает пару минут, в итоге примерно полчаса работы счётчиков.

Ха, а ведь опять ни один не ошибся!

Эксперимент второй

Итак, дребезг в реальности оказался не столь страшным, как казалось. Снимаю маятник, и цепляю к оси энкодера шуруповёрт:

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

100 оборотов в минуту - порядок. 500 оборотов в минуту - порядок, согласие полное. 900 оборотов в минуту: АГА! Останавливаю шуруповёрт:

Хардверные счётчики по-прежнему согласны между собой, а вот софтверный прилично отстал. Давайте считать, насколько это согласуется с теорией. Мануал на ATmega328p говорит, что обработка (пустого) прерывания - это минимум 10 тактов микроконтроллера. Работа со стеком, чуть кода внутри прерывания - это в сумме тактов 40 на одно прерывание. 8000 тысяч прерываний на 900 оборотов в минуту (15 оборотов в секунду) на 40 тактов = 4800000 тактов в секунду. В целом наша оценка весьма недалека от тактовой частоты ардуины, то есть, 1000 оборотов в минуту - это потолок для счётчика энкодера высокого разрешения на прерываниях, причём для ардуины, которая не делает ничего другого.

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

Подведём итог:

1. Считать на прерываниях вполне можно, 15 оборотов в секунду - это всё же весьма приличная скорость. Но если нужно обрабатывать больше одного счётчика, всё становится резко хуже. Выбор энкодера играет сильную роль, так как в хороших энкодерах подавление дребезга есть внутри, поэтому хороший энкодер и копеечный 8-битный микроконтроллер - вполне себе решение.

2. Хардверные счётчики надёжнее, но дороже.

3. hctl2032 существенно дешевле BeagleBone Blue, но и сложнее подключается к контроллеру, а биглбон и сам себе контроллер, и умеет четыре энкодера разом обрабатывать. Да и усилитель для двигателя там уже есть на борту, поэтому стенд с маятником можно собрать вообще малой кровью. С другой стороны, даже будучи довольно экзотичной, hctl-2032 стоит пять долларов за штуку, и может спасти ситуацию, когда схема с каким-нибудь пиком или атмелом уже есть, и сильно менять её не хочется.

4. Говорят, stm32 и дёшев, и имеет хардверный счётчик. Но цена вхождения (в смысле времени) в вопрос больно кусается.

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



Copyright © 2024 Строительный портал - Djec.