Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Introduction
In this lab, you’ll build an alternative
Contents [hide]
computer mouse using an Arduino
Leonardo using a joystick to move the 1 Introduction
mouse left, right, up and down. You’ll use 2 What You’ll Need to Know
the joystick’s select button to replace the 3 Things You’ll Need
mouse button as well. You’ll see how to 3.1 Note on mouse control
4 Prepare the breadboard
scale the analog outputs of the joystick to a
5 Add a pushbutton
reasonable range using the map() function.
6 Add a thumb joystick
7 Program the module to read the pushbutton
A joystick is typically made up of two 8 Program the Leonardo to read the Joystick
potentiometers, one for the X axis and one 9 Map the X and Y output readings
for the Y axis. The potentiometers are 10 Add code to listen for the Joystick Select Button
mounted so that when the joystick is at rest 10.1 Note on pullup vs. pulldown resistors
in the center, the potentiometers are at the 11 Add commands to control the mouse
middle of their range. Some joysticks like 11.1 Note on mouse misbehaving
the Thumb Joystsick used here also have a
pushbutton that you can press by pushing down on the stick. (Note: SparkFun and Parallax have
equivalent models as well.)
https://itp.nyu.edu/physcomp/labs/labsmousecontrol/labmousecontrolwithjoystick/ 1/11
2/7/2015 Lab: Mouse Control With Joystick | ITP Physical Computing
The sketches here will work on an Uno until you add the mouse commands. So you can test
this on an Uno simply by commenting out any line that says Mouse.begin() or Mouse.move().
https://itp.nyu.edu/physcomp/labs/labsmousecontrol/labmousecontrolwithjoystick/ 2/11
2/7/2015 Lab: Mouse Control With Joystick | ITP Physical Computing
Connect power and ground on the breadboard to power and ground from the microcontroller.
On the Arduino module, use the 5V and any of the ground connections:
Add a pushbutton
Attach a pushbutton to digital pin 2. Connect one side of the pushbutton to 5 volts, and the other
side of the pushbutton to a 10-kilohm resistor. Connect the other end of the resistor to ground.
Connect the junction where the pushbutton and the resistor meet to digital pin 2. (For more on
this digital input circuit,see the Digital Input Lab)
https://itp.nyu.edu/physcomp/labs/labsmousecontrol/labmousecontrolwithjoystick/ 3/11
2/7/2015 Lab: Mouse Control With Joystick | ITP Physical Computing
https://itp.nyu.edu/physcomp/labs/labsmousecontrol/labmousecontrolwithjoystick/ 4/11
2/7/2015 Lab: Mouse Control With Joystick | ITP Physical Computing
// Global variables:
int lastButtonState = LOW; // state of the button last time you checked
boolean mouseIsActive = false; // whether or not the Arduino is controlling the
void setup() {
// initialize serial communication:
Serial.begin(9600);
pinMode(2, INPUT);
}
void loop() {
// read the first pushbutton:
int buttonState = digitalRead(2);
// if it's changed and it's high, toggle the mouse state:
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
// if mouseIsActive is true, make it false;
// if it's false, make it true:
mouseIsActive = !mouseIsActive;
Serial.print("Mouse control state: ");
Serial.println(mouseIsActive);
}
}
// save button state for next comparison:
lastButtonState = buttonState;
}
// Global variables:
int lastButtonState = LOW; // state of the button last time you checked
boolean mouseIsActive = false; // whether or not the Arduino is controlling the
void setup() {
https://itp.nyu.edu/physcomp/labs/labsmousecontrol/labmousecontrolwithjoystick/ 5/11
2/7/2015 Lab: Mouse Control With Joystick | ITP Physical Computing
// initialize serial communication:
Serial.begin(9600);
pinMode(2, INPUT);
}
void loop() {
// read the first pushbutton:
int buttonState = digitalRead(2);
// if it's changed and it's high, toggle the mouse state:
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
// if mouseIsActive is true, make it false;
// if it's false, make it true:
mouseIsActive = !mouseIsActive;
Serial.print("Mouse control state: ");
Serial.println(mouseIsActive);
}
}
// save button state for next comparison:
lastButtonState = buttonState;
// read the analog sensors:
int sensor1 = analogRead(A0);
delay(1);
int sensor2 = analogRead(A1);
// print their values. Remove this when you have things working:
Serial.print(sensor1);
Serial.print(" ");
Serial.println(sensor2);
}
In order to do this, you need to scale the X and Y outputs from the default range that they return
(0 to 1023) to a range from -5 to 5. You can do this using the map() function. Map takes five
parameters: the input value, the range of the input value, and the desired output range, like so:
result = map(inputValue, inputMinimum, inputMaximum, outputMinimum,
https://itp.nyu.edu/physcomp/labs/labsmousecontrol/labmousecontrolwithjoystick/ 6/11
2/7/2015 Lab: Mouse Control With Joystick | ITP Physical Computing
outputMaximum);
So, if your input range is 0 to 1023, and your output range is -5 to 5, you might map like this:
result = map(sensorReading, 0, 1023, ‐5, 5);
Add code to the main loop to map the X and Y outputs to a range from -5 to 5. Print the mapped
values instead of the original sensor values.
// read the analog sensors:
int sensor1 = analogRead(A0);
delay(1);
int sensor2 = analogRead(A1);
int xAxis = map(sensor1, 0, 1023, ‐5, 5);
int yAxis = map(sensor2, 0, 1023, ‐5, 5);
// print their values. Remove this when you have things working:
Serial.print(xAxis);
Serial.print(" ");
Serial.println(yAxis);
NOTE: If your joystick defaults to -1 at rest on one axis or both, try adding 1 to the result of the
map command. Try different output ranges and see what they do.
When you run this sketch, you should see the Mouse Control State message once every time you
press the first pushbutton, and the values of the X and Y axes of the joystick, mapped to a range
of -5 to 5. You still need to add in the select button on the joystick, however.
You can see the schematic for a pullup resistor circuit below.
https://itp.nyu.edu/physcomp/labs/labsmousecontrol/labmousecontrolwithjoystick/ 7/11
2/7/2015 Lab: Mouse Control With Joystick | ITP Physical Computing
The Arduino has built-in pullup resistors that you can use on the digital inputs. When you set
the pin to be an input using the pinMode() command, use the parameter INPUT_PULLUP
instead of INPUT. This will activate the built-in pullup resistor on that pin, so you only have to
attach a switch between the pin and ground.
The advantage of connecting your switch to ground instead of 5V is that you can use the
internal pullup resistor instead of having to add an external resistor. The disadvantage is
that your switch logic is inverted: HIGH means the switch is open, and LOW means it is
closed. Most of the time you can wire your switches either way, but when you have a switch
that’s already wired to ground like the select button in the joystick, you have to use the
internal pullups and inverted logic.
Previously, you wired the select button to digital input 3. To read the select button in this sketch,
add a pinMode command to the setup that makes it an INPUT_PULLUP. Then in the main loop,
check if the mosueIsActive variable is true. If it is, then use digitalRead() to read the select button
and store it in a local variable called button2State.
// make pin 2 an input, using the built‐in pullup resistor:
pinMode(2, INPUT_PULLUP);
if (mouseIsActive == true) {
// read the second pushbutton:
int button2State = digitalRead(3);
https://itp.nyu.edu/physcomp/labs/labsmousecontrol/labmousecontrolwithjoystick/ 8/11
2/7/2015 Lab: Mouse Control With Joystick | ITP Physical Computing
The select button’s behavior should be like the mouse control pushbutton’s behavior: you only
want something to happen when it changes. When the select button changes from off to on, you
want it to perform a mouse click. When it changes from on to off, you want it to perform a mouse
release. So you need to check for when the select button changes, just like you do with the other
pushbutton.
To check for the select button to change, set up a global variable called lastButton2State to save
its previous state. Then set up an if statement in the main loop after you read it to see if the
current state and the previous state are different. If they are different, add another if statement
to see if the current state is HIGH or LOW. If it’s LOW, then print “Mouse press” (remember,its
logic is inverted). If the current state is HIGH, then print “mouse press”.
This block of code will look a lot like the code you used for Mouse Control to track the state
change of the pushbutton on pin 2.
int lastButton2State = LOW; // state of the other button last time you check
Then inside the if statement that you added to check the mouseIsActive variable, add the
following code (the if statement is shown here too):
if (mouseIsActive == true) {
// read the second pushbutton:
int button2State = digitalRead(3);
// if it's changed and it's high, toggle the mouse state:
if (button2State != lastButton2State) {
if (button2State == LOW) {
Serial.println("mouse pressed");
}
else {
Serial.println("mouse released");
}
}
// save second button state for next comparison:
lastButton2State = button2State;
}
When you run this code, you should see the words “mouse pressed” once when you press the
select button, and “mouse released” when you release the select button. If it prints continually,
https://itp.nyu.edu/physcomp/labs/labsmousecontrol/labmousecontrolwithjoystick/ 9/11
2/7/2015 Lab: Mouse Control With Joystick | ITP Physical Computing
When you’ve got that working, you’re ready to take control of the mouse.
The Mouse.begin() command is called in the setup. It initializes mouse control from your
Leonardo.
Modify the setup by adding the command Mouse.begin(). Then, in the loop where check if
mouseIsActive is true, add Mouse.move commands to move as needed. Also add Mouse.press()
when the select button is pressed, and Mouse.release() when it is released.
// initialize mouse control:
Mouse.begin();
Then in the main loop, add the following lines to the if statement that checks mouseIsActive:
if (mouseIsActive == true) {
Mouse.move(xAxis, yAxis, 0);
// read the second pushbutton:
int button2State = digitalRead(3);
// if it's changed and it's high, toggle the mouse state:
if (button2State != lastButton2State) {
if (button2State == LOW) {
Serial.println("mouse pressed");
Mouse.press();
}
else {
Serial.println("mouse released");
Mouse.release();
}
https://itp.nyu.edu/physcomp/labs/labsmousecontrol/labmousecontrolwithjoystick/ 10/11
2/7/2015 Lab: Mouse Control With Joystick | ITP Physical Computing
}
That’s the whole sketch. When you run this, press the mouse control pushbutton, then move the
joystick and press the select button. You should have full mouse control.
The full sketch for this can be found on the phys comp github repository, called
MouseMoveSimpleJoystick.
In this sketch, you can see the value of scaling an analog sensor’s readings to match the output
range you need. Since the joystick potentiometers are at rest in the middle of their range, scaling
them from -5 to 5 gives you easy control of the mouse movement, which is relative. You can also
see how reading the state change of a digital input is important. You’re doing it for two different
buttons in this sketch.
https://itp.nyu.edu/physcomp/labs/labsmousecontrol/labmousecontrolwithjoystick/ 11/11