Introduction: Подключаем Ардуино К Счётчику / Connecting Arduino to Read Impulse Data From Electric Counter

Мне давно было интересно посмотреть как меняется мощность в домашней электро-цепи в разное время суток и при разном потреблении. Складывать ватты всех лампочек - скучно и, увы, не факт, что точно. Во всяком случае, что там думает себе счётчик - всегда не очень наглядно. Висит на стене. Мигает. Барабаны крутятся очень медленно, чтобы ощутить разницу в 100 W.
И тут у меня нашлась свободная плата arduino nano, час та натхнення. :)

Step 1: Теория / Theory

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

Принцип работы не сильно изменился — в данном случае диск заменен электроникой, которая генерирует импульсы в соответствии с величиной потребляемой электроэнергии. Как правило, в большинстве приборов эти импульсы показывает светодиодный индикатор. Соответственно, чем быстрее мигает эта лампочка — тем больше сжигается драгоценных kW. Кроме того, на лицевой панели любого устройства есть передаточное соотношение счетчика А — число импульсов на 1 kW*h.

Step 2: Электро-механический Счётчик / Electromechanic Counter

На моём подопытном счётчике есть светодиодный индикатор импульсов “Сеть” и рядом указано, 1kW*h набегает за 6400 импульсов.

Это значит, что 1 импульс равен 1/6400 kW или 1000/6400=0,015625 W*H.

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

Step 3: Материальная База / Stuff I've Used

Для макетирования и отладки устройства я использовал:

  1. Arduino nano
  2. Дисплей аналог Hitachi LCD 20x2
  3. Светодиод с резистором для индикации считывания и буззер с генератором для оповещения о слишком высоком потреблении.
  4. Фоторезистор
  5. Макетная плата breadboard и всякие проводки/перемычки, резисторы, конденсаторы, чтобы это всё соеденить.

Step 4: 1. Arduino Nano

1. Я использовал arduino nano потому что она очень маленькая, дешёвая, имеет встроенный USB для удобной отладки и прошивки, а так же её коммуникационных способностей достаточно для моего проекта. Ну а так же, поскольку именно такая плата у меня освободилась от прошлого проекта. :)

Step 5: 2. Дисплей / Display

2. Дисплей Barton BT22005VSS-09 является аналогом дисплея Hitachi LCD
20x2 и отличается лишь расположением выводов в гребёнке 8х2.

Step 6: Подключение Дисплея / Display Wiring

Я подключил дисплей к arduino по 5-проводной шине, как описано ЗДЕСЬ. Линию данных D4-7 к контактам D5-2 arduino, RS к D12, EN к D11, а R/W на GND.

Управление дисплеем я поручил библиотеке LiquidClystall из стандартного набора в arduino IDE.

Step 7: 3. Светодиод И Буззер / LED and BUZZER

3. К ножке D13 arduino я подключил светодиод индикации с последовательным резистором на GND, который будет дублировать светодиод на счётчике.
К ножке D10 arduino подключил буззер (пьезо-пищалку с генератором частоты), который будет пищать при высоком уровне на этой ножке для сигнализации слишком высокого потребления.

Step 8: 4. Фото-сенсор / Light-sensor (photoresistor)

4. Фоторезистор ФСК-1 я подключил к аналоговому входу A1 и к +5в. При этом, прижав ножку входа A1 к GND резистором 10k.

Без этого резистора потенциал на входе спадал очень медленно, что мешало снимать показания.

Step 9: Программа Для Arduino / Coding an Arduino

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

Step 10: Начнём Со Статистического Поиска Ширины Окна / Getting Window Width for Init

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

В качестве такой опоры я написал функцию инициализацииinitWindow, вызывая её единожды в цикле setup().

При старте микроконтроллер сперва 5 секунд следит за показаниями сенсора, запоминая его предельные верхний и нижний уровни показаний соответствующие переменные порогов окна winHi и winLo.

Step 11: Определим Состояние Индикатора / Look As at Logical

Теперь я могу сравнивать текущее значение с этими порогами и написать функцию определения состояния индикатораcheckLogic, которая следит за тем, как соотносятся текущие показания сенсора к пороговым значениям при сборе статистики с индикатора.
Эта функция присваивает переменной ledState значение TRUE при показаниях сенсора выше верхнего порога с припуском (минус 30% ширины окна), и значение FALSE, когда показания сенсора ниже чем нижний порог (плюс 30% ширины окна).

Step 12: Loop()

Таким образов, в основном цикле программы я сперва считываю значение сенсора, затем, на всякий случай, расширяю окно до его значения, старое состояние индикатора ledState копирую в буфер ledStateOld, и провожу анализ нового состояния индикатора, вызвав функцию checkLogic(ledState).

.

Step 13: Переход Вверх Или Начало Импульса / Impulse Head

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

К этой проверке я привязал таймер, построенный на функции micros. Она возвращает количество микросекунд, прошедших с момента старта arduino. Осталось только из “текущее времени” вычесть “время прошлого перехода” и получить количество микросекунд между переходами, а это и есть длина импульса.

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

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

Так же в момент перехода “вверх” я привязал функции вывода данных на дисплей, поскольку он сильно мерцал при большой частоте обновления данных на нём.

---

“Но ведь в одном часе 3’600’000’000 микросекунд, а не 3’600’000’000’000” - заметят мне внимательные. И будут правы. Лишние три нуля - это то самое умножение на 1000, для перевода из kW в W. Иначе компилятор ругается на сликом большие величины, компилирует, но в итоге программа не сообщает значения. Пришлось как-то выкручиваться.

Step 14: Переход Вниз, Или Продолжение Отсчёта / Impulse Tail

К “переходу вниз” я привязал отключение диода индикации и буззера, таким образом, частота пищания буззера соответствует частоте мигания индикатора счётчика.

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

Step 15: Индикация / Data View

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

А цифровой дисплей на 20x2 символов я захотел использовать по-полной. :) Во время загрузки при сборе статистики в одну строку дисплея я вывожу 3 значения: низ окна, значение сенсора и верх окна. Эту же информацию отображаю во второй строке на шкале шириной в окно.

В рабочем цикле я в одну строку вывожу ток (wattage/220), мощность (wattage) и ширину шкалы, а в другую строку - саму шкалу, масштаб которой изменяется в зависимости от того, не превышен ли порог. Так при пороге в 1000 W и шкала 0-1000 в нормальном режиме и 1000-2000 в режиме превышения.

Step 16: Шкала От 0 До 99 На 20 Символьной Строке И Знакогенератор / Progressbar 100px

Цифры на дисплее довольно мелкие и их сложно разглядеть издалека. Поэтому на каком-то этапе я решил использовать одну из строк дисплея как шкалу.Дисплей имеет по 20 знакомест в строке. Каждое знакоместо может содержать в себе один символ: цифру, букву или знак. В таком случае я могу без труда разместить шкалу с ценой деления в одно знакоместо. Т.е. у меня будет 20 делений.

Мне показалось, что это маловато для дисплея, у которого по факту целых 100 пикселей в один ряд, ведь каждое знакоместо - это квадрат из 5 столбиков по 7 пикселей высотой. Итого, в одной строке у меня целых 100 столбиков. На шкале длиной в 1 kW я могу разместить шкалу с ценой деления 10 W. А это уже довольно наглядное разрешение.

Я решил воспользоваться возможностью этого дисплея создавать пользовательские символы. В arduino IDE имеется стандартный пример, создания произвольных символов. (и замечательное руководство по этой задаче я нашёл в интернете)

Step 17:

Сперва я описал эти символы.

Здесь можно увидеть, что один символ имеет вертикальную черту слева, а второй - уже две черты

Потом нужно проинитить их в цикле setup() так же, как и в примере из ардуино (Первые 5 символов (0-4)я использую для для “палочкой”.)

Step 18:

Затем написал функцию, которая при помощи map составляет пропорцию для нахождения символа и его места на шкале.

Далее я уже использовал данную функцию для вывода шкалы во всех нужных местах.

Step 19: Послесловие / Outro

Я проверил работоспособность данного девайса, и когда убедился, что он работает как следует, изготовил печатную плату, которая вешается на дисплей, и в которой есть слот для установки arduino nano. Теперь я с лёгкостью могу использовать дисплей или arduino в других проектах, или же вернуть их в эту плату, и получить сразу же работающий счётчик мощности.


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

Step 20: Исходник Программы / Source Code for Arduino

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

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