As part of my RetroMatic project, I’ll be using a rotary encoder to control an Arduino. This will control menus on an LCD display, which will set the parameters on a video converter board, and the configuration of a scanline generator.
But my RetroMatic also contains a USB floppy drive emulator. Since I have the Arduino there anyway, and the video converter is controlled by a rotary encoder, I wondered if I could also control the USB floppy emulator via another rotary encoder?
The USB emulator is made by Gotek, but flashed with HxC firmware. I started by soldering on connections to the two buttons on the front:
The buttons connect ‘something’ on the board to ground, so I soldered connections on to the ‘something’ side of the buttons. The Gotek board and my Arduino share a common ground, so I can just ground the pins at the Arduino end to ‘press’ the buttons.
To ensure none of the Arduino’s 5v goes anywhere near the lower voltage Gotek board, I make sure the Arduino’s pins are left floating by setting them as INPUT mode with no pull-up. I then set them to LOW (0v):
// input mode so they float pinMode(HXC_BUTTON_LEFT, INPUT); pinMode(HXC_BUTTON_RIGHT, INPUT); // low so that when we set them to output they'll be pulled to ground digitalWrite(HXC_BUTTON_LEFT, LOW); digitalWrite(HXC_BUTTON_RIGHT, LOW);
This means they’ll be at a floating voltage until I’m ready to press the button. Then all I need to do is set the pin to OUTPUT mode to ground the pin (because it’s already set LOW) and therefore ‘press’ the button:
void hxcLeft() { pinMode(HXC_BUTTON_LEFT, OUTPUT); delay(BUTTON_DOWN_MILLI); pinMode(HXC_BUTTON_LEFT, INPUT); delay(BUTTON_UP_MILLI); }
I found that the Gotek buttons are quite slow to respond, and require 145ms to reliably register a ‘press’. I also need a delay of 85ms between presses to reliably register as separate events. So a total of 230ms per press, or about four events per second.
Here’s a short video of my first successful test. The LCD on the left prints “GO” and then sends ten button presses to the Gotek (the LCD on the right). Then it pauses for five seconds and repeats:
With only four events per second, the user experience is quite limited. It’s possibly to spin the rotary encoder much faster than this.
So I experimented with buffering up the ‘clicks’ and then playing them back at a rate the Gotek can handle. This works so far, but if you get too many then it will take several seconds to finish, which gives a very confusing user experience.
I decided to allow a certain number of clicks to be buffered (for now I’m trying five). Above that, the user is probably spinning it so fast they don’t care about the exact number of clicks, they just want to scroll as fast as they can. So above five clicks in the buffer I switch to simulating holding down the button on the Gotek, which activates a slightly faster continuous scrolling mode (about 170ms per item). I then release the button if the user stops spinning for more than half a second.
Here’s an example:
This gives a fairly accurate and fairly responsive ‘feel’ to the control, so I think it’s probably worthwhile continuing with my experiment :-)