// inladdad 2018-07-25 som ECU B
#include <PureAtmega328.h>
// här är olika justerbara parametrar som påverkar enligt följande:
// const byte lageffekt = 5; // effektläge tomgång utan gaspot (5) (nödkörning)
// const byte marcheffekt = 230; // effektläge marcheffekt utan gaspot (230)(nödkörning)
// const byte fulleffekt = 252; // effektläge fulleffekt utan gaspot (252) (nödkörning)
const byte totaltid = 14; // totaltid för case 15: x * motorns duration (14 = 7 tänder + upp till 2 extra = 55 gr)
const int lagstavarv = 520; // tomgångsvarvet 580 uS motsvarar ca 800 Rpm (580)
const byte hogstavarv = 120; // fullgasvarvet 100 uS motsvarar ca 4200 RPM (100)(160 = ca 2500 RPM)
const byte aggrfaktorlag = 20; // hur mycket spridar PWM skall öka vid belastning mellanvarv (30)
const byte aggrfaktorhog = 150; // hur mycket spridar PWM skall öka vid belastning högvarv (150)
const int minfart = 3300; // lägsta startvarv för spridarfunktion (3300 uS = 152 RPM)(3300)
const byte startmangd = 6; //5 // avgör max startmängd 5 = 0,75 vevaxelpulser = 4,5 grader ontid (5) (6 är 1 vevpuls, 6 grader)
const float maxdeltalag = 9.0; // max insprutningstid mellanvarv mdutation * 6.0 ger 3 vevaxelpulser = 18 gr ontid (6.0)
const byte lagmangd = 3; // ev 3 // max lågvarvsmängd 2 = 1 vevaxelpuls = 6 grader ontid (under tomgångsvarv)(2)(3 är 1,5 vevpuls = 9 grader ontid)
const int tid1 = 3000; // tid 1 är för att hitta pulsluckan vid start/lågvarv < 300 RPM (400)
const int tid2 = 900; // tid 2 är för att hitta pulsluckan i mellanvarv 1100--> (1200)
const int tid3 = 200; // tid 3 är för att hitta pulsluckan i alla andra förekommande varv 1100--> (300)
const int sprtroghet = 200; // korrektion för den inbyggda påslagströgheten i spridarna
const byte turbostartregl = 150; // när tubotrycket börjar avläsas och bli aktivt (150 = uS mduration ca 3200RPM)(150)
float senasteinsprfordroj; // senaste insprutningstid (vid tomgång)(12.0 = 6 vevaxelpulser = 36 grader delaytid = 6 grader FÖDP) 8-14
byte tidigasteinspr; // kortaste insprutningsfördröjning (vid maxvarv)(60=t19=24grFödp)(30=t20=18grFödp)(27) 18-38
const int sprdiff1 = 0; // en ev tidigareläggning av spridare 1 om den avviker i startfördröjning
const int sprdiff2 = 0; // en ev tidigareläggning av spridare 2 om den avviker i startfördröjning
const int sprdiff3 = 0; // en ev tidigareläggning av spridare 3 om den avviker i startfördröjning
const int sprdiff4 = 0; //20 // en ev tidigareläggning av spridare 4 om den avviker i startfördröjning
const int grundvarde = 330; // grundtrycksvärde ställs in här, högre tal = mindre tryck (330)
int vevpin = 2; // vevaxelgivarens ingång, (aktivt hög).
int kampin = 3; // kamaxelgivarens ingång, (aktivt låg).
int pulsutpin = 7; // pulsutgång 2 pulser per varv (kontrollutgång för övervakningen).
int sprpins [] ={11,10,9,8}; // till spridarna (blir aktivt höga)
int disable = 12; // aktivt hög stoppar utsignalerna till spridarna
int sprControl = 13; // kontrollutgång för spridare till övervakningen
unsigned long delvalue; // delvärde av pulstid i uS.
unsigned int ondelay; // tillslagsfördröjning spridare i uS (mS)(inne i case 15)
long puls, priv, delta; // senaste, föregående och delta (totalöppningstid) i uS(mS)
float error; // error = varvfelet i decimalform
float starttandf; // starttand i decimalform för att få startfördröjningstid
float mduration, bduration; // varvfelet = motorduration/börduration i decimalform
byte tand = 0; // vevpin räknare 0 till 28, i alla fall till 26
byte gas; // gas 0-255
byte pekare = 0 ; // pekare för att välja rätt spridarutgång, startar på 0
byte kamtand = 0; // Kamtand för att sluta detektera kamaxelgivaren efter 51 (max 255)tänder, startar på 0
int fasttid = 200; // Fasttid = tid,tid2 eller tid3 beroende på varvtal, startar alltid på 200 uS
int spridardiff; // en individuell spridartidskorrigering
int sprtroghetklar; // ett klart värde för spridartidskorrigering
int battVolt; // mäter systemspänning till spridare
int atmtryck = 330; // mäter atmosfärstrycket
int ambTemp =300; // mäter omgivningstemperaturen
byte analogval; // en switch/case till analogläsningen
int variabel1; // bra att ha variabel 1
int variabel2; // bra att ha variabel 2
int turbotryck = 0; // turbotryck
int turboAirTemp = 300; // komprimerad turboluft temp
int sprstartkorr = 50; // spridarstartkorrigering i uS spänningberoende.
int engineTemp = 700; // motortemp.
void setup()
{
pinAsInput(vevpin); // satt vevpin som ingång (2)
pinAsInputPullUp(kampin); // satt kampin som ingång (3)
pinAsOutput(sprpins[pekare]); // spridarutgångar satta som arrey (11,10,9,8)
pinAsOutput(sprControl); // en spridarutgång som blir hög varje gång en spridare öppnas (13)(Övervakningen)
pinAsInputPullUp (disable); // ECU väljare Hög = on, Låg = off (12)
pinAsOutput(pulsutpin); // satt pulsutpin som utgång (2 pulser per varv)(7)(övervakningen)
//Serial.begin(250000);
}
//______________________________________________________________________
void loop()
{
//Det får plats ca 1700 klockcykler mellan varje x tal(case) (1 till 17)
//Det tar lite mer än 100 mikrosek att läsa av en analogingång,
//så ingen analogRead här, skall vara i case 16!
if (digitalRead(disable)==LOW) //Disable låg stänger av ECU:n och gör den passiv
{
puls = 0; //Genom att pulstiderna förblir 0.
pinAsInput(sprpins[pekare]); //Gör om spridarutgångarna till ingångar för att ej belasta
pinAsInput(sprControl); //Gör om spridarcontrollen till ingång för att ej belasta
}
else
{
pinAsOutput(sprpins[pekare]); //Vid aktiv igen så gäller spridarutgångarna som utgångar igen.
pinAsOutput(sprControl); //Vid aktiv så gäller spridarcontrollen som utgång igen
} //*Detta är normalläget, samma som i setup*
// Räknare för kamaxeln, stängs av efter 251 varv (502 motorvarv)
if (kamtand <= 250) // när tand 251 är räknad slutar den detektera kampin.
{
if (digitalRead(kampin)== HIGH)// varje gång kamaxelns hempuls detekteras så resetas 4 räknaren
{
pekare = 0; // resetas till 0. Denna funktion läses utanför switch.
kamtand ++; // räknar upp kamtandräknaren vid varje kampin låg upp till max.
}
}
switch (tand) // här startar switch och case, tandräknaren stegar fram ett steg (case)
{
case 0: // Detta case ger första pulstid
delvalue = priv; // Första pulstid läggs in som deltid 1
senasteinsprfordroj = map(variabel1, 0,32 , 7.0,11.0);
//Serial.println(senasteinsprfordroj);
break;
case 1: // Detta case ger andra pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
tidigasteinspr = map(variabel2,0,128 , 15,26);
//Serial.println(tidigasteinspr);
break;
case 2: // Detta case ger tredje pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 3: // Detta case ger fjärde pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 4: // Detta case ger femte pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 5: // Detta case ger sexte pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 6: // Detta case ger sjunde pulstid och spridarstartkorrigering
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop (ca 50 uS)
sprstartkorr =map(battVolt, 600, 1024, 0, 150); // batterispänningen blir spridartidskorrigering
break;
case 7: // Detta case ger motorns börvärde från gaspoten som blir lägsta och högsta varvtal
bduration =map(gas,0, 255, lagstavarv, hogstavarv); // ställs in högst upp
// Och åttonde pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop ( ca 115)
break;
case 8: // Detta case ger motorns verkliga fart baserat på dom 9 första tänderna. (660 - 115 uS vid normalvarv ca 800 till 4200 rpm.)
mduration = delvalue/12; // Motorns totala pulstid i mikrosek dividerat med 12 ger motorns duration
// Och avgör om tillräcklig fart är uppnådd för motorstart
if(mduration >= minfart) // motorn måste upp i x fart för att få bränsle, ställs högst upp (minfart i uS)
{
mduration = 0; // Om underfart, motorduration resetas
delta = 0; // och delta(insprutningstid)resetas ( ca 55 uS)
}
break;
case 9: // Detta case räknar ut skillnaden mellan är och börvärde - 1 = error
error = (mduration / bduration)-1;
if (error <=0.) // om error under noll
{
error = 0.; // förblir error 0 för att ej få minusvärden
}
break; // error = felet i uS mellan är och börvärde för motorns fart (ca 50 uS)
case 10: // Detta case ger förtändningen
starttandf = mduration /tidigasteinspr; // starttandf, ett flyt-tal = motorns duration/ minsta duration/max RPM. ställs högst upp
if (starttandf >= senasteinsprfordroj) // om fördröjning över målvärdet, som vid tex startvarv (ställs in högst upp)
{
starttandf = senasteinsprfordroj; // blir det målvärdet ändå
}
break;
case 11: // Detta case för insprutningsfördröjning i gånger, ställs högst upp
ondelay = (mduration * starttandf); // tillslagsfördröjning = motorns duration * starttandsfördröjning (decimaltal)
break; // Ondelay uS = mduration uS * starttandf i decimalform
case 12: // Detta case ger motorns karaktärstik på arbetsvarv
if (mduration >=161) // "mellanvarv"
{ // Felkorrigeringsvärde som ger spridaröppningstid i uS
delta = mduration * error * aggrfaktorlag; // aggrfaktor låg avgör hur mycket extra ontid spridarna får vid belastning lägre varv
if (delta >= maxdeltalag * mduration) // om delta är mer än max tillåten delta x mduration
{
delta = maxdeltalag * mduration; // förblir delta max tillåten
}
}
if (mduration <= 160) // "högvarv"
{
delta = mduration * error * aggrfaktorhog; // Felkorrigeringsvärde som ger spridaröppningstid i uS
} // aggrfaktor hög avgör hur mycket extra on tid spridarna får vid belastning högre varv
break;
case 13: // (används ej) Detta case bestämmer varvtalet när turbon skall börja regleras ner
if (mduration <= turbostartregl)
{ // via kortare spridartider, ställs högst upp
delta = delta - turbotryck + grundvarde - atmtryck + ambTemp - turboAirTemp;// korrigering för måltryck genom att minska öppningstiden i uS ; // används ej än så delta förblir delta oförändrat
// 1500 = 1500 - 0 + 330 - 330 + 300 - 300 full gas ingen turboladdning
// 1200 = 1500 - 200 + 330 - 330 + 300 - 400 full gas, turbon laddar, ttemp stiger
// 1190 = 1500 - 200 + 330 - 280 + 290 - 450 f. g, t. laddar, ttemp stiger, utetryck/temp sjunker
// 940 = 1000 - 100 + 330 - 280 + 290 - 300 marcheffekt på höjd en dag...
// 1500 = 1500 - (0) + (330) - (330) + (300) - (300)
if (delta <=0)
{
delta = 0; // för att undvika minusvärden
}
}
// och mjukstartsfunktion
if (mduration >= 700) // Vid lite över startfart
{
delta = lagmangd * mduration; // blir det mjukstart som justeras via lågmängd högst upp
}
// och absolut längsta insprutningstid
if (delta + ondelay >= totaltid * mduration) // om delta och ondelay i uS blir mer än totaltid
{ // så justeras endast delta ner
delta = (totaltid * mduration) - ondelay;// Absolut max insprutningstid (delta), ställs högst upp
} // denna justering gäller bara på högvarv, hög belastning (< 50 uS)
break;
case 14: // detta case räknar ut tidsdiff per spridare plus systemspänningsdiff
sprtroghetklar = sprtroghet + spridardiff - sprstartkorr; // spridartröghet klart värde räknas ut här
// 450 + (0 till 50) - (0 till 150)
break; // 450 + 0 - 50
case 15: // Detta case är insprutningsfasen "spridar-on-off-mode"
if (ondelay >=10000) // Om ondelay är mer än 10000 uS. ( < 300RPM )
{ // går tiden över från uS till mS.
ondelay = ondelay/1000; // Ondelay uS blir mS.
delta = delta/1000; // Delta uS blir mS.
// och startmängden vid motorstart
if ((delta * 2)>= startmangd) // här ställs startmängden in (högst upp)
{
delta = startmangd; // så det blir rätt startmängd/slag (5 = 0,75 tänder = 4,5 vevgrader)
}
delay(ondelay); // Fördröjer starttiden x antal mS beroende på varvtalet (mdurationen)
digitalWrite (sprpins[pekare],HIGH); // Spridarpinne hög,insprutning börjar. sprpins [pekare 8,9,10 eller 11].
digitalWrite(sprControl, HIGH); // Kontrollpinne som går hög vid varje insprutningstillfälle.
delay(delta); // Här läggs insprutningstiden in som sen fördröjer processorn i delta mS
digitalWrite (sprpins[pekare],LOW); // Spridarpinne låg,insprutning avslutad sprpins [pekare 8,9,10 eller 11].
digitalWrite (sprControl, LOW); // Kontrollpinne som går låg efter varje insprutningstillfälle.
} // Denna del av caset används vid låga farter såsom start/lågvarv < 250 RPM
else // Eller om delay är mindre än 14000 uS. (> 250 RPM, normalfall)
{
ondelay = ondelay - sprtroghetklar; // minskar ondelaytiden med ca 450 uS (kompenserar spridarens tröghet att öppna)
if (delta > 30) // Delta under 30 uS skall inte ha något värde.
{
delta = delta + sprtroghetklar; // Delta över 30 blir x delta + kompensation för spridarens tröghet att öppna
}
delayMicroseconds(ondelay); // Fördröjer starttiden i ondelay uS beroende på varvtalet (mdurationen)
digitalWrite (sprpins[pekare],HIGH); // Spridarpinne hög,insprutning börjar. sprpins [pekare 11,10,9 eller 8].
digitalWrite(sprControl, HIGH); // Kontrollpinne som går hög vid varje insprutningstillfälle.
delayMicroseconds(delta); // Här läggs insprutningstiden in som sen fördröjer processorn att ha spridare on i x (delta) uS
digitalWrite (sprpins[pekare],LOW); // insprutning avslutad sprpins [pekare 8,9,10 eller 11] går låg.
digitalWrite (sprControl, LOW); // Kontrollpinne som går låg efter varje insprutningstillfälle.
} // Denna del av caset används vid varv (250 -> RPM = nästan alltid, förutom vid motorstart)
break; // Dessa case tar 3 till 10 tänder att genomföra beroende på varvtal och belastning
case 16: // är mellan tand 19 och 25
switch (analogval)
{
case 0:
gas = analogRead(A0)>>2; // analogingång för gasreglage 0 till 255( skiftad 2 gånger)
// turbotryck = analogRead(A4); // analogingång för turbotryck 0 till 1024
break;
case 1:
variabel1 = analogRead(A1)>>5; //(enginetmp) 0 till 512 0,1 Volt/10 grad använder LM-35 tempgivare (skiftad 1 gång)
battVolt = analogRead(A7);
break;
case 2:
gas = analogRead(A0)>>2; // analogingång för gasreglage 0 till 255( skiftad 2 gånger)
// turbotryck = analogRead(A4); // analogingång för turbotryck 0 till 127 (skiftad 3 gånger)ambTemp = analogRead(A3);
break;
case 3:
variabel2 = analogRead(A2)>>3; // (turboAirTemp) skall vara turboAirTemp,
//atmtryck = analogRead(A6); // analogingång för lufttrycket max 255
break;
case 4:
gas = analogRead(A0)>>2; // analogingång för gasreglage 0 till 255( skiftad 2 gånger)
// turbotryck = analogRead(A4); // analogingång för turbotryck 0 till 127 (skiftad 3 gånger)
break;
case 5:
// variabel1 = analogRead(A5)>>5; // A7!!
// ambTemp = analogRead(A3);
break;
}
break; // analalogRead tar ca 120 uS att läsa = 1-2 tänder vid fullvarv
}
//______________________________________________________________________________________________________
analogval ++; // räkna 0 till 5 som analogval i case 16
tand ++ ; // räkna upp ett steg efter varje genomfört case, (kommer via pulseIn()funkt)
priv = puls; // lägger in den förra pulstiden "puls" i värdet "priv" (uS)
if (mduration >1800) // Om motorn går på allra lägsta varv (start)
{
fasttid = tid1; // används tid1 (4000 uS i grundinställning)
}
if ((mduration >400)||(mduration <1800)) // Om motorn går mellan lägsta varv upp till ca 1100 RPM
{
fasttid = tid2; // används tid2 (1200 uS i grundinställning)
}
if (mduration <400) // Om motorn går över 1100 RPM
{
fasttid = tid3; // används tid3 (200 uS i grundinställning)
}
puls = pulseIn(vevpin, LOW, 30000); // PulseIn ger durationen på varje puls från vevaxelgivare(tand = case).
// vid stillastående motor blir det en timeout
// efter 0,03 Sek
if (puls > priv + fasttid) // jämför om ny pulstid i uS är större än föregående
{
digitalWrite (pulsutpin, HIGH); // utpin blir hög när pulsluckan är identifierad
tand = 0; // och resetar 0 till 28 räknaren
pekare = pekare + 1; // och räknar upp spridarpinpekräknare
if (pekare > 3) // när fjärde pinnen är nådd börjar den om igen
{
pekare = 0; // spridarpinne 1 är igång igen (1 = D11)
} // Denna if-sats är bara sann varje halv-varv vid luckan
}
if (pekare == 0)
{
spridardiff = sprdiff4;
}
if (pekare == 1)
{
spridardiff = sprdiff2;
}
if (pekare == 2)
{
spridardiff = sprdiff1;
}
if (pekare == 3)
{
spridardiff = sprdiff3;
}
if (puls < priv - fasttid) // jämför on ny pulstid är mindre än förgående (luckan)
{
digitalWrite (pulsutpin, LOW); // och utpin blir låg igen nästa puls i pulståget.
} // Denna if-sats är bara sann efter det att luckan är slut och första pulsen är detekterad
if (analogval == 5)
{
analogval = 0;
}
}
// end void loop()
case 16: // är mellan tand 19 och 25
switch (analogval)
{
case 0:
gas = analogRead(A0)>>2; // analogingång för gasreglage 0 till 255( skiftad 2 gånger)
// turbotryck = analogRead(A4); // analogingång för turbotryck 0 till 1024
break;
case 1:
variabel1 = analogRead(A1)>>5; //(enginetmp) 0 till 512 0,1 Volt/10 grad använder LM-35 tempgivare (skiftad 1 gång)
battVolt = analogRead(A7);
break;
case 2:
gas = analogRead(A0)>>2; // analogingång för gasreglage 0 till 255( skiftad 2 gånger)
// turbotryck = analogRead(A4); // analogingång för turbotryck 0 till 127 (skiftad 3 gånger)ambTemp = analogRead(A3);
break;
case 3:
variabel2 = analogRead(A2)>>3; // (turboAirTemp) skall vara turboAirTemp,
//atmtryck = analogRead(A6); // analogingång för lufttrycket max 255
break;
case 4:
gas = analogRead(A0)>>2; // analogingång för gasreglage 0 till 255( skiftad 2 gånger)
// turbotryck = analogRead(A4); // analogingång för turbotryck 0 till 127 (skiftad 3 gånger)
break;
case 5:
// variabel1 = analogRead(A5)>>5; // A7!!
// ambTemp = analogRead(A3);
break;
}
break; // analalogRead tar ca 120 uS att läsa = 1-2 tänder vid fullvarv
}
//______________________________________________________________________________________________________
analogval ++; // räkna 0 till 5 som analogval i case 16
tand ++ ; // räkna upp ett steg efter varje genomfört case, (kommer via pulseIn()funkt)
Återgå till [Allmänt] El/elektronik
Användare som besöker denna kategori: Inga registrerade användare och 10 gäster