Move moo-detection into accel driver hdaps-support
authorJoachim Breitner <mail@joachim-breitner.de>
Thu, 27 Nov 2008 22:39:59 +0000 (23:39 +0100)
committerJoachim Breitner <mail@joachim-breitner.de>
Thu, 27 Nov 2008 22:39:59 +0000 (23:39 +0100)
Slight refactorization: The decision, whether a moo should happen, is
moved to the driver-specific code (because it knows best what kind of
device to expect). A member “state” is added to the accel struct which
can be used to implement a state machine inside the driver (as was done
before with pos).

src/accelerometers.c
src/types.h

index 8f13114..b1deb7c 100644 (file)
@@ -64,6 +64,7 @@ AccelHandle *accelerometer_open() {
        accel->lx = 0;
        accel->ly = 0;
        accel->lz = 0;
+       accel->state = 0;
        accel->type = ACCEL_UNKNOWN;
        
        /* Determine accelerometer type */
@@ -88,7 +89,7 @@ AccelHandle *accelerometer_open() {
 
 }
 
-void accelerometer_update_hdaps(AccelHandle *accel) {
+int accelerometer_moo_hdaps(AccelHandle *accel) {
 
        struct input_event ev;
        size_t rval;
@@ -96,12 +97,30 @@ void accelerometer_update_hdaps(AccelHandle *accel) {
        rval = read(accel->fd, &ev, sizeof(ev));
        if ( rval != sizeof(ev) ) {
                fprintf(stderr, "Couldn't read accelerometer data");
-               return;
+               return 0;
        }
-       if (ev.type == EV_ABS && ev.code == REL_Y) 
-               // This is the result of some experimentation
-               accel->y = -600 + abs(ev.value) * 12;
-       
+       if (ev.type == EV_ABS && ev.code == REL_Y) {
+               if (accel->state == 0 && abs(ev.value)>100) {
+                       // Laptop tilted far enough
+                       accel->state=1;
+                       return 0;
+               }
+
+               if (accel->state == 1 && abs(ev.value)<70) {
+                       // Laptop tilted back, play sound
+                       accel->state=2;
+                       return 1;
+               }
+               
+               if (accel->state == 2 && abs(ev.value)<20) {
+                       // Laptop almost at center, enable another round
+                       accel->state=0;
+                       return 0;
+               }
+       }
+
+       return 0;
+               
        /*
        fprintf(stderr, "Event: time %ld.%06ld, type %s, code %d, value %d\n",
                       ev.time.tv_sec, ev.time.tv_usec,
@@ -109,9 +128,9 @@ void accelerometer_update_hdaps(AccelHandle *accel) {
                        ev.type == EV_ABS ? "ABS" : "Other" ,
                       ev.code, ev.value);
        */
-
 }
-void accelerometer_update_freerunner(AccelHandle *accel) {
+
+int accelerometer_moo_freerunner(AccelHandle *accel) {
 
        struct input_event ev;
        size_t rval;
@@ -119,7 +138,7 @@ void accelerometer_update_freerunner(AccelHandle *accel) {
        rval = read(accel->fd, &ev, sizeof(ev));
        if ( rval != sizeof(ev) ) {
                fprintf(stderr, "Couldn't read accelerometer data");
-               return;
+               return 0;
        }
        
        if ( ev.type == EV_REL ) {
@@ -142,27 +161,35 @@ void accelerometer_update_freerunner(AccelHandle *accel) {
                }
        }
 
+       if ( (accel->y < -500) && (accel->state > -1000) ) {
+               accel->state = -1000;
+               return 1;
+       }
+
+       if ( (accel->y > 500) && (accel->state < 1000) ) {
+               accel->state = 1000;
+               return 1;
+       }
+
+       return 0;
 }
 
-void accelerometer_update(AccelHandle *accel) {
+int accelerometer_moo(AccelHandle *accel) {
 
        switch ( accel->type ) {
                case ACCEL_UNKNOWN : {
-                       return;
+                       return 0;
                }
                case ACCEL_FREERUNNER : {
-                       accelerometer_update_freerunner(accel);
-                       break;
+                       return accelerometer_moo_freerunner(accel);
                }
                case ACCEL_HDAPS : {
-                       accelerometer_update_hdaps(accel);
-                       break;
+                       return accelerometer_moo_hdaps(accel);
                }
-               /* Add other types here. You simply need to provide the "y"
-                * component of acceleration in milli-g in the relevant
-                * structure. */
+               /* Add other types here. */
        }
 
+       return 0;
 }
 
 /* The accelerometer work thread */
@@ -170,22 +197,14 @@ static void *accel_work(void *data) {
 
        AccelHandle *accel;
        int *finished = data;
-       int pos = 0;
        
        accel = accelerometer_open();
        audio_setup();
        
        while ( !(*finished) ) {
        
-               accelerometer_update(accel);
-               
-               if ( (accel->y < -500) && (pos > -1000) ) {
-                       pos = -1000;
+               if (accelerometer_moo(accel))
                        audio_trigger_moo();
-               } else if ( (accel->y > 500) && (pos < 1000) ) {
-                       pos = 1000;
-                       audio_trigger_moo();
-               }
                
                usleep(25000);
                
index eae97b6..cc7a227 100644 (file)
@@ -50,6 +50,9 @@ typedef struct {
        int             lx;
        int             ly;
        int             lz;
+       
+       /* Current state (driver dependent) */
+       int             state;
 
 } AccelHandle;