Transmission de données entre un Arduino et une Raspberry Pi 3 en utilisant des modules radio Nrf24L01

image_pdfimage_print

Il s’agit ici de faire une démo de transmission de données (température) entre un Arduino et un Raspberry Pi 3. C’est le protocole SPI qui est utilisé.

Liens utiles :

  • https://github.com/Michelgard/Capteur-DS18D20-Arduino-avec-emetteur-2.4Ghz
  • https://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo#PP

ATTENTION : si Arduino alimenté via port USB PC alors il faut que le module radio émette à puissance minimale

Connexions :

Connexion nRF24L01+ sur l’arduino :
1 GND 2 VCC 3.3
3 D9 4 D10
5 D13 6 D11
7 D12 8 D2

Installer nRF24L01+ sur le Raspberry PI
NRFL01 Raspi
1 6 GND
2 1 VCC 3.3
3 22 CE
4 24 CSN
5 23 SCK
6 19 MOSI
7 21 MISO

Activer le SPI sur le Raspberry Pi (raspi-config)

Code Python pour le Raspberry Pi

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

from nrf24 import NRF24
import time
from time import gmtime, strftime
import xml.dom.minidom
import sys

verbose = 0
if len(sys.argv) > 1:
    if sys.argv[1] == "-v":
        verbose = 1
    else:
        print "Argument non reconnu !  -v pour verbose"
        sys.exit(0) 


"""Variable de connexion R24"""
pipes = [[0xf0, 0xf0, 0xf0, 0xf0, 0xe1], [0xf0, 0xf0, 0xf0, 0xf0, 0xd2]]

""" init variable"""
temperExt = '0.0'

"""Initialisation connexion R24"""
radio = NRF24()
radio.begin(0, 0,25,18) #set gpio 25 as CE pin
radio.setRetries(15,15)
radio.setPayloadSize(52)
radio.setChannel(0x4c)
radio.setDataRate(NRF24.BR_250KBPS)
radio.setPALevel(NRF24.PA_MAX)
radio.setAutoAck(1)
radio.openWritingPipe(pipes[0])
radio.openReadingPipe(1, pipes[1])

radio.startListening()
"""fin initialisation R24"""

"""Fonction pour extraire de la variable receptionnée les différentes valeurs"""
def extract(raw_string, start_marker, end_marker):
    start = raw_string.index(start_marker) + len(start_marker)
    end = raw_string.index(end_marker, start)
    return raw_string[start:end]

if verbose:
    print
    print ("Attente réception du capteur")
    print

"""Boucle infinie de réception des données"""
while True:
    pipe = [0]
    """Si pas de réception on attends ..."""
    
    
    while not radio.available(pipe, True):
        time.sleep(1000/1000000.0)
    recv_buffer = []
    radio.read(recv_buffer) #Les données réceptionnées sont mise dans la variable
    out = ''.join(chr(i) for i in recv_buffer)#création d'une variable blobage avec les valeurs du tableu buffer

    """Création de la date et heure en francais et en SQL"""
    now = time.localtime(time.time())  
    year, month, day, hour, minute, second, weekday, yearday, daylight = now
    dateheure = "%02d/%02d/%04d" % (day, month, year) + "  " + "%02d:%02d:%02d" % (hour, minute, second)
    dateheureSQL = "%04d-%02d-%02d" % (year, month, day) + " " + "%02d:%02d:%02d" % (hour, minute, second)
    
    """"La variable out est décortiquée avec les données de numéro de capteur, température, humidité, tension pile """
    temperExt=extract(out,'E','E')

    """affichage des données recues pour es teste"""
    if verbose:
        print (dateheure)
    if verbose:
        print ("La température Ext : " + temperExt + "°C")
        print

Code Arduino :

#include <avr/sleep.h>
#include <avr/wdt.h>
#include
#include "nRF24L01.h"
#include
#include
#include // Inclusion de la librairie OneWire

#define DS18B20 0x28 // Adresse 1-Wire du DS18B20
#define BROCHE_ONEWIRE 7 // Broche utilisée pour le bus 1-Wire

OneWire ds(BROCHE_ONEWIRE); // Création de l’objet OneWire ds

//variables radio
RF24 radio(9,10); //création instance radio (pin ce,csn)
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL,0xF0F0F0F0D2LL };

// Fonction récupérant la température depuis le DS18B20
// Retourne true si tout va bien, ou false en cas d’erreur
boolean getTemperature(float *temp){
byte data[9], addr[8];
// data : Données lues depuis le scratchpad
// addr : adresse du module 1-Wire détecté

if (!ds.search(addr)) { // Recherche un module 1-Wire
ds.reset_search(); // Réinitialise la recherche de module
return false; // Retourne une erreur
}

if (OneWire::crc8(addr, 7) != addr[7]) // Vérifie que l’adresse a été correctement reçue
return false; // Si le message est corrompu on retourne une erreur

if (addr[0] != DS18B20) // Vérifie qu’il s’agit bien d’un DS18B20
return false; // Si ce n’est pas le cas on retourne une erreur

ds.reset(); // On reset le bus 1-Wire
ds.select(addr); // On sélectionne le DS18B20

ds.write(0x44, 1); // On lance une prise de mesure de température
delay(800); // Et on attend la fin de la mesure

ds.reset(); // On reset le bus 1-Wire
ds.select(addr); // On sélectionne le DS18B20
ds.write(0xBE); // On envoie une demande de lecture du scratchpad

for (byte i = 0; i < 9; i++) // On lit le scratchpad
data[i] = ds.read(); // Et on stock les octets reçus

// Calcul de la température en degré Celsius
*temp = ((data[1] << 8) | data[0]) * 0.0625;

// Pas d’erreur
return true;
}

// nrf24 debug
int serial_putc( char c, FILE * )
{
Serial.write( c );
return c;
}

void printf_begin(void)
{
fdevopen( &serial_putc, 0 );
}

void setup()
{
printf_begin();
Serial.begin(9600); //Debug

radio.begin();
radio.setChannel(0x4c);
radio.setAutoAck(1);
radio.setRetries(15,15);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_MIN);
radio.setPayloadSize(32);
radio.openReadingPipe(1,pipes[0]);
radio.openWritingPipe(pipes[1]);
radio.stopListening();
radio.powerUp(); //alimente le module nrf24l01+
radio.printDetails(); //for Debugging
}

void loop (){
float txbuffer[1] = {0};
char SendPayload[32] = « RS1 : »;
char tempstr[10] = «  »;

if(getTemperature(&txbuffer[0])) {
strcat(SendPayload, « E »);
dtostrf(txbuffer[0],2,2,tempstr);

Serial.println(« ok »);

strcat(SendPayload,tempstr);
strcat(SendPayload, « E »);

Serial.println(SendPayload);
// radio.powerUp(); //alimente le module nrf24l01+
delay(1000);
bool ok = radio.write(&SendPayload,sizeof(SendPayload));
delay(1000);
//Serial.println(« ok2 »);

//radio.powerDown(); //arrêt de l’alimentation du module nrf24l01+
}
// else
// {
// Serial.println(« Error »);
// }
//for (int i = 0; i < 100; i++){
delay(3000);
//}
}

root@raspberrypi:~/nrf/Capteur-DS18D20-Arduino-avec-emetteur-2.4Ghz# python ./lecture-capteurRF24_KB.py -v

Attente réception du capteur

15/07/2018 12:32:23
La température Ext : 27.38°C

15/07/2018 12:32:32
La température Ext : 27.38°C