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 gick i valet/kvalet om ag skulle byta olja i växellådan/bakaxeln. I förra veckan bestämde jag mig och hällde ur den och jösses vad vatten och skit det kom ut... Jag misstänkte att hydraulen inte funkade så jag passade på att ta ner pumpenheten när ändå oljan var avtappad. Pump och ventilpaket är sammanbyggt, själva pumpen drivs av kraftuttagsaxeln och ventilen styrs dels av höj/sänkreglaget och dels av ett automatiskt tryckstångsreglerat system som hjälper föraren vid tex plöjning att hålla exakt djup. I dag tog jag isär hela pump-paketet och gjorde rent och fixade, den behöver en ny reglerventil så den är beställd (148 kr + moms), annars var allt i hyfsat skick. En grej, jag hittade en kugge i den bakersta oljepluggen (under bakaxeln), det såg ut som den legat där åtskilliga år men den är alldeles för liten för att komma från bakaxeln, växellådan har mer den storleken på dreven men kunde inte se nåt drev som haltade eller lät konstigt. Detta kan ju vara en rest från en reparation för länge sedan? Bilder finns men jag kan inte vända dom rätt så allt blir fel.
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 har fått hem reservdelen till hydraulen och fått ihop det, hällt på 20 liter olja. I går gjorde jag en gaspot, se bild
20181101_102119.jpg
Jag har även hunnit få till den på traktorn och fått dit elektroniken i en gammal väska av nån polymerplast som verkar passa ganska väl. Jag är inte riktigt nöjd men hittar inget bättre just nu...
20181029_213500.jpg
Efter detta så är grejerna monterade och ett elsystem börjar växa fram.

edit, det har kommit med en PDF-fil av misstag som jag inte kan ta bort för jag kan inte se den i "ändra" men det är bara ett kalibreringsprotokoll... nu kanske borta?
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
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 »

Detta har hänt sedan sist. Jag har nu fått igång traktorn men dubbelmassasvänghjulet gör (förutom svårstartad) att traktorn småhoppar fram på back, 1: och 2:an så jag har beslutat mig för att antingen steloperera eller byta till ett massivt hjul. Nu är traktorn delad på igen för bla helsvetsning och målning. Min tandgivare har ju 28_2_28_2 drev osv men dom nya tandgivarna har 60_2 drev per varv istället och jag har fått tag på en sådan platta/givare så jag kommer att montera denna bakom svänghjulet parallellt med den gamla och när jag är nöjd med min från början programmering så kommer jag nog att göra ett nytt program för den nya givaren...
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 »

Det "nya" tandgivaren/drevet kom hem i dag men jag måste bygga om motorblocket för att få det att passa så jag väntar till nästa tillfälle. Nu i dag så blev svänghjulet steloperarat med svetsen och traktorn ihopsatt igen i ett stycke ståendes på egna hjul. I morgon (om jag hinner) skall jag försöka få till resten, typ bränsletank, kyl, div elkopplingar sen göra ett startförsök...
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 »

Traktorn hopmonterad och provkörd. Som SEF:are så läser jag även andra inlägg mm. Och ang Arduino så kan man läsa både plus och minus om både hårdvaran och mjukvaran, mest minus på mjukvaran faktiskt... Det jag funderar på är om den är tillräckligt "tidsföljande" dvs. tar samma sak alltid samma tid eller har den nåt fuffens för sig då och då? Anledningen till att jag undrar är för att motorn går periodvis bra men andra perioder så går den dåligt, kan helt plötsligt börja ryka svart vid gaspådrag (tyder på för långa spridartider) och gå väldigt illa, det kan ta ett par sekunder för motorn att hämta sig efter detta. Jag har helt enkelt svårt för att avgöra om det är hårdvaran (motorns insprutningssystem) eller mjukvaran i Arduinon. Jag har kört denna sketch ganska länge på kammaren i dom flesta enskilda varvtal, enskilda "belastningar" (pulsbredder) fram och tillbaka och jag kan inte finna nåt anmärkningsvärt gitter/störningar/fel pulsbredd på nån spridare vid enstaka tillfällen eller dylikt. Kort sagt så gör den det den ska, dvs det som jag programmerat den till. Sen så kommer det alltid "fenomen" lite då och då som beror på av mig felprogrammering/dålig programmering. (jag är komplett nybörjare) Ang gitter vilket jag tolkar som lite labil i tiderna som det tar att göra en viss sak har jag blivit varnad för förut på denna tråd, att det skulle skilja så mycket som +-40 grader på vevaxeln... Jag har lagt in "tidsmarkörer" som ger en uS -tid varje varv som jag sen har kört väldigt länge vid olika tillfällen och sen kollat tillbaka på utskrifterna (serialmonitorn) Vissa saker tar tex 12-15 uS per varv varje gång, jag kan se nån antydan till uppåt 20 uS nån enstaka gång. ( totalt under 10 uS fel mellan varje gång) Men min motor börjar förmodligen klaga när tiderna övergår 50 till 80 uS fel och det har jag aldrig mätt upp totalt tidsfel till någon gång. Så min fråga till er: Kan jag fortsätta att programmera i Arduinokod? Jag hoppas på ett ja då det är en ganska stort steg till nästa. Men måste man så måste man...
Användarvisningsbild
Klas-Kenny
Inlägg: 11291
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av Klas-Kenny »

Jag tror absolut att det hela är fullt lösbart i Arduino-kod.

Men, nu har jag inte kollat i din kod på länge, men förut har du ju inte kört någonting interrupt-drivet. Där tror jag att man har mycket att tjäna, på att skriva om de tidskritiska delarna i programmet.
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 »

Senaste koden...

Kod: Markera allt

    // Förändrad 2018-11-16 och  inlaggd  11/17, 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. Fungerar
    // ändrad i gasen så 5 volt är tomgång och 0 volt fullfart Fungerar
    // ändrad till att bara läsa av tand 9. Skall provas
    // ändrad till max 2500 rpm om varvpin sätts låg. Skall provas
    
            // 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)
    byte hogstavarv = 100;            // 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)3800 nu
    const byte startmangd = 9;        // avgör max startmäng 9 = 1,5 vevaxelpulser = 9 grader ontid (9)
    const float maxdeltalag = 9.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 = 0;     //20  // en ev tidigareläggning av spridare 4 om den avviker i startfördröjning (uS)                                 
    const byte maxstopp = 60;         // en varvtalsbegränsare som + på högstavarv (microsek)
    const int tandlasning = 3000;      // vid vilken tid på puls som läsning skall ändras mellan 1 tand = start och = /12 vid drift
   
    int vevpin = 2;                   // pulsingång vevaxelgivare, (aktivt hög).
    int kampin = 3;                   // kamaxelgivarens ingång, (aktivt låg).
    int varvpin = 4;                  // en varvbegränsningspinne  
    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)
    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;                  // 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)
   pinMode(varvpin, INPUT_PULLUP);    // satt varvpin som ingång (4) varvtalsbegränsare
   //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(digitalRead(varvpin)==LOW)  // om varvpin är låg 
      {
        hogstavarv = hogstavarv + maxstopp; // så blir maxvarv tex 2500 Rpm
      }

     else
     {
      // maxvarv blir 4200 Rpm
     }
             
 
        
      if (kamtand <= 256)              // 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,150,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,255, 0, lagstavarv, hogstavarv); // ställs in högst upp
           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 eller bara tand 8
          if (priv <= tandlasning)    // Här väljs om man skall räkna på en tand vid start eller alla räknetänder/12
          {
           mduration = delvalue/12;   // Motorns totala pulstid i mikrosek dividerat med 12 ger motorns duration vid drift
          }

          else
          {
           mduration = priv;         // motorns pulstid i case 8 vid start får gälla för hela halvvarvet.
          }
     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:           // 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.

                       // 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) 
        {                         
         delta = 0;               // och delta(insprutningstid)resetas
        }
                // och startmängden vid motorstart
       if ((delta * 4)>= 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-500 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);                              
        break;
        
        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 (3800 > 3800 + 2500) blir 3800 > 6300 FALSKT                                     (-2500)
     // if (11400 > 3800 + 2500) blir 11400 > 6300 SANT luckan funnen!                      (+5100)
     // if (3800 > 11400 + 2500) blir 3800 > 13900 FALSK                                    (-10100)                                 
     // if (2000 > 2000 + 2500) blir 2000 > 4500 FALSKT  Detta är dom 28 vanligaste lägen   (-2500)                                   
     // if (10000 > 2000 + 2500 ) blir 10000 > 4500 SANT Luckan funnen, då det är lång tid till nästa tand (efter luckan)
     // if (2000 > 10000 + 2500)  blir  2000 > 12500 FALSKT  Nu är det vanlig tid igen, första tanden börjar om räkningen        
      if  (puls > priv + fasttid)             // jämför om ny pulstid i uS är större än föregående + fasttid.
       {
        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 (ben D11)
  {
    spridardiff = sprdiff4;                  // skall det individuella värdet för spridare 4 hämtas
  }

  if (pekare == 1)                           // om spridarpekaren pekar på 1 (ben D10)
  {
    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;                  // ben D9
  }

  if (pekare == 3)
  {
    spridardiff = sprdiff3;                 // ben D8
  }
     // if (3800 < 3800 - 2500)  blir 3800 < 1300 FALSKT   (2500)
     // if (11400 < 3800 - 2500) blir 11400 < 1300 FALSKT  (10100)
     // if (3800 < 11400 - 2500) blir 3800 < 8900 SANT     (5100)
      
     // if (2000 < 2000 - 2500) blir 2000 < -500 FALSKT  Detta är dom 28 vanligaste lägen 
     // if (10000 < 2000 - 2500 ) blir 10000 < -500 FALSKT
     // if (2000 < 10000 - 2500)  blir  2000 < 7500 SANT  
       if  (puls < priv - fasttid)            // jämför on ny pulstid är mindre än förgående - fasttid.     
         {   
         digitalWrite (pulsutpin, LOW);       // utpin blir låg igen nästa uppgång i pulståget.
         } 
 }        
        
                                              // end void loop()
 
Jag har ju som sagt kört denna kod ganska länge under dom mesta kombinationer av fart och effekt. Jag kan inte se att den gör nåt konstigt... Men det är klart en motor lämnar inte ut en statisk signal, den vandrar både per varv och framförallt inom varvet. Men jag kan se att dels uppfattar programmet förändringarna och dels justerar den efter det.
Så frågan lite kvarstår om vilket...
Jag har tillfälligt gjort om programmet på en liten snutt så jag kan tidigarelägga spridarnas tillslagstid och duration per spridare med 4 potar, en för varje spridare men jag tycker mig inte märka att den går bättre vid något enskilt tillfälle. ja, här är filen för det också:

Kod: Markera allt

    // Förändrad 2018-11-17 och inlagd 11/17, 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. 
    // ändrad i gasen så 5 volt är tomgång och 0 volt fullfart
    // hitat fel i analogRead glömt break, skiftat fel på gas i case 2: >>3 istället för >>2
    
            // 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 = 10;         // 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)
    byte hogstavarv = 100;            // 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)skall vara på 3800
    const byte startmangd = 11;        // avgör max startmäng 9 = 1,5 vevaxelpulser = 9 grader ontid (9)
    const float maxdeltalag = 7.0;    // max insprutningstid mellanvarv mdutation * 6.0 ger 3 vevaxelpulser = 18 gr ontid (9.0)
    const byte lagmangd = 11;          // 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.                           
     int sprdiff1 = 0;           // en ev tidigareläggning av spridare 1 om den avviker i startfördröjning (uS)
     int sprdiff2 = 0;           // en ev tidigareläggning av spridare 2 om den avviker i startfördröjning (uS)
     int sprdiff3 = 0;           // en ev tidigareläggning av spridare 3 om den avviker i startfördröjning (uS)
     int sprdiff4 = 0;     //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 varvpin = 4;                  // en varvbegränsningspinne  
    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)
    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;                  // 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)
   pinMode(varvpin, INPUT_PULLUP);    // satt varvpin som ingång (4) varvtalsbegränsare
   //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(digitalRead(varvpin)==LOW)  // om varvpin är låg 
      {
        hogstavarv = hogstavarv + 60; // så blir maxvarv 2500 Rpm
      }

     else
     {
      // maxvarv blir 4200 Rpm
     }
             
 
        
      if (kamtand <= 256)              // 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,150,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,255, 0, 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
     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
               //       400      + (0 till 50) - (0 till 400)
     break;    //       400      +     0       -      50
      
                     
    
     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 >=8000)                     // 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.

                      //   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) 
        {                         
         delta = 0;               // delta(insprutningstid)blir 0 vid för lågt varv
        }
                     // och startmängden vid motorstart
       if ((delta * 4)>= 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);
            sprdiff4 = analogRead(A4)>>3;
            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)
            sprdiff1 = analogRead(A1)>>3;
            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);                              
            break;
            
            case 3:
            //variabel2 = analogRead(A2)>>3;        // (turboAirTemp) skall vara turboAirTemp,
            sprdiff2 = analogRead(A2)>>3;
            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);
            sprdiff3 = analogRead(A3)>>3;
            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

   /*  case 18:
     Serial.print("cyl1  ");
     Serial.println(sprdiff1);
     Serial.print("cyl2  ");
     Serial.println(sprdiff2);
     Serial.print("cyl3  ");
     Serial.println(sprdiff3);
     Serial.print("cyl4  ");
     Serial.println(sprdiff4);
     break; 
   */     
  }
     //______________________________________________________________________________________________________   
        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 (3800 > 3800 + 2500) blir 3800 > 6300 FALSKT                                     (-2500)
     // if (11400 > 3800 + 2500) blir 11400 > 6300 SANT luckan funnen!                      (+5100)
     // if (3800 > 11400 + 2500) blir 3800 > 13900 FALSK                                    (-10100)                                 
     // if (2000 > 2000 + 2500) blir 2000 > 4500 FALSKT  Detta är dom 28 vanligaste lägen   (-2500)                                   
     // if (10000 > 2000 + 2500 ) blir 10000 > 4500 SANT Luckan funnen, då det är lång tid till nästa tand (efter luckan)
     // if (2000 > 10000 + 2500)  blir  2000 > 12500 FALSKT  Nu är det vanlig tid igen, första tanden börjar om räkningen        
      if  (puls > priv + fasttid)             // jämför om ny pulstid i uS är större än föregående + fasttid.
  {
   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 (ben D11)
  {
    spridardiff = sprdiff4;                  // skall det individuella värdet för spridare 4 hämtas
  }

  if (pekare == 1)                           // om spridarpekaren pekar på 1 (ben D10)
  {
    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;                  // ben D9
  }

  if (pekare == 3)
  {
    spridardiff = sprdiff3;                 // ben D8
  }
     // if (3800 < 3800 - 2500)  blir 3800 < 1300 FALSKT   (2500)
     // if (11400 < 3800 - 2500) blir 11400 < 1300 FALSKT  (10100)
     // if (3800 < 11400 - 2500) blir 3800 < 8900 SANT     (5100)
      
     // if (2000 < 2000 - 2500) blir 2000 < -500 FALSKT  Detta är dom 28 vanligaste lägen 
     // if (10000 < 2000 - 2500 ) blir 10000 < -500 FALSKT
     // if (2000 < 10000 - 2500)  blir  2000 < 7500 SANT  
       if  (puls < priv - fasttid)            // jämför on ny pulstid är mindre än förgående - fasttid.     
         {   
         digitalWrite (pulsutpin, LOW);       // utpin blir låg igen nästa uppgång i pulståget.
         } 
 }        
        
                                              // end void loop()
 
Ingen större skillnad... men dom analoga här är spridarjusteringar istället för div temperaturer mm.
Och sen kan jag aktivera Serialen och få ut värdena per spridare för att sen lägga in dom i konstanterna. (sprdiff1-3)
Användarvisningsbild
mrfrenzy
Co Admin
Inlägg: 14818
Blev medlem: 16 april 2006, 17:04:10

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av mrfrenzy »

Det spelar ingen roll om du använder Arduino, STM32 eller Infineon, det måste till interupptbaserad timing för att få det hela pålitligt med denna tidskritiska applikation.
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 »

To dä? Ok, jag har en logikanalysator för 8 kanaler som skall först, ja först få liv i den och sen spela in lite och gå tillbaka. Blev det rätt eller fel? Om det visar sig att det är tidsfel, då får jag tänka om!
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 »

Alltså, jag har funderat fram och tillbaka på detta med interrupt och kommer fram till så som jag har programmerat idag så blir det aldrig tillfälle för interruptet att verka. Den gör en eller flera uträkningar per tand, jag får det till några få uS oavsett (förutom analogaRead som jag därför lagt i slutet där det kvittar vilket) om den räknar en eller flera grejer. Själva Serial.printen som jag använder för att se looptiden tar betydligt mer tid i anspråk än det processorn skall räkna ut per tand. Den kortaste tiden är lite under 100 uS som processorn har till förfogande per tand och samtliga uträkningar tar under 20 uS att utföra. Så om inte Arduino har nått fuffens för sig så är det "gott om tid" När uträkningarna per tand är gjort går den till pulseIn och väntar, mellan 75 uS (lite övervarv) och 480 uS beroende på varvtalet. När den sen kommer till tand 16 (insprutningsfasen) så får den tanden ta väldigt lång tid på sig att bli klar, jag har begränsat till tand 24 som längst vilket motsvarar 12 grader EÖDP. Sen nästa tand, processorn tror det är tand 17 men i verkligheten är det 17 till 24 och där ligger alla analogRead parvis, en tar lite mer än 100 uS och två tar ca 160 uS . När tand 17 (17-24) är klar går processorn ut och gör inte mer förrän sista tanden är lämnad och tandgapet kommer, då resetar den 28 räknaren och börjar på ny kula.
Om jag skall använda interrupt så måste jag nog göra på ett helt annat sätt. Jag var lite inne på att använda Micros() och göra olika markörer på en tidslinje som sen används för att starta, stoppa insprutningen med och låta vevaxelgivaren vara interruptstyrd och följa vevaxelpulserna även vid insprutning och låta analogRead köra när tid finnes.
Användarvisningsbild
mrfrenzy
Co Admin
Inlägg: 14818
Blev medlem: 16 april 2006, 17:04:10

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av mrfrenzy »

Bäst skulle nog vara som du säger att börja om och göra på ett helt annat sätt men man behöver ju inte det.
Man kan börja med att göra ett nytt program som bara läser av vevgivare och kamgivare via interruptrutiner samt matar ut aktuell position på serieporten.

När det fungerar och är bombsäkert kan man kopiera in koden i ditt gamla program och behålla allt utom dom delarna som mäter position.
Har du laddat upp koden för din simulator nånstans ifall man vill prova hemma?

För ganska exakt ett år sen skrev basshead några inlägg på sidan 2 i denna tråd, det är så läsvärt så jag tar mig friheten att citera valda delar:
basshead skrev:Själva svajet dvs jittret kommer just ifrån ... main loop. Kallas ibland för sekventiell exekvering.
...
Men när man kliver in och skall styra tidskritiska saker, tex köra en motor så räcker det inte till längre.
En motor på tomgång är inte så störd av lite fördröjningar. Inte heller på högre varv utan last.
Men den dagen du lägger last på motor och koden sitter och sover när det behövs bränsle då blir inte motorn gammal.
...
Så till interrupt. På Arduino har dom gjort det görenkelt att använda interrupt. Man ansluter en bit kod till en händelse. Tex öka en räknare varje gång man passerar en tand på triggerplattan. Här kan du använda alla sorters triggerkod precis som på oscilloskopet. Rising, falling, change.
Man lagrar därefter in detta i säg 4 olika variabler. Vi kallar dom cylinder cycles.
Nu har du en annan interruptkod som triggas av en sanningstabell som visar vart i cykeln motorn befinner sig.
Denna är livsviktig för motorn behöver olika mycket bränsle och tändvinkel beroende av varv och last.
...
Summa på vilka interrupt som man kan behöva så här i början är;
1. master counter. Dvs godtyckligt räknare för hela 720 graders otto cykeln.
2. Trigger interrupt.
3. Scheduler. Dvs schemaläggare. Detta är din sanningstabell.
4. Ny PWM-styrning för bla spridare.

För om du räknar på 1/4500 varv får du 222 microsekunder. Det blir värre, tro mig. Om vi då redan har 6 usec jitter åt båda håll. Dvs 12/222 ger 5,5% konstant fel per varv! Detta är enormt i motorsammanhang. Dvs 720*0,055 är 39,6 grader i båda riktningarna dvs både innan och efter dödläge. Ifall vi nu räknar med det som vår referens. Men det är detsamma vilken del av cykeln vi använder.

Med interrupt försvinner dessa problem nästan helt.
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 »

En fråga om interruptet: Kan ett interrupt agera snabbare än att processorn ligger och väntar på att ingången slår om? (Den här pulseIn gör så)
Jag hade också basshead´s inlägg i tankarna när jag skrev nu. Men jag får det inte till +- 40 grader jitter. Inte teoretiskt och framför allt inte praktiskt, när jag använder min motorsimulator och kör emot ECU:n så är alla tider exakta varje gång. Jag använder oscilloskopet för tidsmätningar och det skiljer inom någon enstaka uS, kan lika gärna vara skåpet i sig självt som Arduinon…
basshead: Men den dagen du lägger last på motor och koden sitter och sover när det behövs bränsle då blir inte motorn gammal.
Jag har faktiskt tvärtom problem, den får för mycket soppa men det beror nog på min programmering, jag har dålig aning om hur mycket extra den skall ha under acceleration/varvtalsökning och jag har ju programmerat för turbo men den ligger på golvet i garaget just nu så jag tror jag måste snåla ner maxmängd per slag på spridarna. Kan ju faktiskt vara detta som krånglar när man gasar på... Hmm, får nog dra ner maxmängen rejält och testa.
Användarvisningsbild
mrfrenzy
Co Admin
Inlägg: 14818
Blev medlem: 16 april 2006, 17:04:10

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av mrfrenzy »

Från dokumentationen av pulseIN:
The timing of this function has been determined empirically and will probably show errors in shorter pulses.
Det är förmodligen det här jittret som basshead pratar om.

Om du gör en korrekt mätning med hjälp av interrupt och timers ser jag ingen anledning till att det inte ska bli exakt.

Att testa mot simulatorn är uppenbarligen för enkelt, den har inte dom plötsliga variationer och förändringar som finns i motorn pga förbränning och belastning.
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 »

Ja det citatet är nog från pulseInLong, jag har pulseIn bara. Bägge fungerar inom 10 uS men pulseIn kan räkna fel på långa tider, jag anser mig ha korta tider (mellan 100 till 5-600 uS) Hade nu denna pulseIn räknat lite hips som haps så hade inte insprutningsstarttiderna och längderna på spridarpulserna varit så exakta gång efter gång. Vidare så används denna pulseIn i en annan sketch där man mäter avstånd med hjälp av en ultraljudsmodul och den fungerar ju med hög säkerhet och repeternoggrannhet även på kortaste avståndet. Jag antar att där sätts denna sketch mest på prov? Jag läser lite om attachinterrups som jag tror skulle vara rätt för mig vid en ev. omkonstruktion, där står inget direkt om onoggrannheter eller så. Men hur fungerar detta egentligen? Processorn måste väl ändå köra någon slags polling på bevakad ingång för den kan väl inte bevaka en ingång kontinuerligt samtidigt som den arbetar med annat (har ju bara en kärna) Sen när den väl märker att ingången förändras så kan den första lägge en tidsmarkör på förändringen och sen städa bort och spara det den höll på med och sen ta hand om den interruptade ingången. Detta tar väl ochså tid i anspråk?
Tusan, jag måste få ordning på min logikanalysator så jag kan göra IRL mätningar. Jag kommer att tro på min programmering tills motsatsen är bevisad, antingen av mig själv eller av någon annan som kan bevisa det.
Användarvisningsbild
mrfrenzy
Co Admin
Inlägg: 14818
Blev medlem: 16 april 2006, 17:04:10

Re: ECU- styrning till en VW pumpdysediesel.

Inlägg av mrfrenzy »

Jo det fina med interrupt är att dom bevakas av hårdvara medan processorn håller på med annat.
Man behöver inte polla hela tiden.

Exempel
Du håller på i mainloopen att beräkna pi.
Du har just kommit till 3,141 när vevaxelgivaren skickar en puls.
Eftersom du har satt interruptbevakning på den ingången så reagerar hårdvaran direkt.
Mainloopen tar paus vid nästa klockcykel och interruptrutinen körs.
Den är väldigt kort och gör bara tand++
Interruptet avslutas och mainloop fortsätter exakt där den var på 3,141.
Den hinner räkna vidare till 3,141592 innan nästa tand kommer och cykeln repeteras.

Noggrannhet/jitter i denna mätning blir tiden för en klockcykel vilket är cirka 0,25 ųs
Det borde vara fullt tillräckligt för en motor, annars är till exempel Teensy3 10ggr snabbare.
Skriv svar