Japan Car

Version complète : Importer la carto XE5 (Mugen PM7) dans TurboEdit, possible ?
Vous consultez actuellement la version basse qualité d’un document. Voir la version complète avec le bon formatage.
Pages : 1 2
Voilà je cherche à éditer ma cartographie Mugen dans TurboEdit pour lui rajouter des fonctions comme le datalogging, Launch Control, etc...

Mais TurboEdit n'arrive qu'à éditer les cartographies de PGMFI.ORG (séries NG). Comment peut on faire pour alors importer cette cartographie dans TurboEdit ? Faut il re-rentrer toutes les valeurs à la main ?


Merci de vos réponses Wink
Tu ouvre la carto mugen avec obd0 edit puis ensuite tu les copie dans turbo edit Wink

PS: pourquoi tu n'as pas pris l'EVO2 :] ?
Ok, mais les valeurs de dépression ne correspondent pas (enfin pas toutes), ca risque d'influer bcp ?


P.S : Je n'y pensais plus, mais je te donne mon email si tu veux :]
Piv m'a devancé ...
Sinon pour les valeurs des colonnes c'est modifiable, ou alors tu extrapole avec un fichier excel.
civic_16Turbal a écrit :Piv m'a devancé ...
Comme dab :] LOL
Citation :tu extrapole avec un fichier excel.

Yes, ca doit bien etre le plus simple

En plus ca te permet de voir les variances en 3d en direct live Wink
Oula, il me faut des cours de TurboEdit moua.... je trouve pas la fonction pour modifier la valeur des colonnes Confused
J'ai écrit un logiciel qui extrait les cartos au format excell, mais il vaut cher ! LOL

Sinon j'arrive à charger XE5 dans turboedit mais ... faut être un bricoleur de binaires ! ^^
Je suis vraiment dans un jour de bonté ! LOL

Je vous file mon code source C++. Wink


Code :
/*

IcedFluid

  
First version    :    19/07/2004

Modified        :    31/09/2004
                    15/09/2005



  ECU PM7 Only



  Dev Compiler : MS Visual C++ 6.0

*/




/*

INFORMATIONS :


FUEL MAP

      o Adresse

      $3EF2 (PM6 / PM7)


    o Equations completes
  
      injector pulse (ms)  = (fuel map value + (224 / (2^multi))) / (208 / (2^multi))
      fuel map value (hex) = (pulse x (208 / (2^multi))) - (224 / (2^multi))


    o Equations simplifies
  
      a = (224 / (2^multi))
      b = (208 / (2^multi))

      injector pulse (ms)  = (fuel map value + a) / b
      fuel map value (hex) = (pulse x b) - a


IGNITION MAP


    o Adresses

      $3DF3 (PM6)
      $3CE5 (PM7)


    o Equations

      retard (angle en ░)  = ((igni map value) - 15 ) * 0.36
      igni map value (hex) = (retard / 0.36) + 15


CHECKSUM

    o activÚ
      $23BF = 0x60
      
    o desactivÚ
      $23BF = 0x80


REV LIMITER


    o Adresses
      
      PM7 (HOT)
      hb : high byte = @$0F53
      lb : low  byte = @$0F55

      origine = 0x00, 0xFA = 7680 RPM


    o Equations
  
      RPM = 1920000 / ( ( *($) x 256) + *($+2) )

      (hb x 256) + lb = 1920000 / RPM

      
    o Algorithme de calcul hb & lb depuis RPM
    
      V  = 1920000 / RPM
      hb = valeur_entiere(V / 256)
      lb = V - (256 x hb)
          

      nb : Attention a RPM = 0 (division par 0 !)

  
IDLE

    o Adresses
      
      PM7 (HOT)
      hb : high byte = @$3B53
      lb : low  byte = @$3B55
    
      origine = 0x09, 0x09 = 830 RPM

*/


#include <windows.h>

#include <stdio.h>
#include <io.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>



typedef unsigned char    uchar;
typedef unsigned short    ushort;


class cPM7
{


    public :            cPM7();
    public :            ~cPM7();

    public :    bool    read ( char * qfileName );
    public :    bool    write( char * qfileName );
    public :    bool    dump ( char * qfileName );

    
    
    //
    // SECTION MAPS
    //

    protected :    void    loadMap( ushort qoffset, void * qdstmap, ushort qsize );
    protected :    void    writeMap( ushort qoffset, void * qsrcmap, ushort qsize );

    protected :    void    loadFuelMap()    { loadMap(ofuelmap, c_fuelmap, sizeof(c_fuelmap));  }
    protected :    void    loadFuelMult()    { loadMap(ofuelmult,c_fuelmult,sizeof(c_fuelmult)); }
    protected :    void    loadIgniMap()    { loadMap(oignimap, c_ignimap, sizeof(c_ignimap));  }
    protected :    void    loadMaps()      { loadFuelMap(); loadFuelMult(); loadIgniMap();        }

    protected :    void    writeFuelMap()    { writeMap(ofuelmap, c_fuelmap, sizeof(c_fuelmap));  }
    protected :    void    writeIgniMap()    { writeMap(oignimap, c_ignimap, sizeof(c_ignimap));  }

    protected :    float    calcPulse( uchar qpulse, uchar qmulti );
    protected :    uchar    calcPulse( float qpulse, uchar qmulti );
    
    protected :    float    calcAngle( uchar qangle );
    protected :    uchar    calcAngle( float qangle );

    public    :    void    buildMaps( void * qdstmap, void * qsrcmap );

    public    : bool    fuelMap( uchar qrow, uchar qcol, float qvalue ){  return sMap(qrow, qcol, qvalue, f_fuelmap); }
    public    : bool    igniMap( uchar qrow, uchar qcol, float qvalue ){  return sMap(qrow, qcol, qvalue, f_ignimap); };
    public    : float    fuelMap( uchar qrow, uchar qcol ){  return gMap(qrow, qcol, f_fuelmap); }
    public    : float    igniMap( uchar qrow, uchar qcol ){  return gMap(qrow, qcol, f_ignimap); }

    protected : bool    sMap( uchar qrow, uchar qcol, float qvalue, float * qmap );
    protected : float    gMap( uchar qrow, uchar qcol, float * qmap  );

    protected : char *    floatToChar( float qvalue, int qcount );
    protected : bool    rowcol(uchar qrow, uchar qcol);

    protected :

    uchar c_fuelmap[255];
    uchar c_fuelmult[15];

    uchar c_ignimap[255];

    float f_fuelmap[255];
    float f_ignimap[255];

    ushort    ofuelmap;
    ushort    ofuelmult;
    ushort    oignimap;



    //
    // SECTION RPM STUFF
    //

    protected : ushort    loadRpm(ushort qoffh, ushort qoffl);
    protected : void    writeRpm( ushort qrpm, ushort qoffh, ushort qoffl );

    protected : ushort    calcRpm( uchar qhb, uchar qlb );
    protected : void    calcRpm( ushort qrpm, uchar * qhb, uchar * qlb );


    //
    // SECTION REV.LIMITER
    //

    public      : void    setRevLimiter( ushort qrpm )    { revl = qrpm; }

    protected : void    loadRevLimiter()                { revl = loadRpm(orvhb, orvlb); }
    protected : void    writeRevLimiter( ushort qrpm )    { writeRpm(revl, orvhb, orvlb); }


    protected :

    ushort  revl;
    ushort    orvhb;        //offset rev.limiter High Byte
    ushort    orvlb;        //offset rev.limiter Low  Byte


    //
    // SECTION IDLE
    //

    public      : void    setIdle( ushort qrpm )            { idle = qrpm; }

    protected : void    loadIdle()                        { idle = loadRpm(oidlhb, oidllb); }
    protected : void    writeIdle( ushort qrpm )        { writeRpm(idle, oidlhb, oidllb); }


    protected :

    ushort  idle;
    ushort    oidlhb;        //offset idle High Byte
    ushort    oidllb;        //offset idle Low  Byte


    //
    // SECTION CHECKSUM
    //

    protected : void    writeChecksumDisabled();

    protected :

    ushort    ochecksum;


    //
    // SECTION GENERAL
    //

    protected :

    ushort    szfile;

    FILE *  f;

};


cPM7::cPM7()
{

    szfile        = 16384;    //16ko
    f            = NULL;    


    // MAPS
    ofuelmap    = 0x3EF2;
    ofuelmult    = 0x3FF1;
    oignimap    = 0x3CE5;

    memset(c_fuelmap,    0, sizeof(c_fuelmap));
    memset(c_fuelmult,    0, sizeof(c_fuelmult));
    memset(c_ignimap,    0, sizeof(c_ignimap));
    memset(f_fuelmap,    0, sizeof(f_fuelmap));
    memset(f_ignimap,    0, sizeof(f_ignimap));


    // REV.LIMITER
    revl        = 0;
    orvhb        = 0x0F53;
    orvlb        = 0x0F55;

    
    // IDLE
    idle        = 0;
    oidlhb        = 0x3B53;
    oidllb        = 0x3B55;


    // CHECKSUM
    ochecksum    = 0x23BF;

}


cPM7::~cPM7()
{
    ;
}


bool cPM7::rowcol(uchar qrow, uchar qcol)
{
    if( qrow >= 0 && qrow <=17 )    
        if( qcol >= 0 && qcol <=15 )
            return true;        

    return false;
}


bool cPM7::sMap( uchar qrow, uchar qcol, float qvalue, float * qmap )
{
    if( rowcol(qrow, qcol) )
    {
        qmap[ (15 * qrow) + qcol ] = qvalue;
        return true;
    }

    return false;
}


float cPM7::gMap( uchar qrow, uchar qcol, float * qmap )
{
    if( rowcol(qrow, qcol) )
    {
        return qmap[ (15 * qrow) + qcol ];        
    }

    return -1;
}


void cPM7::loadMap( ushort qoffset, void * qdstmap, ushort qsize )
{
    fseek(f, qoffset, 0);

    fread(qdstmap, 1, qsize, f);
}


void cPM7::writeMap( ushort qoffset, void * qsrcmap, ushort qsize )
{
    fseek(f, qoffset, 0);

    fwrite(qsrcmap, 1, qsize, f);
}


float cPM7::calcPulse( uchar qpulse, uchar qmulti )
{
    float a = powf( 2, qmulti);

    return (qpulse + (224 / a)) / (208 / a);
}


uchar cPM7::calcPulse( float qpulse, uchar qmulti )
{
    float a = powf( 2, qmulti);

    return (uchar)((qpulse * (208 / a)) - (224 / a));
}


float cPM7::calcAngle( uchar qangle )
{
    return ((qangle - 15 ) * (float)0.36);
}


uchar cPM7::calcAngle( float qangle )
{
    return (uchar)((qangle / 0.36) + 15);
}


void cPM7::buildMaps( void * qdstmap, void * qsrcmap )
{
    int i, m;

    for(i= m= 0; i<255; i++)
    {        
        if( qdstmap == f_fuelmap && qsrcmap == c_fuelmap )
            f_fuelmap[i] = calcPulse( c_fuelmap[i], c_fuelmult[m] );

        if( qdstmap == f_ignimap && qsrcmap == c_ignimap )
            f_ignimap[i] = calcAngle( c_ignimap[i] );

        if( qdstmap == c_fuelmap && qsrcmap == f_fuelmap )
            c_fuelmap[i] = calcPulse( f_fuelmap[i], c_fuelmult[m] );
    
        if( qdstmap == c_ignimap && qsrcmap == f_ignimap )
            c_ignimap[i] = calcAngle( f_ignimap[i] );

        
        if( m >= 14 ) m = 0;
        else m++;
    }

}


ushort cPM7::calcRpm( uchar qhb, uchar qlb )
{
    return (1920000 / ((qhb * 256) + (qlb)));
}


void cPM7::calcRpm( ushort qrpm, uchar * qhb, uchar * qlb )
{
    long v;

    if( qrpm <= 0    ){ qrpm = 1;        }
    if( qrpm > 15000 ){ qrpm = 15000;    }


    v        = (long)(1920000 / qrpm);
    *qhb    = (uchar)(v / 256);
    *qlb    = (uchar)(v - (256 * (*qhb)));
}


ushort cPM7::loadRpm( ushort qoffh, ushort qoffl )
{
    uchar hb, lb;

    fseek(f, qoffh, 0);
    fread(&hb, 1, sizeof(hb), f);

    fseek(f, qoffl, 0);
    fread(&lb, 1, sizeof(lb), f);

    return calcRpm( hb, lb );
}


void cPM7::writeRpm( ushort qrpm, ushort qoffh, ushort qoffl )
{
    uchar hb, lb;

    calcRpm( qrpm, &hb, &lb );

    fseek(f, qoffh, 0);
    fwrite(&hb, 1, sizeof(hb), f);

    fseek(f, qoffl, 0);
    fwrite(&lb, 1, sizeof(lb), f);
}


void cPM7::writeChecksumDisabled()
{
    uchar v = 0x80; // replace a 0x60 for kill the checksum routine

    fseek(f, ochecksum, 0);
    fwrite(&v, 1, sizeof(v), f);
}







bool cPM7::read( char * qfileName )
{
    bool r = false;

    if( (f = fopen(qfileName, "rb")) != NULL )
    {
        if( _filelength(f->_file) >= szfile )
        {
            loadMaps();

            buildMaps( f_fuelmap, c_fuelmap );
            buildMaps( f_ignimap, c_ignimap );

            loadRevLimiter();
            loadIdle();

            r = true;
        }

        fclose(f);
    }

    return r;
}


bool cPM7::write( char * qfileName )
{
    bool r = false;

    if( (f = fopen(qfileName, "wb")) != NULL )
    {
        if( _filelength(f->_file) >= szfile )
        {
            buildMaps( c_fuelmap, f_fuelmap );
            buildMaps( c_ignimap, f_ignimap );

            writeFuelMap();
            writeIgniMap();

            writeRevLimiter( this->revl );
            writeIdle( this->idle );

            writeChecksumDisabled();
        }

        fclose(f);
    }

    return r;
}


char * cPM7::floatToChar( float qvalue, int qcount )
{
    static char v[30];
    
    int decimal, sign;
    
    char * buf = _fcvt( qvalue, qcount, &decimal, &sign);

    memset(v, 0, sizeof(v));


    if( sign )
        strcat(v, "-");

    strncat(v, buf, decimal);
    strcat (v, ",");
    strcat (v, buf+decimal);

    
    return v;
}


bool cPM7::dump(char * qfileName)
{
    int        l, c, map;
    float * ptab;
    char    buf[100];

    char *    RPM[17] = {"500 ","600 ","700 ","800 ","900 ","1100","1300","1600","1900","2200","2600","3100","3700","4400","5300","6300","7400"};
    char *    MAP[15] = {"26","24","22","21","19","18","16","14","13","11","9","8","4","1","1,3" };

    bool    r = false;


    if( (f = fopen(qfileName, "wb")) != NULL )
    {

        //
        // Maps dump
        //            
        for(map=0; map<2; map++)
        {

            // Show Maps Titles
            if( map == 0 )
            {
                fputs("\r\n- FUEL MAP - ( x = vaccum (ingh) ; y = RPM ; values = injector pulse (milliseconds) ) \r\n", f);
                ptab = &f_fuelmap[0];
            }

            if( map == 1 )
            {
                fputs("\r\n- IGNITION MAP - ( x = vaccum (ingh) ; y = RPM ; values = ignition advance (angle degrees) ) \r\n", f);
                ptab = &f_ignimap[0];
            }


            //Show Vaccum Row    
            fputs("\r\n;\t\t", f);

            for(c= 0; c<15; c++)
            {                
                fputs(MAP[c], f);        
                fputs(";\t\t", f);
            }

            
            //Show RPM Columns and table values
            fputs("\r\n", f);

            for(l= 0; l<17; l++)
            {
                
                fputs(RPM[l], f);
                fputs(";\t", f);
                {
                
                    for(c= 0; c<15; c++)
                    {    
                        fputs( floatToChar( ptab[ (15*l)+c ], 2 ), f );
                        fputs(";\t", f);        
                    }

                }
                fputs("\r\n", f);
            }    

        
        }//end for



        //
        // Show Rev.Limiter
        //        
        fputs("\r\n- REV.LIMITER - \r\n", f);
        sprintf(buf, "%d", revl );
        
        fputs(buf, f);
        fputs("\r\n", f);


        //
        // Show Idle
        //        
        fputs("\r\n- IDLE - \r\n", f);
        sprintf(buf, "%d", idle );
        
        fputs(buf, f);
        fputs("\r\n", f);



        fclose(f);
    }

    return r;
}




///////////////////////////////////////////////////////////////////////////////////////////////////////
// MAIN
///////////////////////////////////////////////////////////////////////////////////////////////////////




char * openFile();
char * saveFile();


int main (int argc, char * argv[])
{    
    cPM7 pm7;

    pm7.read(openFile());

    pm7.dump(saveFile());

    return 0;
}


char * openFile()
{

    static    char srcFile[255];

    OPENFILENAME ofn;


   // Initialisation de la DialogBox de choix de fichier
    
    memset(&ofn, 0, sizeof(ofn));
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = NULL;
    ofn.lpstrFile = srcFile;
    ofn.nMaxFile = sizeof(srcFile)-1;
    ofn.lpstrFilter = "*.BIN;*.bin";
    ofn.nFilterIndex = 1;
    ofn.lpstrFileTitle = NULL;
    ofn.nMaxFileTitle = 0;
    ofn.lpstrInitialDir = NULL;
    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;


    int getopen = GetOpenFileName(&ofn);


    if( getopen )
    {
        if( strlen(ofn.lpstrFile) )
        {
            return ofn.lpstrFile;
        }

    }

    return "";
}


char * saveFile()
{

    static    char dstFile[255];
    
    OPENFILENAME ofn;


   // Initialisation de la DialogBox de choix de fichier
    
    memset(&ofn, 0, sizeof(ofn));
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = NULL;
    ofn.lpstrFile = dstFile;
    ofn.nMaxFile = sizeof(dstFile)-1;
    ofn.lpstrFilter = "";
    ofn.nFilterIndex = 1;
    ofn.lpstrFileTitle = NULL;
    ofn.nMaxFileTitle = 0;
    ofn.lpstrInitialDir = NULL;
    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;


    int getsave = GetSaveFileName(&ofn);


    if( getsave )
    {
        if( strlen(ofn.lpstrFile) )
        {
            return ofn.lpstrFile;
        }

    }

    return "";
}
ça c'est très sympa, j'ai déjà pompe ton programme sur le bloc note....

Pour l'utiliser : comment je fais ? Je passe par C++

(C'est pour éviter de me faire encore insulter par mon pote en BTS info)
Ouep, faut compiler avec un compilateur C++ sous Windows. En fait le code peut tourner sur n'importe quelle plateforme, mais j'appele 2 fonctions de l'API Windows : GetOpenFileName() et GetSaveFileName(). On pourrait les virer et remplacer par la ligne de commande.

Tu remarqueras que je ne fais que 2 appels de méthodes dans le main(). En fait le prog lit un binaire PM7 et génére dans le fichier texte de sortie la version lisible des paramètres et cartographies, que l'on peut importer dans excel.

Tu veux l'executable ? ^^
Je vais montrer ton message et filer le code source à mon collègue, il m'a dit qu'il me ferait l'exe sans pb.
Merci
Faut juste pas cliquer sur "annuler" quand tu choisis les fichiers, car çà crash. Ouais j'ai pas mis de test à cet endroit, c'est un prog pour moi au départ ...
ok, mon collègue pourra surement faire quelquechose là dessus.
Code :
int main (int argc, char * argv[])
{  
   cPM7 pm7;

   char * o, *s;

   o = openFile();
   s = saveFile();

   if( strlen(o) && strlen(s) )
   {
       pm7.read(o);
       pm7.dump(s);
   }

   return 0;
}


Wink
Merci Ice pour le code, un ami me l'a modifié, car moi et le C++, ca fait 2

http://niconfr.free.fr/Civic/BinConverter.exe

Par contre, malgré cela, je n'arrive tjs pas à ouvrir ma Mugen dans TE, pour lui ajouter le datalog

P.S : J'ai encore le code si tu veux
nico42 a écrit :Par contre, malgré cela, je n'arrive tjs pas à ouvrir ma Mugen dans TE, pour lui ajouter le datalog

Personne ne sait faire ça ?
Hop !
A mon avis tu devrais créer une nouvelle carto stock avec ton soft, tu rajoutes tes options/fonctions, puis ensuite tu écrases tes maps avec celles que tu as importées puis tu sauvegardes le tout.

C'est come que je procède pour me faire des carto safe s'appuyant sur un code stock, ça évite les "raccourcis" du code qui oublie des codes erreurs par exemple LOL
Le prob c'est qu'avec TurboEdit, tu ne peux partir qu'avec une carto existante.

De plus, les valeurs des colonnes ne sont pas les mêmes entre ODB0-Edit et TurboEdit, on m'a dit que l'on pouvait changer les valeurs des colonnes dans TurboEdit, mais je trouve pas la fonction.
Et les basemaps pour le PM7 et pour TurboEdit n'existent pas, car TurboEdit est fait par pgmfi.org, et au states ils ne connaissent pas l'ECU PM7, il n'y a que le PM6 qui est le plus approchant
tu n'as pas trouver une carto PM7 Euro qui traine sur PGMFI ? Ca m'étonne.

Normalement en double cliquant sur les valeurs des lignes et colones tu peux changer la valeur (ne jamais modifier la première te la dernière).

Voilà en 2 min de recherche :
Des BIN : http://forum.pgmfi.org/viewtopic.php?t=1651
Des infos : http://forum.pgmfi.org/viewtopic.php?t=822

Je refuse de t'aider d'avantage... Twisted
dj_spark, grand merci, pourtant j'ai passé du temps sur PGMFI à rechercher, même dans le wiki, et pas de résultat.

Par contre sur TurboEdit, même en double cliquant sur les valeurs des colonnes et des lignes (valeurs de dépression du collecteur d'admission, et tours/min), je n'arrive pas à modifier les valeurs, je ne peux modifier que les valeurs du tableau en lui même, ce qui est normal
J'ai essayé les cartos PM7 euro trouvées gracieusement par dj_spark sur PGMFI, mais rien ne marche sur la voiture, l'ECU se met en défault direct.

Mon seul souhait est de trouver une carto qui s'ouvre dans TurboEdit, qui supporte le datalog, et surtout qui marche !

Merci de votre aide
Et pourquoi pas une cuisine memballepa à moitié prix ?!

Désolé nico celle là était trop ..... tentante Oops!


[Image: sac.gif]
Bonne chance dans ta recherche Piaf Piaf
A part les NG55/60 je ne pense qu'il y ai grand chose qui tourne correctement sur l'ecu PM7 Euro.
En ODB0 les adresses sont assez spec parait-il. Sinon Icedfluid à longtemps lutté avec les NG (pour virer l'erreur O²) peut être qu'il pourrais t'en dire plus.

Ou passe en ODB1 !!! LOL
tu as quelle version de TE?

tu n'as qu'à faire un copier coller de la xe5 sur une Ng60 et voila !!!!!
je vois pas ou est le problem !
Version TE 2.5.5.


J'aimerai bien, mais les valeurs des entêtes des colonnes ne correspondent pas. Et si je met la NG60 avec les valeurs de la XE5, j'ai un beau code erreur pour les injecteurs, alors qu'ils sont bien sélectionné dans TE.
Le plus dur est donc de replacer les deux "échelles" pour avoir les mêmes valeurs...
Déja fait, j'ai ensuite essayé ma carto, mais comme dit plus haut, le code erreur apparait pas longtemps après avoir démarrer et le moteur tourne comme une patate.

Voila ma carto, base NG60 avec les valeurs de la XE5 modifiées en rapport de la valeur des entêtes des colonnes :

[Image: carto9hz.jpg]
si tu prends les 2 carto que t'a filé dj_spark, elles souvrent avec TE et ont les memes colones que la XE5 !!

donc je ne vois toujours pas ou est le problem !!
:roll:
Relis ce que j'ai écris plus haut, les 2 cartos ne marchent pas, l'ECU se met en mode défault direct Wink
Pages : 1 2