Showing posts with label wireless. Show all posts
Showing posts with label wireless. Show all posts

Sunday, December 30, 2012

Wiimote+nunchuk web surfing in linux

At this point, messing around with the wiimote probably seems dated, but hey, I have one lying around with a motionplus and nunchuk. The final outcome of this post if you follow it- you'll be able to control your mouse cursor with the nunchuk analog stick, scroll up/down/left/right with the wiimote d-pad and left/right click with either the wiimote or the nunchuk. Let's get started.

Prerequisites:
  • A wiimote
  • A wiimote nunchuk
  • A linux system with the uinput kernel module
Procedure:
  1. Clone my fork of cwiid into a directory of your choice(wiimouse for example here)
    git clone https://github.com/trtg/cwiid.git wiimouse
  2. cd wiimouse
  3. aclocal
  4. autoconf
  5. ./configure --with-cwiid-config-dir=/etc/cwiid/
  6. make
  7. sudo make install

    Note that by default this will install everything using a prefix of /usr/local unless you pass --prefix=some_other_directory to configure so make sure whatever prefix you use is in your path.
  8. sudo modprobe uinput
  9. Create a new config file for the plugin I wrote by creating the file /etc/cwiid/nunchuk_stick_ptr and adding the text below to it
    include buttons
    Plugin.nunchuk_stick_ptr.X = REL_X
    Plugin.nunchuk_stick_ptr.Y = REL_Y
  10. sudo wminput -c nunchuk_stick_ptr You will see this message appear: Put Wiimote in discoverable mode now (press 1+2)... Do as it says and press buttons 1 and 2 on the wiimote then release them, the LEDs on the wiimote will blink for a while then the terminal where you entered the previous command will say: Ready.
  11. Now try moving the nunchuk analog stick and it should move your cursor around. Adjust /etc/cwiid/wminput/buttons if you want to change button mappings
Note: if you do not want to have to run wminput as root, you can configure things so that uinput may be accessed by users in the wheel users group. To make this happen, create a udev rules file in /etc/udev/rules.d/ with a name of your choosing, for example /etc/udev/rules.d/uinput.rules which contains the following line of text:

KERNEL=="uinput",GROUP="wheel",MODE="0660"

If you've already loaded the uinput kernel module prior to creating this file, you'll have to unload the module:
sudo rmmod uinput
and then reload it:
sudo modprobe uinput
Now you should be able to run wminput without sudo (assuming your user is in the wheel group)

Monday, May 21, 2012

Withings wifi scale python dashboard using matplotlib and pandas

The Withings wifi scale is a great bit of hardware, much more visually appealing than my handmade equivalent and wifi makes it standalone, also a big advantage over my bluetooth scale. I've been using the scale to log my weight and using fatsecret to track caloric intake for a while now and decided it would be nice to make a dashboard integrating data from both sources. The plots on Withings' website leave much to be desired. Thankfully, both Withings and fatsecret have APIs which make third party apps possible. Below I'll show some code that uses the rauth library to access both services. rauth provides OAuth 1.0/a, 2.0, and Ofly consumer support. You can install rauth using easy_install:
sudo easy_install rauth
Before using the Withings and fatsecret APIs, you'll need to register as a developer, you can do that by following the links below:
Withings developer registration:
https://oauth.withings.com/en/partner/add
If you just want to extend the code I provide further down you can fill an arbitrary value for the "Application Website" and "Organization" fields and leave the Callback URL blank. Otherwise, fill in those fields according to your needs. Once you've registered as a developer with both services you will have your Consumer Key and Shared Secret which you will need to send API requests. Now grab my python code from github:

git clone https://github.com/trtg/pywithings.git

The git repo has two files: withings.py(the actual library itself) and example.py (seen below). Open up example.py and fill in your consumer key, consumer secret, and the email address you used to register with Withings as indicated. Using the library is pretty straightforward: instantiate a withings object and then just call get_weights() to retrieve a list of weight measurements and an associated list of dates (in seconds since the epoch format) which you can then use however you'd like. Note that the very first time you run example.py you will be prompted to authorize the app to access your withings account by pasting a URL into your browser. Once you go to that URL and login, you will see a screen like this:
After you click "allow" you will see an oauth token string as shown below. Copy just the part after "oauth_verifier=" , in this case PZBDNyyuxDnGkeMxccY.
Paste the "PZ..." string into your terminal where prompted, hit enter, and you should get a graph like the one below.(Click on the graph to see a larger version) I used the python package pandas to treat the weight data as a time series and get nice date labels on the x-axis as well as to plot the smooth red rolling average of the data.
In an upcoming post, I'll discuss similar code that retrieves data from fatsecret to generate plots like the one below:

Monday, October 18, 2010

The magic keyboard



As I hinted at in an earlier post, the magic trackpad hardware is very well designed and bears a strong resemblance to the Fingerworks series of input devices. Now, I've decided to extend the functionality of this device by building a wireless multitouch keyboard using two magic trackpads. Currently, this keyboard will only work in linux since it relies on my extensive modifications to the linux kernel driver for the magic trackpad.

The first image above shows my two magic trackpads with plastic overlays to indicate key placement. It turns out the magic trackpad will still detect contact through a thin insulator placed on top of its surface. The overlays are simply standard laser-printable overhead projector transparencies. I originally considered laser etching the surface of the trackpads at TechShop, but I think I will hold off until I've settled on a key arrangement that I like. Here's a picture showing how I originally planned to lay out the keys relative to my hand.



For now, I opted against the layout above in order to simplify the code that converts coordinates to keycodes. The layout I'm currently using consists simply of three concentric circles, so the code simply checks which circles contain the current touch to determine the corresponding "row" and then compares the X coordinate to a table of thresholds to determine the "column". I created the layout seen in the other pictures using Illustrator. I'll post links to PDFs for the left and right halves in case anyone feels like trying this out.

The keyboard was intended to be placed on the lap to minimize elbow flexion. To hold the halves together I used two strips of rubberized truck tarp (very strong stuff used for a windsurfing roof rack). I'm still working out how to make this attachment adjustable without being bulky.


The transparent blobs seen on the home row of the keyboard in the previous images is clear nail polish. A few coats of this allowed creating a raised ridge to facilitate finding the home row while touch typing. This is actually the principal drawback of a multitouch keyboard- the inherent lack of tactile feedback. The nail polish helps somewhat, but I'm still thinking of other ways to mitigate this issue. The image below shows the nail polish blobs close up.



I currently have preliminary mixed typing/mousing support and a few simple gestures. I also implemented certain behaviors which I think make the use of a touchpad far more ergonomic:
(1)Moving the cursor and single clicking is done with two fingers rather than one.
This helps eliminate the annoyance of inadvertent cursor movement or clicks when a single finger alights on the trackpad. I also think it's more ergonomic, since for me using a single finger requires more effort than using two.
(2)Double clicking is done with a three finger tap- this eliminates the hassle of properly timing a double click.
(3)Scrolling is done with four fingers instead of two. This allows just plopping your entire hand down on the trackpad to scroll rather than contorting it to extend only two fingers.

Todo list:

Software:
Add support for modifiers (i.e. shift,ctrl,alt,meta) using chords.

Write a GUI to rearrange key placement which generates suitable header files based on user's choices. Perhaps eventually come up with a means to allow reconfiguration on the fly.

Hardware:
Come up with better attachment and adjustment system for the straps which connect the two halves of the keyboard

To give some context for this project- here's some images of the devices the magic trackpad derives from - the iGesture and touchstream. You can see that the magic trackpad is significantly smaller than both the iGesture and touchstream which is why I think that modifiers will have to be handled only via chords (no room for separate keys). In the images below there's a weird blob on the USB cords of the iGesture and touchstream- those are my improvised hot-glue strain reliefs.





Sunday, May 2, 2010

bluetooth wireless bathroom scale with fatsecret integration



Not exactly a keyboard, but I'd argue that a datalogging scale is an imput device... In any case, this is a project I did a while ago (~2 years ago). Start with a cheap bathroom scale from ikea, then strip out all the hardware except for the load cells. Add in the following:

microcontroller (AT90USB162)
roving networks bluetooth serial module


24 bit ADC (AD7799)


4 AA batteries +linear regulator (don't want switching noise here)+ input ORing diodes to allow powering from batteries or USB without damaging either (handy during development)

After assembling the above hardware, the microcontroller code was fairly straightforward- when a user taps a corner of the scale I take repeated ADC readings until the "running STD" (STD of last N measurements) drops below a certain threshold. At this point the scale will have a stable zero point to normalize the subsequent weighing. When the user stands on the scale I do the same thing- take ADC readings till STD< threshold. I chose the threshold such that the delay before convergence was short, at the expense of some accuracy. Left to run long enough the scale was able to detect the difference between my bodyweight and my bodyweight plus one US quarter. With the current threshold the scale appears to be repeatably accurate to within 0.1 lbs which for my purposes is acceptable. I was actually pretty happy to get that level of performance considering I didn't lay out a board for the ADC and just used a schmartboard instead.

One other metric I was happy about is the battery life - approximately > 9 months when used once or twice a day. I coded things such that the microcontroller is in a deep sleep until the user touches a corner of the scale. I could have taken a hardware approach and actually disconnected the uC power with a transistor until the user touched the scale, thus arming a delay circuit, but the software approach yielded more than acceptable results. The uC current draw is in the microamp range when sleeping and I use transistors to disconnect power from the bluetooth module and ADC while sleeping so I probably shouldn't have been surprised.
I think for a future revision of this project I'll actually spin my own main board. This would allow for a much more compact footprint and allow me to power from a smaller 3.3V source instead of the stack of 4 AAs. This latter arrangement was needed to avoid extensive rework of the olimex board where certain bits of hardware expect 5V.

On the PC side of this project I'm using bluez rfcomm server to listen for inbound serial connections and then run some other code when a connection is established. That other code consists of python scripts that insert the current reading in a sqlite database (which is then visible from my ruby-on-rails site) and submits the reading to fatsecret via its API. This data submission is done using OAuth, so the whole process requires no human intervention and I avoid any ugly hacks involving plaintext saved passwords.

Fatsecret is great because:
(1) it has an API
(2) it has an android version
(3) it can scan barcodes to fetch associated calories and nutritional content
Here's a screenshot from my phone showing a graph of weight readings for the last few months.


One final aspect of the scale which I find interesting is the means by which the user interacts with it. I intentionally made it so that scale does not have an LCD to show the current weight reading. Day to day fluctuations are not reflective of what really matters- long term trends. Usage of the scale thus boils down to the following:
(1) User taps lower corner of scale to initiate auto-zero sequence
(2) The scale turns on its sole LED to indicate that the zero process is ongoing
(3) The scale switches its status LED from solid red to blinking to indicate the zero process is complete.
(4) User stands on scale until LED turns off, indicating the reading has stabilized.
(5) User reviews cumulative weighing data at some later time (either via phone, or at their PC)

For fun, I added an additional means of relaying data to the user- spoken weights. By feeding the stabilized weight reading to festival (text to speech engine), the scale can "announce" the most recent weighing.

Thursday, August 20, 2009

wireless alphagrip progress

I've finally managed to resolve some timing problems with the RF link; I now have my heavily customized wireless alphagrip mostly working.  Up till now I was having issues with jerky trackball movement when using the alphagrip wirelessly, now I've managed to sort that out, cursor movement is smooth, keystrokes are not getting duplicated anymore either.  Here's the features I've added so far: 

  • Wireless and wired operation- I retrofitted the alphagrip with a lithium ion battery and USB charger IC, and ultra-low quiescent current regulator in such a way that when you plug it in the battery recharges but the alphagrip is still fully functional. When you disconnect, the alphagrip begins to work wirelessly by talking to the special USB dongle I'm using (NOT bluetooth). 
  • Scroll wheel emulation using the trackball- enabling numlock will lock out the trackball x-axis and all buttons except the mouse buttons.  In other words when you enable numlock, the trackball no longer moves the cursor, it just acts as a scroll wheel. 
  • Firmware upgrade-ability on the fly- a special key sequence  kicks the alphagrip into its bootloader at which point new firmware can be loaded without having to physically hit a reset button tied to the microcontroller. 
  • Real modifier keys- when you push Ctrl, Shift, etc. they are actually transmitted to the host. This allows things like Ctrl/Shift click multiple selection which aren't possible with the original alphagrip. 

At this point the remaining tasks before I can deem this keyboard fully functional are mostly mechanical issues.  Solder joints at the Ctrl key are bad, need to be retouched, but this is easy. The hard problem that I've yet to resolve is cramming all the new hardware components  into the very limited amount of space inside the alphagrip.  There is just barely enough room for the new microcontroller board, RF transceiver, battery+regulator, tons of wires. I may just try  to dremel out any plastic that isn't absolutely critical in order to free up some space. Once things are more finalized I'll post some pics.