It is currently Tue Oct 24, 2017 2:52 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 64 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next
Author Message
 Post subject:
PostPosted: Sun Apr 01, 2012 11:29 am 
Offline

Joined: Mon Jul 07, 2008 7:40 pm
Posts: 61
Round 4 test:
Got the full packet structure. A few weird things do go on, but the term "junk" is highly inaccurate.
Also, revising my earlier observation, packet position is quite stable even with all fingers reporting maximum flex. What sends the glove into a tailspin is dramatic over-flex. Flexing in the vicinity of the root-knuckle of any finger, even just one finger. My best guess is that this returns a value so high that the glove's A->D converter takes more than a frame to attempt to tally it up, or perhaps simply overflows.

----

Values come through bitwise-inverted. E.g. "11111111" should be read as "00000000". The header byte "01011111" seen raw from the controller should be read as "10100000"

The Packet:
Byte 1: header
Value: always 10100000 ($A0)

Byte 2-4: X, Y, Z
Value: 2's complement -128 to 127; right/up/away-from-screen is positive

Byte 5: rotation
Value: $0 (back of hand facing up) clockwise to $B (back of hand facing 11:00)

Byte 6: fingers
Value: needs to be calibrated. Digits will report all 1s until glove is flexed to a new maximum flexure, at which point digit values will report the 2-bit resolution amount between straight and maximum observed flex.
bits: ttiimm?? - [t]humb (hard to use), [i]ndex, [m]iddle, [?]unknown (I thought I recalled seeing the glove should report thumb + first 3 fingers, but either my ring-finger flexstrip is broken or else you only get thumb+2)

Byte 7: buttons
Value: index of lowest button pressed (you only get one button index, and the lowest index generally takes precedence*)
Button indices:
0/Center: $0
1-9: $1-$9
A: $A
B: $B
left: $C
up: $D
down: $E
right: $F

Enter: $80
start: $82
select: $83

* Directional buttons trump all. Enter/Select/Start (in that order) take precedence over all non-directional buttons, but are trumped by directions. Within directions, left and right take priority over up and down.
** I would not be surprised if Prog is $81, but Center and Enter are already to-be-avoided as they beep the glove and wreck one sample or so of data. Prog seems to flip the glove back into user-program mode, so it really doesn't matter what value it returns (other than perhaps to catch it so you can re-flash the glove to high-res)

Bytes 8-9: zero
Value: always 0

Byte 10: occlusion
Value: 00abcdef
abc: right-mic
def: left-mic
a/d: lower-right speaker
b/e: upper-right speaker
c/f: upper-left speaker
bits will normally be 1, but will drop to 0 if the particular speaker-mic data is lost.
e.g. if bit 0 (f) drops to 0, the left mic can't hear the upper-left speaker.

Byte 11-12: one
Value: always $FF


Top
 Profile  
 
 Post subject:
PostPosted: Mon Apr 02, 2012 8:54 pm 
Offline

Joined: Mon Jul 07, 2008 7:40 pm
Posts: 61
Round 5 test:
At least 2 bytes of the init message have fallen, and based on them, I have suspicions about 2 others.

The last 2 init bytes appear to be a data mask
1 bit per data field, read lowbit to highbit.

Init byte 6 (formerly fixed at $FF):
??bfrzyx
[x] position
[y] position
[z] position
[r]otation
[f]ingers
/[b/]uttons
[?] always 0?
[?] always 0?

Init byte 7 (formerly fixed at $01):
1s?????m
[m]ic occlusion
[?] preliminary indications are that these may be "writeable" to turn the 6 frame LEDs on and off. They all seem to return fixed garbage patterns that rescramble at reset.
[s]peaker status? This byte seems to return 0aaa1bbb where 'a's are flickering in sync at roughly the LED rate, and 'b's are flickering out-of-sync but roughly at the same rate. I strongly suspect that both triplets reflect some aspect of the real-time status of the speakers/pings.
[1] returns 11111111

12 bytes are always returned (until further notice- that may be what the $C in $C1 means), but any masked-out fields are skipped. E.g. if byte 6 was $F0, packets would start with fingers/buttons/0/0. If fewer fields are unmasked than there are packet bytes, the packet is padded with $FFs.


Also, some timing news:
Neither the 5µs latch wait at the start of each byte, nor the 22µs timing between clocks, NOR the 1-frame wait after the first 8 bytes(!!) are required. In fact, reading all bytes on one frame actually removes the issues I was seeing with packet-shift when making a tight fist. The short wait between bytes, however, is required. It may not be exactly 96µs, but that value works well enough. And per the above info on the bit masks, more bits means the glove needs more time between readings... I think. Or I may have just accidentally asked for more bytes than fit in the current 11-byte (+ header) packet :oops:

I'll be out of town for a few days, but I'm getting pretty psyched here. Expect more results by the weekend :D

Edit: corrected byte 7 bits based on new observation.


Last edited by LoneKiltedNinja on Sun Apr 08, 2012 1:16 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Sat Apr 07, 2012 7:49 am 
Offline
User avatar

Joined: Fri Sep 26, 2008 7:55 pm
Posts: 105
Location: Montreal
Just wanna say I've been following; no doubt you are a god-send and my mind is blown.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Apr 07, 2012 4:05 pm 
Offline

Joined: Mon Jul 07, 2008 7:40 pm
Posts: 61
*PowerGlovemumblemumblesledgehammermumble*
oh, sorry, where was I?
Right. Cracking the init message.
Got a new half-byte, the most painful way possible.

on byte 2 (canonically $C1)
Increasing C (upper 4 bits) has no immediate effect. Decreasing it to A breaks the system. I still want to believe this is some kind of specification to set aside 12 bytes of memory for return data, but if it actually controls packet size, then the system is more tolerant of specifying 13 bytes and polling for 12 (no visible change) than specifying 12 and polling 8 (gratuitous packet creep).

The $01 part (lower 4 bits) appears to be a mode switch.
Bytes returned when changed to
$00: header, junk*, FFs
$01: normal (header, x, y, z, rotation, fingers, buttons, 0, 0,mic,…)
$02: header, z, rotation, buttons, mic, junk*, junk*, FFs
$03: header, rotation, fingers, FFs
$04: header, mic, FFs
$05: header, x, gesture(), mic, FFs
$06: header, x, z, gesture(z), 01100000, FFs.
$07: header, z, rotation, FFs
$08: header, x, rotation, mic, junk*, junk*, FFs
$09: header, y, rotation, fingers, junk*, FFs
$0A: header, x, y, z, fingers, mic, junk*, FFs
$0B: header, x, fingers, mic, junk*, junk*, FFs
$0C: header, y, z, rotation, buttons, junk*
$0D: ** special sauce. Gonna need to give this one another frame (total 5 60Hz NMI waits) to get its data together. Returns header, x, gesture(tyz), highnearfinger, junk*, junk*, junk*, FF, 01100000, FFs. Highnearfinger is an oddball value and may be why mode $D takes so long. 0000h1nf. h is 1 if the glove goes too [h]igh (above center in y). n is 1 if the glove goes too [n]ear (screenwards of center in z). f is 1 if your index [f]inger is bent at all. There may or may not be a slight delay on these, but they don't seem to be timed against gesture (although they are likely provided to allow $D to be an advanced motion-gesture mode).
$0E: header, y, fingers, buttons, gesture(yz), junk*, junk*, FFs
$0F: header, z, tyzmotionx, mic, FFs

"gesture" is a new packet byte that fell out of the system, and it shows up in various flavors. In full form, its bits are tyzlrx10.
[l] 1 if glove has, generally over the last few samples, moved left (or stayed still after previously moving left)
[r] 1 if glove has, generally over the last few samples, moved right (or stayed still after previously moving right)
[x] 1 if, last time l/r changed value, x position was left of center (negative)
[y] 1 if, last time l/r changed value, y position was below center (negative)
[z] 1 if, last time l/r changed value, z position was screenwards of center (negative)
[t] 1 if, last time l/r changed value, the thumb was bent.
Bits l, r and x always seem to show up. The others vary by mode and are included in parentheses. E.g. gesture(yz) means the gesture byte with y, z, l, r and x live (but t fixed to 0)

It is possible for l and r to both be 0 if the glove moves one direction and then nudges the other without actually moving much. They seem to set themselves after a movement of 4-8 units.

* these "junk" values behave like the second-mask-byte-middle-bit (LED control?) values. Static, seemingly meaningless values that rescramble when Center is pressed. New values only seem to change if some monitorable field has changed, and some seem to correspond particularly to a given field. Nonetheless, I have yet to find a meaningful way to utilize their return values.

The above data was obtained with the mask bytes set to their canonical values ($FF,$01). While FFs usually mean the end of the packet, it is not beyond belief that there would be a tiny bit more data if everything was unmasked. I just don't want to try asking for 16 bytes of data without knowing how to ask for a 17-byte packet.

I also have a suspicion that many of these modes that only return 3-6 bytes may sample faster than mode $1, meaning you may be able to jump up higher than every-4-frames. But I'm not going to do 48 more tests to determine how few frames sampling-delay each mode is stable at. *grumblesledgehammergrumble*

I've run a few demo revisions testing the "LED control" bytes, but have yet to get anything but all-out 8-clocks-per-latch x 6 latches to show an effect on the LEDs. So it's not quite as simple as I hoped, but I remain optimistic, since the other fields in that mask byte seem to be coming from the speaker-frame.

Edit: that first nybble is still kicking my ass. I've tried $6 and $A on mode 4, and $A, $B, $D, $E and $F on mode 1 (and accidentally, $B on mode F). Legal values appear to be $C and $D, regardless of mode. Other values seem to consistently jam in either returning all FFs without finishing configuration, or return all F0s and flicker the directional LEDs while holding the A/B LEDs steady, without finishing configuration. Since there seems to be a sweet spot, and values don't appear to affect packet size, I'm going to revise my guess and say this may be a sampling-rate setting. Murmurings at the tail-end of the newsgroup/mailing list suggest the glove is at least hardware-modifiable for sampling rates between "1" and "30" with a suggested setting of "14." Maybe some future person with a good scope can clear this up, but I may throw in the towel and call byte 2 as defined as it's going to get if I don't see anything immediately noteworthy on e.g. that speaker-state byte from mode 1.

Edit2: As confirmed as it's gonna get: the first nybble is, with my 90% confidence, sampling rate.
I have no hard numbers on precisely what units it's in, but if I put my ear very close to the glove, I can hear some component ticking away either emitting or receiving pulses. Before initialization (in pad-emulation mode), it's quite rapid. With initialization to $C, it slows down slightly. With initialization to $D it slows down more perceptibly. I don't quite know why asking it to sample too slowly would cause issues at init, but too fast could easily out-pace the hardware for big packets. Perhaps other bytes will shed light on this.


Edit 3: Er... no, the first 4 bits really should be $C. $D works, but now that I can re-flash the glove at runtime rather than just once at startup, I'm (a) not hearing the frequency change, and (b) sending $D locks the glove out of receiving any more config until it is manually cleared back to a pad-emu program (e.g. [PROG][1][ENTER][ENTER]).

And the middle bits are looking less like LED control now that (a) I've looked more carefully and found there are only 7 of them, and (b) when I'm polling within 1 frame rather than across 2, the LEDs are all stable. Which means the LEDs probably only go out of sync when the glove's timing is being stretched.


Last edited by LoneKiltedNinja on Sun Apr 08, 2012 1:27 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Sat Apr 07, 2012 8:36 pm 
Offline

Joined: Mon Jul 07, 2008 7:40 pm
Posts: 61
Last one for the night, and maybe for the weekend.

on byte 1 (canonically $06)
Only use the low nybble. The system seems to lock up if the value is above $0F (tried $10, $11, $F0). System locks identically if the value is $00. Either way, all returns are $FF.
Nonzero values below $04 yield a degenerate return packet with only header, rotation, buttons and mic (and trailing FFs).
$04 itself yields a confused mode in which the LEDs flicker as if high-res sampling (sampling rate byte seems initially to be ignored) but also illuminate as if in pad emulation mode. Returned values behave as pad-emulation mode.
$05 and above appear to yield normal performance (tried $05, $06, $07, $0F).
I'm going to tentatively call this one fully specified for now. Emulator authors can return the values specified. My gut sense is that this header byte is either some sort of reserved-value additional mode config or, as originally posited, a notification of how much memory to reserve for taking in the config message. The glove just so happens to be forgiving for slightly-too-low and moderately excessive values.

on byte 5 (canonically $02)
I got nuthin. Values $00, $01, $02, $04, and $FF are all legal, and performance is indistinguishable. This is probably either a reserved slot or a defined value that the hardware ultimately ignores safely.
Homebrewers, I'd say keep using $02. Emulator authors, freely ignore this byte for now.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Apr 08, 2012 2:03 pm 
Offline

Joined: Mon Jul 07, 2008 7:40 pm
Posts: 61
I did what I should have done days ago and put together a new, streamlined test ROM that lets me use a regular pad in port 2 to change init values and re-flash the glove at runtime rather than constantly building new test cases by hand. I should be able to post the source & binary soon.

on timing:
The LEDs blink on whenever the glove is polled-while-expecting-to-be-polled. Slow down your own query rate and the blinking slows. But if you ask for data when the glove isn't ready, they get flakey and out-of-sync.
When you do all your polling in 1 frame, it is possible to poll the glove every 3 frames (20Hz) rather than every 4 (15Hz), but then you push the limits and run over whenever you make a tight fist. Still, it may be useful for high-speed interaction when the player knows to only flex their fingers slightly.
You can also slightly decrease the time required between packets by asking for fewer fields. It may not gain you a full frame of time reduction, but when I make a tight fist at 20Hz, data is a lot more stable when I'm masking in 4 fields and only polling 6 bytes than when I'm masking in 9 and polling 12.
Even in mode 4 with only the 1 field masked in and only polling for 3-4 bytes, I can't get up to 30Hz (every other frame) sampling.

on data fields and packet size:
There is no standard packet size. The 12-byte canon is spurious.
If you ask for more bytes than you have fields masked in, you get trailing FFs. If you ask for fewer bytes than you have fields masked in, the glove appears to TRY to retain values for you until it's seen you request them all, and then next time it sees a big long pause it will reset to the header of the next packet, but I would not rely upon this behavior for anything. Be safe and always latch at least as many fields as you mask in. If you routinely ask for precisely as many bytes as you have fields (plus 1 byte for the header), you get data, but the LEDs get angry. Good practice is probably to always ask for at least 1 trailing byte (which is probably why the canonical 9-field packet was polled in 12 bytes).

on artifacts:
There may be something significant about the first configuration flashed at startup. Once or twice I've flashed new configurations that should have only required polling a few bytes but observed system instability until I went back up to my full prior packet size. This seemed to resolve when I reverted the glove to a pad-emu program and flashed it back into direct mode from there.

Edit: info updates


Top
 Profile  
 
 Post subject:
PostPosted: Sun Apr 08, 2012 6:24 pm 
Offline

Joined: Mon Jul 07, 2008 7:40 pm
Posts: 61
I'm still going to take a swing at the remaining init bytes, but I don't think I'll come across anything that lets me make a better tool than this. So as a data viewer, hardware tester, and coding reference, check out

http://www.psychsoftware.org/portfolio/ ... testDX.zip

File contains
- glovetestDX.nes (compiled test ROM)
- glovetestDX.asm (nesasm source)
- fullascii_alt.chr / fullascii_alt.bmp (chr file and content preview for building the ROM)
- readme.rtf (document on operating the test tool, and organizing the various findings on this thread)


Top
 Profile  
 
 Post subject:
PostPosted: Sun Apr 08, 2012 8:04 pm 
Offline

Joined: Mon Jul 07, 2008 7:40 pm
Posts: 61
more on byte 1
If you have already flashed one string leading with 0x06 or higher, any subsequent flashes seem okay with a lower value in byte 1 UNLESS the glove has been set back into a pad emulation program. In that case, it has trouble with values below 0x06 (0x05 "works," but only if byte 7 is insignificant- e.g. 0x05 in byte 1 somehow works with 0x01 in byte 7, but not with 0x41 in byte 7).

This collection of circumstantial evidence leads me to adopt my initial hypothesis that this first byte is the number of subsequent bytes to be given in the init string, which the glove needs to set aside memory for. When it's cold (at startup, before getting anything flashed) and is asked to allocate more memory than is available, it dies. If it's already allocated memory and is running in direct-access mode, it's forgiving and doesn't reallocate downwards. If it's put back into prog-mode but is otherwise initialized for direct-mode, it does reallocate but is a bit more stable against too-high values.

more on byte 5
Changed in isolation, this byte does not appear to have any impact on anything. With the other bytes at their canonical values, 0x00, 0x01, 0x02, 0x04, and 0xFF are all legal, and performance is indistinguishable.
Changed in conjunction with byte 1 (provisionally, total init string length) and byte 7 (mask byte 2) while reverting to a pad-emu program between tests, interesting behavior appears. If byte 7 is nontrivial (more than just the single trailing high bit), e.g. 0x41, the system seems to detect that it's there regardless of what it's told to expect. In which case, if byte 1 is 0x5 and byte 5 is 0x1, the system freaks out- garbage values everywhere. But if byte 1 is 0x5 and byte 5 is 0x2, the glove is more likely to just lock. This may suggest byte 5 is, as I have half-suspected, some sanity check of how many mask bytes follow (since in many modes only a few fields exist, and 2 masks may not be needed). Again, the longer the glove has been up and the more it has been flashed, the more forgiving it is, but if it's suddenly asked to receive more than it has allocated, or if it is sent more than it has allocated, or if it knows it needs more bytes but cuts off receiving before it gets them, interesting undefined states occur which may or may not be stable.


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 06, 2012 11:18 am 
Offline

Joined: Mon Jul 07, 2008 7:40 pm
Posts: 61
Project is not ~quite~ done yet, but this is where everything's been headed for the past 2 months. Yes, it is possible to homebrew for the PowerGlove, thank you very much :D

http://www.youtube.com/watch?v=OlyE5zA4XZ4


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 06, 2012 12:19 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3944
I just can't help but think how much easier it would be to just plug in a Miracle.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 07, 2012 5:29 pm 
Offline

Joined: Mon Jul 07, 2008 7:40 pm
Posts: 61
Dwedit wrote:
I just can't help but think how much easier it would be to just plug in a Miracle.

Two points, both from Wikipedia:
"Due to its high price ($500) and low sales, the keyboard with all of the original cables together are a rare find."
Even buying the devcart and a complete-in-box PowerGlove, Nesglovphone only cost half that.

"The Miracle Piano did not ever generate sounds from the NES hardware; all NES MIDI information was converted into audio by the instrument's built-in ROM and played through the instrument's stereo speakers"
Nesglovphone was designed to turn the 2A03 pAPU into an instrument. While the Miracle would be cool to have, and if I ever see one I may just buy it as an input if it can really transmit keypresses to the NES (and brew my own software to play the notes on pAPU rather than on-board), it wouldn't have quite fit the bill.

But it does look cool, and hadn't been on my radar before :)

_________________
Psych Software- failing to profit from retro/indie development since before it was cool
http://www.psychsoftware.org


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 07, 2012 6:04 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3944
Miracle communicated with the NES in both directions. NES sent the Miracle midi note events, controllers, etc, and the NES received MIDI note events from the keyboard.
One of the commands muted the Miracle. The NES game briefly sent that command at the end of every lesson or played back song, then sent the other command to resume audio once the next screen had loaded, so it's usually muted for about a half second. I'm not 100% sure whether the keyboard would be transmitting midi events at that time, but it probably would be.
So you could have a muted Miracle tell the NES to play notes, and the NES could play them.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 07, 2012 6:28 pm 
Offline

Joined: Mon Sep 27, 2004 2:57 pm
Posts: 1248
Well, I don't see anyone else trying to reverse engineer the powerglove, so I'd say he can do whatever he wants with it. :P

Keep up the good work! It's fascinating that this old NES peripheral is so complex. o_O


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 07, 2012 6:49 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6304
Location: Seattle
Tangentially, do we have permission to use your words in describing the powerglove on the wiki?


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 08, 2012 7:32 pm 
Offline

Joined: Mon Jul 07, 2008 7:40 pm
Posts: 61
lidnariq wrote:
Tangentially, do we have permission to use your words in describing the powerglove on the wiki?

I wouldn't just transcribe the thread, if that's what you're asking- a lot of my earlier posts were purely hypothetical starting points for exploration, and the rest is organized by discovery date rather than in any kind of coherence.

The video comments link it, but this is probably a fair place as well- my website has my full "devkit" for the glove- the test tool with source, a tech doc, a few of the docs I started with, and source distributions of nesasm and Bob Rost's CHR/sprite tools thrown in for good measure.
http://www.psychsoftware.org/portfolio/ ... html#Other

Feel free to copy whatever's useful from the readme, ideally with attribution.

Also, assuming I meander over to People Play Games this Friday and they happen to randomly have a Miracle with enough cabling to get it to the NES... I don't suppose there's a definitive tech doc on that one either? At least I'd hope it doesn't need an init string... >.<

_________________
Psych Software- failing to profit from retro/indie development since before it was cool
http://www.psychsoftware.org


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 64 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group