Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
TouchSense.h
- Committer:
- BuntarouShizuki
- Date:
- 2015-01-22
- Revision:
- 0:fefcd43a3608
File content as of revision 0:fefcd43a3608:
#include "mbed.h"
#include "rtos.h"
//#define DEBUG
// for profiling
#define PRSIZE 500
#define START_THREAD 1
class FrameRate {
float rate;
int counter;
Timer timer;
public:
FrameRate() {
rate = 0;
counter = 0;
timer.start();
}
void update() {
counter++;
if (counter == 10) {
rate = 1000*10.0/timer.read_ms();
counter = 0;
timer.reset();
}
}
float getRate() {
return rate;
}
};
class TouchSense
{
float V0;
float V1;
float C1;
DigitalOut &dout;
AnalogIn &ain;
static const int BUFSIZE = 3;
int buf[BUFSIZE];
int bufindex;
int state;
FrameRate rater;
static void threadStarter(void const *p);
Thread _thread;
public:
TouchSense(DigitalOut &dout, AnalogIn &ain): V0(0.0), V1(0.5), C1(20), dout(dout), ain(ain),
_thread(&TouchSense::threadStarter, this, osPriorityNormal, 10240) {
// XXX: 0.5 must be defined automatically
state = 0;
calibrate();
_thread.signal_set(START_THREAD);
}
int touched() {
return state;
}
private:
void calibrate() {
printf("TouchSense.calibrate\r\n");
dout.write(0);
Thread::wait(1000);
// initialize V0
float s = 0.0;
for (int i = 0; i < 10; i++) {
float level = ain.read();
printf("TouchSense.calibrate: level=%f\r\n", level);
if (s < level)
s = level;
Thread::wait(100);
}
V0 = s;
printf("TouchSense.calibrate: V0=%f\r\n", V0);
// initialize buf, bufindex, and C1
for (int i = 0; i < BUFSIZE; i++) {
buf[i] = sense();
printf("TouchSense.calibrate: sense=%d\r\n", buf[i]);
}
int sum = 0;
for (int i = 0; i < BUFSIZE; i++)
sum += buf[i];
C1 = sum*3.0/BUFSIZE; // XXX: 3 is a magic number
bufindex = 0;
printf("TouchSense.calibrate: C1=%f\r\n", C1);
}
void loop() {
_thread.signal_wait(START_THREAD);
printf("TouchSense.loop: start\r\n");
for (;;) {
int r = sense();
if (r == -1)
buf[bufindex] = C1+1;
else
buf[bufindex] = r;
bufindex = (bufindex+1)%BUFSIZE;
int sum = 0;
for (int i = 0; i < BUFSIZE; i++)
sum += buf[i];
float avg = (float)sum/BUFSIZE;
if (avg > C1) // touhced for 0.001*BUFSIZE sec
state = 1; // touched
else
state = 0; // untouched
rater.update();
Thread::wait(5);
}
}
int sense() {
DigitalIn prswitch(p5);
prswitch.mode(PullUp);
// step 1
int xxx = 0;
dout.write(0);
#ifdef DEBUG
printf("touched: ain=%f\n\r", ain.read());
#endif
while (ain.read() > V0) {
xxx++;
if (xxx > 100) { // 0.1 sec
printf("touched: warning ain=%f\n\r", ain.read());
return -1;
}
Thread::wait(1);
}
// step 2
dout.write(1);
// step 3
int count = 0;
if (prswitch) {
// mode: normal
for (;;) {
if (count > C1)
break;
if (ain.read() > V1)
break;
count++;
}
#ifdef DEBUG
printf("touched: count=%d\r\n", count);
#endif
} else {
// mode: profiling
printf("rate = %f\r\n", rater.getRate());
float prdata[PRSIZE];
float prtime[PRSIZE];
Timer timer;
timer.start();
for (;;) {
prdata[count] = ain.read();
prtime[count] = timer.read();
if (prdata[count] > V1)
break;
count++;
if (count == PRSIZE) {
printf("touched: warning[count==PRSIZE]\r\n");
count--;
break;
}
}
printf("# n=%d V0=%f V1=%f\r\n", count+1, V0, V1);
for (int i = 0; i <= count; i++)
printf("%f %f\r\n", prtime[i], prdata[i]);
printf("\r\n");
}
// step 4
dout.write(0);
return count;
}
};