Чтение сигнала с лямбда зонда

hyperion
Offline
Зарегистрирован: 23.12.2015
Добрый день. Делаю БК для старого прадика в котором протокол 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 секунды потому и данные на экране обновляются с этой же частотой.)

b7f04ff3-4e0f-49dc-9f9f-731f2ba05eaf.jpg

 
 
85aa41aa-6f84-4a84-8615-cd4c5cfc468c.jpg
Olej
Olej аватар
Offline
Зарегистрирован: 05.03.2018

hyperion пишет:

Делаю БК для старого прадика в котором протокол Toyota OBD1.
Вообщем хочется читать лямбду в диагностических целях.

Для полноты картины хотелось бы понимать кто это такой "старый прадик" (ой! ...)

И что это за лямбда, и в каком месте у старого прадика эта самая лямбда растёт?

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

что-то как-то муторно. Может просто по значению АЦП выводить два состояния, богатая или бедная. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

hyperion пишет:
Вообщем хочется читать лямбду в диагностических целях.

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

hyperion
Offline
Зарегистрирован: 23.12.2015

Olej пишет:

Для полноты картины хотелось бы понимать кто это такой "старый прадик" (ой! ...)

И что это за лямбда, и в каком месте у старого прадика эта самая лямбда растёт?

TLC Prado 95, 97Го года с двигателем 5VZ

БК пока что получился такой :)

e378bb5s-960.jpgff78bb5s-960.jpg

Лямбда зонд как и у всех машин, в выпускном коллекторе :)

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

hyperion пишет:

TLC Prado 95, 97Го года с двигателем 5VZ

Лямбда зонд как и у всех машин, в выпускном коллекторе :)

В праворуких япошках тех годов зачастую две лямбды, одна сразу в штанах, на выходе из движка, вторая после первого расширения выхлопной трубы, территориально примерно под местом для ног переднего пассажира.  Это у чортовых япошек борьба за ыкалогию была в те годы, поэтому они лямбды ставили до и после катализатора.  Не знаю насчёт VZ, у мня на 3S, 5S и 2MZ две лямбды стояло. 

hyperion
Offline
Зарегистрирован: 23.12.2015

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

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

hyperion
Offline
Зарегистрирован: 23.12.2015

не, лямбда одна 100%. Стоит перед катализатором. За катализатором датчик температуры выхлопных газов. Это насколько я слышал у американских калифорнийских 4runnerов тех годов две лямбды.

evgta
Offline
Зарегистрирован: 02.09.2016

Вторая лябда стоит на части евро три, и на всех с евро четыре, служит для контроля исправности катализатора. Обычная и новая лямбда насколько помню, при бедной смеси показывает 0.2В , при богатой 0.8В, переходом принято считать 0.4В.
Существуют ещё параметрические лябды, стоят на Ауди и Фольксвагенах.

Исправная и свежая лямбда имеет вертикальные фронты, по мере старения фронты все сглаживаются а напряжение становится меньше 0.8 , затем лямбда перестает работать на холостом ходу, и вскоре совсем помирает "радуя" запахом из глушителя и расходом топлива

hyperion
Offline
Зарегистрирован: 23.12.2015

Хм пришла в голову еще одна идея. Есть такая штукаf01d81as-960.jpg

которая зажигает диоды в зависимости от входного напряжения. 0В - 0 диодов 1В - 10 диодов. Конечно 10 цифровых пинов использовать на МК слишком будет жирно. Предполагаю что может существуют какие то микросхемы по типу сдвиговых регистров, но наоборот. Собрать 10 регистров в один поток битов. Анализируя его можно будет сделать вывод о том какое напряжения на лямбде с минимум вычислений. Даже прямо через прерывания все можно будет сделать наверное

Нашел, есть такая штука, но не подойдет.

http://robocraft.ru/blog/arduino/541.html

это еще один spi использовать.. 

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

hyperion пишет:

это еще один spi использовать.. 

А сколько их у Вас всего?

hyperion
Offline
Зарегистрирован: 23.12.2015

два, делаю на stm32duino. Проц Stm32f103

Один занят tft экраном. Второй в принципе свободен но что то костыль из LM3914+74HC165 да еще и по 5 проводам. бррр :) 

evgta
Offline
Зарегистрирован: 02.09.2016

А зачем знать какое напряжение на лябде? Она промежуточных значений не показывает, либо 0.2 либо 0.8 (исправная) , гораздо интереснее видеть скорость нарастания от 0.2 к 0.8 т.к это показывает степень изношенности лямбды.

Это если она не пяти проводная. Если 5ти то она показывает содержание кислорода в выхлопе.

hyperion
Offline
Зарегистрирован: 23.12.2015

лямбда узкополосная. Провода 4. Два на подогрев. Два сигнальный и масса. Напряжение хочется знать потому что прочитал что умирающая лямбда теряет помимо скорости переключения еще и диапазон напряжений.

evgta
Offline
Зарегистрирован: 02.09.2016

К тому времени когда у нее начнется понижаться напряжение она уже перестанет работать на холостом ходу. Так что в принципе достаточно знать что напряжение постоянно переключается на границе 0.4 В.

MaksVV
Offline
Зарегистрирован: 06.08.2015

hyperion пишет:
Вообщем хочется читать лямбду в диагностических целях.

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

MaksVV
Offline
Зарегистрирован: 06.08.2015

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

MaksVV
Offline
Зарегистрирован: 06.08.2015

вот вам для размышления 

evgta
Offline
Зарегистрирован: 02.09.2016

Ну как бы когда начинает помирать лямбда, чек должен загореться , так что смыла мудрить не вижу, если только всё-таки смотреть график по которому определить ее степень изношенности.

MaksVV
Offline
Зарегистрирован: 06.08.2015

это не факт, мониторинг состояния датчиков на таких старых автомобилях был слабый и примитивный.  

evgta
Offline
Зарегистрирован: 02.09.2016

У меня пыж 206, так в нем чек загорается если только снять разъем с катушки зажигания, и при неисправности лямбды, сам проверял отключил все датчики кроме ДПКВ а чек так и не загорелся , хотя и двигатель не заглох)))

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

hyperion пишет:

два, делаю на stm32duino. Проц Stm32f103

Ну, вообще говоря, SPI придуман как раз для того, чтобы одним SPI управлять множеством различных устройств.

Цитата:

Один занят tft экраном. Второй в принципе свободен но что то костыль из LM3914+74HC165 да еще и по 5 проводам. бррр :) 

Для 165 регистров достаточно 2 проводов.

MaksVV
Offline
Зарегистрирован: 06.08.2015

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

hyperion
Offline
Зарегистрирован: 23.12.2015

Ну по сути да, это показометр ради показометра. Конечно проще будет ее поменять и забыть на года 3 о ней :)
Моего поколения ЭБУ показывает чек по лямбде только когда она совсем все. Нету кода на медленное ее переключение и низкий диапазон напряжения. Это с рестайла пошло года с 2002го

MaksVV
Offline
Зарегистрирован: 06.08.2015

hyperion пишет:
Конечно проще будет ее поменять и забыть на года 3 о ней :)

советую так и сделать . Универсальная лямбда от бош стоит немногим более 1тыс рублей. Зато с новой можно адекватный сигнал воспринимать по составу смеси. Помоему это более важная инфа. 

b707
Offline
Зарегистрирован: 26.05.2017

MaksVV пишет:

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

а должен? :) у меня за 7 лет чек загорался один раз - когда  прошивку в ЭБУ меняли...

Но приятель - ваще-та лох :)  Все лампочки при включении зажигания должны загораться на короткое время.