Vai al contenuto
PLC Forum


Problemi di trasmissione con NRF24L01


m2fro

Messaggi consigliati

Ciao a tutti,

sto sviluppando in modo hobbistico dei semplici dispositivi basati su PCB per il controllo di alcune funzioni domotiche, ad esempio gestione comandi radio 443 mhz e gestione delle prese elettriche (accensione / spegnimento). Si tratta di dispositivi basati su Atmega328P-PU e NRF24L01 (senza PA-LNA).  Allego i relativi disegni Eagle delle viste schematiche e PCB. I componenti sono interrogati da un gateway su Raspberry PI 3 model B, sempre via NRF24L01.

 

Il problema che riscontro è che, pur essendo basati sullo stesso disegno, il componente radio funziona correttamente mentre il componente per le prese no: a differenza del radio, non sembra esserci nessuna trasmissione radio in risposta al raspberry. Il problema è lo stesso anche su altri PCB che svolgono altre funzioni (monitoraggio consumi, rilevazione presenza, gestione luci...) e che hanno in comune il fatto di essere basati su HLK PM01. Analogamente, il problema non si ripresenta su un altro PCB basato su alimentazione via USB  (monitoraggio temperatura).

 

- Una prima ipotesi di errore quindi è stata l'alimentazione tramite HLK PM01 (effettivamente ho letto altri forum legati alla interferenza radio che questi componenti possono creare); dopo un primo troubleshooting sul trasformatore però, ho aggirato questa ipotesi togliendo il componente dal PCB e cominciando ad alimentare tramite header dai 5V della scheda Arduino Uno. Il comportamento è stato lo stesso.

- La seconda ipotesi di errore è stata l'errata connessione dei pin NRF24L01 oppure dell'alimentazione dell'Atmega (ossia un errore nel disegno delle tracce su PCB, che si è "propagato"  nel passaggio da alimentazione HLK-PM01 ad alimentazione USB). Una verifica sulle connessioni però non ha evidenziato nessuna differenza.

- La terza ipotesi di errore è stata la configurazione Atmega o il codice caricato sul PCB. Ho provato a montare lo stesso Atmega con lo stesso codice prima sul PCB radio e poi sul PCB delle prese, con lo stesso risultato (radio funzionante, nessuna risposta dal dispositivo delle prese).

- Una quarta ipotesi è stata lo spessore delle linee di alimentazione e segnale sui PCB, ma da Eagle risultano della stesso spessore (0.254) e profondità (1 oz).

 

A questo punto, apparentemente eliminate queste ipotesi di errore, non so più cosa pensare...

 

Vi allego per completezza (visto che lo stesso codice su stesso atmega genera lo stesso comportamento, tenderei ad escludere problemi legati al codice, ma non si sa mai...) i codici dei firmware caricati su Atmega e sviluppati con Arduino per la componente Radio:

#include <SPI.h>
#include <RF24.h>

RF24 radio(9, 10);
const char id[] = "00:00:02";

int relPin = 8;                 // Pin for driving relè
boolean rele;

void setup(){ 
  while(!Serial);
  Serial.begin(9600);

  rele = false;
  pinMode(relPin, OUTPUT);  //Sets digital pin 13 as output pin
  digitalWrite(relPin, LOW);
  
  radio.begin();
  radio.setPALevel(RF24_PA_MAX);
  radio.setChannel(0x76);
  radio.openWritingPipe(0xF0F0F0F0E1LL);
  const uint64_t pipe = (0xE8E8F0F0E1LL);
  radio.openReadingPipe(1, pipe);
  radio.enableDynamicPayloads();
  radio.enableDynamicAck();
  radio.powerUp();	

}

void loop(){
  radio.startListening();
  char receivedMessage[32] = {0};
  String str(id);
  if(radio.available()){
    radio.read(receivedMessage, sizeof(receivedMessage));
    radio.stopListening();
    String stringMessage(receivedMessage);   
    if(stringMessage == (str + "t")){            // get device type
       const char type[] = "L";          // L = Line
       radio.write(type, sizeof(type));  
    } else if(stringMessage == ("i")){     // get device ID
       radio.write(id, sizeof(id));   
    } else if(stringMessage == (str + "p")){     // switch the line
       rele=not(rele);   
       if (rele){
         digitalWrite(relPin, HIGH);
       } else {
         digitalWrite(relPin, LOW);
       }
    } else if(stringMessage == (str + "s")){      // get the status
       if (rele){
         radio.write("1", sizeof("1"));  
       } else {
         radio.write("0", sizeof("0")); 
       }     
    } 
  } 
}

per la parte gestione prese:

#include <RCSwitch.h>
#include <SPI.h>
#include <RF24.h>
#include <MD5.h>

RCSwitch mySwitch = RCSwitch(); 
long interval = 5000;                  // reading delta
RF24 radio(9, 10);
const char id[] = "00:00:03";
const char pwd[] = "password";

void setup() {
  Serial.begin(9600);
  mySwitch.enableReceive(0);                // Receiver on interrupt 0 => that is pin #2
  mySwitch.enableTransmit(5);               // Transmitter is connected to Arduino Pin #5 
  mySwitch.enableReceive(0);                // Receiver on interrupt 0 => that is pin #2

  radio.begin();
  radio.setPALevel(RF24_PA_MAX);
  radio.setChannel(0x76);
  radio.openWritingPipe(0xF0F0F0F0E1LL);
  const uint64_t pipe = (0xE8E8F0F0E1LL);
  radio.openReadingPipe(1, pipe);
  radio.enableDynamicPayloads();
  radio.powerUp();
}

void loop() {
  radio.startListening();
  char receivedMessage[32] = {
    0  };
  boolean received = false;
  if(radio.available()){
    radio.read(receivedMessage, sizeof(receivedMessage));
    radio.stopListening();
    String stringMessage(receivedMessage);
    // convert id from chart array to String
    String strId(id);
    if(stringMessage == "i"){                                  // Id
      radio.write(id, sizeof(id));   
    } else if (stringMessage == strId + "t"){                   // Device Type
      const char type[] = "R";                                // R = Radio
      radio.write(type, sizeof(type));           
    } 
    else if(stringMessage == (strId + "r")){                  // Receive
      unsigned long startMillis = millis();
      unsigned long currentMillis = millis();
      unsigned long received;
      int protocol;
      int lenght;
      int pulse;
      boolean flag = true;

      while (currentMillis - startMillis < interval && flag) {
        if (mySwitch.available()) {
          received = mySwitch.getReceivedValue();
          protocol = mySwitch.getReceivedProtocol();
          lenght = mySwitch.getReceivedBitlength();
          pulse = mySwitch.getReceivedDelay();
          mySwitch.resetAvailable();
          flag = false;
        }
        currentMillis = millis();
      }
      if (not flag){
        // convert received unsigned long code to char buffer then to String
        char buffer[10];
        sprintf(buffer, "%lu", received);
        String strRec(buffer);
        // compose a String with code, lenght, protocol and pulse lenght
        String str = strRec+ "-" + String(lenght) + "-" + String(protocol) + "-" + String(pulse);
        char code[32] = {0};
        str.toCharArray(code, sizeof(code));
        radio.write(code, sizeof(code));
      } 
    } 
    else if (stringMessage.indexOf(strId + "s") == 0){                //  Send code
      char commands[32] = {0};
      stringMessage.toCharArray(commands, sizeof(commands));
      char delimiter[1] = {'-'};                          // delimiter in radio command string
      // parse command string
      String command = strtok(commands, delimiter);       // header
      String buf = strtok(NULL, delimiter);               // radio line
      char line[32] = {0};
      buf.toCharArray(line, sizeof(line));
      String lenght = strtok(NULL, delimiter);            // line lenght 
      String protocol = strtok(NULL, delimiter);          // protocol
      String pulse = strtok(NULL, delimiter);             // pulse
      // send the radio line
      mySwitch.setProtocol(protocol.toInt());
      mySwitch.setPulseLength(pulse.toInt());    
      mySwitch.send(atol(line), lenght.toInt());     
      char code[32] = {1};
      radio.write(code, sizeof(code));
    }
  }
}

e per il gateway su Raspberry (codice python):

import RPi.GPIO as GPIO
from lib_nrf24 import NRF24
import time
import spidev

discovery_time = 10

GPIO.setmode(GPIO.BCM)

pipes = [[0xE8, 0xE8, 0xF0, 0xF0, 0xE1], [0xF0, 0xF0, 0xF0, 0xF0, 0xE1]]

radio = NRF24(GPIO, spidev.SpiDev())
radio.begin(0, 17)

radio.setPayloadSize(32)
radio.setChannel(0x76)
radio.setDataRate(NRF24.BR_1MBPS)
radio.setPALevel(NRF24.PA_MAX)

radio.setAutoAck(True)
radio.enableDynamicPayloads()
radio.enableAckPayload()

radio.openWritingPipe(pipes[0])
radio.openReadingPipe(1, pipes[1])
radio.printDetails()

############################################################

#print "DISCOVERED DEVICES:"
discovered = []

message = list("i")
while len(message) < 32:
  message.append(0)

#radio.write(message)

start_discovery = time.time()
while (time.time() - start_discovery < discovery_time):
  radio.write(message)
  radio.startListening()
  start = time.time()
  while not radio.available(0):
    time.sleep(1 / 100)
    if time.time() - start > 0.2:
        break

  receivedMessage = []
  radio.read(receivedMessage, radio.getDynamicPayloadSize())
  #print(receivedMessage)
  id = ""
  for n in receivedMessage:
    if (n >= 32 and n <= 126):
        id += chr(n)
  radio.stopListening()
  #time.sleep(1)
  #print id
  if (id not in discovered and id != "" and len(id) == 8):
    print id
    discovered.append(id)

result = []

for dev in discovered:
  type = ""
  while (type == ""):
    message = list(dev + "t")
    while len(message) < 32:
      message.append(0)
    start_discovery = time.time()
    radio.write(message)
    radio.startListening()
    start = time.time()
    while not radio.available(0):
      time.sleep(1 / 100)
      if time.time() - start > 0.2:
        break

    receivedMessage = []
    radio.read(receivedMessage, radio.getDynamicPayloadSize())
    for n in receivedMessage:
      if (n >= 32 and n <= 126):
        type += chr(n)
    radio.stopListening()
    time.sleep(1)
    if (type != "" and len(type) == 1):
      if (type == "M"):
        element = [dev, "MyahMeter"]
      if (type == "L"):
        element = [dev, "MyahLine"]
      if (type == "R"):
        element = [dev, "MyahRadio"]
      if (type == "P"):
        element = [dev, "MyahMotion"]
      if (type == "T"):
        element = [dev, "MyahTemp"]
      if (type == "S"):
        element = [dev, "MyahSocket"]
#    element = [dev, type]
      print type
      result.append(element)

print result

Grazie!

 

Ciao

Mattia

radio - BRD.jpg

line - BRD.jpg

line - SCH.jpg

radio - SCH.jpg

Link al commento
Condividi su altri siti


Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...