Send and receive Accelerometer Data from ADXL 335 through NRF24l01

I am a beginner in Arduino interfacing, and there are many points I still do not realize; now, I am trying to send and receive ADXL335 data through NRF24l01.; please, I need any advice about how I send and receive data from adxl335 via the NRF24l01. Moreover, below is the code of the ADXL sensor.

//Analog read pins
const int xPin = A0;
const int yPin = A1;
const int zPin = A2;

//The minimum and maximum values that came from
//the accelerometer while standing still
//You very well may need to change these
int minVal = 265;
int maxVal = 402;

//to hold the caculated values
int x;
int y;
int z;

void setup(){
Serial.begin(9600);
}

void loop(){

//read the analog values from the accelerometer
int xRead = analogRead(xPin);
int yRead = analogRead(yPin);
int zRead = analogRead(zPin);

//convert read values to degrees -90 to 90 - Needed for atan2
int xAng = map(xRead, minVal, maxVal, -90, 90);
int yAng = map(yRead, minVal, maxVal, -90, 90);
int zAng = map(zRead, minVal, maxVal, -90, 90);

//Caculate 360deg values like so: atan2(-yAng, -zAng)
//atan2 outputs the value of -π to π (radians)
//We are then converting the radians to degrees
x = RAD_TO_DEG * (atan2(-yAng, -zAng) + PI);
y = RAD_TO_DEG * (atan2(-xAng, -zAng) + PI);
z = RAD_TO_DEG * (atan2(-yAng, -xAng) + PI);

//Output the caculations
// Serial.print("x=");
Serial.print(x);
Serial.print(",");
delay(100);
//Serial.print("Y=");
Serial.print(y);
Serial.print(",");
delay(100);
// Serial.print("z=");
Serial.print(z);
Serial.println(",");
delay(100);
}

Please find out how to use "code tags", the </> symbol.
Start by just reading the ADXL printing it on Serial monitor.
The exercise the nrf by sending "Hello world".
When both of them work Your getting close.

1 Like

The first and most difficult part is going to be getting the rf24 radios to communicate. Have you done that yet? If not, I suggest that you read and carefully follow Robin2's simple rf24 tutorial. That helped me a lot.

Here are examples that you may modify to do what you want. The sender will acquire 4 analog values from joysticks, put the values into a struct payload and transmit them. The other will receive the struct payload and separate those values.

Sender

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

const byte CE_PIN = 9;
const byte CSN_PIN = 10;

const byte slaveAddress[5] = {'R', 'x', 'A', 'A', 'A'};

RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

struct JoyValues
{
  int joy1x;
  int joy1y;
  int joy2x;
  int joy2y;
}joyValues;

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second

const byte joy1xPin = A0;
const byte joy1yPin = A1;
const byte joy2xPin = A2;
const byte joy2yPin = A3;

void setup()
{
   Serial.begin(115200);
   Serial.println("SimpleTx Starting");
      
   radio.begin();
   radio.setChannel(76);  //76 library default
   //RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX
   radio.setPALevel(RF24_PA_HIGH);
   radio.setDataRate( RF24_250KBPS );
   radio.setRetries(3, 5); // delay, count
   radio.openWritingPipe(slaveAddress);
}

void loop()
{
   currentMillis = millis();
   if (currentMillis - prevMillis >= txIntervalMillis)
   {
      send();
      Serial.print("JOY 1 X = ");
      Serial.print( joyValues.joy1x);
      Serial.print("  JOY 1 Y = ");
      Serial.print( joyValues.joy1y);
      Serial.print("  JOY 2 X = ");
      Serial.print( joyValues.joy2x);
      Serial.print("  JOY 2 Y = ");
      Serial.println( joyValues.joy2y);
      prevMillis = millis();
   }
}

//====================

void send()
{
   joyValues.joy1x = analogRead(joy1xPin);
   joyValues.joy1y = analogRead(joy1yPin);
   joyValues.joy2x = analogRead(joy2xPin);
   joyValues.joy2y = analogRead(joy2yPin);
   radio.write( &joyValues, sizeof(joyValues) );
}

Receiver:

// SimpleRx - the slave or the receiver

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

const byte CE_PIN = 9;
const byte CSN_PIN = 10;

const byte thisSlaveAddress[5] = {'R', 'x', 'A', 'A', 'A'};

RF24 radio(CE_PIN, CSN_PIN);

struct JoyValues
{
  int joy1x;
  int joy1y;
  int joy2x;
  int joy2y;
}joyValues;

bool newData = false;

//===========
void setup()
{
   Serial.begin(115200);
   Serial.println("SimpleRx Starting");

   radio.begin();
   radio.setChannel(76);  //76 library default
   //RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX
   radio.setPALevel(RF24_PA_HIGH);
   radio.setDataRate( RF24_250KBPS );
   radio.openReadingPipe(1, thisSlaveAddress);
   radio.startListening();
}

//=============

void loop()
{
   getData();
   showData();
}

//==============

void getData()
{
   if ( radio.available() )
   {
      radio.read( &joyValues, sizeof(joyValues) );
      newData = true;
   }
}

void showData()
{
   if (newData == true)
   {
      Serial.print("Data received >> ");
       Serial.print("JOY 1 X = ");
      Serial.print( joyValues.joy1x);
      Serial.print("  JOY 1 Y = ");
      Serial.print( joyValues.joy1y);
      Serial.print("  JOY 2 X = ");
      Serial.print( joyValues.joy2x);
      Serial.print("  JOY 2 Y = ");
      Serial.println( joyValues.joy2y);
      newData = false;
   }
}
1 Like

Thank you, sir, I try to send the "Hello word" and it's ok; I can receive it on the receiver monitor. But what about the data obtained from the accelerometer, how can I read the output result?

Thank you, sir, I try to send the "Hello word", and it's ok; I can receive it on the receiver monitor. But what about the data obtained from the accelerometer? How can I read the output result? I appreciate your support. I will see the tutorial and the examples.

Are You able to read the ADXL? Test printing the readings on Serial monitor is a good beginning.
Or is Your question how the receiver will read the transmitted ADXL data?

1 Like

Thank you for your fast response. Yes, I try to send hello world and ok, I can receive it on the monitor. But I wonder what addition I should add to the code to make the receiver read the ADXL data.

As You look like sending records containing several different data. You need to use a protocool so the receiver knows if it is an X - or an Y - value it is reading.

1 Like

The example code that I posted in post #3 shows how to put values into a struct to make up the payload and how to separate the values out of the received struct payload.

1 Like

The transmitted data is value of X,Y, and Z. In the receiver side I use nrf24l024, Arduino mega, and laptop. Thankyou

Here is the problem I cant recognize what is the data should I add to your example code to attain the tranmitted and receiving data. Thank you

I didn't expect for you to add anything. The code was to illustrate putting the data to be sent into a struct, sending the data, receiving the data and displaying the data. It took very little to add that functionality to your code.

I modified the code that I posted to send the angle values via a rf24 and wrote a program to receive and display the values. This sending and receiving code has been tested on 2 Uno boards running rf24 radios. The part of the code that acquires values and does the calculations is unchanged and not in the scope of the code that I am supplying. Mind pin numbers and baud rates.

Sender code that puts the data into the accelValues struct and sends the values.

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

const byte CE_PIN = 9;
const byte CSN_PIN = 10;

const byte slaveAddress[5] = {'R', 'x', 'A', 'A', 'A'};

RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

// *********  declare a srtuct for the payload
struct AccelValues
{
   int x;
   int y;
   int z;
} accelValues;

//Analog read pins
const int xPin = A0;
const int yPin = A1;
const int zPin = A2;

//The minimum and maximum values that came from
//the accelerometer while standing still
//You very well may need to change these
int minVal = 265;
int maxVal = 402;

//to hold the caculated values
//int x;
//int y;
//int z;

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

   radio.begin();
   radio.setChannel(76);  //76 library default
   //RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX
   radio.setPALevel(RF24_PA_HIGH);
   radio.setDataRate( RF24_250KBPS );
   radio.setRetries(3, 5); // delay, count
   radio.openWritingPipe(slaveAddress);
}

void loop()
{

   //read the analog values from the accelerometer
   int xRead = analogRead(xPin);
   int yRead = analogRead(yPin);
   int zRead = analogRead(zPin);

   //convert read values to degrees -90 to 90 - Needed for atan2
   int xAng = map(xRead, minVal, maxVal, -90, 90);
   int yAng = map(yRead, minVal, maxVal, -90, 90);
   int zAng = map(zRead, minVal, maxVal, -90, 90);

   //Caculate 360deg values like so: atan2(-yAng, -zAng)
   //atan2 outputs the value of -π to π (radians)
   //We are then converting the radians to degrees
   // ******* and adding them to the payload struct
   accelValues.x = RAD_TO_DEG * (atan2(-yAng, -zAng) + PI);
   accelValues.y = RAD_TO_DEG * (atan2(-xAng, -zAng) + PI);
   accelValues.z = RAD_TO_DEG * (atan2(-yAng, -xAng) + PI);

   // ******** send the struct
   radio.write( &accelValues, sizeof(accelValues) );
   
   //Output the caculations
   // Serial.print("x=");
   Serial.print(accelValues.x);
   Serial.print(",");
   delay(100);
   //Serial.print("Y=");
   Serial.print(accelValues.y);
   Serial.print(",");
   delay(100);
   // Serial.print("z=");
   Serial.print(accelValues.z);
   Serial.println(",");
   delay(100);
}

The code to receive and display the values.

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

const byte CE_PIN = 9;
const byte CSN_PIN = 10;

const byte thisSlaveAddress[5] = {'R', 'x', 'A', 'A', 'A'};

RF24 radio(CE_PIN, CSN_PIN);

struct AccelValues
{
   int x;
   int y;
   int z;
} accelValues;

bool newData = false;

//===========

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

   Serial.println("SimpleRx Starting");

   radio.begin();
   radio.setChannel(76);  //76 library default
   //RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX
   radio.setPALevel(RF24_PA_HIGH);
   radio.setDataRate( RF24_250KBPS );
   radio.openReadingPipe(1, thisSlaveAddress);
   radio.startListening();
}

void loop()
{
   getData();
   showData();
}

void getData()
{
   if ( radio.available() )
   {
      radio.read( &accelValues, sizeof(accelValues) );
      newData = true;
   }
}

void showData()
{
   if (newData == true)
   {
      Serial.print("Data received >> ");
       Serial.print("X = ");
      Serial.print( accelValues.x);
      Serial.print("   Y = ");
      Serial.print( accelValues.y);
      Serial.print("   Z = ");
      Serial.println( accelValues.z);
     
      newData = false;
   }
}
1 Like

Thank you very much. I appreciate your support. I will try the code in my experiment.

Thank you very much, now I can receive the data from adxl335 (x, y, z), but the appearing value is x=0, y=0, z=0. I check the adxl sensor and it works properly.

If the data is 0 then your receiver is not working. Did you get the radios to work with a simple example from the library or from Robin2's simple rf24 tutorial?

Like I said, I tested the code with real hardware and I know that the code works.

1 Like

Thank you for your response and support. I tried the examples and it's right I could not receive the target point. I try to change the Arduino on the received side and it's the same. I don't know what is the problem.

Here are some tips that I have accumulated while getting my rf24 radios to work.

If you read and, closely, follow Robin2's simple rf24 tutorial you should be able to get them working. That tutorial sure helped me. The code in the examples has been proven to work many many times. If it does not work for you, there is likely a hardware problem.

Run the CheckConnection.ino (look in reply #30 in the tutorial) to verify the physical wiring between the radio module and its processor (Arduino).

It is very important that you get the 3.3V supply to the radio modules to supply enough current. This is especially true for the high power (external antenna) modules. I use homemade adapters like these. They are powered by 5V and have a 3.3V regulator on the board. Robin2 also has suggested trying with a 2 AA cell battery pack.

If using the high powered radios make sure to separate them by a few meters. They may not work too close together. Try the lower power settings.

Reset the radios by cycling power to them after uploading new code. I have found that to help. They do not reset with the Arduino.

Switch to 1MB data rate to catch the not so cloned clones.
radio.setDataRate( RF24_1MBPS );

Also for some clones, change TMRh20's RF24.cpp line 44
_SPI.setClockDivider(SPI_CLOCK_DIV2);
Into
_SPI.setClockDivider(SPI_CLOCK_DIV4);

Have a look at the common problems page.

1 Like

Thank you very much; I appreciate your help and support. I will try these steps to check my work. Thank you

Here are a couple of more pages that may be helpful:

The arduinoinfo Wiki.

The Last Minute Engineers rf24 page.

1 Like

Thank you very much. Best regards