Topic: Use the motion sensor to control your chumby
Since I just registered, first of all: Hello Everyone!
I received my Chumby a week ago and since then I trying get improve the usability and with this the WAF (wife acceptance factor) of it.
I found it annoying to always have to go through the control center to achieve things like changing volume or muting the sound, so I came with the following. Maybe some of you find it useful, too.
The chumby comes with this nice 3D motion sensor. Unfortunately it is "blocked" by the control panel. To workaround this I renamed the device file to /dev/real_accel and linked /dev/zero to /dev/accel, since the control panel won't work without the /dev/accel file (it hangs).
Then I wrote a small application that just dumps the acceleration data to stdout. A shell script checks the data every second or so and triggers different things according to the motions, you do with the chumby.
At the moment the following things are implemented:
- rotate clockwise -> Volume Up
- rotate counter clockwise -> Volume Down
- slight punch -> Mute/Unmute
I post the code here, since I don't know, how to upload files (is this possible at all?)
debugchumby
--------------------
#!/bin/sh
mv /dev/accel /dev/real_accel
cd /dev
ln -s zero accel
/mnt/usb/acceld.sh > /dev/null 2>&1 &
acceld.sh
--------------
#!/bin/sh
AVPRG="/mnt/usb/accelvals"
ACCEL_DEVICE="/dev/real_accel"
[ -x "${AVPRG}" ] || { echo "[ERROR] \"accelvals\" prg. not found." ; exit 1 ; }
[ -e "${ACCEL_DEVICE}" ] || { echo "[ERROR] Invalid acceleration device!" ; exit 1 ; }
delta_x=100
vol_steps=10
# calibration
${AVPRG} ${ACCEL_DEVICE} > /tmp/acceldata.$$
read ver ts x y z avgx avgy avgz impx impy impz imptime imphint grange < /tmp/acceldata.$$
cal_x=${x}
cal_y=${y}
cal_z=${z}
mute="$(cat /proc/chumby/audio/mixer/left-speaker/mute)"
current_volume="$(cat /proc/chumby/audio/mixer/left-speaker/volume)"
last_impact=${imptime}
echo "Calibrated! (${cal_x}, ${cal_y}, ${cal_z}, ${last_impact})"
while [ 1 ]; do
${AVPRG} ${ACCEL_DEVICE} > /tmp/acceldata.$$
read ver ts x y z avgx avgy avgz impx impy impz imptime imphint grange < /tmp/acceldata.$$
if [ "${imptime}" != "${last_impact}" ]; then
echo -n "[IMPACT] -> "
if [ "${mute}" = "0" ]; then
mute=1
echo "Mute"
else
mute=0
echo "Unmute"
fi
echo ${mute} > /proc/chumby/audio/mixer/both-speakers/mute
last_impact=${imptime}
fi
if [ "${x}" -gt "$((${cal_x} + ${delta_x}))" ]; then
echo "[ROLL] Right"
current_volume=$((${current_volume} + ${vol_steps}))
if [ "${current_volume}" -gt "100" ]; then
current_volume=100
fi
echo ${current_volume} > /proc/chumby/audio/mixer/both-speakers/volume
fi
if [ "${x}" -lt "$((${cal_x} - ${delta_x}))" ]; then
echo "[ROLL] Left"
current_volume=$((${current_volume} - ${vol_steps}))
if [ "${current_volume}" -lt "0" ]; then
current_volume=0
fi
echo ${current_volume} > /proc/chumby/audio/mixer/both-speakers/volume
fi
sleep 1
done
accelvals.c
----------------
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
static int accel_fd;
struct accelReadData {
unsigned int version;
unsigned int timestamp;
unsigned int inst[3]; // x, y, z
unsigned int avg[3];
unsigned int impact[3]; // values for the last impact peak acceleration
unsigned int impactTime;
unsigned int impactHint;
unsigned int gRange; // g range in milli-g's
};
int getAccelData(struct accelReadData *ac)
{
int rc = read(accel_fd, ac, sizeof(*ac));
if (rc != sizeof(*ac))
return -1;
return 0;
}
int main(int argc, char*argv[])
{
int rc;
struct accelReadData ac;
if (argc != 2) {
fprintf(stderr, "Usage: %s accel-device\n", argv[0]);
return -1;
}
accel_fd = open(argv[1], O_RDONLY);
if (accel_fd == -1) {
perror("open");
return -1;
}
rc = getAccelData(&ac);
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
ac.version,
ac.timestamp,
ac.inst[0],
ac.inst[1],
ac.inst[2],
ac.avg[0],
ac.avg[1],
ac.avg[2],
ac.impact[0],
ac.impact[1],
ac.impact[3],
ac.impactTime,
ac.impactHint,
ac.gRange);
return 0;
}
A tar file with everything ready-to-go it available here. Just unpack to the root directory of your usb stick.
Please use at own risk. It works for me. YMMV.
Have fun,
Rolf.