EnOcean Partie 3: Premier test de réception

EnOcean Partie 3: Premier test de réception

Déchiffrage d’un paquet

J’ai réalisé le premier test simplement en appuyant sur un de mes interrupteurs et en écoutant ce qui arrivait sur le port série.

On va décoder la trame reçue, où plutôt les trames, il y en a deux, une pour l’appuie sur l’interrupteur, une pour le relâchement :

55 00 07 07 01 7A F6 30 00 34 BB E4 30 00 FF FF FF FF 2D 00 75

55 00 07 07 01 7A F6 00 00 34 BB E4 20 00 FF FF FF FF 2D 00 C3

D’après la documentation, voici l’architecture générale d’un paquet

 

Ce qui nous donne pour le premier paquet :

Bytes Description
55 Byte de synchronisation, toujours 55
00 07 Taille du télégramme du groupe Data (en bleu), soit 7 octets
07 Taille des données optionnelles (en vert), 7 octets également
01 Type de paquet, ici 1 = RADIO_ERP1
7A CRC8 Header (on va voir plus loin comment le calculer)
F6 Télégramme RPS
30 Données : un RPS contient un unique octet de données.
00 34 BB E4 ID de l’émetteur
30 Status
00 Sub tel Num
FF FF FF FF ID du destinataire (ici broadcast)
2D RSSI value
00 Niveau de sécurité
75 CRC8 Data

 

Maintenant on va déchiffrer la valeur de données du télégramme RPS : 30. J’ai fais mon test avec un interrupteur qui a pour EEP F6-02-01, ce qui dans la documentation donne :

30 en hexadécimal, se traduit par 00110000 en binaire.

bits Description
001 001 ça fait 1, donc le bouton A0 a été actionné
1 Ce bouton a été pressé
000 Par défaut, pas important car pas de seconde action
0 Pas de seconde action

 

Calcul du CRC

Il y a deux CRC : l’un pour la partie Header (en jaune) et l’autre pour la partie Data (en bleu et vert). Le byte de synchro n’entre pas dans le CRC.

La table servant de base au calcul du CRC est générée à partir du polynôme G(x) = x8 + x2 + x1 + x0. Elle est fournie dans la documentation.

uint8_t u8CRC8Table[256] = {
0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,
0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5,
0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85,
0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,
0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,
0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2,
0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32,
0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a,
0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c,
0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec,
0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,
0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,
0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c,
0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b,
0x76, 0x71, 0x78, 0x7f, 0x6A, 0x6d, 0x64, 0x63,
0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13,
0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb,
0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8D, 0x84, 0x83,
0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb,
0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3
};

Exemple de calcul du CRC à partir de cette table :

uint8_t EnOceanInterface::calcCrc(char* enOceanBuffer, uint16_t startIdx, uint16_t endIdx){
  uint8_t crc = 0;
  for (uint16_t idx = startIdx; idx <= endIdx; ++idx){
    crc = u8CRC8Table[(crc ^ enOceanBuffer[idx])];
  }
  return crc;
}

On va ensuite voir comment appairer plusieurs modules entre eux : EnOcean Partie 4: Appairage

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *