Archives de Catégorie: DIY

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.

Publicités

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

La domotique arrive de plus en plus dans nos foyers, depuis des années j’avais des prises commandées par radio fréquence mais je ne les utilisaient pas car la télécommande n’était pas assez puissante (et pourtant je n’ai pas un château 😦 ). De plus j’ai toujours trouvé inconfortable de chercher la télécommande a chance fois que je veux allumer la lumière (n’avez vous jamais remarqué la timidité de ces dernières ? La preuve elles adorent se cacher derrière les coussins 😉 )

Bref j’avais dans l’idée de cloner ces télécommandes, voir d’automatiser tout ça (avec des capteurs de présence, via des « crontab », via commande vocale, …).

Les télécommandes auxquelles j’ai décidé de m’attaquer sont basées sur la fréquence 433MHz.
Coté matériel, j’ai trouvé des kits émetteur + récepteur pour un prix dérisoire via e-bay (4€ les 5 kits).
[pour ceux qui cherchent la référence on doit en trouver avec ce genre de recherche « 433Mhz RF transmitter receiver kit » ]

433Mhz emetteur-recepteur

433Mhz emetteur-recepteur

Première étape : voir à quoi on a affaire

montage

J’ai trouvé un montage d’une grand simplicité qui permet de « lire » le signal à partir d’un bête PC sans matériel coûteux.
Pour ce faire j’utilise un simple montage trouvé sur http://davehouston.net/learn.htm.
Le schéma à utiliser est le suivant :

Recepteur RF vers Line-In

Recepteur RF vers Line-In

Au niveau de l’alimentation j’utilise une alimentation variable. Du coup j’ai pu tester la réception entre 5 et 9V, je me suis fixé vers 8V ce qui affaibli le nombre de parasites reçus. Pour mes tests je n’ai pas branché d’antenne sur le récepteur, je préfères éviter de récupérer les signaux de tout le quartier 😉

Dans mes recherches je suis tombé sur une phrase concernant les jack, le fil Rouge serait toujours la voie de Droite (Right Red), si ça se confirme ça peut éviter de faire des tests pour trouver le bon câblage. (sur celui que j’ai récupéré Jaune : GND, Rouge : Droite, Bleu : Gauche. À voir si l’axiome RedRight est vérifié ailleurs ). Chez moi les deux fils (rouge et bleu) ont été joints, certains considèrent qu’on peut enregistrer deux signaux en parallèle (deux sources), moi je n’en ai pas besoin, donc on joint ;).

Audacity

Une fois le cablage vérifié (vérifiez deux fois, une boulette est si vite arrivée, je nierais avoir eu connaissance de vos actes en cas d’explosion de votre carte son) et le jack branché sur l’entré Ligne ( Line-In PAS le microphone, je ne sais pas si ça fait tout exploser mais mes sources étaient claires, ce montage est pour l’entrée Line-In !), lancez Audacity;
Ce programme est un enregistreur de son avec la possibilité de visualiser le son sous forme d’ondes. Et c’est exactement ce dont nous avons besoin ici !

Donc lançons l’enregistrement (je répète pour les deux du fonds qui discutent : en sélectionnant l’entrée Ligne ) et appuyons sur une touche de notre télécommande.
Un signal devrait apparaître, zoomez dessus :
Audacity_049

J’ai mis des 0 et des 1 pour bien comprendre ce qu’on voit. La télécommande utilise un codage (Manchester ?) où chaque bit est représenté sous forme d’un « escalier » entre un front haut et un front bas. La durée de ce front haut défini si c’est un « 1 » (front haut long) ou si c’est un « 0 » (front haut court).
Dans l’exemple pris ici nous avons une trame binaire 011111111111100101101, chaque bouton de ma télécommande envoi une trame différente.

Zoomons encore, cette fois en prenant un « 1 » et un « 0 » (idéalement, mais ça m’étonnerais que vous n’ayez pas un 1 à coté d’un 0 au moins une fois).
Le but cette fois va être de comprendre le protocole Radio Fréquence utilisé ici. Je n’ai pas la savoir pour expliquer ici les différentes méthodes existantes, mais j’ai compris qu’au moins ici c’est la durée de chaque front qui doit être mesuré.

Pour facilité l’analyse j’ai demandé à Audacity d’afficher par « sample » et non en millisecondes, un front durant quelques centaines de µs.

Mesure des temps de chaque front

Mesure des temps de chaque front


Dans l’exemple ci-dessus j’ai sélectionné le front haut du « 1 » et l’ai mesuré à 55 « échantillons ». Sachant que j’ai échantillonné à 44100Hz, il y a donc 44100 échantillons dans une seconde. Sortez vos calculettes, ce front haut dure donc ? Allez un effort … 55/44100 soit 0,001247166s soit 1.247ms. J’ai recommencé les mesures pour le front bas du « 1 » et les deux fronts du « 0 ». J’ai noté ces résultats précieusement ils seront utiles dans la partie suivante où l’on va se mettre à émettre des trames.

Suite dans la partie 2

Documentation :
http://davehouston.net/learn.htm
http://rayshobby.net/?p=3381
http://www.homautomation.org/2014/03/02/433mhtz-rf-communication-between-arduino-and-raspberry-pi-arduino-as-receiver/

Du pliage de plexiglas – aka Je fais mes boites moi même

Il y a quelques temps j’ai acheté une plaque de plexiglas au casto le plus proche dans le but de faire une boite pour mon arduino. D’après ce que j’avais lu sur ce matériaux sur divers forums il suffit de chauffer et de tordre.

Je suis tombé sur une vidéo très didactique sur ce sujet :

Pour ma part je n’ai pas de cornières métallique comme dans la vidéo j’ai donc pris des tasseaux rabotés et des planches de parquet. J’ai fixé au bureau avec des sert joints.

Pour le chauffage j’ai pris le sèche cheveux de madame, à plus forte puissance il monte à 1500W, à croire qu’il peut décaper de la peinture.

Le but est de plier en prenant appui entre deux planches en bois comme sur la vidéo.

Je n’avais pas de gants et cela m’a manqué, le plastique devenant vite chaud, il ne faut pas espérer plier le plastique à main nue d’où l’utilisation d’une seconde planche pour appuyer sur le point à plier.

Le chauffage doit être appliqué sur l’extérieur  de la pliure, c’est à dire du coté où on va appuyer avec la planche.

Le film de protection est à enlever (entièrement je dirais), il fond beaucoup plus tôt que le plexiglas et peut laisser des coulures inélégantes.

A noter qu’un chauffage peu rendre mou au mauvais endroit, c’est d’ailleurs ce qui m’est arrivé, certaines parties sont « pas très droite ». Pour un premier test ça ira ^^.

Pour finir la boite j’ai collé avec un tube de colle qui me tombait sous la main : la bonne vielle colle Gel de chez Scotch. ça colle mais ça fait quelques « bulles ». Attention j’ai fait une coulure et elle reste … le plexi est attaqué

Image

Capteur de pluie – DIY

J’ai eu l’idée saugrenue de fabriquer un capteur de pluie pour m’envoyer un signal sonore quand il se met à pleuvoir la nuit et que la fenêtre est ouverte.

Le montage

Je suis parti d’une plaque de polystyrène mince et de deux fils de cuivre (une chute de câble multi brin dénudé). Il est tout a fait possible de prendre d’autres matériaux tant qu’ils ne craignent pas l’eau et qu’ils ne sont pas trop flexibles (il faut tendre les fils pour éviter qu’ils fassent contact entre eux). Sur le schéma les fils se chevauchent mais il faut imaginer qu’il passent derrière la carte par des trous percés. Il serait aussi tout a fait possible de faire un PCB mais pas sûr que cela soit rentable si la surface est énorme.

Le but est d’avoir deux fils dénudés qui ne sont pas en contact entre eux. C’est l’eau qui assurera leur contact, fermant ainsi le circuit comme un interrupteur. Reste a voir à l’usage à quelle vitesse l’eau va encrasser/oxyder les fils.

 

Capteur de pluie - DIY

 

Je mesure la résistance entre A et B (cf schéma), au repos il ne dois pas y avoir de contact. A est relié à GND et B à A0, une résistance de 1k Ohm est placée entre A0 et 5V.

 

Le code Arduino

J’ai réalisé un rapide programme d’alerte sur l’Arduino qui utilise mon bus ARV pour la communication. C’est le WR703N qui assure la connexion à distance de la sonde.

Je me contente d’une lecture toutes les 100 millisecondes, ça doit être assez précis dans la majorité des cas.

Pour éviter de noyer le bus sous les messages j’évite d’envoyer un message si la variation entre deux mesures est trop faible, j’estime que le changement ne se fera que brutalement, si la variation en 100ms est de 1 unité (sur 1023 …) c’est uniquement dû à l’incertitude de mesure.

De la même manière je considère que les valeurs qui m’intéressent sont < 1000, au dessus c’est sec , sauf si j’ai besoin de savoir si le capteur a séché … à voir si physiquement l’inclinaison du capteur peut aider à le sécher naturellement.

int sensorPin = A0;    // select the input pin for the potentiometer
int sensorValue = 0;  // variable to store the value coming from the sensor
int oldValue = 0;
int sensorDelay=100;

// Seuil en dessous duquel regarder l'évolution
int seuil = 1000;

void setup() {
  Serial.begin( 115200 );
}

void loop() {
  // read the value from the sensor:
  sensorValue = analogRead(sensorPin); 

  if ( sensorValue < seuil )
  {
    // si la valeur a changé de 1 on n'en tient pas compte, il y a trop de fluctuation sur la ligne pour que ce soit important
    if ( abs(  oldValue - sensorValue ) > 1 )
    {
      Serial.print("D");
      Serial.println(sensorValue);
    }
  }

  delay(sensorDelay);
  oldValue = sensorValue;
}

Paramétrage d’ARV

Pour ceux qui suivent ce carnet de note, j’ai développé un bus de communication en TCP/IP qui peut acheminer des messages lus depuis le port série de  l’arduino pour être traités ailleurs.

Pour le test je trace les informations dans un fichier texte grâce au plugin toFile d’ARV. Il faudra d’ailleurs que je développe un plugin qui peut appeler un programme/lire un son/tweeter/… quand il reçoit un message. Le problème sera de régler la sensibilité pour ne pas envoyer de messages trop fréquemment … Peut être en fixant un seuil et en ne notifiant que ce passage de seuil ?

collector.ini

Le fichier collector.ini permet d’associer à un type de message reçu un plugin qui va traiter celui-ci. La « paramétrabilité » est encore sommaire pour l’instant, mais ça viendra au fil du temps.

Pour l’exemple ci-dessous, l’arvcollector lisant le port série arduino envoie des messages de type « arduinoTP.WarningStation ». Un autre arvcollector déporté (celui ayant le collector.ini renseigné comme703 ci-dessous)  tracera les messages reçus (plugin toFile) en les horodatant (timestamp=TRUE).

[plugins]
arduinoTP.WarningStation=toFile.so

[toFile:arduinoTP.WarningStation]
timestamp=TRUE
fileOut=warning.csv

Lancement des processus

Sur le serveur je lance l’arvserveur et l’arvcollector pour traiter les messages via les plugins

./arvserver
./arvcollector [ip_serveur] PluginMaster

Enfin sur le WR703N je lance un collecteur lisant le port série

./arvcollector [ip_serveur] DropWarner /dev/ttyACM0 arduinoTP.WarningStation

L’instance DropWarner enverra des messages au serveur quand la valeur du capteur descendra en dessous de 1000. Le serveur va relayer à tous les autres collecteurs, dont PluginMaster qui a été configuré pour tracer dans le fichier warning.csv.

Application du capteur

Pour tester en situation j’ai mis le capteur cette nuit sous ma chaudière (qui depuis une semaine à une fuite une ou deux fois pas jour et dont on ne connait pas la provenance ). Cela m’a permis de détecter que la fuite a eu lieu à 2h34 du matin, au moment où tout le monde était assoupi dans la maison … surement la faute des chats.

Capteur de pression – DIY

J’ai réalisé une ébauche de détecteur de pression à base de matériel de tous les jours. Attention il s’agit de détecteur si quelque-chose appuie sur le détecteur, pas du poids de la colonne d’air (pression atmosphérique), nos amis anglo-saxon parleraient de Force Sensor, mais en Français je n’ai pas trouvé de terme moins ambiguë.

Pour ce test vous aurez besoin de :

  • papier aluminium
  • feuille de papier
  • ruban adhésif
  • fils de couleurs
  • cutter
  • règle

Prenez une feuille d’aluminium à laquelle vous allez attacher un fil dénudé  (pour ce test je l’ai tout bêtement scotché, pas de soudure pour cette fois).

Prenez une feuille de papier dans laquelle vous allez découper des bandes d’un millimètre de largeur et d’une longueur légerement  inférieure à celle de l’aluminium (pas comme sur les photos).

Scotchez là sous la feuille de papier.

Faites de même de l’autre coté du papier avec une autre feuille d’aluminium, la feuille de papier sera donc prise en sandwitch entre les deux feuille d’aluminium.

Reliez votre ohmmètre entre les deux fils qui doivent être reliés chacun à une des feuilles d’alu. Normalement il ne doit pas y avoir de continuité . Sinon cela veut dire que les fentes dans la feuille de papier sont trop large.

Posez votre main ou un objet d’un certain poids, la feuille d’alu va se déformer, passer à travers le papier et faire contact avec l’autre feuille d’alu.

Ce projet est très imparfait car tout à été fait « au pif », en particulier la taille des fentes dans le papier et le choix de l’épaisseur de papier. Un papier plus épais ou des fentes plus étroites devrait changer la tolérance du système, permettant de le glisser sous un paillasson ou un tapis sans être perturbé par ceux-ci. Cela dit les (patients) lecteurs de ce billet auront peut être le courage de poursuivre l’expérimentation.