Using nrf24l01 with nema17 and accelstepper library

Hello. i am having problems getting my code to run correctly. I am using an NRF transmitter and receiver to run a nema 17 stepper motor. right now the code should run 1 of 2 speeds, which are selected by a toggle switch. and a joystick (Yaxis) sets direction, (Middle is STOP). when I use the transmitter the motor goes only one way, and the toggle switch does not change the speed.

Is there a way to use the receiver data to map speed and direction to the joystick. I will be adding limit switches later for position control.

works_perfect_with_buttons_joystick_posted.ino (2.5 KB)

Members, my self included, are reluctant to download code. It is a PITA. Read the forum guidelines to see how to properly post code and some hints on how to get the most from this forum.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

Post both the transmitter and receiver code.

Please include a schematic showing all components, their values and/or part numbers and all power supplies.

Receiver code

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <AccelStepper.h>
AccelStepper stepper1(1, 6, 7);
RF24 radio(10, 9);   // nRF24L01 (CE, CSN)

const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;
int Analog_Y = 0; //y-axis value
int Analog_Y_AVG = 0; //y-axis value average
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j1Button;
  byte j2PotX;
  byte j2PotY;
  byte j2Button;
  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() {
  stepper1.setCurrentPosition(0);
  stepper1.setAcceleration(1000);
  stepper1.setMaxSpeed(1500);
  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

}
void loop() {


  ReadAnalog();
  {
    stepper.runSpeed(); //step the motor (this will step the motor by 1 step at each loop indefinitely)

    stepper2.runSpeed();
  }


  void ReadAnalog()
  {
    //Reading the 3 potentiometers in the joystick: x, y and r.

    Analog_Y = (data.j2PotY)


               //if the value is 25 "value away" from the average (midpoint), we allow the update of the speed
               //This is a sort of a filter for the inaccuracy of the reading

               if (abs(Analog_Y - Analog_Y_AVG) > 25)
    {
      stepper2.setSpeed(5 * (Analog_Y - Analog_Y_AVG));
    }
    else
    {
      stepper2.setSpeed(0);
    }

  }


  void InitialValues()
  {
    //Set the values to zero before averaging
    float tempX = 0;
    float tempY = 0;
    float tempR = 0;
    //----------------------------------------------------------------------------
    //read the analog 50x, then calculate an average.
    //they will be the reference values
    for (int i = 0; i < 50; i++)
    {
      tempX += analogRead(Analog_X_pin);
      delay(10); //allowing a little time between two readings
      tempY += analogRead(Analog_Y_pin);
      delay(10);
      tempR += analogRead(Analog_R_pin);
      delay(10);
    }
    //----------------------------------------------------------------------------
    Analog_X_AVG = tempX / 50;
    Analog_Y_AVG = tempY / 50;
    Analog_R_AVG = tempR / 50;



    // 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
    }
  }
  void resetData() {
    // Reset the values when there is no radio connection - Set initial default values
    data.j1PotX = 127;
    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;
  }


transmitter code

/*
        DIY Arduino based RC Transmitter
  by Dejan Nedelkovski, www.HowToMechatronics.com
  Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/

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


// Define the digital inputs
#define jB1 1  // Joystick button 1
#define jB2 0  // Joystick button 2
#define t1 7   // Toggle switch 1
#define t2 4   // Toggle switch 1
#define b1 8   // Button 1
#define b2 9   // Button 2
#define b3 2   // Button 3
#define b4 3   // Button 4

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(5, 6);   // nRF24L01 (CE, CSN)
const byte address[6] = "00001"; // Address

// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j1Button;
  byte j2PotX;
  byte j2PotY;
  byte j2Button;
  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);
  


  // Call this function if you need to get the IMU error values for your module
  //calculate_IMU_error();
  
  // Define the radio communication
  radio.begin();
  radio.openWritingPipe(address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  
  // Activate the Arduino internal pull-up resistors
  pinMode(jB1, INPUT_PULLUP);
  pinMode(jB2, INPUT_PULLUP);
  pinMode(t1, INPUT_PULLUP);
  pinMode(t2, INPUT_PULLUP);
  pinMode(b1, INPUT_PULLUP);
  pinMode(b2, INPUT_PULLUP);
  pinMode(b3, INPUT_PULLUP);
  pinMode(b4, INPUT_PULLUP);
  
  // Set initial default values
  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() {
  // Read all analog inputs and map them to one Byte value
  data.j1PotX = map(analogRead(A1), 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(A0), 0, 1023, 0, 255);
  data.j2PotX = map(analogRead(A2), 0, 1023, 0, 255);
  data.j2PotY = map(analogRead(A3), 0, 1023, 0, 255);
  data.pot1 = map(analogRead(A7), 0, 1023, 0, 255);
  data.pot2 = map(analogRead(A6), 0, 1023, 0, 255);
  // Read all digital inputs
  data.j1Button = digitalRead(jB1);
  data.j2Button = digitalRead(jB2);
  data.tSwitch2 = digitalRead(t2);
  data.tSwitch1 = digitalRead(t1);
  data.button1 = digitalRead(b1);
  data.button2 = digitalRead(b2);
  data.button3 = digitalRead(b3);
  data.button4 = digitalRead(b4);
 
  // Send the whole data from the structure to the receiver
  radio.write(&data, sizeof(Data_Package));
  Serial.print("Y Axis");
  Serial.print(data.j2PotY);
  Serial.print("X Axis");
  Serial.print(data.j2PotX);
  Serial.print("SPEED");
  Serial.println(data.j1PotY);
}

i am using the schematics from this link https://howtomechatronics.com/projects/diy-arduino-rc-transmitter/

i am running a dedicated 24v power supply and db6600 driver for the stepper motor.

The receive code will not compile as posted. Use the auroformat toll and you can see that there is a { out of place and a ; missing. The steppers (stepper and stepper2) in loop() are not declared and some variables in the functions are not declared.

I don't see where you are actually reading the rf24 in the posted receiver code. So is the posted code what you want to get to work (no reading of the rf24, just y axis and stepper1?) or is the code that you want help with actually reading and working with the transmitted data. If so, please post the code that you want help with.

i forgot i tried something with the code...this is the receiver code that i am working with.

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <AccelStepper.h>
AccelStepper stepper1(1, 6, 7);
RF24 radio(10, 9);   // 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 j1Button;
  byte j2PotX;
  byte j2PotY;
  byte j2Button;
  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() {
  stepper1.setCurrentPosition(0);
  stepper1.setAcceleration(1000);
  stepper1.setMaxSpeed(1500);
  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() {
 
 Serial.println(data.j2PotY);
 
 if(data.j2PotY != 123){
   while ((data.j2PotY) > 145 ) {
    stepper1.setSpeed(-100);
    stepper1.runSpeed();
    
    radio.read(&data, sizeof(Data_Package));
  }
  while ((data.j2PotY) < 100) {
     radio.read(&data, sizeof(Data_Package));
    stepper1.setSpeed(100);
    stepper1.runSpeed();
    
   
  }
  

  }
  // 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
  }
}
void resetData() {
  // Reset the values when there is no radio connection - Set initial default values
  data.j1PotX = 127;
  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;
}

 

i was able to get this code to move the motor in the desire direction using two buttons, but could not control the speed. when i switched the buttons for the joystick themotor only goes one way, and i still cannot control the speed. the serial monitor confirms that the receiver and transmitter are communicating correctly.

You want to be calling your .runSpeed() function every time through loop(). To do this quickly, get rid of all those extra radio.read() calls and only do the call if you have received at least a full packet size of data...

void loop() {

  // Check whether there is data to be received
  if (radio.available() >= sizeof(Data_Package)) {
    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
  }

  Serial.println(data.j2PotY);

  if ( data.j2PotY == 123 ) {
    stepper1.setSpeed(0);
  }
  else if (data.j2PotY > 145) {
    stepper1.setSpeed(-100);
  }
  else if (data.j2PotY < 100) {
    stepper1.setSpeed(100);
    stepper1.runSpeed();
  }
  stepper1.runSpeed();
}

i tried inserting the code you posted. when i open the serial monitor i get no response from the transmitter. in my code i do.

here is the code with your part.

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <AccelStepper.h>
AccelStepper stepper1(1, 6, 7);
RF24 radio(10, 9);   // 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 j1Button;
  byte j2PotX;
  byte j2PotY;
  byte j2Button;
  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() {
  stepper1.setCurrentPosition(0);
  stepper1.setAcceleration(1000);
  stepper1.setMaxSpeed(1500);
  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() {
 
 Serial.println(data.j2PotY);
 
// Check whether there is data to be received
  if (radio.available() >= sizeof(Data_Package)) {
    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
  }

  Serial.println(data.j2PotY);

  if ( data.j2PotY == 123 ) {
    stepper1.setSpeed(0);
  }
  else if (data.j2PotY > 145) {
    stepper1.setSpeed(-100);
  }
  else if (data.j2PotY < 100) {
    stepper1.setSpeed(100);
    stepper1.runSpeed();
  }
  stepper1.runSpeed();
}
void resetData() {
  // Reset the values when there is no radio connection - Set initial default values
  data.j1PotX = 127;
  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;
}

 

maybe put in a debug print statement to see how many characters are available on the radio? Maybe announce when you are resetting? when you did a read?

I don't have that hardware...

when i run my code only the while loop with j2PotY <100 seems to control the speed. if i change the speed value there from positive to negative and re upload, the direction will change

i made a few adjustments to the code and was able to make a little progress. i was able to use data.tSwitch1 to select two different speeds. the joystick however still will not determine direction. in the code below, the second while statement is the one controlling direction. if i change stepper1.setSpeed in the second while statement the direction changes.

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <AccelStepper.h>
AccelStepper stepper1(1, 6, 7);
RF24 radio(10, 9);   // nRF24L01 (CE, CSN)
const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;
int Speed=0;
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j1Button;
  byte j2PotX;
  byte j2PotY;
  byte j2Button;
  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() {
  stepper1.setCurrentPosition(0);
  stepper1.setAcceleration(1200);
  stepper1.setMaxSpeed(1200);
  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() {
 
 Serial.println(data.j2PotY);

 if(data.tSwitch1==0){
  Speed=100;
 }
 else if(data.tSwitch1==1){
 Speed=900;
 }
   while (data.j2PotY > 145 ) {
    radio.read(&data, sizeof(Data_Package));
    stepper1.setSpeed(Speed);// this is not working goes the direction data.j2PotY < 100
    stepper1.runSpeed();
    
    
  }
  while (data.j2PotY < 100) {
     radio.read(&data, sizeof(Data_Package));
    stepper1.setSpeed(Speed*(-1)); //positive ccw
    stepper1.runSpeed();
    
   
  }
  

  
  // 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
  }
}
void resetData() {
  // Reset the values when there is no radio connection - Set initial default values
  data.j1PotX = 127;
  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;
}

 

i just need to know why this section is not setting the speed/direction.

while (data.j2PotY > 145 ) {
    radio.read(&data, sizeof(Data_Package));
    stepper1.setSpeed(Speed);// this is not working goes the direction data.j2PotY < 100
    stepper1.runSpeed();

You really need to get rid of those while() loops. Let loop() do what it is designed to do. Your code should have 1 location where it reads the data and then you should print out everything to see what is being received

i made one while statement to do both direction. and it works, kinda. now the problem is a lag in the data read. the serial monitor runs normal until i move the joystick, then it almost seems to freeze.

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <AccelStepper.h>
AccelStepper stepper1(1, 6, 7);
RF24 radio(10, 9);   // nRF24L01 (CE, CSN)
const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;
int Direction=1;
int Speed=0;
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j1Button;
  byte j2PotX;
  byte j2PotY;
  byte j2Button;
  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() {
  stepper1.setCurrentPosition(0);
  stepper1.setAcceleration(1200);
  stepper1.setMaxSpeed(1200);
  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() {

 Serial.print("Speed:");
 Serial.print(Speed);
 Serial.print("YAxis:");
 Serial.println(data.j2PotY);

 if(data.tSwitch1==1 && data.tSwitch2==1){//1 is down
  Speed=100*Direction;
 }
 else if(data.tSwitch1==1 && data.tSwitch2==0 ){
 Speed=300*Direction;
 }
else if(data.tSwitch1==0 && data.tSwitch2==1 ){
 Speed=500*Direction;
 }
else if(data.tSwitch1==0 && data.tSwitch2==0 ){
 Speed=900*Direction;
 }  

  
  // 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
  }
   while(data.j2PotY<100||data.j2PotY>150){
   radio.read(&data, sizeof(Data_Package));
    Direction=((data.j2PotY-132)/abs(data.j2PotY-132));
    stepper1.setSpeed(Speed);// 
    stepper1.runSpeed();
   }
}
void resetData() {
  // Reset the values when there is no radio connection - Set initial default values
  data.j1PotX = 127;
  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;
}

 

if i remove the while statement like suggested in post #13 the motor does not stop moving

thank you for all your suggestions.

i think im just going to go direct wire and analog read rather than wireless with data packets. i just cant seem to get any examples of how to do it with stepper motors and joystick.

FINALLY....success. i pulled up an older code i stumbled across that was using stepper.move to position, and altered it to run.speed. i was also able to map the speed and direction to the joystick. while no one persons advice solved my problem, the combined hints were able to finally get me there.

Thanks again for your patience and help.

this is the transmitter and the receiver code

receiver is first

/*
    DIY Arduino based RC Transmitter Project
   == Receiver Code - ESC and Servo Control ==
  by Dejan Nedelkovski, www.HowToMechatronics.com
  Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <AccelStepper.h>
RF24 radio(10, 9);   // nRF24L01 (CE, CSN)
const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;
AccelStepper stepper1(1, 6, 7);
int Dir = 0;
int Speed = 0;
int X_val = 0;        // Value for X pos of JS
int Y_val = 0;        // Value for Y pos of JS
int position_to_go_max = 6000;
int position_to_go_min = 0;// Arbitrary Position for motor to go
int previousPosition;
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j1Button;
  byte j2PotX;
  byte j2PotY;
  byte j2Button;
  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

  //Stepper
  stepper1.setMaxSpeed(5000);
  stepper1.setAcceleration(1000);



}
void loop() {
  // Check whether we keep receving data, or we have a connection between the two modules
  currentTime = millis();

  // 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
  }


  X_val = (data.j2PotX);
  Y_val = (data.j2PotY);

  if (Y_val > 100 && Y_val < 145) {
    stepper1.setSpeed(0);

  }
  Speed = map(Y_val,0,255,-1300,1300);

  if ( Y_val < 100 || Y_val > 145) {
  stepper1.setSpeed(Speed);


  }


  stepper1.runSpeed();


}
void resetData() {
  // Reset the values when there is no radio connection - Set initial default values
  data.j1PotX = 127;
  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;
}

here is the transmitter

/*
        DIY Arduino based RC Transmitter
  by Dejan Nedelkovski, www.HowToMechatronics.com
  Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/

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


// Define the digital inputs
#define jB1 1  // Joystick button 1
#define jB2 0  // Joystick button 2
#define t1 7   // Toggle switch 1
#define t2 4   // Toggle switch 1
#define b1 8   // Button 1
#define b2 9   // Button 2
#define b3 2   // Button 3
#define b4 3   // Button 4

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(5, 6);   // nRF24L01 (CE, CSN)
const byte address[6] = "00001"; // Address

// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j1Button;
  byte j2PotX;
  byte j2PotY;
  byte j2Button;
  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);
  


  // Call this function if you need to get the IMU error values for your module
  //calculate_IMU_error();
  
  // Define the radio communication
  radio.begin();
  radio.openWritingPipe(address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  
  // Activate the Arduino internal pull-up resistors
  pinMode(jB1, INPUT_PULLUP);
  pinMode(jB2, INPUT_PULLUP);
  pinMode(t1, INPUT_PULLUP);
  pinMode(t2, INPUT_PULLUP);
  pinMode(b1, INPUT_PULLUP);
  pinMode(b2, INPUT_PULLUP);
  pinMode(b3, INPUT_PULLUP);
  pinMode(b4, INPUT_PULLUP);
  
  // Set initial default values
  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() {
  // Read all analog inputs and map them to one Byte value
  data.j1PotX = map(analogRead(A1), 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(A0), 0, 1023, 0, 255);
  data.j2PotX = map(analogRead(A2), 0, 1023, 0, 255);
  data.j2PotY = map(analogRead(A3), 0, 1023, 0, 255);
  data.pot1 = map(analogRead(A7), 0, 1023, 0, 255);
  data.pot2 = map(analogRead(A6), 0, 1023, 0, 255);
  // Read all digital inputs
  data.j1Button = digitalRead(jB1);
  data.j2Button = digitalRead(jB2);
  data.tSwitch2 = digitalRead(t2);
  data.tSwitch1 = digitalRead(t1);
  data.button1 = digitalRead(b1);
  data.button2 = digitalRead(b2);
  data.button3 = digitalRead(b3);
  data.button4 = digitalRead(b4);
 
  // Send the whole data from the structure to the receiver
  radio.write(&data, sizeof(Data_Package));
  Serial.print("Y Axis");
  Serial.print(data.j2PotY);
  Serial.print("X Axis");
  Serial.print(data.j2PotX);
  Serial.print("SPEED");
  Serial.println(data.j1PotY);
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.