Cloner une télécommande Radio Fréquence (433MHz) – Part 2

Après avoir vu comment récupérer une trame émise par une télécommande Radio Fréquence je vais vous montrer comment remplacer la télécommande avec un raspberry Pi.

Montage pour envoi (simplisme)

Le montage est ultra simple, le VCC de l’emetteur vers le 3,3V du raspi, le GND de l’emetteur vers le GND du raspberry et enfin le port DATA de l’emetteur vers le port 17 du raspi.
Je remets ici le diagramme des ports GPIO et leur notation (tout du moins pour la version 2 du raspberry pi)

Diagramme du port GPIO pour le Raspberry Pi version 2

Diagramme du port GPIO pour le Raspberry Pi version 2

Programme Python pour envoi code

La librairie RPi.GPIO est nécessaire, elle est dans les dépots de la raspian, pour les autres distrib veuillez vous adresser auprès de sa communauté.

 apt-get install python-rpi.gpio

La doc de cette librairie est ici : http://pythonhosted.org/RPIO/rpio_py.html#ref-rpio-py

#!/usr/bin/python
# -*- coding: utf-8 -*-

import RPi.GPIO as GPIO
import time
import sys



class RF :
	
	tableau = { "AVIDSEN" : 
				{ "echantillonnage" : 44100,
				  "bits" : 
					{ 0 : [ [ 52, 0 ], [ 22, 1 ] ] ,
					  1 : [ [ 22, 0 ], [ 52, 1 ] ] },
				  "buttons" : 
					{ "1 ON"  : "011111111111100101101",
					  "1 OFF" : "011111111111100111100",
					  "2 ON"  : "011111111111110101111",
					  "2 OFF" : "011111111111110111110",
					  "3 ON"  : "011111111111111101110",
					  "3 OFF" : "011111111111111111111",
					  "4 ON"  : "011111111111100001111",
					  "4 OFF" : "011111111111100011110",
					  
					}
				}
			}
	
	paramBits = {}
	dataPin    = 17
	tempsPerdu = 0
	nb_retry   = 4
	# Nombre de secondes d'attente entre deux retry
	attenteEntrePaquets = 0.075
	
	def __init__(self, dataPin ):
		self.dataPin = dataPin
		GPIO.setwarnings(False) 
		GPIO.setmode(GPIO.BCM)
		GPIO.setup(self.dataPin, GPIO.OUT)

	def sendDataPulse( self, dataPin, duration, value ):
		if value == 1 :
			GPIO.output(dataPin, GPIO.HIGH)
		else:
			GPIO.output(dataPin, GPIO.LOW)
		time.sleep( duration )

	def send( self, marque, button ):
		
		# Précalcul les attentes pour chaque type de bits
		for valeur in range(0, 2):
			self.paramBits[ valeur ] = [] 
			for paramBit in self.tableau[marque]["bits"][valeur]:
				tempsAttente  = 1.0 * ( paramBit[0] - self.tempsPerdu) / self.tableau[marque]["echantillonnage"]
				self.paramBits[valeur].append( [ tempsAttente , paramBit[1] ] )
		
		self.sendDataPulse( self.dataPin, 0.01 , 0 )
		for i in range( 0, self.nb_retry ) :
			for bit in self.tableau[marque]["buttons"][ button ]:
				for paramBit in self.paramBits[ int( bit ) ]:
					self.sendDataPulse ( self.dataPin, paramBit[0], paramBit[1])
			self.sendDataPulse( self.dataPin, 0.01 , 0 )
			time.sleep( self.attenteEntrePaquets )
		self.sendDataPulse( self.dataPin, 0.01 , 0 )

	def __del__(self):
		GPIO.cleanup()

if __name__ == "__main__" :
	marque = "AVIDSEN"
	button = "1 ON"
	
	if len(sys.argv) > 2:
		marque = sys.argv[1]
		button = sys.argv[2] + " " + sys.argv[3]
	else :
		print "arguments incorrects :"
		print sys.argv[0] + " <marque> <id> <position>"
		sys.exit(1)

	rf = RF( 17 )
	rf.send( marque, button )

Quelques petites choses sont à adapter pour votre télécommande, j’ai essayé de les regrouper dans la variable « tableau » ( ouh que ce nom est mal choisi !).

tableau = { "AVIDSEN" : 

AVIDSEN est le petit nom de la télécommande, j’ai donné le nom de la marque, je n’ai aucune imagination pour les noms 😉

				{ "echantillonnage" : 44100,

Le taux d’échantillonnage utilisé dans Audacity est noté ici, les temps seront notés en « samples » (il est facil d’adapter cette partie pour mettre des secondes à la place, je me tâte d’ailleurs de mettre un nombre de µs à la place).

				  "bits" : 
					{ 0 : [ [ 52, 0 ], [ 22, 1 ] ] ,
					  1 : [ [ 22, 0 ], [ 52, 1 ] ] },

C’est la partie qui me dérange le plus, car partant de bases théoriques que je pensais sûres (un nombre de points sur un enregistrement Audacity), cela ne marchait pas. Le raspberry pi n’est pas capable d’attendre un nombre de µs fiable, l’attente de 55 samples était trop long, j’ai du descendre à 52 de façon empirique (et les autres valeurs aussi). En effet nous ne sommes pas sur un système temps réel, c’est à dire que le programme d’envoi n’est pas seul à tourner sur la machine, d’autres vont le ralentir et ce de façon non prédictive. Ajoutons à ça des lib pythons qui ne sont pas forcement aussi rapides que du C du coup j’espère que le service sera viable.

				  "buttons" : 
					{ "1 ON"  : "011111111111100101101",
					  "1 OFF" : "011111111111100111100",
					}

La trame capturée à l’aide d’Audacity est stockée ici, brute de fonderie. Je n’ai pas trouvé le logique entre le bouton ON et le bouton OFF, alors j’ai pris le parti de stocker la trame complète.

Pour utiliser ce programme il fonctionne en ligne de commande

 python RF.py "AVIDSEN" 1 ON 

, mais il est aussi possible de l’utiliser comme une librairie pour un autre programme python.

Comme d’habitude cet article est un travail empirique qui peut ne pas fonctionner chez les autres (en somme il est sous licence Demerdenzizich que les Anglo Saxon appelle As-Is)

La troisième partie concernera l’utilisation d’une télécommande Blyss avec un code roulant.

Publié le 8 juin 2014, dans DIY, Raspberry Pi, et tagué , , , . Bookmarquez ce permalien. 2 Commentaires.

  1. Super!! je viens d’essayer le script pour les prises avidsen ça marche super, merci pour le pour le travail et le tuto.

  2. Pour ta trame, les 8 derniers bits semblent être inversé 4 d’un sens et les 4 derniers dans l’autre, et le dernier des groupes de 4 bits est l’état 1 ou 0

Laisser un commentaire