ECU- styrning till en VW pumpdysediesel.

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

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Janson1 »

Jag är inne lite på att skaffa en ZERO eller en DUE, den har en annan processor, 32 bitar istället för 8 vad det nu innebär...
Den går i alla fall att programmera i Arduinomiljön som jag blivit van vid. Rent teoretiskt så borde jag kunna flytta över min ECU sketch till den och få lite respit på tiderna, jag är nu ganska nära max. Och, jodå, det går säkert att programmera smartare men det klarar jag inte av just nu oavsett. Ett "problem" är ju att den går på 3,3 volt istället för 5 volt vilket ställer till det på utgångssidan, istället för att bara driva en MOS-transistor rakt av så behövs några extra komponenter, men det går! Det jag lite funderar på är att kunna köra överlagrad PWM på utgångarna till slutstegen. Med NANO:n/UNO:n blir det alldeles för dåligt, för låg frekvens helt enkelt (490 resp 980 Hz, dessutom den "höga" frekvensen bara på två utgångar). Där tror jag den större processorn blir ett bättre alternativ? Men vilka flaskhalsar har den tro??
Användarvisningsbild
KLset
Inlägg: 207
Blev medlem: 31 augusti 2014, 17:36:19
Ort: Uppsala

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av KLset »

Kul att du gör framsteg. Tidigare skrev du:
Jag har D2 och D3 som digital input från vev och kamgivare för dom är dom ända två som går att interrupta, fast det klarar jag inte av att få till med nån reda så jag har inget interrupt.
Skriv mer om det här så löser vi det. Vet du hur en interrupt fungerar till att börja med?
Det jag lite funderar på är att kunna köra överlagrad PWM på utgångarna till slutstegen. Med NANO:n/UNO:n blir det alldeles för dåligt, för låg frekvens helt enkelt
Överlagrad PWM - är det PWM som du genererar själv i mjukvaran till skillnad från att använda de inbyggda hårdvarumodulerna?
Borre
Inlägg: 4565
Blev medlem: 14 juni 2007, 15:43:50
Ort: Hälsingland

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Borre »

Janson1 skrev:Ett "problem" är ju att den går på 3,3 volt istället för 5 volt vilket ställer till det på utgångssidan, istället för att bara driva en MOS-transistor rakt av så behövs några extra komponenter, men det går! Det jag lite funderar på är att kunna köra överlagrad PWM på utgångarna till slutstegen. Med NANO:n/UNO:n blir det alldeles för dåligt, för låg frekvens helt enkelt (490 resp 980 Hz, dessutom den "höga" frekvensen bara på två utgångar). Där tror jag den större processorn blir ett bättre alternativ? Men vilka flaskhalsar har den tro??
Zero rekommenderar jag.
Väljer du "rätt" mosfet är 3.3V inget problem.
PWM-frekvensen går att ändra, läs tex https://playground.arduino.cc/Main/TimerPWMCheatsheet
Användarvisningsbild
hawkan
Inlägg: 2586
Blev medlem: 14 augusti 2011, 10:27:40

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av hawkan »

D2 och D3 är de pinnar som har extern intterrupt. Men nästan alla pinnar har möjlighet till "Pin change interrupt" som är lika bra (nästan).
För ditt ändamål borde det funka.
Bild
Alla pinnar som har "PCINTxxx" kan göra Pin change interrupt".

Så här krångligt satte jag upp det häromdan i min kod.

Kod: Markera allt

#include <EnableInterrupt.h>
...
setup()
{
  pinMode(PIN11, INPUT);        
  digitalWrite(PIN11, HIGH);
  enableInterrupt(PIN11, &pin11, CHANGE); // M40 S0
..
Pin change betyder att man får kolla om pinnen är hög eller låg det första man gör i isr för min del i pin11() som den så fantasilöst heter.

PWM-frekvensen går mycket riktigt att ändra, speciellt med Timer1 som är 16-bitars PWM. För Due och Zero så är analogOutput också kring 1 kHz och man får ändra pwm-inställningen på samma sätt som för Nano. Du får hur som helst lära dej hur man gör det och det är processorspecifikt genom att pilla på olika register, så du kan lika gärna lära dej principen på Nanon du har.
Janson1
Inlägg: 1338
Blev medlem: 1 december 2016, 09:06:02
Ort: Marks Kommun

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Janson1 »

Var skall jag börja? Borre: Jag har ej kollat om det finns EffektMOS-transistorer men finns så är det problemet löst. Skulle en vanlig transistor funka tro? Har den tillräckligt hög förstärkning så den inte belastar ner den stackars utgången?
Jag har tjuvtittat lite på andra PWM frekvenser men det jag behöver är 4 utgångar som har samma grundfrekvens ca 20 KHz men ev olika duty-cykel, ev en hög start som sen går ner efter nån millisekund. Själva upplösningen behöver inte vara högre än 8 bitar. Just den biten klarar en NANO nästan...
KLset: Ja det här med interrupt... I min nuvarande sketch där NANO:n är en ECU så behövs egentligen inte interrupt men om jag nu skall ha det så till vad? Jag har två pinnar som skall bevakas, den ena pinnen bevakas bara i 250 kamaxelvarv som max (125 motorvarv) sedan görs den döv (stänger av sig själv helt enkelt) kvar blir vevaxelgivarens ingång. Alla dom pulserna kommer ytters regelbundet, "man kan ställa klockan efter dom" vilket jag faktiskt gör. Mellan varje ny vevaxelpuls har jag en viss tid som är som kortast på fullvarv, ca 200 uS. Det finns ingenting som processorn inte hinner med i dag och analogread som är det ända som egentligen tar tid i anspråk ligger i slutet där det inte gör nåt om en puls eller två skulle missas, jag har totat ihop sketchen så... Som direkt svar på frågan om jag vet hur interrupt fungerar så är det väl lite nja.
Man kan välja att "passa" en ingång tex vevaxelpulsingången så den aldrig missas. Man kan också passa en speciell händelse i processorn som gör en speciell sak vid ett exakt tillfälle, tex. starta en spridare via nu är det dags och sen går processorn vidare och gör det den skall och sen när spridaren skall stängas av då kallas en intern interrupt och allt annat städas undan och spridaren stängs av och sen går allt vidare igen. Men som jag fått ihop det nu så behövs nog inte interruptet... Här är ECU sketchen, jag tror det är den sista versionen?

Kod: Markera allt

 #include <PureAtmega328.h>
    
            // 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 = 16;         // totaltid för case 15/45: x * motorns duration (16)OBS: spridartröghetstid tillkommer!!
    const int grundvarde = 330;       // grundvärde ställs in här, högre tal = mindre tryck (330)
    const int lagstavarv = 520;       // tomgångsvarvet 580 uS motsvarar ca 800 Rpm (580)
    const byte hogstavarv = 130;      // fullgasvarvet 100 uS motsvarar ca 4200 RPM  (100)
    const byte aggrfaktorlag = 30;    // hur mycket spridar PWM skall öka vid belastning mellanvarv (30)
    const byte aggrfaktorhog = 150;   // hur mycket spridar PWM skall öka vid belastning högvarv (150)
    const int minfart = 3300;         // lägsta startvarv för spridarfunktion (3300 uS = 152 RPM)(3300)
    const byte startmangd = 9;        // avgör max startmängd 6 = 1 vevaxelpuls = 6 grader ontid (6)
    const float maxdeltalag = 9.0;    // max insprutningstid mellanvarv mdutation * 9.0 ger 4,5 vevaxelpulser = 26 gr ontid (9.0)
    const byte lagmangd = 4;          // max lågvarvsmängd 3 =  1,5 vevaxelpuls = 9 grader ontid (under tomgångsvarv)(3)
    const int tid1 = 2000;            // tid 1 är för att hitta pulsluckan vid start/lägsta varv(2000)                            
    const int tid2 = 1500;            // tid 2 är för att hitta pulsluckan vid lite under tomgång (1500)
    const int tid3 = 1000;            // tid 3 är för att hitta/behålla pulsluckan vid tomgångsvarv (1000)
    const int tid4 =  200;            // tid 4 är för att hitta pulsluckan vid alla andra varvtal (200)
    const int sprtroghet = 500;       // korrektion för den inbyggda påslagströgheten i spridarn (500)
    const byte turbostartregl = 150;  // när tubotrycket börjar avläsas och bli aktivt (150 = uS mduration ca 3200RPM)(150)
    const int sprdiff1 = 0;           // en ev tidigareläggning av spridare 1 om den avviker i startfördröjning
    const int sprdiff2 = 0;           // en ev tidigareläggning av spridare 2 om den avviker i startfördröjning
    const int sprdiff3 = 0;           // en ev tidigareläggning av spridare 3 om den avviker i startfördröjning
    const int sprdiff4 = 20;          // en ev tidigareläggning av spridare 4 om den avviker i startfördröjning
    
    float senasteinspr = 12.0;        // senaste insprutningstid (vid tomgång)(12.0)(8 till 14)ej constant
    byte tidigasteinspr = 27;         // kortaste insprutningsfördröjning (vid maxvarv)(27)ej constant
                                      
                                  
    int vevpin = 2;                   // pulsingång vevaxelgivare, 
    int kampin = 3;                   // kamaxelgivarens ingång,  
  //int logfart = 5;                  // till mikroswitch tomgång aktiv.
  //int hogfart = 6;                  // till mikroswitch fullgas aktiv.
    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).
    int turboAirTemp = 300;           // komprimerad turboluft temp
    int engineTemp = 700;             // motortemp.
    unsigned long delvalue;           // delvärde av pulstid i uS.
    unsigned int ondelay;             // tillslagsfördröjning spridare i uS.
    long puls,priv, delta;            // senaste, föregående och deltatid i uS,
    float error;                      // error = varvfelet i decimalform 
    float starttandfin;               // starttandfin i decimalform för att få startfördröjningstid.
    float  mduration, bduration;      // varvfelet = motorduration/börduration i decimalform
    byte tand = 0;                    // vevpin räknare 0 till 46 
    byte gas = 0;                     // gas 0-255
    int turbotryck = 700;             // turbotryck
    byte pekare;                      // pekare för att välja rätt spridarutgång (0 till 3)
    byte kamtand = 0;                 // Kamtand för att sluta detektera kamaxelgivaren efter några tänder
    int sprstartkorr = 50;             // spridarstartkorrigering i uS
    int variabel1;                    // bra att ha variabel 1
    int variabel2;                    // bra att ha variabel 2
    int fasttid = 300;                // Fasttid = tid1,tid2,tid3 eller tid4 beroende på varvtal, startar alltid på 200 uS
    int battVolt = 700;               // mäter systemspänning till spridare
    int atmtryck = 300;               // mäter atmosförstrycket
    int ambTemp =300;                 // mäter omgivningstemperaturen
    int sprtroghetklar;               // det klara spridartröghetsvärdet
    int spridardiff;                  // en individuell spridartidskorrigering
    


void setup()
{
   pinAsInputPullUp(vevpin);         // satt vevpin som ingång (2)                         
   pinAsInput(kampin);               // satt kampin som ingång (3)
   pinAsOutput(sprpins[pekare]);     // spridarutgångar satta som arrey (11,10,9,8)
   pinAsOutput(sprControl);          // en spridarutgång som blir hög varje gång en spridare öppnas (13)
   pinAsInputPullUp (disable);       // ECU väljare Hög = on, Låg = off (12)
   pinAsOutput(pulsutpin);           // satt pulsutpin som utgång (2 pulser per varv)(7)
 //pinAsInputPullUp(logfart);        // lågfart-switch aktivt låg = on (5)
 //pinAsInputPullUp(hogfart);        // högfart-switch aktivt låg = on (6)
   Serial.begin(250000);             // bra att ha, behöver aldrig tas bort
}

void loop() 
{
   if (digitalRead(disable)==LOW)   //Disable låg stänger av ECU:n och gör den passiv
      {  
      delta = 0;                    //Genom att pulstiderna förblir 0.
      pinAsInput(sprpins[pekare]);  //Gör om spridarutgångarna till ingångar för att ej belasta
      pinAsInput(sprControl);       //Gör om spridarcontrollen till ingång för att ej belasta
      }
      
     else 
      {
      pinAsOutput(sprpins[pekare]); //Vid aktiv igen så gäller spridarutgångarna som utgångar igen.
      pinAsOutput(sprControl);      //Vid aktiv så gäller spridarcontrollen som utgång igen
      }                             //*Detta är normalläget, samma som i setup*
        
    //------------------------------------------------------ 
        
      if (kamtand <= 250)            // när tand 251 är räknad 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.
         }
       }
  //--------------------------------------------------------------------
       
   switch (tand)
  {

   case 16:
          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)
         // engineTemp = analogRead(A1);        // 0 till 512 0,1 Volt/10 grad använder LM-35 tempgivare 
          variabel2 = analogRead(A2)>>3;        // skall vara turboAirTemp, 
   break;

   case 46:
         // ambTemp = analogRead(A3);
        //  battVolt = analogRead(A5);
         // atmtryck = analogRead(A6);          // analogingång för lufttrycket max 255
          variabel1 = analogRead(A1)>>5;        // A7!!
   break;

   case 32:
         delvalue = priv + delvalue;            // föregående pulstid + föregående deltid läggs ihop 
         senasteinspr = map(variabel1, 0, 32,8.0,14.0);
   break;

   case 33:
          delvalue = priv + delvalue;            // föregående pulstid + föregående deltid läggs ihop 
      tidigasteinspr = map(variabel2,0,128, 18,31);
      
                                                     
   break;


   case 10:
          starttandfin = mduration /tidigasteinspr;// insprutningsfördröjning i gånger, ställs högst upp
          // starttandf, ett flyttal = motorns duration/ x som är minsta duration/max RPM. ställs högst upp
          if (starttandfin >= senasteinspr)         // om över målvärdet (som ställs in högst upp)
           {                  
            starttandfin = senasteinspr;            // blir det målvärdet ändå
           }
   break;

   case 11:
          ondelay = mduration * starttandfin;// tillslagsfördröjning = motorns duration * starttandsfördröjning (decimaltal)       
   break;                                    //       Ondelay     uS = mduration     uS * starttandf i decimalform 
    

   case 12:
            delvalue = priv + delvalue;                 // föregående pulstid + föregående deltid läggs ihop
       if (mduration >=151)                             // "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 <= 150)                          // "högvarv"
          {
           delta = mduration * error * aggrfaktorhog;   // Felkorrigeringsvärde som ger spridaröppningstid i uS 
          }                               
   break;
                  
   case 13:
          if (mduration <= turbostartregl)        // här bestämms varvtalet när turbon skall börja regleras ner 
           {                                      // via kortare spridartider, ställs högst upp
            delta = delta - turbotryck + grundvarde - atmtryck + ambTemp - turboAirTemp;// korrigering för måltryck genom att minska öppningstiden i uS
         // 1500  =  1500  -     0     +   330      -    330   +   300   -    300 full gas ingen turboladdning
         // 1200  =  1500  -    200    +   330      -    330   +   300   -    400 full gas, turbon laddar, ttemp stiger
         // 1190  =  1500  -    200    +   330      -    280   +   290   -    450 f. g, t. laddar, ttemp stiger, utetryck/temp sjunker 
         //  940  =  1000  -    100    +   330      -    280   +   290   -    300 marcheffekt på höjd en dag...
            if (delta <=0)
             {
              delta = 0;                          // för att undvika minusvärden
             }
           }
          if (mduration >= 700)                   // för att få mjukstart vid motorstart.
           {
            delta = lagmangd * mduration;         // mjukstarten justeras via lågmängd högst upp              
           }
          if (delta + ondelay >= totaltid * mduration)
           {
            delta = (totaltid * mduration)-ondelay;// Absolut max insprutningstid, ställs högst upp
           }                                
   break;
  
   case 14:
           if(mduration >= minfart)   // motorn måste upp i x varv för att få bränsle, ställs högst upp
            {
             delta = 0;
            }         // x =  fast tid  + spridardiff per spridare, fyra val - spridarstartkorr beroende på battspänningen
            sprtroghetklar = sprtroghet + spridardiff - sprstartkorr;
    
   break;    

   case 34:
          delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
          bduration =map(gas,5, 252, lagstavarv, hogstavarv); // Ger motorns börvarvtal
   break;

   
   case 0:
         delvalue = priv;            // Första  föregående pulstid läggs in som deltid 1
   break;

   case 1:
         delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop 
   break;

   case 2:
         delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop 
   break;

   case 3:
         delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
   break;

   case 4:
         delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
   break;     
   

   case 5:
         delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
   break;

   case 6:
         delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
   break;

   case 7:
         delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
   break;

   case 8:
         delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
   break;

   case 30:
         delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
   break;

   case 35:
         delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
   break;

   case 36:
         delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
   break;

   case 37:
         delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
   break;

   case 38:
         delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
   break;
          
   case 39:
         delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop                  
   break;

   case 40:
         delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop
   break;

   case 42:
         delvalue = priv + delvalue; // föregående pulstid + föregående deltid läggs ihop        
   break;                              

   case 41:
         delvalue = priv + delvalue;                    // föregående pulstid + föregående deltid läggs ihop
       if (mduration >=151)                             // "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 <= 150)                          // "högvarv"
          {
           delta = mduration * error * aggrfaktorhog;   // Felkorrigeringsvärde som ger spridaröppningstid i uS 
          }                               
   break;
  
   case 43:
          delvalue = priv + delvalue;            // föregående pulstid + föregående deltid läggs ihop
    if (mduration <= turbostartregl)             // här bestämms varvtalet när turbon skall börja regleras ner 
           {                                     // via kortare spridartider, ställs högst upp
            delta = delta - turbotryck + grundvarde - atmtryck + ambTemp - turboAirTemp;                       // korrigering för måltryck genom att minska öppningstiden i uS
            if (delta <=0)
             {
              delta = 0;                          // för att undvika minusvärden
             }
           }
          if (mduration >= 700)                   // för att få mjukstart vid motorstart.
           {
            delta = lagmangd * mduration;         // mjukstarten justeras via lågmängd högst upp              
           }
          if (delta + ondelay >= totaltid * mduration)
           {
            delta = (totaltid * mduration)-ondelay;// Absolut max insprutningstid, ställs högst upp
           }                                
   break;

   case 44:
          mduration = delvalue/26;   // motorns totala pulstid i mikrosek dividerat med 26
          if(mduration >= minfart)   // motorn måste upp i x varv för att få bränsle, ställs högst upp
           {
            delta = 0;
           }
          sprtroghetklar = sprtroghet + spridardiff - sprstartkorr; // spridartröghet klart värde räknas ut här
    
  break;

  case 9:
          error = (mduration / bduration)-1;       // räknar ut skillnaden mellan är och börvärde - 1 = error
         if (error <=0.)                           // om error under noll
          {
           error = 0.;                             // för att ej få minusvärden
          }
  break;
    
  case 15:
           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.
            if ((delta*2) >= startmangd)           // här ställs startmängden in (högst upp) 
             {
              delta = startmangd;                  // så det blir rätt startmängd/slag
             }
             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.
             ondelay = ondelay *1000;
             delta = delta * 1000;
           }                                      // Detta paket används vid låga farter såsom start/lågvarv
     
        else                                      // Eller om delay är mindre än 14000 uS. (> 250 RPM)
           {
            ondelay = ondelay - sprtroghetklar;   // spridaren tidigareläggs x uS pga dess starttröghet
            if (delta > 30)                       // Delta under 30 uS har inget värde
             {
             delta = delta + sprtroghetklar;      // Delta över 30 blir x delta + trögheten i spridaren (ca 450 uS)
             }
            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 8,9,10 eller 11]. 
            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 delta uS
            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.
            ondelay = ondelay + sprtroghetklar;   // Ondelay görs ursprunglig igen innan urgång
            delta = delta - sprtroghetklar;       // Delta görs ursprunglig igen innan urgång
           }                        
   break;

   case 45:
           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.
           if ((delta *2) >= startmangd)          // här ställs startmängden in (högst upp) 
            {
             delta = startmangd;                  // så det blir rätt startmängd/slag
            }
            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.
            ondelay = ondelay * 1000;             // Ondelay mS blir uS igen innan urgång.
            delta = delta * 1000;                 // Delta mS blir uS igen innan urgång
          }                            //Detta paket används vid låga farter såsom start/lågvarv
     
        else                                      // Eller om delay är mindre än 10000 uS. (> 300 RPM)
          {
          ondelay = ondelay - sprtroghetklar;     // spridaren tidigareläggs x uS pga dess starttröghet
          if (delta > 30)                         // Delta under 30 uS har inget värde
           {
            delta = delta + sprtroghetklar;       // Delta över 30 blir x delta + trögheten i spridaren (ca 450 uS)
           }
            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 8,9,10 eller 11]. 
            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 delta uS
            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.
            ondelay = ondelay + sprtroghetklar;   // Ondelay görs ursprunglig igen innan urgång
            delta = delta - sprtroghetklar;       // Delta görs ursprunglig igen innan urgång
          } 
   break;

    case 31:
       /*    if (gas < 2 || gas > 253)    // om gaspotentiometern går sönder...
            {
            if (digitalRead(logfart) == LOW && digitalRead(hogfart) == HIGH)
             {
              gas = lageffekt; // om tomgångsbrytaren är aktiverad (låg) blir det gas=tomgång
             }
          if (digitalRead(logfart) == HIGH && digitalRead(hogfart) == HIGH)
           {
            gas = marcheffekt; // om ingen brytare är aktiverad (hög hög) blir det gas=marcheffekt 
           }
          if (digitalRead(logfart) == HIGH && digitalRead(hogfart) == LOW)
           {
           gas = fulleffekt; // om fullgasbrytaren är aktiverad (låg) blir det gas=fulleffekt
           }
       }
 */  break;
  
  }
 //  ----------------------------------------------------------
     
     tand  ++ ;                  //räkna upp ett steg för varje ny tand, kommer via pulseIn()funkt.

     priv = puls;                         // lägger in den förra pulstiden i värdet "priv" (uS)

      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 tid4 (300 uS i grundinställning)
        }
        
        
        puls = pulseIn(vevpin, LOW, 30000);      // Ett färdigt kommando som väntar in nästa puls (tand).
                                                 // vid stillastående motor blir det en timeout 
                                                 // efter 30000 uS vilket motsvarar < 30 RPM.
                       
     if  (puls > priv + fasttid)                // jämför om ny pulstid i uS är större än föregående + 300 uS.
      {
        digitalWrite (pulsutpin, HIGH);          // utpin blir hög när pulsluckan återgår till pulser

          if (tand <27)
           {
            tand = 30;
            pekare = pekare + 1;                 // 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
              }
           }
         
          if (tand >40)
           {
            tand = 0;
            pekare = pekare + 1;                 // 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
              }
            }
       
     
       if (pekare == 0)
        {
         spridardiff = sprdiff4;                
        }

       if (pekare == 1)
        {
         spridardiff = sprdiff2;
        }

       if (pekare == 2)
        {
         spridardiff = sprdiff1;
        }

       if (pekare == 3)
        {
         spridardiff = sprdiff3;
        }
     

      // Serial.println(spridardiff);
      }
       if  (puls < priv - fasttid)               // jämför on ny pulstid är mindre än förgående - 300 uS.     
         {   
         digitalWrite (pulsutpin, LOW);          // utpin blir låg igen nästa uppgång i pulståget.
         } 
}  
Om det är någon som orkar läsa in sig på coden ovan så kan jag kanske svara på frågor sen och kanske försvara varför det är på ett visst sätt och om det är någon som vill/orkar ändra något till det bättre så är jag tacksam.
Edit: ja nu tillkom Hawkan som jag inte läst riktigt än.
Janson1
Inlägg: 1338
Blev medlem: 1 december 2016, 09:06:02
Ort: Marks Kommun

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Janson1 »

Hawkan: Det är väl inte speciellt krångligt att sätta upp en interrupt, det krångliga är vad den skall göra och vad jag skall plantera den någonstans och sist men inte minst: nyttan...
Nu finns ju mitt alster för allmän beskådan, bara att kolla in!
Användarvisningsbild
KLset
Inlägg: 207
Blev medlem: 31 augusti 2014, 17:36:19
Ort: Uppsala

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av KLset »

Har skummat lite igenom koden och har en fråga: Vad är det variabeln tand representerar? Jag förstår att den räknar från 0-46 och så om igen och, att timingen på insprutningen beror i huvudsak på denna. Det är någon sensor förstår jag.
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 »

Jag har bara skummat igenom koden....
Men du har alltså inte vevaxelgivaren på interrupt och ändå fått detta att funka.
Det är lite imponerande faktiskt.
För att implementera interrupt på vevaxelgivaren så kommer du tycka att det är ganska snurrigt tills du får till det, men när du väl har implementerat det så vill jag ändå påstå att resterande program kommer att bli mycket lättare att sätta upp.
Användarvisningsbild
hawkan
Inlägg: 2586
Blev medlem: 14 augusti 2011, 10:27:40

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av hawkan »

Otroligt bra kommenterad kod :)
Om jag förstår koden rätt så händer det mesta i sekvens och timing styrs av "tand" och av delayer för några "tand".
Tycker nog att approachen du har är helt okej. Använda interrupt undrar jag om det underlättar speciellt eftersom saker sker i sekvens och det finns möjlighet att ligga och polla en pinne för att se om det händer saker utan att andra saker behöver göras.
Keep going!
Användarvisningsbild
ViktorSigg
Inlägg: 376
Blev medlem: 11 januari 2015, 17:33:50
Ort: Eskilstuna-Ludvika

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av ViktorSigg »

MOSFET för 3.3 volt brukar ha ett L i namnet om jag minns rätt. Någon mer får gärna stämma in om så är fallet!
Användarvisningsbild
hawkan
Inlägg: 2586
Blev medlem: 14 augusti 2011, 10:27:40

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av hawkan »

Vet inte svaret på det, men min favorit är IRLML6244 N-MOSFET och den har två L i namnet :) Drivs direkt av 3.3V, 5-6A.
Användarvisningsbild
KLset
Inlägg: 207
Blev medlem: 31 augusti 2014, 17:36:19
Ort: Uppsala

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av KLset »

Efter vad Bosen skrev och en till titt på variablerna förstår jag nu att variabeln tand är vevaxelns läge. Får ta och hålla med hawkan i att koden är välkommenterad! Får jag föreslå att placera de olika case:n i ordning? Då tycker jag det skulle bli lättare att visualisera processen allt eftersom man läser koden i ordning, uppifrån och nedåt.

Edit: Varför just 47 olika tillstånd på vevaxeln? Blev lite nyfiken...
Janson1
Inlägg: 1338
Blev medlem: 1 december 2016, 09:06:02
Ort: Marks Kommun

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Janson1 »

3-4 Amp räcker inte, den jag har i dag är nog på nästan 30 Amp när det gäller MOS-transistorer. Som ni nog har listat ut så representerar varje case en tand på vevaxeln. Själva kugghjulet som sitter på vevaxeln och givaren detekterar har 28 tänder, 2 luckor, 28 tänder, 2 luckor per varv osv. Och jag har låtit varje tand (case) representera en händelse eller tre och sen när händelsen är slut så går den ur case´t och väntar snällt på nästa Puls från vevaxeln. Jag hade case´n i ordning från början men det blev så mycket bläddrande innan jag hittade rätt så nu har jag lagt dom case som måste ändras hela tiden först och dom som egentligen inte behöver nån handpåläggning alls, ja dom ligger sist. Sen blir det förprocessorns huvudvärk att lägga case`n rätt igen. Tandantalet är ju 28 plus 28 plus luckorna vilket blir 56 tillstånd plus 2 lucktillstånd.
Processorn behöver hålla reda på alla tänderna tills insprutningstanden kommer, tand 15 eller 45. Sen går processorn på död räkning tills det är dags att stänga av spridaren/spridarna. När den sen går ur case 15/45 så är man x antal tänder senare beroende på varvtal och belastning, detta är egentligen oväsentligt så länge det finns tid kvar för analogread av 4 värden och en sista tand för att inte tappa räkningen. 47 olika tillstånd är det nog inte men första halvvarvet består av 0 till 15 säkra tänder och sen hoppar den över x antal tänder för att ge nästa tand nr 16, rätt som det är tänderna slut och luckan dyker upp, dags att reseta eller gå till tand 30 (case 30) och göra om allt i hopa.
Hoppas detta är förståeligt...
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 »

Hur vet man om man är på första eller andra halvan av vevaxelvarvet? Då tänderna har 28+2+28+2 så finns det ju ingen indikation vilket som är 0:an?

Jag har bara skummat igenom tråden så jag har inte riktigt koll på hur du styr motorn, men det sättet jag själv hade försökt med är vevaxelgivaren på interrupt och i ISR:en skulle jag räkna tiden från förra ISR. på så sätt kan jag hitta luckan och sedan räkna varje tand från det. När jag har kommit upp till tand 15 så startas insprutningen på samma sätt som du gör nu. Eventuellt måste man då stänga av interruptet under insprutningstiden.
Jag tycker det är väldigt många case som gör samma sak. Genom att göra den beräkningen i ISR så skulle du slippa många case känns det som.
Janson1
Inlägg: 1338
Blev medlem: 1 december 2016, 09:06:02
Ort: Marks Kommun

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Janson1 »

Vevaxelgivaren triggas in av kamaxelgivaren sen behövs inte den mera... Jag har försökt ta bort "dubblett" case men då blir det fel senare. Det finns säkert nåt bättre/smartare sätt att programmera på... Om man måste ta bort interupet under insprutningstiden, då försvinner väl hela interruptgrejen? Det är väl där man skulle ha det istället för död räkning.
Skriv svar