Q-Stick : Reuse. Rewire. Replay. a Discarded Cigarette Rolling Machine Becomes a Retro USB Controller.

by shredermann in Circuits > Arduino

185 Views, 2 Favorites, 0 Comments

Q-Stick : Reuse. Rewire. Replay. a Discarded Cigarette Rolling Machine Becomes a Retro USB Controller.

Q-Stick.png
vectrex Q-stick.gif
q-stick.gif

This project started with an old manual OCB cigarette rolling machine that I rescued just before it ended up in the trash. Its mechanism was no longer useful, but the shell was still compact, rigid, and surprisingly well suited to the shape of a small arcade controller.

At the same time, an analog joystick and several push buttons from an old Arduino kit were sitting unused in a drawer. I also had several Arduino Nano 33 BLE Sense Rev2 that I regularly use for prototypes. I brought these forgotten parts together and gave them an entirely new purpose.

I did not buy any component specifically for this build.

Reuse. Rewire. Replay.

The result is called "Q‑Stick: a USB controller with an analog joystick and four colored buttons, recognized as a true HID device. It works with RetroArch, MAME, and many games or emulators that support USB gamepads. Q-Stick was developed and tested on the Arduino Uno Q.

The transformation goes beyond the enclosure. The firmware calibrates the joystick, debounces the buttons, uses the Nano's built-in IMU, and identifies the controller as "Arduino Q‑Stick". The Nano's RGB LED indicates the active mode. Software profiles can then adapt the controls to each game without changing the wiring.

The first profile was validated with "Mine Storm on Vectrex": left/right rotation on the joystick, fire on the blue button, thrust on the white button, and teleport on the red button. Holding the fire button enables a comfortable continuous-fire rate.

Validated result: two analog axes, four action buttons integrated into the shell, Select and Start buttons retained on the prototyping breadboard, software debounce, three control modes, RGB indication, USB device named Q‑Stick, and working game profiles.

  1. Project-specific cost: €0 : I only reused parts that were already available.
  2. Estimated build time: one weekend, excluding firmware development
  3. Level: intermediate
  4. Useful skills: drilling, soldering, Arduino, and basic Linux configuration

Supplies

01-tubeuses-ocb-avant-demontage.jpg
IMG_3650.jpg
IMG_3651.jpg
IMG_3652.jpg
IMG_3654.jpg

Shell from a broken OCB manual cigarette rolling machine rescued before disposal.

Arduino Nano 33 BLE Sense Rev2 prototyping board already on hand.

KY‑023 analog joystick or equivalent from old Arduino kit.

Small buttons for "Select" and "Start" from old button assortment on breadboard only

USB data cable from existing stock.

As needed flexible wires, heat-shrink tubing, screws, and standoffs from workshop stock.

The prototype is powered entirely through its USB cable. It contains no battery, charger, or additional converter. This keeps the build compact and preserves the simple, reproducible spirit of the project.


Gaming setup used for testing

- an Arduino UNO Q running Linux.

- a USB hub.

- RetroArch.

- the open-source VecX core for Vectrex emulation, or any other core you prefer.

The UNO Q is not required: Q‑Stick is a standard USB gamepad and can be used with another compatible machine.


Tools

- screwdrivers

- an old wash basin

- a used toothbrush kept for DIY work

- calipers or an accurate ruler

- fine-tip soldering iron and solder

- multimeter in continuity mode

- rotary tool and progressively larger drill bits

- fine file and utility knife

- heat-shrink tubing

- safety glasses

Let the Salvaged Object Guide the Project

02-usure-et-coques-deformees.jpg
05-demontage-avec-tournevis.jpg
08-tubeuses-entierement-demontees.jpg
09-nettoyage-de-toutes-les-parties-dans-bassine.jpg
12-nettoyage-coque-ocb-brosse-a-dents.jpg

I did not design a controller first and then look for an enclosure. I started by examining the rolling machine: its shape, internal volume, mounting points, and the way the two halves of the shell fit together.

Its exterior condition already explained why it had been discarded: the green base was heavily worn, the shell was deformed, and some plastic mounting points were damaged. These defects made it unusable for its original purpose, but not for the large shell pieces I needed.

Opening the Shell

The rolling machine contains no screws. It is assembled entirely with clips. I gently inserted a small flat-head screwdriver into the joints, then released the clips one by one without twisting the long plastic parts. Work gradually: aged plastic is more likely to crack than to release cleanly.

Once the shell was open, I removed the base, covers, lever, and damaged internal mechanism. I kept every part still useful for rigidity and closure, then thoroughly cleaned the parts intended for the Q‑Stick.

Cleaning

The cleaning process follows the same reuse philosophy as the rest of the project. I used no new equipment: an old wash basin, my old toothbrush, and soapy water were enough.

I placed the disassembled parts in the basin to soften the residue, then brushed each piece separately. The toothbrush's small head easily reaches grooves, corners, the raised logo, and the clip recesses without damaging the plastic.

After brushing, I rinsed the parts, removed most of the water with a clean microfiber cloth, and then let everything air-dry completely.

Important: all parts must be perfectly dry before continuing. Check the grooves, clip recesses, and metal parts in particular. Do not begin drilling or installing electronics while any moisture remains.

Before drilling, I measured:

- the internal length and width

- the actual available height once the shell is closed

- the plastic thickness

- the joystick PCB footprint

- the height of the buttons and their connections

- the space required for the Nano and its USB connector

- possible wire routing without interfering with the joystick shaft.

This check is essential. In a salvaged enclosure, a few millimeters can determine whether the build closes properly or not.

This first series of photos documents both the disassembly method and the reason for rescuing the object: it could no longer be used as a rolling machine, but its material and shape could still serve another purpose.

Design the Ergonomics Before Drilling

15-prototype-electronique-avant-integration.jpg
16-disposition-reelle-joystick-orientation-imposee.jpg
17-boutons-en-croix-et-joystick-fixes.jpg
19-essai-encombrement-nano-et-cable-usb.jpg
25-ajustement-decoupe-interieure-outil-rotatif.jpg
26-controle-debattement-joystick-premiere-decoupe.jpg
27-verification-course-joystick-apres-ajustement.jpg

In the final playing orientation, I placed the joystick on the right and the four buttons on the left. A first horizontal-row layout could not fit within the narrow width of the rolling machine. The solution was to arrange them in a cross, like the diamond-shaped button layout of a gamepad: red at the top, blue at the bottom, white on the left, and yellow on the right.

This compact arrangement makes better use of the available width and keeps all four controls within easy reach of the thumb. Having two identical rolling machines was also useful: the second one served as a donor for spare parts during the integration tests.

The electronic prototype had first been validated flat on a breadboard. Positioning the actual components on the shell then revealed an important constraint: the joystick module only fits correctly in one orientation, with its pin header aligned along the length of the enclosure. This mechanical orientation does not necessarily match the one used during the first tests.

This is not a wiring problem: the firmware can swap X and Y and independently invert each axis. However, all four directions must be tested with the module held exactly in its final position before drilling and before locking in the settings.

I started by making a 1:1 paper template:

1. trace the outline of the top of the shell

2. position the joystick center

3. arrange the four buttons

4. temporarily attach the template

5. place your hands as if you were playing

6. check the internal clearance again

7. mark the centers only after validation

The colored button caps give the Q‑Stick its visual identity and make the actions easier to memorize:

B1 Blue : primary action or fire

B2 White : secondary action or movement

B3 Red : special action

B4 Yellow : fourth action depending on the game

The plastic in a salvaged object may have aged and become brittle. I therefore avoided drilling directly to the final diameter.

For each opening:

1. secure the shell properly

2. drill a small pilot hole

3. gradually increase the diameter

4. finish with a file

5. deburr both sides

6. test-fit the part without forcing it

The joystick is mounted under the front panel: only its shaft passes through the shell, while its PCB remains protected inside. Removable fasteners are preferable to large amounts of glue. The goal is to keep the controller serviceable, repairable, and upgradeable.

An initial test showed that the Nano board by itself could fit in the lower part of the shell, with its USB connector accessible at the end. The following photo documents this clearance test before the complete wiring was added.

In practice, the two rows of headers and the large number of wires required by the prototype take up much more space than the bare board. Once all the connections were added, the shell could no longer close cleanly. For this first working version, I therefore moved the Nano outside the enclosure rather than forcing the shell shut or weakening the wiring.

This compromise is intentional: this version validates the ergonomics, firmware, and game profiles using reusable prototyping hardware. A more compact evolution could use a smaller USB HID board, or a board soldered directly without headers or Dupont wires.

For testing, the Nano therefore remains outside the enclosure and the connectors stay removable. The board should be placed or secured so that its weight does not pull on the wires while playing.

At this stage, the silhouette of the rolling machine has completely changed: the joystick and four colored caps already make it look like a real Q‑Stick controller. In this version, intended to validate the concept without buying anything new, the Start and Select buttons remain on the breadboard with the Nano. They work normally, but are not yet integrated into the shell.

Electronics

QStickSchemaCablage_V3.png
28-q-stick-breadboard-start-select.jpg

I use the Nano 33 BLE Sense Rev2, why?

I already had this board in my prototyping equipment. It combines several useful features:

- a compact form factor;

- a native USB interface capable of creating a HID gamepad;

- a built-in RGB LED;

- a BMI270 accelerometer and gyroscope;

- enough inputs for the joystick, buttons, and future extensions.

The Nano operates at 3.3 V logic. Its inputs must not receive the 5 V used by some classic Arduino modules.

The joystick must be powered from the Nano's 3V3 pin, never from 5V.

The USB cable provides both power and communication. A Bluetooth version was considered, but it would have required a battery, protection circuitry, a charger, a converter, and a switch. All of that would unnecessarily crowd the small enclosure. This first version therefore remains intentionally wired.

Validated prototype pinout:

Joystick VRx : A0

Joystick VRy : A1

Joystick click SW : D2

Button B1 : D3

Button B2 : D4

Button B3 : D5

Button B4 | D6

Joystick VCC : 3V3

Common ground : GND

Each action button is wired between its digital pin and ground. The firmware enables the internal INPUT_PULLUP resistors, so no external resistor is required.

- button released: input is high.

- button pressed: input is connected to ground.

- logic inversion is handled by the firmware.

Ground can be daisy-chained between the four buttons to reduce the number of wires. The other terminal of each button goes respectively to D3, D4, D5, or D6.

Before plugging in USB, I checked with a multimeter:

1. no short circuit between 3V3 and GND

2. continuity of the common ground

3. each button, open when released and closed when pressed

4. no contact between adjacent inputs

The firmware applies an 8 ms software debounce. Rapid tests produced no unwanted double presses.

Select and Start buttons

Inputs D7 and D8 are already supported by the firmware:

Select : between D7 and ground

Start : between D8 and ground

These two buttons use HID positions 5 and 6. In this prototype, they remain accessible on the external breadboard next to the Nano. This keeps the setup reversible, avoids an additional purchase, and clearly shows the difference between the salvaged controller shell and the development electronics. Like the action buttons, they use INPUT_PULLUP and share the common ground.

Their operation was verified in Ridge Racer 4: Start confirms and pauses the game, Select changes the view, and the Start + Select combination opens the RetroArch menu.

The Firmware

29-prototype-complet-cablage-demontable.jpg
30-led-rgb-mode-classic-bleu.jpg
31-led-rgb-mode-motion-vert.jpg
32-led-rgb-mode-hybrid-violet.jpg
33-led-rgb-calibration-blanc.jpg

The Arduino folder contains four files:

- q-stick.ino

- config.h

- QStickGamepad.h

- QStickGamepad.cpp

In Arduino IDE:

  1. 1. install Arduino Mbed OS Nano Boards
  2. 2. select Arduino Nano 33 BLE
  3. 3. install the Arduino_BMI270_BMM150 library
  4. 4. open q-stick.ino
  5. 5. compile and upload over USB.

From the command line:

sh arduino-cli compile --fqbn arduino:mbed_nano:nano33ble q-stick

At startup, leave the joystick at rest for a short moment. The program takes 64 samples to determine its actual center, then applies:

- a dead zone around neutral

- conversion to the HID range −127 to +127

- software button filtering

- a USB report containing two axes, a directional hat, and eight button positions

In the final build, the joystick module is rotated by 90°: the original left direction points downward. The firmware corrects this orientation with X = -A0 and Y = -A1:

cpp
constexpr bool SWAP_XY_AXES = false;
constexpr bool INVERT_X_AXIS = true;
constexpr bool INVERT_Y_AXIS = true;

These three settings allow the program to be adapted to another physical layout without changing the wiring.

Make Q‑Stick appear by name over USB

The Arduino Mbed core normally identifies the complete device with the generic name Nano 33 BLE, even when a different name is defined in the HID class.

The provided tools/patch-usb-product-name.sh script replaces this string in the compiled binary before uploading it. The Nano keeps its Arduino USB IDs and standard bootloader, but the operating system now displays:

Arduino Q-Stick

The retroarch/Q-Stick.cfg file can therefore identify the controller precisely and automatically apply its mapping. This customization is optional: without it, the controller still works, but appears under the Nano's generic name.

Computer compatibility

Q‑Stick uses the USB HID Gamepad standard and normally requires no specific driver.

- Linux : detection and operation validated with RetroArch

- macOS : tested and confirmed working as a generic USB gamepad with RetroArch and HID-compatible emulators.

- Windows : should appear as a DirectInput controller and can be checked with the system joy.cpl tool.

The current version has been tested under Linux. macOS and Windows compatibility is based on the HID standard but should be verified on the corresponding machines before being presented as fully validated.

On Windows, some modern games only accept Xbox-style XInput controllers. They may require conversion software, unlike RetroArch, MAME, and most emulators that accept HID or DirectInput controllers. A USB data cable is required; a Mac equipped only with USB‑C ports will also need a suitable cable or hub.

Use the joystick click and RGB LED

The joystick's built-in push button is not used as an in-game action. It controls Q‑Stick's modes:

- short press: switch to the next mode

- one-second long press: recalibrate the IMU's neutral position

The built-in RGB LED immediately indicates the current state:

Solid blue CLASSIC: joystick on the X/Y axes

Solid green MOTION: tilt mapped to the directional pad

Solid purple HYBRID: joystick and motion available together

White : IMU calibration in progress

Red : IMU unavailable or calibration failed

In MOTION mode, two different thresholds create hysteresis: tilt activates a direction at about 15°, then releases it only after returning below about 9°. This difference prevents jitter when the controller stays close to a threshold.

CLASSIC mode is the one used for Mine Storm. MOTION and HYBRID prepare the controller for experiments with driving games or accessibility-oriented controls, but are not required for basic operation.

While examining the disassembled parts, I noticed a small translucent element already built into the shell. Its shape appears suitable for reuse as a light guide: its base could receive light from the Nano's RGB LED and carry the color to the visible part without drilling a new opening.

This solution must be tested before permanently fixing the board in place. Simply position the LED close to the base of the translucent piece, try blue, green, purple, white, and red in turn, and check visibility with the shell closed. If too much light leaks from the sides, a short opaque sleeve can optically couple the LED more closely to the translucent piece. Avoid putting glue on its optical surfaces.

Test and Create Profiles Adapted to Each Game

Test each function separately

Once the Q‑Stick was connected to the UNO Q's USB hub, Linux detected it as a game controller. The jstest tool can be used to verify the inputs before launching an emulator:

sh jstest /dev/input/js0

The physical test confirmed the final orientation:

left → negative X
right → positive X
down → positive Y
up → negative Y
center → 0

The four action buttons correspond to events 0, 1, 2, and 3. Select and Start, connected on the prototype breadboard, correspond to events 4 and 5.

Testing the controller outside the game is important: an incorrect direction can come from the mechanical installation, the firmware, or the emulator configuration. This method immediately isolates the correct layer.

Create profiles adapted to each game

Older consoles do not all use the same control conventions. Q‑Stick therefore separates two levels:

1. the Nano always provides a consistent USB gamepad

2. RetroArch loads a profile adapted to the game being launched

A profile can:

- keep both analog axes or use only one

- invert a direction

- disable unused movements

- assign the blue button to the primary action

- enable rapid fire for a specific game

- keep Start and Select for general navigation

There is therefore no need to reprogram the Nano every time the game changes. The physical layout remains consistent, while the profile translates the original console controls.

For PlayStation games that use a digital controller, the ps1-qstick.cfg profile converts the joystick axes into a directional pad with input_player1_analog_dpad_mode = "1". This setting is essential for navigating the menus in Ridge Racer 4. In this profile, white B2 confirms and red B3 cancels or goes back.

First profile: Mine Storm on Vectrex

Mine Storm is a good first test because its control scheme is simple but unusual:

- left/right rotates the ship

- Vectrex button 4 fires

- Vectrex button 3 controls thrust

- Vectrex button 2 triggers teleportation

- Vectrex button 1 is not used during gameplay

The minestorm-qstick.cfg profile translates these controls:

Joystick left/right Rotation

B1 blue : Fire / held Continuous fire

B2 white : Thrust

B3 red : Teleport

B4 yellow : Disabled

Joystick up/down : Disabled

The file contains, among other settings:

ini
input_player1_a_btn = "nul"
input_player1_b_btn = "2"
input_player1_x_btn = "1"
input_player1_y_btn = "0"

input_player1_left_axis = "-0"
input_player1_right_axis = "+0"
input_player1_up_axis = "nul"
input_player1_down_axis = "nul"

Continuous fire is enabled when B1 is held:

ini
input_player1_turbo_btn = "0"
input_turbo_mode = "3"
input_turbo_default_button = "1"
input_turbo_period = "6"
input_turbo_duty_cycle = "3"

A short press produces a single shot; holding the button chains shots continuously. The joystick is connected directly to the horizontal directions, a solution that proved more reliable here than automatically converting analog input into a directional pad.

About the games: this project does not provide any commercial ROMs. RetroArch and VecX are open-source software; to play, use a legally obtained copy or a freely distributed homebrew game.

Test Results

IMG_3655.jpg
IMG_3668.jpeg
IMG_3671.jpeg
IMG_3672.jpeg
IMG_3673.jpeg
q-stick.gif

Electrical

- no unwanted connection between 3V3 and GND

- four functional normally open buttons

- common ground validated

- joystick correctly powered at 3.3 V.

Firmware and USB

- successful compilation and upload

- automatic recognition under Linux

- USB name Arduino Q‑Stick validated

- two centered analog axes

- four independent action buttons

- working debounce

- functional RGB LED and mode switching

- Select on D7 and Start on D8, placed on the breadboard and recognized independently

- Start + Select combination validated for opening the RetroArch menu.

Real gameplay

- correct rotation in both directions

- blue B1: single or continuous fire

- white B2: thrust

- red B3: teleportation

- vertical controls disabled to avoid accidental actions

- Ridge Racer Type 4 can be navigated with the joystick using the digital PlayStation profile

- white B2 validated as confirm and red B3 as back

- Start, Select, and their combination tested in actual gameplay from the breadboard


Both tested profiles are therefore playable. They also serve as templates for adapting other games without changing the hardware.


What I could improve next

This version remains intentionally simple. The most useful improvements would be:

- add non-slip feet or a small internal weight

- build a custom internal mount

- save the current mode and selected settings in memory

- automatically select a profile according to the launched game

- make greater use of the IMU in a driving game, for example Hyperchase

- integrate all electronics and all six user buttons into the shell, without bulky headers or Dupont wiring.

A Bluetooth version remains technically possible, but it would require a battery and several additional circuits. I prefer not to complicate this small project as long as the USB version does its job perfectly.

Conclusion

V2 in preparation : fit everything inside the shell

The first version presented here intentionally remains a €0 prototype: the Nano, Start, and Select are installed on an external breadboard with removable connections. It validates the mechanics, firmware, ergonomics, and game profiles without buying any additional hardware.

V2 will have a different goal: fit the board, all six user buttons, and all wiring inside the rolling-machine shell. The future board will need:

- two analog inputs for VRx and VRy

- four digital inputs for B1 to B4

- two digital inputs for Start and Select

- one digital input for the joystick click

- a native USB interface capable of emulating a HID gamepad

- a built-in IMU, or an available interface for adding one.

That means at least two analog inputs and seven digital inputs.

Board under consideration: Seeed Studio XIAO nRF52840 Sense

The leading candidate for V2 is the Seeed Studio XIAO nRF52840 Sense. It measures only 21 × 17.8 mm and uses the same nRF52840 microcontroller as the current Nano. In this tiny form factor, it includes:

- a USB‑C connector and native USB interface

- eleven accessible GPIO pins, including six analog inputs

- an LSM6DS3TR‑C six-axis IMU

- an RGB LED

- Bluetooth Low Energy and a Li‑ion charging circuit, available for a later evolution but unnecessary for the wired V2.

Specifications, pinout, and mechanical files are available in the official XIAO nRF52840 Sense documentation (https://wiki.seeedstudio.com/XIAO_BLE/).

Proposed V2 pinout

  1. Joystick VRx : D0 / A0
  2. Joystick VRy : D1 / A1
  3. Joystick click : D2
  4. B1 blue : D3
  5. B2 white : D4
  6. B3 red : D5
  7. B4 yellow : D6
  8. Select : D7
  9. Start : D8
  10. Spare : D9 and D10

The joystick will remain powered at 3.3 V. To save as much space as possible, the board will be used without headers, with the wires soldered directly to its pads. A small insulating mount and strain relief will protect both the board and the USB cable.

Remaining software work

The current firmware cannot simply be uploaded without modification. The joystick handling, buttons, debounce, calibration, and profile logic can be retained, but the USB layer will need to be ported to Adafruit TinyUSB. This library already provides an official HID gamepad example for nRF52840 microcontrollers

The motion-reading code will also need to be adapted to the XIAO's LSM6DS3TR‑C IMU, followed by new tests under Linux, macOS, and Windows. V2 is therefore a planned evolution, not a feature already implemented in the contest prototype.

look differently at what is already lying around:

Q‑Stick is not just a homemade controller. It is the meeting point of several objects that no longer had a shared purpose: a rolling machine headed for the trash, a joystick and buttons forgotten in an old kit, and an Arduino board already used for prototyping.

The shell provided the shape and identity. The parts from the drawer provided the controls. The Nano and firmware transformed the whole assembly into a programmable USB device. Nothing was purchased specifically for the project.

The original function has completely disappeared, but traces of that first life are still visible. They are not flaws to hide: they tell the story of the transformation.

Reuse. Rewire. Replay.

Before buying a new enclosure or another kit, look at what is already in your drawers or in the pile of objects waiting to be recycled. An old remote control, a broken toy, an industrial control box, or an unlikely enclosure could become your next controller.

I used Claude (Anthropic) to review my English and suggest corrections, but I chose to keep some of my own wording and mistakes , English isn't my first language, and I'd rather stay honest about that than sound like someone I'm not.

Thank you!