Nä jag är bara nyfiken o DJUPT imponerad..
Ödmjuk inför dina kunskaper liksom. Keep on!
// Förändrad 2018-08-02 och inlagd 08/03, 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.
// 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)
const byte hogstavarv = 120; // 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)
const byte startmangd = 9; // avgör max startmäng 9 = 1,5 vevaxelpulser = 9 grader ontid (9)
const float maxdeltalag = 5.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 = 20; //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 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) // <<<<<<<<<<<<<<<<<------------HÄR
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 = 0; // 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)
//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 (kamtand <= 250) // 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,50,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,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
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
// 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
}
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:
// ledigt
// break;
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.
// 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.
} // 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);
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);
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 (puls > priv + fasttid) // jämför om ny pulstid i uS är större än föregående + tid1 eller tid2.// <<<<<<<<<<<-------------HÄR
{
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
{
spridardiff = sprdiff4; // skall det individuella värdet för spridare 4 hämtas
}
if (pekare == 1) // om spridarpekaren pekar på 1
{
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;
}
if (pekare == 3)
{
spridardiff = sprdiff3;
}
if (puls < priv - fasttid) // jämför on ny pulstid är mindre än förgående - fasttid. // <<<<<<<<<<-------------HÄR
{
digitalWrite (pulsutpin, LOW); // utpin blir låg igen nästa uppgång i pulståget.
}
}
// end void loop()
Återgå till [Traktorer] Allmänt
Användare som besöker denna kategori: Hidsmekolek, Simse och 20 gäster