Stepper Motor + nrf24l01 CODE FUSION

Hi! im going crazy :confused:

I have 2 arduino, and 3 CODES

1st CODE: receiver RF24 CODE
2nd CODE: transmitter RF24 CODE
3rd CODE: the program to run the stepper motor with a potentiometer

I manage to comunicate the 2 arduino together
And I manage to run the stepper motor with the pot by itself

The question is, how can one arduino (with pot) run the motor of the other arduino

HARDWARE USED:
nrf24l01
24byj48 stepper with unl2003
arduino nano
arduino uno
10k pot

SOFTWARE USED:
I attached the 3 files i have, how can i "fuse them togheter" and control the motor wirelessly?

any guidence will help, thank you for reading

Stepper_con_Timeout_el_mejor.ino (2.16 KB)

Rx.ino (555 Bytes)

Tx.ino (630 Bytes)

The question is, how can one arduino (with pot) run the motor of the other arduino

The one with the potentiometer reads the voltage it produces, and sends that value to the other one.

What part(s) of that do you need help with?

fernandosada:
I attached the 3 files i have, how can i "fuse them togheter" and control the motor wirelessly?

In the motor program there is a variable called PotVal which gets its value from analogRead(). You just need to change that so it gets its value from the number received by the wireless.

This Simple Merge Demo may help with merging the receiver program and the motor program.

Have a go at it, and if it does not work post the code for your best attempt.

...R

Alright, I merged together the Motor + RX code. Next step is to declare a variable in Tx, store the value from analogueRead(0), and then... how can I send that value to the Rx arduino? :frowning:

Im very new at this, thanks for the patience guys, I attached again the 2 files

Stepper_WithRX.ino (2.74 KB)

Tx.ino (630 Bytes)

1 Like

I wonder ...

I found it was necessary to modify the file RF24.cpp (which is part of the RF24 library). Towards the end of the write() function there is a line powerDown(); Put a comment // at the start of the line to prevent it working.

After making the change it would be a good idea to compile the program for a different Arduino board and then re-compile for your board to make sure it uses the revised version.

See what happens.

...R

Is it too much to ask you guys for a line of code that can work on this?

What line of code should i put in the RxMotor and TxPot files, For this to work?

Thanks for your help guys

fernandosada:
Is it too much to ask you guys for a line of code that can work on this?

Did you try the simple "line of code" I suggested in Reply #4 ?

If my experience is correct that will solve the problem.


Since writing the above I have been experimenting with this "improved" nRF24 library

It seems to work with my program without needing any changes to the library. Note that the read() function does not return anything - in the maniacBug library it returns a bool

...R

Im so sry man I totally missed that reply, I tried commenting the last write LOW but it doesnt seems to work, i feel something is missing in the code

fernandosada:
Im so sry man I totally missed that reply, I tried commenting the last write LOW but it doesnt seems to work, i feel something is missing in the code

Before we go any further try the library I linked to in Reply #7.

The reason is that your Tx code only sends data when it receives something. I found with the earlier library that it would not work unless there was only an extremely short interval (a few millisecs) between Txs and that was solved by the change that I referred to. The newer library does not have that problem.

I would like to be sure this issue is not the cause of the problem before exploring other issues.

...R

Alright, i updated the library with the one on reply 7. Can it be a problem with the arduinos?, the one with the Tx code is a Nano, and the Rx is a UNO. Thanks man, i really appreciate your patience


edit:
Hey man! When i tried to merge the RX with the motor code, something there seems to stop working. RX and TX no longer comunicate, I think my Rx-Motor code is wrong or is missing something, something that connects the 2 codes together

Hey man! Im very new at programing, im trying so hard to try to understand code. So far, I manage to get the code from other guy, and I config everything with my particular scenario.

So far, i manage to get things working with this code, the sender gives the receiver the potentiometer values, can you help me with the motor part?

How can the motor get the value im receiving? I think this is the last thing I need =D

RECEIVER.ino (2.88 KB)

SENDER.ino (1.3 KB)

It's a bit of a PITA when you force me to download short programs that you could easily include in your post using the code button </> so it looks like this and is easy to copy to my text editor.

I find it hard to see my way through all the structs and stuff in your code. There is nothing wrong with using them, but it just makes it hard to see the wood for the trees.

Are you able to send and receive a simple array with 2 or 3 int values?

If I get time later I will try your programs myself.

...R

These versions of your program work on my Mega and Uno
SENDER

//SENDER.INO

// http://www.bajdi.com
// Sending a struct with the nRF24L01 module
// Data to be sent is the reading of 2 analog pins
// Data received is the analog reading of 2 pins on the other Arduino 

#include <SPI.h>
#include <TmRnRF24L01.h>
#include <TmRRF24.h>

RF24 radio(9,10);  // make sure this corresponds to the pins you are using
const uint64_t pipes[2] = { 
  0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

const int led = 0;

typedef struct{
  int A;
  int B;
  float C;
  float D;
}
A_t;

typedef struct{
  int W;
  int X;
  float Y;
  float Z;
}
B_t;

A_t duino1;  
B_t duino2; 

void setup()
{
  Serial.begin(9600);
  Serial.println("Starting Sender");
  pinMode(led, OUTPUT);
  radio.begin();
  radio.openWritingPipe(pipes[0]);
 
}

void loop(void)
{
  // we need data to sent...
  // duino2.W = analogRead(A0);
  duino2.W += 3;
  
  // end of analog reading

  // radio stuff
  radio.stopListening();
  bool ok = radio.write( &duino2, sizeof(duino2) );
  Serial.print("Data sent ");
  Serial.println(duino2.W);
  radio.startListening();

  unsigned long started_waiting_at = millis();
  bool timeout = false;
  while ( ! radio.available() && ! timeout )
    if (millis() - started_waiting_at > 250 )
      timeout = true;

  if ( timeout )
  {
   
    digitalWrite(led, HIGH);
  }
  else
  {
    radio.read( &duino1, sizeof(duino1) );
    digitalWrite(led, LOW);
  }
  // end of radio stuff

  // serial print received data
  
 
  // end of serial printing
}

RECEIVER

//RECEIVER.ino


// http://www.bajdi.com
// Sending a struct with the nRF24L01 module
// Data to be sent is the reading of 2 analog pins
// Data received is the analog reading of 2 pins on the other Arduino 


#include <SPI.h>
#include <TmRnRF24L01.h>
#include <TmRRF24.h>
#include <Stepper.h>

#define  STEPSREV    4096    // 64(fullsteps) * 64 (reduction ratio)
#define  COIL1       8
#define  COIL2       9
#define  COIL3       10
#define  COIL4       11
#define  POT         0
#define  ENER        13
#define  TIMEOUT     3000    //Turns off after 3 secs of inactivity.

Stepper myStepper(STEPSREV, COIL1, COIL3, COIL2, COIL4);
int PotVal;
int Val = 0;
int LastPotVal= 0 ;          // To implement a software Low-Pass-Filter
int pos = 0;              // stepper position(0-4096)->(0-360°)
unsigned long stamp = 0;  // last move time stamped.



typedef struct{
  int A;
  int B;
  float C;
  float D;
}
A_t;

typedef struct{
  int W;
  int X;
  float Y;
  float Z;
}
B_t;

A_t duino1;  
B_t duino2;

RF24 radio(9,10);   // make sure this corresponds to the pins you are using
const uint64_t pipes[2] = { 
  0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

void setup()
{
  Serial.begin(9600);
  Serial.println("Starting Receiver");
  radio.begin(); 
  radio.openReadingPipe(1,pipes[0]);
  radio.startListening();
  
  myStepper.setSpeed(4);  // set the motor speed to 4 RPM
  pinMode(ENER, OUTPUT);  // status led (coils energized).
}

void loop(void)
{ 

 //~ PotVal = analogRead(Val);       // Potentiometer value range 0-1023
//~ 
  //~ PotVal= map(PotVal,0,1400,0,2047);      // Map pot range in the stepper range.
  //~ PotVal= PotVal * 0.1 + LastPotVal * 0.9 ;  // Filtering to reduce noise.
  //~ LastPotVal= PotVal;
//~ 
//~ //  Serial.print(Val);              // For debuging.
//~ //  Serial.print("   ");            //    "
//~ //  Serial.println(pos);            //    "
//~ //  delay(500);                     //    "  
//~ 
  //~ if(abs(PotVal - pos)> 4){              //if diference is greater than 4 steps.
      //~ if((PotVal - pos)> 0){
          //~ digitalWrite(ENER, HIGH);   //Motor energized.     
          //~ myStepper.step(1);           // move one step to the right.
          //~ pos++;
          //~ }
      //~ if((PotVal - pos)< 0){
          //~ digitalWrite(ENER, HIGH);   //Motor energized.
          //~ myStepper.step(-1);            // move one step to the left.
          //~ pos--;
          //~ }
      //~ stamp = millis();               // stamp actual time.
      //~ }
  //~ else {      
      //~ if((millis() - stamp) > TIMEOUT){   //Turn Off coils after TIMEOUT.
          //~ digitalWrite(COIL1, LOW);
          //~ digitalWrite(COIL2, LOW);
          //~ digitalWrite(COIL3, LOW);
          //~ digitalWrite(COIL4, LOW);
          //~ digitalWrite(ENER, LOW);    //Motor de-energized.
          //~ }    
//~ 
  //~ // radio stuff
  if ( radio.available() )
  {
    bool done = false;
   
    radio.read( &duino2, sizeof(duino2) );
      
    
  }
  // end of radio stuff

  // serial print received data 
  Serial.print("Received duino2.W = ");
  Serial.println(duino2.W);
  
  // end of serial printing
}
//~ }

Note that on my PC I have added "TmR" before the names of the library files so I can tell which is which. So, for example RF24.h is TmRRF24.h

When I commented out the potentiometer stuff in your receiver program it would not compile because there was an extra } - which I then commented out at the end of the program. It made me wonder if your failure to receive was because it was not actually checking the radio due to the IF/ELSE

Note that I have added some extra Serial.print instructions so I could follow what is happening.

...R

:slight_smile: OK I finally did it! i will call this project
DIY wireless follow focus 28byj stepper motor arduino uno arduino nano pot potentiometer rf24 project xD

Thanks Robin2 for all your inspiration, and thank you paulS, both were great inspirations.

Here is my final code

Receiver:

//#include <AccelStepper.h>
#include <MultiStepper.h>

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Stepper.h>
 
//Declaremos los pines CE y el CSN
#define CE_PIN 9
#define CSN_PIN 10

#define  STEPSREV    2048   // 64(fullsteps) * 64 (reduction ratio)
#define  COIL1       4
#define  COIL2       5
#define  COIL3       6
#define  COIL4       7
#define  POT         0
#define  ENER        13
#define  TIMEOUT     3000    //Turns off after 3 secs of inactivity.
 
//Variable con la dirección del canal que se va a leer
byte direccion[5] ={'c','a','n','a','l'}; 

//creamos el objeto radio (NRF24L01)
RF24 radio(CE_PIN, CSN_PIN);

//vector para los datos recibidos
float datos[3];

Stepper myStepper(STEPSREV, COIL1, COIL3, COIL2, COIL4);
int PotVal;
int LastPotVal= 0 ;          // To implement a software Low-Pass-Filter
int pos = 0;              // stepper position(0-4096)->(0-360°)
unsigned long stamp = 0;  // last move time stamped.

void setup()
{
 //inicializamos el NRF24L01 
  radio.begin();
  //inicializamos el puerto serie
  Serial.begin(9600); 
  
  //Abrimos el canal de Lectura
  radio.openReadingPipe(1, direccion);
  
    //empezamos a escuchar por el canal
  radio.startListening();


   myStepper.setSpeed(4);  // set the motor speed to 4 RPM
  pinMode(ENER, OUTPUT);  // status led (coils energized).
 
}
 
void loop() {
 uint8_t numero_canal;
 //if ( radio.available(&numero_canal) )
 if ( radio.available() )
 {    
     //Leemos los datos y los guardamos en la variable datos[]
     radio.read(datos,sizeof(datos));
     
     //reportamos por el puerto serial los datos recibidos
     Serial.print("POTENCIOMETRO " );
     Serial.println(datos[0]);
    
    
 }
 else
 {
     Serial.println("No hay datos de radio disponibles");
 }
 //delay(1000);

 int PotVal = datos[0];

PotVal= map(PotVal,0,1023,0,2048);      // Map pot range in the stepper range.
  PotVal= PotVal * 0.1 + LastPotVal * 0.9 ;  // Filtering to reduce noise.
  LastPotVal= PotVal;
 

if(abs(PotVal - pos)> 4){              //if diference is greater than 4 steps.
      if((PotVal - pos)> 0){
          digitalWrite(ENER, HIGH);   //Motor energized.     
          myStepper.step(1);           // move one step to the right.
          pos++;
          }
      if((PotVal - pos)< 0){
          digitalWrite(ENER, HIGH);   //Motor energized.
          myStepper.step(-1);            // move one step to the left.
          pos--;
          }
      stamp = millis();               // stamp actual time.
      }
  else {      
      if((millis() - stamp) > TIMEOUT){   //Turn Off coils after TIMEOUT.
          digitalWrite(COIL1, LOW);
          digitalWrite(COIL2, LOW);
          digitalWrite(COIL3, LOW);
          digitalWrite(COIL4, LOW);
          digitalWrite(ENER, LOW);    //Motor de-energized.
          }    
      } 

}

TRANSMITTER:

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

//Declaremos los pines CE y el CSN
#define CE_PIN 9
#define CSN_PIN 10
 
//Variable con la dirección del canal por donde se va a transmitir
byte direccion[5] ={'c','a','n','a','l'};

//creamos el objeto radio (NRF24L01)
RF24 radio(CE_PIN, CSN_PIN);

//vector con los datos a enviar
float datos[3];

void setup()
{
  //inicializamos el NRF24L01 
  radio.begin();
  //inicializamos el puerto serie
  Serial.begin(9600); 
 
//Abrimos un canal de escritura
 radio.openWritingPipe(direccion);
 
}
 
void loop()
{ 
 //cargamos los datos en la variable datos[]
 datos[0]=analogRead(0);

 //enviamos los datos
 bool ok = radio.write(datos, sizeof(datos));
  //reportamos por el puerto serial los datos enviados 
  if(ok)
  {
     Serial.print("Datos enviados: "); 
     Serial.print(datos[0]); 
    
  }
  else
  {
     Serial.println("no se ha podido enviar");
  }
  //delay(1000);
}

This is to people who is like me and surfs the web in search of codes already written XD. You just need to install libraries, and change the values acording to your needs, pay attention to the stepper motor pins, and connect them on your board accordinly.

Thank you again Robin2