Go Down

Topic: Arduino & ble TPMS (Capteur pression pneus) (Read 514 times) previous topic - next topic

savoriano

#15
May 18, 2019, 12:21 am Last Edit: May 18, 2019, 12:42 am by savoriano
Code: [Select]
 if (BTSerial.available())
  {
    //c = BTSerial.read();
    Serial.print(BTSerial.read(), HEX);
    //Serial.write(BTSerial.read());
  }
[code]
[/code]


Ce qu'il me donne en HEX:

4F 4B 2B 44 49 53 41 53 4F 4B 2B 44 49 53 41 3A AA 3 40 CA EA 83 0 AB 1B 2 1 5 3 3 B0 FB 13 FF 0 1 83 EA CA 40 3 AA B5 2E 0 0 FC 6 0 0 2F 0 D A
4F 4B 2B 44 49 53 41 3A AA 3 40 CA EA 83 0 AA E D 9 54 50 4D 53 34 5F 34 30 30 33 41 41 D A
4F 4B 2B 44 49 53 43 45 4F 4B 2B 44 49 53 41 3A 71 8E 34 F3 7B 98 0 B0 11 2 1 6 3 2 F0 FF 9 FF 1 7 98 7B F3 34 8E 71 D A
4F 4B 2B 44 49 53 41 3A 71 8E 34 F3 7B 98 0 B0 15 B 9 53 4D 50 2D 42 31 36 2D 46 52 5 12 10 0 10 0 2 A 0 D A
4F 4B 2B 44 49 53 41 3A AA 3 40 CA EA 83 0 C6 1B 2 1 5 3 3 B0 FB 13 FF 0 1 83 EA CA 40 3 AA B5 2E 0 0 FC 6 0 0 2F 0 D A
4F 4B 2B 44 49 53 41 3A AA 3 40 CA EA 83 0 C6 E D 9 54 50 4D 53 34 5F 34 30 30 33 41 41 D A

rouge = ADDR MAC
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

al1fch

#16
May 18, 2019, 07:41 am Last Edit: May 18, 2019, 08:24 am by al1fch
pas mal !!

ta routine semble eliminer les zéros non significatifs, tu as vu plus haut que l'adrese MAC est
83 EA CA 40 03 AA  et non  83 EA CA 40 3 AA

ci joint un debut de coloriage des trames

Les infos émises par le capteur TPMS  sont apparement distribuées sur des trames de divers types et non sur une longue trame de type unique (contrainte de taille des trames "Advertizing"), il pourrait  y avoir une trame pression , une trame température.... un octet dans chaque trame signalant en général son type.

Dans certaines trames l'adresse MAC figure aussi à l'envers
On voit aussi des chaines de caractères comme TPMS 4_003


Il se pourrait qu' entre les deux occurence de l'adresse MAC , se placent des entiers porteurs des infos utiles.
Ci dessous cette zone 'à fort potentiel'  dans deux  des trames reçues.
Pression et température s'y trouvent probablement de même que l'identifiant de chaque capteur



al1fch

#17
May 18, 2019, 08:15 am Last Edit: May 18, 2019, 08:56 am by al1fch
Lien : dans la réponse 1 figure un  exemple de codage TPMS. (je ne sais pas si c'est 'standard' )

Avec l'application dédié aux capteurs les valeurs de température et de pression sont connues  , reste à les trouver , codées sous une forme ou une autre

Penser aussi aux 4F 4B 2B 44 49 53 41   = " OK+DISA"  produits par le HM-10 après chaque trame reçue  et non par le capteur TPMS
                           
Pour ce genre d'investigation un terminal affichant côte à côte ASCII et hexa est utile (Cutecom dans mon cas) et puis bien entendu  l'incontournable application 'nRF Connect' sur smartphone (et les outils Bluetooth de Linux)



savoriano

Voici les trame filtrées et simplifiées:

AT+DISA: MAC(AA 03 40 CA EA 83) 00 BE 1B 02 01 05 03 03 B0 FB 13 FF 00 01 MAC(83 EA CA 40 03 AA) 2C 5B 00 00 A5 09 00 00 2F 00 0D 0A
AT+DISA: MAC(AA 03 40 CA EA 83) 00 BE 0E 0D 09 TPMS4_4003AA(54 50 4D 53 34 5F 34 30 30 33 41 41) 0D 0A
AT+DISA: MAC(AA 03 40 CA EA 83) 00 C4 1B 02 01 05 03 03 B0 FB 13 FF 00 01 MAC(83 EA CA 40 03 AA) 5D 52 00 00 9E 09 00 00 2F 00 0D 0A
AT+DISA: MAC(AA 03 40 CA EA 83) 00 C4 0E 0D 09 TPMS4_4003AA(54 50 4D 53 34 5F 34 30 30 33 41 41) 0D 0A
AT+DISA: MAC(AA 03 40 CA EA 83) 00 C3 1B 02 01 05 03 03 B0 FB 13 FF 00 01 MAC(83 EA CA 40 03 AA) F6 5D 00 00 85 09 00 00 2F 00 0D 0A
AT+DISA: MAC(AA 03 40 CA EA 83) 00 C3 0E 0D 09 TPMS4_4003AA(54 50 4D 53 34 5F 34 30 30 33 41 41) 0D 0A

Mes conclusions:
en rouge la pression: 2C 5B = 5B 2C = 23,340 psi en décimal
en vert la température: A5 09 = 09 A5 = 24.69 C° en décimal
Il y a aussi caché le niveau de la batterie! bleu jaune rose?
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

al1fch

#19
May 19, 2019, 09:28 pm Last Edit: May 19, 2019, 09:39 pm by al1fch
Gagné !

batterie 00 2F (rose) , pour 4,7V  ? (un peu élévé) mais le 2F est pourtant  bien placé après les deux autres donnénes.

Un lien SVP vers les capteurs utilisés pour permettre  de reproduire la manip ?

savoriano

#20
May 19, 2019, 10:05 pm Last Edit: May 19, 2019, 10:06 pm by savoriano
modèle VC601. je ne peux pas dire de plus. Acheté sur ebay le vendeur a retiré l'annonce.
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

al1fch


savoriano

Tu veux les acheter? moi je pensais que tu voulais seulement avoir des infos.
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

al1fch

#23
May 19, 2019, 11:14 pm Last Edit: May 20, 2019, 07:23 am by al1fch
Pas d'achat  prévu pour l'instant de mon côté , je pensais que l'info était nécessaire pour le fil de discussion.

Chacun peut voir quel modèle de capteur TPMS  BLE possède ce format de trame, en particulier le positionnement et le codage des infos 'pression' et 'température' que tu as trouvé.

Voilà une utilisation supplémentaire des HM-10 (voir le tutoriel HM-10  de J-M-L)
Ces capteurs TPMS envoient 'spontanément' les infos en "Advertizing' comme des balises, sans connection préalable et sans interogation par un terminal

savoriano

Une carte à ESP32 pourrait remplacer l'ensemble Mega + HM-10 .... (sous réserve que l'écran tactile actuel ne réclame pas trop de GPIO pour une ESP32)
Le choix une mega 256 est due parce que j'ai déjà travaille avec un TFT+ tactile et les libs dédié sont très volumineuse  donc 32Kb vont devenir très  vite insuffisante.
J'ai fait un thermostat avec une carte uno + tft + tactile + rtc + HC-SR04 et j'ai bataillé avec 32kb. J'ai du modifier la librairie de l'écran  pour faire rentrer tout ça.
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

savoriano

#25
May 21, 2019, 12:34 am Last Edit: Jun 02, 2019, 04:08 pm by savoriano
Je pense que le niveau de la batterie sont les données en rose: 002F = 47%

Le capteurs envoient les données au moins toutes les 3 minutes même si rien à changé sauf si la pression est à 0 !
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

savoriano

#26
May 22, 2019, 01:17 am Last Edit: May 22, 2019, 01:32 am by savoriano
Si ça peut intéresser à quelqu'un....

Code: [Select]
#include <SoftwareSerial.h>
String sTrama;
SoftwareSerial BTSerial(4, 5);
unsigned long lTimer = 0;
float fPneuPressAv, fPneuPressAr, fPneuTempAv, fPneuTempAr;
int iPneuBattAv, iPneuBattAr;

void setup() {
   Serial.begin(9600);
   BTSerial.begin(9600);
   Serial.println("ok");
   BTSerial.write("AT");
   delay(500);
   BTSerial.write("AT+RENEW");
   delay(1000);
   //Serial.println("1 ");
   //BTSerial.write("AT+NAME=Controller\r\n");
   BTSerial.write("AT+IMME1");
   delay(1000);
   lTimer = millis();
   BTSerial.write("AT+ROLE1"); //Simple pairing
}
 
void loop()
{
 
  long unsigned int c;
  char cDato[4];
  String sHex;
  if (BTSerial.available())//il y a quelque chose que le BT veut nous trasmettre?
  {
    sHex = String(BTSerial.read(), HEX);//lit le BT
    if (sHex.length() == 1) sHex = "0" + sHex;
    sTrama = sTrama + " " + sHex; //Crée la trame
    //Serial.println(trama);
    if (sTrama == " 4f 4b 2b 44 49 53 41 3a")
    {
      sTrama = ""; // efface "OK+DISA:"
    }
    if (sTrama.endsWith(" 0d 0a")) //fin de la trame
    {
      if (sTrama.startsWith(" ef 01 20 ca") || sTrama.startsWith(" 51 01 10 ca")) //cherche si la trame viens des capteurs
      { // Analise la trame
        if (sTrama.startsWith(" 51") && sTrama.length() > 80)//le capteur transmet 2 differentes trames
        { //Premier Capteur                                //seulement la plus longue nous interesse
          cDato[0] = sTrama.charAt(82);// Preds les char de la pression
          cDato[1] = sTrama.charAt(83);
          cDato[2] = sTrama.charAt(79);
          cDato[3] = sTrama.charAt(80);
          c = strtoul (cDato, 0, 16);//Converte HEX to DEC
          //Serial.println(b);
          //Serial.println(cDato);
          fPneuPressAv = c / 14.5 / 1000;//Converte la valeur de pression en BAR
          Serial.print(String(fPneuPressAv) + " BAR   ");
         
          cDato[0] = sTrama.charAt(94);// Preds les char de la Temperature
          cDato[1] = sTrama.charAt(95);
          cDato[2] = sTrama.charAt(91);
          cDato[3] = sTrama.charAt(92);
          c = strtoul (cDato, 0, 16);//Converte HEX to DEC
          //Serial.println(c);
          //Serial.println(cDato);
          fPneuTempAv = c / 100;//
          Serial.println(String(fPneuTempAv) + " C°");
        }

        if (sTrama.startsWith(" ef") && sTrama.length() > 80) //le capteur transmet 2 differentes trames
        {//Deuxiemme Capteur                                //seulement la plus longue nous interesse
          cDato[0] = sTrama.charAt(82);// Preds les char de la pression
          cDato[1] = sTrama.charAt(83);
          cDato[2] = sTrama.charAt(79);
          cDato[3] = sTrama.charAt(80);
          c = strtoul (cDato, 0, 16);//Converte HEX to DEC
          //Serial.println(b);
          //Serial.println(cDato);
          fPneuPressAr = c / 14.5 / 1000;//Converte la valeur de pression en BAR
          Serial.print(String(fPneuPressAr) + " BAR   ");
         
          cDato[0] = sTrama.charAt(94);// Preds les char de la Temperature
          cDato[1] = sTrama.charAt(95);
          cDato[2] = sTrama.charAt(91);
          cDato[3] = sTrama.charAt(92);
          c = strtoul (cDato, 0, 16);//Converte HEX to DEC
          //Serial.println(c);
          //Serial.println(cDato);
          fPneuTempAr = c / 100;//Converte la valeur de pression en BAR
          Serial.println(String(fPneuTempAr) + " C°");
        }
        //Serial.println("2: " + sTrama);
      }
      sTrama = "";//efface la trame
    }
  }
 
  if (lTimer + 3000 < millis()) //relance tous les 3 sec la commande "AT+DISA?"
  {
    BTSerial.write("AT+DISA?");
    lTimer = millis();
  }
}
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

savoriano

#27
Jun 02, 2019, 12:31 pm Last Edit: Jun 02, 2019, 03:15 pm by savoriano
Juste quelque précision pour comprendre:
Ça fait 3 jours que je travail sur un problème après l'intégration de ce code dans le programme final avec un écran TFT.
Ce que j'ai compris (a rectifier si c'est faut!):

Le module BT a un buffer ou stocke les octets à transmettre.
Si le buffer est plein est on ne le vide pas en lisant le buffer avec l'arduino, on peut perdre des données.
L'arduino lit les données plus vite que le module BT peut les  transmettre. Dons la valeur de "BTSerial.available()" peux passer a "-1" même si la trame n'est pas finie.
J'ai l'impression que des fois on perds des octets inexplicablement!!

J'ai remplacé
if (BTSerial.available())
Par
while (Serial2.available() > 0)

Le code modifié:
Code: [Select]
void CapteursPresion()
{
  long unsigned int c;
  char cDato[4];
  //sTrama = "";
  //String sHex;
  while (Serial2.available() > 0)//il y a quelque chose que le BT veut nous trasmettre?
  {
    c = Serial2.read();//lit le BT
    String sHex = String(c, HEX);
    if (sHex.length() == 1) sHex = "0" + sHex;
    sTrama = sTrama + " " + sHex; //Crée la trame
    //Serial.println(sTrama);
    //if (sTrama.length() > 100) Serial.println();
    //Serial.print(char(c));
    if (sTrama == " 4f 4b 2b 44 49 53 41 3a")
    {
      sTrama = ""; // efface "OK+DISA:"
    }
    if (sTrama.endsWith(" 0d 0a")) //fin de la trame
    {
      //Serial.println("");
      if (sTrama.startsWith(" ef 01 20 ca") || sTrama.startsWith(" 51 01 10 ca")) //cherche si la trame viens des capteurs
      { // Analise la trame
        if (sTrama.startsWith(" 51") && sTrama.length() > 100)//le capteur transmet 2 differentes trames
        { //Premier Capteur                                //seulement la plus longue nous interesse
          cDato[0] = sTrama.charAt(82);// Preds les char de la pression
          cDato[1] = sTrama.charAt(83);
          cDato[2] = sTrama.charAt(79);
          cDato[3] = sTrama.charAt(80);
          c = strtoul (cDato, 0, 16);//Converte HEX to DEC
          //Serial.println(b);
          //Serial.println(cDato);
          fPneuPressAv = c / 14.5 / 1000;//Converte la valeur de pression en BAR
          Serial.print(sTrama);
          Serial.print(String(fPneuPressAv) + " BAR   ");

          cDato[0] = sTrama.charAt(94);// Preds les char de la Temperature
          cDato[1] = sTrama.charAt(95);
          cDato[2] = sTrama.charAt(91);
          cDato[3] = sTrama.charAt(92);
          c = strtoul (cDato, 0, 16);//Converte HEX to DEC
          //Serial.println(c);
          //Serial.println(cDato);
          fPneuTempAv = c / 100;//
          Serial.println(String(fPneuTempAv) + " C°");
          tft.setCursor(0, 92);
          tft.println(" Pression pneu Av: " + String(fPneuPressAv) + " Bar  Temp:" + String(fPneuTempAv) + " C°");
        }

        if (sTrama.startsWith(" ef") && sTrama.length() > 80) //le capteur transmet 2 differentes trames
        { //Deuxiemme Capteur                                //seulement la plus longue nous interesse
          cDato[0] = sTrama.charAt(82);// Preds les char de la pression
          cDato[1] = sTrama.charAt(83);
          cDato[2] = sTrama.charAt(79);
          cDato[3] = sTrama.charAt(80);
          c = strtoul (cDato, 0, 16);//Converte HEX to DEC
          //Serial.println(b);
          //Serial.println(cDato);
          fPneuPressAr = c / 14.5 / 1000;//Converte la valeur de pression en BAR
          Serial.print(String(fPneuPressAr) + " BAR   ");

          cDato[0] = sTrama.charAt(94);// Preds les char de la Temperature
          cDato[1] = sTrama.charAt(95);
          cDato[2] = sTrama.charAt(91);
          cDato[3] = sTrama.charAt(92);
          c = strtoul (cDato, 0, 16);//Converte HEX to DEC
          //Serial.println(c);
          //Serial.println(cDato);
          fPneuTempAr = c / 100;//Converte la valeur de pression en BAR
          Serial.println(String(fPneuTempAr) + " C°");
          tft.setCursor(0, 112);
          tft.println(" Pression pneu Ar: " + String(fPneuPressAr) + " Bar  Temp:" + String(fPneuTempAr) + " C°");
        }
        //Serial.println("2: " + sTrama);
      }
      sTrama = "";//efface la trame
    }
  }
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

savoriano

 >:(
Arduino + TFT + Bleutooth pour les capteurs = ça marche.
J'ai ajouté le module GPS = problèmes.
Le BT utilise Serial2 et le GPS Serial3.
Je pense que le module GPS envoi tellement des données que l'arduino n'arrive pas à suivre car j'ai encore des pertes de données avec le BT!
Quelqu'un à une piste pour résoudre le problème?
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

savoriano

J'ai résolu en optimisant le code.
A quoi ressemble mon Ordinateur de bord version beta:

 
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

Go Up