Всем привет! Небольшое вступление:
После безвременной кончины стокового двигателя SR20DE на моей Приме P11 возникло желание извлечь хоть какие то плюсы из данной ситуации, а именно – поднять мощность посредством установки контрактного двигателя SR20VE. Двигатель пришел из Японии со всем навесным, кроме датчика массового расхода воздуха — он же MAF, который, как известно, у двигателя SR20VE имеет характеристику, отличающуюся от ДМРВ SR20DE.
Поскольку покупать новый ДМРВ в мои планы не входило (ценник в половину стоимости движка казался немного излишним…), а заказывать контрактный не хотелось по причине долгого ожидания, вначале был подключен штатный ДМРВ SR20DE, и он вполне себе работал… но черные свечи и повышенный расход топлива давали о себе знать.
Поскольку согласно сведениям, найденным в сети, по «производительности» (максимальному расходу воздуха) и корпусу датчики обоих типов были одинаковыми, возникло желание просто перепрошить ECU, он же «мозг» машины, но это, опять же, требовало лишних затрат.
Встал вопрос, как бы так «обмануть» мозги машины, чтобы все работало как надо, и тут пригодилась плата Arduino Duemilanove (вернее ее отечественный функциональный аналог Freeduino), завалявшаяся в закромах со времен радиолюбительских экспериментов maf sr20de на АлиЭкспресс — купить онлайн по выгодной цене
Данная плата в различных модификациях представляет собой микроконтроллер Atmega с элементами обвязки (кварцем, интегральным стабилизатором питания и микросхемой интерфейса USB), который можно легко программировать через USB-порт компьютера, управляя входами и выходами МК посредством собственной программы. МК имеет аналоговые входы, позволяющие измерять аналоговые сигналы в диапазоне от 0 до 5 В, но не имеет полноценных аналоговых выходов, зато в нем предусмотрен режим широтно-импульсной модуляции выходных сигналов (PWM), что позволяет, используя очень простую схему на RC-цепочке и буферном операционном усилителе, получить полноценный аналоговый выходной сигнал с приемлемым уровнем пульсаций.
Самое главное – цена новой платы Freeduino составляет около 600 руб.
Дополнение:  Nissan Primera капитальный ремонт двигателя в Москве - сервис трубок

Принцип действия преобразователя заключается в следующем:
Входной аналоговый сигнал от используемого ДМРВ поступает на вход АЦП микроконтроллера, затем его цифровое значение сопоставляется программой МК с условной величиной расхода воздуха по таблице VQ (Voltage Quantifier) используемого ДМРВ. Затем выполняется поиск полученного значения в таблице VQ в программе МК, соответствующей таблице VQ «мозгов» автомобиля, чтобы найти уровень напряжения для данной величины расхода воздуха. Полученный уровень напряжения затем устанавливается на выходе МК в виде ШИМ-сигнала, который преобразуется в «настоящее» аналоговое напряжение RC-цепочкой и буферным ОУ. При этом в программе на обоих этапах преобразования используется линейная интерполяция – то есть, если уровень входного сигнала соответствует некоему промежуточному значению во входной таблице VQ, из нее берется соответствующее промежуточное значение расхода воздуха, и аналогично, если полученное значение расхода воздуха соответствует промежуточному значению уровня напряжения по выходной таблице VQ, на выходе устанавливается промежуточный уровень напряжения. Таблицы VQ удалось найти в заводских прошивках мозгов в Nistune maf sr20de на АлиЭкспресс — купить онлайн по выгодной цене
Схема устройства:
Преобразователь VQ-таблиц для использования нестандартного ДМРВ (MAF)-1.jpg
Блок включается в разрыв сигнального провода ДМРВ, 12 В можно взять с любой линии зажигания.

Код программы на языке Си для среды программирования Ардуино с таблицами VQ для преобразования сигнала ДМРВ SR20DE 22680-2J200 в сигнал для блока управления двигателя SR20VE, работающего с датчиком 22680-5J000:

Код:

const int PWM_PIN = 3;
const int AIN_PIN = 0;
long VQin[64] = {
271, 
271, 
271, 
271, 
271, 
275, 
297, 
337, 
396, 
475, 
575, 
695, 
837, 
1002, 
1190, 
1402, 
1639, 
1901, 
2190, 
2506, 
2850, 
3224, 
3628, 
4063, 
4530, 
5030, 
5565, 
6135, 
6741, 
7385, 
8068, 
8790, 
9554, 
10360, 
11209, 
12104, 
13045, 
14087, 
15169, 
16308, 
17507, 
18766, 
20087, 
21473, 
22925, 
24444, 
26034, 
27695, 
29429, 
31238, 
33125, 
35090, 
37136, 
39265, 
41479, 
43779, 
46168, 
48647, 
51219, 
53885, 
56648, 
59509, 
62471, 
65535
};

long VQout[64] = {
36, 
36, 
36, 
36, 
36, 
36, 
132, 
232, 
338, 
453, 
578, 
718, 
873, 
1047, 
1241, 
1457, 
1699, 
1967, 
2265, 
2581, 
2892, 
3234, 
3611, 
4028, 
4484, 
4980, 
5513, 
6079, 
6674, 
7290, 
7919, 
8550, 
9338, 
10171, 
11057, 
11996, 
12991, 
14043, 
15153, 
16323, 
17554, 
18848, 
20205, 
21628, 
23118, 
24675, 
26301, 
27998, 
29766, 
31606, 
33520, 
35509, 
37573, 
39714, 
41933, 
44230, 
46606, 
49063, 
51601, 
54221, 
56924, 
59710, 
62580, 
65535
};

void setup()  
{ 
  TCCR2B = TCCR2B & 0b11111000 | 0x02;
} 

void loop()  
{
    const int VPWR = 5030;
    const int MAXV = 5120;
    const int MINV = 80;
    int inVoltage = map(analogRead(AIN_PIN), 0, 1023, 0, VPWR);
    int outVoltage = 0;
    long inQ = 0;
    int adrL = constrain(map(inVoltage, MINV, MAXV, 0, 63), 0, 63);
    int adrH = adrL   1;
    int voltageValueL = map(adrL, 0, 63, MINV, MAXV);
    int voltageValueH = map(adrH, 0, 63, MINV, MAXV);
    int diff = voltageValueH - voltageValueL;
    float k = (float)(inVoltage - voltageValueL) / (float)diff;
    float valL = 0.0;
    float valH = 0.0;
    
    if (inVoltage < MINV)
    {
      inQ = VQin[0];
    }
    else if (adrL < 63)
    {
       valL = VQin[adrL];
       valH = VQin[adrH];
       inQ = valL   ((valH - valL) * k);
       
    }
    else
    {
      inQ = VQin[63];
    }
     
    for (long i = 0; i < 64; i  )
    {
        int outVolL = 0;
        int outVolH = 0;
        long QvalL, QvalH, d;

        if (VQout[i] > inQ)
        {
            if (i > 0)
            {
                outVolH = map(i, 0, 63, MINV, MAXV);
                outVolL = map(i - 1, 0, 63, MINV, MAXV);
                QvalH = VQout[i];
                QvalL = VQout[i - 1];
                d = QvalH - QvalL;
                k = (float)(inQ - QvalL) / (float)d;
                outVoltage = (outVolL   ((outVolH - outVolL) * k));
            }
            else
            {
                outVoltage = MINV;
            }
    
            break;
        }
    }
      
    analogWrite(PWM_PIN, constrain(map(outVoltage, 0, VPWR, 0, 255), 0, 255));
}

Константу VPWR необходимо задать в соответствии с точным напряжением на выходе интегрального стабилизатора платы Ардуино — в данном случае 5030 соответствует напряжению 5,03 В.

Дополнение:  Замена масел, фильтров и прочее — Nissan Avenir, 2.0 liter, 2000 year on DRIVE2

Фото:

Транзистор на плате не используется — был впаян для других целей maf sr20de на АлиЭкспресс — купить онлайн по выгодной цене

В начале программы с помощью регистра TCCR2B повышается частота PWM-модуляции для снижения пульсаций выходного напряжения примерно до 0,01 В (по осциллографу). Это следует учитывать при расширении функционала программы — библиотечные функции Delay могут работать неправильно.
Программа никак не оптимизировалась, при желании есть огромный потенциал для повышения быстродействия и уменьшения размера кода, если возникнет желание расширить функционал блока. На базе этого можно сделать много чего — это и возможности коррекции состава смеси (наподобие Apexi SAFC), для чего достаточно просто менять таблицы VQ, и управление клапанами VVL и т.д. и т.п. Кстати изначально хотел сделать VVL-контроллер, но временно отказался от этой идеи, изучив таблицы угла опрежения зажигания прошивки мозгов — оказывается на 5000 об/мин (при переключении фаз) УОЗ падает на несколько градусов, очевидно, для предотвращения детонации, то есть без коррекции таблиц УОЗ снижение оборотов переключения фаз может привести к детонации.
Пока что машинка успешно ездит с описанным блоком, расход топлива снизился, хоть и не радикально, нагар свечей принял более естественный цвет. В принципе при наличии таблиц VQ этот блок позволяет использовать любой ДМРВ с любыми мозгами – даже при несовпадении производительности можно пересчитать таблицы, лишь бы этой потоковой производительности датчика вообще хватало для двигателя.