Le site dédié à l'Alfa Romeo 147
FAQFAQ RechercheRechercher MembresListe des Membres S'enregistrerS'enregistrer Mon ProfilProfil Messagerie privée (MP)Se connecter pour vérifier ses messages privés ConnexionConnexion


Exploitation réseau CAN et affichage
Aller à la page Précédente  1, 2, 3, 4, 5, 6, 7  Suivante
 
Poster un nouveau sujet   Répondre au sujet    ALFA 147 France Index du Forum -> Divers
Voir le sujet précédent :: Voir le sujet suivant  
Auteur Message
Arthur_035



Inscrit le: 11 Nov 2007
Messages: 182
Localisation: 35

MessagePosté le: 25 Mar 2015 23:35    Sujet du message: Répondre en citant

Force est de constater que le forum AlfaGTPassion est plus actif sur le sujet !!
2 réalisations opérationnelles avec les instructions données et échangées. Donc c'est réalisable !
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé




CocoNat's



Inscrit le: 30 Mai 2014
Messages: 380
Localisation: Oise

MessagePosté le: 26 Mar 2015 14:46    Sujet du message: Répondre en citant

Ca m'intéresse mais je n'ai aucune connaissance dans le domaine. J'arrive à comprendre quelques trucs mais pas tout.

Qui plus est, j'ai quelques travaux à faire sur ma 147 et les finances doivent être contrôlées. j'aurais plaisir à partager et à essayer dès qu'elles seront plus vertes..
_________________

Alfa Romeo 147 (vendue)
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
bips



Inscrit le: 15 Sep 2013
Messages: 2342
Localisation: Anjou

MessagePosté le: 26 Mar 2015 23:14    Sujet du message: Répondre en citant

Arthur_035 a écrit:
Force est de constater que le forum AlfaGTPassion est plus actif sur le sujet !!
2 réalisations opérationnelles avec les instructions données et échangées. Donc c'est réalisable !

J'ai regardé un long moment sans rien trouver, tu as les url des page par hasard ?
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
Arthur_035



Inscrit le: 11 Nov 2007
Messages: 182
Localisation: 35

MessagePosté le: 26 Mar 2015 23:18    Sujet du message: Répondre en citant

Voici le lien :
http://www.alfagtpassion.com/index.php?showtopic=21105
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
bips



Inscrit le: 15 Sep 2013
Messages: 2342
Localisation: Anjou

MessagePosté le: 26 Mar 2015 23:22    Sujet du message: Répondre en citant

Merci. mdr
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
grise147



Inscrit le: 14 Oct 2007
Messages: 8762
Localisation: TOULOUSE !

MessagePosté le: 06 Avr 2015 00:34    Sujet du message: Répondre en citant

de mon coté, je ne peux pas le realiser, car je n ai pas de voiture avec CAN bus .... oh oh oh

si un jour, je peux acheter une alfa, je le ferai razz
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
Arthur_035



Inscrit le: 11 Nov 2007
Messages: 182
Localisation: 35

MessagePosté le: 17 Avr 2015 23:02    Sujet du message: Répondre en citant

j'ai retravaillé un peu sur le sujet, afin de mieux comprendre le protocole, et les timing.

Celà permet d'ajouter de nouvelles fonctionnalités :

Affichage de l'ensoleillement mesuré (droite et gauche cumulés)

Meilleure réactivité des commandes + augmentation fréquence de rafraichissement (3 par seconde).
Prise en compte d'appuis multiples (pour progresser rapidement dans les menus)
Correction bug d'affichage

Indicateur de changement de vitesse s'affiche dans tous les modes (préempte les autres affichages)

Réinitialisation de l'intervalle de révision (fixé à 10.000 km)

Affichage de messages >8 caractères avec défilement.
Affichage de la puissance et du couple, calcul de l'accélération
Affichage des codes d'erreur (DTC : Diagnostic Trouble Code)
- enregistrés dans l'ECU : max=3
- courants (non encore enregistrés). max=3
- enregistrés dans le bodyComputer. max=1
Effacement des codes d'erreur (ECU et Body)

Données de consommation du parcours, depuis le démarrage du moteur (l, km, l/100km, temps) : Tests en cours ...!

Après, j'ai plus beaucoup d'idées, sans aide extérieure pour savoir comment piloter des éléments en roulant (ex affichage des warning, en cas de décélération forte au dessus d'une certaine vitesse).
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
CocoNat's



Inscrit le: 30 Mai 2014
Messages: 380
Localisation: Oise

MessagePosté le: 18 Avr 2015 11:09    Sujet du message: Répondre en citant

Excellent !

La luminosité ne permettrait pas de piloter les feux pour qu'ils "deviennent" automatique ?

Le défilement est une bonne chose mais... Est-ce possible d'avoir un affichage sur deux lignes comme "Test en cours" à chaque démarrage de la voiture ?

Et, on va me taper dessus peut-être mais... C'est possible de mettre un petit message de bienvenu au démarrage style "Bonjour Coco" :D ?

Je fini mes examens et je vais me pencher dessus très sérieusement !
_________________

Alfa Romeo 147 (vendue)
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
grise147



Inscrit le: 14 Oct 2007
Messages: 8762
Localisation: TOULOUSE !

MessagePosté le: 20 Avr 2015 21:22    Sujet du message: Répondre en citant

Arthur_035 a écrit:
Après, j'ai plus beaucoup d'idées, sans aide extérieure pour savoir comment piloter des éléments en roulant (ex affichage des warning, en cas de décélération forte au dessus d'une certaine vitesse).


j en ai peut etre une, si intervention abs, tu peux faire allumer le warning razz
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
Arthur_035



Inscrit le: 11 Nov 2007
Messages: 182
Localisation: 35

MessagePosté le: 20 Avr 2015 22:28    Sujet du message: Répondre en citant

Citation:
La luminosité ne permettrait pas de piloter les feux pour qu'ils "deviennent" automatique ?


hélas 2 fois non :
- le capteur mesure l'ensoleillement. en gros, çà décolle quand la luminosité est déjà très forte.
- je ne sais pas piloter les actuateurs lorsque le système detecte qu'on roule !
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
Arthur_035



Inscrit le: 11 Nov 2007
Messages: 182
Localisation: 35

MessagePosté le: 20 Mai 2015 23:20    Sujet du message: Répondre en citant

Voici donc, une nouvelle version, incluant les évolutions décrites précédemment :
- optimisations diverses
- consultation et effacement des codes d'erreur
- reinitialisation de l'intervalle de révision,
- indicateur de changement de vitesse,
- menu Eco-conduite, donnant les éléments relatifs à 1 parcours, consommation totale de coarburant, ..., incluant la consommation de CO2 (en g/km)



code :
Code:

/*
V07 : Rationalisation
Affiner passage vitesses
Ajout setup
Taille code : 18172
V08
Affichage de l'ensoleillement mesuré (droite et gauche cumulés)
Gestion de bips 
Réinitialisation de l'intervalle de révision (fixé à 10.000 km)
Modification de fonctionnement du setup (Choix à valider par appui très long (3s))
Indicateur de changement de vitesse s'affiche dans tous les modes (préempte les autres affichages)

V09
Meilleure réactivité des commandes + augmentation fréquence de rafraichissement (3 par seconde).
Prise en compte d'appuis multiples (pour progresser rapidement dans les menus)
Correction bug d'affichage
Affichage de messages >8 caractères avec défilement.
Affichage de la puissance et du couple.
Affichage des codes d'erreur (DTC : Diagnostic Trouble Code)
 - enregistrés dans l'ECU : max=3
 - courants (non encore enregistrés). max=3
 - enregistrés dans le bodyComputer. max=1
Effacement des codes d'erreur (ECU et Body)
20896
V10
Données de consommation parcours (l, km, l/100km, CO2/km,  temps)

*/


#define BTS1                // bluetooth CAN
#define BTS2                // bluetooth ISO9141
#define RLI                 // envoie et traite trames RLI
#define SP3          // envoie et traite ISO9141
#define DTC                 // Default Trouble Codes
#define SRA                 // SpeedRegul action
#define TADJ                // Time Adjust


//#define DEBUG              // Serial
//#define DEBUG_SEND1
//#define DEBUG_SEND2
//#define EMUL              // pour test en local

//#define DEBUG_RECV1
//#define DEBUG_RECV2



#include <EEPROM.h>
#include <SoftwareSerial.h>

// Connexions modules BT et boutons
#define BUT1_PIN  5
#define BUT2_PIN  6
#define RxD1_PIN 8
#define TxD1_PIN 9
#define RxD2_PIN 11
#define TxD2_PIN 12

// BTS1 : Module CAN
#if defined(BTS1)
SoftwareSerial Bts1Serial(RxD1_PIN,TxD1_PIN);  //Rx, Tx

String can_Resp1="";
String can_LastResp1="";
byte can_Idle1=1;         // 0:pas idle
#endif

// BTS2 : Module KKL
#if defined(BTS2)
SoftwareSerial Bts2Serial(RxD2_PIN,TxD2_PIN);  //Rx, Tx
String can_Resp2="";
String can_LastResp2="";
byte can_Idle2=1;         // 0:pas idle
byte bts2_init=0;
byte bts2_protocol;
unsigned int bts2_init_tt;

unsigned long tt_SP3_next;
#define tt_SP3_period 2000
#endif

char MFD_buf8[9];                      // variables de Multi-Function Display
char MFD_buf6[6];
char MFD_buftmp[12];
String MFD_strg;


String MFD_string;        // globale : utilisé pour affichage long
String cmde;              // globale : construction commande



byte can_ATMA_Status=LOW;   // variables de AT Monitor All
byte can_ATMA_Fill=0;       // état de réception des trames
byte can_ATMA_Mask=0;       // masque de réception
byte can_ATMA_Nb=0;         // nb de trames à recevoir. se décrémente

unsigned long tt_can_ATMA_next;
#define tt_can_ATMA_period 2000


unsigned long tt_can_RLI_next;
#define tt_can_RLI_period 300

                                        // Table des rapports de vitesse BVM6 JTDM
//float gearTab[]={0, 8.8, 15, 24.6, 34.4, 43.8, 54.5};
static const float gearTab[]={0, 7.8, 13.8, 23.3, 32.9, 41.8, 52.4};
#define CO2_RATIO  26  //Essence : 22.8 Diesel : 26

//triggers
char can_SpeedRegulOn_status=0;
char can_SpeedRegulOff_status=0;
char can_ReverseGearOn_status=0;
char can_ReverseGearOff_status=0;
char can_FAMOn_status=0;
char can_FAMOff_status=0;
char can_Acceleration_trigger;

byte          can_Beep_nb;
unsigned long tt_can_acceleration;

                                      // Variables lues
float            can_Vbat;
byte       can_FuelLevel;
byte       can_EngineTemp;
int       can_EngineRPM;
byte       can_EngineSpeed;
unsigned long   can_EngineSpeed_tt;
byte       can_EngineSpeedLast;
unsigned long   can_EngineSpeedLast_tt;
float           can_EngineAcceleration;
float      can_EngineConsH;
//char      can_EngineOilLevel;
float      can_EngineBoost;
byte            can_EngineLoad;
byte            can_EngineP;
int            can_EngineC;
float      can_ExtTemp;
byte       can_IntTemp;
char       can_ReverseGear;
char       can_FAM=1;      // FreinAMain mis par defaut
char      can_SpeedRegul;
char      can_Belt;
byte           can_EGR;
byte            can_Gear;
byte            can_GearShift;
byte            can_Light;
int            can_CC_Lrad;
int            can_CC_Rrad;

float           can_km1, can_km2;


float cons100;
float consTotal;
unsigned long consTotal_tt;
unsigned long consTotal_00;
float can_GearR;
int  pmax2,cmax2, rpm2, load2;

#if defined(TADJ)
unsigned int mmc, mm1, mm2;
unsigned long mm1_tt;
float   mm_ratio=1;
#endif

// valeurs de boutons virtuels
#define btnUP     1
#define btnDOWN   2
#define btnUNDEF  0

byte vBtn;    // VirtualButton
byte vBtnNb;  // Nb appuis


// Bouton physique
byte           button_Trigger;   // +1 à chaque fois que appui + relache
unsigned long  button_Duration;  // durée d'appui
byte           button_Status;    // 0 si relaché, 1 si appuyé
unsigned long  button_tt;        // timer activé lorsque bouton appuyé



// ATMA : Broadcast sur le bus
// 180 : Etat feux
// 281 : RPM, Temp, Consh, regul
// 286 : Speed
// 380 : FreinAMain, Reverse, Vbat, Fuel
// 388 : Ext Temp
#define ATMA_281_MASK   0x01
#define ATMA_286_MASK   0x02
#define ATMA_380_MASK   0x04
#define ATMA_388_MASK   0x08
#define ATMA_180_MASK   0x10

#define NODE_BODY        0x7C0
#define NODE_CC          0x7CA

#define SVC_POSRESP_RDBLI   0x61
#define SVC_POSRESP_RDTCBS  0x58


#define TRIGGER_ARMED            3
#define TRIGGER_DETECTED    2
#define TRIGGER_PROCESSED    1
#define TRIGGER_OFF      0



byte          dlg_status;
byte                    dlg_subStatus;   // defilement menus

byte i;

                                // Etats du dialogue
#define status_VBAT       0
#define status_PARCOURS     1
#define status_CONSH        2
#define status_BOOST        3
#define status_EGR          4
#define status_SPEED        5
#define status_POWER        6
#define status_LOAD         7
#define status_FUEL         8
#define status_GEAR         9
#define status_TEMPI        10
#define status_DTC          11
#define status_SETUP        12
#define DLG_NB               13


// ----------- eeprom config -------------
byte config_status;         // config courante

#define CONFIG_EEPROM_ADDR  1

#define CONFIG_SWEEP_MASK    B00000001
#define CONFIG_AUTOLOCK_MASK B00000010



// ---------------------- SETUP ----------------
void setup()


#if defined(DEBUG)
Serial.begin(57600);
#endif



dlg_status=status_VBAT;
 
pinMode(RxD1_PIN, INPUT);
pinMode(TxD1_PIN, OUTPUT);
Bts1Serial.begin(38400);

#if defined(BTS2)
pinMode(RxD2_PIN, INPUT);
pinMode(TxD2_PIN, OUTPUT);
Bts2Serial.begin(38400);
#endif

pinMode(BUT1_PIN,OUTPUT);
digitalWrite(BUT1_PIN, LOW);
pinMode(BUT2_PIN,INPUT_PULLUP);


#if defined(DEBUG)
Serial.println(F("InitOk"));
#endif

can_SPC_init();        // Initialisation bus CAN
button_Init();   

config_read();          // lecture config dans EEPROM
can_Sweep();
can_ATMA_Start(1,ATMA_380_MASK);
}



// ---------------------------------- UTIL ---------------------

void(* resetFunc) (void) = 0;//declare reset function at address 0


unsigned char hex2dec(char c)
{
if ((c>='0')&&(c<='9'))
  return(c-'0');
if ((c>='A')&&(c<='F'))
  return(c-'A'+10);
return(0);
}



// ------------------------eeprom ----------------------------
void config_read()
{
config_status=EEPROM.read(CONFIG_EEPROM_ADDR);
#if defined(DEBUG)
Serial.print("CFG :");
Serial.println(config_status);
#endif
}


// ----------------------------------BTS 1 ------------------------
void bts1_Idle_Wait()
{
unsigned long ttn;

Bts1Serial.listen();
ttn=millis()+500;

#if defined (EMUL)
can_Idle1=1;
#endif

while((can_Idle1==0)&&(millis()<ttn)) 
  {
  bts1_ReceivedPrint();
  button_Delay(10);  // en SPC, réponse en 30ms environ (req simple)
  }
 
#if defined(DEBUG)
if (can_Idle1 ==0)
  {
  Serial.print(F("TO   1:"));
  Serial.print(millis());Serial.print(":");
  Serial.println(F("Idle1 wait TIMEOUT"));
  }
#endif

}


void bts1_Send(String commande)
{

Bts1Serial.listen();

bts1_Idle_Wait();


#if defined(DEBUG_SEND1)
Serial.print(F("Envoi1:"));
Serial.print(millis());Serial.print(":");
Serial.println(commande);
#endif


#if defined (BTS1)
Bts1Serial.print(commande);
Bts1Serial.print("\r");
Bts1Serial.flush();
#endif
can_Idle1=0;

bts1_Idle_Wait();

}



void bts1_ReceivedPrint()
{
char recvChar;


#if defined(BTS1)
Bts1Serial.listen();

while(Bts1Serial.available())
  {
  recvChar = Bts1Serial.read();
  if((recvChar=='\n')||(recvChar=='\r'))
    {
    if (can_LastResp1.length()>1)
      {
#if defined(DEBUG_RECV1)
      Serial.print(F("Recep1:"));Serial.print(millis());Serial.print(":");Serial.println(can_LastResp1);
#endif
      can_ATMA_decode();
#if defined(RLI)
      can_RLI_decode();
#endif
      can_Resp1=can_LastResp1;
      }
    can_LastResp1="";
    can_ATMA_Stop_Test();      // teste ATMA
    button_Test();
    if (button_Action()!=0)
      return;
    } // fin CR-LF
  else
  if (recvChar=='>')
    can_Idle1=1;
  else
    can_LastResp1+=recvChar;    
  }
 #endif // BTS

}


// ----------------------------------BTS 2 ------------------------

void bts2_Idle_Wait()
{
#if defined(BTS2)
unsigned long ttn;

Bts2Serial.listen();
ttn=millis()+bts2_init_tt;

#if defined (EMUL)
can_Idle2=1;
#endif

while((can_Idle2==0)&&(millis()<ttn)) 
  {
  bts2_ReceivedPrint();
  button_Delay(25);  // en SP3, réponse en 200ms environ
  if (button_Action()!=0)
      return;
  }
#if defined(DEBUG)
if (can_Idle2 ==0)
  {
  Serial.print(F("TO   2:"));
  Serial.print(millis());Serial.print(":");
  Serial.println(F("TIMEOUT"));
  }
#endif

#endif
}


void bts2_Send(String commande)
{
#if defined (BTS2)

Bts2Serial.listen();

bts2_Idle_Wait();

#if defined(DEBUG_SEND2)
Serial.print(F("Envoi2:"));
Serial.print(millis());Serial.print(":");
Serial.println(commande);
#endif

Bts2Serial.print(commande);
Bts2Serial.print("\r");
Bts2Serial.flush();
can_Idle2=0;

bts2_Idle_Wait();

#endif

}



void bts2_ReceivedPrint()
{
#if defined(BTS2)

char recvChar;
Bts2Serial.listen();
while(Bts2Serial.available())
  {
   recvChar = Bts2Serial.read();
    if((recvChar=='\n')||(recvChar=='\r'))
     {
     if (can_LastResp2.length()>1)
       {
#if defined(DEBUG_RECV2)
     Serial.print(F("Recep2:"));
     Serial.print(millis());Serial.print(":");
     Serial.println(can_LastResp2);
#endif
     
#if defined(SP3)
          can_SP3_decode();
#endif
      can_Resp2=can_LastResp2;
       } // end len >1
   can_LastResp2="";     
     } // fin CR-LF
     else
     if (recvChar=='>')
       can_Idle2=1;
   else
    can_LastResp2+=recvChar;    
  }

#endif
}




// ------------------------- MFD Display  ---------------------
// Afficheur du Tableau de bord

void MFD_Init()
{
bts1_Send(F("ATSH525"));
bts1_Send(F("002B03"));

bts1_Send(F("ATSH540"));
bts1_Send(F("00A7B2"));

bts1_Send(F("ATSH545"));
bts1_Send(F("4703F40002"));

}



void MFD_buftmp_Init2(String str)
{

for(i=0;i<=8;i++)
  MFD_buftmp[i]=0;
str.toCharArray(MFD_buftmp,8);
}



void MFD_Display_Long()
{
byte i;

i=0;
MFD_Display(MFD_string.substring(i,min(MFD_string.length(),i+8)));

button_Delay(300);

if (button_Action()!=0)
  return;

while((MFD_string.length()-i)>7)
  {
  MFD_Display(MFD_string.substring(i,min(MFD_string.length(),i+8)));
  i++;
  button_Delay(200);
  if (button_Action() !=0)
    return;
  }
button_Delay(500);

}



void MFD_buf8_6_convert()
{

for (i=0;i<8;i++)
{
  if ((MFD_buf8[i]>='0')&&(MFD_buf8[i]<='9'))
    MFD_buf8[i]-=47;
  else if ((MFD_buf8[i]>='A')&&(MFD_buf8[i]<='Z'))
    MFD_buf8[i]-=53;
  else if (MFD_buf8[i]==' ')
    MFD_buf8[i]=40;
  else if (MFD_buf8[i]=='.')
    MFD_buf8[i]=11;
  else if (MFD_buf8[i]==':')
    MFD_buf8[i]=58;
  else if (MFD_buf8[i]=='-')
    MFD_buf8[i]=57;
  else if (MFD_buf8[i]=='*')
    MFD_buf8[i]=61;
  else if (MFD_buf8[i]=='/')
    MFD_buf8[i]=59;
  else if (MFD_buf8[i]=='#')
    MFD_buf8[i]=60;
  else                // valeur par défaut
    MFD_buf8[i]=60; 
}

MFD_buf6[0]=(MFD_buf8[0]<<2)+((MFD_buf8[1]&0xF0)>>4);
MFD_buf6[1]=((MFD_buf8[1]&0x0F)<<4)+((MFD_buf8[2]&0xFC)>>2);
MFD_buf6[2]=((MFD_buf8[2]&0x03)<<6)+MFD_buf8[3];

MFD_buf6[3]=(MFD_buf8[4]<<2)+((MFD_buf8[5]&0xF0)>>4);
MFD_buf6[4]=((MFD_buf8[5]&0x0F)<<4)+((MFD_buf8[6]&0xFC)>>2);
MFD_buf6[5]=((MFD_buf8[6]&0x03)<<6)+MFD_buf8[7];
 
}



void MFD_Display(String str)
{
byte i;

#if defined(DEBUG)
Serial.print("MFD dsp:");
Serial.print(millis());Serial.print(":");
Serial.println(str);
#endif

bts1_Send(F("ATSH565"));
 
str[8]=0;
MFD_strg=str;
for(i=str.length();i<8;i++)
  MFD_strg+=' ';

MFD_strg.toCharArray(MFD_buf8,MFD_strg.length()+1);
MFD_buf8_6_convert();

for(i=0;i<6;i++)
     {
#if defined(DEBUG__)
   if ((byte)MFD_buf6[i]<16)
        Serial.print('0');
   Serial.print((unsigned char) MFD_buf6[i],HEX);
   Serial.print(' ');
#endif
   if ((byte)MFD_buf6[i]<16)
      Bts1Serial.print('0');
   Bts1Serial.print((unsigned char) MFD_buf6[i],HEX);
//xxx   Bts1Serial.print(' ');
   }

#if defined(DEBUG__)
  Serial.println(' ');
#endif
Bts1Serial.print("\r"); // xxx
Bts1Serial.flush();
can_Idle1=0;
bts1_Idle_Wait();

}




// ------------------ CAN MFD ---------------------
// Affiche sur le MFD selon l'état de l'automate

void can_MFD_Affiche(byte MFD_Affiche_status)
{
if (button_Status==1)
  return;
 
if ((MFD_Affiche_status ==status_GEAR) || (can_GearShift>1))
 {
  MFD_buftmp_Init2("VT:");        // Affiche la vitesse courante
  if (can_Gear !=99)
    dtostrf(can_Gear,1,0,&MFD_buftmp[3]);   
  if (can_GearShift>1)      //Couple et puissance sont ok
  {
    MFD_buftmp[4]=' ';
    MFD_buftmp[5]='-';
    MFD_buftmp[6]=' ';
    dtostrf(can_Gear+1,1,0,&MFD_buftmp[7]);   // Affiche vitesse N+1 si pertinente (%couple et %puissance)
  }
}
else
if (MFD_Affiche_status ==status_VBAT)
  {
  MFD_buftmp_Init2("BAT:");
  dtostrf(can_Vbat,4,1,&MFD_buftmp[4]);   
  }
else if (MFD_Affiche_status ==status_SPEED)
  {
  MFD_buftmp_Init2("V:");
  dtostrf(can_EngineSpeed,3,0,&MFD_buftmp[2]);
  dtostrf(can_EngineAcceleration,3,0,&MFD_buftmp[5]);      
  }
else
if (MFD_Affiche_status ==status_PARCOURS)
 {
    dlg_subStatus++;
  if (dlg_subStatus==5)
    dlg_subStatus=0;
  if (dlg_subStatus==0)
    {
    MFD_buftmp_Init2("C:");
    dtostrf(mm_ratio*consTotal,4,1,&MFD_buftmp[2]);
    MFD_buftmp[6]='L';
    }
  else
  if (dlg_subStatus==1)
    {
    MFD_buftmp_Init2("KM:");
    dtostrf((can_km2-can_km1),4,1,&MFD_buftmp[3]);
    }
  else
  if (dlg_subStatus==2)
    {
    MFD_buftmp_Init2("L/C:");
    if (can_km2 >can_km1)
      {
      dtostrf(mm_ratio*consTotal*100.0/(can_km2-can_km1),4,1,&MFD_buftmp[4]);
      } 
    }
  else
  if (dlg_subStatus==3)
    {
    MFD_buftmp_Init2("CO2:");
    if (can_km2 >can_km1)
      dtostrf(CO2_RATIO*mm_ratio*consTotal*100.0/(can_km2-can_km1),3,0,&MFD_buftmp[4]);
    }
  else
  if (dlg_subStatus==4)
    {
    MFD_buftmp_Init2("DUR.:");
    dtostrf((int) (mm_ratio*(consTotal_tt-consTotal_00)/1000.0/60.0),3,0,&MFD_buftmp[5]);
    }
 }
else
if (MFD_Affiche_status ==status_FUEL)
 {
    dlg_subStatus++;
  if (dlg_subStatus==2)
    dlg_subStatus=0;
  if (dlg_subStatus==0)
    {
    MFD_buftmp_Init2("FUEL:");
    dtostrf(can_FuelLevel,2,0,&MFD_buftmp[5]);
    }
  else
  if (dlg_subStatus==1)
    {
    MFD_buftmp_Init2("T:");
    dtostrf(can_EngineTemp,2,0,&MFD_buftmp[2]);
    }
 }
else
if (MFD_Affiche_status ==status_TEMPI)
 {
  dlg_subStatus++;
  if (dlg_subStatus==2)
    dlg_subStatus=0;
  if (dlg_subStatus==0)
  {
  MFD_buftmp_Init2("SO:");
  dtostrf(can_CC_Lrad+can_CC_Rrad,4,0,&MFD_buftmp[3]);   // ensoleillement
  }
  else
  {
  MFD_buftmp_Init2("TI:");
  dtostrf(can_IntTemp,2,0,&MFD_buftmp[3]);
  }
 }
else
if (MFD_Affiche_status ==status_CONSH)
 {     
  MFD_buftmp_Init2("L/X:");

  if (can_EngineSpeed ==0)
    {
     MFD_buftmp[2]='H';  // Affiche conso horaire sur la vitesse est nulle
     dtostrf(can_EngineConsH,4,1,&MFD_buftmp[4]);
    }
  else                // Affiche consommation aux 100km si vitesse non nulle.
    {
    cons100=100*can_EngineConsH/can_EngineSpeed;
    MFD_buftmp[2]='C';
    dtostrf(cons100,4,1,&MFD_buftmp[4]);
    }
  }
else
if (MFD_Affiche_status ==status_BOOST)
 {
  MFD_buftmp_Init2("TRB:");
  dtostrf(can_EngineBoost,4,1,&MFD_buftmp[4]);
  }
else
if (MFD_Affiche_status ==status_EGR)
  {
  MFD_buftmp_Init2("EGR:");
  dtostrf(can_EGR,3,0,&MFD_buftmp[4]);   
  }
else
if (MFD_Affiche_status ==status_LOAD)
  {
  MFD_buftmp_Init2("L");
  dtostrf(can_EngineLoad,3,0,&MFD_buftmp[1]);   
  if ((can_Gear >0)&&(can_Gear<6))
    { 
    MFD_buftmp[4]=' ';
    dtostrf(load2,3,0,&MFD_buftmp[5]);
    }
  if (can_GearShift>1)      //Couple et puissance sont ok depuis 2 valeurs
    MFD_buftmp[1]='*';
  }
else
if (MFD_Affiche_status ==status_POWER)
 {
  MFD_buftmp_Init2(" ");              // Puissance en CH
  dtostrf(can_EngineP*1.36,3,0,&MFD_buftmp[1]);
  MFD_buftmp[4]=' ';
  dtostrf(can_EngineC,3,0,&MFD_buftmp[5]);
  }
else
#if defined(DTC)
if (MFD_Affiche_status ==status_DTC)
  {
  MFD_buftmp_Init2("");
  MFD_Display_Long();
  }
else
#endif
if (MFD_Affiche_status ==status_SETUP)
 {
  dlg_subStatus++;
  if (dlg_subStatus==5)
    dlg_subStatus=0;

  if (dlg_subStatus==0)
    MFD_buftmp_Init2("EXIT");
  else
  if (dlg_subStatus==1)
    {
    MFD_buftmp_Init2("ALOCK:");
    dtostrf(((config_status & CONFIG_AUTOLOCK_MASK)==CONFIG_AUTOLOCK_MASK),1,0,&MFD_buftmp[6]);   
    }
  else
  if (dlg_subStatus==2)
    {
    MFD_buftmp_Init2("SWEEP:");
    dtostrf(((config_status & CONFIG_SWEEP_MASK)==CONFIG_SWEEP_MASK),1,0,&MFD_buftmp[6]);
    }
   else
   if (dlg_subStatus==3)
    {
    MFD_buftmp_Init2("MIL RST");
    }
   else
   if (dlg_subStatus==4)
    {
    MFD_buftmp_Init2("DTC RST");
    }
  }
if (MFD_buftmp[0]!='\0')
  MFD_Display(MFD_buftmp);
}




//  ------------------------ CAN Cmdes ---------------------


void can_SPC_init()    // Init bus can
{
bts1_Send("ATZ");
if (can_Idle1!=1)
   bts1_Idle_Wait();
if (can_Resp1.substring(0,3)!="ELM")
  {  // init KO
#if not defined(EMUL)
  resetFunc();
#endif
  }

bts1_Send(F("ATE0"));
bts1_Send(F("ATSPC"));
bts1_Send(F("ATS1"));    //mets les espaces
bts1_Send(F("ATH1"));    // header + PCI
bts1_Send(F("ATL1"));    // Line feed :on
bts1_Send(F("ATCAF0"));    // CAN auto_formatting off
bts1_Send(F("ATCFC1"));    //CAN Flow control
bts1_Send(F("ATAT1"));     // Set Adaptative timing Option
bts1_Send(F("ATST25"));    // Set timeout 25 (x4=100 ms)

MFD_Init();              // init ecran
}



//  ------------------------ CAN Cmdes : BODY ---------------------

void can_Body_startCommunication()
{
bts1_Send(F("ATSH7B0"));
bts1_Send(F("ATCRA7C0"));
bts1_Send(F("04021081"));    // Body
}

void can_Body_startCommunication89()
{
bts1_Send(F("ATSH7B0"));
bts1_Send(F("ATCRA7C0"));
bts1_Send(F("04021089"));    // Body
}

void can_Body_stopCommunication()
{
bts1_Send(F("040120"));
}

void can_Body_DTC_Read()
{
can_Body_startCommunication();
bts1_Send(F("04041800FF00"));
can_Body_stopCommunication();
}

void can_Body_DTC_Reset()
{
can_Body_startCommunication();
bts1_Send(F("040314FF00"));
can_Body_stopCommunication();
}

void can_Lock(byte b)    // Fermeture/ouverture portières
{
byte lock_nbTent=3;
// 7C3 F1 03 61 36 5A 00 00 00
if ((config_status & CONFIG_AUTOLOCK_MASK) !=CONFIG_AUTOLOCK_MASK)
  return;

can_Body_startCommunication();

while (lock_nbTent>0)
{
  if(b==1)  //lock
    {
    bts1_Send(F("0404301007FF"));
    bts1_Send(F("040430100700"));
    }
  else      // Unlock
    {
    bts1_Send(F("0404300F07FF"));
    bts1_Send(F("0404300F0700"));
    }

  if (can_Resp1.substring(10,12)==F("70"))    // reponse OK
    lock_nbTent=0;
  else
    lock_nbTent--;
}
can_Body_stopCommunication();
}


void can_Lock89(byte b)    // Fermeture/ouverture portières
{
byte lock_nbTent=3;
// 7C3 F1 03 61 36 5A 00 00 00

can_Body_startCommunication();
delay(200);
can_Body_startCommunication89();

while (lock_nbTent>0)
{
  if(b==1)  //lock
    {
    bts1_Send(F("0404301007FF"));
    bts1_Send(F("040430100700"));
    }
  else      // Unlock
    {
    bts1_Send(F("0404300F07FF"));
    bts1_Send(F("0404300F0700"));
    }

  if (can_Resp1.substring(10,12)==F("70"))    // reponse OK
    lock_nbTent=0;
  else
    lock_nbTent--;
}
can_Body_stopCommunication();
}



//  ------------------------ CAN Cmdes : CLIMATE CONTROL  ---------------------

void can_CC_RLI(String code)      // Climate Control
{
bts1_Send(F("ATSH7B0"));
bts1_Send(F("ATCRA7CA"));
bts1_Send(F("08021081"));
cmde=F("080221");
cmde+=code;
bts1_Send(cmde);
bts1_Send(F("080120"));

}


//  ------------------------ CAN Cmdes : DASHBOARD  ---------------------


void can_Dash_startCommunication()
{
bts1_Send(F("ATCRA7C3"));
bts1_Send(F("ATSH7B0"));
bts1_Send(F("85021081"));      // Start DiagSessio(10), defaultMode(81)
}

void can_Dash_stopCommunication()
{
bts1_Send(F("850120"));   // stop communication
}


void can_Sweep()      // sweep aiguilles
{
if ((config_status & CONFIG_SWEEP_MASK) !=CONFIG_SWEEP_MASK)
  return;

can_Dash_startCommunication();

for(i=72;i<=73;i++)
  {
    cmde=F("850430");
    cmde+=i;
    cmde+="07FF";
    bts1_Send(cmde);
}
delay(1000);
for(i=72;i<=73;i++)
  {
    cmde=F("850430");
    cmde+=i;
    cmde+="0700";
    bts1_Send(cmde);
  }
/*for(i=72;i<=73;i++)
  {
    cmde="850330";
    cmde+=i;
    cmde+="00";
    bts1_Send(cmde);
  }
*/
can_Dash_stopCommunication();

}


void MIL_RST()
{
can_Dash_startCommunication();

bts1_Send(F("85043B251388"));    // 3B : WriteDataByLocalIdentifier 5000 km
bts1_Send(F("850330B108"));   
// Reset service interval
// 30 : inputOutputControlByLocalIdentifier
// B1 : Local identifier
// 08 : Long term adjustement
can_Dash_stopCommunication();

}



//  ------------------------ CAN Cmdes : Broadcast  ---------------------

void can_Beep(byte n)
{
can_ATMA_Stop();
bts1_Send(F("ATSH388"));
while(n>0)
{
Bts1Serial.print((byte) (can_ExtTemp+40)*2,HEX);
Bts1Serial.print("0081");
Bts1Serial.print("\r");
Bts1Serial.flush();
can_Idle1=0;
bts1_Idle_Wait();
n--;
if (n!=0)
  button_Delay(200);
}
}


// ------------------------ ISO 9141 ------------------------

void can_SP3_init()    // Init KKL
{
#if defined(BTS2)
bts2_init_tt=3000;

bts2_Send("ATZ");

#if defined(EMUL)
can_Resp2=F("ELM327 V1.5");
#endif

if (can_Resp2.substring(0,3)=="ELM")
  {  // Init OK
#if defined(DEBUG)
  Serial.println("SP3 : Init : OK");
#endif
  }

bts2_Send("ATE0");
bts2_Send("ATS1");
bts2_Send("ATSP3");

delay(2000);
do
{
bts2_Send("0104");
#if defined(EMUL)
bts2_init=1;
#endif
}
while (bts2_init != 1);

bts2_init_tt=1000;



#endif
}


byte LastResp2Byte( byte idx)
{
return (hex2dec(can_LastResp2[idx])*16+hex2dec(can_LastResp2[idx+1]));
}


void can_SP35_init_decode()
{

if ((can_LastResp2.substring(0,8)==F("BUS INIT")) &&
    (can_LastResp2.indexOf("OK") != (-1)))
{
  bts2_init= 1;
#if defined(DEBUG)
Serial.println(F("BUS INIT OK 2"));
#endif
  return;
}
}


void can_SP3_decode()    // decode réponses KKL
{
#if defined(BTS2)
byte SP3_verb, B34, B67;

can_SP35_init_decode();

SP3_verb=LastResp2Byte(0);
B34=LastResp2Byte(3);
if (can_LastResp2.length()>7)
  B67=LastResp2Byte(6);


if (SP3_verb == 0x41)
  {
  if (B34==0x0B)              // MAP
    {
    can_EngineBoost=(B67-100.0)/100.0;
#if defined (DEBUG_VAL2)
Serial.print("BOOST:");
Serial.println(can_EngineBoost,2);
#endif
    }
  else
  if (B34==0x2C)    // EGR
    {
    can_EGR=B67*100/255;
#if defined(DEBUG_VAL2)
Serial.print("EGR:");
Serial.println(can_EGR,DEC);
#endif
    }
  else
  if (B34==0x04)    // LOAD
    {
    can_EngineLoad=B67*100/255;
    can_SP3_gear();
#if defined(DEBUG_VAL2)
Serial.print("LOAD:");
Serial.println(can_EngineLoad,DEC);
#endif
    }
  } 
#if defined(DTC)
else
if (SP3_verb==0x43)            // DTC Mode 3
  {
  MFD_string=F("DTC 3:");
  SP3_DTC_decode();
  }       
else
if (SP3_verb==0x47)            // DTC Mode 7
  {
  MFD_string=F("DTC 7:");
  SP3_DTC_decode();
  }           
#endif // DTC
#endif // bts2
}


byte DTC_append(unsigned int DTC_code)
{
String strl="PCBU";
byte DTC_prefix;

if (DTC_code ==0)
  return (0);
 
MFD_string+=" ";
DTC_prefix=(unsigned int) DTC_code>>14;
MFD_string+=strl[DTC_prefix];
MFD_string+=String(DTC_code & 0x3FFF,HEX);

return(1);
}

void SP3_DTC_decode()
{
#if defined(DTC)
byte i, found;

found=0;
for(i=0;i<3;i++)
    found+=DTC_append(hex2dec(can_LastResp2[3+6*i])*4096+hex2dec(can_LastResp2[4+6*i])*256+hex2dec(can_LastResp2[7+6*i])*16+hex2dec(can_LastResp2[7+6*i]));

if (found ==0)
  MFD_string +=F("NO DTC");
#endif
}


// ----------------------------- Getsion Rapports vitesses ------------------
byte enginePMax( int rpm)    // Puissance Max selon RPM. Valable pour JTDM 126cv
{
if (rpm<832)
  return (0.1);
else
if (rpm<3000)
  return((byte) (8+85.0*(rpm-832.0)/2168.0) );    // 3000-832
else
  return(93);
}

int engineCMax( int rpm)    // Couple max selon RPM. Valable pour JTDM 126cv
{
if (rpm<832)
  return (0.1);
else
if (rpm<2000)
  return((int) (100+205.0*(rpm-832.0)/1168.0) );    // 2000-832
else
if (rpm<2500)
  return(305);
else
  return((int) (305-65.0*(rpm-2500.0)/1500.0) );    // 4000-2500
 
}



void can_SP3_gear()    // calcul de la pertinence du rapport supérieur
{
byte gs;

if (can_EngineRPM !=0)
   can_GearR=can_EngineSpeed*1000.0/can_EngineRPM;
else
   can_GearR=0;

i=0;
while(i<=7)    // Recherche de la vitesse courante
  {
    if ((can_GearR >=gearTab[i]*0.8) &&(can_GearR<=(gearTab[i]*1.2)))
      break;
    i++;
  }
if (i<7)
  can_Gear=i;
else
  can_Gear=99;
 
// Calcul des puissances et couple courants
can_EngineP=enginePMax(can_EngineRPM)*can_EngineLoad/100;
can_EngineC=engineCMax(can_EngineRPM)*can_EngineLoad/100;

gs=0;
if ((can_Gear>0)&&(can_Gear<6))
  {
  rpm2=can_EngineRPM*gearTab[can_Gear]/gearTab[can_Gear+1]; 
  pmax2=enginePMax(rpm2);
  cmax2=engineCMax(rpm2);

  if (pmax2!=0)
    {
    load2=can_EngineC*100/cmax2;
    if ( (load2>40) // inf : eviter sous regime
       &&(load2<90)) // sup : avance le passage de vitesse
      gs=gs+1;
    load2=can_EngineP*100/pmax2;
    if ( (load2>30) // inf : eviter sous regime
       &&(load2<100)) // sup : avance le passage de vitesse
      gs=gs+2;
    }
   else
     load2=100;
  }

if (gs==3)
  can_GearShift+=1;
else
  can_GearShift=0;
   
#if defined(DEBUG_VAL2)
Serial.print("can Gear Ratio:");
Serial.println(can_GearR,2);
Serial.print("can Gear:");
Serial.println(can_Gear,DEC);
Serial.print("can Puissance:");
Serial.println(can_EngineP,DEC);
Serial.print("can pmax2:");
Serial.println(pmax2,DEC);
Serial.print("can Couple:");
Serial.println(can_EngineC,DEC);
Serial.print("can Cmax2:");
Serial.println(cmax2,DEC);
Serial.print("can load2:");
Serial.println(load2,DEC);
Serial.print("can rpm2:");
Serial.println(rpm2,DEC);
Serial.print("gear Shift:");
Serial.println(can_GearShift,DEC);
#endif

}


// -------------------------------------- RLI ----------------------------------

#if defined(RLI)

// décodage des trames CAN reçues, des différents modules
void can_RLI_decode()
{
byte B1617, can_RLI, can_verb;
unsigned int can_code2;

can_code2=LastResp1Code();
can_verb=LastResp1Byte(10);

if (can_LastResp1.length()>15)
  can_RLI=LastResp1Byte(13);

if (can_LastResp1.length()>17)
  B1617=LastResp1Byte(16);

// 7C3 F1 03 61 36 5A 00 00 00
//7C3 dashboard
//     F1 : Extra Address byte (F1=scantool)
//        03 : PCI : protocol information byte : Nombre de bytes.
//           61 : Réponse à 21 : lecture infos
#if defined(DTC)
if (can_code2==NODE_BODY)    // BODY
  {
  if ((can_verb==0x7F) &&
       (can_RLI==0x18))   // réponse à readDTC
    {
    MFD_string=can_LastResp1;
    }
  else
    if (can_verb==0x58)   // réponse à readDTC
    {
    MFD_string=F("DTC BODY :");
    SPC_DTC_decode();
    }
  }
else
#endif
/*
if (can_LastResp1.substring(0,3)==F("7C3"))    // dashboard
   {
   if (can_LastResp1.substring(13,15)==F("07"))   // RegulSpeed
      {
        if ((can_SpeedRegul!=B1617)&&(B1617==0xFF))
                      {
                        can_SpeedRegul_status=TRIGGER_DETECTED;
                        can_SpeedRegul=0xFF;
                      }
#if defined(DEBUG)
Serial.print(F("Regul:"));Serial.println(can_SpeedRegul);
#endif
      } // end 07
   else
   if (can_LastResp1.substring(13,15)==F("32"))   // OilLevel
      {
        can_EngineOilLevel=B1617;
        // can_EngineOilLevel_status=1;
#if defined(DEBUG)
Serial.print(F("OilLevel:"));Serial.println(can_EngineOilLevel);
#endif
      } // end 32
   else
   if (can_LastResp1.substring(13,15)==F("33"))   // Speed
      {
        can_EngineSpeed=(hex2dec(can_LastResp1[17])*256+hex2dec(can_LastResp1[19])*16+hex2dec(can_LastResp1[20]))*0.1;
         can_EngineSpeed_status=1;
#if defined(DEBUG)
Serial.print(F("EngSpeed:"));Serial.println(can_EngineSpeed);
#endif
      } // end 33
   else
   if (can_LastResp1.substring(13,15)==F("34"))   // Fuel
      {
          can_FuelLevel=B1617;
                can_FuelLevel_status=1;
#if defined(DEBUG)
Serial.print("Fuel:");Serial.println(can_FuelLevel);
#endif
       } // end 34
   else
   if (can_LastResp1.substring(13,15)==F("35"))   // RPM
      {
        can_EngineRPM=32*B1617;
         can_EngineRPM_status=1;
#if defined(DEBUG)    
Serial.print(F("EngRPM:"));Serial.println(can_EngineRPM);
#endif      
                } // end 35
   else
   if (can_LastResp1.substring(13,15)==F("36"))   // Engine Temp
      {
      can_EngineTemp=B1617-40;
            can_EngineTemp_status=1;
#if defined(DEBUG)
Serial.print(F("EngTemp:"));Serial.println(can_EngineTemp);
#endif
      } // end 36
   else
   if (can_LastResp1.substring(13,15)==F("3D"))   // Belt
      {
        if ((can_Belt==0xFF) && (B1617==0x00))
                    can_BeltOff_status=TRIGGER_DETECTED;
             can_Belt=B1617;
#if defined(DEBUG)    
Serial.print(F("Belt:"));Serial.println(can_Belt);
#endif      
                } // end 3D

   } //7C3
else
*/
if (can_code2==NODE_CC)      // Climate Control
   {
   if (can_RLI==0x31)   // Int Temp
      {
                can_IntTemp=LastResp1Byte(19)-40;
        //can_IntTemp_status=1;
#if defined(DEBUG_VAL1)
Serial.print(F("IntTemp:"));Serial.println(can_IntTemp);
#endif

      } // end 31
   else
        if (can_RLI==0x37)   // Radiation gauche
      {
                can_CC_Lrad=LastResp1Byte(16)*256+LastResp1Byte(19);
      }
   else
        if (can_RLI==0x38)   // Radiation droite
      {
                can_CC_Rrad=LastResp1Byte(16)*256+LastResp1Byte(19);
      }
        } // end 7CA

}

#endif // RLI


void SPC_DTC_decode()
{
byte dtc_nb;
//FC0 F1 05 58 01 D6 01 68 00
//             13 16 19   
dtc_nb=LastResp1Byte(13);
if (dtc_nb ==0)
  MFD_string +=F("NO DTC");
else
  {
  MFD_string+=dtc_nb;
  MFD_string+=" ";
  DTC_append(LastResp1Byte(16)*256+LastResp1Byte(19));
  }
}


// -------------------------------- ATMA --------------------

// démarrage du mode de lecture des informations CAN
void can_ATMA_Start(byte nb, byte mask)
{
bts1_Send("ATD");
bts1_Send("ATE0");
bts1_Send("ATAL");
bts1_Send("ATH1");

//bts1_Send("ATCRAFFF");
Bts1Serial.print(F("ATMA\r")); // pas via bts1_send, car pas d'acquittement de cette commande
Bts1Serial.flush();
#if defined(DEBUG)
Serial.print(F("Envoi1:"));Serial.print(millis());Serial.print(":");Serial.println(F("ATMA START"));
#endif

can_ATMA_Status=HIGH;
can_ATMA_Fill=0;
can_ATMA_Nb=nb;
can_ATMA_Mask=mask;
tt_can_ATMA_next=millis()+tt_can_ATMA_period;

}



void can_ATMA_Stop_Test()
{
#if defined(DEBUG__)
Serial.print("STOP TEST:");Serial.println(can_ATMA_Nb);
Serial.print(" ");Serial.print(can_ATMA_Mask);
Serial.print(" ");Serial.print(can_ATMA_Fill);
Serial.println();
#endif
if (can_ATMA_Status == LOW)
   return;
if ((can_ATMA_Fill & can_ATMA_Mask) == can_ATMA_Mask)
   {
   if (can_ATMA_Nb!=0)
      can_ATMA_Nb--;
   can_ATMA_Fill=0;
   }

if ((millis()>tt_can_ATMA_next)||(can_ATMA_Nb==0))
   can_ATMA_Stop();

}


void can_ATMA_Stop()
{

if (can_ATMA_Status == LOW)
   return;

can_ATMA_Status=LOW;
#if defined(DEBUG_SEND1)
Serial.print(F("Cntrol:"));
Serial.print(millis());Serial.print(":");
Serial.println(F("A ATMA stop"));
#endif
  Bts1Serial.print(F("A\r\n"));
  Bts1Serial.flush();
  can_Idle1=0;
  bts1_Idle_Wait();

}

byte LastResp1Byte( byte idx)
{
return (hex2dec(can_LastResp1[idx])*16+hex2dec(can_LastResp1[idx+1]));
}

unsigned int LastResp1Code()
{
return(hex2dec(can_LastResp1[0])*256+hex2dec(can_LastResp1[1])*16+hex2dec(can_LastResp1[2]));
}


void can_ATMA_decode()   
{
byte b_tmp;
byte can_len;
//String can_code;
unsigned int can_code2;

can_code2=LastResp1Code();
can_len=can_LastResp1.length();

if ((can_len==22) && (can_code2==0x180))
   {
   can_ATMA_Fill = can_ATMA_Fill | ATMA_180_MASK;
        can_Light=LastResp1Byte(7);
        }
else
if ((can_len==28) && (can_code2==0x380))
   {
   can_ATMA_Fill = can_ATMA_Fill | ATMA_380_MASK;
        //Serial.print("380 : ");Serial.println(can_LastResp1);
   //"380 20 00 48 4C 00 24 0D 00";
        b_tmp=LastResp1Byte(4);
     if ((b_tmp&0x20)==0x20)   // FreinAMain mis
            {
              if (can_FAM==0)
         can_FAMOn_status=TRIGGER_DETECTED;
         can_FAM=1;
            }
   else
           {
              if (can_FAM==1)
         can_FAMOff_status=TRIGGER_DETECTED;
              can_FAM=0;
           }
       
        b_tmp=LastResp1Byte(10);
     if ((b_tmp&0x04)==0x04)
            {
              if (can_ReverseGear==0)
         can_ReverseGearOn_status=TRIGGER_DETECTED;
          can_ReverseGear=1;
            }
   else
           {
              if (can_ReverseGear==1)
         can_ReverseGearOff_status=TRIGGER_DETECTED;
              can_ReverseGear=0;
           }
     
     
      can_Vbat=LastResp1Byte(13)*0.16;
      can_FuelLevel=LastResp1Byte(19);

#if defined(DEBUG_VAL1)
//   Serial.print(F("vbat:"));Serial.println((float)can_Vbat);
//   Serial.print(F("fuel:"));Serial.println(can_FuelLevel);
#endif
   }
else
if ((can_len==28) && (can_code2==0x281))
   {
   can_ATMA_Fill = can_ATMA_Fill | ATMA_281_MASK;

   //"281 00 80 C0 72 02 0F 19 00";
   // Regul : B2 ; RPM : B7 ; Temp : B4 ; FuelConsH:B5-B6 
     if (can_LastResp1.substring(8,9)=="2")
      {
        if (can_SpeedRegul==0)
                      {
                        can_SpeedRegulOn_status=TRIGGER_DETECTED;
                        tt_can_ATMA_next=0;
                      }
                   can_SpeedRegul=0xFF;
                }
   else
                {
        if (can_SpeedRegul==0xFF)
                      {
                        can_SpeedRegulOff_status=TRIGGER_DETECTED;
                        tt_can_ATMA_next=0;
                      }
                   can_SpeedRegul=0;
                }

  if ((can_EngineRPM ==0) && (LastResp1Byte(22) !=0)&&(can_km2 ==0))
    {
    can_km1=can_km2=0;
    consTotal=0;
    consTotal_00=millis();
    consTotal_tt=consTotal_00;
    }
   
  can_EngineRPM=32*LastResp1Byte(22);
  can_EngineTemp=LastResp1Byte(13)-40;
  can_EngineConsH=0.0022*(LastResp1Byte(16)*256+LastResp1Byte(19));
  consTotal+=can_EngineConsH*(millis()-consTotal_tt)/3600.0/1000.0;
  consTotal_tt=millis();
#if defined(DEBUG_VAL1)   
//Serial.print(F("RPM:"));Serial.println(can_EngineRPM);
//Serial.print(F("EngineTemp:"));Serial.println(can_EngineTemp);
//Serial.print(F("EngineConsH:"));Serial.println(can_EngineConsH);
#endif
   }
else
if ((can_len==28) && (can_code2==0x286))
   {
   can_ATMA_Fill = can_ATMA_Fill | ATMA_286_MASK;
   //"286 00 00 C0 72 02 0F 19 00";
   // Speed : B3-B4 
     can_EngineSpeed=(hex2dec(can_LastResp1[11])*256+LastResp1Byte(13))*0.0625;
        can_EngineSpeed_tt=millis();

        if (millis()>tt_can_acceleration)
          {
        tt_can_acceleration=millis()+500;   
        can_EngineAcceleration=(can_EngineSpeed-can_EngineSpeedLast)*1000.0/(can_EngineSpeed_tt-can_EngineSpeedLast_tt);
        can_EngineSpeedLast=can_EngineSpeed;
        can_EngineSpeedLast_tt=can_EngineSpeed_tt;
          }
#if defined(DEBUG_VAL1)   
//   Serial.print(F("Speed:"));Serial.println(can_EngineSpeed);
#endif
   }
else
if ((can_len==13) && (can_code2==0x388))
   {
   can_ATMA_Fill = can_ATMA_Fill | ATMA_388_MASK;

   //"388 6C 00 80";
   // Tempext : B1 
     can_ExtTemp=(LastResp1Byte(4))/2-40;
#if defined(DEBUG_VAL1)
//   Serial.print(F("TempExt:"));Serial.println(can_ExtTemp);
#endif
   }
else
if ((can_len==28) && (can_code2==0x6A3))
   {

   //"6A3 08 21 0F F9 0F F9 31 00";
   // km 0FF9 
     can_km2=(LastResp1Byte(10)*256+LastResp1Byte(13))/10.0;
        if (can_km1==0)
          can_km1=can_km2;
#if defined(DEBUG_VAL1)
//   Serial.print(F("TempExt:"));Serial.println(can_ExtTemp);
#endif
   }
#if defined(TADJ)
else
if ((can_len==16) && (can_code2==0x683))
  {     //"683 hh mm jj mm
  mmc=(hex2dec(can_LastResp1[4])*10+hex2dec(can_LastResp1[5]))*60+(hex2dec(can_LastResp1[7])*10+hex2dec(can_LastResp1[8]));
  if (mm2==0)
    mm2=mmc;  // 1ère valeur reçue
  else
  if (mmc>mm2)  // changement de minute
    {
    if (mm1==0)    // stockage de la référence
      {
      mm1=mmc;
      mm1_tt=millis();
      mm2=mmc;
      }
    else
      {
      mm2=mmc;
      mm_ratio=(mm2-mm1)*60.0*1000.0/(millis()-mm1_tt);
      }
    }
  } // end 683
#endif
}





// ---------------------BUTTONS ----------------

void button_Init()
{
button_Trigger= 0;
button_Status=0;
button_Duration=0;
}


void button_Test()
{
char bs;  //button_state

bs=digitalRead(BUT2_PIN);

if ((button_Status==0) && (bs==LOW))   //button:pressed
  {
  button_Status=1;
  button_tt=millis();
#if defined(DEBUG)
  Serial.print(F("Cntrol:"));
  Serial.print(millis());Serial.print(":");
  Serial.print(F("BUT2_pressed:"));
  Serial.println(button_Duration);
#endif
  }
else
if ((button_Status==1) && (bs==HIGH)) //button:released
  {
  button_Status=0;
  button_Trigger+=1;
  if (button_Duration ==0)
    button_Duration=millis()-button_tt;
#if defined(DEBUG)
  Serial.print(F("Cntrol:"));
  Serial.print(millis());Serial.print(":");
  Serial.print(F("BUT2_released:"));
  Serial.println(button_Duration);
#endif
  }
}


byte button_Action()
{
if ((button_Status==1) || (button_Trigger !=0))
  return(1);
else
  return(0); 
}


void button_Delay( unsigned int dur)      // delay avec test du bouton
{
unsigned long tt;
tt=millis()+dur;

while ((millis()<tt) && (button_Action()==0))
  button_Test();
}


// --------------------------------ACTIONS ----------------

void dlg_Action_Key()
{
if (vBtn == btnDOWN)
  {
     dlg_status+=vBtnNb;
     if (dlg_status>=DLG_NB)
       dlg_status-=DLG_NB;
  }
else
if (vBtn == btnUP)
  {
   if (dlg_status==0)
     dlg_status=DLG_NB-1;
   else
     dlg_status--;
  }
else
  return;

dlg_subStatus=0;

#if defined(DEBUG)
  Serial.print("DAK dlg_status:");
  Serial.println(dlg_status);
#endif       
}


void dlg_Action_Key_Test()
{
if (vBtn != btnUNDEF)
  {
#if defined(DEBUG)
  Serial.print("Action:");
  Serial.println(vBtn);
#endif
  can_ATMA_Stop();
  dlg_Action_Key();   
  vBtn=btnUNDEF;
  }
}   


void dlg_Action_Status()
{
byte atma_req_nb=0;

if ((millis()>tt_can_RLI_next)&& (can_ATMA_Status==LOW))
  {
#if defined (SP3)
if ((bts2_init>0) &&(millis()>6000))
  {
  if (bts2_protocol==5)
    {
            bts2_Send("2136");

      if ((can_EngineSpeed ==0) && (can_SpeedRegul !=0))
     bts2_Send("300C00");
       
      if (dlg_status==status_BOOST)
   bts2_Send("2138");
      else
      if (dlg_status==status_EGR)
   bts2_Send("2137");

    }
  else
    {
    bts2_Send("01 04"); // La charge est calculee tt le temps, pour determiner chgt vitesse

  if (dlg_status==status_BOOST)
   bts2_Send("01 0B");
  else
  if (dlg_status==status_EGR)
   bts2_Send("01 2C");
    }
  }
#endif
#if defined(DTC)
if (dlg_status==status_DTC)
  {
  if (dlg_subStatus==0)
    {
     bts2_Send("03"); // Mode 3 : Lecture DTC enregistrés
#if defined(EMUL)
     can_LastResp2="43 11 11 00 00 00 00";
     can_SP3_decode();
#endif
       }
     else if (dlg_subStatus==1)
       {
#if defined(EMUL)
        can_LastResp2="47 00 00 00 00 00 00";
        can_SP3_decode();
#endif
        bts2_Send("07"); // Mode 7 : Lecture DTC Temps réel
       }
     else if (dlg_subStatus==2)
       {
        MFD_string=F("DTC B");
        can_Body_DTC_Read();       // Mode can : Lecture DTC Body xxx
#if defined(EMUL)
        can_LastResp1=F("7C0 F1 05 58 01 D6 01 68 00");
        can_RLI_decode();
#endif
       }
       
  dlg_subStatus++;
  if (dlg_subStatus==3)
    dlg_subStatus=0;

    } // end DTC       
#endif // DTC

#if defined(RLI)
  if (dlg_status==status_TEMPI)
    {
   //can_RLI_ECU_DASHBOARD("32");       // OIL
   can_CC_RLI("31");               // int Temp
   can_CC_RLI("37");               // W/m2 Gauche
   can_CC_RLI("38");               // W/m2 Droite
    }
#endif

  tt_can_RLI_next=millis()+tt_can_RLI_period;   
  } // end delai


 
if (can_ATMA_Status==LOW)
  {
  can_MFD_Affiche(dlg_status);

  if ((dlg_status==status_SETUP)||
      (dlg_status==status_DTC)||
      (dlg_status==status_TEMPI)||
      (dlg_status==status_FUEL))
    atma_req_nb=25;
  else
    atma_req_nb=6;   
  can_ATMA_Start(atma_req_nb,ATMA_281_MASK);
  } //end atma_status_low
}





void dlg_Action_Post()
{

#if defined(BTS2)
if (bts2_init==0)   // bts2 non initialise
{             // on n'initialise que lorsque démarré, pour laisser priorité au bus CAN
  if ((can_EngineSpeed>10)||
   (millis()>3000))
      {
       if (tt_SP3_next>millis())
         return;
       tt_SP3_next=millis()+tt_SP3_period;
         can_SP3_init();
      }
}
#endif


if (button_Trigger!=0)
  {
    if (button_Duration>3000)          // Appui long : Reset
      {
       if (dlg_status==status_SETUP)
        {
        can_Beep_nb=2;
       if (dlg_subStatus==1)
         {
         config_status=config_status ^CONFIG_AUTOLOCK_MASK; 
         EEPROM.write(CONFIG_EEPROM_ADDR,config_status);
         }
        else if (dlg_subStatus==2)
          {
          config_status=config_status ^CONFIG_SWEEP_MASK;
          EEPROM.write(CONFIG_EEPROM_ADDR,config_status);
          }
        else if (dlg_subStatus==3)
          {
          can_ATMA_Stop();
          MIL_RST();
          MFD_Display(F("MIL RST*"));
          }
        else if (dlg_subStatus==4)
          {
          bts2_Send("04");
          can_ATMA_Stop();
          can_Body_DTC_Reset();
          MFD_Display(F("DTC RST*"));
          }
         
        } // end status_setup
      else
        resetFunc();
      }
    else
    if (button_Duration>500)                  // Appuis mi-long : Menu-1
      {
      vBtn=btnUP;
      }
    else
      {                                                  // Appui rapide : Menu+1
      vBtn=btnDOWN;
      vBtnNb=button_Trigger;
      }
  button_Init();
  }
       

if (can_SpeedRegulOn_status ==TRIGGER_DETECTED)
  {
#if defined(SRA)
  vBtn=btnDOWN;
  vBtnNb=1;
#endif
  can_SpeedRegulOn_status=TRIGGER_PROCESSED;
 
  }
 
if (can_SpeedRegulOff_status ==TRIGGER_DETECTED)
  {
  can_SpeedRegulOff_status=TRIGGER_PROCESSED;
  }

if (can_FAMOff_status == TRIGGER_DETECTED)
  {
  can_ATMA_Stop();
  can_Lock(1);
  can_FAMOff_status = TRIGGER_PROCESSED;
  }

if (can_FAMOn_status == TRIGGER_DETECTED)
  {
  can_ATMA_Stop();
  can_Lock(0);  // Unlock
  can_FAMOn_status = TRIGGER_PROCESSED;
  }


if (can_Beep_nb !=0)
  {
  can_Beep(can_Beep_nb);
  can_Beep_nb=0;
  }

}





// ------------------------------------ LOOP -----------------


void loop()
{
#if defined(EMUL)
  delay(500);
#endif

bts1_ReceivedPrint();
//bts2_ReceivedPrint();    // utile ?

can_ATMA_Stop_Test();      // teste ATMA
button_Test();
dlg_Action_Key_Test();

dlg_Action_Status();        // Actions du statut
dlg_Action_Post();          // traite les evenements
} // end loop
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
MiKL



Inscrit le: 11 Déc 2003
Messages: 29056
Localisation: Les Hauts de Cergy Val d'Oise France

MessagePosté le: 20 Mai 2015 23:24    Sujet du message: Répondre en citant

et ben il y a des motivés ici ;-) cool cool cool
_________________
Golf GTE + 147 selespeed Ti et 156 GTA de Deydey ;-)
EX : Giulietta 1.4 MultiAir TCT Executive Rouge Alfa TOE Panoramique Duplex O--O Ragazzon H2 Vrooom
Ex : 159 SW 2.4 JTD Selective (Dist. Corporate) reprog/Défap/EGR out
EX : 147 T.S. 150 Selespeed Select. Noire Cuir rouge 17' Supersport Nav+ TOE CSC Radar Recul 6000°K et 4 Koni FSD ;-)
EX : 147 T.S. 120 Dist. Bleu Inca Int. cuir gris CSC
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur MSN Messenger
skyglider



Inscrit le: 10 Aoû 2012
Messages: 453

MessagePosté le: 21 Mai 2015 00:54    Sujet du message: Répondre en citant

J'adore ce topic, bravo pour le boulot en tout cas cool .
M'y connaissant un tout petit peu dans le milieu je pourrais reprendre tout ça pour l'adapter sur la mienne, car ça m'intéresserait énormément de contrôler l'affichage, mais je ne suis pas fan sur le fait de rajouter des composants comme ça dans le véhicule. L'idéal aurait été de pouvoir programmer tout ça en branchant son pc sur l'odb ^^
A quand un véhicule qui permettra de paramétrer soit même tout ça :O ça ne leur coûte pas grand chose de rajouter toutes ces fonctions ^^

En tout cas j'ai hâte de voir la suite :p
_________________
147 1,6TS 120 distinctive 2003
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
CocoNat's



Inscrit le: 30 Mai 2014
Messages: 380
Localisation: Oise

MessagePosté le: 21 Mai 2015 08:47    Sujet du message: Répondre en citant

Volkswagen propose énormément de fonctions inactives via VAG-COM.
Notamment de fermer les vitres et toit ouvrant si le capteur de pluie détecte de la pluie, même voiture fermée...
C'est pas tout paramétrer, mais c'est déjà plus complet.
_________________

Alfa Romeo 147 (vendue)
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
skyglider



Inscrit le: 10 Aoû 2012
Messages: 453

MessagePosté le: 21 Mai 2015 11:06    Sujet du message: Répondre en citant

Mais ça manque de charme les VW je trouve :( bien que niveau qualité/prix ce sont peut-être les meilleurs.
_________________
147 1,6TS 120 distinctive 2003
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
CocoNat's



Inscrit le: 30 Mai 2014
Messages: 380
Localisation: Oise

MessagePosté le: 21 Mai 2015 11:22    Sujet du message: Répondre en citant

Je suis d'accord, un peu trop "banale" avec un style germanique un peu triste.
Pour autant, belles performances et qualité au Rendez-vous, on est d'accord !
_________________

Alfa Romeo 147 (vendue)
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
Arthur_035



Inscrit le: 11 Nov 2007
Messages: 182
Localisation: 35

MessagePosté le: 31 Mai 2015 17:43    Sujet du message: Répondre en citant

une solution industrielle intéressante : http://www.xee.com/boitier/
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
grise147



Inscrit le: 14 Oct 2007
Messages: 8762
Localisation: TOULOUSE !

MessagePosté le: 09 Sep 2015 00:46    Sujet du message: Répondre en citant

je relance le sujet

car , ca y est, j ai une 147 !! enfin !!

Arthur, peux tu faire un petit recap des "option" rajoutée par tes soins ? (par ex, pression turbo, etc .. )

car ce dernier en cas de grosse reprog, j en ai besoin razz
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
Arthur_035



Inscrit le: 11 Nov 2007
Messages: 182
Localisation: 35

MessagePosté le: 10 Sep 2015 22:38    Sujet du message: Répondre en citant

sur les PID standard, j'ai extrait : capteur pression turbo (0B), recyclage EGR (2C) et niveau de charge (04).
ex : 01 0B retourne la pression d'air.
Pour savoir ceux qui sont disponibles, il faut lancer 01 00, 01 20, 01 40 ... et décoder
C'est décrit ici : https://en.wikipedia.org/wiki/OBD-II_PIDs

La mienne (JTDM 126cv) retourne
983B0011
A0122001
80C00000

tel que décrit ici : http://www.outilsobdfacile.com/vehicle-list-compatible-obd2/alfa-romeo.


les autres infos, proviennent du bus can confort, donc concernent moins les fonctions fines de gestion moteur.
On a quand même : consommation instantanée, rpm, température d'eau, ...
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
grise147



Inscrit le: 14 Oct 2007
Messages: 8762
Localisation: TOULOUSE !

MessagePosté le: 11 Sep 2015 08:15    Sujet du message: Répondre en citant

merci Arthur !

et est ce possible de créer une option "change lane" ca manque enormemment sur 147 razz
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
Montrer les messages depuis:   
Poster un nouveau sujet   Répondre au sujet    ALFA 147 France Index du Forum -> Divers Toutes les heures sont au format GMT + 2 Heures
Aller à la page Précédente  1, 2, 3, 4, 5, 6, 7  Suivante
Page 5 sur 7



 
Sauter vers:  
Vous ne pouvez pas poster de nouveaux sujets dans ce forum
Vous ne pouvez pas répondre aux sujets dans ce forum
Vous ne pouvez pas éditer vos messages dans ce forum
Vous ne pouvez pas supprimer vos messages dans ce forum
Vous ne pouvez pas voter dans les sondages de ce forum





ok