Arduino счётчик импульсов. Ардуино головного мозга: импульсный датчик положения

Главная / Все материалы
  • 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 и дёшев, и имеет хардверный счётчик. Но цена вхождения (в смысле времени) в вопрос больно кусается.

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

Для дополнительного задания

Принципиальная схема

Схема на макетке

Обратите внимание

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

    Выходной сдвиговый регистр дает нам возможность «сэкономить» цифровые выходы, использовав всего 3 вместо 8. Каскад регистров позволил бы давать 16 и т.д. сигналов через те же три пина.

    Перед использованием микросхемы нужно внимательно изучить схему ее подключения в datasheet’е . Для того, чтобы понять, откуда считать ножки микросхемы, на них с одной стороны есть полукруглая выемка. Если мы расположим нашу 74HC595 выемкой влево, то в нижнем ряду будут ножки 1-8, а в верхнем 16-9.

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

    Напомним, что на изображении семисегментного индикатора подписаны номера его ножек и их соответствие сегментам.

Скетч

Для того, чтобы передать порцию данных, которые будут отправлены через сдвиговый регистр далее, нам нужно подать LOW на latch pin (вход ST cp микросхемы), затем передать данные, а затем отправить HIGH на latch pin, после чего на соответствующих выходах 74HC595 появится переданная комбинация высоких и низких уровней сигнала.

Для передачи данных мы использовали функцию shiftOut(dataPin, clockPin, bitOrder, value) . Функция ничего не возвращает, а в качестве параметров ей нужно сообщить

  • пин Arduino, который подключен ко входу DS микросхемы (data pin),

Счетчик электроэнергии своими руками на Arduino

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

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

Что вам понадобится для домашнего счетчика электроэнергии

Arduino (Uno, используемый в этом руководстве)
ЖК-экран
Трансформатор тока CT - Talema AC1030 (см. Ниже различные варианты и ссылки на покупку)
Резистор с сопротивлением 56 Ом
10μF конденсатор
2 x 100KОм делительные резисторы

Как сделать счетчик электроэнергии

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

Сборка компонентов

Если вы собираетесь установить свой измеритель мощности где-нибудь надолго, вы можете припаять резисторы и конденсатор непосредственно на CT.

Ниже показана базовая схема подключения CT к Arduino:


Экран ЖК-экрана уже использует аналоговые входы, но экран использует только A0. Просто припаяйте три провода от вашего текущего датчика к контактам на шилде и используйте A1 в качестве входного сигнала датчика, как показано ниже.


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

Выбор различных компонентов

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

Выбор трансформатора тока

Первый - трансформатор тока. Используется здесь Talema AC1030, который может воспринимать номинальный ток 30A и максимальный ток 75A. При напряжении 220 В он теоретически может воспринимать до 16,5 кВт в течение коротких периодов времени, но он рассчитан на то, чтобы непрерывно воспринимать мощность 6,6 кВт, подходящую для небольшого домашнего хозяйства. Чтобы вычислить, сколько усилителей вам нужно использовать, возьмите максимальную непрерывную мощность, которую вы ожидаете потреблять и разделить по напряжению (обычно 110 В или 220 В в зависимости от вашей страны).

Калибровка нагрузочного резистора

Затем вам нужно определить значение резистора R3, это преобразует ваш ток ТТ в опорный сигнал напряжения. Начните с деления первичного тока (максимального, как использовано выше) на коэффициент трансформации трансформатора тока (имеется в техническом паспорте). Это должно быть порядка 500-5000 к 1. Эта статья работала на 42A с коэффициентом трансформации 1000: 1, давая вторичный ток 0.042A или 42mA. Ваше аналоговое опорное напряжение на Arduino составляет 2,5 В, поэтому для определения используемого вами сопротивления R = V / I - R = 2,5 / 0,042 = 59,5 Ом. Самое близкое стандартное значение резистора составляет 56 Ом, так что это было использовано.

Вот несколько вариантов на разных ТТ и их идеальных нагрузочных резисторах (в стандартных размерах):

  • Murata 56050C – 10A – 50:1 – 13Ω
  • Talema AS-103 – 15A – 300:1 – 51Ω
  • Talema AC-1020 – 20A – 1000:1 – 130Ω
  • Alttec L01-6215 – 30A – 1000:1 – 82Ω
  • Alttec L01-6216 – 40A – 1000:1 – 62Ω
  • Talema ACX-1050 – 50A – 2500:1 – 130Ω
  • Alttec L01-6218 – 60A – 1000:1 – 43Ω
  • Talema AC-1060 – 60A – 1000:1 – 43Ω
  • Alttec L01-6219 – 75A – 1000:1 – 33Ω
  • Alttec L01-6221 – 150A – 1000:1 – 18Ω
  • CTYRZCH SCT-013-000 – 100A
  • TOOGOO SCT-013-000 – 100A
Используемый конденсатор 10 мкФ, что должно быть достаточным для большинства диапазонов ТТ для бытовых применений.

Наконец, вам нужно два разделительных резистора, чтобы получить опорное напряжение 2,5 В от Arduino. Они должны быть одинаковыми, поэтому R1 = R2, и нам не нужно много тока, поэтому в этих статьях используются два 100KОм резисторы.

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

Обновление - с тех пор код был модифицирован для использования функции millis (), см. Конец раздела для обновленного кода.

Скачать файл: (cкачиваний: 357)

Если вы не хотите использовать или не имеете ЖК-экран, вы также можете изменить скетч для вывода в последовательное окно IDE Arduino, как показано ниже.

Скачать файл: (cкачиваний: 340)

Обновление кода

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

Вот улучшенный код: Скачать файл: (cкачиваний: 516) Для тех из вас, кто прочитал, что функция millis () переполняется примерно через 49 дней, код автоматически выполняет обнуление.


Откалибруйте показания значения тока

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

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

Подключите небольшую лампочку (100 Вт или около того) и посмотрите, какая нагрузка отображается. Теперь вам нужно настроить использование коэффициента масштабирования в строке калькуляции:

Двойной RMSCurrent = ((maxCurrent - 516) * 0,707) /11,8337

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

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

Нет, эта статья не об очередном способе обмануть этот злосчастный прибор. Здесь пойдет речь о том, как с помощью 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 Вт. Нажал на кнопку до упора, чуть чуть подождал и отпустил, но не плавно. На графике хорошо видно бросок тока при пуске двигателя. Именно поэтому моргает свет, когда добрый сосед начинает долбить свою любимую стену.

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

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

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 (иначе как подсчет импульсов поможет?). -

© 2024 spares4bmw.ru -- Автомобильный портал - Spares4bmw