bclose

17 – Circuit with joystick and a servo

Objectives

 

 

    • Introduce joysticks
    • Reading the joystick
    • Moving the servo by using the joystick
    • Filtering the readings

 

BILL OF MATERIALS

Arduino Uno  Arduino Uno or equivallent.
We can use any other Arduino board in this chapter.
Breadboard

Jumper wires

 A solderless Breadboard plus some jumper wires.
Joystick A Joystick.
Servo with horns A Servo with its horns, these small pieces of plastic put on the shaft.

 

WHAT IS A JOYSTICK?

 

A joystick is usually composed of two potentiometers, placed at 90º one from each other, which transform the movement from the X and Y axes of the joystick in an electrical signal proportional to its position. They also use to include a button.

Normally a joystick have 5 pins: X axis, Y axis, button, 5V and GND.

Actually we have used all these components before and its only special feature is to provide a very comfortable way to position something, although it is not too precise.

Let’s mount a prototype with a servo, as in the previous chapter. We will use one of the axes of the joystick to position it and the button to turn on an LED. (We’ll ignore the other axis, although we could use it to position a second servo).
The pin corresponding to the button is usually labelled as SW, Switch.

Here we have the circuit schematic diagram:

Chapter 17, Schematic diagram

 

And this is the wiring schematic diagram:

Chapter_17_wiring_diagram

 

 

THE CONTROL PROGRAM

 

Let’s start off by writing the program

Sketch 17.1
#include <Servo.h>                     // Includes Servo library
Servo servo1;                          // Creates a Servo type object called servo1
int angle = 0;
int X_Axis = A1;
int Y_Axis = A2;
int button = 4  , LED = 12;

void setup()
{
     servo1.attach(6) ;                // Connects servo1 to pin 6
     pinMode(button, INPUT_PULLUP);
}

void loop()
{
     angle = map(analogRead(A1), 0, 1024, 0, 180);
     servo1.write(angle);
     if (!digitalRead(button))
           digitalWrite(LED, HIGH);
     else
           digitalWrite(LED, LOW);
     delay(250);
 }
 
  • The part corresponding to the servo is exactly the same as that in the chapter 16. Moreover, we have included some definitions at the beginning indicating that we have connected the X axis to the analog pin A1 and the Y axis to the analog pin A2.
  • The button is connected to digital pin 4 and the LED to the pin 12 so that if we want to change the pin number, for whatever reason, you can simply update this list at the beginning of the program.
 

Pay attention to the fact that we have defined the button input of the joystick as INPUT_PULLUP and not as INPUT, because it does not need to include a resistor as a pull-up resistor is already internally attached to the Arduino.

This way we will read LOW when the button is pressed and HIGH in the meantime, that is why we reverse the condition in the if statement. We will switch on the LED only when the button is pressed.

The servo follows the position of the joystick and when we release it, it comes back to the center.

But the servo moves in a somehow epileptic way (even more in my case, as I am using a cheap one).The servo receives many interferences and its movement is very troubled, because although servos have a certain accuracy (which is an assumption between optimistic and highly optimistic), potentiometers and analog to digital converters (ADCs) always have a noise margin.

We can think of some way to improve that movement for sure. Think about it. What can we do to filter that noise?
Seriously, think on it before proceeding.

Well, in the real world, things are never black or white, but rather shades of gray (or very frequently chocolate), so it is not a good idea to send the readings directly control the servo, or whatever you’re moving .

We have to filter the signal a little bit. Without going too much on this issue (on which there have been written encyclopedias), we will use a very basic though very effective technique, on many occasions, that you should know.

We will read the potentiometer to decide whether we increase or decrease the angle value, not to calculate the angle directly.

As the potentiometer sends values between 0 and 1000, when it is centered or loose it will send a value of about 500, more or less (although it will fluctuate). So we will give it a tolerance margin. We will only increase the angle, a given value, if the reading of the potentiometer exceeds the value of 600 and we will decrease it when it falls from 400.

This way, small oscillations around the midpoint will not affect the movement of the servo. That is, we have filtered them.

The following sketch includes all these improvements:

Sketch 17.2
     #include <Servo.h>                             // Includes the Servo library
     Servo servo1;                                  // Creates a Servo type object called servo1
     int angle = 90;                                // We start in the middle
     int offset = 3;                                // Controls the movement's offset
     int X_axis = A1;
     int Y_axis = A2;
     int button = 4;
     void setup()
     {
        servo1.attach(6);                            // Connects servo1 to pin 6
        pinMode(button, INPUT_PULLUP);
     }

     void loop()
     {
        int p = analogRead(X_axis);
        if (p < 400)                                 // If the reading is less than 400 
            angle = angle - offset;                  // Decreases the angle 
        else if (angle > 600)                        // If the reading is greater than 600
            angle = angle + offset;                  // Increases the angle
        servo1.write(angle);                         // Moves the servo
        delay (50);                                  // This delay controls movement speed
        if (!digitalRead(button))
            digitalWrite(LED, HIGH);
        else
            digitalWrite(LED, LOW);
        delay(250);
     }

You will check that the movement is more fluid and consistent and that the convulsions of the servo are virtually eliminated. We also use this method to fix the servo in the desired position (although we release the joystick), something that would be impossible otherwise.

Summary

 

 

    • We have seen that a joystick is composed of two potentiometers, placed at 90º one from each other, plus a button, all of them ordinary
    • We have taken advantage of the assembly of the previous chapter to move the servo with the joystick and map its value between 0 and 180º.
    • We have introduced the concept of signal filtering, which in itself is a specific branch of electronics and computing, and every day is more important in all fields of technology.

 

 

 

 

No Comments

Give a Reply