AnimatedLED9

Dependencies:   mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TouchSense.h Source File

TouchSense.h

00001 #include "mbed.h"
00002 #include "rtos.h"
00003 
00004 //#define DEBUG
00005 
00006 // for profiling
00007 #define PRSIZE 500
00008 #define START_THREAD 1
00009 
00010 class FrameRate {
00011     float rate;
00012     int counter;
00013     Timer timer;
00014 
00015 public:    
00016     FrameRate() {
00017         rate = 0;
00018         counter = 0;
00019         timer.start();
00020     }
00021     
00022     void update() {
00023         counter++;
00024         if (counter == 10) {
00025             rate = 1000*10.0/timer.read_ms();
00026             counter = 0;
00027             timer.reset();
00028         }
00029     }
00030     
00031     float getRate() {
00032         return rate;
00033     }
00034 };
00035 
00036 class TouchSense
00037 {
00038     float V0;
00039     float V1;
00040     float C1;
00041 
00042     DigitalOut &dout;
00043     AnalogIn &ain;
00044 
00045     static const int BUFSIZE = 3;
00046     int buf[BUFSIZE];
00047     int bufindex;
00048 
00049     int state;
00050 
00051     FrameRate rater;
00052     
00053     static void threadStarter(void const *p);
00054     Thread _thread;
00055 public:
00056     TouchSense(DigitalOut &dout, AnalogIn &ain): V0(0.0), V1(0.5), C1(20), dout(dout), ain(ain),
00057      _thread(&TouchSense::threadStarter, this, osPriorityNormal, 10240) {
00058         // XXX: 0.5 must be defined automatically
00059         state = 0;
00060         calibrate();
00061 
00062         _thread.signal_set(START_THREAD);
00063     }
00064 
00065     int touched() {
00066         return state;
00067     }
00068 
00069 private:
00070     void calibrate() {
00071         printf("TouchSense.calibrate\r\n");
00072         dout.write(0);
00073         Thread::wait(1000);
00074 
00075         // initialize V0
00076         float s = 0.0;
00077         for (int i = 0; i < 10; i++) {
00078             float level = ain.read();
00079             printf("TouchSense.calibrate: level=%f\r\n", level);
00080             if (s < level)
00081                 s = level;
00082             Thread::wait(100);
00083         }
00084         V0 = s;
00085         printf("TouchSense.calibrate: V0=%f\r\n", V0);
00086 
00087         // initialize buf, bufindex, and C1
00088         for (int i = 0; i < BUFSIZE; i++) {
00089             buf[i] = sense();
00090             printf("TouchSense.calibrate: sense=%d\r\n", buf[i]);
00091         }
00092         int sum = 0;
00093         for (int i = 0; i < BUFSIZE; i++)
00094             sum += buf[i];
00095         C1 = sum*3.0/BUFSIZE;   // XXX: 3 is a magic number
00096         bufindex = 0;
00097         printf("TouchSense.calibrate: C1=%f\r\n", C1);
00098     }
00099 
00100     void loop() {
00101         _thread.signal_wait(START_THREAD);
00102         printf("TouchSense.loop: start\r\n");
00103         for (;;) {
00104             int r = sense();
00105             if (r == -1)
00106                 buf[bufindex] = C1+1;
00107             else
00108                 buf[bufindex] = r;
00109             bufindex = (bufindex+1)%BUFSIZE;
00110 
00111             int sum = 0;
00112             for (int i = 0; i < BUFSIZE; i++)
00113                 sum += buf[i];
00114             float avg = (float)sum/BUFSIZE;
00115 
00116             if (avg > C1)       // touhced for 0.001*BUFSIZE sec
00117                 state = 1;  // touched
00118             else
00119                 state = 0;  // untouched
00120 
00121             rater.update();
00122             Thread::wait(5);
00123         }
00124     }
00125 
00126     int sense() {
00127         DigitalIn prswitch(p5);
00128         prswitch.mode(PullUp);
00129 
00130         // step 1
00131         int xxx = 0;
00132         dout.write(0);
00133 #ifdef DEBUG
00134         printf("touched: ain=%f\n\r", ain.read());
00135 #endif
00136         while (ain.read() > V0) {
00137             xxx++;
00138             if (xxx > 100) {           // 0.1 sec
00139                 printf("touched: warning ain=%f\n\r", ain.read());
00140                 return -1;
00141             }
00142             Thread::wait(1);
00143         }
00144 
00145         // step 2
00146         dout.write(1);
00147 
00148         // step 3
00149         int count = 0;
00150 
00151         if (prswitch) {
00152             // mode: normal
00153             for  (;;) {
00154                 if (count > C1)
00155                     break;
00156                 if (ain.read() > V1)
00157                     break;
00158                 count++;
00159             }
00160 #ifdef DEBUG
00161             printf("touched: count=%d\r\n", count);
00162 #endif
00163         } else {    
00164             // mode: profiling
00165             printf("rate = %f\r\n", rater.getRate());
00166 
00167             float prdata[PRSIZE];
00168             float prtime[PRSIZE];
00169             Timer timer;
00170 
00171             timer.start();
00172             for (;;) {
00173                 prdata[count] = ain.read();
00174                 prtime[count] = timer.read();
00175                 if (prdata[count] > V1)
00176                     break;
00177                 count++;
00178                 if (count == PRSIZE) {
00179                     printf("touched: warning[count==PRSIZE]\r\n");
00180                     count--;
00181                     break;
00182                 }
00183             }
00184             printf("# n=%d V0=%f V1=%f\r\n", count+1, V0, V1);
00185             for (int i = 0; i <= count; i++)
00186                 printf("%f %f\r\n", prtime[i], prdata[i]);
00187             printf("\r\n");
00188         }
00189 
00190         // step 4
00191         dout.write(0);
00192 
00193         return count;
00194     }
00195 };