Re: ECU- styrning till en VW pumpdysediesel.
Postat: 14 december 2016, 22:02:10
Från början en VNT men den kommer jag att låsa i yttersta läget då jag inte behöver några lågvarvsegenskaper.
Svenskt forum för elektroniksnack.
https://elektronikforumet.com/forum/
Kod: Markera allt
int kampin7 = 7; //kamaxelgivarens ingång, (aktivt låg). används ej än...
int vevpin2 = 2; // pulsingång vevaxelgivare, (aktivt hög).
int utpin3 = 3; // pulsutgång 2 pulser per varv (kontrollutgång)
int sprpin1 = 8; // till spridare 1 (blir aktivt hög)
int sprpin2 = 9; // 2 används ej än
int sprpin3 = 10; // 3 -:-
int sprpin4 = 11; // 4 -:-
long puls, priv; // här läggs den senaste och föregående pulstiden in i microsekunder
long starttid, stopptid, sluttid, delta; // starttid, stopptid, sluttid och delta i microsek.
float error, mduration, bduration; // = varvfelet = motorduration/börduration i decimalform
byte x = 0; // vevpin2 räknare 0 till 28
byte starttand, gas, turbo, vtemp; //starttand = vilken tand där spridaren skall öppna.
// och gas 0-255, turbo 0-127, vtemp 0-127
//________________________________________________________________________________________________
void setup()
{
pinMode(vevpin2, INPUT); //sätt vevpin2 som ingång
pinMode(sprpin1, OUTPUT); // spridarutgång 1 ben 8
pinMode(sprpin2, OUTPUT); // 2 ben 9
pinMode(sprpin3, OUTPUT); // 3 ben 10
pinMode(sprpin4, OUTPUT); // 4 ben 11
pinMode(utpin3, OUTPUT); // sätt utpin3 som utgång
Serial.begin(250000); // bra att ha
}
//_________________________________________________________________________________________________________
void loop()
{
// Det får plats ca 1700 klockcykler mellan varje x tal (1 till 27) Det tar ca 100 mikrosek att läsa av en analogingång, så max en per lucka.
if (digitalRead(utpin3)== HIGH)// när utpin3 går hög startar 0-25 räknaren
{
x = 0; // säkerställer att vevpin2 räknaren börjar på 0
}
x ++ ; //räkna upp ett steg för varje ny puls Fungerar
if (x == 1) // Vid första vevpinpuls Gör:
{
gas = analogRead(A1)>>2; // analogingång 0 till 255( skiftad 2 gånger)Fungerar
}
if (x == 2) // Vid andra vevpinpuls Gör:
{
// turbo = analogRead(A0)>>3; // analogingång för turbotryck 0 till 127 (skiftad 3 gånger)
}
if (x == 3) // Vid tredje vevinpuls Gör: osv
{
// ledigt
}
if (x == 4)
{
bduration =map(gas,0, 255, 660, 115); // motorns börvärde från gaspoten. 660 mS =tomgång, 115 mS = fullvarv. (ca 750 rpm till ca 4500 rpm)
}// 660 - 115 mS = 750 till 4500 rpm Fungerar
if (x == 5)
{
// ledigt
}
if (x == 6)
{
mduration = priv; // motorns pulstid i mikrosek ger motorns fart. 660 - 115 mS
} // 660 - 115 = 660 - 115 mS Fungerar
if (x == 7)
{
error = (mduration / bduration); // felet i mikrosekunder mellan är och börvärde för motorns fart baserat på pulslängderna.
} // 0.0 - 6.0 Fungerar
if (x ==8)
{
// ledigt
}
if (x == 9)
{
// ledigt
}
if (x==10)
{
// ledigt
}
if (x ==11)
{
// ledigt
}
if (x==12)
{
starttand = map(priv,1300, 130, 21, 18); // y1 = spridarstart från tand 21 vid tomgång till tand 18 vid fullvarv, ca 6-36 grader FÖDP
}// förtändningen i 4 fasta steg, fungerar
if(x == 13)
{
// ledigt
}
if (x == 14)
{
// ledigt
}
if (x ==15)
{
// ledigt
}
if (x == starttand) // när rätt puls är räknad, sätt sprpin1 hög, (tand 21 till 18)
{
starttid = micros(); // här vill jag ha en markör som signalerar i micros() att sprpin1 går hög. -------<<<<<<<<<--------Kolla
digitalWrite (sprpin1,HIGH); //spridarpinne hög, insprutning börjar. pin 8 Fungerar
} // alternatit att micros() nollställs när sprpin går hög?? ------------------------------------------<<<<<<<<<<--------Kolla
delta = mduration * error ; // felkorrigeringsvärde Fungerar
sluttid = starttid + delta; // själva uträknaren fungerar
if (delta, micros() >= sluttid, micros() ) // Detta fungerar nog inte!!! --------------------------------<<<<<<<<<-------Kolla
{
digitalWrite (sprpin1,LOW); //spridarpinne låg, insprutning avslutad pin 8 denna fungerar nog inte heller ----------<<<<<-Kolla
} // Antingen stänger den av direkt, det blir bara en spik eller stänger den inte av alls. ---------------<<<<<<<<-------Kolla
Serial.print(starttid);
Serial.print(" ");
Serial.print(delta);
Serial.print(" ");
Serial.println(sluttid); // Hela serialpaketet fungerar men stör övriga funktioner vid lite högre farter, så bara för test.
if (x == 26 || x < starttand)
{
digitalWrite (sprpin1, LOW); // För att säkerställa att spridaren stängs av senast 18 grader efter ödp (tand 26)
}// Denna funktion tar över när tidsfunktionen inte går Fungerar
if (x == 26)
{
}
if (x >= 27) // efter 28 pulser sätt x till 0
{
x = 0; //reseta 0-28 räknaren Fungerar
}
priv = puls; // gämför ny pulstid med föregående pulstid
puls = pulseIn(vevpin2, LOW); //Triggar på nersidan
if (puls > priv+25) // jämför om ny pulstid i mikrosekunder är större än föregående + 25 mikrosek.
{
digitalWrite (utpin3, HIGH); // utpin_ blir hög när pulsluckan återgår till pulser
}
if (puls < priv-25) // jämför on ny pulstid är mindre än förgående - 25 mikrosek.
{
digitalWrite (utpin3, LOW); // utpin_ blir låg igen nästa uppgång i pulståget.
}
}
// end void loop()
//________Hela detta paketet från: if (x == 27) Fungerar________________________________________________________________________________________________
Kod: Markera allt
int kampin7 = 7; //kamaxelgivarens ingång, (aktivt låg)
int vevpin2 = 2; // pulsingång vevaxelgivare, (aktivt hög).
int utpin3 = 3; // pulsutgång 2 pulser per varv (kontrollutgång)
int sprpins [] ={8,9,10,11}; // till spridarna (blir aktivt hög)
int sprControl = 13;// kontrollutgång för spridare till övervakningen.
int turbokorr; // utgående felkorrigeringsvärde från turbogivare
int disable = 12;// aktivt hög stoppar utsignalerna till spridarna
long puls, priv, delta, starttid, sluttid, turbovalue, delvalue; // senaste och föregående pulstiden in och start,slut i microsekunder,+ klart turbovärde.
float error; // error = varvfelet i decimalform
float starttandf; // starttand i decimalform.
float mduration, bduration; // varvfelet = motorduration/börduration i decimalform
byte x = 0; // vevpin2 räknare 0 till 28
byte gas, turbo, pekare, starttand; //starttand = vilken tand där spridaren skall öppna.
// och gas 0-255, turbo 0-127, tmp för att välja rätt spridarutgång
//________________________________________________________________________________________________
void setup()
{
pinMode(vevpin2, INPUT); //satt vevpin2 som ingång
pinMode(kampin7, INPUT_PULLUP);// satt kampin som ingång .
pinMode(sprpins[pekare],OUTPUT); // 8,9,10,11 satta som utgånsarrey
pinMode(sprControl, OUTPUT);// en spridarutgång som blir hög varje gång en spridare öppnas.
pinMode(disable, INPUT_PULLUP);// ECU väljare Hög = on, Låg = off.
pinMode(utpin3, OUTPUT); // sätt utpin3 som utgång
Serial.begin(250000); // bra att ha vid tester, skall var bortkopplat vid högre farter.(stör)
}
//_________________________________________________________________________________________________________
void loop()
{
// Det får plats ca 1700 klockcykler mellan varje x tal (1 till 27) Det tar ca 100 mikrosek att läsa av en analogingång, så max en per lucka.
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.
pinMode(sprpins[pekare],INPUT); // gör om spridarutgångarna till ingångar.
pinMode(sprControl, INPUT); // gör om spridarcontrollen till ingång.
}
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
}
x ++ ; //räkna upp ett steg för varje ny puls, kommer från pulseIn()funktionen, Fungerar
if (digitalRead(kampin7)== LOW) { // varje gång kamaxelns hempuls detekteras så resetas 4 räknaren
pekare = 0; // resetas till 0
}
if (x == 1) // Vid första vevpinpuls Gör:
{
gas = analogRead(A1)>>2;// analogingång 0 till 255( skiftad 2 gånger)Fungerar
delvalue = priv;// föregående pulstid läggs in som deltid 1
}
if (x == 2) // Vid andra vevpinpuls Gör:
{//0,034 v/steg
turbo = analogRead(A0)>>3; // analogingång för turbotryck 0 till 127 (skiftad 3 gånger)
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
}// atm = 1 volt, fullt turbotryck = 2,4 volt (1,4 bar över atm)>> A0 = 29 =atm, A0 = 70 = fullt turbotryck
if (x == 3) // Vid tredje vevinpuls Gör: osv
{
turbokorr = map(turbo, 0, 127, 100, 300); // här matas in 0 till 80 som max. invärdet bör bli 70, omgjort till korrfaktor 10
delvalue = priv + delvalue;// föregående pulstid + föregående deltid läggs ihop
if (turbokorr <=0)
{
turbokorr = 1; // för att undvika minusvärden
}
} //0 till 127 = 100 till 300
if (x == 4)
{
bduration =map(gas,0, 255, 660, 115); // motorns börvärde från gaspoten. 660 mS =tomgång, 115 mS = fullvarv. (ca 750 rpm till ca 4500 rpm)1250
delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
}// 660 - 115 mS = 750 till 4500 rpm Fungerar
if (x == 5)
{
turbovalue = (mduration * turbokorr); // detta värde minskar spridarens ontid när värdet blir högre än faktor 1
delvalue = priv + delvalue;// föregående pulstid + föregående deltid läggs ihop
}
if (x == 6)
{
mduration = delvalue/9; // motorns totala pulstid i mikrosek dividerat med 9 (4x2+1) ger motorns fart. 660 - 115 mS
} // 660 - 115 = 660 - 115 mS Fungerar
if (x == 7)
{
error = (mduration / bduration); // felet i mikrosekunder mellan är och börvärde för motorns fart baserat på pulslängderna.
} // 0.0 - 6.0 Fungerar
if (x == 8)
{
//error = error - 1;
if (error <=0)
{
error = 0;// för att ej få minusvärden
}
}
if (x == 9){
if (error >=6){
error = 6;// för att få max 6.0 som error
}
}
if (x== 10)
{
//ledigt
}
if (x == 11)
{
// ledigt
}
if (x==12)
{
// ledigt
}
if(x == 13)
{
// ledigt
}
if (x == 14)
{
// ledigt
}
if (x ==15)
{
starttandf = (mduration-130.0)*(22.0-17.0)/(1300.0-130.0);// +18
if ((starttandf >= 1)|| (starttandf <=1)){ // en test för att få variabel tillslagstid av spridare
starttandf = 0;
}
starttand = map(mduration,1300.0, 130.0, 22.0, 17.0); // spridarstart från tand 21 vid tomgång till tand 18 vid fullvarv, ca 6-36 grader FÖDP
//starttandf = starttandf -
if (starttand >= 22.0)
{
starttand = 22.0;
}
} // förtändningen i 4 fasta steg, fungerar Tand 23 är TDC
if (x ==16)
{
delta = (mduration * error) - turbokorr ; // felkorrigeringsvärde Fungerar
if (delta <=0)
{
delta = 0;// för att ej få minusvärden.
}
Serial.print(starttand);
Serial.print(" ");
Serial.println(starttandf);
}
if (x == starttand) // när rätt puls är räknad, sätt sprpin1 hög, (tand 22 till 17)
{
starttid = micros(); //Den sätter en markör vid spridarstart.
digitalWrite (sprpins[pekare],HIGH);//spridarpinne hög, insprutning börjar. pin tmp 8,9,10 eller 11
digitalWrite(sprControl, HIGH);
delayMicroseconds(delta); // Nyaste tankesättet, skiter i pulseIn() och väntar istället på offtiden
}
sluttid = micros(); // håller reda på när sluttiden skall vara
if ((delta <= sluttid - starttid)|| (delta <=delvalue /2)) //
{
digitalWrite (sprpins[pekare],LOW); //spridarpinne låg, insprutning avslutad pin tmp 8,9,10 eller 11
digitalWrite (sprControl, LOW);
}
//_________________________________________________________________________________________________________________________________________________________
priv = puls; // lägger in den förra pulstiden i värdet "priv"
puls = pulseIn(vevpin2, LOW, 20000); // Ett färdigt kommando som väntar in nästa puls, mäter offtiden, low
// vid stillastående motor blir det en timeout var 0,2 sekund.
if (puls > priv+25) // jämför om ny pulstid i mikrosekunder är större än föregående + 25 mikrosek.
{
digitalWrite (utpin3, HIGH); // utpin3 blir hög när pulsluckan återgår till pulser
x = 0; // resetar 0 till 28 räknaren
pekare=pekare+1;// räknar upp spridarpinnerä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
}
}
if (puls < priv-25) // jämför on ny pulstid är mindre än förgående - 25 mikrosek.
{
digitalWrite (utpin3, LOW); // utpin_ blir låg igen nästa uppgång i pulståget.
}
}
// end void loop()
//________Hela detta paketet Fungerar________________________________________________________________________________________________
Kod: Markera allt
#include <LiquidCrystal.h>
char x;
int ecuAktiv = 2; // pulsingång vevaxelgivare, (aktivt hög).
int inpin3 = 3; // pulsingång 2 pulser per varv till beräkning av motor/propvarv.
int motorvarvut = 9; // till motorns varvräknare PWM
int propvarvut = 10; // till propellervarvräknare PWM
int gasvalue; // gasvärde från poten 0-1023
int turbovalue;// turbovärde från tryckgivaren 0-1023
int sprSignalin = 8;// ansluts till valfri spridarutgång eller sprcontrol, valfritt
float sprTid; // spridaröppningstid i % av halvt motorvarv
float liter; // liter/timma
int rs=4, en=5, d4=6, d5=11, d6=12, d7=13;// till displayanslutningar
LiquidCrystal lcd(rs,en,d4,d5,d6,d7);// till display
long varvtalprop; // värde i microsek
long puls, varvtalmotor;// värde i mikrosek
int readECUAvoltage;
int readECUBvoltage;
int readbattVoltage;
int engineTemp;
int turboAirTemp;
int ambientTemp;
int atmTryck;//
float ECUAvoltage;
float ECUBvoltage;
void setup() {
pinMode(ecuAktiv, INPUT_PULLUP); //satt vevpin2 som ingång
pinMode(motorvarvut, OUTPUT); // till motorvarvräknare PWM
pinMode(propvarvut, OUTPUT); // till propvarvräknare PWM
pinMode(sprSignalin, INPUT); // från en valfri spridare
pinMode(inpin3, INPUT); // ingång för att beräkna motor/propvarvtal
lcd.begin(20,4);
lcd.setCursor(0,0);
lcd.print("Diesel ECU ver.1.0");// visar versionsnummer
lcd.setCursor(0,1);
lcd.print("Byggd av J Berglund");//
lcd.setCursor(0,2);
lcd.print("Motor VW PD 135 hp");//
lcd.setCursor(0,3);
lcd.print("Mjukvara 1.0 rev 0");//
Serial.begin(250000); // serial utgång till datorn
delay(5000);
}
void loop() {
gasvalue = analogRead(A0);
turbovalue = analogRead(A1);
atmTryck = analogRead(A2);
readECUAvoltage = analogRead(A3);
readECUBvoltage = analogRead(A4);
engineTemp = (5.0* analogRead(A5)*100.)/1024;// använder LM-35 tempgivare
turboAirTemp = (5.0* analogRead(A6)*100.)/1024;// använder LM-35 tempgivare
ambientTemp = analogRead(A7);
gasvalue = map(gasvalue,0,1023,0,100);// 0 till 100 % effekt börvärde
turbovalue = map(turbovalue,0,1023,400,4000);// 400 till 4000 mBar
atmTryck = atmTryck *4;// absoluttryck i mBar.
ECUAvoltage = readECUAvoltage *(6.0/1023.0); // ECU A drivspänning till 6 volt
ECUBvoltage = readECUBvoltage *(6.0/1023.); // ECU B drivspänning till 6 volt
ambientTemp =map(ambientTemp,0,1023,-20,60);// omgivningstemperatur -20 till 60 G c med en NTC
sprTid = pulseIn(sprSignalin, HIGH); // mäter in valfri spridares ontid
sprTid = sprTid/puls*100.;// gör om ontiden från microsek till procent
liter = sprTid * varvtalmotor /150;//: /150 skall provas ut...
if (digitalRead(ecuAktiv)== HIGH){
x = 'A';
}
else {
x = 'B';
}
lcd.setCursor(0,0);
lcd.print("Propeller ");
lcd.print(varvtalprop);
lcd.setCursor(0,15);
lcd.print(" ");
lcd.print(" RPM");
lcd.setCursor(0,1);
lcd.print("EFFEKTSETTING ");
lcd.print(gasvalue);
lcd.print(" %");
lcd.setCursor(0,2);
lcd.print("Motortemp ");
lcd.print(engineTemp);
lcd.print(" gr. C.");
lcd.setCursor(0,3);
lcd.print("FUELFLOW ");
lcd.print(liter);
lcd.print(" L/h");
Serial.print("Gasvalue ");// skriver ut div realtidsvärden
Serial.print(gasvalue);
Serial.print("% ");
Serial.print("Turbovalue ");
Serial.print(turbovalue);
Serial.print(" Bar ");
Serial.print("Turbo Air Temp ");
Serial.print(turboAirTemp);
Serial.println(" Grader C.");
Serial.print("Absoluttryck ");
Serial.print(atmTryck);
Serial.print(" mBAR ");
Serial.print("ECU A ");
Serial.print(ECUAvoltage);
Serial.print(" Volt ");
Serial.print("ECU B ");
Serial.print(ECUBvoltage);
Serial.println(" Volt");
Serial.print("Engine Temp ");
Serial.print(engineTemp);
Serial.print(" Grader C. ");
Serial.print("Ambient Temp ");
Serial.print(ambientTemp);
Serial.print(" Grader C.");
Serial.print(" ECU ");
Serial.print(x);
Serial.println(" Aktiv");
Serial.print("Motor ");
Serial.print(varvtalmotor);
Serial.print(" RPM");
Serial.print(" Propeller ");
Serial.print(varvtalprop);
Serial.print(" RPM");
Serial.print(" Pulswidth ");
if (varvtalmotor >=5100){// max pulslängd tomgång, < 5000 mikrosek
varvtalmotor = 0; // om stillastående/startmotorvarv så blir motorvarvet noll till ev varvräknare
}
varvtalmotor = map(varvtalmotor,0,5000,0,255);// 0 till 5000 mikrosek görs om till 0 till 255
analogWrite(motorvarvut,varvtalmotor); // ger ut en pwm signal 0 till 255 beroende på motorns varvtal
analogWrite(propvarvut,varvtalmotor * 0.625);// ger ut en pwm signal som är konverterad för att passa propellervarvet
Serial.print(varvtalmotor);// fortsättning div realtidsvärden
Serial.print(" spridare ");
Serial.print(sprTid);
Serial.println(" % open");
delay(100);
puls = pulseIn(inpin3, LOW); // väntar in nästa puls, Triggar på nersidan
// vid stillastående motor blir det en timeout varje sekund.
varvtalmotor = (1000000/puls)*30.06;// pulsbrädden görs om till RPM motor
varvtalprop = varvtalmotor *0.625;// RPM motor görs om till RPM propeller
}