Recent Changes - Search:

Главная страница

Загрузки

Домашний WiFi роутер

Проекты

Статьи

Брошенные проекты

GitHub

SourceForge

edit SideBar

FortressDisplay

Протезирование UPS.

Введение

В конце 90-х появился у меня UPS. Красивый, с LED индикатором и кучей кнопок. Имел внутри два аккумулятора и мог поддерживать жизнь моего тогдашнего компьютера (вместе с монитором!) аж целых 15 минут. Времена на Камчатке тогда были тяжелые, свет выключали регулярно, поэтому данный прибор был весьма кстати. Я прошел вместе с ним весь энергетический кризис, и не раз он спасал мои курсовые от внезапного пропадания электричества. А еще, к нему можно было подключить магнитофон и при свете свечи слушать радио или любимые кассеты, готовя себе ужин на портативной газовой плитке...

Естественно, UPS ломался. В первый раз у него сгорел трансформатор. Не тот, который большой и стоит в инверторе, а какой-то маленький, наверное, для измерения напряжения в сети. Не найдя такой же заводской, я поставил самопальный, и девайс еще какое-то время поработал. Затем перестал. Долго, очень долго, я не мог найти причину. Приходилось выпаивать разные детали, проверять их на работоспособность и впаивать обратно. Проблема не находилась. Распотрошенный прибор пару лет провалялся под кроватью, пока, в один прекрасный день, мне не пришла в голову идея подать 5 вольт непосредственно на контроллер. И о чудо: раздался писк встроенного динамика и на LED индикаторе появились цифры. Он был жив! Дальше — дело техники: прошелся по цепи питания вольтметром и выяснил, что на плате был распаян плавкий предохранитель, наглым образом выглядевший как резистор! Предохранитель (естественно, сгоревший), был заменен и UPS ожил.

К сожалению, мой ремонт и два года под кроватью не прошли для прибора даром. Каким-то непостижимым образом в контроллере сгорел порт, который отвечал за свечение зеленого светодиода «On-Line» и самого нижнего сегмента всех цифровых сегментных индикаторов. Тут уж ничего не поделаешь — пришлось смириться. Через некоторое время я уехал с Камчатки и наши пути разошлись.

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

Задача

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

Идея починить его приходила мне и раньше. Нарисовав на тетрадном листке все цифры (и кое-какие буквы) семи сегментного индикатора, я понял, что определить состояние самого нижнего сегмента возможно по состоянием остальных. Зеленый же светодиод можно зажигать тогда, когда не горят другие светодиоды. Мыслей, как это можно было бы сделать имелось много: от простой микросхемы ПЗУ до простенькой FPGA. Но, поскольку я был студентом и жил на Камчатке, то не имел возможности приобрести что-нибудь сложнее мелкой логики. Починка индикатора откладывалась.

В этот раз я решил заняться проблемой всерьез. Порывшись в закромах, я снова не нашел у себя ни ПЗУ, ни FPGA или какого-нибудь CPLD. Зато под руки попала Adrduino Nano, вернее, его дешевый китайский клон с Ali Express. Ардуину я купил для того, чтобы сделать мини-компьютер на базе WiFi SD карточки от Transcend. К сожалению, карточка померла во время экспериментов, и плата с микроконтроллером осталась лежать без дела. Ничего, мы нашли ей новую задачу!

Работа

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

Вначале я хотел обойтись самым простым решением: обыкновенный цикл, который проверяет сигналы c шести рабочих сегментов, и включает или выключает не рабочий седьмой. Фактически это просто эмуляция ПЗУ, про которую я думал в самом начале. Для этого, мне пришлось подключить шесть рабочих сегментом ко входу микроконтроллера, а нерабочий сегмент – к выходу.

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

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

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

Это было правильным решением. Но окончательно все заработало только после того, как я синхронизировал цикл принятия решения с прерыванием с помощью spin-блокировки и запретил обработку прерывания во время работы этого цикла. И оно не просто заработало: заработало так как надо!

С индикаторами оставалась еще одна проблема: большую часть времени они показывали только цифры. Однако, после включения UPS запускался процесс тестирования, во время которого, помимо цифр, появлялись еще и два слова: TEST и PASS. И если, буквы T, E и P можно было просто добавить в массив допустимых символов, а S – была аналогична 5-ки, то буква A ничем, с точки зрения моей программы, не отличалась от восьмерки. Цикл принятия решений просто находил соответствующий шаблон в массиве и дорисовывал нижний сегмент. Нужно было что-то придумать, чтобы этого избежать.

И я придумал. Во время прихода сигнала о смене индикатора, нужно определять, к какому индикатору он относится и сохранять состояния его сегментов в специально отведенную для него переменную. Теперь, в любой момент времени я точно смогу определить текущее содержимое сразу всех четырех индикаторов. И если на первом, третьем и четвертом отображаются символы P, 5 и 5 соответственно, то вторым символом однозначно является A, и нижний сегмент зажигать не нужно. На всякий случай, я еще добавил обработку слова FAIL, которое я ни разу не видел, но возможность появления которого предполагал.

Все, с цифровым индикатором покончено. Осталось только починить зеленый светодиод «On-Line». Но тут меня ожидал сюрприз... Идея была такая: зеленый светодиод (On-Line) всегда горит один. Если горят желтый (Battery) или красный (Low Battery) светодиоды, то зеленый гореть не должен. Таким образом, подпаиваем к микроконтроллеру провода от этих светодиодов, ставим простой if() с логическим “OR” и все должно заработать. Но выяснилось, что, когда горит желтый светодиод, он, на самом деле, не горит постоянно, а быстро мигает. Быстро, но недостаточно, чтобы if() это пропустил и не зажег зеленый светодиод. Получалось, что при работе от сети, зеленый светодиод горит в полую яркость, но при переключении на батарею, он горел в половину яркости, но все-равно горел. Ну, не проблема, подумал я, поставлю простенький низкочастотный фильтр: буду отсекать все быстрые мигания, но оставлю только медленные, которые соответствуют переходу на батарею и обратно. Анализ времени мигания желтого светодиода принес следующую неожиданность: период импульсов, которые на него подаются, весьма нестабилен и может достигать доволно больших величин. Получалось, что фильтр должен пропускать сигналы никак не выше 0.5-1 гц. Это не есть очень хорошо, поскольку получаем довольно большую задержку в изменении сигнала On-Line, но вполне терпимо.

Фильтр я решил сделать очень простой. Мы 50 раз, в равные промежутки времени, отслеживаем состояние желтого и красного светодиодов. Если один из них горит, то увеличиваем на единицу специальный счетчик. Затем, проверяем значение счетчика, и если, контрольные светодиоды горят в течении 50% проверяемого времени, то считаем, что он включен, а если меньше, то – выключен. В процессе отладки, пришлось уменьшить эту цифру до 10%. Почему — так и не разобрался.

И все заработало! Оставалось только красиво смонтировать плату Arduion Nano в корпусе UPS с помощью двухстороннего скотча и клеящего пистолета.

Видео работы дисплея

Edit - History - Print - Recent Changes - Search
Page last modified on November 19, 2023, at 09:25 PM