Courte procédure permettant l’allumage ou l’arrêt de prise électrique CHACON 54795 à l’aide d’un RaspBerry Pi 2 et d’un émetteur 433Mhz. Le projet finale vous permettra via une commande bash sur le raspberry d’allumer ou éteindre une prise électrique via l’émetteur radio 433Mhz.
Pour débuter il vous faudra posséder la liste de matériel suivante :
- Raspberry Pi 2 Type B – 34€
- Kingston – SDC4 – Carte Micro SDHC 8 Go (Classe 4) – Adaptateur SD5.90€
- 433 MHz émetteur et récepteur radio5.50€
- Cables Dupont Femelle / Femele 1.26
- Kit 3 prises télécommandées CHACON DIO First24.90€
- Optionnel : coque trenspante + 5v 3000mA Alimentation + dissipateur thermique12.99€
- Totale : 84€
Les prises éléctrique Chacon DIO fonctionnent avec le principe suivant :
– Lors de l’allumage, durant 5 secondes la led rouge clignote cela indique qu’elle est en phase d’écoute pour recevoir une requête d’association, si elle ne reçoit rien elle conserve la précédente
– L’objectif sera donc d’envoyer une requête durant ces 5 secondes avec le Raspberry afin qu’elle réponde par la suite
Je pars du principe que vous avez une installation fonctionnelle de Raspbian Stretch. Pour la procédure j’étais en version de kernel 4.9.41-v7+. L’ensemble de la procédure s’effectuera via ssh, un accès WEB est indispensable.
Depuis RASPBIAN PIXEL après l’installation de l’ISO sur votre carte SD SSH est désactivé par défaut.
Pour activer SSH montez la carte SD, la partition « /boot » doit être accessible en écriture. Puis il vous faut créer un fichier vide nomé « ssh » à la racine. Lors du démarrage Raspbian va détecter le fichier et activer le SSH-server avec comme identifiants par défaut : pi/raspberry
Câblage émetteur radio et connectiques
Câblage Récépteur radio et connectique (Inutile dans ce billet, posté pour information)
Connection et authentification SSH vers le raspberry
Mises à jours
Installation des outils de bases, gcc ; g++ et make sont des compilateurs, git permet d’importer un dépôt depuis github.com
Clone de WiringPi depuis le dépôt, wiringPi (doc) est une bibliothèque d’accès GPIO basée sur un code écrit en C
Déplacement dans le dossier du projet et build
On teste la bonne reconnaissance, cela lit toutes les broches normalement accessibles et imprime un tableau de leurs numéros
Créer un dossier destiné à recevoir le code à compiler, puis ajoutez-y le fichier « chacon_send.cpp »
Téléchargez le Code C du programme de idleman d’envoi de commandes depuis l’émetteur radio branché sur la pin 11 du Raspberry.(Voir schéma ci-dessus)
OU
Création du fichier via nano puis copiez collez le code ci-dessous.
Code à copier/coller
#include <iostream>
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
#include <sched.h>
#include <sstream>
#include <unistd.h>
/*
Par Idleman (idleman@idleman.fr - http://blog.idleman.fr)
Licence : CC by sa
Toutes question sur le blog ou par mail, possibilité de m'envoyer des bières via le blog
*/
using namespace std;
int pin;
bool bit2[26]={}; // 26 bit Identifiant emetteur
bool bit2Interruptor[4]={};
int interruptor;
int sender;
string onoff;
void log(string a){
//Décommenter pour avoir les logs
//cout << a << endl;
}
void scheduler_realtime() {
struct sched_param p;
p.__sched_priority = sched_get_priority_max(SCHED_RR);
if( sched_setscheduler( 0, SCHED_RR, &p ) == -1 ) {
perror("Failed to switch to realtime scheduler.");
}
}
void scheduler_standard() {
struct sched_param p;
p.__sched_priority = 0;
if( sched_setscheduler( 0, SCHED_OTHER, &p ) == -1 ) {
perror("Failed to switch to normal scheduler.");
}
}
//Envois d'une pulsation (passage de l'etat haut a l'etat bas)
//1 = 310µs haut puis 1340µs bas
//0 = 310µs haut puis 310µs bas
void sendBit(bool b) {
if (b) {
digitalWrite(pin, HIGH);
delayMicroseconds(310); //275 orinally, but tweaked.
digitalWrite(pin, LOW);
delayMicroseconds(1340); //1225 orinally, but tweaked.
}
else {
digitalWrite(pin, HIGH);
delayMicroseconds(310); //275 orinally, but tweaked.
digitalWrite(pin, LOW);
delayMicroseconds(310); //275 orinally, but tweaked.
}
}
//Calcul le nombre 2^chiffre indiqué, fonction utilisé par itob pour la conversion decimal/binaire
unsigned long power2(int power){
unsigned long integer=1;
for (int i=0; i<power; i++){
integer*=2;
}
return integer;
}
//Convertis un nombre en binaire, nécessite le nombre, et le nombre de bits souhaité en sortie (ici 26)
// Stocke le résultat dans le tableau global "bit2"
void itob(unsigned long integer, int length)
{
for (int i=0; i<length; i++){
if ((integer / power2(length-1-i))==1){
integer-=power2(length-1-i);
bit2[i]=1;
}
else bit2[i]=0;
}
}
void itobInterruptor(unsigned long integer, int length)
{
for (int i=0; i<length; i++){
if ((integer / power2(length-1-i))==1){
integer-=power2(length-1-i);
bit2Interruptor[i]=1;
}
else bit2Interruptor[i]=0;
}
}
//Envoie d'une paire de pulsation radio qui definissent 1 bit réel : 0 =01 et 1 =10
//c'est le codage de manchester qui necessite ce petit bouzin, ceci permet entre autres de dissocier les données des parasites
void sendPair(bool b) {
if(b)
{
sendBit(true);
sendBit(false);
}
else
{
sendBit(false);
sendBit(true);
}
}
//Fonction d'envois du signal
//recoit en parametre un booleen définissant l'arret ou la marche du matos (true = on, false = off)
void transmit(int blnOn)
{
int i;
// Sequence de verrou anoncant le départ du signal au recepeteur
digitalWrite(pin, HIGH);
delayMicroseconds(275); // un bit de bruit avant de commencer pour remettre les delais du recepteur a 0
digitalWrite(pin, LOW);
delayMicroseconds(9900); // premier verrou de 9900µs
digitalWrite(pin, HIGH); // high again
delayMicroseconds(275); // attente de 275µs entre les deux verrous
digitalWrite(pin, LOW); // second verrou de 2675µs
delayMicroseconds(2675);
digitalWrite(pin, HIGH); // On reviens en état haut pour bien couper les verrous des données
// Envoie du code emetteur (272946 = 1000010101000110010 en binaire)
for(i=0; i<26;i++)
{
sendPair(bit2[i]);
}
// Envoie du bit définissant si c'est une commande de groupe ou non (26em bit)
sendPair(false);
// Envoie du bit définissant si c'est allumé ou eteint 27em bit)
sendPair(blnOn);
// Envoie des 4 derniers bits, qui représentent le code interrupteur, ici 0 (encode sur 4 bit donc 0000)
// nb: sur les télécommandes officielle chacon, les interrupteurs sont logiquement nommés de 0 à x
// interrupteur 1 = 0 (donc 0000) , interrupteur 2 = 1 (1000) , interrupteur 3 = 2 (0100) etc...
for(i=0; i<4;i++)
{
if(bit2Interruptor[i]==0){
sendPair(false);
}else{
sendPair(true);
}
}
digitalWrite(pin, HIGH); // coupure données, verrou
delayMicroseconds(275); // attendre 275µs
digitalWrite(pin, LOW); // verrou 2 de 2675µs pour signaler la fermeture du signal
}
int main (int argc, char** argv)
{
if (setuid(0))
{
perror("setuid");
return 1;
}
scheduler_realtime();
log("Demarrage du programme");
pin = atoi(argv[1]);
sender = atoi(argv[2]);
interruptor = atoi(argv[3]);
onoff = argv[4];
//Si on ne trouve pas la librairie wiringPI, on arrête l'execution
if(wiringPiSetup() == -1)
{
log("Librairie Wiring PI introuvable, veuillez lier cette librairie...");
return -1;
}
pinMode(pin, OUTPUT);
log("Pin GPIO configure en sortie");
itob(sender,26); // convertion du code de l'emetteur (ici 8217034) en code binaire
itobInterruptor(interruptor,4);
if(onoff=="on"){
log("envois du signal ON");
for(int i=0;i<5;i++){
transmit(true); // envoyer ON
delay(10); // attendre 10 ms (sinon le socket nous ignore)
}
} else{
log("envois du signal OFF");
for(int i=0;i<5;i++){
transmit(false); // envoyer OFF
delay(10); // attendre 10 ms (sinon le socket nous ignore)
}
}
log("fin du programme"); // execution terminée.
scheduler_standard();
}
On lance la compilation
Le code compilé fournit un binaire « chacon_send », utilisez les syntaxes ci-dessous pour vous associer aux prises et les manager
./chacon_send 0 12325261 1 on
#Prise 2
./chacon_send 0 12325262 2 on
#Prise 3
./chacon_send 0 12325263 3 on
- wiringPi pin : numéro wiringPi sur lequel on a branché la broche « DATA » de l’émetteur radio 433mhz. Il est sur le pin physique 11 qui correspond sur wiringPi au pin 0.
- controler_code : numéro identification de l’émetteur d’une longueur de 26 bits. Arbitraire, il doit juste respecter la syntaxe des 26 bits
- outlet_code : ID de la prise. Elle prendra ce code comme identifiant et le gardera jusqu’à qu’une nouvelle association l’écrase
- on|off : ON ou OFF pour allumer ou éteindre la prise éléctrique
Je partage les sources qui m’ont beaucoup aidé dans la réalisation de cela, avec l’article de idleman à l’origine de la manipulation notamment sur le code à compiler ainsi que l’article de arno0x0x qui m’a permis de compléter ma recherche avec sa version modifiée.
Ca ne fonctionne pas pour le chacon 54663 :( qqn a une solution ?