Senaste koden...
Kod: Markera allt
// Förändrad 2018-11-16 och inlaggd 11/17, aktiv/inaktiv fungerar
// utmärkt. max ändrat till strax under 4000 rpm ua. Tändläget verkar ua ochså.
// nu läser den av alla analogread i följd om 2 och 2 = fungerar!!
// batterispänningens inverkan grovjusterad = fungerar
// en individuell möjlig injustering per spridare finns med. Fungerar
// ändrad i gasen så 5 volt är tomgång och 0 volt fullfart Fungerar
// ändrad till att bara läsa av tand 9. Skall provas
// ändrad till max 2500 rpm om varvpin sätts låg. Skall provas
// 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 = 13; // totaltid för case 16: x * motorns duration (13)
const int tryckminskn = 60; // turbotrycket ställs in här, högre tal = mindre tryck (60)
const int lagstavarv = 500; // tomgångsvarvet 500 uS motsvarar ca 800 Rpm (500)
byte hogstavarv = 100; // fullgasvarvet 100 uS motsvarar ca 4200 RPM (100)(160 = ca 2500 RPM)
const byte aggrfaktorlag = 8; // hur mycket spridar PWM skall öka vid belastning mellanvarv (8)
const byte aggrfaktorhog = 20; // hur mycket spridar PWM skall öka vid belastning högvarv (20)
const int minfart = 3800; // lägsta startvarv för spridarfunktion (3300 uS = 152 RPM)(3300)3800 nu
const byte startmangd = 9; // avgör max startmäng 9 = 1,5 vevaxelpulser = 9 grader ontid (9)
const float maxdeltalag = 9.0; // max insprutningstid mellanvarv mdutation * 6.0 ger 3 vevaxelpulser = 18 gr ontid (9.0)
const byte lagmangd = 4; // max lågvarvsmängd 4 = 2 vevaxelpulser = 9 grader ontid (under tomgångsvarv)(4)
const int tid1 = 2500; // tid 1 är för att hitta pulsluckan vid start/lågvarv < 300 RPM (400)
const int tid2 = 1500; // tid 2 är för att hitta pulsluckan i mellanvarv 1100--> (1200)
const int tid3 = 1000; // tid 3 är för att hitta pulsluckan i alla andra förekommande varv 1100--> (300)
const int tid4 = 100; // tid 4 är för att hitta pulsluckan på högsta varvtal
const byte turbostartregl = 150; // när tubotrycket börjar avläsas och bli aktivt (150 = uS mduration ca 3200RPM)(150)
const float senasteinspr = 7.0; // senaste insprutningstid (vid tomgång)(7.0 = 3,5 vevaxelpulser = 21 grader delaytid
const byte tidigasteinspr = 60; // kortaste insprutningsfördröjning (vid maxvarv)(60=t19=24grFödp)(30=t20=18grFödp)
const int sprtroghet = 400; // ett grundvärde för spridarnas påslagsfördröjning i uS.
const int sprdiff1 = 0; // en ev tidigareläggning av spridare 1 om den avviker i startfördröjning (uS)
const int sprdiff2 = 0; // en ev tidigareläggning av spridare 2 om den avviker i startfördröjning (uS)
const int sprdiff3 = 0; // en ev tidigareläggning av spridare 3 om den avviker i startfördröjning (uS)
const int sprdiff4 = 0; //20 // en ev tidigareläggning av spridare 4 om den avviker i startfördröjning (uS)
const byte maxstopp = 60; // en varvtalsbegränsare som + på högstavarv (microsek)
const int tandlasning = 3000; // vid vilken tid på puls som läsning skall ändras mellan 1 tand = start och = /12 vid drift
int vevpin = 2; // pulsingång vevaxelgivare, (aktivt hög).
int kampin = 3; // kamaxelgivarens ingång, (aktivt låg).
int varvpin = 4; // en varvbegränsningspinne
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 18)
long puls, priv, delta; // senaste, föregående och delta (totalöppningstid) i uS(mS)
float error; // error = varvfelet i decimalform
float starttandf, finKorr; // starttand i decimalform för att få startfördröjningstid och finkorrigering av öppninstiden +-.
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 = 300; // Fasttid = tid,tid2 eller tid3 beroende på varvtal, startar alltid på 300 uS
byte analogval; // En switch/case till analogread
int turbotryck; // turbotryck
int battVolt = 400; // mäter systemspänning till spridare
int variabel1; // bra att ha variabel 1
int variabel2; // bra att ha variabel 2
int ambTemp = 300; // mäter omgivningstemperaturen
int atmtryck = 330; // mäter atmosfärstrycket
int sprstartkorr = 50; // spridarstartkorregering i uS, spänningsberoende
int sprtroghetklar; // korrektion för den inbyggda påslagströgheten i spridarna
int spridardiff; // en ev. individuell spridartid korrigering (uS)
void setup()
{
pinMode(vevpin, INPUT_PULLUP); // satt vevpin som ingång (2) Testar nu med pullup...
pinMode(kampin, INPUT); // satt kampin som ingång (3)
pinMode(sprpins[pekare], OUTPUT); // spridarutgångar satta som arrey (11,10,9,8)
pinMode(sprControl, OUTPUT); // en spridarutgång som blir hög varje gång en spridare öppnas (13)(Övervakningen)
pinMode(Disable, INPUT_PULLUP); // ECU väljare Hög = on, Låg = off (12)
pinMode(pulsutpin, OUTPUT); // satt pulsutpin som utgång (2 pulser per varv)(7)(övervakningen)
pinMode(varvpin, INPUT_PULLUP); // satt varvpin som ingång (4) varvtalsbegränsare
//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 17!
if (digitalRead(Disable)==LOW) // Disable låg stänger av ECU:n och gör den passiv
{
delta = 0; // Genom att delta (insprutningstid) förblir 0.
pinMode(sprpins[pekare], INPUT); // Gör om spridarutgångarna till ingångar för att ej belasta
pinMode(sprControl, INPUT); // Gör om spridarcontrollen till ingång för att ej belasta
}
else
{
pinMode(sprpins[pekare], OUTPUT); // Vid aktiv igen så gäller spridarutgångarna som utgångar igen.
pinMode(sprControl, OUTPUT); // Vid aktiv så gäller spridarcontrollen som utgång igen
} //*Detta är normalläget, samma som i setup*
if(digitalRead(varvpin)==LOW) // om varvpin är låg
{
hogstavarv = hogstavarv + maxstopp; // så blir maxvarv tex 2500 Rpm
}
else
{
// maxvarv blir 4200 Rpm
}
if (kamtand <= 256) // när kamtanden är räknad 251 gånger så 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 1: // Detta case ger första pulstid
delvalue = priv; // Första pulstid läggs in som deltid 1
break;
case 2: // Detta case ger andra pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
sprstartkorr =map(battVolt, 150, 700, 0, 400); // batterispänningen blir spridartidskorrigering
sprstartkorr = constrain(sprstartkorr,150,400);
break;
case 3: // Detta case ger tredje pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 4: // Detta case ger fjärde pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 5: // Detta case ger femte pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 6: // Detta case ger sexte pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 7: // Detta case ger sjunde pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 8: // Detta case ger motorns börvärde från gaspoten som blir lägsta och högsta varvtal
bduration =map(gas,255, 0, 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: // Detta case ger motorns verkliga fart baserat på dom 9 första tänderna eller bara tand 8
if (priv <= tandlasning) // Här väljs om man skall räkna på en tand vid start eller alla räknetänder/12
{
mduration = delvalue/12; // Motorns totala pulstid i mikrosek dividerat med 12 ger motorns duration vid drift
}
else
{
mduration = priv; // motorns pulstid i case 8 vid start får gälla för hela halvvarvet.
}
break;
case 10: // 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; // felet i uS mellan är och börvärde för motorns fart
case 11: // 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
// 500 + (0 till 50) - (0 till 400)
break; // 500 + 0 - 50
case 12: // Detta case för insprutningsfördröjning i gånger, ställs högst upp
starttandf = mduration /tidigasteinspr; // starttandf, ett flyt-tal = motorns duration/ minsta duration/max RPM. ställs högst upp
if (starttandf >= senasteinspr) // om fördröjning över målvärdet, som vid tex startvarv (ställs in högst upp)
{
starttandf = senasteinspr; // blir det målvärdet ändå
}
break;
case 13: // Detta case ger förtändningen
ondelay = (mduration * starttandf); // tillslagsfördröjning = motorns duration * starttandsfördröjning (decimaltal)
break; // Ondelay uS = mduration uS * starttandf i decimalform
case 14: // 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 15: // (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 ; // används ej än så delta förblir delta oförändrat
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
break;
case 16: // 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.
// 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)
{
delta = 0; // och delta(insprutningstid)resetas
}
// och startmängden vid motorstart
if ((delta * 4)>= 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. (> 300 RPM)
{
if (delta > 50) // Delta under 50 uS har inget värde
{
delta = delta + sprtroghetklar; // Delta över 50 blir x delta + trögheten i spridaren (ca 250-500 uS)
}
ondelay = ondelay - sprtroghetklar; // tidigarelägger insprutningstart med hänsyn till spridartrögheten
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 i on 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 17: // är mellan tand 19 och 24
switch (analogval)
{
case 0:
gas = analogRead(A0)>>2; // analogingång för gasreglage 0 till 255( skiftad 2 gånger)
turbotryck = analogRead(A4);
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); // skall vara 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;
}
analogval ++; // räkna upp analogval 1 steg
if (analogval > 5) // när analogval har blivit 5 så
{
analogval = 0; // resettas analogval till 0 igen
}
break; // analalogRead tar ca 120 uS att läsa = 1-2 tänder vid fullvarv
}
//______________________________________________________________________________________________________
tand ++ ; // räkna upp ett steg för varje ny puls, kommer via pulseIn()funkt.
priv = puls; // lägger in den förra pulstiden i värdet "priv" (uS)
//Serial.println(priv);
if (mduration >1800) // när motorn går på allra lägsta varv (start)
{
fasttid = tid1; // används tid1 (4000 uS i grundinställning)
}
if ((mduration > 1200)|| (mduration < 1800))
{
fasttid = tid2;
}
if ((mduration > 500)||(mduration < 1200)) // Om motorn går under 1100 RPM
{
fasttid = tid3; // används tid2 (1200 uS i grundinställning)
}
if (mduration <500) // Om motorn går över 1100 RPM
{
fasttid = tid4; // används tid3 (300 uS i grundinställning)
}
puls = pulseIn(vevpin, LOW, 30000); // Ett färdigt kommando som väntar in nästa puls (tand = case).
// vid stillastående motor blir det en timeout
// efter 0,03 Sek
// if (3800 > 3800 + 2500) blir 3800 > 6300 FALSKT (-2500)
// if (11400 > 3800 + 2500) blir 11400 > 6300 SANT luckan funnen! (+5100)
// if (3800 > 11400 + 2500) blir 3800 > 13900 FALSK (-10100)
// if (2000 > 2000 + 2500) blir 2000 > 4500 FALSKT Detta är dom 28 vanligaste lägen (-2500)
// if (10000 > 2000 + 2500 ) blir 10000 > 4500 SANT Luckan funnen, då det är lång tid till nästa tand (efter luckan)
// if (2000 > 10000 + 2500) blir 2000 > 12500 FALSKT Nu är det vanlig tid igen, första tanden börjar om räkningen
if (puls > priv + fasttid) // jämför om ny pulstid i uS är större än föregående + fasttid.
{
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 ++; // 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) // om spridarpekaren pekar på 0 (ben D11)
{
spridardiff = sprdiff4; // skall det individuella värdet för spridare 4 hämtas
}
if (pekare == 1) // om spridarpekaren pekar på 1 (ben D10)
{
spridardiff = sprdiff2; // skall det individuella värdet för spridare 2 hämtas
}
if (pekare == 2) // om osv... upp till 3 (fjärde spridaren)
{
spridardiff = sprdiff1; // ben D9
}
if (pekare == 3)
{
spridardiff = sprdiff3; // ben D8
}
// if (3800 < 3800 - 2500) blir 3800 < 1300 FALSKT (2500)
// if (11400 < 3800 - 2500) blir 11400 < 1300 FALSKT (10100)
// if (3800 < 11400 - 2500) blir 3800 < 8900 SANT (5100)
// if (2000 < 2000 - 2500) blir 2000 < -500 FALSKT Detta är dom 28 vanligaste lägen
// if (10000 < 2000 - 2500 ) blir 10000 < -500 FALSKT
// if (2000 < 10000 - 2500) blir 2000 < 7500 SANT
if (puls < priv - fasttid) // jämför on ny pulstid är mindre än förgående - fasttid.
{
digitalWrite (pulsutpin, LOW); // utpin blir låg igen nästa uppgång i pulståget.
}
}
// end void loop()
Jag har ju som sagt kört denna kod ganska länge under dom mesta kombinationer av fart och effekt. Jag kan inte se att den gör nåt konstigt... Men det är klart en motor lämnar inte ut en statisk signal, den vandrar både per varv och framförallt inom varvet. Men jag kan se att dels uppfattar programmet förändringarna och dels justerar den efter det.
Så frågan lite kvarstår om vilket...
Jag har tillfälligt gjort om programmet på en liten snutt så jag kan tidigarelägga spridarnas tillslagstid och duration per spridare med 4 potar, en för varje spridare men jag tycker mig inte märka att den går bättre vid något enskilt tillfälle. ja, här är filen för det också:
Kod: Markera allt
// Förändrad 2018-11-17 och inlagd 11/17, aktiv/inaktiv fungerar
// utmärkt. max ändrat till strax under 4000 rpm ua. Tändläget verkar ua ochså.
// nu läser den av alla analogread i följd om 2 och 2 = fungerar!!
// batterispänningens inverkan grovjusterad = fungerar
// en individuell möjlig injustering per spridare finns med.
// ändrad i gasen så 5 volt är tomgång och 0 volt fullfart
// hitat fel i analogRead glömt break, skiftat fel på gas i case 2: >>3 istället för >>2
// 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 = 10; // totaltid för case 16: x * motorns duration (13)
const int tryckminskn = 60; // turbotrycket ställs in här, högre tal = mindre tryck (60)
const int lagstavarv = 500; // tomgångsvarvet 500 uS motsvarar ca 800 Rpm (500)
byte hogstavarv = 100; // fullgasvarvet 100 uS motsvarar ca 4200 RPM (100)(160 = ca 2500 RPM)
const byte aggrfaktorlag = 8; // hur mycket spridar PWM skall öka vid belastning mellanvarv (8)
const byte aggrfaktorhog = 20; // hur mycket spridar PWM skall öka vid belastning högvarv (20)
const int minfart = 3800; // lägsta startvarv för spridarfunktion (3300 uS = 152 RPM)(3300)skall vara på 3800
const byte startmangd = 11; // avgör max startmäng 9 = 1,5 vevaxelpulser = 9 grader ontid (9)
const float maxdeltalag = 7.0; // max insprutningstid mellanvarv mdutation * 6.0 ger 3 vevaxelpulser = 18 gr ontid (9.0)
const byte lagmangd = 11; // max lågvarvsmängd 4 = 2 vevaxelpulser = 9 grader ontid (under tomgångsvarv)(4)
const int tid1 = 2500; // tid 1 är för att hitta pulsluckan vid start/lågvarv < 300 RPM (400)
const int tid2 = 1500; // tid 2 är för att hitta pulsluckan i mellanvarv 1100--> (1200)
const int tid3 = 1000; // tid 3 är för att hitta pulsluckan i alla andra förekommande varv 1100--> (300)
const int tid4 = 100; // tid 4 är för att hitta pulsluckan på högsta varvtal
const byte turbostartregl = 150; // när tubotrycket börjar avläsas och bli aktivt (150 = uS mduration ca 3200RPM)(150)
const float senasteinspr = 7.0; // senaste insprutningstid (vid tomgång)(7.0 = 3,5 vevaxelpulser = 21 grader delaytid
const byte tidigasteinspr = 60; // kortaste insprutningsfördröjning (vid maxvarv)(60=t19=24grFödp)(30=t20=18grFödp)
const int sprtroghet = 400; // ett grundvärde för spridarnas påslagsfördröjning i uS.
int sprdiff1 = 0; // en ev tidigareläggning av spridare 1 om den avviker i startfördröjning (uS)
int sprdiff2 = 0; // en ev tidigareläggning av spridare 2 om den avviker i startfördröjning (uS)
int sprdiff3 = 0; // en ev tidigareläggning av spridare 3 om den avviker i startfördröjning (uS)
int sprdiff4 = 0; //20 // en ev tidigareläggning av spridare 4 om den avviker i startfördröjning (uS)
int vevpin = 2; // pulsingång vevaxelgivare, (aktivt hög).
int kampin = 3; // kamaxelgivarens ingång, (aktivt låg).
int varvpin = 4; // en varvbegränsningspinne
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 18)
long puls, priv, delta; // senaste, föregående och delta (totalöppningstid) i uS(mS)
float error; // error = varvfelet i decimalform
float starttandf, finKorr; // starttand i decimalform för att få startfördröjningstid och finkorrigering av öppninstiden +-.
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 = 300; // Fasttid = tid,tid2 eller tid3 beroende på varvtal, startar alltid på 300 uS
byte analogval; // En switch/case till analogread
int turbotryck; // turbotryck
int battVolt = 400; // mäter systemspänning till spridare
int variabel1; // bra att ha variabel 1
int variabel2; // bra att ha variabel 2
int ambTemp = 300; // mäter omgivningstemperaturen
int atmtryck = 330; // mäter atmosfärstrycket
int sprstartkorr = 50; // spridarstartkorregering i uS, spänningsberoende
int sprtroghetklar; // korrektion för den inbyggda påslagströgheten i spridarna
int spridardiff; // en ev. individuell spridartid korrigering (uS)
void setup()
{
pinMode(vevpin, INPUT_PULLUP); // satt vevpin som ingång (2) Testar nu med pullup...
pinMode(kampin, INPUT); // satt kampin som ingång (3)
pinMode(sprpins[pekare], OUTPUT); // spridarutgångar satta som arrey (11,10,9,8)
pinMode(sprControl, OUTPUT); // en spridarutgång som blir hög varje gång en spridare öppnas (13)(Övervakningen)
pinMode(Disable, INPUT_PULLUP); // ECU väljare Hög = on, Låg = off (12)
pinMode(pulsutpin, OUTPUT); // satt pulsutpin som utgång (2 pulser per varv)(7)(övervakningen)
pinMode(varvpin, INPUT_PULLUP); // satt varvpin som ingång (4) varvtalsbegränsare
//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 17!
if (digitalRead(Disable)==LOW) // Disable låg stänger av ECU:n och gör den passiv
{
delta = 0; // Genom att delta (insprutningstid) förblir 0.
pinMode(sprpins[pekare], INPUT); // Gör om spridarutgångarna till ingångar för att ej belasta
pinMode(sprControl, INPUT); // Gör om spridarcontrollen till ingång för att ej belasta
}
else
{
pinMode(sprpins[pekare], OUTPUT); // Vid aktiv igen så gäller spridarutgångarna som utgångar igen.
pinMode(sprControl, OUTPUT); // Vid aktiv så gäller spridarcontrollen som utgång igen
} //*Detta är normalläget, samma som i setup*
if(digitalRead(varvpin)==LOW) // om varvpin är låg
{
hogstavarv = hogstavarv + 60; // så blir maxvarv 2500 Rpm
}
else
{
// maxvarv blir 4200 Rpm
}
if (kamtand <= 256) // när kamtanden är räknad 251 gånger så 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 1: // Detta case ger första pulstid
delvalue = priv; // Första pulstid läggs in som deltid 1
break;
case 2: // Detta case ger andra pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
sprstartkorr =map(battVolt, 150, 700, 0, 400); // batterispänningen blir spridartidskorrigering
sprstartkorr = constrain(sprstartkorr,150,400);
break;
case 3: // Detta case ger tredje pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 4: // Detta case ger fjärde pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 5: // Detta case ger femte pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 6: // Detta case ger sexte pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 7: // Detta case ger sjunde pulstid
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
break;
case 8: // Detta case ger motorns börvärde från gaspoten som blir lägsta och högsta varvtal
bduration =map(gas,255, 0, 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
break;
case 9: // 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
break;
case 10: // 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; // felet i uS mellan är och börvärde för motorns fart
case 11: // 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
// 400 + (0 till 50) - (0 till 400)
break; // 400 + 0 - 50
case 12: // Detta case för insprutningsfördröjning i gånger, ställs högst upp
starttandf = mduration /tidigasteinspr; // starttandf, ett flyt-tal = motorns duration/ minsta duration/max RPM. ställs högst upp
if (starttandf >= senasteinspr) // om fördröjning över målvärdet, som vid tex startvarv (ställs in högst upp)
{
starttandf = senasteinspr; // blir det målvärdet ändå
}
break;
case 13: // Detta case ger förtändningen
ondelay = (mduration * starttandf); // tillslagsfördröjning = motorns duration * starttandsfördröjning (decimaltal)
break; // Ondelay uS = mduration uS * starttandf i decimalform
case 14: // 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 15: // (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 ; // används ej än så delta förblir delta oförändrat
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
break;
case 16: // Detta case är insprutningsfasen "spridar-on-off-mode"
if (ondelay >=8000) // 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.
// 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)
{
delta = 0; // delta(insprutningstid)blir 0 vid för lågt varv
}
// och startmängden vid motorstart
if ((delta * 4)>= 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. (> 300 RPM)
{
if (delta > 50) // Delta under 50 uS har inget värde
{
delta = delta + sprtroghetklar; // Delta över 50 blir x delta + trögheten i spridaren (ca 250 uS)
}
ondelay = ondelay - sprtroghetklar; // tidigarelägger insprutningstart med hänsyn till spridartrögheten
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 i on 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 17: // är mellan tand 19 och 24
switch (analogval)
{
case 0:
gas = analogRead(A0)>>2; // analogingång för gasreglage 0 till 255( skiftad 2 gånger)
//turbotryck = analogRead(A4);
sprdiff4 = analogRead(A4)>>3;
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)
sprdiff1 = analogRead(A1)>>3;
battVolt = analogRead(A7); // skall vara 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,
sprdiff2 = analogRead(A2)>>3;
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);
sprdiff3 = analogRead(A3)>>3;
break;
}
analogval ++; // räkna upp analogval 1 steg
if (analogval > 5) // när analogval har blivit 5 så
{
analogval = 0; // resettas analogval till 0 igen
}
break; // analalogRead tar ca 120 uS att läsa = 1-2 tänder vid fullvarv
/* case 18:
Serial.print("cyl1 ");
Serial.println(sprdiff1);
Serial.print("cyl2 ");
Serial.println(sprdiff2);
Serial.print("cyl3 ");
Serial.println(sprdiff3);
Serial.print("cyl4 ");
Serial.println(sprdiff4);
break;
*/
}
//______________________________________________________________________________________________________
tand ++ ; // räkna upp ett steg för varje ny puls, kommer via pulseIn()funkt.
priv = puls; // lägger in den förra pulstiden i värdet "priv" (uS)
//Serial.println(priv);
if (mduration >1800) // när motorn går på allra lägsta varv (start)
{
fasttid = tid1; // används tid1 (4000 uS i grundinställning)
}
if ((mduration > 1200)|| (mduration < 1800))
{
fasttid = tid2;
}
if ((mduration > 500)||(mduration < 1200)) // Om motorn går under 1100 RPM
{
fasttid = tid3; // används tid2 (1200 uS i grundinställning)
}
if (mduration <500) // Om motorn går över 1100 RPM
{
fasttid = tid4; // används tid3 (300 uS i grundinställning)
}
puls = pulseIn(vevpin, LOW, 30000); // Ett färdigt kommando som väntar in nästa puls (tand = case).
// vid stillastående motor blir det en timeout
// efter 0,03 Sek
// if (3800 > 3800 + 2500) blir 3800 > 6300 FALSKT (-2500)
// if (11400 > 3800 + 2500) blir 11400 > 6300 SANT luckan funnen! (+5100)
// if (3800 > 11400 + 2500) blir 3800 > 13900 FALSK (-10100)
// if (2000 > 2000 + 2500) blir 2000 > 4500 FALSKT Detta är dom 28 vanligaste lägen (-2500)
// if (10000 > 2000 + 2500 ) blir 10000 > 4500 SANT Luckan funnen, då det är lång tid till nästa tand (efter luckan)
// if (2000 > 10000 + 2500) blir 2000 > 12500 FALSKT Nu är det vanlig tid igen, första tanden börjar om räkningen
if (puls > priv + fasttid) // jämför om ny pulstid i uS är större än föregående + fasttid.
{
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 ++; // 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) // om spridarpekaren pekar på 0 (ben D11)
{
spridardiff = sprdiff4; // skall det individuella värdet för spridare 4 hämtas
}
if (pekare == 1) // om spridarpekaren pekar på 1 (ben D10)
{
spridardiff = sprdiff2; // skall det individuella värdet för spridare 2 hämtas
}
if (pekare == 2) // om osv... upp till 3 (fjärde spridaren)
{
spridardiff = sprdiff1; // ben D9
}
if (pekare == 3)
{
spridardiff = sprdiff3; // ben D8
}
// if (3800 < 3800 - 2500) blir 3800 < 1300 FALSKT (2500)
// if (11400 < 3800 - 2500) blir 11400 < 1300 FALSKT (10100)
// if (3800 < 11400 - 2500) blir 3800 < 8900 SANT (5100)
// if (2000 < 2000 - 2500) blir 2000 < -500 FALSKT Detta är dom 28 vanligaste lägen
// if (10000 < 2000 - 2500 ) blir 10000 < -500 FALSKT
// if (2000 < 10000 - 2500) blir 2000 < 7500 SANT
if (puls < priv - fasttid) // jämför on ny pulstid är mindre än förgående - fasttid.
{
digitalWrite (pulsutpin, LOW); // utpin blir låg igen nästa uppgång i pulståget.
}
}
// end void loop()
Ingen större skillnad... men dom analoga här är spridarjusteringar istället för div temperaturer mm.
Och sen kan jag aktivera Serialen och få ut värdena per spridare för att sen lägga in dom i konstanterna. (sprdiff1-3)