While testing my initial port of the the techfooninja nRF24L01P library to a Wilderness Labs Meadow I noticed that the power level value was a bit odd.

The program '[16720] App.exe' has exited with code 0 (0x0).
IsPowered: True
Address: Dev01
PA: 15
IsAutoAcknowledge: True
Channel: 15
DataRate: DR250Kbps
Power: 15
IsDynamicAcknowledge: False
IsDynamicPayload: True
IsEnabled: False
Frequency: 2415
IsInitialized: True
IsPowered: True
00:00:18-TX 8 byte message hello 17
Data Sent!
00:00:18-TX Succeeded!
00:00:48-TX 8 byte message hello 48
Data Sent!
Looking at nRF24L01P datasheet and how this has been translated into code
/// <summary>
/// The power level for the radio.
/// </summary>
public PowerLevel PowerLevel
{
get
{
var regValue = Execute(Commands.R_REGISTER, Registers.RF_SETUP, new byte[1])[1] & 0xF8;
var newValue = (regValue - 1) >> 1;
return (PowerLevel)newValue;
}
set
{
var regValue = Execute(Commands.R_REGISTER, Registers.RF_SETUP, new byte[1])[1] & 0xF8;
byte newValue = (byte)((byte)value << 1 + 1);
Execute(Commands.W_REGISTER, Registers.RF_SETUP,
new[]
{
(byte) (newValue | regValue)
});
}
}
The power level enumeration is declared in PowerLevel.cs
namespace Radios.RF24
{
/// <summary>
/// Power levels the radio can operate with
/// </summary>
public enum PowerLevel : byte
{
/// <summary>
/// Minimum power setting for the radio
/// </summary>
Minimum = 0,
/// <summary>
/// Low power setting for the radio
/// </summary>
Low,
/// <summary>
/// High power setting for the radio
/// </summary>
High,
/// <summary>
/// Max power setting for the radio
/// </summary>
Max,
/// <summary>
/// Error with the power setting
/// </summary>
Error
}
}
No debugging support or Debug.WriteLine in beta 3.7 (March 2020) so first step was to insert a Console.Writeline so I could see what the RF_SETUP register value was.
The program '[11212] App.exe' has exited with code 0 (0x0).
Address: Dev01
PowerLevel regValue 00100101
PowerLevel: 15
IsAutoAcknowledge: True
Channel: 15
DataRate: DR250Kbps
IsDynamicAcknowledge: False
IsDynamicPayload: True
IsEnabled: False
Frequency: 2415
IsInitialized: True
IsPowered: True
00:00:18-TX 8 byte message hello 17
Data Sent!
00:00:18-TX Succeeded!
The PowerLevel setting appeared to make no difference and the bits 5, 2 & 0 were set which meant 250Kbps & high power which I was expecting.
The RF_SETUP register in the datasheet, contains the following settings (WARNING – some nRF24L01 registers differ from nRF24L01P)

After looking at the code my initial “quick n dirty” fix was to mask out the existing power level bits and then mask in the new setting.
public PowerLevel PowerLevel
{
get
{
byte regValue = Execute(Commands.R_REGISTER, Registers.RF_SETUP, new byte[1])[1];;
Console.WriteLine($"PowerLevel regValue {Convert.ToString(regValue, 2).PadLeft(8, '0')}");
var newValue = (regValue & 0x06) >> 1;
return (PowerLevel)newValue;
}
set
{
byte regValue = Execute(Commands.R_REGISTER, Registers.RF_SETUP, new byte[1])[1];
regValue &= 0b11111000;
regValue |= (byte)((byte)value << 1);
Execute(Commands.W_REGISTER, Registers.RF_SETUP,
new[]
{
(byte)regValue
});
}
}
I wonder if the code mighty be simpler if I used a similar approach to my Windows 10 IoT RFM9X LoRa library
// RegModemConfig1
public enum RegModemConfigBandwidth : byte
{
_7_8KHz = 0b00000000,
_10_4KHz = 0b00010000,
_15_6KHz = 0b00100000,
_20_8KHz = 0b00110000,
_31_25KHz = 0b01000000,
_41_7KHz = 0b01010000,
_62_5KHz = 0b01100000,
_125KHz = 0b01110000,
_250KHz = 0b10000000,
_500KHz = 0b10010000
}
public const RegModemConfigBandwidth RegModemConfigBandwidthDefault = RegModemConfigBandwidth._125KHz;
...
[Flags]
enum RegIrqFlagsMask : byte
{
RxTimeoutMask = 0b10000000,
RxDoneMask = 0b01000000,
PayLoadCrcErrorMask = 0b00100000,
ValidHeadrerMask = 0b00010000,
TxDoneMask = 0b00001000,
CadDoneMask = 0b00000100,
FhssChangeChannelMask = 0b00000010,
CadDetectedMask = 0b00000001,
}
[Flags]
enum RegIrqFlags : byte
{
RxTimeout = 0b10000000,
RxDone = 0b01000000,
PayLoadCrcError = 0b00100000,
ValidHeadrer = 0b00010000,
TxDone = 0b00001000,
CadDone = 0b00000100,
FhssChangeChannel = 0b00000010,
CadDetected = 0b00000001,
ClearAll = 0b11111111,
}
This would require some significant modifications to the Techfooninja library. e.g. the PowerLevel enumeration
namespace Radios.RF24
{
/// <summary>
/// Power levels the radio can operate with
/// </summary>
public enum PowerLevel : byte
{
/// <summary>
/// Minimum power setting for the radio
/// </summary>
Minimum = 0b00000000,
/// <summary>
/// Low power setting for the radio
/// </summary>
Low = 0b00000010,
/// <summary>
/// High power setting for the radio
/// </summary>
High = 0b00000100,
/// <summary>
/// Max power setting for the radio
/// </summary>
Max = 0b00000110,
}
}
I need to do some more testing of the of library to see if the pattern is repeated.
Pingback: TinyCLR OS V2 nRF24L01 library Part2 | devMobile's blog
Pingback: nanoFramework nRF24L01 library Part2 | devMobile's blog