Подключение лямбда зонда к ардуино
Сегодня в серии публикаций про ардуино головного мозга коротенькая статья с небольшим экспериментом и парой рецептов. В комментариях к одной из моих прошлых статей меня обвинили в том, что ардуиной подсчитывать импульсы энкодера — фу так делать:
Оптически энкодер 1000/оборот и ATMega не имеющая аппаратной схемы работы с энкодером (как у серий STM32, например) — это тупик.
Дальше в комментариях было много теоретизирования, которое лучше пропустить. Давайте лучше попробуем протестировать в железе, насколько это тупик. Для начала, что такое инкрементальный энкодер? Тот, кто помнит эпоху до-оптических мышек, ответ знает точно. Внутри энкодера есть диск с прорезями, вот для наглядности я сделал фотографию диска с пятьюстами прорезями:
С одной стороны этого диска помещают светодиод, с другой фотодиод:
Вращаясь, диск то пропускает свет на фотодиод (если прорезь напротив пары светодиод-фотодиод), то не пропускает. При постоянной скорости вращения на выходе фотодиода получается красивая синусоида (не забываем, что поток света может быть перекрыт частично). Если этот сигнал пропустить через компаратор, то получится сигнал прямоугольной формы. Подсчитывая количество импульсов сигнала, получим насколько провернулся вал датчика.
Как же определяется направление вращения? Очень просто: в датчике не одна, а две пары светодиод-фотодиод. Давайте нарисуем наш диск, точки A и B показывают положение фотодатчиков. При вращении вала энкодера снимаем два сигнала с этих фотодатчиков:
Датчики поставлены на таком расстоянии, чтобы при вращении с постоянной скоростью генерировался меандр, свинутый на четверть периода. Это означает, что когда фотодатчик А стоит напротив середины прорези, то фотодатчик B стоит ровно на границе прорези. Когда датчик крутится (условно) по часовой стрелке, то при восходящем фронте на сигнале B сигнал A равен единице. Когда же датчик крутится в обратную сторону, то при восходящем фронте на сигнале B а равен нулю.
Давайте объясню, как этот код работает. Я тестирую код на ATmega328p (Arduino nano), выходы энкодера поставлены на пины d8 и d9 arduino nano. В терминах ATmega328p это означает, что младшие два бита порта PINB дают текущее состояние энкодера. Функция ISR будет вызвана при любом изменении в этих двух битах. Внутри прерывания я сохраняю состояние энкодера в переменную AB:
Для чего? Давайте посмотрим на предыдущий график, в нём пунктирными линиями обозначены моменты вызова прерывания (любой фронт на любом сигнале). Для каждого вызова прерывания цифры внизу — это состояние переменной AB:
Видно, что при вращении по часовой стрелке переменная AB меняется с периодом в четыре значения: 231023102310. При вращении против часовой стрели переменная AB меняется 013201320132.
Если у нас оба фотодатчика были перекрыты (переменная AB=0), а при вызове прерывания AB становится равной 2, то датчик вращается по часовой стрелке, добавим к счётчику единицу. Если же AB переходит от 0 к 1, то датчик вращается против часовой стрелки, отнимем единицу от счётчика. То же самое и с другими изменениями переменной AB, давайте составим таблицу:
Обратите внимание, что таблица заполнена не до конца. Что вставить на месте вопросительных знаков? Например, по идее, главная диагональ таблицы не должна использоваться никогда, прерывание вызывается при изменении переменной AB, поэтому перехода 0->0 случаться не должно. Но жизнь штука тяжёлая, и если микроконтроллер занят, то он может пропустить несколько прерываний и таки вызваться. В таком случае предлагаю ничего не прибавлять и не отнимать, так как нам явно не хватает данных; заполним недостающие клетки нулями, вот наша таблица:
Теперь, надеюсь, код понятен полностью.
В итоге на один период сигнала A у нас вызывается четыре прерывания, что при вращении датчика в одну сторону увеличит счётчик не на 1, но на 4. То есть, если на инкрементальном энкодере написано 2000PPR (две тысячи прорезей на диске), то реальное его разрешение составляет 1/8000 оборота.
Пропуская синусоиду через компаратор, мы неизбежно получим дребезг на фронтах нашего сигнала прямоугольной формы. Давайте возьмём лупу и посмотрим на один фронтов:
Сигнал A постоянный, поэтому согласно нашей табличке, на восходящем фронте сигнала B мы добавляем единицу, а на нисходящем вычитаем. В итоге, если мы сумеем отработать все фронты нашего дребезга, то наш алгоритм его прекрасно проглотит. И вот тут становится интересно, а сможет ли наша ардуинка отработать такие прелести? Теоретизировать можно долго, давайте ставить эксперимент.
- Софтверно на ATmega328p
- ATmega328p, опрашивающая хардверный счётчик
Подключение
Софтверный счётчик
Подключение простейшее, достаточно два провода от энкодера завести на ноги 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 оборотов в минуту оба хардверных счётчика работали без рассогласований, а больше у меня шуруповёрт выдать не может.
2. Хардверные счётчики надёжнее, но дороже.
3. hctl2032 существенно дешевле BeagleBone Blue, но и сложнее подключается к контроллеру, а биглбон и сам себе контроллер, и умеет четыре энкодера разом обрабатывать. Да и усилитель для двигателя там уже есть на борту, поэтому стенд с маятником можно собрать вообще малой кровью. С другой стороны, даже будучи довольно экзотичной, hctl-2032 стоит пять долларов за штуку, и может спасти ситуацию, когда схема с каким-нибудь пиком или атмелом уже есть, и сильно менять её не хочется.
4. Говорят, stm32 и дёшев, и имеет хардверный счётчик. Но цена вхождения (в смысле времени) в вопрос больно кусается.
В общем, как обычно, идеального решения нет, всё зависит от задачи и от доступных ресурсов.
Заинтересовался темой газоанализаторов и с толкнулся с одной проблемой. Для Arduino есть куча датчиков на горючие и опасные газы, но таких же компактных датчиков на кислород не увидел. Есть разные кислородные зонды, типа "лямбда", для автомобильной техники. Но для того, чтобы определить содержание кислорода в помещении, такого не нашел. В портативных ручных газоанализаторах какие то датчики используются, но в интернете не смог о таких ничего найти. Если кто в курсе темы подскажите в какой стороне искать. Спасибо.
Определение фактов заправок по датчику уровня топлива
Есть сигнал с датчика уровня топлива в баке. Нужно определить все факты заправок. ( выделены.
Определение уровня дерева
Кто знает, подскажите пожааалуйстаа как можно определять уровни дерева? (Корень - считать первым.
Определение уровня громкости в dB
Всем привет. Помогите реализовать вывод уровня громкости в dB. Источник звука микрофонный вход.
покопавшись в интернете пришел к выводу, что большинство датчиков газа работают по принципу адсорбции на метал-оксид пленке, и измеряют проводимость адсорбента; существуют еще колориметрические, которые по изменению сопротивления зонда, зависящего от его температуры, через мост Уитстона, определяют концентрацию сгораемого на зонде газа; но, первый вариант не сепарирует газы, и в следствии этого там вообще большой вопрос что адсорбируется, то ли кислород, толи все что попало; во втором варианте датчик детектирует только на выбранный газ, и это не совсем удобно, а кроме того он используется в основном на горючих газах
схемы именно по детектированию кислорода так и не нашел
Определение уровня вложенности подсписка
Помогите пожалуйста написать функцию для CLISP, на вход которой задаётся список вида ( a b ( c d e.
Определение уровня Junior C++ developer?
Доброй всем ночи. Как и многие здесь я недавно встал на нелегкий но приятный путь изучения С++.
Определение уровня атома в списке
Здравствуйте! Необходима помощь в решении задачи. Написать программу, которая определяет.
Директивы и определения верхнего уровня - определение
Рассмотрим следующий .scala файл: package com.myapp.greenhouse class Plant(val name: String).
Определение уровня яркости пикселя ч/б изображения
Как определить яркость пикселя черно-белого изображения? Находил такой код(ниже), но объект Color.
Определение числа ветвей n-го уровня бинарного дерева
Вершина бинарного дерева содержит ключ, строку и два указателя на потомков. Написать функцию.
Программа для работа с данными Wi-Fi адаптера (определение уровня сигнала)
Здравствуйте! Подскажите, с чего начать (желательно, пример кода). Необходимо приложение для.
Каждый год с развитием технологий увеличивается комфортабельность пребывания человека на Земле. Вот только к таким благам можно отнести не только широкое применение умных устройств, но и природные потребности человека. Например, потребность в чистом воздухе.
Те, кто бывали в горах, наверняка помнят какой там свежий воздух. Особенно хорошо жить на берегу озера и дышать ароматными травами, цветущими растениями, проще говоря – природой. В загрязненной атмосфере мегаполисов этого всего практически не встретишь, зато можно получить серьезные проблемы со здоровьем.
С помощью Arduino и специального датчика мы можем оценить качество воздуха в помещении или среде, где мы регулярно проводим время, сравнить с допустимыми значениями и принять меры.
Благодаря таким устройствам мы можем взять под собственный контроль ситуацию с загрязнением и обезопасить себя.
Для того чтобы стало понятно, чем вы дышите, нам понадобится специальный датчик газа под названием
Купить его можно в нашем магазине: Датчик MQ-135.
Данный датчик позволяет обнаруживать в воздухе такие газы, как дым, аммиак, бензин, спирт и другие. В схеме он является полупроводниковым прибором, а его чувствительность основана на изменении сопротивления небольшого слоя диоксида олова в так называемом чувствительном слое. Также в датчике есть небольшой нагревательный элемент, который нагревает слой до нужной температуры, с целью реагировать на определенный газ. Из-за наличия нагревателя, датчик способен сильно нагреваться и вообще для него желательно подключать внешнее питание.
Питается он от напряжения в 5 вольт, как и большинство датчиков на Arduino. Подключается по трем контактам. Это контакты заземления и питания, а также контакт управления (это может быть как аналоговый, так и цифровой вывод)
Схему подключения вы сейчас видите ниже:
Измеряет содержание тех или иных газов в воздухе (метан, водород, пропан и др.) в величинах ppm – (миллионная доля) единица концентрации.
Также есть определенный диапазон измерений.
Например, для аммиака это 10ppm-300ppm; для бензина 10ppm-1000ppm; для спирта 10ppm-300ppm.
Полный даташит на датчик есть здесь
Исходя из этих данных, можно определить в норме или выше допустимая концентрация.
Вот табличка предельно допустимой концентрации газов в воздухе:
Давайте разберемся с аммиаком. Во-первых, смотрим на единицы измерения. В таблице это мг/м3. Значение ppm измеряется в мг/л или в мг/дм3
Значит содержание аммиака в воздухе более 200 ppm опасно для человека, а наш датчик сможет это смело зафиксировать и измерить.
В примере демонстрируется подключение датчика и вывод полученных данных в монитор Serial - порта
На этом статья подходит к концу. Всем желаю удачной компиляции и до скорых встреч!
An attempt to build an Engine Control Unit based on stm32.
Широкополосный лямбда зонд + контроллер
Широкополосный лямбда зонд + контроллер
rus084 contributor
Posts: 678 Joined: Sun Dec 01, 2013 1:40 pm Location: Russia , Stavropol
я подключил ДАД просто - от джостика с старой приставки разобрал разъем , к этим кругляшам припаял провода . держится вроде нормально .
Да хочется как-то по человечески, я на крайний случай просто другую пару разьемов возьму. Если отойдет контакт то можно угробить лямбду, там температура нагрева регулируется по обратной связи, можно перегреть.
puff contributor
Posts: 2912 Joined: Mon Nov 11, 2013 11:28 am Location: Moskau
Разьемы пока не особо искал, контроллер полностью протестировать наверно можно только с лямбдой, а работоспособность платы думаю труда не составит.
puff contributor
Posts: 2912 Joined: Mon Nov 11, 2013 11:28 am Location: Moskau
puff contributor
Posts: 2912 Joined: Mon Nov 11, 2013 11:28 am Location: Moskau
кстати. не очень-то понятно зачем там столько разъемов.
плюс и минус питание на плату - понятно. (предохранитель можно сделать выносным на проводе, кстати).
допустим, шесть контактов на сам датчик (хотя нафига?), так? но на предлагаемой плате-то аж 12 контактов выведено?! плюс еще на uart зачем-то 4 контакта (оно что, принимает еще что-то?)
meXanicus contributor
Posts: 314 Joined: Sat Dec 21, 2013 2:42 pm Location: Russia, Rostov-na-Donu
to:puff там еще есть выходы +5в ШДК для подключения к "показометру" или к ЭБУ если в нем есть поддержка данной фичи и +1в УДК для подключения к ЭБУ в место родного УДК
puff contributor
Posts: 2912 Joined: Mon Nov 11, 2013 11:28 am Location: Moskau
цена в экзисте ~2800р (ebay 65 долларов? фиг там! от 3600 без стоимости доставки!)
и всё равно по числу контактов не сходится! или каждый логический - со своей землей?
meXanicus contributor
Posts: 314 Joined: Sat Dec 21, 2013 2:42 pm Location: Russia, Rostov-na-Donu
puff contributor
Posts: 2912 Joined: Mon Nov 11, 2013 11:28 am Location: Moskau
Sergey89 contributor
Posts: 839 Joined: Wed Sep 25, 2013 5:30 pm Location: Russia, Velikiy Novgorod
Начал рисовать схему для STM32.
Для управления током накачки можно использовать встроенный ЦАП.
acab provoker
Posts: 263 Joined: Wed Dec 18, 2013 7:27 pm Location: Minsk, BY
Друзья, может быть, если не трудно, стоит делать работу сразу с двумя ШПЛ зондами? Ведь было бы круто контролировать смесь каждой головы (V-образные движки), ну или когда секвентал или попарный впрыск. А не сразу всё.
Кстати, для тех кто искал коннектор - подходит от VAG 1J0 973 733, стоит понты.
Если говорить о поддержке широкополосника мозгами, то где-то видел готовый фирменный модуль, который можно встраиваь в свои решения. Найду, скину ссылку.
Но если у кого-то получится сделать что-то реально работающее с приемлимой точностью - дайте знать! Но, честно говоря, я не очень то в это верю.
acab provoker
Posts: 263 Joined: Wed Dec 18, 2013 7:27 pm Location: Minsk, BY
Друзья, схема достаточно большая Walltech контроллера. Может быть проще использовать схему Sigma? Она компактнее и проще. Меньше выходов использует у процессора.
puff contributor
Posts: 2912 Joined: Mon Nov 11, 2013 11:28 am Location: Moskau
наверное не зря они отличаются? от валтека можно в смд засунуть. там, кстати, кучу места отнимают клеммники.
к комменту выше - странно что самому нельзя спаять схему, которая бы обеспечивала приемлемую точность при разных температурах.
Maxi Sr Consultant
Posts: 786 Joined: Wed Oct 23, 2013 4:25 pm
puff contributor
Posts: 2912 Joined: Mon Nov 11, 2013 11:28 am Location: Moskau
Maxi Sr Consultant
Posts: 786 Joined: Wed Oct 23, 2013 4:25 pm
puff contributor
Posts: 2912 Joined: Mon Nov 11, 2013 11:28 am Location: Moskau
а, ну мне вот тоже интересно - это _dx вроед бы начал. я так понял, он почему-то взял LC-1 за эталон.
основные претензии, как я понял, зависимость от температуры (как определили?) и некие сбои после определённого срока эксплуатации.
по мне валтек выглядит вполне себе собираемым решением. судя по отзывам в инете - вполне себе выполняющим возложенные на него функции.
meXanicus contributor
Posts: 314 Joined: Sat Dec 21, 2013 2:42 pm Location: Russia, Rostov-na-Donu
puff contributor
Posts: 2912 Joined: Mon Nov 11, 2013 11:28 am Location: Moskau
AndreyB Site Admin Posts: 12662 Joined: Wed Aug 28, 2013 1:28 am Location: Jersey City Github Username: rusefillc Slack: Andrey B
У меня есть плата waltech, я планирую к ней подпаяться и начать программировать под rusEfi с нуля. Я официально ничего во всём этом не понимаю, пожалуйста помогите мне с разжёвыванием всего с нуля. Начну насиловать эту тему
LSU - это что? Lambda Sensor Universal? Кто-то знает?
У меня как раз датчик 4.2, но я так понял бывают еще другие? 4.9 кажется где-то видел?
AndreyB Site Admin Posts: 12662 Joined: Wed Aug 28, 2013 1:28 am Location: Jersey City Github Username: rusefillc Slack: Andrey B
Would IRL3803 - транзистор нагревательного элемента - будет ли управляться 3мя вольтами?
pump driver - насос? как мы это по-русски назовём? аналогичный вопрос - как будут дела с прямым управлением от stm32? Или заводить 5 вольт через TC4427?
puff contributor
Posts: 2912 Joined: Mon Nov 11, 2013 11:28 am Location: Moskau
Sergey89 contributor
Posts: 839 Joined: Wed Sep 25, 2013 5:30 pm Location: Russia, Velikiy Novgorod
pump driver - это драйвер тока накачки. Этот драйвер должен изменять ток через помпу в заданных пределах. Разный ток соответствует разному составу смеси. У нас кстати в stm32f4 есть полноценный ЦАП, который можно использовать вместо программной эмуляции через ШИМ. Но портабельность кода уже будет определяться наличием ЦАП у другого МК.
AndreyB Site Admin Posts: 12662 Joined: Wed Aug 28, 2013 1:28 am Location: Jersey City Github Username: rusefillc Slack: Andrey B
кварц и питание к нам не относятся - я плату запитаю снаружи и проц мой. не важно по большому какая плата для первой версии кода. Эта плата уже есть, в этом ей главный козырь.
puff contributor
Posts: 2912 Joined: Mon Nov 11, 2013 11:28 am Location: Moskau
всё идёт к тому, чтобы городить своё, и наверное, это правильно)
кстати, в том же доке от waltech (в самом его конце) приводятся ссылки на альтернативные реализации.
но в целом, как я понимаю, особых проблем ведь быть не должно? (эх, надо было заложить на франкенштейне пару мест для lm324))
Sergey89 contributor
Posts: 839 Joined: Wed Sep 25, 2013 5:30 pm Location: Russia, Velikiy Novgorod
russian wrote: У меня как раз датчик 4.2, но я так понял бывают еще другие? 4.9 кажется где-то видел?
В lsu 4.9 нагреватель управляется немного по другому и ещё там требуется постоянный опорный ток 20 мкА через помпу.
Читайте также: