Sitemap / Advertise

Introduction

This Raspberry Pi-compatible device lets you use joysticks as a mouse and enter keyboard and modifier keys with two dynamic keypad options.


Tags

Share

Arduino-Based (ATmega32U4) Mouse and Keyboard Controller

Advertisement:


read_later

Read Later



read_later

Read Later

Introduction

This Raspberry Pi-compatible device lets you use joysticks as a mouse and enter keyboard and modifier keys with two dynamic keypad options.

Tags

Share





Advertisement

Advertisement




    Components :
  • [1]PCBWay Custom PCB
  • [1]Arduino Pro Micro
  • [2]COM-09032 Analog Joystick
  • [16]Button 6x6
  • [1]5mm Green LED
  • [1]5mm Blue LED
  • [2]220Ω Resistor

Description

For a long time, I needed a simple device allowing me to send varying mouse and keyboard commands to test some of my web applications and games on browsers. Also, I could utilize such a device to test keyboard and mouse functionalities of new single-board computers, for instance, Raspberry Pi, without kvetching about my lack of a proper keyboard and mouse :) Thus, I decided to create this project.

First of all, to be able to send keyboard and mouse commands via USB, I used an Arduino Pro Micro centered around an ATmega32U4 - an 8-bit AVR very similar to the ATmega328. The ATmega32U4 comes equipped with a full-speed USB transceiver, which can emulate any USB device.

Then, I utilized the 4x4 matrix keypad design to send keyboard keys, supporting up to 32 keys with two dynamic keypad options.

Finally, I used two joysticks as a fully-functional mouse, also controlling the dynamic keypad options and modifier keys.

After completing my design on a breadboard and testing the code, I designed a controller-shaped PCB (Arduino-Based Mouse and Keyboard Controller) with an integrated 4x4 matrix keypad and two embedded joysticks, displaying Pikachu as its center logo :)

Huge thanks to PCBWay for sponsoring this project.

project-image
Figure - 57.1


project-image
Figure - 57.2

Step 1: Designing and Soldering the Mouse and Keyboard Controller PCB

Before prototyping my PCB design, I tested all connections and wiring with the Arduino Pro Micro on the breadboard.

project-image
Figure - 57.3

Then, I designed the Mouse and Keyboard Controller PCB by using KiCad. I attached the Gerber file of the PCB below, so if you want, you can order this PCB from PCBWay to create a stylish and fully-functional USB Keyboard/Mouse displaying Pikachu as its center logo :)

Click here to inspect and order this PCB directly on PCBWay.

project-image
Figure - 57.4


project-image
Figure - 57.5

First of all, by using a soldering iron, I attached headers (female), COM-09032 analog joysticks, 5mm green LED, 5mm blue LED, 6x6 pushbuttons, and 220Ω resistors.

Component list on the PCB:

A1 (Headers for Arduino Pro Micro)

J1, J2 (COM-09032 Analog Joystick)

K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13, K14, K15, K16 (6x6 Pushbutton)

D1 (5mm Green LED)

D2 (5mm Blue LED)

R1, R2 (220Ω Resistor)

C1 (Headers for External Keypad)

project-image
Figure - 57.6


project-image
Figure - 57.7


project-image
Figure - 57.8

Step 2: Setting up the Pro Micro in the Arduino IDE

Before coding, we need to add and verify the Pro Micro board settings on the Arduino IDE. With the latest release of Arduino IDE, adding third party boards to the IDE is easily achieved through the Boards Manager.

⭐ Open up the Arduino IDE, then go to the Preferences (File > Preferences). Then, towards the bottom of the window, paste this URL into the "Additional Board Manager URLs" text box:

https://raw.githubusercontent.com/sparkfun/Arduino_Boards/master/IDE_Board_Manager/package_sparkfun_index.json

You can add multiple URLs by clicking the window icon and pasting one URL per line.

project-image
Figure - 57.9

⭐ Click OK. Then, open the Boards Manager by clicking Tools > the Board selection tab > Boards Manager.

project-image
Figure - 57.10

⭐ Search for "sparkfun" in the Boards Manager. When the SparkFun AVR Boards package appears, click install, wait a few moments until the IDE confirms all the installed .brd files.

project-image
Figure - 57.11

⭐ Now, select the Sparkfun Pro Micro board under the Sparkfun Boards to upload code to the Pro Micro.

project-image
Figure - 57.12

Step 3: Programming the Arduino Pro Micro

⭐ Include the required libraries.

Keypad | Library

Keyboard | Library

Mouse | Library

⭐ Define the symbols on the buttons of the dynamic keypad options - letter and number.

⭐ Initialize the dynamic keypads.


char letterKeys[ROWS][COLS] = {
  {'e','a','r','i'},
  {'o','t','n','s'},
  {'p','m','h','w'},
  {'l','c','u','d'}
};

char numberKeys[ROWS][COLS] = {
  {'1','2','3','+'},
  {'4','5','6','-'},
  {'#','0','*','%'},
  {'7','8','9','/'}

};

byte rowPins[ROWS] = {6, 7, 8, 9}; // Connect to the row pinouts of the keypad.
byte colPins[COLS] = {2, 3, 4, 5}; // Connect to the column pinouts of the keypad.

// Initialize an instance of class NewKeypad for each keypad setting - letter and number.
Keypad letterKeypad = Keypad( makeKeymap(letterKeys), rowPins, colPins, ROWS, COLS);
Keypad numberKeypad = Keypad( makeKeymap(numberKeys), rowPins, colPins, ROWS, COLS);

⭐ In the read_joysticks() function, collect the data generated by joysticks - J1 and J2.


void read_joysticks(){
  joystick_left_x = analogRead(VRX_L); 
  joystick_left_y = analogRead(VRY_L);
  joystick_left_button = digitalRead(SW_L);
  
  joystick_right_x = analogRead(VRX_R); 
  joystick_right_y = analogRead(VRY_R);  
  joystick_right_button = digitalRead(SW_R);
}

⭐ In the mouse_controls() function, move the cursor according to the left joystick (J1) movements and click using the left (J1) and right (J2) joysticks.


void mouse_controls(){
  // Move mouse according to the left joystick movements.
  if(joystick_left_y > 700)  Mouse.move(0, -15); // UP
  if(joystick_left_y < 300)  Mouse.move(0, 15);  // DOWN
  if(joystick_left_x > 700)  Mouse.move(-15, 0); // LEFT
  if(joystick_left_x < 300)  Mouse.move(15, 0);  // RIGHT
  if(joystick_left_button == 0) Mouse.click(MOUSE_LEFT); // LEFT CLICK
  if(joystick_right_button == 0) Mouse.click(MOUSE_RIGHT); // RIGHT CLICK
  delay(100);
}

⭐ In the keyboard_controls() function, change dynamic keypad settings (letter or number) and press modifier keys (RETURN and BACKSPACE) according to the right joystick (J2) movements.

⭐ Get the custom key depending on the selected dynamic keypad option - letter or number - and write the custom key as a keyboard key.


void keyboard_controls(){
  // Change keypad settings (letter or number) and press modifier keys according to the right joystick movements.
  if(joystick_right_y > 700){ Keyboard.press(KEY_RETURN); delay(100); Keyboard.releaseAll(); }    // RETURN
  if(joystick_right_y < 300){ Keyboard.press(KEY_BACKSPACE); delay(100); Keyboard.releaseAll(); } // BACKSPACE
  if(joystick_right_x > 700){ letter = true; number = false; digitalWrite(let_LED, HIGH); digitalWrite(num_LED, LOW); } // Letter Keypad
  if(joystick_right_x < 300){ letter = false; number = true; digitalWrite(let_LED, LOW); digitalWrite(num_LED, HIGH); } // Number Keypad
  
  // Get the custom key depending on the selected keypad type - letter or number.
  char customKey;
  if(letter == true) customKey = letterKeypad.getKey();
  if(number == true) customKey = numberKeypad.getKey();
  
  // Write the custom key.
  if (customKey){
    Keyboard.write(customKey);
  }
}

project-image
Figure - 57.13


project-image
Figure - 57.14


project-image
Figure - 57.15


project-image
Figure - 57.16

Connections and Adjustments


// Connections
// Arduino Pro Micro :           
//                                JoyStick (Left)
// A0  --------------------------- VRX
// A1  --------------------------- VRY
// D14 --------------------------- SW
// 5V  --------------------------- 5V
// GND --------------------------- GND
//                                JoyStick (Right)
// A2  --------------------------- VRX
// A3  --------------------------- VRY
// D16 --------------------------- SW
// 5V  --------------------------- 5V
// GND --------------------------- GND
//                                KeyPad
// D2  --------------------------- C1
// D3  --------------------------- C2
// D4  --------------------------- C3
// D5  --------------------------- C4
// D6  --------------------------- R1
// D7  --------------------------- R2
// D8  --------------------------- R3
// D9  --------------------------- R4
//                                Letter Keypad LED
// D15 --------------------------- +
//                                Number Keypad LED
// D10 --------------------------- +

After finishing and uploading the code to the Arduino Pro Micro, I attached it to the PCB via headers.

project-image
Figure - 57.17

Modes and Features

🎮 The controller lets the user move the cursor by the left joystick (J1) movements and click by pressing the left (J1) or right (J2) joystick buttons.

project-image
Figure - 57.18

🎮 The controller allows the user to choose between the dynamic keypad options (letter and number) and send modifier keys by the right joystick (J2) movements.

project-image
Figure - 57.19


project-image
Figure - 57.20

🎮 The controller includes an integrated 4x4 matrix keypad. With the dynamic keypad options, the controller supports up to 32 keyboard keys.

🎮 Default Keyboard Keys on Keypad Buttons:

project-image
Figure - 57.21

Videos and Conclusion

The controller is compatible with Raspberry Pi, as depicted below:


Code

Arduino_Based_Mouse_and_Keyboard_Controller.ino

Download



         /////////////////////////////////////////////  
        //   Arduino-Based Mouse and Keyboard      //
       //               Controller                //
      //             ---------------             //
     //           (Arduino Pro Micro)           //           
    //             by Kutluhan Aktar           // 
   //                                         //
  /////////////////////////////////////////////

//
// This Raspberry Pi-compatible device lets you use joysticks as a mouse and enter keyboard and modifier keys with two different keypad settings.
//
// For more information:
// https://www.theamplituhedron.com/projects/Arduino-Based-ATmega32U4-Mouse-and-Keyboard-Controller
//
//
// Connections
// Arduino Pro Micro :           
//                                JoyStick (Left)
// A0  --------------------------- VRX
// A1  --------------------------- VRY
// D14 --------------------------- SW
// 5V  --------------------------- 5V
// GND --------------------------- GND
//                                JoyStick (Right)
// A2  --------------------------- VRX
// A3  --------------------------- VRY
// D16 --------------------------- SW
// 5V  --------------------------- 5V
// GND --------------------------- GND
//                                KeyPad
// D2  --------------------------- C1
// D3  --------------------------- C2
// D4  --------------------------- C3
// D5  --------------------------- C4
// D6  --------------------------- R1
// D7  --------------------------- R2
// D8  --------------------------- R3
// D9  --------------------------- R4
//                                Letter Keypad LED
// D15 --------------------------- +
//                                Number Keypad LED
// D10 --------------------------- +


// Include the required libraries.
#include <Keypad.h>
#include "Keyboard.h"
#include "Mouse.h"

const byte ROWS = 4; // four rows
const byte COLS = 4; // four columns

// Define the symbols on the buttons of the keypads.
char letterKeys[ROWS][COLS] = {
  {'e','a','r','i'},
  {'o','t','n','s'},
  {'p','m','h','w'},
  {'l','c','u','d'}
};

char numberKeys[ROWS][COLS] = {
  {'1','2','3','+'},
  {'4','5','6','-'},
  {'#','0','*','%'},
  {'7','8','9','/'}

};

byte rowPins[ROWS] = {6, 7, 8, 9}; // Connect to the row pinouts of the keypad.
byte colPins[COLS] = {2, 3, 4, 5}; // Connect to the column pinouts of the keypad.

// Initialize an instance of class NewKeypad for each keypad setting - letter and number.
Keypad letterKeypad = Keypad( makeKeymap(letterKeys), rowPins, colPins, ROWS, COLS);
Keypad numberKeypad = Keypad( makeKeymap(numberKeys), rowPins, colPins, ROWS, COLS);

// Define pinouts of joysticks.
#define VRX_L A0
#define VRY_L A1
#define SW_L 14
#define VRX_R A2
#define VRY_R A3
#define SW_R 16

// Define keypad LED pins:
#define let_LED 15
#define num_LED 10

// Define dynamic keypad options - letter and number.
volatile boolean letter = true;
volatile boolean number = false; 

// Define the data holders:
int joystick_left_x, joystick_left_y, joystick_left_button, joystick_right_x, joystick_right_y, joystick_right_button;

void setup() {
  Serial.begin(9600);

  // Initialize mouse and keyboard control:
  Mouse.begin();
  Keyboard.begin();

  // Joystick button settings:
  pinMode(SW_L, INPUT);
  digitalWrite(SW_L, HIGH);
  pinMode(SW_R, INPUT);
  digitalWrite(SW_R, HIGH);

  // Keypad LEDs:
  pinMode(let_LED, OUTPUT);
  digitalWrite(let_LED, HIGH);
  pinMode(num_LED, OUTPUT);
  digitalWrite(num_LED, LOW);
}

void loop() {
  // Read joystick positions:
  read_joysticks();

  // Mouse:
  mouse_controls();

  // Keyboard:
  keyboard_controls();

}

void read_joysticks(){
  joystick_left_x = analogRead(VRX_L); 
  joystick_left_y = analogRead(VRY_L);
  joystick_left_button = digitalRead(SW_L);
  
  joystick_right_x = analogRead(VRX_R); 
  joystick_right_y = analogRead(VRY_R);  
  joystick_right_button = digitalRead(SW_R);

  /*
  Serial.print(joystick_right_x);
  Serial.print("\t");
  Serial.print(joystick_right_y);
  Serial.print("\t\t");
  Serial.print(joystick_right_button);
  Serial.print("\n\n");
  */
}

void mouse_controls(){
  // Move mouse according to the left joystick movements.
  if(joystick_left_y > 700)  Mouse.move(0, -15); // UP
  if(joystick_left_y < 300)  Mouse.move(0, 15);  // DOWN
  if(joystick_left_x > 700)  Mouse.move(-15, 0); // LEFT
  if(joystick_left_x < 300)  Mouse.move(15, 0);  // RIGHT
  if(joystick_left_button == 0) Mouse.click(MOUSE_LEFT); // LEFT CLICK
  if(joystick_right_button == 0) Mouse.click(MOUSE_RIGHT); // RIGHT CLICK
  delay(100);
}

void keyboard_controls(){
  // Change keypad settings (letter or number) and press modifier keys according to the right joystick movements.
  if(joystick_right_y > 700){ Keyboard.press(KEY_RETURN); delay(100); Keyboard.releaseAll(); }    // RETURN
  if(joystick_right_y < 300){ Keyboard.press(KEY_BACKSPACE); delay(100); Keyboard.releaseAll(); } // BACKSPACE
  if(joystick_right_x > 700){ letter = true; number = false; digitalWrite(let_LED, HIGH); digitalWrite(num_LED, LOW); } // Letter Keypad
  if(joystick_right_x < 300){ letter = false; number = true; digitalWrite(let_LED, LOW); digitalWrite(num_LED, HIGH); } // Number Keypad
  
  // Get the custom key depending on the selected keypad type - letter or number.
  char customKey;
  if(letter == true) customKey = letterKeypad.getKey();
  if(number == true) customKey = numberKeypad.getKey();
  
  // Write the custom key.
  if (customKey){
    Keyboard.write(customKey);
  }
}


Schematics

project-image
Schematic - 57.1


project-image
Schematic - 57.2


project-image
Schematic - 57.3


project-image
Schematic - 57.4


Downloads

Gerber Files

Download


Fabrication Files

Download