ECU- styrning till en VW pumpdysediesel.

Berätta om dina pågående projekt.
Janson1
Inlägg: 1351
Blev medlem: 1 december 2016, 09:06:02
Ort: Marks Kommun

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Janson1 »

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.
Användarvisningsbild
Bosen
Inlägg: 1753
Blev medlem: 18 juli 2005, 10:56:31
Ort: Karl Gustav, Varberg
Kontakt:

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Bosen »

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.
Janson1
Inlägg: 1351
Blev medlem: 1 december 2016, 09:06:02
Ort: Marks Kommun

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Janson1 »

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...
Janson1
Inlägg: 1351
Blev medlem: 1 december 2016, 09:06:02
Ort: Marks Kommun

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Janson1 »

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.
Janson1
Inlägg: 1351
Blev medlem: 1 december 2016, 09:06:02
Ort: Marks Kommun

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Janson1 »

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.
Janson1
Inlägg: 1351
Blev medlem: 1 december 2016, 09:06:02
Ort: Marks Kommun

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Janson1 »

Skit också, det funkar inte med caseRead == 0 och oläst == 1, det borde det göra?

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.
   }
  
 }


  
Vad tusan gör jag för fel?
Janson1
Inlägg: 1351
Blev medlem: 1 december 2016, 09:06:02
Ort: Marks Kommun

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Janson1 »

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!!
 
Janson1
Inlägg: 1351
Blev medlem: 1 december 2016, 09:06:02
Ort: Marks Kommun

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Janson1 »

Det har blivit en liten filmsnutt på provkörningen...
Användarvisningsbild
Klas-Kenny
Inlägg: 11325
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Klas-Kenny »

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?
Användarvisningsbild
mrfrenzy
Co Admin
Inlägg: 14850
Blev medlem: 16 april 2006, 17:04:10

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av mrfrenzy »

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
Janson1
Inlägg: 1351
Blev medlem: 1 december 2016, 09:06:02
Ort: Marks Kommun

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Janson1 »

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.
Janson1
Inlägg: 1351
Blev medlem: 1 december 2016, 09:06:02
Ort: Marks Kommun

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Janson1 »

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?
Användarvisningsbild
mrfrenzy
Co Admin
Inlägg: 14850
Blev medlem: 16 april 2006, 17:04:10

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av mrfrenzy »

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.
Användarvisningsbild
Klas-Kenny
Inlägg: 11325
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Klas-Kenny »

Allt du behöver göra för volatile är att lägga till nyckelordet då variablerna deklareras.

Kod: Markera allt

volatile unsigned long VEVTAND_langd;
volatile unsigned long VEVTAND_start;
volatile byte tand = 0;
volatile int caseRead;
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.
Janson1
Inlägg: 1351
Blev medlem: 1 december 2016, 09:06:02
Ort: Marks Kommun

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Janson1 »

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?
Skriv svar