Kui valida lisapihusti kõrge takistusega, on selle juhtimine lihtsam - ei pea kasutama voolu piiramiseks PWM-i, vaid saab lihtsalt pihusti avada. Pihusti avamiseks sobib sisuliselt mistahes transistor/fet, mis kannatab piisavat voolutugevust.
Võimaliku Arduino koodi osas oskan anda paar soovitust:
* implementeeri pöörete lugemine protsessori katkestustega (
interrupt,
https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/)
* vastavalt pöörete ja rõhu väärtusele arvuta vajalik pihusti avatuse aeg või %.
* loop() funktsiooni sees ära ühtki
delay-d tee ning iga tsükliga arvuta, kas pihusti on vaja avada või sulgeda. Aja arvutusteks kasuta nt micros() funktsiooni
Visandan näitekoodi - läksin natuke hoogu
. Toimimist pole katsetanud:
Kood:
const byte RPM_INPUT_PIN = 2; // nt tahhomeetri väljund, Arduino sisend pin
const byte MAP_PIN = A0; // MAP sisend pin, saab otse 0-5V ühendada
const byte INJECTOR_PIN = 3; // pihusti väljundpin, millele on lisatud jõu-transistor (fet)
const int TIME_FRAME = 20000; // tsükkel mikrosekundites, mille vältel toimub 1x pulseerimine. kui pihusti pole silindritest kaugel, peaks seda väärtust dünaamiliselt pööretega muutma
const double MAP_0V = 20; // kPa väärtus 0V juures
const doulbe MAP_5V = 250; // kPa väärtus 5V juures
const int TABLE_SIZE = 5; // tabeli suurus
// pihusti avatuse tabel protsentides RPM/MAP
const int INJECTOR_OPEN_TABLE[6][6] = {
{ 0, 0, 3000, 4000, 5000, 6000 }, // esimene rida on pöörded, esimene veerg MAP
{ 0, 0, 0, 0, 0, 0 },
{ 110, 10, 15, 20, 25, 30 },
{ 130, 20, 28, 38, 45, 50 },
{ 150, 35, 45, 58, 65, 75 },
{ 180, 50, 65, 72, 85, 100 }
};
volatile int rpm = 0; // viimatimõõdetud RPM väärtus.
volatile int revCount = 0; // loendab pulsse viimasest RPM arvutamisest
volatile unsigned long lastTime = 0; // viimase RPM arvutamise aeg
bool injectorOpen = false; // pihusti avatuse olek
long changeStateAtMoment = 0L; // pihusti järgmise avamise/sulgemise ajahetk
void setup() {
pinMode(INJECTOR_PIN, OUTPUT);
pinMode(MAP_PIN, INPUT);
pinMode(RPM_INPUT_PIN, INPUT);
attachInterrupt(RPM_INPUT_PIN, rpmInterrupt, RISING);
}
void rpmInterrupt() {
revCount++;
if (revCount == RPM_COUNT_COLLECT) {
unsigned long thisTime = micros();
rpm = (double) revCount
/ (((double) thisTime - (double) lastTime) / (double) 60000000);
revCount = 0;
lastTime = thisTime;
}
}
int readMapKpa() {
int mapRaw = analogRead(MAP_PIN); // 0..1023
return MAP_0V + ((double) mapRaw / 1024.) * (double)(MAP_5V - MAP_0V);
}
// pihusti avatuse protsent
int getInjectorOpenPercent() {
int map = readMapKpa();
int mapIndex = 1;
int rpmIndex = 1;
while (mapIndex < TABLE_SIZE - 1 && map > INJECTOR_OPEN_TABLE[mapIndex + 1][0]) {
mapIndex++;
}
while (rpmIndex < TABLE_SIZE - 1 && rpm > INJECTOR_OPEN_TABLE[0][rpmIndex + 1]) {
rpmIndex++;
}
// TODO interpolation
return INJECTOR_OPEN_TABLE[mapIndex][rpmIndex];
}
void loop() {
unsigned long moment = micros();
if (moment > changeStateAtMoment) {
int openPercent = getInjectorOpenPercent();
if (injectorOpen) {
if (openPercent >= 100) {
// 100+% korral hoia pihusteid lihtsalt lahti
changeStateAtMoment = moment + TIME_FRAME;
}
else {
// sulgeme pihusti "ülejäänud" timeframe'i ulatuses
digitalWrite(INJECTOR_PIN, LOW);
injectorOpen = false;
changeStateAtMoment = moment + ((double)(100 - openPercent) / 100. * TIME_FRAME);
}
}
else {
if (openPercent <= 0) {
// 0% korral ei hakka pihustit avama
changeStateAtMoment = moment + TIME_FRAME;
}
else {
// avame pihusti ettenähtud ajaks
digitalWrite(INJECTOR_PIN, HIGH);
injectorOpen = true;
changeStateAtMoment = moment + ((double)(openPercent) / 100. * TIME_FRAME);
}
}
}
}