Go Down

Topic: nRF24L01 (Read 162 times) previous topic - next topic

ctcombs0351

Hey everyone, I'm new to Arduino and this forum also. So much so in fact that Im not how to start a new discussion. I am trying to send 6 axis IMU data from a MEGA to a nano using the NRF24.


Receiver code...

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

RF24 radio(7, 8 ); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};

uint8_t pitchYaw[2]; //my attempt at an array

void setup() {
  Serial.begin(115200);
  radio.begin();
  radio.openWritingPipe(addresses[0]); // 00001
  radio.openReadingPipe(1, addresses[1]); // 00002
  radio.setPALevel(RF24_PA_MIN);

}
void loop() {
  radio.startListening();
  if ( radio.available()) {
    while (radio.available()) {
      radio.read( &pitchYaw[2], sizeof(pitchYaw[2]));//my attempt at an array
      Serial.println(pitchYaw[2]);//my attempt at an array
    }
  }
}


Transmitter code...

#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include "Wire.h"

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

RF24 radio(7, 8 ); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};

uint8_t pitchYaw[2]; //my attempt at an array

MPU6050 mpu;

#define OUTPUT_READABLE_QUATERNION

#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
bool blinkState = false;

bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };

volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
    mpuInterrupt = true;
}

void setup() {

    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    //Serial.begin(115200);
    //while (!Serial); // wait for Leonardo enumeration, others continue immediately
   
    mpu.initialize();
   
    devStatus = mpu.dmpInitialize();

    mpu.setXGyroOffset(220);
    mpu.setYGyroOffset(76);
    mpu.setZGyroOffset(-85);
    mpu.setZAccelOffset(1788); // 1688 factory default for my test chip

    if (devStatus == 0) {
     
        mpu.setDMPEnabled(true);

        attachInterrupt(0, dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();

        dmpReady = true;

        packetSize = mpu.dmpGetFIFOPacketSize();
    //} else {

        //Serial.print(F("DMP Initialization failed (code "));
        //Serial.print(devStatus);
        //Serial.println(F(")"));
    }

    // configure LED for output
    pinMode(LED_PIN, OUTPUT);
   
    radio.begin();
    radio.openWritingPipe(addresses[1]); // 00002
    radio.openReadingPipe(1, addresses[0]); // 00001
    radio.setPALevel(RF24_PA_MIN);

}

void loop() {

    if (!dmpReady) return;

    while (!mpuInterrupt && fifoCount < packetSize) {

    }

    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();

    // get current FIFO count
    fifoCount = mpu.getFIFOCount();

    if ((mpuIntStatus & 0x10) || fifoCount == 1024) {

        mpu.resetFIFO();

    } else if (mpuIntStatus & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

        mpu.getFIFOBytes(fifoBuffer, packetSize);

        fifoCount -= packetSize;

        #ifdef OUTPUT_READABLE_QUATERNION
            // display quaternion values in easy matrix form: w x y z
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            //Serial.print(q.w);
            //Serial.print(" ");
            //Serial.print(q.x);
            //Serial.print(" ");
            //Serial.print(q.y);
            //Serial.print(" ");
            //Serial.print(q.z);
            //Serial.print(" ");
            //Serial.println("end");
        #endif

        blinkState = !blinkState;
        digitalWrite(LED_PIN, blinkState);
    }
   
    radio.stopListening();
    pitchYaw[0] = (q.x);//my attempt at an array
    pitchYaw[1] = (q.z);//my attempt at an array
    //int angleValue = map(XVAL, 0, 1023, 0, 180);
    //int angleValue = map(YVAL, 0, 1023, 0, 180);
    radio.write(&pitchYaw[2], sizeof(pitchYaw[2]));//my attempt at an array
    //Serial.println(q.x, q.z);



The IMU works and sends out valid data on the nano's serial port. I modified the receiver code from an example sketch and tested both transmit (on the NANO) and receive (on the MEGA) with sending a "hello world" message to make sure the boards are communicating through the NRF's.

Im pretty sure the problem lies in the use of the array i have named as pitchYaw in the code. Everything uploads with no errors but I have tried using the array i can't seem to get anything out on the receiver's serial monitor. The array may not be the way to go, but all i need is to be able to get the IMU data over and I can finish this thing up. I imagine the solution is really simple but i am stuck, please help  :o

UKHeliBob

Quote
Hey everyone, I'm new to Arduino and this forum also. So much so in fact that Im not how to start a new discussion.
The "NEW TOPIC" button would have been a good place to start

Your post has been split from the one that you hijacked
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Robin2

Have a look at this Simple nRF24L01+ Tutorial.

Wireless problems can be very difficult to debug so get the wireless part working on its own before you start adding any other features.

The examples are as simple as I could make them and they have worked for other Forum members. If you get stuck it will be easier to help with code that I am familiar with. Start by getting the first example to work

There is also a connection test program to check that the Arduino can talk to the nRF24 it is connected to.

A common problem with nRF24 modules is insufficient 3.3v current from the Arduino 3.3v pin. This seems to be a particular problem with the nano. The high-power nRF24s (with the external antenna) will definitely need an external power supply. At least for testing try powering the nRF24 with a pair of AA alkaline cells (3v) with the battery GND connected to the Arduino GND.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

ctcombs0351

Sorry about that I signed up really fast and hadn't read up on creating a post. I'm just excited to part of the community now. Ok I will upload the code from the tutorial and see if i can get it running. I'm sure I will have some more questions either way. I have a background in industrial electronics and had some formal training with pic micro controllers using c++ but that was years ago and I hadnt utilized the skill since so there has been a curve for me up to this point. I'll see what i can do and message back. Thanks so much.

ctcombs0351

Thanks all for being patient with me. I am new but that isn't an excuse for being prepared. I have read through the guide to posting in the forum and feel that I can better articulate my objectives and the other relevant details this go round.

So for the broader overview I am trying to send over the X value data and the Z rotation data from an MPU6050 attached to a Arduino nano through an NRF24 link to an Arduino Mega. Now I had the MPU6050 code functioning prior to inquiring about getting the NFR link set up. Robin2, I went through the simple tutorial link and followed it through just to make sure I had an NFR24 link that was working. The tutorial example code provided some insights but wasn't really applicable for this project, but I thank you for it.

So at this stage I have successfully been able to send one channel (the X value component) through the link to the MEGA. of course I can send the Z rotation also instead, but I havent been able to send both together. I have still been working with the float array as the raw IMU data comes out in values ranging from negative to positive decimals (ex X = -0.11). I have thought about multiplying by say a factor of 100 so I could send it perhaps as a plain integer, but if the solution is simple enough I would like to keep the values as they are coming from the MPU6050 so it would be less confusing in future debugging. Let me see if i can upload the code properly on this reply...


Transmitting NRF from Arduino NANO and MPU6050

Code: [Select]

#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include "Wire.h"

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

RF24 radio(7, 8); // CE, CSN
const byte addresses[][64] = {"00001", "00002"}; 

MPU6050 mpu;

#define OUTPUT_READABLE_QUATERNION

#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
bool blinkState = false;

bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };

volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
    mpuInterrupt = true;
}

void setup() {

    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    //Serial.begin(115200);
    //while (!Serial); // wait for Leonardo enumeration, others continue immediately
   
    mpu.initialize();
   
    devStatus = mpu.dmpInitialize();

    mpu.setXGyroOffset(220);
    mpu.setYGyroOffset(76);
    mpu.setZGyroOffset(-85);
    mpu.setZAccelOffset(1788); // 1688 factory default for my test chip

    if (devStatus == 0) {
     
        mpu.setDMPEnabled(true);

        attachInterrupt(0, dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();

        dmpReady = true;

        packetSize = mpu.dmpGetFIFOPacketSize();
    //} else {

        //Serial.print(F("DMP Initialization failed (code "));
        //Serial.print(devStatus);
        //Serial.println(F(")"));
    }

    // configure LED for output
    pinMode(LED_PIN, OUTPUT);
     
    radio.begin();
    radio.openWritingPipe(addresses[1]); // 00002
    radio.openReadingPipe(1, addresses[0]); // 00001
    radio.setPALevel(RF24_PA_LOW);

}

void loop() {

    if (!dmpReady) return;

    while (!mpuInterrupt && fifoCount < packetSize) {

    }

    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();

    // get current FIFO count
    fifoCount = mpu.getFIFOCount();

    if ((mpuIntStatus & 0x10) || fifoCount == 1024) {

        mpu.resetFIFO();

    } else if (mpuIntStatus & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

        mpu.getFIFOBytes(fifoBuffer, packetSize);

        fifoCount -= packetSize;

        #ifdef OUTPUT_READABLE_QUATERNION
            // display quaternion values in easy matrix form: w x y z
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            //Serial.print(q.w);
            //Serial.print(" ");
            //Serial.print(q.x);
            //Serial.print(" ");
            //Serial.print(q.y);
            //Serial.print(" ");
            //Serial.print(q.z);
            //Serial.println(" ");
            //Serial.println("end");
        #endif

        blinkState = !blinkState;
        digitalWrite(LED_PIN, blinkState);
    }
   
    radio.stopListening();
    float pitch = (q.x);
    float yaw = (q.z);
    float pitchYaw[2] = {pitch, yaw};
    radio.write(&pitchYaw, sizeof(pitchYaw));




Receiving NRF from Arduino MEGA

Code: [Select]

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

RF24 radio(7, 8); // CE, CSN
const byte addresses[][64] = {"00001", "00002"}; 

void setup() {
  Serial.begin(115200);
  radio.begin();
  radio.openWritingPipe(addresses[0]); // 00001
  radio.openReadingPipe(1, addresses[1]); // 00002
  radio.setPALevel(RF24_PA_LOW);

}
void loop() {
  radio.startListening();
  if ( radio.available()) {
    float pitchYaw=0;
    radio.read( &pitchYaw, sizeof(pitchYaw));
    Serial.println(pitchYaw);
    }
}


Now as I said, at this stage the NRF link is established and i am able to send one channel of the data. I am thinking I am just missing something on the receiver end. I have tried numerous iterations of declaring a float array on the receiver end, declaring pitch and yaw separately, and at this stage best I can figure is that either i am missing something super simple, or i need to be trying to store the data that is coming over in an address and then parsing out the individual components after the fact. I am trying to keep the code as simple as possible because maintaining the lowest latency is key.

I intend to explain the broader project overview in greater detail, but I don't want to convolute the topic at hand with any more detail at this stage. Also, i am aware that the code could be more streamlined, I just haven't had the opportunity to put the effort in on that. Thanks Again, I look forward to more discussion on the matter. 

One more note. In proofing this post, for clarity,

    radio.stopListening();
    float pitch = (q.x);
    float yaw = (q.z);
    float pitchYaw[2] = {pitch, yaw};
    radio.write(&pitchYaw, sizeof(pitchYaw));

This portion of code is from the TX. When I say I can get one channel or the other but not both I mean that I can switch the order of pitch and yaw and vise versa, but all i manage to see on the serial monitor is the value that I list first but not both. Maybe I had said that in a coherent enough thought, but if not I hope that helps.

UKHeliBob

In the Tx code pitchYaw is an array of floats
Code: [Select]
    float pitchYaw[2] = {pitch, yaw};

In the Rx code pitchYaw is a single float
Code: [Select]
    float pitchYaw=0;

Why are they different ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

ctcombs0351

Awesome I got it. I stayed up late and finally figured out a solution. I'll go ahead and post it just for the purpose of if someone else comes along looking for the same or a similar solution. Actually let me post that now because I do have additional questions that i was hoping to get some help with.

Tx from Arduino NANO through NRF link:

Code: [Select]

#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include "Wire.h"

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

RF24 radio(7, 8); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};  
float Xval;
float Zval;
MPU6050 mpu;

#define OUTPUT_READABLE_QUATERNION

#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
bool blinkState = false;

bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };

volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
    mpuInterrupt = true;
}

void setup() {

    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    Serial.begin(115200);
    //while (!Serial); // wait for Leonardo enumeration, others continue immediately
  
    mpu.initialize();
    
    devStatus = mpu.dmpInitialize();

    mpu.setXGyroOffset(220);
    mpu.setYGyroOffset(76);
    mpu.setZGyroOffset(-85);
    mpu.setZAccelOffset(1788); // 1688 factory default for my test chip

    if (devStatus == 0) {
      
        mpu.setDMPEnabled(true);

        attachInterrupt(0, dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();

        dmpReady = true;

        packetSize = mpu.dmpGetFIFOPacketSize();
    //} else {

        //Serial.print(F("DMP Initialization failed (code "));
        //Serial.print(devStatus);
        //Serial.println(F(")"));
    }

    // configure LED for output
    pinMode(LED_PIN, OUTPUT);
    
    radio.begin();
    radio.openWritingPipe(addresses[1]); // 00002
    radio.openReadingPipe(1, addresses[0]); // 00001
    radio.setPALevel(RF24_PA_LOW);

}

void loop() {

    if (!dmpReady) return;

    while (!mpuInterrupt && fifoCount < packetSize) {

    }

    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();

    // get current FIFO count
    fifoCount = mpu.getFIFOCount();

    if ((mpuIntStatus & 0x10) || fifoCount == 1024) {

        mpu.resetFIFO();

    } else if (mpuIntStatus & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

        mpu.getFIFOBytes(fifoBuffer, packetSize);

        fifoCount -= packetSize;

        #ifdef OUTPUT_READABLE_QUATERNION
            // display quaternion values in easy matrix form: w x y z
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            //Serial.print(q.w);
            //Serial.print(" ");
            //Serial.print(q.x);
            //Serial.print(" ");
            //Serial.print(q.y);
            //Serial.print(" ");
            //Serial.print(q.z);
            //Serial.println(" ");
            //Serial.println("end");
        #endif

        blinkState = !blinkState;
        digitalWrite(LED_PIN, blinkState);
    }
    
    radio.stopListening();
    float pitchYaw[2];
    Xval = (q.x);
    Zval = (q.z);
    pitchYaw[0] = Xval;
    pitchYaw[1] = Zval;
    //float MX = map(XVAL, 0, 1023, 0, 180);
    //float MZ = map(ZVAL, 0, 1023, 0, 180);
    radio.write(&pitchYaw, sizeof(pitchYaw));
    Serial.print(Xval);
    Serial.print(" ");
    Serial.print(Zval);
    Serial.println(" ");

}  



RX through NRF link to Arduino MEGA

Code: [Select]

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

RF24 radio(7, 8); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};  
float Xval;
float Zval;

void setup() {
  Serial.begin(115200);
  radio.begin();
  radio.openWritingPipe(addresses[0]); // 00001
  radio.openReadingPipe(1, addresses[1]); // 00002
  radio.setPALevel(RF24_PA_LOW);

}
void loop() {
  radio.startListening();
  if (radio.available()){
    float pitchYaw[2];
    radio.read(&pitchYaw, sizeof(pitchYaw));
    Xval = pitchYaw[0];
    Zval = pitchYaw[1];
    Serial.print(Xval);
    Serial.print(" ");
    Serial.print(Zval);
    Serial.println(" ");
    }
}


As I said there are some refinements to be made like removing the reading pipe from the TX side and others, but it definitely works. Maybe the larger part was in just asking the question. So for the additional questions i'm curious if the page protocols would dictate that I start a new thread as these would be addressing different aspects?


ctcombs0351

The next thing i need to do is add code to the receiver side where I am storing the initial values from the X and Z channels to be used as reference in comparing them as Zero point values to the current values at any given point in time.

To pose the question more specifically let me explain. I have a friend that had been in a car wreck some time ago and she has limited mobility in her arms but she can click the buttons of a mouse but not move the mouse. So this is my motivation for developing this project. The idea is that she can wear an IMU and that we use the X and Z axis data to control the mouse cursor movement.

So the first milestone in the code development is complete in that we now have IMU data coming from the head mounted remote being received but the Arduino MEGA. I have already taken the example code from the Mouse.h example sketch and began to make the modifications to add in the code to the now operable receiver code.

With the background out of the way, I am asking for guidance what functions and data types I need to save the initial value from the TX remote so that I can have a reference for the mouse.move function. Let me show you all what I have so far.

Code: [Select]

#include "Mouse.h"

// parameters for reading the IMU data and initiating mouse movement:

int range = 12;               // output range of X or Y movement
int threshold = range / 4;    // resting threshold
int center = range / 2;       // resting position value

int responseDelay = 5;        // response delay of the mouse, in ms

bool mouseIsActive = false;    // whether or not to control the mouse

int xZero = readAxis(Xval); //This is where I would like to grab the Initial Zero Value for the X axis
int yZero = readAxis(Zval); //This is where I would like to grab the Initial Zero Value for the Z axis

int xCurrent = readAxis(Xval); //This is the current Value for the X axis
int yCurrent = readAxis(Zval); //This is the current Value for the z axis

void setup() {
  Mouse.begin();
}

void loop() {

  int XYzero = (xZero*yZero);
  int XYcurrent = (xCurrent*yCurrent);

  // examine xZero and xCurrent:
  // if it's changed and it's high, toggle the mouse state:
  if (XYzero != XYcurrent) {
    mouseIsActive = !mouseIsActive;
    }
  }

  // read the two axes:
  int xReading = readAxis(Xval);
  int yReading = readAxis(Zval);

  // if the mouse control state is active, move the mouse:
  if (mouseIsActive) {
    Mouse.move(xReading, yReading, 0);
  }
  delay(responseDelay);
}

 

I know this is a ways off from a functional program, and yes this is just cut straight from the USB mouse example program. I need a number of things here:

1. I need to capture the initial X and Z values that is sent over and store them to be used as Zero reference.

2. I need to map the X znd Z values coming in from the IMU to the range that the program will recognize // still not sure on the values and it will take some functional testing.

3. Im still not quite sure on how to incorporate the Thershold Center and Range values.

I will do the heavy lifting here, I'm no slouch but I definitely need some advice. I guess going forward we just start with the first problem and work down the list. Also i'm not sure at this point if I need to start a new thread because we are moving away from the NRF 24 topic. Just let me know how I should proceed, and thanks again!!!

Go Up