VolumeChangeWithAccelerometer

=Changing Chumby Volume using Accelerometer= (original trick created by zapp on the forum http://forum.chumby.com/viewtopic.php?id=2459)

Note: Using this trick will disable accelerometer access for the control panel / widgets The chumby comes with this nice 3D motion sensor. Unfortunately it is "blocked" by the control panel. (The control panel keeps the handle open so any further attempt to read it gets a device busy). The workaround for this is to rename the device file to /dev/real_accel and link /dev/zero to /dev/accel. Note: since the control panel won't work without the /dev/accel file, it hangs. Attached is a small application that dumps the acceleration data to stdout. There is also a shell script that 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 

Archive with all files including the .c file compiled for chumby available at: http://www.bluesata.com/chumby_volume_accel.zip (BROKEN)

debugchumby:

mv /dev/accel /dev/real_accel cd /dev ln -s zero accel
 * 1) !/bin/sh

/mnt/usb/acceld.sh > /dev/null 2>&1 &

acceld.sh:


 * 1) !/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

${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}
 * 1) calibration

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


 * 1) include 
 * 2) include 
 * 3) include 
 * 4) include 
 * 5) include 

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; }