0

I am currently working with a project using NRF24L01 which I integrated with my Joystick so that I can make it wireless.While transmitting the information in my Joystick to the receiver only analog pin status is getting transmitted where as digital pin status is not getting transmitted.

Transmitter Code:

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>
#include <Wire.h>

//Define the digital inputs
#define tGL1 7
#define tGL2 6
#define b1 5
#define b2 4
#define b3 3
#define b4 2


const int MPU = 0x68; // MPU6050 I2C address
float AccX, AccY, AccZ;
float GyroX, GyroY, GyroZ;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY;
float angleX, angleY;
float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY;
float elapsedTime, currentTime, previousTime;
int c = 0;

RF24 radio(9,10);
const byte address[6]="00001";

struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j2PotX;
  byte j2PotY;
  byte button1;
  byte button2;
  byte button3;
  byte button4;
  byte tSwitch1;
  byte tSwitch2;
  byte pot1;
  byte pot2;
};

Data_Package data;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  initialize_MPU6050();

  radio.begin();
  radio.openWritingPipe(address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);

  pinMode(tGL1, INPUT_PULLUP);
  pinMode(tGL2, INPUT_PULLUP);
  pinMode(b1, INPUT_PULLUP);
  pinMode(b2, INPUT_PULLUP);
  pinMode(b3, INPUT_PULLUP);
  pinMode(b4, INPUT_PULLUP);

   data.j1PotX = 127; // Values from 0 to 255. When Joystick is in resting position, the value is in the middle, or 127. We actually map the pot value from 0 to 1023 to 0 to 255 because that's one BYTE value
   data.j1PotY = 127;
   data.j2PotX = 127;
    data.j2PotY = 127;
//  data.j1Button = 1;
//  data.j2Button = 1;
  data.pot1 = 1;
  data.pot2 = 1;
  data.tSwitch1 = 1;
  data.tSwitch2 = 1;
  data.button1 = 1;
  data.button2 = 1;
  data.button3 = 1;
  data.button4 = 1;

}

void loop() {
  // put your main code here, to run repeatedly:
  data.j1PotX = map(analogRead(A2), 0, 1023, 0, 255); // Convert the analog read value from 0 to 1023 into a BYTE value from 0 to 255
  data.j1PotY = map(analogRead(A1), 0, 1023, 0, 255);
  data.j2PotX = map(analogRead(A3), 0, 1023, 0, 255);
  data.j2PotY = map(analogRead(A0), 0, 1023, 0, 255);
  data.pot1 = map(analogRead(A7), 0, 1023, 0, 255);
  data.pot2 = map(analogRead(A6), 0, 1023, 0, 255);

  data.tSwitch2 = digitalRead(tGL2);

  data.button1 = digitalRead(b1);
  data.button2 = digitalRead(b2);
  data.button3 = digitalRead(b3);
  data.button4 = digitalRead(b4);

  if (digitalRead(tGL1) == 0) {
    read_IMU();    // Use MPU6050 instead of Joystick 1 for controling left, right, forward and backward movements
  }

  radio.write(&data, sizeof(Data_Package));
}

This is the Reciever Code

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10);   // nRF24L01 (CE, CSN)
const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j2PotX;
  byte j2PotY;
  byte pot1;
  byte pot2;
  byte tSwitch1;
  byte tSwitch2;
  byte button1;
  byte button2;
  byte button3;
  byte button4;
};
Data_Package data; //Create a variable with the above structure
void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.startListening(); //  Set the module as receiver
  resetData();
}
void loop() {
  // Check whether there is data to be received
  if (radio.available()) {
    radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
    lastReceiveTime = millis(); // At this moment we have received the data
  }
  // Check whether we keep receving data, or we have a connection between the two modules
  currentTime = millis();
  if ( currentTime - lastReceiveTime > 1000 ) { // If current time is more then 1 second since we have recived the last data, that means we have lost connection
    resetData(); // If connection is lost, reset the data. It prevents unwanted behavior, for example if a drone has a throttle up and we lose connection, it can keep flying unless we reset the values
  }
  // Print the data in the Serial Monitor
  Serial.print("j1PotX: ");
  Serial.print(data.j1PotX);
  Serial.print("; j1PotY: ");
  Serial.print(data.j1PotY);
  Serial.print("; button1: ");
  Serial.print(data.button1);
  Serial.print("; j2PotX: ");
  Serial.println(data.j2PotX); 
}

When I print the status of the buttons and Joystick in my transmitter(Joystick) I get the correct status of my push button when I press but the status of my push button remain unchanged in the Serial monitor of my Receiver despite there is change other values (I mean the analog value is transmitting correctly)

This the screenshot of my both serial Monitor COM7 is my Transmitter but COM6 is Receiver but change in state of button1 is COM7 is not produced in COM6

  • 4
    Hint: A common header file with the message struct would help avoid this issue. The layout of the struct's are not the same :) – Mikael Patel Jul 13 at 13:12
2

As Mikael Patel mentions in the comments: your structures do not match between the transmitter and receiver.

Transmitter               Receiver
=====================     =====================
struct Data_Package {     struct Data_Package {
      byte j1PotX;    ->      byte j1PotX;
      byte j1PotY;    ->      byte j1PotY;
      byte j2PotX;    ->      byte j2PotX;
      byte j2PotY;    ->      byte j2PotY;
      byte button1;   ->      byte pot1;
      byte button2;   ->      byte pot2;
      byte button3;   ->      byte tSwitch1;
      byte button4;   ->      byte tSwitch2;
      byte tSwitch1;  ->      byte button1;
      byte tSwitch2;  ->      byte button2;
      byte pot1;      ->      byte button3;
      byte pot2;      ->      byte button4;
};                        };

With structures, what matters is not what each field is called. What matters is the position of the fields in the list. When you compile your code all the names are lost. All that is left is where in the list each entry is.

The best way of avoiding this problem is to have a single header file (make it a library so it's easy to share) that contains the packet structure. Then if you ever make any changes to the packet all the sketches that use it see that change the next time you compile them.

  • Does that mean I have to make an file with .h extension and then import them using #include – Abel C Dixon Jul 13 at 15:51
  • Yes. If you make that file as Documents\Arduino\libraries\PacketFormat\PacketFormat.h then you can just #include <PacketFormat.h> in any sketch to get the structure. – Majenko Jul 13 at 15:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.