Чтение сигнала с лямбда зонда
- Войдите на сайт для отправки комментариев
Ср, 14/03/2018 - 20:49
Добрый день. Делаю БК для старого прадика в котором протокол Toyota OBD1.
Вообщем хочется читать лямбду в диагностических целях. А может и прикрутить еще какую нибудь математику к этому.
Вообщем в связи с тем что сигнал от 0 до 1В, прерывание тут не подходит. На ум пришло только использования таймера.
Суть алгоритма пока такая. Есть 4 массива. Массив минимумов, максимумов, и соответсвенно временные точки максимума и минимума.
По ним можно будет посчитать и выводить амплитуду и частоту.
Массив макс и мин заполняется значениями 0.5В процедурой инициализации. Временные точки при инициализации обнуляются.
Каждые х-мс считывается напряжение с лямбды. Сразу фильтруется все что больше 1В. Далее если полученное напряжение больше 0.5В то считается максимум и его время. Если меньше то минимум и его время. И заносятся в первую ячейку массива.
Переход на следующую ячейку происходит когда начинается подсчет нового минимума. И так пока не заполнится весь массив. Как заполнился - считает и выводим на экран.
Код примерный, отражает только алгоритм по которому планирую считывать данные.
#define VREF_MEASURED 3.32 #define O2_PIN PA2 //D9 struct O2_STRUCT { volatile uint16_t max[255]; volatile uint16_t min[255]; volatile uint16_t t_max[255]; volatile uint16_t t_min[255]; volatile uint16_t current; }; O2_STRUCT O2; volatile byte i; volatile boolean flag = true; void setup() { // put your setup code here, to run once: pinMode(O2_PIN, INPUT_ANALOG); //таймер для считывания напряжения с лямбды скажем каждые 20мс HardwareTimer timer(1); timer.pause(); timer.setPeriod(10000); //микросекунды timer.setChannel1Mode(TIMER_OUTPUT_COMPARE); timer.setCompare(TIMER_CH1, 1); timer.attachCompare1Interrupt(ISR_O2); timer.refresh(); timer.resume(); for (uint8_t ii = 0; i < 255; i++) { //Инициализация массива для корректного сравнения O2.max[ii] = 620; O2.min[ii] = 620; O2.t_max[ii] = 0; O2.t_min[ii] = 0; } } void loop() { if (i == 254) { timer.pause();//останавливаем таймер ////Бла бла бла выводима на экран шайтанами щитаем все такое for (uint8_t ii = 0; i < 255; i++) { //Инициализация массива для корректного сравнения O2.max[ii] = 620; O2.min[ii] = 620; O2.t_max[ii] = 0; O2.t_min[ii] = 0; } i = 0; //обновляем индекс для нового массива. timer.resume(); //и запускаем снова таймер } } void ISR_O2(void) { O2.current = analogRead(O2_PIN); if (O2.current < 1240) { //сразу откидываем значения больше 1В if (O2.current < 620 && i < 254) { //если текущее значение меньше 0.5в и кол-во значений в массиве меньше 255 if (O2.current < O2.min[i]) { //если текущее значение меньше того что уже есть в массиве O2.min[i] = O2.current; //то записываю новый минимум O2.t_min[i] = millis(); //и время минимума } if (O2.t_max[i] > O2.t_min[i]) i++; //если время максимума больше чем время минимума то начинается новый период } if (O2.current > 621 && i < 254) { //если текущее значение больше 0.5в и кол-во значений в массиве меньше 255 if (O2.current > O2.max[i]) { //если текущее значение больше того что уже есть в массиве O2.max[i] = O2.current; //то записываю новый максимум O2.t_max[i] = millis(); //и время максимума } } } }
данный код еще не тестировался, просто сама идея, может кто нибудь подскажет что то поинтереснее и оптимальнее.
Само считывание вполне жизнеспособно. Проверял. Даже графики строил :) Но там я тупо считал каждые 20мс напряжение и писал на карточку. Сейчас же хочется сделать так чтобы скажем в течении секунды считались и усреднялись макс-мин значения, частота и раз в секунду выводились эти данные на экран (ОБД данные поступают раз в ~1.3 секунды потому и данные на экране обновляются с этой же частотой.)

Для полноты картины хотелось бы понимать кто это такой "старый прадик" (ой! ...)
И что это за лямбда, и в каком месте у старого прадика эта самая лямбда растёт?
что-то как-то муторно. Может просто по значению АЦП выводить два состояния, богатая или бедная.
И вот эта фраза не понятна. Нужна конкретика, особенно по слову читать. Предлагаю замерять два времени: в течение которого сигнал находился в богатой и в бедной смеси. В итоге выводить две цифры за отчетный период, например 10 сек: сколько времени в (%) смесь была богатая, и сколько времени в % - бедная.
Для полноты картины хотелось бы понимать кто это такой "старый прадик" (ой! ...)
И что это за лямбда, и в каком месте у старого прадика эта самая лямбда растёт?
TLC Prado 95, 97Го года с двигателем 5VZ
БК пока что получился такой :)
Лямбда зонд как и у всех машин, в выпускном коллекторе :)
TLC Prado 95, 97Го года с двигателем 5VZ
Лямбда зонд как и у всех машин, в выпускном коллекторе :)
В праворуких япошках тех годов зачастую две лямбды, одна сразу в штанах, на выходе из движка, вторая после первого расширения выхлопной трубы, территориально примерно под местом для ног переднего пассажира. Это у чортовых япошек борьба за ыкалогию была в те годы, поэтому они лямбды ставили до и после катализатора. Не знаю насчёт VZ, у мня на 3S, 5S и 2MZ две лямбды стояло.
В принципе хорошая идея. Надо будет обдумать. Изначально хотелось так - вычислять пиковые максимальные и минимальные напряжения и их моменты времени. На основе этого можно делать выводы о том как она быстро переключается и насколько велик этот размах.
Если делать по вашему то думаю можно будет вычислить частоту переключения, допустим все что больше 0.7В - богатая, а все что меньше 0.3 - бедная. Но не зная пиков нельзя будет сказать насколько она плохо себя чувствует
не, лямбда одна 100%. Стоит перед катализатором. За катализатором датчик температуры выхлопных газов. Это насколько я слышал у американских калифорнийских 4runnerов тех годов две лямбды.
Вторая лябда стоит на части евро три, и на всех с евро четыре, служит для контроля исправности катализатора. Обычная и новая лямбда насколько помню, при бедной смеси показывает 0.2В , при богатой 0.8В, переходом принято считать 0.4В.
Существуют ещё параметрические лябды, стоят на Ауди и Фольксвагенах.
Исправная и свежая лямбда имеет вертикальные фронты, по мере старения фронты все сглаживаются а напряжение становится меньше 0.8 , затем лямбда перестает работать на холостом ходу, и вскоре совсем помирает "радуя" запахом из глушителя и расходом топлива
Хм пришла в голову еще одна идея. Есть такая штука
которая зажигает диоды в зависимости от входного напряжения. 0В - 0 диодов 1В - 10 диодов. Конечно 10 цифровых пинов использовать на МК слишком будет жирно. Предполагаю что может существуют какие то микросхемы по типу сдвиговых регистров, но наоборот. Собрать 10 регистров в один поток битов. Анализируя его можно будет сделать вывод о том какое напряжения на лямбде с минимум вычислений. Даже прямо через прерывания все можно будет сделать наверное
Нашел, есть такая штука, но не подойдет.
http://robocraft.ru/blog/arduino/541.html
это еще один spi использовать..
это еще один spi использовать..
А сколько их у Вас всего?
два, делаю на stm32duino. Проц Stm32f103
Один занят tft экраном. Второй в принципе свободен но что то костыль из LM3914+74HC165 да еще и по 5 проводам. бррр :)
А зачем знать какое напряжение на лябде? Она промежуточных значений не показывает, либо 0.2 либо 0.8 (исправная) , гораздо интереснее видеть скорость нарастания от 0.2 к 0.8 т.к это показывает степень изношенности лямбды.
Это если она не пяти проводная. Если 5ти то она показывает содержание кислорода в выхлопе.
лямбда узкополосная. Провода 4. Два на подогрев. Два сигнальный и масса. Напряжение хочется знать потому что прочитал что умирающая лямбда теряет помимо скорости переключения еще и диапазон напряжений.
К тому времени когда у нее начнется понижаться напряжение она уже перестанет работать на холостом ходу. Так что в принципе достаточно знать что напряжение постоянно переключается на границе 0.4 В.
из вышесказанного я понял, что вы хотите читать лямбду в диагностических целях самого лямда зонда, а не автомобиля. Просто это разные подходы к обработке сигнала - проверять исправность лямбда зонда или исправность двигателя.
просто поставьте новую лямду и никаких хлопот. тыщ на 50 км проблем с этим не будет. Уж лучше мониторить состояние двигателя, зная что лямда зонд заведомо исправен.
вот вам для размышления
Ну как бы когда начинает помирать лямбда, чек должен загореться , так что смыла мудрить не вижу, если только всё-таки смотреть график по которому определить ее степень изношенности.
это не факт, мониторинг состояния датчиков на таких старых автомобилях был слабый и примитивный.
У меня пыж 206, так в нем чек загорается если только снять разъем с катушки зажигания, и при неисправности лямбды, сам проверял отключил все датчики кроме ДПКВ а чек так и не загорелся , хотя и двигатель не заглох)))
два, делаю на stm32duino. Проц Stm32f103
Ну, вообще говоря, SPI придуман как раз для того, чтобы одним SPI управлять множеством различных устройств.
Один занят tft экраном. Второй в принципе свободен но что то костыль из LM3914+74HC165 да еще и по 5 проводам. бррр :)
Для 165 регистров достаточно 2 проводов.
у меня приятель ездит на рено логан, говорит что то чек ниразу за три года не загорался. Полезли лампочку смотреть, а её там нет и как оказалось не должно быть. На Россию не стали ставить на первых логанах)) Нет чека - нет проблем
Ну по сути да, это показометр ради показометра. Конечно проще будет ее поменять и забыть на года 3 о ней :)
Моего поколения ЭБУ показывает чек по лямбде только когда она совсем все. Нету кода на медленное ее переключение и низкий диапазон напряжения. Это с рестайла пошло года с 2002го
советую так и сделать . Универсальная лямбда от бош стоит немногим более 1тыс рублей. Зато с новой можно адекватный сигнал воспринимать по составу смеси. Помоему это более важная инфа.
у меня приятель ездит на рено логан, говорит что то чек ниразу за три года не загорался.
а должен? :) у меня за 7 лет чек загорался один раз - когда прошивку в ЭБУ меняли...
Но приятель - ваще-та лох :) Все лампочки при включении зажигания должны загораться на короткое время.