Friday, April 4, 2014

LED VU Meter using the MyPiShop 8x8 PiMatrix

One of the first addons I got for the Raspberry Pi was the 8x8 PiMatrix, which was a lot of fun to play with. Who doesn't enjoy making LEDs blink? I also wanted to use the PiMatrix for some sort of music visualization, but I'll get to that in a little bit. 

Below are the links for the PiMatrix, assembly instructions and the original example code. The expansion board under the removable LED matrix is also usable by itself for an additional 16 bits of I/O: - Assembly - Test Routines - Toolkit - Scrolling Text

I rewrote Bruce E. Hall's sample code library into a more object-oriented form, creating a LEDMatrix object and making the variables and functions in the original into properties and methods of that object.  I also changed a few methods to accept more parameters such as variable delay times, so the timing and speed of individual routines can be changed without affecting everything. 

All my code is at the Bitbucket link below:

This example makes an explosion pattern that starts in the center and moves out to the four corners of the display:

I use a similar script as a visual indication that the Pi had lost wifi connection; when my wifi check script fails to ping my router, it launch a python script that causes lots of blinking to get my attention.

So now I wanted to use the PiMatrix for some sort of music visualization, but I also wanted it to work with my existing mpd setup instead of using other players and music library management as in the other examples found online. From using the ncmpccpp client I also knew that mpd could already create a fifo output file usable for this purpose:

Fortunately, there was an example on stackoverflow for doing almost exactly what I needed. In XBMC, I prefer the simpler oscilloscope music visualization instead of the more complex ones, so I'm OK with just displaying the volume peaks instead of the fancier (and more CPU-intensive?) spectrum analyzer.

In the linked code example the mpd.fifo is read using audioop functions:

Below is the complete code for the which is also in the Bitbucket repo linked above. Basically, here's what happens:

* The peak stereo volume is read from the fifo
* That value is divided by some "magic number" I arrived at by trial and error to get a 0-to-8 to correspond to a row index, and that new value is appended to the head of a deque
* Loop through the deque and light up the individual LED corresponding to the loop index and value stored in the deque
* Pop the oldest value off the tail end of the deque
The visual effect should be of a "wave" moving left to right.

I've since read that a deque is not the fastest data structure to use for this, but it behaves exactly the way I needed it to without my having to jump through hoops to manage the list of values read from the fifo, and the performance seems fine.

Another thing to note is that in my mpd.conf I changed the location of my mpd.fifo to /var/tmp/mpd.fifo (/var/tmp/ is mapped to RAM in my fstab); I believe the example config in the "Enabling visualization" link above uses /tmp/mpd.fifo instead. So what's defined in your mpd.conf needs to match the file the script below will try to read.

Since this is on my dedicated print server mpd music player, I have the script auto-start by adding it to /etc/rc.local

I've watched the Pi's CPU usage while this script is running and it doesn't seem to be bad - usually around 25% and sometimes spiking to around 40% for very short periods. In fact I've been ssh'ed into the Pi and editing other code in nano while it's running and it's been very responsive.

One final problem to solve is having different scripts that can use the PiMatrix not interfere with each other. This led_vu_meter is always running, and as I mentioned above there's another script that gets triggered when the wifi connection goes down. Sometimes I've also accidentally started more than one instance of these scripts. The multiple processes sending different instructions to the LEDs at the same time is probably not a good thing, and at the very least leads to garbage pixels on the display. I'll probably resort to one "master" script that has logic to determine what should be displayed.

Saturday, November 30, 2013

Lubuntu on an old Toshiba Tecra M7 laptop/tablet convertible

Over the summer I got an old Toshiba Tecra M7 (made in 2006); this is one of those laptop/tablet convertibles, where the screen can be rotated around and locked face-up over the keyboard to be used as a tablet with a stylus. So I can have fun scribbling on the screen with Inkscape and other drawing programs, then flip the screen back around and still use it as a normal laptop. It's handling XBMC playback just fine, so I don't think it's that underpowered.

Lubuntu 12.10 is currently installed and seem to be working well. The built-in wifi card is only Wireless G, which isn't bad, but I'm trying out a Tenda W311MI "Pico USB Adapter" to get Wireless N, and it's averaging 70-80Mb/s. I'm concerned about losing or damaging this tiny little adapter when packing up the laptop, since it does stick out, and when I plugged in another USB device it stopped responding. So I may still eventually replace the internal wifi card, though it looks like major surgery.

To enable screen rotation to portrait mode when using it as a tablet, I did the following, combining instructions from Steve Welburn's post here, as well as some Ubuntu forum threads that I can't seem to find anymore.

I switched to the proprietary tested Nvidia drivers (launch Software Updater, click Settings and go to the Additional Drivers tab), restarted, and then generated an xorg.conf with the following command:
Then edit the generated /etc/X11/xorg.conf and add the following to the last "Device" section
Check what the detected input devices for the stylus are:
This will produce a listing like the following: it's the Serial Wacom Tablet stylus and eraser that we want.
⎡ Virtual core pointer            id=2  [master pointer  (3)]
⎜ ↳ Virtual core XTEST pointer    id=4  [slave  pointer  (2)]
⎜ ↳ AlpsPS/2 ALPS GlidePoint      id=10 [slave  pointer  (2)]
⎜ ↳ ALPS PS/2 Device              id=11 [slave  pointer  (2)]
⎜ ↳ Serial Wacom Tablet stylus    id=12 [slave  pointer  (2)]
⎜ ↳ Serial Wacom Tablet eraser    id=14 [slave  pointer  (2)]
⎣ Virtual core keyboard           id=3  [master keyboard (2)]
  ↳ Virtual core XTEST keyboard   id=5  [slave  keyboard (3)]
  ↳ Power Button                  id=6  [slave  keyboard (3)]
  ↳ Video Bus                     id=7  [slave  keyboard (3)]
  ↳ Power Button                  id=8  [slave  keyboard (3)]
  ↳ AT Translated Set 2 keyboard  id=9  [slave  keyboard (3)]
  ↳ Toshiba input device          id=13 [slave  keyboard (3)]
The shell script is below, I put mine in /usr/local/bin and made a menu shortcut to it.


# Find the line in "xrandr -q --verbose" output that contains current screen orientation and "strip" out current orientation. 

rotation="$(xrandr -q --verbose | grep 'connected' | egrep -o  '\) (normal|left|inverted|right) \(' | egrep -o '(normal|left|inverted|right)')" 

# Using current screen orientation proceed to rotate screen and input tools. 

stylus="Serial Wacom Tablet stylus"
eraser="Serial Wacom Tablet eraser"
mouse="PS/2 Mouse"
touchpad="AlpsPS/2 ALPS GlidePoint"

case "$rotation" in 
#    -rotate to the right 
    xrandr -o right 
    xsetwacom set "$stylus" rotate  CW 
    xsetwacom set "$eraser" rotate CW 
#    -rotate to normal 
    xrandr -o normal 
    xsetwacom set "$stylus" rotate NONE 
    xsetwacom set "$eraser" rotate NONE 
I wanted to use the "rotate" button built into the Tecra's monitor. After some Google searching I found that the following would display what keycodes were bound to it:
As it turns out, that button is bound to "Windows Key + 6". In order to trigger the hotkey, I had to edit my ~/.config/openbox/lubuntu-rc.xml and add the following at the end of the other "keybind" items:
I don't think there's a global lubuntu-rc.xml so if you want to share customized hotkeys with other users on the same computer you have to update the lubuntu-rc.xml in their profile.

And that's it!

Saturday, July 20, 2013

Building PCManFM and LibFM from source to fix the network browsing bug in 1.1.0

One of the things I like about LXDE and Lubuntu is the PCManFM file manager. One of the few features it lacked was integrated file search. That's now build into version 1.1.0, which is installed by default in Lubuntu 13.04 and available as an update in 12.10.

However, this version also introduces a bug that breaks network browsing, and you won't be able to browse Samba shares on your network. I've read the fix is scheduled for the 1.1.1 release, but in this case it's very straightforward to compile the necessary files yourself from source, thanks to the clear instructions on the LXDE wiki.

One additional dependency that's not listed in the wiki is gtk-doc-tools, which the scripts will keep halting on. It's possible that it would have been installed as a recommended dependency by another package, but I usually use "apt-get install" with "--no-install-recommends" to prevent installing extra packages.

In compiling for Lubuntu 13.04, one of the package dependencies is also slightly different, you have to substitute libmenu-cache-dev for libmenu-cache1-dev from the wiki instructions.

Friday, June 14, 2013

Using Grails external config can only override values in the original Config.groovy?

When using an external config for a Grails 1.3.7 application, it appears that you are actually overriding properties defined in the project's /grails-app/conf files (like Config.groovy, DataSource.groovy). So if a given property exists but isn't explicitly initialized to some default value (such as connection pool sizing parameters in DataSource.groovy) you can't even set their values in the external config - or at least, that has been my experience.

Sunday, May 5, 2013

Switching from OpenELEC to XBMC + Raspbian on Raspberry Pi

[Update 09/13/2015]
While the instructions below probably still work, if you are starting from scratch I would recommend OSMC (formerly Raspbmc) which gives you an optimized Kodi install over Raspbian, so you can still install anything else you need on top of that. Currently, I'm trying OSMC + Samba + minidlna to replace my old htpc, and may give OpenELEC another try.

[Original post 05/05/2013]
I decided to switch from OpenELEC to XBMC installed on Raspbian due to all the issues I've experienced with the latest releases - random lockups and unreliable wireless network connection make it completely unusable, and OpenELEC's stripped-down nature makes it difficult to diagnose and implement workarounds. From what I read on the OpenELEC forums these instability issues are due to old firmware in the build, but since all my Raspberry Pi hardware already runs fine on the latest Raspbian I decided to just install XBMC on top of that.

Apparently there are other issues with running XBMC on Raspbian, such as the full keyboard not working in the XBMC interface, but that can be worked around. With a stable wifi connection I can edit config files via ssh. Also, once XBMC is configured to enable remote control via http the soft keyboard on the smartphone XBMC remote app will work.

Since I'm using BerryBoot, I used the "clone" function to create a clean copy of the latest Raspbian image. With the latest BerryBoot I was able to do this via VNC, and as an unexpected bonus my wifi config settings got carried over into the new Raspbian install. I named it "Raspbian XBMC," set it as default, then booted into it and went through the usual setup steps in "raspi-config." Before running updates I install screen so that I can let the long update run and just disconnect from the ssh session. After that I did the usual "sudo apt-get update" and "sudo apt-get upgrade" to get everything up to date.

I installed XBMC as per Michael Gorven's instructions here and edited /etc/default/xbmc so XBMC would run on startup as user pi. After that it's more or less just installing plugins and customizing.

Sunday, April 14, 2013

Fixing Samba master browser conflicts between multiple OpenElec instances

The default OpenELEC Samba configuration (in the 1.x and 2.x versions I ran) appears to set itself up as the local network "master browser," which is responsible for managing the list of network shares and so on. This makes some sense, since the computer with shared media files is likely to be left on all the time. 

But if you have more than one OpenELEC instance running (or have set up Samba with borrowed settings from the OpenELEC config), it's possible for the wrong computer to become the master browser, and when it's shut down or rebooted all of the network shares suddenly become un-browsable. This was happening when I would temporarily boot one Raspberry Pi to OpenELEC, watch or listen to stuff shared from the "main" HTPC for a few hours, then reboot it back into Raspbian.

To resolve this I changed the Samba configs as below; I believe the wins support settings are needed for name resolution in Network Neighborhood in Windows:

On the primary instance (the one that will always be running):
  - domain master = yes
  - local master = yes
  - preferred master = yes
  - os level = 100
  - wins support = yes
  - name resolve order = lmhosts wins bcast host

On the other instances (the ones not left on all the time):
  - preferred master = no
  - domain master = no
  - local master = no
  - os level = 5
  - wins server = <ip address of the primary instance>
  - name resolve order = lmhosts wins bcast host

Check which computer is currently the master browser:
smbclient -L <ip address>

Tuesday, February 26, 2013

Keeping a smartphone from dropping the wi-fi connection

This is a "note to self" post covering what I've tried to keep my phone (a Motorola Atrix MB860) from repeatedly dropping and reconnecting to my wireless network.

* Connecting to Wireless G seems more stable than N (probably varies with the router) - on my dual-band router I have the two bands set up as Wireless G and Wireless N networks with different SSIDs for identification.

* Change router DHCP lease time changed from "forever" to the next longest time available ("two weeks" in my case) - I recall reading that "forever" is actually sent as a really large numeric value that is not properly handled by some devices - it instead overflows into a really small value.

* On the phone:
* When you want to stay connected, set Battery Mode to Performance. Depending on the application (such as Netflix or Hulu Plus) you will also want to keep the display from sleeping (set Display Timeout to Never).
* Additional settings I set:
* In Wi-Fi Settings uncheck the options to auto connect to "AT&T Wi-Fi Hot Spot" - I think this reduces the phone scanning for other wi-fi networks and possible switching when you're already connected to your preferred/home network.
* Uncheck Network Notification > Open Network and Secure Network - again, I think this reduces scanning for other networks.
* In Wi-Fi Networks, remove the Wireless N network and set up the Wirless G one to make sure we connect to the preferred one.

So far so good - my phone has not dropped my wi-fi connection while I was using it over the last two days.