www.ghislain.fr

Reception sonde lacrosse via arduino et raspberry pi.

 

 

Objectifs :

- Recuperer la temperature d'une sonde exterieur ( Lacrosse ws-9015t (TX3N) TFA 30.3125)

 

Crédits :

 

Code Arduino

 

Author:       Nils Nesemann

 

Code Raspberry Pi

 

@author : Valentin CARRUESCO (idleman@idleman.fr)

@contributors : Yann PONSARD, Jimmy LALANDE

@webPage : http://blog.idleman.fr

@references & Libraries: https://projects.drogon.net/raspberry-pi/wiringpi/, http://playground.arduino.cc/Code/HomeEasy

 

Définition des besoins :

- 1 RaspberryPi ou equivalent. Personnelement j'utilise un BananaPi, Plus evolué.

- 1 sonde de temperature ( Je possede une station meteo avec une sonde externe 433Mhz)

- 1 Modude RF 433Mhz ( RXB6 ou XY-MK-5V

- 1 Résistance 1Kohms

 

Schema :

 

Source Arduino:  

// Funksensor TFA, 433 MHz Temperatur-Außensender TFA 30.3120.90 not compatible with receiver 30.3034.01

// read and decode temperature.  44 bits alltogather  
// 12 bits device type 111101011111 
// 7 bits device ID changes every time batteries inserted
// 1 bit  checksum is one if bit sum in first 3 digits is even
// 4 bits inverted tens. Subtract 5 to get degrees. 4 bits inverted ones. 4 bits inverted decimal parts
// 4 bits invertedtens again. 4 bits invertedones again. 4 bits inverted tens. We don’t use this.  
byte pin = 13; // from receiver. Between receiver and Arduino is 2 transistor 3V to TTL voltage converter 
byte ar[116], pos=0; unsigned long dur; //array, position in array, pulse duration
int b, d, t;         
void setup() { 
pinMode(pin, INPUT);  
Serial.begin(9600); 
Serial.flush(); 
}  
void loop() { 
b: pos=0; 
// 1111 01 011111 device type other temp sensor TFA 30.3120.90 
dur = pulseIn(pin, HIGH); if ((dur>1100)&&(dur<1500)) {ar[pos] = 1; pos++;
dur = pulseIn(pin, HIGH); if ((dur>1100)&&(dur<1500)) {ar[pos] = 1; pos++;
dur = pulseIn(pin, HIGH); if ((dur>1100)&&(dur<1500)) {ar[pos] = 1; pos++;
dur = pulseIn(pin, HIGH); if ((dur>1100)&&(dur<1500)) {ar[pos] = 1; pos++;
dur = pulseIn(pin, HIGH); if ((dur>400)&&(dur<700)) {ar[pos] = 0; pos++; 
dur = pulseIn(pin, HIGH); if ((dur>1100)&&(dur<1500)) {ar[pos] = 1; pos++;
dur = pulseIn(pin, HIGH); if ((dur>400)&&(dur<700)) {ar[pos] = 0; pos++; 
dur = pulseIn(pin, HIGH); if ((dur>1100)&&(dur<1500)) {ar[pos] = 1; pos++; 
dur = pulseIn(pin, HIGH); if ((dur>1100)&&(dur<1500)) {ar[pos] = 1; pos++; 
dur = pulseIn(pin, HIGH); if ((dur>1100)&&(dur<1500)) {ar[pos] = 1; pos++; 
dur = pulseIn(pin, HIGH); if ((dur>1100)&&(dur<1500)) {ar[pos] = 1; pos++; 
dur = pulseIn(pin, HIGH); if ((dur>1100)&&(dur<1500)) {ar[pos] = 1; pos++; 
}else goto b;
}else goto b; 
}else goto b; 
}else goto b; 
}else goto b; 
}else goto b; 
}else goto b; 
}else goto b; 
}else goto b; 
}else goto b; 
}else goto b; 
}else goto b; 
//  Serial.print("data "); // if one gets to this point then message is most probably correct  
 for (int i=1; i <= 32; i++){ 
   dur = pulseIn(pin, HIGH);   
 if ((dur>400)&&(dur<700)){ar[pos] = 0; pos++; /* Serial.print("0"); */ } 
 if ((dur>1100)&&(dur<1500)){ar[pos] = 1; pos++;/*  Serial.print("1"); */}
 
 
 }  
// Serial.print("databegin TFA2 ");  
 d=0; for (int i=0; i <= 6; i++) {/*if (ar[12+i]==1) Serial.print("1"); if (ar[11+i]==0) Serial.print("0");*/
 d=d << 1; d=d+ar[12+i]; } // Serial.print(d); Serial.print(" "); // Device ID  
  d=0; for (int i=0; i <= 3; i++) {d=d << 1; if (ar[20+i]==1) b=0; else b=1; d=d+b;} d=d-5; t=d*100; // tens of degrees  
  d=0; for (int i=0; i <= 3; i++) {d=d << 1; if (ar[24+i]==1) b=0; else b=1; d=d+b;} t=t+10*d; // ones of degrees 
  d=0; for (int i=0; i <= 3; i++) {d=d << 1; if (ar[28+i]==1) b=0; else b=1; d=d+b;} t=t+d;  // decimal parts of degrees
  t=t/10;
  Serial.print(t);  
  Serial.print(".");
  Serial.println(d);
  d=ar[19]; for (int i=0; i <= 11; i++) {if (ar[20+i]==1) d=d+1;} 
  
  }

 

 

Source Raspberry Pi:  

/*Cette page récupere les informations du signal radio recu par le raspberry PI

en lui fournissant tout les paramêtres.
Vous pouvez compiler cette source via la commande :
	g++ radioReception.cpp -o radioReception -lwiringPi
	
	N'oubliez pas d'installer auparavant la librairie wiring pi ainsi que l'essentiel des paquets pour compiler
Vous pouvez lancer le programme via la commande :
	sudo chmod 777 radioReception
	./radioReception 2
	
@author : Valentin CARRUESCO (idleman@idleman.fr)
@contributors : Yann PONSARD, Jimmy LALANDE
@webPage : http://blog.idleman.fr
@references & Libraries: https://projects.drogon.net/raspberry-pi/wiringpi/, http://playground.arduino.cc/Code/HomeEasy
@licence : CC by sa (http://creativecommons.org/licenses/by-sa/3.0/fr/)
RadioPi de Valentin CARRUESCO (Idleman) est mis à disposition selon les termes de la 
licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 France.
Les autorisations au-delà du champ de cette licence peuvent être obtenues à idleman@idleman.fr.
*/
#include <wiringPi.h>
#include <iostream>
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
#include <sched.h>
#include <sstream>
using namespace std;
//initialisation du pin de reception
int pin;
//Fonction de log
void log(string a){
	//Décommenter pour avoir les logs
	//cout << a << endl;
}
//Fonction de conversion long vers string
string longToString(long mylong){
    string mystring;
    stringstream mystream;
    mystream << mylong;
    return mystream.str();
}
//Fonction de passage du programme en temps réel (car la reception se joue a la micro seconde près)
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.");
	}
}
//Fonction de remise du programme en temps standard
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.");
	}
}
//Recuperation du temp (en micro secondes) d'une pulsation
int pulseIn(int pin, int level, int timeout)
{
   struct timeval tn, t0, t1;
   long micros;
   gettimeofday(&t0, NULL);
   micros = 0;
   while (digitalRead(pin) != level)
   {
      gettimeofday(&tn, NULL);
      if (tn.tv_sec > t0.tv_sec) micros = 1000000L; else micros = 0;
      micros += (tn.tv_usec - t0.tv_usec);
      if (micros > timeout) return 0;
   }
   gettimeofday(&t1, NULL);
   while (digitalRead(pin) == level)
   {
      gettimeofday(&tn, NULL);
      if (tn.tv_sec > t0.tv_sec) micros = 1000000L; else micros = 0;
      micros = micros + (tn.tv_usec - t0.tv_usec);
      if (micros > timeout) return 0;
   }
   if (tn.tv_sec > t1.tv_sec) micros = 1000000L; else micros = 0;
   micros = micros + (tn.tv_usec - t1.tv_usec);
   return micros;
}
//Programme principal
int main (int argc, char** argv)
{
	log("Start");
	//On passe en temps réel
	scheduler_realtime();
//int ar[116];
int ar[116], pos=0;
int b, d, td; 
//on récupere l'argument 1, qui est le numéro de Pin GPIO auquel est connecté le recepteur radio
	pin = atoi(argv[1]);
	//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;
    }else{
    	log("Librairie WiringPI detectee");
    }	
    pinMode(pin, INPUT);
	log("Pin GPIO configure en entree");
    log("Attente d'un signal du transmetteur ...");
	
	//On boucle pour ecouter les signaux
    	int i = 0;
		unsigned long t = 0;
	    //avant dernier byte reçu
		int prevBit = 0;
	    //dernier byte reçu
		int bit = 0;
		
		//mise a zero de l'idenfiant télécommande
	    unsigned long sender = 0;
		//mise a zero du groupe
	    bool group=false;
		//mise a zero de l'etat on/off
	    bool on =false;
		//mise a zero de l'idenfiant de la rangée de bouton
	    unsigned long recipient = 0;
			
	
	//Si les données ont bien été détéctées
    b: pos=0; 
// 1111 01 011111 device type other temp sensor TFA 30.3120.90 
t = pulseIn(pin, HIGH, 1000000); 
t = pulseIn(pin, HIGH, 1000000); if ((t>1100)&&(t<1500)) {ar[pos] = 1; pos++;
t = pulseIn(pin, HIGH, 1000000); if ((t>1100)&&(t<1500)) {ar[pos] = 1; pos++;
t = pulseIn(pin, HIGH, 1000000); if ((t>1100)&&(t<1500)) {ar[pos] = 1; pos++;
t = pulseIn(pin, HIGH, 1000000); if ((t>1100)&&(t<1500)) {ar[pos] = 1; pos++;
t = pulseIn(pin, HIGH, 1000000); if ((t>400)&&(t<700)) {ar[pos] = 0; pos++; 
t = pulseIn(pin, HIGH, 1000000); if ((t>1100)&&(t<1500)) {ar[pos] = 1; pos++;
t = pulseIn(pin, HIGH, 1000000); if ((t>400)&&(t<700)) {ar[pos] = 0; pos++; 
t = pulseIn(pin, HIGH, 1000000); if ((t>1100)&&(t<1500)) {ar[pos] = 1; pos++; 
t = pulseIn(pin, HIGH, 1000000); if ((t>1100)&&(t<1500)) {ar[pos] = 1; pos++; 
t = pulseIn(pin, HIGH, 1000000); if ((t>1100)&&(t<1500)) {ar[pos] = 1; pos++; 
t = pulseIn(pin, HIGH, 1000000); if ((t>1100)&&(t<1500)) {ar[pos] = 1; pos++; 
t = pulseIn(pin, HIGH, 1000000); if ((t>1100)&&(t<1500)) {ar[pos] = 1; pos++; 
}else goto b;
}else goto b; 
}else goto b; 
}else goto b; 
}else goto b; 
}else goto b; 
}else goto b; 
}else goto b; 
}else goto b; 
}else goto b; 
}else goto b; 
}else goto b; 
//  Serial.print("data "); // if one gets to this point then message is most probably correct  
 for (int i=1; i <= 32; i++){ 
   t = pulseIn(pin, HIGH, 1000000);   
 if ((t>400)&&(t<700)){ar[pos] = 0; pos++;  /*log("0"); */ } 
 if ((t>1100)&&(t<1500)){ar[pos] = 1; pos++; /* log("1");*/ }
  
}
// Serial.print("databegin TFA2 ");  
 d=0; for (int i=0; i <= 6; i++) {//if (ar[12+i]==1) log("1"); if (ar[11+i]==0) log("0");
 d=d << 1; d=d+ar[12+i]; } // log(d); log(" "); // Device ID  
  d=0; for (int i=0; i <= 3; i++) {d=d << 1; if (ar[20+i]==1) b=0; else b=1; d=d+b;} d=d-5; td=d*100; // tens of degrees  
  d=0; for (int i=0; i <= 3; i++) {d=d << 1; if (ar[24+i]==1) b=0; else b=1; d=d+b;} td=td+10*d; // ones of degrees 
  d=0; for (int i=0; i <= 3; i++) {d=d << 1; if (ar[28+i]==1) b=0; else b=1; d=d+b;} td=td+d;  // decimal parts of degrees
  td=td/10;
cout << td << "." << d << endl;
	scheduler_standard();
}
 

 

 

 

 

 

 

 

nach oben