Имитация датчиков для проверки электронных блоков автомобиля

chiptuningnt
chiptuningnt аватар
Offline
Зарегистрирован: 22.01.2018

Приветствую форумчане! Сфера моей деятельности автомобильная электроника. Решил сам собрать для себя приборчик для проверки электронных блоков управления снятых с автомобиля эмулируя работу двигателя. Потихоньку изучаю язык, пробуцю писать. Хотелось бы вашего экспертного мнения и подсказки.

Для начала поставил простую задачу, эмитация датчика положения коленчатого вала и распред вала автомобилей ВАЗ. ДПКВ у них стоит индукционный, но при имитации прямоугольной формы сигнала как у датчика хола принимает нормально. Демферный диск на вазах 60 минус 2 зуба, тоесть 58 зубьев и 2 отсутствующих для синхранизации. Вначале сделал имитацию ДПКВ с помощю функции зарержки _delay, все получилось но позже по степени изучения ардуино понял что так одновременно умулировать несколько датчиков независимо от друг друга не получится тк _delay останавливает полностью работу программы на некое время. Переделал, и вроде получилось, сигнал идет правильный, ЭБУ принимает сигнал как должный. Хотелось бы услышать ваше экспертное мнение, может можно как то проще или лучше это сделать. И пока не могу вкупить как сделать эмуляцию датчика распредвала с привязкой к сигналу ДПКВ. Тоесть начиная с определенного зуба установка в HIGH и на определенном зубе LOW

 

// задаем константы
const int PinA = 13; // присваиваем номер контакта выхода сигнала ДПКВ
// const int PinB = 11; // присваиваем номер контакта выхода сигнала ДПРВ

// задаем переменные
byte zub = 58; // задаем переменную и указываем коллечество зубьев задающего диска ДПКВ
// byte propusk = 2; // задаем сколько зубьев будет пропущено
byte schet = 0; // задаем переменную для подсчета зубьев и устанавливаем его начальное значение в ноль
long interval = 10000; // задаем время задержки 

int PinAstatus = LOW; //
long periudMicros = 0; //

unsigned long time;
void setup() {
 Serial.begin(115200); // включаем COM порт и задаем скорость его работы
 pinMode(PinA, OUTPUT); // задаем режим работы циврового контакта PinA(12) на выход
 // pinMode(PinB, OUTPUT); // задаем режим работы цифрового контакта PinB(11) на выход
 digitalWrite(PinA, LOW); // устанавливаем вывод PinA(12) в состояние LOW
 // digitalWrite(PinB, LOW); // устанавливаем вывод PinB(11) в состояние LOW
}


void loop() {  
  Serial.println(schet);
  unsigned long podschetMicros = micros();
  digitalWrite(PinA, PinAstatus);


  if(podschetMicros - periudMicros > interval){
      periudMicros = podschetMicros;
      
        if (PinAstatus == LOW && schet < zub){
        PinAstatus = HIGH;
        }

        else if (PinAstatus == HIGH && schet < zub) {
        PinAstatus = LOW;
        schet ++;
        }
        
        else if (PinAstatus == LOW && schet == zub) {
        PinAstatus = LOW;
        schet ++;
        }

        else {
          schet = 0;
        }
  }

}

 

chiptuningnt
chiptuningnt аватар
Offline
Зарегистрирован: 22.01.2018
// задаем константы
const int PinA = 13; // присваиваем номер контакта выхода сигнала ДПКВ
const int PinB = 12; // присваиваем номер контакта выхода сигнала ДПРВ

// задаем переменные для имитации ДПКВ
byte zub = 60; // задаем переменную и указываем коллечество зубьев задающего диска ДПКВ
byte propusk = 2; // задаем сколько зубьев будет пропущено для синхранизации
byte schet = 0; // задаем переменную для подсчета зубьев и устанавливаем его начальное значение в ноль
long interval = 100000; // задаем время задержки 
byte PinAstatus = LOW; //
byte PinBstatus = LOW; //
long periudMicros = 0; //

// задаем переменные для имитации ДПРВ
byte zub_camchaft_high = 50; // номер зуба на котором необходимо переключить состояние выхода PinB с LOW на HIGH
byte zub_camchaft_low = 3; // номер зуба на котором необходимо переключить состояние выхода PinB с HIGH на LOW



/* 
 *  функция эмитации ДПКВ
 */
void umulator_crankchaft () { 
  unsigned long podschetMicros = micros();
  if(podschetMicros - periudMicros > interval){
      periudMicros = podschetMicros;
      
        if (PinAstatus == LOW && schet < zub - propusk){
        PinAstatus = HIGH;
        }

        else if (PinAstatus == HIGH && schet < zub - propusk) {
        PinAstatus = LOW;
        schet ++;
        }
        
        else if (PinAstatus == LOW && schet <= zub) {
        PinAstatus = LOW;
        schet ++;
        }

        else {
          schet = 0;
        }
    }
}

/* 
 *  функция эмитации ДПРВ
 */
void umulator_camkchaft() { 
  if (schet == zub_camchaft_high){
    PinBstatus = HIGH;
  }
  if (schet == zub_camchaft_low){
    PinBstatus = LOW;
  }
}


void setup() {
 pinMode(PinA, OUTPUT); // задаем режим работы цифрового контакта PinA(12) на выход
 pinMode(PinB, OUTPUT); // задаем режим работы цифрового контакта PinB(11) на выход
 digitalWrite(PinA, LOW); // устанавливаем вывод PinA(12) в состояние LOW
 digitalWrite(PinB, LOW); // устанавливаем вывод PinB(11) в состояние LOW
}


void loop() {  
  umulator_crankchaft();
  umulator_camkchaft();
  digitalWrite(PinA, PinAstatus);
  digitalWrite(PinB, PinBstatus);
}

Вроде что то похожее на желаемое вышло, все же хотелось мнения окружаюих, может что то можно прое сделать

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

1. Если используете в ф-ии переменную, которая должна сохранять своё значение между вызовами ф-ии, то объявляйте её с квалификатором static

stаtic unsigned long podschetMicros = micros();
chiptuningnt
chiptuningnt аватар
Offline
Зарегистрирован: 22.01.2018

Спасибо. А не подскажите как можно реализовать задержку между импульсами используя меньше переменных? 

Как щас взял из примера базового в ардуино. 

Перенес команды DigitalWrite из цикла loop в внутрь  самих функций, поднял максимальную скорость в два раза

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

вот я делал немного похожее . Для высоких оборотов нужно вместо digitalWrite применять прямое обращение к портам.