Программы. Советы. Безопасность. Интересное. Накопитель

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

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

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

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

Тахометр - это полезный инструмент для подсчета RPM (оборотов в минуту) колеса или всего, что крутится. Самый простой способ сделать тахометр - это использовать ИК передатчик и приемник. Когда связь между ними прерывается, вы знаете, что что-то вращается и можете применять код для вычисления RPM, ориентируясь на частоту прерывания связи.

В этой статье мы рассмотрим, как использовать ИК-передатчик и приемник для изготовления тахометра с применением Arduino. Результат отображается на ЖК-дисплее 16х2.

Целью данного проекта является создание системы с одним входом и одним выходом. На входе устройства присутствует сигнал, изменяющийся с высокого (+5В) на низкий (+0В) уровень при нарушении связи. Согласно этому сигналу, Arduino будет увеличивать значение внутреннего счетчика. Потом проводится дополнительная обработка и расчет, и по прерыванию триггера на ЖК-дисплей будет выводиться рассчитанное RPM.

Для связи мы будем использовать ИК-луч от ИК-светодиода, включенного через низкоомный резистор так, чтобы светиться ярко. В качестве приёмника мы будем использовать фототранзистор, который при отсутствии света ИК-светодиода "закрывается". Компьютерный вентилятор будет размешен между ИК-передатчиком и приёмником и включен. ИК-приёмник включенный через транзисторную схему, будет генерировать прерывания. Для вывода результата будет использоваться Arduino LCD интерфейс, поэтому мы можем вывести окончательное значение RPM на ЖК-дисплей.

Элементы:
Arduino UNO
16x2 LCD
Макетная плата
Подстроечный резистор 5 кОм
Перемычки
SIP разъёмы
2x 2N2222 NPN транзистор
Инфракрасный светодиод
Фототранзистор
Резистор 10 Ом
Резистор 100 кОм
Резистор 15 кОм или 16 кОм
Компьютерный вентилятор

Подробный список элементов

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

Arduino UNO
Это плата Arduino, которую мы будем использовать для обработки импульсов от прерывания ИК-луча, которые сообщают о нахождении лопасти компьютерного вентилятора между приемником и датчиком. Arduino будет использовать эти импульсы наряду с таймером, чтобы вычислить RPM вентилятора.

ЖК-дисплей 16x2
После того, как Arduino вычислило RPM, эта значение будет отображаться на дисплее в понятном для пользователя виде.

Подстроечный резистор 5 кОм
Этот подстроечный резистор будет использоваться для регулировки контрастности ЖК-дисплея 16x2. Он дает аналоговое напряжение в диапазоне от 0 до +5В, позволяя настроить яркость ЖК-дисплея.

Инфракрасный светодиод и Фототранзистор
Фототранзистор открывается, когда мощный ИК-свет падает на него. Поэтому, когда ИК-светодиод горит, он держит фототранзистор открытым, но если ИК-светодиод закрывается например, лопастью вентилятора, то фототранзистор закрывается.

2N3904 и 2N3906
Эти транзисторы используются для преобразования уровня сигнала, с целью обеспечения выходных импульсов с фототранзистора для Arduino, в которых нет никаких напряжений кроме +0 и +5В.

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

В схеме, интерфейс связи с ЖК-дисплеем упрощен и имеет только 2 линии управления и 4 линии передачи данных.

Особенности схемы

Интерфейс ЖК-дисплея 16x2
2 управляющих контакта и 4 для передачи данных подключены от Arduino к ЖК-дисплею. Это то, что указывает ЖК-дисплею, что и когда делать.

Схема обрыва ИК-луча
Сигнал обрыва ИК-луча идет на 2-ой цифровой контакт Arduino. Это прерывает Arduino, что позволяет ему засчитать импульс и позволяет тахометру получать данные.

Arduino LCD библиотека

Для этого проекта мы будем использовать Arduino LCD библиотеку. В основном мы будем просто обновлять значение RPM на второй строке на новое.

В качестве подготовки, посмотрите на код приведенный ниже, в котором при помощи этой библиотеки на ЖК-дисплей выводиться "Hello, World!" В тахометре мы будем использовать похожий код, особенно: "lcd.print(millis()/1000);".

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

Подсчет RPM при помощи Arduino

Так как мы собираемся подсчитать RPM компьютерного вентилятора, мы должны понимать, что для подсчета мы используем прерывание ИК-луча. Это очень удобно, но мы должны учитывать, что у компьютерного вентилятора 7 лопастей. Это значит, 7 прерываний равно 1 обороту.

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

Время 1-го оборота = P * (µS/оборот)
RPM = кол-во оборотов/мин = 60 000 000 * (µS/мин) * (1/P) = (60 000 000 / P) * (кол-во оборотов/мин)

Для расчета RPM мы будем использовать формулу приведенную выше. Формула точная, и точность зависит от того, насколько хорошо Arduino сможет отслеживать время между прерываниями и посчитывать количество полных оборотов.

На фотографии ниже вы можете увидеть все необходимые детали и перемычки как на схеме.

Для начала подключается +5В и линии данных/управления ЖК-дисплея. Затем ЖК-дисплей, потенциометр контрастности и светодиод питания.

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

Хватит разговоров о аппаратной части! Давайте начнем делать прошивку/программу, чтобы увидеть работу устройства!

Программная часть

Есть две основных части кода, которые показаны и подробно описаны ниже:
-Основной цикл обновления ЖК-дисплея
-Обновление времени прерываний

В основном цикле считаются обороты и обновления ЖК-дисплея. Поскольку основной цикл это гигантский while(1) цикл, то он будет работать всегда, RPM считаться, а ЖК-дисплей обновляться несколько раз в секунду. Функция в прерывании подсчитывает время между прерываниями ИК, поэтому считать RPM можно в основном цикле.

Помните, что компьютерный вентилятор имеет 7 лопастей, так что это тахометр предназначен для работы только с такими вентиляторами. Если ваш вентилятор или другое устройство дает только 4 импульса за оборот, измените в коде "(time*4)".

Два вентилятора работают на примерно 3000 оборотов в минуту и ​​2600 оборотов в минуту, с погрешностью около + / -100 оборотов в минуту.

Обзор тахометра на Arduino

Вентилятор генерирует импульсы прерывания, а на выходе мы видим RPM. Хотя точность не 100%, а примерно 95%, при стоимости элементов 10$ есть смысл построить этот тахометр на Arduino.

Что теперь делать?

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

Заключение

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

Список радиоэлементов

Обозначение Тип Номинал Количество Примечание Магазин Мой блокнот
Плата Arduino

Arduino Uno

1 В блокнот
T2, T3 Биполярный транзистор

2N2222

2 2N3904 и 2N3906 В блокнот
R1 Резистор

10 Ом

1 В блокнот
R2 Резистор

100 кОм

1 В блокнот
R3 Резистор

16 кОм

1

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. Доделал немного ПО сайта показывающего данные. Теперь там есть вольтаж по часам, почасовой и посуточный расходы.

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

Похожие публикации