Échanges de données entre RPi et Atmega

Un billet pour mémoriser les techniques utilisées pour les échanges entre RPi et Atmega de ma carte de chauffage.

Les objectifs :
 1/ récupérer les 4 températures mesurées par l'ATmega
 2/ envoyer des ordres depuis RPi vers l'ATmega : M/A, En Chauffe, Marche Forcée, Eté/Hiver
 3/ recevoir les changements effectués sur la carte via les boutons de contrôle : M/A, En Chauffe, Marche Forcée
 4/ remonter l'alarme HPBP détectée par l'ATmega

Les 3 1er points sont traités par la liaison i2C, le 4ème est une liaison entre broches A0>G22

pour le câblage de l'i2C, se référer au schéma ci-près : carte_chauffage.pdf on y trouvera la connexion des broches SDA et SCL : A5-G03 et A4-G02 + une masse commune. Pour l'initialisation du bis i2c, v. 2018/10/10/communication-i2c-RPi-Arduino

format d'échange

La communication se fait octet par octet. C'est le RPi (maître) qui initie l'échange en envoyant un code et attend en retour la température attendue. Les températures sont envoyées sur 2 octets :

    - d'abord les 10ème de °C sur 4 bits de poids faibles et suite aux codes pairs (0,2,4,etc...)
    - puis les °C sur 8 bits faisant aux codes impairs (1,3,5,etc...)

les 4 bits de poids forts libres vont indiquer les différents états du chauffage : M/A MF EC EH/P

code 0 | Dans le sens RPi vers ATmega le 1er octet envoyé est : M/A MF EC EH 0 0 0 0 (état + code 0).

 > En retour l'ATmega renvoie  : M/A EF MF P X X X X  (état + 10ème de  T0).
 pour P=0, les états sont inchangés côté RPi.
 pour P=1, les états de l'ATmega sont prioritaires et pris en compte par le RPi.

code 1 | émis par le RPi, l'ATmega envoie T0, valeur entière de la température. code 2 | et 3 | : échanges de .T1 et T1. - code 4 | et 5| pour .T2 et T2, - etc.... La limite est de 8 température (code 0 à 15 : 4 bits).

méthode d'extraction des données

pour le code 0, il faut séparer les états des 10ème de °C de T0

 - les 4 bits de poids faibles sont extraits par masquage : X X X X T T T T & 0 0 0 0 1 1 1 1
 - les états sont extraits un à un, par un masque de 1 bit sur les valeurs 0x10, 0X20, 0X40 et 0X80

Les codes en Python : MA = not((code & 0x80)==0) # bit d'état MarcheArrêt MF = not((code & 0x40)==0) # bit d'état MarcheForcée EC = not((code & 0x20)==0) # bit d'état EnChauffe P = not((code & 0x10)==0) # bit de priorité pour la création du code :

       code = MA*0x80+MF*0x40+EC*0x20+EH*0x10	# construction de l'octet de pilotage

par convention : brochage ATmega

 A0..A5 : broches analogiques  
 D0..D13 : broches numériques

brochage RPi

 G0..G31 : broches GPIO

M/A : marche / Arrêt EC : en chauffe MA : marche forcée EH : été / hiver P : priorité