Inspired by Martin Magnusson's wearable computer, I've refined the display, and modified a Nintendo Powerglove to be the complete interface!
To make the experience fit your profile, pick a username and tell us what interests you.
We found and based on your interests.
So, I haven't posted in a few months, but I have a big update! I was featured as the first segment in Ben Heck's Hacktiques Roadshow! It was filmed at the 2015 Makerfaire Detroit. See the video below:
My final code is linked below.
https://github.com/slicer364/powerglove-mouse/blob/master/HACKADAY_POWERGLOVE
A few notes,
Since the last code post, we add the "ledbutton" on/off switch code, and put the rest of the code together.
//led button on/off code is below:
const int buttonPin = 11; // the number of the pushbutton pin
const int ledPin = 12; // the number of the LED pin
int ledbuttonledState = HIGH; // the current state of the output pin
int ledbuttonbuttonState; // the current reading from the input pin
int ledbuttonlastButtonState = LOW; // the previous reading from the input pin
long ledbuttonlastDebounceTime = 0; // the last time the output pin was toggled
long ledbuttondebounceDelay = 50; // the debounce time; increase if the output flickers
void loop() {
//LED button code (temporary on/off switch)
int ledbuttonreading = digitalRead(buttonPin);
if (ledbuttonreading != ledbuttonlastButtonState) {
ledbuttonlastDebounceTime = millis();
}
if ((millis() - ledbuttonlastDebounceTime) > ledbuttondebounceDelay) {
if (ledbuttonreading != ledbuttonbuttonState) {
ledbuttonbuttonState = ledbuttonreading;
if (ledbuttonbuttonState == HIGH) {
ledbuttonledState = !ledbuttonledState;//if button is pressed, swap the led state
}
}
}
digitalWrite(ledPin, ledbuttonledState);
ledbuttonlastButtonState = ledbuttonreading;
if (ledbuttonledState == HIGH) {
/*ledbutton has to be lit in order to allow mouse clicks, mouse movement and precision mode to toggle.
*/
if (fingbool2 == 0) {
Mouse.press(MOUSE_LEFT);
}
else {
Mouse.release(MOUSE_LEFT);
}
}
}
}
Next, I'll go into how I made the heads up display and "computer box" !
Sorry for the long delay in updates. I’m currently working as part of a team for a large project at Makerfaire Detroit 2015, and that is taking up most of my project time.
Now, while I was tweaking the boom arm, I was simultaneously working on the electronics. While I do not have any experience yet laying out etched circuit boards, in my efforts to keep the project on schedule to complete by Penguicon 2015, I decided to go with what I knew- perfboards. With the four bend sensors, and the x&y wires from the joystick I ended up using every analog pin on the Arduino Micro. At the makerspace, I had found a led mounted inside of a momentary switch. My plan would be that it would allow me to have the glove output commands to the computer only when the button led was lit. Depressing the button would toggle the led and glove output on and off. I used digital pins 11 and D12 to control the button and LED respectively. The button uses a pulldown resistor. http://www.arduino.cc/en/Tutorial/Button
I used fritzing to lay out my perfboard. I'll be honest, the layout could have been less cluttered,and simplified in terms of resistor use but I had a time crunch.
I desoldered the ultrasonic speakers on the front of the glove, and hot glued them into place, to maintain a stock-ish appearance.
I soldered the eight flex sensor wires to two banks of .1” headers- one for the red wires, and the other bank for the rest of the colors.
While resistors (and flex sensors) can work in either direction, I never bothered to pair each of the red wires with its corresponding other-colored wire.Thankfully, each flex sensor has only one red wire. I would just use code to assign each arduino input to the function I wanted.
However, for the record, here is the following flex sensor wire colors:
thumb-dark blue
index-black
middle-white
ring-light blue/teal
In the images, you can see an additional momentary switch near the arduino’s analog pins. I had intended it to act as a backup on/off switch, but the project ended up going in a different direction. I’ve removed that from my fritizing diagram.
I used a dremel to make a rectangular hole in the right side of the backhand case, in order to make room for the eight connectors and wires that go to the LED button & switch, and the psp joystick.
Also, I had difficulty mounting the micro usb male connector. I took a standard usb male to usb micro male cable, and removed the plastic enclosure near the usb micro side, in order to make the wire bend angle more severe. I hotglued the usb cable into the hole where the backhand unit to wrist unit cable used to be.
Now, to close the backhand unit's case.
http://upload.wikimedia.org/wikipedia/commons/d/d3/NES-Power-Glove.jpg
I had initially overlooked the fact that the usb micro connector’s position was directly underneath a valley in the top of the powerglove, called out in the yellow rectangle. This valley greatly reduced the space available for my perfboard, and made the backhand unit impossible to close with the mini usb connector in place. So, after a suggestion from a fellow member and the makerspace, I put a heatgun to plastic panel, and hit both sides with a small,heavy, flat piece of metal, repeatedly. This worked surprisingly well, and the top of the backhand unit is now flat, and the cover could now close!
Sadly, by using the heat gun, the front area (marked in red) contracted, leaving an oval gap on the front side (with the circular openings for the ultrasonic speakers) when the backhand unit is closed. For appearances sake, I put a piece of black electrical tape over the gap, and the reflectivity of the tape is similar enough to the plastic that it is difficult to differentiate them.
Lastly, after the glove was functioning when the backhand...
Read more »To mount the boom arm to the glove, I bent a decent size piece of aluminum to hold the powerglove's forearm-fitting plastic piece. I made another bracket to attach to both the hinge and the main aluminum bracket. These brackets fit right into the glove, and are held in by 4-40 nuts and a backing plate. I stuck two strips of imitation velcro onto the backing plate and a FAVI FE02RF-BL2.4GHz Keyboard. This keyboard has a dedicated usb dongle to allow easy setup. I had initially messed around with a similar bluetooth keyboard, but getting it to reliably pair with the Raspberry Pi on boot was taking a significant amount of time.
http://www.amazon.com/FAVI-FE02RF-BL-Wireless-Keyboard-SmartStick/dp/B0090BTY8Y
Lots of pictures below.
Boom arm Retraction:
Mounting to the powerglove:
(Please ignore the green button in the image below. As I took these photos after the fact, I forgot to remove it while I took these photos. I'll explain it in a later post)
Backing plate, and velcro mounting the keyboard:
Fully attached boom arm and keyboard:
Next, we will add a temporary on/off switch, fit an arduino micro into the existing wrist unit, and put all of the code together!
Mounting the PSP joystick to the powerglove would be tricky. I had considered a few options for joystick placement, such as attaching it to the side of the index finger, a hinge that came over the top of the wrist, or even somehow adding the joystick to the bottom side of the thumb itself.
None of these seem practical. At i3 Detroit, the makerspace that I'm a member of, we had computer flight-sim joysticks laying around one day, and I realized that it might be practical to have a mechanism that replicated the top of a flight sim joystick, which has an ergonomically placed secondary joystick on the top of it. In order to retract it, and keep it in whatever position I wanted it to be in, extended or retracted, I found a lever-lock hinge on Mcmaster-carr. http://www.mcmaster.com/#1604a43/=x7pbl2
I replaced the lever with a wing nut to simplify the locking process.
After a fair amount of time cutting a piece of aluminum and bending it to conform to the inside of my palm- I finally had a boom arm equivalent to the flight sim joystick.
Another challenge was setting up the joystick wire bundle to avoid awkwardly contacting my palm while I was using the glove. I mounted the joystick 90 degrees from vertical, and did some funky soldering to connect 90 decree bent pins to rotate the bundle of wires. I zip tied the wire bundle to the side of the boom arm, and hot glued the bent pin setup to reenforce it, as it looked a bit fragile.
Now that we have mouse clicks being picked up by the computer, its time to get the mouse to actually move around the screen. In order to do this, I referred to the joystick mouse tutorial below, and modified the code as necessary.
http://www.arduino.cc/en/Tutorial/JoystickMouseControl
https://github.com/slicer364/powerglove-mouse/blob/master/powerglove_joystickmouse
Now, as I wanted the mouse to be low profile, and easily retractable, I settled on the PSP-1000 joystick- the joystick from the first generation PSP game system. https://www.adafruit.com/products/444
The "joystickmousecontrol" tutorial code applied cleanly to the psp joystick.
For some reason, I found issues if I let the mouse calibrate itself indefinitely. It might have been an issue with a short somewhere, but if I had let it calibrate too long, the mouse would eventually be pulled to the top left of the screen. In any case, stopping calibration after 5 seconds solved that issue. Calibration is listed in the tutorial's code as "borderdetect".
if (millis() > 5000){
/* after 5 seconds, do not allow any more border detection (mouse calibration)
*/
borderdetect=false;
}
-------------------------------
Let's add a way to hold the joystick to the glove.
Hey guys and gals. As this is my first writeup for one of my projects, please let any constructive criticism that you may have, or your thoughts on the posts that I have made so far. I am attempting to show a logical progression of the project, but there is always room for improvement!
To start converting finger movement into mouse clicks, I set up some rough code to define a threshold of approximate finger joint bending that beyond which, would translate into a mouse click. Make sure to have the serial monitor open while running the code.
https://github.com/slicer364/powerglove-mouse/blob/master/powerglove_calibrate
Now, the values taken from bend sensors in the fingers are between 0 and 1023, as there are 1023 discrete steps that the A/D converter turns the 0-5 volts into. As the bend sensors in the fingers are bent more, the resistance increases, and the step value decreases with the voltage.
The code above asks the user to keep all of their fingers open for a few seconds, and then close them to get readings from each finger at each position.
The average, "avg" is then taken between those values, and will be later used as a threshold to define "mouse clicks". As the properties of the bend sensors tend to differ from sensor to sensor, you will have to get these values yourself.
My threshold results from the calibration code:
thumb: 45
index: 27
middle: 43
ring: 51
----------------------------------------
Now that we have the finger threshold values, let's actually use them as mouse clicks!
https://github.com/slicer364/powerglove-mouse/blob/master/powerglove_debounced_clicks
Please note- my code above will only work on an Arduino Leonardo or Arduino Micro as they have the ATmega32u4 microcontroller, IT WILL NOT WORK ON A STANDARD ARDUINO. This is because the ATmega32u4 appears to a connected computer as a keyboard and mouse, not just a USB port.
Now, I'll be honest, I am skipping a whole lot of my trial and error code, and efforts learning on my part about debouncing momentary switches/buttons. When I initially wrote the code to translate finger movements into mouse clicks, I had never heard of debouncing. Simply put, it is a methodology to only recognize input "if you mean it", and ignore noise.
Without debouncing, if I quickly bent a finger to click, the code would interpret a really large number of clicks in that small amount of time that my finger was bent. The only good thing that I discovered with a lack of debouncing that is that if I had opened 300 of the same window on my computer, I could quickly close all 300. Yay.
Please see the following tutorial link for more information:
http://www.arduino.cc/en/tutorial/debounce
As a side note, I initially used the mouse.click() command, but then quickly realized that only mouse.press() would allow holding down the mouse- for click&drag input.
http://www.arduino.cc/en/Reference/MouseClick
http://www.arduino.cc/en/Reference/MousePress
I've clumped together all of the pointer finger code below to make it easier to follow.
void loop() { fingbool2= (analogRead(FingerV2))/avg2; /*if the finger reading is larger than avg reading value (threshold) for that finger, then the fraction is greater than 1, and the boolean fingbool BECOMES 1, and is true if the finger reading is smaller than the avg reading value (threshold) for that finger, then the fraction is less than 1, and the boolean fingbool BECOMES 0, and is false */ /* check to see if you just pressed the button (i.e. the input went from 0 to 1), and you've waited long enough since the last press to ignore any noise: If the switch changed, due to noise or pressing: */ if (fingbool2 != lastfingerstate2) { fingerlastDebounceTime2 = millis(); // reset the debouncing timer } //pointer finger = left click // whatever the current reading is, it's been there for longer // than the debounce delay,take it as the actual current state: if ((millis() - fingerlastDebounceTime2) > fingerdebounceDelay) { // if the button state has changed: if (fingbool2 != fingerstate2) { fingerstate2 = fingbool2; if (fingbool2 == 0) { Mouse.press(MOUSE_LEFT); } else { Mouse.release(MOUSE_LEFT); } } } lastfingerstate2 = fingbool2; //store the current values for the next loop of the code }
Opened wrist unit, top of board
http://www.instructables.com/id/Hacking-a-Powerglove/?ALLSTEPS
Opened wrist unit, bottom of board
http://www.instructables.com/id/Hacking-a-Powerglove/?ALLSTEPS
The first two images above are taken from that instructable, and they show the stock wrist unit internals.
In the image of the top (brown) of the board, the only parts that I care about are the tight bundle of eight wires on the left side of the image( four red, and four of various colors) and the four brown/copper colored vertical diodes. I replaced those diodes with 10K Resistors as per the instructable to make each of the flex sensors in the fingers act as part of simple voltage dividers. For more information on voltage dividers in this context, please see: http://homepage.cs.uri.edu/faculty/hamel/workshops/as220-sept-09/sensors-voltage-dividers.html
Please see the circuit diagram above for the general idea for wiring to an arduino, from: http://www.instructables.com/id/DIY-Robotic-Hand-Controlled-by-a-Glove-and-Arduino/?ALLSTEPS
Thankfully, the powerglove's wiring color scheme makes ...some sense. One red wire for each bend sensor. There are a bunch of other colors for the remaining wires from the bend sensors. When I initially hooked everything up, I randomly connected them to the arduino.
I was able to see expected output values from the four voltage divider circuits on my arduino that changed as I bent each of the fingers. Now that I was able to confirm the flex sensors worked as expected, it was time to map the changes in output from the arduino's A/D converter to mouse clicks!
Original Glove:
https://en.wikipedia.org/wiki/Power_Glove
Completed Glove project:
To start things off:
I didn't start writing this how-to while I made the wearable computer project. I've taken a series of photos in order to approximate the procedure in which I made everything. Also I will try to summarize my thought process as I progressed.
Now, as I don't have much experience with making electronics projects, some of my methods might be a bit brute force, or in retrospect, could have been simplified in other ways.
As the wearable computer rig project has multiple segments, I will be making writeups for them in the order that I made them:
1- Powerglove
2- Heads up display
3- "Computer box"
My main design goal with the modified powerglove was to connect to a Raspberry Pi, or any computer using a USB-A connector, and have vaguely ergonomic left/right clicking, mouse movement, and intuitive keyboard functions.
My initial plan to meet that goal was to:
•Keep the bend sensors in the fingers, but modify their use by using the mouse & keyboard libraries in an Arduino Micro to enable ergonomic left/right click functions.
• Add something under the thumb to allow ergonomic and precise mouse control. Whatever it needs to be must be retractable in order for the powerglove user to use their hand normally when they are not using the glove as a computer interface device.
•Add something to ensure that when the user is not actively using the glove, stop any accidental input.
• Remove the forearm "gamepad", and add a bluetooth keyboard
• Completely remove the existing infrared led/led sensor functionality, as I don't need it, but keep the forward-facing external sensors to keep it looking "stock-ish"
Create an account to leave a comment. Already have an account? Log In.
Become a member to follow this project and never miss any updates