Joystick/Stepper Motor Tutorial

1. Joystick test (30 points)

First, use the example from the Elegoo kit. Make the following hardware connections. (Analog_Joystick.ino)





Open the serial monitor you will see the three readings, the switch, and the two axes.



So the analog joystick is actually a bi-directional potentiometer. If I push it to the far left, Y reads 4 (towards 0).



If I push it to the far right, Y reads 1023.



Push upwards, X reads 1023.



Push downward, X reads 0



2. The Open-Smart 2.4 GHz transceiver (30 points)
(this module is obsolete, if you can't find this module anywhere, online or in the lab, please scroll down to Section 4 and use the nRF24 module)

Before connecting any wireless module to a circuit, you need to know how data is being sent and received. Usually just send a number over and look at them at the serial monitor.

Make the following connections:



Here is the sketch for the transmitter and the receiver. Upload them separately to these two UNO boards. (openSmartTest.ino)

At the transmitter end, add a delay to the end of each transmission so it is not keep sending data to the receiver all the time. If I let the joystick rest, it sends 482 to the receiver. It is about half of 1023, which is the full range of the 10-bit ADC.







You may have noticed that the numbers being received are different from the numbers in Section 1. It sends one number each time and creates a new line "\n" when all the numbers are sent. In Section 1, there is no involvement of the wireless module, the UNO board digitizes the analog input and direct sends everything to the serial monitor.
In this example, the digitized data is sent to the wireless module through a Soft Serial port, it separates the three digits and send one at each time in the format of Character.
These characters need to be converted into numbers to drive the motor driver. Also, they need to be reformatted and combined into one number for each joystick reading.

When you modify the code on the receiver end, you can detect the new line '\n' as the delimiter of different data points. The numbers for a data points can be set as characters and combined into a string.

Link to the following sketch. (openSmartTest2_ino)



You can convert the string to an int by the .toInt() function. reference: https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/toint/

3. Use the received command to control the NEMA17 stepper motor (30 points).

Follow the instruction in this link to connect the A4988 driver and the stepper motor to the existing circuit.

Since Pin 2 and 3 are occupied by the SoftSerial ports, I used Pin 4 and 5 for Step and Dir respectfully. Here is the first sketch to just show the joystick works for the motor (openSmartTest3).

Here is the circuit connections on a breadboard:



I used a benchtop DC power supply. You can use a 3-cell lipo battery. I have plenty of these batteries and cartridges, please request these materials from me.



Here is the demo video:



4. The nRF24 module



Refer to the following code, make hardware connections between the RF module and an Arduino NANO board.

//Sender's code:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); // CE, CSN
// CE: is an active-high pin. When enabled, the nRF24L01 will either transmit or receive, depending on the mode.
// CSN: is an active-low pin that is typically held HIGH. When this pin goes low, the nRF24L01 begins listening for data on its SPI port and processes it accordingly.
    
const byte address[6] = "10000";     //Byte of array representing the address. This is the address where we will send the data. This should be same on the receiving side.
const int SW_pin = 2; // digital pin connected to switch output
const int X_pin = 0; // analog pin connected to X output
const int Y_pin = 1; // analog pin connected to Y output

float X_Data=0;
float Y_Data=0;
bool SW_Data=0;

void setup() {
radio.begin();                  //Starting the Wireless communication
radio.openWritingPipe(address); //Setting the address where we will send the data
radio.setPALevel(RF24_PA_MIN);  //You can set it as minimum or maximum depending on the distance between the transmitter and receiver.
radio.stopListening();          //This sets the module as transmitter

pinMode(SW_pin, INPUT);
digitalWrite(SW_pin, HIGH);
Serial.begin(9600);
}
void loop()
{
SW_Data=digitalRead(SW_pin);
X_Data=analogRead(X_pin);
Y_Data=analogRead(Y_pin);
Serial.print("Switch:  ");
Serial.print(SW_Data);
Serial.print("\n");
Serial.print("X-axis: ");
Serial.print(X_Data);
Serial.print("\n");
Serial.print("Y-axis: ");
Serial.println(Y_Data);
Serial.print("\n\n");
radio.write(&SW_Data, sizeof(SW_Data));
radio.write(&X_Data, sizeof(X_Data));
radio.write(&Y_Data, sizeof(Y_Data));

delay(1000);
}


//Receiver's code:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); // CE, CSN
const byte address[6] = "10000";
float X_Data=0;
float Y_Data=0;
bool SW_Data=0;
const int stepPin = 3;
const int dirPin = 2;
int spd=0;

void setup() {
  pinMode(stepPin,OUTPUT);
  pinMode(dirPin,OUTPUT);
pinMode(6, OUTPUT);
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(0, address);   //Setting the address at which we will receive the data
radio.setPALevel(RF24_PA_MIN);       //You can set this as minimum or maximum depending on the distance between the transmitter and receiver.
radio.startListening();              //This sets the module as receiver
}
void loop()
{
if (radio.available())              //Looking for the data.
{
radio.read(&SW_Data, sizeof(SW_Data));    //Reading the data
if(SW_Data==1){
  Serial.println(SW_Data);
  radio.read(&X_Data, sizeof(X_Data));    //Reading the data
  Serial.println(X_Data);
  radio.read(&Y_Data, sizeof(Y_Data));    //Reading the data
  Serial.println(Y_Data);
  if(Y_Data>0){
    spd = Y_Data;
  }
  if(X_Data>505){
    digitalWrite(dirPin,HIGH);
  }
  else{
    digitalWrite(dirPin,LOW);
  }
}
}
  if(spd<1020){
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(spd+500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(spd+500);
  }
  else{
    delay(5);
  }
}




-------------------------------------------------------------------------

Grading:

Section 1: 30 points. Show the demonstration video on your website
Section 4: Use/modify the code in Section 4 and use the nRF24 module to achieve the same results in Section 2 and 3. (30 points for each task).

Writing of the report: 10 points.