Посудомойка. Три месяца спустя. Опыт наладки и эксплуатации
Предыстория
Всем привет, думал к этой теме уже не возвращаться, но пока меня ещё не убило атомной бомбой хотелось поделиться некоторыми результатами наладки посудомойки. А также поделиться рекомендациями для тех, кто захочет повторить процесс, используя мою прошивку или написав свою. Прошло уже около 3 месяцев с тех пор, как я начал заниматься проектом. Электронику всю полностью перенёс, модуль в готовом виде:
Основные группы соединений, паял разными проводами для наглядности:
1. Выходы контроллера на агрегаты (розовый провод МГТФ) - 7 шт.
2. Выходы на дисплей (24AWG цветные) - 6 шт.
3. Входы датчиков (провод без маркировки, красные и черные) - 5 шт.
4. Органы управления (в нашем случае - 1 кнопка, 24AWG черный) - 1 шт.
После переноса были обнаружены следующие ошибки в работе:
1. Яркость дисплея периодически пропадала, иногда дисплей переставал работать вообще.
Решение: ошибка была в монтаже. У проводка питания дисплея отошла одна жилка, которая касалась соседнего вывода. Из-за сопротивления провода короткого замыкания не произошло, но происходила просадка напряжения на участке.
2. Ранее существующая проблема сбоев в работе стала критичной
А именно: если не подключать силовую часть, всё работает, как часы, но при её подключении контроллер зависает между сменой фаз.
Решение: Некоторые люди из комментариев предположили, что это может быть наводка на линию RESET, которая осталась висеть в воздухе. Я подтянул её к линии питания и установил RC цепь. Ситуацию это не изменило. Так что этот совет, как и многие другие из комментариев, оказался бесполезен. Так как при отключенной силовой части всё работало исправно, я предположил, что проблема возникает в просадке основного питания. Были предприняты следующие шаги:
1. Входной конденсатор заменён с 680мкФ до 2200мкФ на то же напряжение
2. Установлен дополнительный конденсатор на 330мкФ по линии 5В, непосредственно рядом с микросхемой
3. Укорочены до предела провода питания микросхемы, чтобы не создавать лишнее сопротивление
В результате этих действий стабильность заметно улучшилась.
3. Дисплей при работе силовой части начинает ловить помехи и показывать мусорные символы между основным текстом
Решение: изменить протокол связи дисплея и МК на более помехозащищённый, экранировка провода, согласование сопротивлений линии, изменение таймингов, введение RC цепей. На данный момент оставил так, потому, что это не особо мешает. Но надо иметь ввиду: если отключена силовая часть, дисплей работает прекрасно. Но от того же двигателя на него начинают наводиться сильные помехи, и при передаче информации это проявляется в виде ненужных знаков, мешающих нормальной работе.
Дисплей при нормальной работе выглядит так:
632 - показания Fluid Meter (нормальная заливка)
32C - показания термометра, который мы делали
11 - текущая фаза программы (как в BASIC-подобных языках)
16:41 - текущее показание таймера.
Теперь рассказываю, если кто-то захочет повторить: ссылки на исходный код и схему можете найти в предыдущих постах.
Вам понадобится: микроконтроллер Atmega328 (вытаскивается из любой платы Arduino Uno, Nano и т.п.), макетная плата, средства для программирования.
Из прочих деталей:
- Стабилитрон 2,5В
- Кварц 4-8 МГц (на более высоких значениях программа не испытывалась)
- Различные конденсаторы и резисторы, их можно посмотреть на схеме, приложенной в предыдущем посте
На текущий момент конфиг жестко зашит на следующие значения:
- Кварц 6МГц - Dishwasher328.h F_CPU
Config.h:
Выходы: PORT D 0-6 (один пин свободен) - можно менять местами
Входы датчиков: PORT C 0-5 (один пин свободен) - жестко зашит пин АЦП и прерывания, менять местами можно, но надо поменять канал АЦП и обработчик PCINT.
lcd1602.h:
Выходы дисплея: PORT B, 0-6 (тут жестко зашито, так как используются непосредственно битовые сдвиги)
CountdownTimer.c:
OCR1AH, OCR1AL необходимо поменять, если меняется кварц - для того, чтобы согласовать часы контроллера с реальным временем. Сейчас зашито на 6 МГц.
В общем и целом, вышеперечисленные параметры необходимо настроить под вашу машинку и ваш кварц, остальное будет работать как есть. Всё собирается по схеме.
Пишем софт для посудомойки ч.4. Смотрим результаты. Испытания "минимально жизнеспособного продукта"
Всем привет. Прошло уже около 2 месяцев с тех пор, как я занялся этим проектом и выложил по этой теме первый пост. Собственно, в последнее время разработка чуточку затормозилась, т.к. внезапно во время занятий спортом ощутимо повредил ногу, а затем занимался её лечением. Но речь не об этом. Уже можно воскликнуть: "Ура! Машина работает!". В общем, учитывая все предыдущие этапы, программу удалось довести до какого-то "рабочего" варианта (хотя назвать это даже альфа-версией язык не повернётся), который позволяет, тем не менее, проводить тестовые мойки и даже эксплуатировать машину по назначению. Итак, по порядку:
1. Прописал состояния программы.
Пришлось немного отступить от задуманной ранее полуторачасовой программы. На текущий момент реализована программа мойки "экспресс": сразу идёт мойка горячей водой в течение 20 минут, а затем одно ополаскивание. Время мойки при этом составляет около 30 минут. Количество воды на программу: 6 литров. Электроэнергия: примерно 0,5 кВт*ч (зимой, возможно, будет больше). Для моих нужд этих процедур достаточно.
2. Постепенно начал переносить плату из прототипа в рабочий вариант.
В моём случае это заключается в том, что макетные DuPont провода постепенно заменяются на МГТФ, припаянные в соответствующих местах к родному модулю. На данный момент процесс завершен частично.
3. Провёл десяток тестовых моек
На данный момент провёл определенные тестовые мойки, в результате которых были найдены некоторые баги в прошивке, которые, однако, пока не исправил. Например, иногда программа может зависнуть в момент запуска двигателя. Вызывается это, судя по всему, помехой от двигателя. Попытка установить доп. конденсаторы на данный момент ничего не дала, варианты решения прорабатываются. Тем не менее, керамическая посуда вымыта достаточно качественно, не докопаешься:
Готовая принципиальная схема прибора (чукча не рисователь схем, так, набросано на скорую руку):
4. Исходный код
В первом посте обещал выложить исходный код.. Конечно, в таком варианте, как сейчас, его применение сильно ограничено - багов там целый вагон, да и настроить сможет только специалист. Тем не менее, выкладываю пока так:
https://github.com/ritsudo/DishWasher328
Если у кого-то есть желание, можете его доработать до вменяемого вида. Я тоже попытаюсь это сделать, но не уверен, что у меня хватит времени, т.к. другие проекты тоже требуют внимания.
На этом всё, спасибо всем, кто следил за веткой, на всякий случай прикладываю также список всех предыдущих частей:
Часть 1. Изучаем устройство машинки
Часть 2. Создаем проект
Часть 3.1. Работаем с расходомером.
Часть 3.2. Работаем с ТЭНом.
Но на этом мы не прощаемся, из нереализованного также осталась куча функций, например, контроль смягчения воды и регенерация соли. Однако, я хотел посвятить специальный пост этому вопросу, а именно - умягчению воды в машинке. Но для этого мне нужно попасть к знакомому в лабораторию водоочистки, поэтому смогу ли я это сделать и когда именно - вопрос. Но, возможно, продолжение этой серии будет. На данный момент основные цели проекта считаю достигнутыми.
С вами был Kekovsky.
ПСДПМ ч.3.2: Термометрия, подключаем ТЭН
Привет, ребятки, из числа подписчиков и не только (если кому-то ещё интересно - можете тоже заходить на огонёк). Как всегда, "пролетели 2 недели", но, программа потихоньку пишется (и уже даже как никогда близка к завершению). Сегодняшний пост будет о реализации обработки ТЭНа, которая жизненно необходима для получения горячей воды в посудомойке. Некоторые моменты я сильно упростил, но, тем не менее, удалось выполнить и эту задачу. Итак, как мы знаем, в нашей машинке имеется ТЭН. Но для его корректной работы необходима обработка данных термометра, чтобы понимать, на какой интервал времени нужно этот самый ТЭН включать. Устанавливать какой-то дополнительный термометр не нужно, он уже есть в машинке.
Нам необходимо показания этого самого термометра обработать. Так как он представляет собой термистор (элемент, изменяющий своё сопротивление в зависимости от температуры), ставится задача провести следующие преобразования:
1. Измерения по сопротивлению термистора (dR от dT)
2. Приведение их к изменению напряжения (преобразование dR в dU) (используется "мост Уитстона")
3. Сравнение полученного напряжения с опорным напряжением, получение разницы в процентном соотношении (в этом нам поможет физик Кларенс Мэлвин Зенер)
4. Приведение полученного соотношения к абсолютному значению температуры в градусах (а в этом нам поможет математика 7 класс)
5. Вычисление ориентировочных интервалов включения ТЭНа по полученным данным
Собственно, на момент написания поста, мною это всё уже проделано и результаты вписаны в историю программы:
Давайте теперь разберём каждый этап.
1. Измерение сопротивления термистора
Так как мы имеем дело с неизвестным термистором, для определения его характеристик, необходим какой-то эталон. В нашем случае я использую готовый покупной термометр, установленный в бак примерно на том же уровне, что и исследуемый. В первоначальную задачу входит запись показаний сопротивления в зависимости от показаний термометра. Практически этот процесс выглядит примерно так:
Тут я столкнулся со следующей проблемой: висячий на воздухе провод термистора ловил целую кучу помех, от насоса, мотора и т.д., поэтому, показания очень сильно прыгали. В данном случае видно, что значению в 26,6 градусов соответствует сопротивление 6,37 кОм. Однако, это совсем не верно. В качестве временного выхода было использовано измерение "на остывание": сначала я разогрел бак до 60 градусов, затем отключил все приборы из сети и измерил повышение сопротивления. Полученные точки показаны на графике (синяя кривая).
Как можно видеть, мы получили примерную характеристику термометра. На участке от 30 до 50 градусов почти линейна, далее немного закругляется в сторону экспоненциальной. Ниже 26 градусов измерить было невозможно, т.к. это была комнатная температура. В целом, этот график позволил сделать следующие выводы:
1. Функция зависимости dR от dT может быть приближена к линейной для температур до 60 градусов (что является заводской температурой в программах для данной машинки)
2. Сопротивление при комнатной температуре начинается от 10-12кОм, следовательно, балластный резистор примем сопротивлением в 15 кОм (т.к. ниже комнатной температуры машинка остывать у нас не будет).
2. Приведение к измерению напряжения
Для измерения напряжения используется слегка видоизмененный измерительный мост Чарльза Уитстона, открытый в 1843 году.
Суть его заключается в сравнении напряжений, полученном с помощью делителя на исследуемом сопротивлении (R1, R2) с опорным (R3, R4). Только, в данном случае, оно даёт как бы "логический" сигнал, где R4 - переменное сопротивление, подбираемое реостатом. А в нашем случае необходимо процентное соотношение, вместо вольтметра используется АЦП, который уже встроен в контроллер ATMEGA328.
3. Сравнение полученного напряжения с опорным напряжением
Хотел бы заострить внимание на следующих моментах:
- Ввиду большого количества помех из-за силовых агрегатов (насосы, клапаны) в качестве опорного напряжения выбирается не резистор, а стабилитрон с балластным сопротивлением. В моём случае нужен был стабилитрон (он же диод Зенера в честь известного физика) на 2,5В. Который заменяется микросхемой TL431 из блока питания, катод соединяется с управляющим выводом). Балластный резистор для него методом подбора выбран на 330 Ом (маловато, но можно оставить и так).
- Т.к. у нас второй "вывод" измерителя АЦП уже подключен к земле по схеме микроконтроллера, мы не можем подавать на него опорное напряжение, это приведёт к замыканию его на землю. Благо, в микроконтроллере на этот случай предусмотрен вывод AREF, на который и подключается опорное напряжение. Противоположный вывод термистора подключаем к одному из входов АЦП (в нашем случае ADC5)
Давайте теперь настроим АЦП на самом контроллере:
Настройка его очень простая:
- Разрешаем считывание показаний АЦП
- Выбираем опорное напряжение с AREF пина (нашего стабилитрона). Специально акцентировал на этом внимание, если REFS1 установить как 0 и REFS0 как 1, то будет выбрано напряжение питания, а на AREF желательно ставить керамический конденсатор. Использование такой конфигурации не всегда рекомендуется, в нашем случае показания начнут плясать, как Айседора Дункан, поэтому устанавливаем оба бита как 0.
- Выбираем ADC5 регистром мультиплексора ADMUX (в нашем случае - вывод 5 он же IN_RS C5 на порту C).
В CheckTemperature просто получаем значение ADC (он же ADCW) после установки соответствующего бита в регистре АЦП. В результате мы "загнали" текущую температуру в доступную нам для работы область.
4. Приведение полученного соотношения к значению температуры
После предыдущего шага мы получили значение в попугаях (процентах): насколько наше исследуемое напряжение превышает или ниже опорного. Так как исследуемое напряжение сконфигурировано резистором на уровень 2,5В и ниже, соответственно, мы будем получать значение от 1024 до 0. (Такое сравнение выбрано, чтобы не терять лишнюю дискретность).
Далее, аналогично с первым опытом были измерены значения температуры в попугаях относительно эталонного термометра. Полученные показания видны на том же графике (бордовая кривая). Как можно видеть, бордовая кривая лежит ниже голубой, что объясняется сопротивлением балластного резистора. Нам это нисколько не мешает, но необходимо будет ввести поправку.
Теперь, наша задача заключается в том, чтобы привести значение в "попугаях" к значению в градусах цельсия. Для этого исследуем зависимость этих двух величин:
Как можно видеть на графике, она представляет собой ветвь функции y = sqrt(x). Видна обратная зависимость значений (в красном квадрате) В нашем случае не требуются очень точные измерения, поэтому мы можем привести следующие простейшие преобразования:
1. Превратим обратную зависимость в прямую. Для этого y = 1024 (макс. значение АЦП) - x
2. Возьмём функцию y = kx + b. K подберём экспериментально, у меня он составил 13,24 для данной системы (при изменении сопротивления хотя бы одного резистора это значение изменится).
3. Сдвиг b подберём эмпирически, у меня он составил 4 единицы (это сдвигает полученный график ближе к середине характеристики), таким образом, погрешность при 25 и при 60 составляет всего лишь 2 градуса Цельсия, что допустимо.
Итак, полученная функция:
Коэффициент округлил до 13, т.к. нет работы с дробными числами. Для тонких термометров необходимо будет её реализовывать, в моём случае это значение нужно лишь для ориентировки, так что им можно пренебречь.
Итак, сверим показания термометров - заводского и нашего (самодельного):
Тут уже сфоткано на тапок, но суть, думаю, понятна. При b = 0 показания сходятся на 28 градусах, на 60 градусах расходятся на 8. При b = 4 Показания равномерно расходятся на 3-4 градуса, поэтому, для получения искомой температуры отключения выгоднее пользоваться попугаями (они более точны), а это значение использовать лишь для визуальной ориентировки.
Была идея сделать пост, посвященный именно термостатированию, если у меня дойдут руки, там исправим все эти недостатки.
5. Реализация работы с ТЭНом
Собственно, мы получили возможность измерять температуру в баке. Для работы ТЭНа реализуем две примитивные проверки:
Проверки сделаны "в 3 этажа", т.к. если делать только одну, то случайная помеха будет вызывать процедуру остановки машины. Периодически такие помехи у меня проскакивали. Поэтому, значение будет подтверждаться аж 3 раза, через 1мс и затем через 10 мс. Если же оно установилось, то ТЭН отключается.
- Первая проверка - догоняем до 60 градусов - 300 попугаев и выключаем ТЭН.
- Вторая - если попугаев очень мало или очень много, значит что-то у нас не так со схемой, выдать ошибку MINTEMP
Собственно говоря, для работы с ТЭНом машинки этого более чем достаточно. Никакого термостатирования в данном случае не требуется, так как машинка достаточно неплохо сохраняет тепло. Если будет необходимость в дополнительном подогреве, нужно будет ещё раз вызвать включение ТЭНа в программе. На данный момент бак прогревается до 62-63 градусов (по самодельному "термометру" это 59-60). После чего сохраняет такое тепло до 30 минут, этого достаточно для одной фазы мойки. Затем можно и подогреть чуть-чуть.
Вот и всё, ребята. На данном этапе практически все приготовления к работе машинки закончены. Программа разрабатывается уже больше месяца, из нереализованного остался только смягчитель воды. Теперь нужно лишь прописать рабочую программу (примерный макет её я набросал):
После этого можно будет испытывать получившийся результат. Далее дело, как говорится, за малым, а с вами был как всегда Kekovsky, спасибо, всем приятных выходных.
Пишем свой софт для посудомоечной машины ч. 3.1. Реализуем расходомер (+ электронный счетчик воды)
Всем привет! Этот пост - продолжение серии про написание софта для посудомоечной машины с реверс-инжинирингом.
Часть 1. Вступление
Часть 2. Написание каркаса программы
Собственно говоря, какое-то время меня не было, т.к. был вынужден заниматься добычей пропитания (собственно, как и все). Но речь не об этом. Были сделаны доработки, проведены первые испытания на машине:
Сама программа за прошедшее время немного увеличилась и обросла различными багами и костылями:
Давайте по порядку. Кое-что из поставленных ранее задач было выполнено, однако, до готового продукта ещё есть некоторая дистанция. На текущий момент необходимо было сделать обработку входных датчиков. Как уже упоминалось в первом посте, датчики у нас были следующие: датчик температуры, датчик воды, датчик соли и 3 микропереключателя. Последние обрабатываются очень просто, достаточно лишь добавить такие макроподстановки:
Т.е. грубо говоря, текущее значение напряжения на данном порту (логическое) сравнивается с требуемым значением. Для этого входной регистр сдвигается на такое число раз, каков номер исследуемого пина, после чего с помощью простого логического И с 0x01 от него "отрезается" крайний разряд. Соответственно, далее делаем сравнение с требуемым логическим уровнем. Если условие удовлетворяется, то делаем какое-то действие. Самое простое - проверка аквастопа (аварии) и датчика соли с компаратора:
Аналогичным образом проверяются кнопки (в нашем случае у нас одна кнопка питания). Т.е. если была нажата кнопка питания или же сработал аквастоп, то вызывается процедура остановки машины. Она отключает выходной порт и выводит сообщение об ошибке.
Впрочем, это не самое интересное. Далее дошла очередь до вывода FM. Вот тут сказалось то, что я плохо знал устройство машины. Я предполагал, что геркон FM срабатывает при заполнении бака, аналогично аквастопу. По факту же оказалось, что сигнал с выхода FM по сути представляет собой стробирование. А сам FM - расходомер, в котором циклично крутится поплавок. Поступила задача - реализовать электронный счетчик этого самого расхода воды. Для этого навесить на контроллер ещё дополнительный функционал. Благо, задача эта несложная. Наш контроллер ATMEGA328 имеет для этого все необходимые мощности. Вот, как выглядит этот самый расходомер. Видно платку и геркон:
Существовало два варианта обработки этого датчика - при помощи сложения сигналов (для этого внутренний таймер нужно настроить на ту же частоту, что и расходомер, после чего выполнить дискретизацию, и записать общее время совпадения, в момент, когда сигнал станет равным нулю). Но этот метод не очень подходит по следующим причинам:
1. Период оборота геркона может быть разным, он зависит от напора, так же попавший пузырёк воды может сбить фазу и привести к неверным выходным данным.
2. Необходимо перенастраивать имеющийся таймер, или же задействовать другой.
Поэтому для реализации счетчика воды решено было использовать второй вариант - прерывания. ATMEGA328 поддерживает два их вида - INT и PCINT. Первое - хорошее дело, так как на оба вывода прерывания выделяется отдельный обработчик. Но увы, они у нас висят на порту D, который в нашем случае хорошо зарекомендовал себя, как выходной порт (т.к. изначально я не думал, что прерывания мне там понадобятся). Так что придется задействовать программные прерывания PCINT, которые можно навесить на любой порт. К тому же, в используемом мною методе обработки это не имеет особого значения. Для начала необходимо определить тайминги. Для этого снимается осциллограмма со входа:
Как можно видеть, в среднем, весь пик занимает интервал в 30 мс. Поэтому для борьбы с помехами и дребезгом мы используем в прерывании метод двух замеров:
Внизу инициализируется прерывание для группы 1 пина 2 - PCINT10, что в нашем случае PINC-2. Пока что оно не согласуется с конфигом, это такой небольшой костылёк, возможно, он будет потом исправлен. В самом прерывании происходит следующее: подстановка FLUID_HOLD - это проверка состояния PINC-2. То есть, прерывание PCINT возникает всегда, когда происходит событие на линии PCINT. Но если при этом у нас это не высокий уровень сигнала на пине C2, то оно идёт мимо и не занимает много лишних тактов. Если же это нужное прерывание, то следом вызывается задержка, спустя 20 мс делается второй замер по этому же пину. Если значение не изменилось, то "горбик" сигнала засчитывается.
Тут есть щекотливый момент: подразумевается, что прерывания не будут вызываться вторым этажом. Иначе же прерыванию необходимо запрещать себя, выполнить задержку, после чего восстанавливаться. Возможно, это место будет переделано - это увеличит точность борьбы с дребезгом. В общем и целом, на осциллограмме это выглядит так:
Красная линия - произошло событие на шине. Оранжевая - событие подтвердилось, это была не помеха. Для контроля получившегося "протокола" к системе была быстро подключена ардуина, выдающая пачку импульсов. Количество импульсов должно быть равным как на передатчике, так и на приёмнике:
Было передано 99 импульсов, пришло 100. Это сделано специально, первый импульс приходит при перезагрузке Arduino. В общем и целом всё соответствует. Интервал 30 мс. Потерь нет, лишних срабатываний тоже нет. Но ардуино связывается по притянутой к земле помехоустойчивой шине. Поэтому при реальных испытаниях всё же возможны ложные срабатывания из-за недостатков алгоритма.
Давайте попробуем залить бак машины, для начала, по времени. Для этого используется цикл из предыдущего поста. Он был подвергнут изменениям, а именно, убраны команды на отключение агрегата. Подразумевается, что вся шина обнуляется, а затем включаются нужные приборы. Тут палка о двух концах - при таком способе каждое состояние обязано хранить лишние команды на включение. Но, при этом, не надо отслеживать, если что-то забыли выключить:
Итак, включаем заливку по времени. На 25 секунд. Опытным путём установлено, что этого времени достаточно для того, чтобы заполнить бак до определенной черты. Давайте посмотрим, сколько импульсов насчитает расходомер:
В полевом варианте всё это выполняется на стареньком ноуте:
Теперь немного из начального курса метрологии. Мы получили значение в 271 попугай. Теперь надо определять, есть ли ошибка и какова случайная составляющая данной величины. Давайте повторим эту же процедуру 6 раз, и сравним результат. Стандартное отклонение, в нашем тяжелом случае, не должно превышать 5.
Итак, результат:
Для сельской местности сойдёт. В принципе, результаты не берутся с потолка, при прочих равных условиях (одинаковый напор воды, одинаковое время включения) величина ошибки не слишком уж и велика. Далее оценим линейность измерения, чтобы определить накопленную ошибку, характерную для счетчиков. Для этого выберем интервалы от 5 до 30 сек и проведем замеры:
Как видно, небольшая ошибочка всё-таки накапливается. Но стоит учесть тот факт, что при заливке в течение 30 секунд, вода уже начинает выливаться из бачка машины. Т.е. имеется ввиду, что более этого времени счетчик работать не будет, он будет обнуляться. Поэтому даже ошибка в 7% в данном случае приемлема. Хотя, конечно, хотелось бы более точных результатов.
Но тут, как говорится, живы будем - не помрём, если сильно загорится - код перепишем. Кстати говоря, явно заметно кореллирование наших попугаев с секундами. Не знаю, было ли так задумано производителем или случайно так вышло.
В общем, осталось только физическое обоснование. Делается оно аналогичным образом. За 30 секунд машинка наливает воду до определенной черты. Давайте просто сольём машину (DRAIN_ENABLE на 30 секунд) и до этой же черты просто нальём воду в бак из мерного стакана.
Для заливки до отмеченной ранее черты понадобился 1 литровый мерный стакан и ещё примерно 550 мл воды. В нашем случае получается, что один попугай примерно равен 6 мл водицы. Следовательно, расход воды в машинке примерно равен 3л/мин при стандартном напоре по 12мм трубе. Так и запишем. В дальнейшем в программе при заливке воды будем считать уже не по таймеру, а по попугаям.
Впрочем, тут придумалась небольшая физическая задачка. Сколько времени понадобится, чтобы в случае поломки расходомера залило соседа снизу? Ответ: при кухне в 8 метров квадратных, если учесть, что залитие произойдет при уровне воды в 1 см, для этого достаточно будет лишь 26 минут зависания программы с открытым клапаном. Поэтому, ребята, посудомойки без присмотра лучше не оставлять. А нам лучше сделать дополнительный контроль по таймеру, помимо аквастопа. Чтобы если в течение минуты требуемые попугаи не набежали, была возможность этот самый клапан прикрыть до выяснения обстоятельств. Эти проверки легко реализуются в различных функциях программы, я оставлю их за кадром пока.
В части поста 3.2. Будем измерять реализовывать термодатчик, дабы можно было ещё и пару поддать, а не только воду экономить.
Всем спасибо, с вами был Kekovsky.
Пишем свой софт для посудомоечной машины ч. 2. Пишем костяк программы
Всем привет! Рад, что понравился мой предыдущий пост. В этой части будет, собственно говоря, то что хотел также поместить туда, но не стал раздувать пост. Она не такая интересная ибо, в основном, работаем с программой. Писал я её 2-3 часа в день в свободное время, так что на текущий момент сделано не много (относительно). Многое ещё нужно доработать или исправить.
Продолжим с того, что мы практически подключили железо. Далее заходим в WinAVR Atmel Studio и пишем. Начнём с создания конфигурационного файла, в котором сразу же укажем назначенные порты и пины микроконтроллера для того, чтобы в будущем была возможность расширить/заменить/переназначить выводы под разные платы без значительных изменений в самой прошивке. Выглядит это на начальном этапе примерно так:
Далее очередь макроподстановок (substitutions) под эти порты для удобной работы. Можно тупо оперировать регистрами, сразу по ходу дела устанавливая на выходной порт значения типа 0x62, 0xCC и т.д., но мы будем всё расписывать для того, чтобы было понятно и самим не запутаться.
Для проверки правильности работы этих макроподстановок пишем каличную мини "программку" на задержках. В нашем случае она включит залив примерно на 12,7 с, далее насос на 25,5с и опять слив на 12,7с. (значения выбраны произвольно).
Для проверки на железе заменил свой переключатель на DuPont пины, попутно выведя на них все датчики в т.ч. DOOR и ISB, которые пока не задействую. Также питание +5V от платы. В готовом виде выглядит это так. Релюшки успешно щелкают:
Далее создадим некое подобие структуры приложения. Учитывая, что программирование под AVR чисто процедурное, никаких классов и экземпляров создавать не надо, поэтому особого труда это не составит.
Попутно также прикручена каличная библиотека для LCD1602, написанная по памяти. Пока что не умеет в русский язык, работает медленно, возможно, подлежит дальнейшей замене, но для отладки её хватает на все 100. Вынес в отдельную функцию нашу "программу" самым очевидным образом:
Далее, возможно, будет несколько разных программ. Как уже смеялись в комментах к предыдущему посту, ошибка пока что будет на уровне "ЕГГОГ", но это не страшно, это всё поправимо.
Далее прикрутил таймер. Т.к. моя микро библиотека 1602 на текущий момент имеет лишь одну функцию - последовательный вывод массива Char'ов (да и те только латиницей), пришлось городить данные костыли для вывода текущего времени таймера (что помогло мне его отладить), со временем это будет исправлено, если будет в этом потребность. Далее занялся вводом с кнопок и датчиков. Для тестирования вывел все выводы подряд на дисплей. Сделано это было не зря - как выяснилось, некоторые порты были замкнуты между собой соплями из припоя на переходнике, возникшими вследствие многократной перепайки контроллера. Эту проблему устранили, после чего всё стало определяться нормально.
Сама процедура программы к этому моменту стала выглядеть так, и уже можно начать установку каких-то условий её работы:
Собственно говоря, реализована она самым очевидным образом, т.к. я никогда не учился на программирование, сделал так, как пришло мне в голову. Программа разбивается на этапы (0-99), на каждом этапе производится какое-то действие (или несколько), после чего заводится на определенное время "будильник" (а как лечить будильники мы уже знаем). Этому же будильнику в память передаётся номер следующей стадии, на которую он должен будет перейти по завершении отсчета (если всё пройдёт нормально). Когда ему приходит 100 стадия, он сам себе запрещает прерывание и останавливается. Т.е., грубо говоря, в процессе работы он отнимает только незначительное количество тактов на проверку того, закончилось ли время. В остальное время программа возвращается в главный цикл, и всецело может следить за показаниями датчиков, аварийными показателями, обрабатывать нажатия кнопкок, менять по мере необходимости состояние портов и т.д. Что самое интересное, программа заработала у меня практически сразу, однако, я долго не мог понять, почему она пропускает одну стадию. Через час отладки и копания кода выяснил, что забыл там оператор break. Что ж, бывает..
В конечном итоге программа научилась:
- Выводить данные о состоянии и ошибках на LCD-модуль
- Принимать (но пока не обрабатывать) значения со внешних датчиков
- Выполнять заданную программу по циклу (пока ещё без поправки на показания датчиков)
Далее, в первую очередь, необходимо:
- Реализовать ветвление программы с поправкой на показания датчиков (для этого нужно определить режимы работы этих датчиков при помощи различных опытных испытаний, об этом в следующем посте)
- Доделать реализацию паузы программы с возможностью продолжения с остановленного места
- Подключить АЦП и реализовать снятие данных с термометра, для возможности безопасного включения ТЭНа
- Расписать одну более-менее качественную циклограмму, которая позволит запустить машинку и в тестовом виде что-то в ней помыть.
В комментариях меня просили:
- Реализовать лог машинки и запись последнего состояния её регистров в EEPROM, для продолжения мойки с остановленного места при отключении питания.
Ребят, возможно, это и будет сделано, но на текущий момент абсолютно не вижу в этом необходимости. Это желательно для машинок, которые будут проданы покупателям, но в моём случае гораздо быстрее просто включить слив на 1-2 минуты в начале программы, который удалит оставшуюся воду и начнёт процесс заново. Насчет того, что ТЭН включится насухую - это теоретически возможно, но если всё грамотно расписать, то это произойдет только в случае аварийного замыкания AVR или ULN'ки. Тут уже никак не отследишь.
Всем спасибо, с вами был Kekovsky. До новых встреч.
Пишем свой софт для посудомоечной машины ч. 1. Реверс-инжиниринг
Всем привет! Предупреждаю заранее, данный проект не является сколь-либо экономически выгодным. За время, затраченное на эту работу, можно было заработать на несколько таких новых посудомоек. Целью данного поста является демонстрация примера разработки ПО для небольшой автоматики в кустарных условиях (аналогичных производственным). Если из этой идеи получится что-то стоящее, то исходные коды проекта я потом выложу. Писать код буду в реальном времени по мере возможности. Конкретно в данном посте мы изучим устройство этой машины, подготовим платформу, и загрузим первую тестовую программу.
Итак, попала ко мне в руки вышедшая из строя посудомоечная машина. Было выяснено, что её агрегаты (соленоиды, насосы и т.д.) находятся в исправном состоянии. Вышел из строя сам контроллер, где находится программа для управления этими приборами. Что, скажу я вам, весьма серьёзная ситуация - ведь без этого контроллера большая и дорогостоящая машина подлежит отправке на помойку. В интернете я уже видел подобные проекты, но они были сделаны как-то халтурно, не уверен, что они вообще работали. Для написания подобного ПО в производственных условиях программисту уже должны быть даны технические параметры всех приборов и назначение выводов. Но у нас нет ни оригинального контроллера, ни исходников. Поэтому нет никаких шансов восстановить заводское ПО. В таком случае, будем писать своё. Но для начала необходимо изучить, что собой представляет машина - ведь у нас нет практически никаких данных, все провода для нас отличаются только цветом. Первым делом, выпаиваем старый, вышедший из строя контроллер:
Далее, мы видим на плате микросхему ULN2003 (моя называется иначе, но 2003 в названии сути не меняет). Подпаяем к прибору специальную платку (состоит из резисторов и блока переключателей):
Итак, из даташита мы знаем, что микросхема ULN2003 имеет семь входов и семь выходов с инвертированием сигнала. Сделано это для удобства подключения к реле - при подаче логической единицы 5В на вход микросхемы, выход подтягивается к земле и в катушках реле начинает течь ток. Мощный прибор, подключенный к реле, включается в работу.
Для определения этих самых приборов плату устанавливаем на машину, после чего щелкаем переключателями по очереди. Методом проб переключателей было выяснено, что каждый из 7 выходных пинов выполняет свою функцию:
1. Запуск центробежного насоса (ЦН) на большой скорости
2. Запуск ЦН на малой скорости (половинная загрузка?)
3. Открытие входного клапана (залив воды)
4. Открытие дозатора моющего средства
5. Включение соленоида, находящегося в баке с солью
6. Включение сливной помпы
7. Включение ТЭНа для нагрева воды.
Теперь стала понятна суть выходного регистра. Далее, была очередь за входным - вот тут сложнее, ибо понять, какой провод за что отвечает было очень сложно. Но, как не зря кстати, совершенно случайным образом мне была ниспослана с неба монтажная схема на этот прибор. Она многое прояснила.
Выявленные опытным путём выводы соответствуют указанным на схеме (выходы - внизу прямоугольника). Однако, также полно внесистемных обозначений. Например, что такое FM? ISS? Это всё пришлось выяснять опытным путём. В результате, спустя некоторое время, схема выглядела уже так:
Входы расположены следующим образом:
1. RE - вход терморезистора (на 9,7КОм), установленного в баке с водой. Он контролирует температуру воды, нагреваемой ТЭНом. Константа зависимости сопротивления от нагрева для него неизвестна (утеряна в заводской прошивке), её предстоит выяснять опытным путём в следующих постах. Пока опустим его. Вход аналоговый.
2. FM - Fluid Meter. Датчик воды. Представляет собой геркон с магнитом, который размыкается при заполнении бака. Вход цифровой.
3. IAQS - датчик (микрик) аквастопа. При его активации включается режим аварии и отключаются все приборы. Вход цифровой. Его мы тоже пока опустим.
4. +5V и ISS. Питание датчика соли. Он выполнен на компраторе LM339, вход цифровой.
5. ISB - неизвестный переключатель, находящийся в дозаторе моющего средства. Его расположение выяснять не стал, для тестового запуска он пока не нужен. Вход также цифровой и опустим его.
6. DOOR - датчик двери (замок). Работает аналогично IAQS.
P1 - пресловутый прессостат, но он в данной машине к модулю не подключается, а работает независимо.
Итого, имеем 4 на данный момент важных входа:
1. RE - его реализуем позже через полумостовую схему измерения
2. FM - проверяется через подтяжку линии к 5В через резистор 10K на плюс питания и 2K к самой линии.
3. ISS - аналогичным образом
4. DOOR/IAQS (их пока можно объединить) - аналогичным образом.
От себя также добавлю 2 кнопки (питание и служебная кнопка), и 6 выводов для работы дисплея 1602 (включен в полубайтном параллельном режиме).
Таким образом, мы определили, что к выбираемому контроллеру для данной машинки предъявляются следующие требования:
1. Наличие 14 и более I/O портов для всех агрегатов (выходной регистр, входы, также для подключения дисплея 1602, которого не было в оригинальной схеме)
2. Наличие на борту таймеров (непосредственно для работы отсчёта времени)
3. Наличие АЦП (для обработки показаний термодатчика)
4. Возможность подключения кварцевого генератора для обеспечения стабильности схемы
Собственно, ничего серьёзного. Подойдёт контроллер ATMEGA8 (но т.к. он уже сильно устарел, заменим на любимый китайцами и ардуинщиками ATMEGA328, они полностью совместимы). Скажу сразу, Arduino в данном проекте мы не используем, пишем на чистом AVR.
Когда контроллер выбран, настало время подготовить плату и приборы для отладки. Начнём с того, что подготовим тестовый стенд для ИМС. Запаяем её и некоторые DuPont пины.
Было / стало:
Далее, подготовим аппаратные имитаторы агрегатов машинки. Кто-то скажет, что отладить можно было и в электронном виде, на что я скажу да, можно. Но часто бывает, что в симуляторе не выявляются некоторые косяки, такие как дребезг кнопок, наводки и т.д., т.к. условия там слишком приближены к идеальным. Плюс ко всему, прибор не очень громоздкий, так что можно изготовить "набор для отладки". Состоит он из платы с микросхемой ULN2003, имитирующей работу нашего модуля и агрегатов (но вместо них установлены светодиоды). Второй модуль состоит из 2 кнопок и 3 переключателей, имитирующих наши важные датчики, также, туда будет установлен терморезистор
Для оптимизации схемы некоторые доработки выполнялись "на соплях" прямо на дисплейном модуле:
Вот так вся эта отладочная установка смотрится после сборки. Выходной регистр назначен на порт D (используется 7 выводов из 8), дисплей - на порт B (6 выводов), входной регистр - на порт C (неполный, 6 выводов):
Подписаны светодиоды, имитирующие приборы и все кнопки с переключателями. В таком виде схему можно отлаживать. Предусмотрено внутрисхемное программирование, сразу накинут кварц на 6 МГц (какой нашел, потом, возможно, поменяю). Для испытания на машинке достаточно будет отпаять с модуля блок переключателей, и установить туда также DuPont штыри, к которым будем подключать макетную плату легко и просто без изменений в схеме. В дальнейшем по завершению испытаний отладочные платы убираются.
Теперь создадим проект под эту схему. Сразу же инициализирую git-репозиторий. Пока что лишь маленькая программка "бегущие огни" на задержках для проверки правильности проводки.
Тут уже вылезли косяки: как выяснилось, две абсолютно новые непаянные ATMEGA328P, лежавшие у меня несколько лет, тупо отказались прошиваться. Судя по всему, вышли из строя от лежания. Такой подлянки я от них не ожидал - ведь стоят сейчас достаточно крупных денег. Пришлось перепаивать три раза сам контроллер с переходника, в итоге выдрал из какой-то ардуины более-менее рабочий. После чего плата завелась. Судя по всему, для решения дефицита комплектующих придется где-то раздербанить немного ардуинов.
Программа запустилась, порты были подключены верно, все приборы успешно запитаны, но дисплей пока не инициализирован. Проверено питание модулей и работа переключателей. Видно, что светодиоды успешно горят, значит, мы на финишной прямой.
Дальнейшие задачи по этому устройству, в основном, программные и заключаются в следующем (будем выполнять во второй части поста):
1. Инициализировать аппаратный таймер, отмеряющий время работы конкретного агрегата
2. Инициализировать дисплей для вывода тестовой информации о состоянии машины
3. Написать тестовую программу, которая позволит залить воду в бак машинки, прогнать её насосом без нагревания в течение 5 минут, после чего слить воду.
В дальнейшем:
- Инициализировать АЦП для корректной работы термодатчика и ТЭНа (какое мытьё посуды без нагрева воды)
- Реализовать функцию паузы / аварийного слива
- Реализовать открытие отсека моющего средства в программе
- Индикация отсутствия соли (вывести с датчика на дисплей)
- Реализовать аквастоп/остановку по замку
Более сложные заморочки, такие как выбор программы под разную посуду, подгонка времени и напора воды под конкретное моющее средство пока реализовывать не планирую, ибо эти фичи, как правило, нужны уже конечному потребителю (да и то не всегда). Для минимальной же работоспособности прибора сойдут и ранее перечисленные функции. Подключение модуля и первые натурные испытания 7-минутной тестовой программы также в следующем посте. Пока что наше изделие ещё не переросло уровень "Ардуина щелкает, светодиодами мигает", но это всё в скором времени поправимо.
А пока всё, с вами был Kekovsky, спасибо всем кто дочитал (если кому-то это интересно). Своё мнение по поводу проекта пишите в комментариях.
Датчик тока в телеграм
Написал давеча пикабушник с предложением собрать простое устройство. После последнего поста про наркоманский контроллер АКБ.
Слово за слово. В общем решили, делать оповещение в телеграм, посредством бота. Ну и конечно, не обошлось без пищалки. Встречайте, датчик тока на esp8266 с оповещением в телегу.
Максимально простое устройство. Датчик тока в виде платы с acs712 на борту. Плата с ESP и потрошки от зарядного устройства APPLE. Разбирать оригинальную зарядку не просто, но надеюсь оно того стоит. Самая дорогая деталь, кстати. Ну и активная пищалка до кучи.
В общем, нарисовал плату.
Максимально просто. Обвязка для управления буззером и делитель напряжения, чтобы калечный вход АЦП не повредить. Изготовил способом ЛУТ - что то про лазеры и утюги.
Опускаем в раствор персульфата аммония, сверлим отверстия и лудим.
Вроде неплохо. Но по сути брак. Случайно заснул и оставил банку с раствором и платой на батарее. Благо, дорожки не 0.3. Запаиваю.
Резистор на базу транзистора уполз вправо. Оказывается, использовать вывод D4 у ESP8266 для пищалки - не лучшая затея.
Как то так. Синий - разъем для питания. Зеленый - для замера силы тока. И вроде все хорошо, прошивка готова, пора готовить устройство к отправке. Остались финальные тесты. Подключаю питание к синему разъему... и, ничего. Что то не так. Снимаю плату зарядного устройства.
А кто это сделал? В общем, поэтому и не работало. Под соплей спрятался небольшой конденсатор. Убираю лишнее, скрещиваю пальцы и пытаюсь запустить по новой. Вроде есть 5.1 вольт.
А вот примерно так выглядит тестовый бот.
Первый раз пробую такой вариант управления - он безумно удобен. А главное очень простой. Напомню, устройство должно засекать время, когда подключенный через него насос не будет работать. То есть, не работает, скажем 12 часов, значит нужно подать сигнал и отправить смс. В настройках можно выбрать время срабатывания. А также отключить надоедливые оповещения, которые будут сыпаться раз в час, днем и ночью. Можно посмотреть сервисную информацию. Там время работы микроконтроллера с момента включения, время с последнего включения насоса и установка времени срабатывания. Просто и удобно.
Результатом доволен. Впереди последние тесты и отправка устройства заказчику.
Моя телега https://t.me/bb773301
Моя пустой сайт http://safboard.ru/