ECU- styrning till en VW pumpdysediesel.
Re: ECU- styrning till en VW pumpdysediesel.
Bosen: Genom praktiska försök har jag kommit fram till att ju fler tänder som beräkningsgrund, desto lugnare/bättre blir regleringen. Men, efter 9 tänder blir det inte så mycket bättre... (ganska noga testat)
BTW, jag har nu löst via en if-sats så varje case läses bara en gång. Jag tror inte alla case blir kritiska så jag kommer bara att ha if-satsen på dom som verkligen behöver det... Nu kan jag egentligen inte programmera så det finns förmodigen mycket bättre/lättare lösningar för detta. Men nu läser den rätt så summorna blir ochså rätt.
BTW, jag har nu löst via en if-sats så varje case läses bara en gång. Jag tror inte alla case blir kritiska så jag kommer bara att ha if-satsen på dom som verkligen behöver det... Nu kan jag egentligen inte programmera så det finns förmodigen mycket bättre/lättare lösningar för detta. Men nu läser den rätt så summorna blir ochså rätt.
Re: ECU- styrning till en VW pumpdysediesel.
De praktiska försöken gjorde du väl när du inte körde interrupt? Nu när du kör interrupt så har du en nogrannare mätning och andra förutsättningar.
Re: ECU- styrning till en VW pumpdysediesel.
Kan tänkas, men jag ser faktiskt inga som helst flaskhalsar just pga utebliven interrupt med tidsräkningen. Däremot har jag hittat felet varför den gick dåligt vid gaspådrag högre varv. Jag hade så långa insprutningstider (antagligen för långa även med fullt turbotryck) så motorn helt enkelt tjövde sig och behövde gå ett par sekunder utan belastning för att hämta sig. Nu har jag ställt ner dom parametrarna ganska rejält, aggfaktorhog 20 till 7 resp aggfaktorlag 8 till 6, (se min ECU-fil lite längre bak i tråden) Sen dess har jag bara provat runt lite på gården och nu är jag närmare rätt härad i insprutningsmängder per slag. Jag lämnade traktorn ute i natt för att kolla startvilligheten vid 0 grader. Jag har kopplat in glöden på Grållens gamla startkontakt som man aktiverade med växelspaken, det finns ett speciellt återfjädrande startläge på alla gamla Grållar så man kan inte glömma växeln i vid start...
Re: ECU- styrning till en VW pumpdysediesel.
Den var inte speciellt lätt att få igång (-1 grad) men gick igång efter lite malande. Den ryker knappt alls vid start så jag tror startmängden skall ökas rejält.
Re: ECU- styrning till en VW pumpdysediesel.
mrfenzy: såg först nu ditt svar på läst/olästflagga. jag gjorde så själv men vände på 0 och 1... Jag har frågat den som gjorde motorsim-koden så jag återkommer där.
Re: ECU- styrning till en VW pumpdysediesel.
Skit också, det funkar inte med caseRead == 0 och oläst == 1, det borde det göra?
Vad tusan gör jag för fel?
Kod: Markera allt
const unsigned int hogstavarv = 200; // div konstanta värden
const unsigned int lagstavarv = 1000;
int inpin = 2;
int utpin = 10;
unsigned long VEVTAND_langd;
unsigned long VEVTAND_start;
unsigned long delvalue = 0;
byte tand = 0;
unsigned long prev_langd;
float mduration;
int caseRead;
int gas;
float bduration;
int battvolt;
int sprstartkorr;
float error;
float starttid;
void setup()
{
pinMode(inpin, INPUT); // satt inpin som ingång
attachInterrupt(digitalPinToInterrupt(inpin), VEV_pulse, RISING); // här blir inpin interruptstyrd
pinMode(utpin, OUTPUT); // satt utpin som utgång
Serial.begin(9600); // initsierar serialprintfunktionen på 250000 b/sek
}
void loop()
{
switch (tand) // här startar switch och case, tandräknaren stegar fram ett steg (case)
{
case 1: // Case 1:
if(caseRead == 1) // om den inte redan är läst så läses case 1
{
delvalue = VEVTAND_langd; // tandluckan läggs in som första delvärde
// gas = analogRead(A0)>>2; // gaspot läses av här, skiftas två gånger (0-255)
// bduration = map(gas, 0, 255, lagstavarv, hogstavarv); // motorns börduration bestäms här (1000-100 uS)
// Serial.println(delvalue);
}
caseRead = +0; // case 1 flaggas av som läst hä}
break;
case 2:
if(caseRead == 1)
{
delvalue = VEVTAND_langd + delvalue;
//battvolt = analogRead(A7);
//sprstartkorr = map(battvolt, 150, 700, 200, 800);
//sprstartkorr = constrain(sprstartkorr,150,400);
Serial.println(delvalue);
}
caseRead = +0;
break;
case 3:
if(caseRead == 0)
{
delvalue = VEVTAND_langd + delvalue;
}
caseRead = 1;
break;
case 4:
if(caseRead == 0)
{
delvalue = VEVTAND_langd + delvalue;
}
caseRead = 1;
break;
case 5:
if(caseRead == 0)
{
delvalue = VEVTAND_langd + delvalue;
}
caseRead = 1;
break;
case 6:
if(caseRead == 0)
{
delvalue = VEVTAND_langd + delvalue;
}
caseRead = 1;
break;
case 7:
if(caseRead == 0)
{
delvalue = VEVTAND_langd + delvalue;
//Serial.println(delvalue);
}
caseRead = 1;
break;
case 8:
if(caseRead == 0)
{
mduration = VEVTAND_langd + delvalue;
mduration = mduration/12;
// Serial.println(mduration);
}
caseRead = 1;
break;
case 16:
if(caseRead==0)
{
error = (mduration / bduration)-1;
if (error <=0.) // om error under noll
{
error = 0.; // förblir error 0 för att ej få minusvärden
}
if(error >=6.)
{
error = 6.;
}
starttid = map(mduration, 2000, 200, 21., 17.);
//starttid =constrain(starttid, 17,21);
//Serial.println(mduration);
}
caseRead = 1;
break;
}
//Serial.print(mduration);
//Serial.print(" ");
//Serial.println(starttid);
}
void VEV_pulse() // Den interruptstyrda delaen börjar här
{
caseRead = 1;
prev_langd = VEVTAND_langd; // nuvarande vevtands längd läggs in som föregående vevtandslängd (döper om)
VEVTAND_langd = micros()-VEVTAND_start; // Längden på nuvarande lucka hamnar i variabeln VEVTAND_langd
VEVTAND_start = micros(); // Börja mätning av lucka
tand++; // tandräknaren räknar upp en tand
// caseRead = 0; // en "flagga" sätts till 0 = oläst case
//Serial.println(tand);
if(VEVTAND_langd > prev_langd +150) // OM nyaste vevtands längd är längre än föregåendes + 150
{ // då är luckan hittad
digitalWrite(utpin, HIGH); // Då går utpin hög
tand = 0; // och tandräknaren resetas till 1 (början på tandräkningen)
}
if(VEVTAND_langd < prev_langd -150) // OM nyaste vevtands längd är kortare än föregående -150
{ // då är luckan slut
digitalWrite(utpin, LOW); // och utpin blir låg igen.
}
}
Re: ECU- styrning till en VW pumpdysediesel.
Här kommer motorsim alá JPD
Kod: Markera allt
unsigned long now, last, last_read;
boolean led_on;
boolean adc_in_progress = false;
int vevpin2 = 2; // vevaxelutgång, ger 28 pulser 2 luckor, 28 pulser 2 luckor ( 1 varv)
int kampin = 3; // kamaxelutgång, ger 7 pulser per varv enligt ett fast mönster.
unsigned long hz; // analogvärdet omsatt i frekvens
unsigned long tid1; // delaytid i us ontid == offtid
byte x,temp; // 1 till 120 räknare
const byte adcPin = 1;
const byte synkpin = 7;
void setup() {
last = 0;
last_read = 0;
pinMode(vevpin2, OUTPUT); // vevpin satt som utgång
pinMode(synkpin, OUTPUT); // synkpinne för scopet
pinMode(kampin, OUTPUT); // kampin satt som utgång
Serial.begin(250000);
x=1;
adc_in_progress = false;
// ADC setup
ADCSRA = bit (ADEN); // turn ADC on
ADCSRA |= bit (ADPS0) | bit (ADPS1) | bit (ADPS2); // Prescaler of 128
ADMUX = bit (REFS0) | (adcPin & 0x07); // AVcc
}
void handle_kampin(){
if (x==4)// || x==13 || x==34 || x==37 || x==64 || x==94 || x==100)// här ändrat för att bara ha en puls/2 varv
{
digitalWrite(kampin, HIGH);
} else {
digitalWrite(kampin, LOW);
}
}
void oscilloskop_trig(){
if (x==1){ // puls för att synka oscilloskopet på
digitalWrite(synkpin, HIGH);
} else {
digitalWrite(synkpin, LOW);
}
}
void handle_tick(){ // körs varje gång en tidslucka har hänt - två gånger per kugg
if (!led_on){
x++;
if (x>120){
x=1;
}
temp = x % 30; // modulo - letar rätt på luckorna 29,30,59,60,89,90,119,120
if (temp!=29 && temp!=0){
digitalWrite(vevpin2, HIGH);
}
led_on=true;
handle_kampin();
oscilloskop_trig();
} else {
digitalWrite(vevpin2, LOW);
led_on=false;
}
}
void read_pot()
{
if (!adc_in_progress)
{
bitSet (ADCSRA, ADSC);
adc_in_progress = true;
}
if (bit_is_clear(ADCSRA, ADSC))
{
int pot = ADC; // read result
/* ca 90 us:
hz = map(pot,0, 1023, 800, 4200); // här omvandlas fart till hz
tid1 = map(hz, 800, 4200, 1250, 120); // här omvandlas hz till tid on/off
*/
/* ca 4us
tid1 = 120 + pot;
*/
/* ca 6us med bättre varvtalsområde:
tid1 = 120 + ((pot*9)>>3);
*/ // 120
// tid1 = 80 + ((pot*25)>>3); //multiplikation med 9/8 som heltal. 60 eller 100 skall vara 120!!
tid1 = pot;
// Serial.println(tid1);
tid1 = map(tid1,0,1023, 4000, 125); //4000, 100
// Serial.println(tid1);
adc_in_progress = false;
}
}
void loop()
{
now = micros();
if ((now-last_read)>10000){
read_pot(); // Läs poten 100 ggr/s
last_read = now;
}
if ((now-last)>tid1){
handle_tick();
last = now;
}
}
// Fungerar väldigt bra!!
Re: ECU- styrning till en VW pumpdysediesel.
Det har blivit en liten filmsnutt på provkörningen...
- Klas-Kenny
- Inlägg: 11343
- Blev medlem: 17 maj 2010, 19:06:14
- Ort: Växjö/Alvesta
Re: ECU- styrning till en VW pumpdysediesel.
Börja med att göra variabeln volatile, annars har du inte en aning om vad kompilatorn hittar på för dumheter. Kan mycket väl orsaka ett sånt fel.
Edit: Fast du sätter ju variabeln till 1 i de flesta case-fall, det är väl fel?
Edit: Fast du sätter ju variabeln till 1 i de flesta case-fall, det är väl fel?
Re: ECU- styrning till en VW pumpdysediesel.
Ja det måste blivit en miss i några av casen.
Du ska väl aldrig någonsin sätta caseRead=1 i mainloop, bara till 0.
för säkerhets skull kan du göra alla dessa volatile:
VEVTAND_langd
VEVTAND_start
tand
caseRead
Du ska väl aldrig någonsin sätta caseRead=1 i mainloop, bara till 0.
för säkerhets skull kan du göra alla dessa volatile:
VEVTAND_langd
VEVTAND_start
tand
caseRead
Re: ECU- styrning till en VW pumpdysediesel.
Jag har nu provat lite olika kombinationer men det blir inte bra... Den läser ibland caset en gång ibland två, tre gånger och plussar ihop.
Jag kan se på Serialmonitorn att den går ojämnt, det kan liksom hänga sig ena stunden för att ge flera tal på en gång nästa stund. Det är nåt vajsing.
Jag kan se på Serialmonitorn att den går ojämnt, det kan liksom hänga sig ena stunden för att ge flera tal på en gång nästa stund. Det är nåt vajsing.
Re: ECU- styrning till en VW pumpdysediesel.
Jag läser om "volatile" på Arduinos hemsida och dom skriver att det kan bli en del konstigheter. Man skall ev. de-aktivera interruptet precis efter det gjort sitt och sen aktivera det igen efter tex. delvalue-mätningen. Men jag är dålig på engelska och vet inte heller hur man bör programmera... Är det någon som känner sig manad?
Re: ECU- styrning till en VW pumpdysediesel.
Jag har bara en arduino här, har beställt en till för ett tag sen. Så snart den kommit ska jag göra en uppkoppling med din simulator och knacka ihop ett litet exempelprogram som fungerar.
- Klas-Kenny
- Inlägg: 11343
- Blev medlem: 17 maj 2010, 19:06:14
- Ort: Växjö/Alvesta
Re: ECU- styrning till en VW pumpdysediesel.
Allt du behöver göra för volatile är att lägga till nyckelordet då variablerna deklareras.
Det du kommer in på med att inaktivera interrupt är just det som jag skrev en del om några inlägg tillbaka. Men jag tror inte du kommer få några problem med just det, så som ditt program fungerar.
Så länge som main-loopen alltid hinner minst ett varv per interrupt så är det ju ingen risk att någon variabel skrives mitt i en läsning nu i och med din "caseRead".
Prova med volatile enligt ovanstående, se om det gör någon skillnad.
Kod: Markera allt
volatile unsigned long VEVTAND_langd;
volatile unsigned long VEVTAND_start;
volatile byte tand = 0;
volatile int caseRead;
Så länge som main-loopen alltid hinner minst ett varv per interrupt så är det ju ingen risk att någon variabel skrives mitt i en läsning nu i och med din "caseRead".
Prova med volatile enligt ovanstående, se om det gör någon skillnad.
Re: ECU- styrning till en VW pumpdysediesel.
mrfenzy: Jag kan skicka en arduinoklon direkt om du vill..
Klas-Kenny: Jag har gjort allt detta redan och resultatet är exakt samma. Jag har även provat caseRead som HIGH/LOW, det jag inte testat är TRUE/FALSE. En grej jag ser på din kodsnutt är att: tand = 0 där din nolla är blå, varför?
Klas-Kenny: Jag har gjort allt detta redan och resultatet är exakt samma. Jag har även provat caseRead som HIGH/LOW, det jag inte testat är TRUE/FALSE. En grej jag ser på din kodsnutt är att: tand = 0 där din nolla är blå, varför?