Nästan längst ner i sketchen är dels PulseIn() och if( puls>priv+ fasttid) mm det är bara för att hitta hemläget, där man sen börjar räkna tänder och göra olika beräkningar per tand (case)
- Kod: Markera allt
#include <PureAtmega328.h>
// här är 16 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 = 19; // totaltid för case 18: x * motorns duration (13)
const int tryckminskn = 60; // turbotrycket ställs in här, högre tal = mindre tryck (60)
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 = 30; // hur mycket spridar PWM skall öka vid belastning mellanvarv (8)
const byte aggrfaktorhog = 150; // hur mycket spridar PWM skall öka vid belastning högvarv (20)
const int minfart = 3300; // lägsta startvarv för spridarfunktion (3300 uS = 152 RPM)(3300)
const byte startmangd = 6; // avgör max startmängd 5 = 0,75 vevaxelpulser = 4,5 grader ontid (5)
const float maxdeltalag = 9.0; // max insprutningstid mellanvarv mdutation * 6.0 ger 3 vevaxelpulser = 18 gr ontid (6.0)
const byte lagmangd = 3; // max lågvarvsmängd 2 = 1 vevaxelpuls = 6 grader ontid (under tomgångsvarv)(2)
const int tid1 = 4000; // tid 1 är för att hitta pulsluckan vid start/lågvarv < 1100 RPM (2500)
const int tid2 = 1200; // tid 2 är för att hitta pulsluckan i låg varv varv 1100--> (1200)
const int tid3 = 300; // tid3 är normalläget vid dom flesta varvtal utom start och lägsta varv (300)
const int sprtroghet = 450; // korrektionstid i uS 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)
const float senasteinspr = 12.0; // senaste insprutningstid (vid tomgång)(8.0 = 4 vevaxelpulser = 24 grader delaytid = 6 grader FÖDP) (8) lägst 4!)
const byte tidigasteinspr =27; // kortaste insprutningsfördröjning (vid maxvarv)(60)
// 60 motsvarar tand 19 = 24 grader FÖDP
// 30 motsvarar tand 20 = 18 grader FÖDP
int vevpin = 2; // pulsingång vevaxelgivare, (aktivt låg).
int kampin = 3; // kamaxelgivarens ingång, (aktivt låg).
int pulsutpin = 7; // 9 // 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)
long puls, priv, delta; // senaste, föregående,total och finkorrigeringstid i uS(mS)
float error; // error = varvfelet i decimalform
float starttandf, finKorr; // 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 tänder, startar på 0
int fasttid = 300; // Fasttid = tid1, tid2 döller tid3 beroende på varvtal, Förval Tid3.
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)
pinAsInputPullUp (disable); // ECU väljare Hög = on, Låg = off (12)
pinAsOutput(pulsutpin); // satt pulsutpin som utgång (2 pulser per varv)(7)
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 19!
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*
tand ++ ; // räkna upp ett steg för varje ny puls, kommer via pulseIn()funkt.
if (kamtand <= 250 // när tand 251 är räknad slutar den detektera kampin.
{
if (digitalRead(kampin)== LOW)// 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.
}
}
switch (tand) // här startar switch och case, tandräknaren stegar fram ett steg (case)
{
case 1: // Vid första vevpinpuls Gör:
delvalue = priv; // Första pulstid läggs in som deltid 1
break;
case 2: // Vid andra vevpinpuls Gör:
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 3: // Vid tredje vevinpuls Gör: osv
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 4:
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 5:
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 6:
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 7:
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 8: // motorns börvärde från gaspoten blir lägsta och högsta varvtal
bduration =map(gas,0, 255, lagstavarv, hogstavarv); // ställs in högst upp
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 9:
mduration = delvalue/12; // motorns totala pulstid i mikrosek dividerat med 12
if(mduration >= minfart) // motorn måste upp i x varv för att få bränsle, ställs högst upp
{
mduration = 0;
}
break; //ger motorns verkliga fart baserat på dom 9 första tänderna. 660 - 115 uS vid normalvarv ca 800 till 4200 rpm.
case 10:
error = (mduration / bduration)-1; // räknar ut skillnaden mellan är och börvärde - 1 = error
if (error <=0.) // om error under noll
{
error = 0.; // för att ej få minusvärden
}
break; // felet i uS mellan är och börvärde för motorns fart baserat på pulslängderna över 9 tänder
case 11:
// ledigt
break;
case 12:
// ledigt
break;
case 13: //27 = tand 19 = 24 grader FÖDP
starttandf = mduration /tidigasteinspr;// insprutningsfördröjning i gånger, ställs högst upp
// starttandf, ett flyt-tal = motorns duration/ x som är minsta duration/max RPM. ställs högst upp
if (starttandf >= senasteinspr) // om över målvärdet (som ställs in högst upp)
{ //12.0 = tand 22 = 6 grader FÖDP
starttandf = senasteinspr; // blir det målvärdet ändå
}
break;
case 14: // ca 1.5 till 8.0
ondelay = (mduration * starttandf);// tillslagsfördröjning = motorns duration * starttandsfördröjning (decimaltal)
break; // Ondelay uS = mduration uS * starttandf i decimalform - trögheten i spridare
case 15:
// ledigt
break;
case 16:
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 17:
if (mduration <= turbostartregl) // här bestämms varvtalet när turbon skall börja regleras ner
{ // via kortare spridartider, ställs högst upp
delta = delta ; // används ej än så delta förblir delta oförändrat
if (delta <=0)
{
delta = 0; // för att undvika minusvärden
}
}
if (mduration >= 700) // för att få mjukstart vid motorstart.
{
delta = lagmangd * mduration; // mjukstarten justeras via lågmängd högst upp
}
if (delta + ondelay >= totaltid * mduration)
{
delta = (totaltid * mduration)-ondelay;// Absolut max insprutningstid, ställs högst upp
} // denna justering gäller bara på högvarv, hög belastning
break;
case 18: // När puls 18 är räknad, gå in i "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.
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.
} // Detta paket används vid låga farter såsom start/lågvarv < 250 RPM
else // Eller om delay är mindre än 10000 uS. (> 250 RPM)
{
ondelay = ondelay - sprtroghet;
if (delta > 30) // Delta under 30 uS har inget värde
{
delta = delta +sprtroghet; // Delta över 30 blir x delta + trögheten i spridaren (ca 450 uS)
}
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 ion spridare 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.
} //Detta paket används vid varv (250 -> RPM = nästan alltid, förutom vid motorstart)
break; //Dessa paket tar 1 till 6 tänder att genomföra beroende på varvtal och belastning
case 19: // är mellan tand 19 och 24
gas = analogRead(A0)>>2; // analogingång för gasreglage 0 till 255( skiftad 2 gånger)
break; // analalogRead tar ca 120 uS att läsa = 1-2 tänder vid fullvarv
}
//______________________________________________________________________________________________________
priv = puls; // lägger in den förra pulstiden i värdet "priv" (uS)
if (mduration >1800) // när motorn går på allra lägsta varv
{
fasttid = tid1;
}
if ((mduration >400)||(mduration <1800)) // Om motorn går under 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 (300 uS i grundinställning)
}
puls = pulseIn(vevpin, LOW); // Ett färdigt kommando som väntar in nästa puls (tand).
// vid stillastående motor blir det en timeout
// efter 1 Sek
if (puls > priv + fasttid) // jämför om ny pulstid i uS är större än föregående + tid1 eller tid2.
{
digitalWrite (pulsutpin, HIGH); // utpin blir hög när pulsluckan återgår till pulser
tand = 0; // resetar 0 till 28 räknaren som bara har hunnit räkna mellan 19 och 27 tänder
pekare = pekare + 1; // 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)
}
}
if (puls < priv - fasttid) // jämför on ny pulstid är mindre än förgående - tid1 eller tid2.
{
digitalWrite (pulsutpin, LOW); // utpin blir låg igen nästa uppgång i pulståget.
}
}
// end void loop()