nRf24L01+ connection quality meter
-
A little frustrated by radio's showing inconsistent behaviour I built a simple connection quality meter with a leftover of a previous project.
Not too complicated ;-) a nano, I2C lcd display, radio adapter board (guarantees a stable power supply for the radio) and the radio to be tested.
a little hot glue and it fits nicely in the box. The radio can be swapped on the outside. Power comes in from a power bank connected to the nano USB so that I can walk around the house.
The sketch sends values from 0..99 to a gateway with "ack" enabled. The LCD shows the "failed" sends and the number of not acknowledged messages. i.e. the messages which did not arrive at the gateway or did not make it on their return flight.
It now takes less than a minute to sort the radio's :bowtie:
-
@AWI
Thanks for the idea! This can become very useful in deciding at which locations a repeater can be used to solve my coverage problem. In my setup I'm facing difficulties getting the signal through a glass pane at the rear of my house.
Same question as @flopp: putting the code in here would be very usefulThanks,
Boozz
-
@AWI is that hardware ack or software ack? (The MySensors ack confusion is driving me insane)
@mfalkvidd my interpretation and based on experience:
- fail (hardware ack..) is the node to node acknowledgement. (i.e. from node to repeater or gateway). Can not be switched on/off from the API. This is the return value from the send() function (or gw.send()). If a fail occurs the node tries multiple times to resend (this can take quitte a lot of time..) This acknowledgement is only from the next node in line.
- missed (software ack) is the node to destination acknowledgement (i.e. node - repeater - gateway) . Can (and should) be enabled in the send() function. The acknowledgement is send automatically by the destination node in the form of an "echo" of the message sent. No automatic resend happens. Eventual action should be taken by the sender (controller / sketch in node).
The "connection quality meter" measures the number of fails and averages this for 100 samples (percentate) and similar for not acknowledged "software ack's".
Ik will post the sketch later today..
-
The sketch for the connection quality meter.
/* PROJECT: MySensors / Quality of radio transmission PROGRAMMER: AWI (MySensors libraries) DATE: 20160529/ last update: 20160530 FILE: AWI_Send.ino LICENSE: Public domain Hardware: ATMega328p board w/ NRF24l01 and MySensors 2.0 (Development) Special: Summary: Sends a radio message with counter each x time to determine fault ratio with receiver Remarks: Fixed node-id & communication channel to other fixed node Change log: 20160530 - added moving average on fail/ miss count */ //**** MySensors ***** // Enable debug prints to serial monitor #define MY_DEBUG #define MY_RADIO_NRF24 // Enable and select radio type attached #define MY_RF24_CHANNEL 80 // radio channel, default = 76 #define MY_NODE_ID 250 #define NODE_TXT "Q 250" // Text to add to sensor name // #define MY_RF24_CE_PIN 7 // Ceech board, 3.3v (7,8) (pin default 9,10) // #define MY_RF24_CS_PIN 8 #define DESTINATION_NODE 0 // receiving fixed node id (default 0 = gateway) #include <SPI.h> #include <MySensor.h> // display #include <Wire.h> // I2C #include <LiquidCrystal_I2C.h> // LCD display with I2C interface // helpers #define LOCAL_DEBUG #ifdef LOCAL_DEBUG #define Sprint(a) (Serial.print(a)) // macro as substitute for print, enable if no print wanted #define Sprintln(a) (Serial.println(a)) // macro as substitute for println #else #define Sprint(a) // enable if no print wanted -or- #define Sprintln(a) // enable if no print wanted #endif // MySensors sensor #define counterChild 0 // send constants and variables int messageCounter = 0 ; const int messageCounterMax = 100 ; // maximum message counter value const unsigned counterUpdateDelay = 100 ; // send every x ms and sleep in between // receive constants and variables boolean failStore[messageCounterMax] ; // moving average stores & pointers int failStorePointer = 0 ; boolean missedStore[messageCounterMax] ; int missedStorePointer = 0 ; int newMessage = 0 ; int lastMessage = -1 ; int missedMessageCounter = 0 ; // total number of messages in range (messageCounterMax) int failMessageCounter = 0 ; // total number of messages in range (messageCounterMax) // Loop delays const unsigned long displayInterval = 1000UL ; // display update in ms unsigned long lastDisplayUpdate = 0 ; // last update for loop timers // standard messages MyMessage counterMsg(counterChild, V_PERCENTAGE); // Send value // ***** LCD LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address void setup() { Wire.begin(); // I2C // ** LCD display ** // LCD 2 lines * 16 char. lcd.begin(16, 2); lcd.setBacklight(HIGH); lcd.setCursor(0, 0); lcd.print("AWI Quality nRF24"); for(int i= 0 ; i < messageCounterMax ; i++){ // init stores for moving averages failStore[i] = true ; missedStore[i] = true ; } missedStorePointer = failStorePointer = 0 ; delay(1000); } void presentation(){ // MySensors present(counterChild, S_DIMMER, "Quality counter " NODE_TXT) ; // counter uses percentage from dimmer value } void loop() { // Sprint("count:") ; Sprintln(messageCounter) ; LCD_local_display(); missedStore[failStorePointer] = false ; // set slot to false (ack message needs to set) ; boolean succes = failStore[failStorePointer] = send(counterMsg.setDestination(DESTINATION_NODE).set(failStorePointer), true); // send to destination with ack if (!succes){ failMessageCounter++ ; Sprint("Fail on message: ") ; Sprint(failStorePointer) ; Sprint(" # ") ; Sprintln(failMessageCounter); } failStorePointer++ ; if(failStorePointer >= messageCounterMax){ failStorePointer = 0 ; // wrap counter } wait(counterUpdateDelay) ; // wait for things to settle and ack's to arrive } void receive(const MyMessage &message) { // Expect few types of messages from controller newMessage = message.getInt(); // get received value switch (message.type){ case V_PERCENTAGE: missedStore[newMessage] = true ; // set corresponding flag to received. if (newMessage > lastMessage){ // number of messages missed from lastMessage (kind of, faulty at wrap) Sprint("Missed messages: ") ; Sprintln( newMessage - lastMessage - 1) ; missedMessageCounter += newMessage - lastMessage - 1 ; } lastMessage = newMessage ; break ; default: break ; } } // calculate number of false values in array // takes a lot of time, but who cares... int getCount(boolean countArray[], int size){ int falseCount = 0 ; for (int i = 0 ; i < size ; i++){ falseCount += countArray[i]?0:1 ; } return falseCount ; } void LCD_local_display(void){ /* prints all available variables on LCD display with units */ char buf[17]; // buffer for max 16 char display lcd.setCursor(0, 0); snprintf(buf, sizeof buf, "Failed:%4d %3d%%", failMessageCounter, getCount(failStore, messageCounterMax)); lcd.print(buf); lcd.setCursor(0, 1); snprintf(buf, sizeof buf, "Missed:%4d %3d%%", missedMessageCounter, getCount(missedStore, messageCounterMax)); lcd.print(buf); } -
I have been walking through and around the house with the meter to find the best radio solutions. So far I have the best reach with the nRF24L01+PA+LNA with the plastic/ aluminum foil (the ugly fix ;-), credits @Oitzu).
b.t.w. I added "parent" and "destination" node to the display to show where the meter is connected to. Destination is fixed in the sketch but the "parent" will change if the meter connects to another node (i.e. repeater)
To give you a real life impression . The transmitter (also nRF24L01+PA+LNA) is where the red arrow is behind two thick brick walls and a few trees. So, unless you live in a big mansion this should be sufficient range. Open field performance would be much better.
For the rest of the tests I had a large variance in results. Some general observations:
-
nRF24L01+PA+LNA without the "shielding" is pretty similar (and sometimes even worse) than the standard radio with the pcb antenna.
-
all nRF24L01+ in SMD version have a comparable performance to the standard ones
-
The standard radio's I have tested with a silk screen (white lines) and pin designation print on the back seem to be fine.
-
The (around 18) radio's is have tested without silk screen (3 different batches) are either "bad" performers (few meters) or don't perform at all. ( I noticed earlier and already put them apart. I was able to sort out 6 that can be used for short distance.).
-
I don;t have any "blob" samples..
I know this is far from scientific proof, but hope it gives you some guidance..
-
-
I have been walking through and around the house with the meter to find the best radio solutions. So far I have the best reach with the nRF24L01+PA+LNA with the plastic/ aluminum foil (the ugly fix ;-), credits @Oitzu).
b.t.w. I added "parent" and "destination" node to the display to show where the meter is connected to. Destination is fixed in the sketch but the "parent" will change if the meter connects to another node (i.e. repeater)
To give you a real life impression . The transmitter (also nRF24L01+PA+LNA) is where the red arrow is behind two thick brick walls and a few trees. So, unless you live in a big mansion this should be sufficient range. Open field performance would be much better.
For the rest of the tests I had a large variance in results. Some general observations:
-
nRF24L01+PA+LNA without the "shielding" is pretty similar (and sometimes even worse) than the standard radio with the pcb antenna.
-
all nRF24L01+ in SMD version have a comparable performance to the standard ones
-
The standard radio's I have tested with a silk screen (white lines) and pin designation print on the back seem to be fine.
-
The (around 18) radio's is have tested without silk screen (3 different batches) are either "bad" performers (few meters) or don't perform at all. ( I noticed earlier and already put them apart. I was able to sort out 6 that can be used for short distance.).
-
I don;t have any "blob" samples..
I know this is far from scientific proof, but hope it gives you some guidance..
@AWI said:
The standard radio's I have tested with a silk screen (white lines) and pin designation print on the back seem to be fine
In the picture, these radios have the notorious 1242AF datecode on the chip (if you didn't take the pictures yourself, do you have the same date code?). I also have a batch of these and they perform very well!
-
-
Thanks @awi for this, might have to build one myself to test a potential bad batch of radios i have.
Do you need the LCD for this or is the data also print in serial?
Thanks,
@drock1985 It will print the data on serial but not very well formatted. You don't need the LCD but it is easy to carry around the house. (a laptop too :smiley: but be aware of disturbances coming from the laptop i.e. Wifi ) I thought off blinking led's also. You can easily change the sketch, there is not much to it..
-
I'm having a problem in this part off the code:
"present(counterChild, S_DIMMER, "Quality counter " NODE_TXT) ; // counter uses percentage from dimmer value"I'm getting this error:
"exit status 1
'present' was not declared in this scope"How can i fix this ?
-
I'm having a problem in this part off the code:
"present(counterChild, S_DIMMER, "Quality counter " NODE_TXT) ; // counter uses percentage from dimmer value"I'm getting this error:
"exit status 1
'present' was not declared in this scope"How can i fix this ?