Merkwürdiger Effekt mit nrf24l01 HighPower Modul B10-ML01DP5

Hallo,

ich habe hier einen merkwürdigen Effekt mit diesen HighPowermodulen den nrf24l01.
Das sind die wo die Elektronik noch mal extra gekapselt ist.

Bitte nicht sofort schreien "Poste den Sketch" (kann ich später gerne noch machen), ich
wollte nur erst einmal wissen ob jemand die Module auch hat und den von mir beobachteten
Effekt kennt.

Ich habe hier einen Primitiven Sendesketch und eine Empfänger mit GPS.
Das habe ich benutzt um Reichweitentests zu machen. Die Kombi klappt prima mit
den kleinen Module ohne externe Antenne und auch mit den bekannten mit dem extra Verstärkerchip
und externer Antenne. Das geht in jeder Kombination.
Sende nur mit 200kBs in bebautem Gebiet und habe damit schon max 120m (sicher) geschafft.
Vereinzelt geht es auch weiter.

Jetzt habe ich die Powermodule dran. Rausgegangen und Reichweite getestet habe ich noch
nicht gemacht. Der Testsender hat ein LCD dran und zeigt mir "gute" und "schlechte"
Aussendungen an.
Klar, wenn der Empfänger aus ist geht der Fehlerzähler hoch.
Aber mit den neuen Modulen zeigt er fast keine Fehler an obwohl der Empfänger aus ist.
Das finde ich schade weil neben der internen Retransmission kann man darauf (wenn es sicher
klappt) eigene Methoden aufsetzen.

Ulli

Du sendest an den Empfänger was und der antwortet dir mit den GPS Daten oder wie?
Und dein Fehlerzähler bleibt stehen obwohl dein Empfänger aus ist? Oder anders herum?

Nein Nein,

viel primitiver. Der Empfänger hat nur das GPS um mir zu zeigen wie weit ich von
zu Hause weg bin.
Der Sender steht fix zu Hause und sendet einfache Zahlen.
Die sehe ich durch blinken einer LED im Empfänger und auf seinem Display.

Der Sender empfängt gar nix. Der kriegt nur im Send normalerweise einen Fehler
wenn kein Empfänger erreichbar ist.

Das ich jetzt zufällig einen fremden Empfänger in Reichweite habe der die selbe Frequenz
und Queue nutzt kann ich nicht glauben.

Ulli

Achso....

Der Sender empfängt gar nix. Der kriegt nur im Send normalerweise einen Fehler
wenn kein Empfänger erreichbar ist.

Dann würde ich mal frei behaupten diese Teile können das nicht. Eigentlich ist dieser Satz auch ein Widerspruch in sich aber ich weiß was du meinst. Da der Empfänger nichts ausstrahlt kann der Sender nicht wissen ob es einen Empfänger gibt. Wenn du diese Funktion brauchst solltest du dich nach anderen Modulen umschauen...

Mit der Sender empfängt 'gar nichts' meinte ich das die Software (meine Software) im Testsender
keine "high level" Antworten erwartet. Also diese Seite hat kein "listen".

Die nrf's haben normalerweise ein Protokoll mit dem der Sender erkennt ob der Empfänger "geackt" hat und
leitet daraus ein "Success" oder "Failed" ab.

Der Sender scheint (fast) immer zufrieden zu sein auch wenn keiner zuhört.

Und können sollte er das schon es ist ja ein "normaler" NRF verbaut.

Ulli

beeblebrox:
Die nrf's haben normalerweise ein Protokoll mit dem der Sender erkennt ob der Empfänger "geackt" hat und
leitet daraus ein "Success" oder "Failed" ab.

Ohne deinen Kode zu sehen weiss niemand ob du dieses Feature auch benutzt,
aber normal ist das schon eingeschaltet.

Heute schaff ich's nicht mehr, aber morgen hänge ich mal Sender und Empfängercode hier rein.

Wie aber schon geschrieben klappt Hard -und Software (bei beiden ist der NRF-Steckbar) liefen
schon mit den kleinen NRF Modulen ohne Ext Antenne und auch mit den einfachen Großen (ohne
Metallgehäuse) mit externen Antennen und auch in allen Mischformen, also :
Groß Groß
Klein Groß
Groß Klein
Klein Klein.

Immer funktionierte das Feature -> Empfänger aus -> Errorcounter im Sender geht hoch !.

Ulli

Vielleicht braucht der besonders leistungsfähige Modul noch mehr (Spitzen-)Strom,
einen Kondensator hast du ja sicher sowieso schon auf den Modulen oder in der Nähe des Steckers, oder?

Gerade mal die beiden neuen Module untereinander getauscht.
Jetzt meldet der Sender ganz selten mal einen Sendefehler.
Mal eins von den alten Sendemodulen wieder reingesteckt (mit externer Antenne), das meldet brav die Fehler
und verbindet sich auch mit einem der neuen Modulen im Empfänger.

Ich glaube da habe ich irgendwelche nicht ganz kompatible Chinachips erwischt. Hat man ja schon mal gelesen.

Zuerst der Testsender (Achtung: Nicht auf Schönheit gucken, alles aus anderen Projekten geraubt, halt ein Test)

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


RF24 radio(A0, 10);
#define BASECHANNEL 42

LiquidCrystal_I2C lcd(0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE); // OLD I2C

typedef struct d
{
  uint16_t key;
  uint16_t dip;
  uint16_t pwr;
} data;

uint64_t addresses[8] = {0xE8E8F0F0E1LL,0xE8E8F0F0E2LL,0xE8E8F0F0E3LL,0xE8E8F0F0E4LL,
                         0xE8E8F0F0E5LL,0xE8E8F0F0E6LL,0xE8E8F0F0E7LL,0xE8E8F0F0E8LL};

data     dataRead;
uint64_t sendQueue; // Variable Sendque

void setup()
{ 
  uint8_t queue;

  lcd.begin(20,4);
  lcd.setCursor(0,0);
  lcd.print("NR24 Testsender V1.0");
  lcd.setCursor(0,1);
  pinMode(A0,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(SS,OUTPUT);

  radio.begin();
  radio.setChannel(BASECHANNEL); // geht nur in Stellung 000
  
  // Set the PA Level low to prevent power supply related issues since this is a
  // getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default.
  
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_250KBPS);
  radio.setRetries(10, 15);
  
  // Open a writing and reading pipe on each radio, with opposite addresses
  
  sendQueue = addresses[0];
  
  radio.openWritingPipe(sendQueue);

  dataRead.key = 0;
}

//
//-----------------------------------
//

uint32_t failed = 0;
uint32_t good   = 0;
char dispBuffer[40];

void loop() 
{
  uint8_t  pipeNr;
  uint16_t gap;
  uint8_t  row;

  dataRead.key++;
  if (dataRead.key >= 10000)
  {
    dataRead.key = 0;
  }

  delay(1000);
  lcd.setCursor(0,1);
  sprintf(dispBuffer,"Sending key   : %04d",dataRead.key);
  lcd.print(dispBuffer);
  if (!radio.write(&dataRead,sizeof(data)))
  {
    lcd.setCursor(0,3);

    failed++;
    sprintf(dispBuffer,"Sending failed: %04d",failed);
    lcd.print(dispBuffer);
  }
  else
  {
    good++;
    lcd.setCursor(0,2);
    sprintf(dispBuffer,"Sending good  : %04d",good);
    lcd.print(dispBuffer);
  }
 
} // Loop

Und zu Allem Überfluss auch noch den Empfänger (Homefinder genannt, der weis halt wo ich wohne :slight_smile: )

#include <SoftwareSerial.h>

#include <TinyGPS.h>
#include <Wire.h>
#include "RF24.h"
#include <TimerOne.h>

#include <LiquidCrystal_I2C.h>

#define I2C_ADRESS 0x27
LiquidCrystal_I2C lcd(I2C_ADRESS, 2, 1, 0, 4, 5, 6, 7,3,POSITIVE); // Neuer Adapter

TinyGPS gps;
SoftwareSerial ss(4, 3);

typedef struct d
{
  uint16_t key;
  uint16_t dip;
  uint16_t pwr;
} data;

uint64_t addresses[8] = {0xE8E8F0F0E1LL,0xE8E8F0F0E2LL,0xE8E8F0F0E3LL,0xE8E8F0F0E4LL,
                         0xE8E8F0F0E5LL,0xE8E8F0F0E6LL,0xE8E8F0F0E7LL,0xE8E8F0F0E8LL};
RF24 radio(A0, 10);

#define BASECHANNEL 42

const uint16_t BlinkPin = 2;

static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);

uint16_t giveVoltage()
{
  .
  .
  .
  return(uin);
}

void setup()
{
  Serial.begin(9600);
  ss.begin(9600);    // SoftwareSerial starten

  Timer1.initialize(600000);

  radio.begin();
  radio.setChannel(BASECHANNEL); // geht nur in Stellung 000
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_250KBPS);
  radio.setRetries(10, 15);
  
  radio.openReadingPipe(1, addresses[0]);
  radio.startListening();                 // Start listening

  pinMode(BlinkPin,OUTPUT);
  digitalWrite(BlinkPin,HIGH);

  lcd.begin(16, 2);
  lcd.setCursor(0,0);
  lcd.print("Homefinder V1.3");

  delay(4000);
  digitalWrite(BlinkPin,LOW);
  lcd.setCursor(0,0);
  lcd.print("                ");
}


//-----------------------------------------------
// Led blinken lassen 
//-----------------------------------------------

uint16_t blinking = false;

void DoBlink()
{
  digitalWrite(BlinkPin,!digitalRead(BlinkPin));
}

void StartBlink()
{
  if (! blinking)
  {
    Timer1.attachInterrupt(DoBlink);
    blinking = true;
  }
}

void StopBlink()
{
  if (blinking)
  {
    Timer1.detachInterrupt();
    digitalWrite(BlinkPin,LOW);
    blinking = false;
  }
}


char dispBuffer[17];
static int flag = true;
static int cnt  = 0;

uint32_t lastDataGot = 0;
data     dataRead;

void loop()
{
  float flat, flon;
  unsigned long age, date, time, chars = 0;
  unsigned short sentences = 0, failed = 0;
  // static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
  static const double LONDON_LAT = 51.545120, LONDON_LON = 7.328589; // Grimbergstasse 5
  static int   sats;
  static float alt;
  static int   dist;
  static float speed;
  static int   v;

  sats = gps.satellites();
  lcd.setCursor(0,0); 

  if (flag)
  {
    lcd.print("S");
    if (sats == TinyGPS::GPS_INVALID_SATELLITES)
    {  
      lcd.print("-- ");
    }
    else
    {
      sprintf(dispBuffer,"%02d ",sats);
      lcd.print(dispBuffer);
    }
    smartdelay(0);
  }
  else
  {
    v=giveVoltage();
    sprintf(dispBuffer,"%1d.%1dV",v / 1000,(v % 1000) / 100);
    lcd.print(dispBuffer);
  }

  gps.f_get_position(&flat, &flon, &age);
  print_date(gps);
  smartdelay(0);

  lcd.setCursor(10,0);


  if (flag)
  {
    lcd.print("H");
    alt = gps.f_altitude();
    smartdelay(0);

    if (alt == TinyGPS::GPS_INVALID_F_ALTITUDE)
    {
      lcd.print("xxx.x");
    }
    else
    {
      if (alt < 100.0) lcd.print(" ");
      if (alt < 10.0)  lcd.print(" ");
      lcd.print(alt,1);
    }
  }
  else
  {
    lcd.print("S");
    speed = gps.f_speed_kmph();
    if (speed < 100) lcd.print(" ");
    if (speed < 10 ) lcd.print(" ");
    lcd.print(speed,1);
  }

  smartdelay(0);

  lcd.setCursor(0,1);
  if (flat == TinyGPS::GPS_INVALID_F_ANGLE)
  {
    lcd.print("D####Km *** ");
    smartdelay(0);
  }
  else
  {
    dist = (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON);
    if (dist > 9999)
    {
      if (dist < 10000)
      {
        sprintf(dispBuffer,"D%1d.%02dKm",dist / 1000,dist % 1000);
      }
      else
      {
        if (dist < 100000)
        {
          sprintf(dispBuffer,"D%2d.%01dKm",dist / 1000,dist % 1000);
        }
        else
        {
          sprintf(dispBuffer,"D%04dKm ",dist / 1000);
        }
      }
    }
    else
    {
      sprintf(dispBuffer,"D %04dm ",dist);
    }
    smartdelay(0);
    lcd.print(dispBuffer);
    sprintf(dispBuffer,"%-3s ",TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)));
    lcd.print(dispBuffer);
    smartdelay(0);
  }
  
  cnt++;
  if (cnt == 5)
  {
    flag = !flag;
    cnt = 0;
  }
  smartdelay(500);

  if (radio.available())
  {
    radio.read(&dataRead,sizeof(data));
    sprintf(dispBuffer,"%04d",dataRead.key % 10000);
    lcd.print(dispBuffer);
    lastDataGot = millis();
    StartBlink();
  }

  if ((millis() - lastDataGot) > 1200)
  {
    lcd.print("----");
    StopBlink();
  }
}

static void smartdelay(unsigned long ms)
{
  unsigned long start = millis();
  do 
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

static void print_date(TinyGPS &gps)
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;

  lcd.setCursor(4,0);
  
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);

  hour = hour + 2;
  if (hour >= 24)
  {
    hour = hour - 24;
  }
  if (age == TinyGPS::GPS_INVALID_AGE)
  {
    lcd.print("++:++");
  }
  else
  {
    sprintf(dispBuffer,"%02d:%02d",hour,minute);
    lcd.print(dispBuffer);
  }
  smartdelay(0);
}

Ulli
p.s. Beim Empfänger musste ich die "Spannungsmessfunktion" raus nehmen weil das Posting sonst zu lang ist.

Whandall:
Vielleicht braucht der besonders leistungsfähige Modul noch mehr (Spitzen-)Strom,
einen Kondensator hast du ja sicher sowieso schon auf den Modulen oder in der Nähe des Steckers, oder?

Jau,

Kondensatoren habe ich direkt aufs Modul gelötet (10µF + 100nF). Hat sich bewährt.

Es macht ja auch kein Problem mit dem Senden, geht ja (prima). Es meldet nur keinen Fehler wenn keiner zuhört !
Und das kann ich - beim besten Willen - nicht auf den zu kleinen Kondensator schieben.

Es tritt ja nicht etwa ein Fehler auf obwohl alles gut ist, dann könnte ich mir vorstellen das das ACK aufgrund des
fehlenden Cs nicht kommt.
Aber es kommt ja gar kein ACK weil niemand eingeschaltet ist, .....

Ulli

Ist schon etwas merkwürdig.
Der Kode sollte er bei nicht vorhandenem Empfängern Fehler liefern.

Was passiert auf einem anderen Channel, was mit niedriger Sendeleistung?

Deine Betriebsparameter sind eher auf 1000m+ ausgelegt, aber das sollte ja bei dem Fehler kein Problem darstellen.
Ich habe diese Variante von NRFs (noch) nicht, kann es also nicht gegentesten.

Stell die Adressen mal auf byte Format um, ansonsten könnte man leicht den Eindruck bekommen,
dass du die ManiacBug Library benutzt.

Dynamic payloads könntest du auch erlauben, dann werden deine Pakete kleiner und damit schneller.

Meinst du die QueueAdressen ? Hatte ich so aus den Beispielen der Lib.

Und die Sendeleistung wollte ich ja gerne maximal haben da ich Reichweitentests machen will.

Mal schauen, am WE probiere ich mal andere Leistungen, Kanäle und Übertragungsgeschwindigkeiten.

Ulli

Ja, ich meine die hässlichen uint64_t Monstren.

Also auf ein 8x8 Char array mit entsprechenden Nullen oder was meinst du ?
Und warum wenn es doch so in den Beispielen steht ?

Ulli

Die Adressregister sind 5 Byte lang, es reicht also z.B. jeder String.

const byte adrs[] = "1Node" "2Node" "3Node";

  radio.openReadingPipe(1, adrs + 5);

Nimmt weniger Platz weg, ist besser lesbar, zudem ist die uint64_t Version deprecated.

beeblebrox:
Und warum wenn es doch so in den Beispielen steht ?

Mit dem Argument könnte man auch für delay() plädieren. :wink:

P.S. in meinen Beispielen (hier GettingStarted) steht aber

byte addresses[][6] = {"1Node","2Node"};

Bist du sicher, dass du nicht doch die ManiacBug Library benutzt?

ICH GLAUBE ES NICHT (ja das war geschrien).
Den Raum mit dem Sender gewechselt. Hmm. Plötzlich wird fast jeder 2te Fehler gezeigt.

Ich denke "wechselse mal die Frequenz". Also von 42 :slight_smile: auf 84 gegangen !
Erst den Empfänger programmiert. OK.
Jetzt den Sender. Kaum hängt der Sender an meinem Notebook .... der Fehlercounter zählt wie nix.

Der Sender ist ein normaler UNO, den habe ich weil es gerade in der Nähe lag an so einer Zwischesteckdose
mit 2 USB-Anschlüssen betrieben. Mit der Lade ich auch meine Handys und allerhand USB-Akkus.
Mit den anderen NRF-Varianten war das kein Problem. Jetzt habe ich ein bewährtes gutes USB-Netzteil
dran und alles geht wie es soll ! Ich denke mal da hat der (besser geschirmte) NRF Probleme
mit zu viel Schaltreglerschmutz gehabt.

Mit so einem Netzteil hatte ich schon mal Ärger weil meine DCF77 (mit einem Atemega 1284) plötzlich
nichts mehr empfing obwohl die LED für den Empfang - ich sag mal wie gewohnt die Nullen und Einsen anzeigte.
Der hing noch nicht mal an dem Teil. Das war so ein "schlechtes" USB Netzteil. Da musste nur im selben
Raum ein Handy laden und der DCF - Empfang war platt.
Ist inzwischen mein Test für die Dinger. Immer in der Nähe der Funkuhr ausprobieren.
Diese Steckdose hat aber nie Ärger gemacht.
Egal, Grund gefunden.

Ulli

Dennoch ein merkwürdiger Effekt.

Mal alle Beispiele durchgeguckt : In einigen ist es auch mit Node1,Node2 so wie du es
geschrieben hast gemacht.

Es ist die RF24.lib .

Ulli

p.s. Läuft jetzt seit einer halben Stunde ohne Empfänger -> nur Fehler ->
Empfänger gerade angemacht : Klappt !

Jetzt gehe ich mal in die Kälte Reichweite messen :-).

Ulli

WOW.

Die Module sind klasse. In bebautem Wohngebiet über 350m !!! (auf kleinster Übertragungsrate)
Morgen gehe ich mal in die andere Richtung da ist die Bebauung weg - hmm - ist aber nach einigen
Metern ein Hügel im Weg. Mal schauen.

Ich habe sogar noch in größerer Entfernung Empfang gehabt, wurde aber - ich sag mal -
sporadischer. Wahrscheinlich über Reflexionen. Ich habe es nicht weiter auf die Spitze gerieben
aber ich denke so 500m sind auch in bebautem Gebiet drin. Man sollte dann halt noch ein eigenes
Protokoll mit entsprechenden Wiederholungen und ACK/NACK einbauen.

Mal gucken was ich jetzt aus den Erkenntnissen machen :wink: . Eine Anwendung habe ich eigentlich
noch gar nicht :slight_smile: .

Ulli

Ich habe gestern noch mal einen Reichweitentest mit diesen Modulen durchgeführt.
Sender aufs Dach in eine offene Dachluke und dann in die Natur mit weniger Bebauung
gelaufen. Bis fast 600m konstanter Empfang :slight_smile: . Noch weiter wurde es Sporadisch aber ging
immer noch. Also die Teile sind schon klasse.
Ich muss dabei sagen das die Landschaft immer noch nicht ideal war.
Ein Haus lag mindestens dazwischen und dann ging es ziemlich straigth einen Berg runter
so das ich mir nicht sicher bin ob noch "Sichtweite" vorlag oder schon der Berg dazwischen lag.

In Kombination mit den kleinen NRFs ohne externe Antenne ergibt sich im Haus
über 3 Stockwerke bis in den Keller eine stabile Kommunikation.
Die "Superreichweite" außerhalb des Hauses bleibt allerdings aus (etwas besser ist es schon).

Ulli