Category Archives: 3D Printing

XBOX Adaptive Controller (XAC) with Custom Arduino Joystick — Working Code

At long last I’ve revisited my problem with getting the Arduino Leonardo / Pro Micro to work with the XBOX Adaptive Controller (XAC). This code now works with the XAC! Huzzah!

More to come. I’m working on a Nintendo JoyCon Joystick version for a user with limited mobility.


include “Joystick.h”


true, true, false, false, false, false,
false, false, false, false, false);


const boolean debug = true;


//Joystick variables – Button (with debounce)
int SEL, prevSEL = HIGH;
long lastDebounceTime = 0;
long debounceDelay = 50; //millis


//Joystick pins

define VERT_PIN A9 // AKA the “Y” — dependent on how thumbstick is oriented

define HORZ_PIN A8 // AKA the “X” — dependent on how thumbstick is oriented

define BUTTON_PIN 7 // Pushbutton of the thumbstick

//Mapping to XBOX Adaptive Controller
//X and Y will auto map to Axis 0/1 or 2/3 depending on which side you plug
//the joystick into (left=0/1 or right=2/3). The pushbutton on the stick needs
//to be set & programmed depending on placement. TODO: Some sort of config on stick?
//10=Left Stick Press, 11=Right Stick Press



int rawHorz, rawVert;
int mapHorz, mapVert;

//invert if needed
bool invHorz = false;
bool invVert = true;


void setup() {

//Startup the joystick object.
Joystick.begin(false); // false indicates that sendState method call required (so we do all changes at once).

//I’m using Map below, but setting range Just In Case.
//Also setting Axis to zero at startup.
Joystick.setXAxisRange(-127, 127); Joystick.setXAxis(0);
Joystick.setYAxisRange(-127, 127); Joystick.setYAxis(0);

//Set HORZ and VERT pins (from joystick) to input

if (debug) {



void loop() {

// —————————————————-

// Check for button push – and debounce
int reading = digitalRead(BUTTON_PIN);
if (reading != prevSEL) {
lastDebounceTime = millis();// reset timer
if (millis() – lastDebounceTime > debounceDelay) {
if (reading != SEL) {
SEL = reading;
if (SEL == LOW) {Joystick.pressButton(XBOX_AC_STICK_BUTTON);}
else {Joystick.releaseButton(XBOX_AC_STICK_BUTTON);}
prevSEL = reading;

// —————————————————-

//Read analog values from input pins.
rawHorz = analogRead(HORZ_PIN);
rawVert = analogRead(VERT_PIN);

//Map values to a range the XAC likes
mapHorz = map(rawHorz, 0, 1023, -127, 127);
mapVert = map(rawVert, 0, 1023, -127, 127);

if (debug) {
Serial.print(“RAW H/V: “);
Serial.print(” “);
Serial.print(” “);
Serial.print(“MAP H/V: “);
Serial.print(” “);

if (invHorz) {mapHorz = -mapHorz;}
if (invVert) {mapVert = -mapVert;}


// —————————————————-

// Send updated joystick state to HID upstream



AutoScope 2.0 : In Search Of Home

It’s so simple a problem that it’s a giant pain in the neck! To further automate the microscope, I need a way for the program to find a “home” position — a starting point. Something that won’t strip gears, crack slides, or otherwise cause mayhem.

Most X/Y/Z devices (3D printers, laser cutters, CNC routers, etc) use limit switches. The trouble is the way the microscope stage moves.

X – Moves just the slide left/right
Y – Moves the stage forward/back
Z – Moves the entire stage up/down

So, you either start attaching switches in weird places (on the stage, on the body) or come up with something else. Added fun? The top limit of Z should change depending on the objective lens. And, by the way, not the entire stage moves for Y — just the very top of it. But, Z does move everything. You start to see my problem.

How to cleanly find home, inexpensively, with as little modification to the microscope as possible?

I’ve looks at more sensors than I wish to admit:

Time of Flight (Laser) — Good for finding a single direction of movement, but I’d need three at $15 each. I tried some ideas of using just one for X and Y, but that didn’t pan out.

RGB Sensor Through Eyepiece — Find the “dark” / black and you determine the edges of the sample. Works fine, in a controlled (dark) environment, but reflected light (from the room light, bouncing off the top of the slide) messes with the readings.

Hall Effect Sensors — Like switches, but triggered by magnets. Most promising, but when Z is moved, their point of triggering changes. I pretty much need a constant/known distance between magnet and sensor.

Accelerometer / Magnetometer — AKA Gyroscope and Compass — Good for finding Yaw/Pitch/Roll, but since the microscope doesn’t Yaw/Pitch/Roll, not helpful for me. The stage movements are too small to accurately tell if its moving in a particular direction. Perhaps this is a solution, but I’ve not figured out how to tease out good data.

I was also thinking of a proximity sensor, like the one found on our Prusa 3D printer. Kinda like a Hall Effect without the magnets. But, the sensors aren’t cheap ($15-$30 each), pretty big, and I’d need three. And the whole range of motion problems and where to mount them.

This is the Y switch. You can see how part of the stage (toward top) moves, bottom part doesn’t.

So, for now, I’ve admitted defeat and gone back to micro switches. I’m hoping to get them working “good enough” so that I can write code. For now, the focus (ha-ha) is on X and Y. I’ll add Z later. (Z is less important, as the focus really needs a human eye, or smart AI.)

The X switch. Using a “finger” on the stage I printed. The program will find Y first, to move the stage closest to the user/switches. Then will look for X. Final program will lower to find Z, then Y, then X.

ESP8266 Digital Pocketwatch — And Network Sniffer

Pocket watch or network sniffer? Not sure. Both? A portable web server? I haven’t figured it out yet.

Using a recycled LiPo battery from an eCigarette. MakerFocus ESP8266 WiFi dev board with 0.91″ OLED display and charging circuit.

The 3D printer makes iterating though designs easier. A lot of unused parts, but we use them during classes to illustrate the progression of work — it’s not right the first time! Or the 5th!

AutoScope 2.0 : X Axis Slippage

I noticed that the X knob needed just a bit of tightening. This, of course, required that most of the microscope be taken apart.

A nice find was that there’s a cutout in the lower casting. Almost exactly the correct size for an OLED display.

Back together again, with one of my “home sensor” tests (in this case, a laser Time of Flight sensor).