-
-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathuser_bat.cpp
83 lines (70 loc) · 3.04 KB
/
user_bat.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// SERVO BAT: flapping paper-cutout bat (attached to servo on SERVO_PIN)
// triggered by contact-sensitive conductive thread on CAPTOUCH_PIN.
// See user.cpp for basics of connecting user code to animated eyes.
#if 0 // Change to 1 to enable this code (must enable ONE user*.cpp only!)
#include "Adafruit_FreeTouch.h"
#include <Servo.h>
#define CAPTOUCH_PIN A5 // Capacitive touch pin - attach conductive thread here
#define SERVO_PIN 4 // Servo plugged in here
// Set up capacitive touch button using the FreeTouch library
static Adafruit_FreeTouch touch(CAPTOUCH_PIN, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);
static long oldState; // Last-read touch value
static bool isTouched = false; // When true, bat is flapping
static uint32_t touchTime = 0; // millis() time when flapping started
static uint32_t touchThreshold;
Servo servo;
void user_setup(void) {
if (!touch.begin())
Serial.println("Cap touch init failed");
servo.attach(SERVO_PIN);
servo.write(0); // Move servo to idle position
servo.detach();
// Attempt to auto-calibrate the touch threshold
// (assumes thread is NOT touched on startup!)
touchThreshold = 0;
for(int i=0; i<10; i++) {
touchThreshold += touch.measure(); // Accumulate 10 readings
delay(50);
}
touchThreshold /= 10; // Average "not touched" value
touchThreshold = ((touchThreshold * 127) + 1023) / 128; // Threshold = ~1% toward max
oldState = touch.measure();
}
#define FLAP_TIME_RISING 900 // 0-to-180 degree servo sweep time, in milliseconds
#define FLAP_TIME_FALLING 1200 // 180-to-0 servo sweep time
#define FLAP_REPS 3 // Number of times to flap
#define FLAP_TIME_PER (FLAP_TIME_RISING + FLAP_TIME_FALLING)
#define FLAP_TIME_TOTAL (FLAP_TIME_PER * FLAP_REPS)
void user_loop(void) {
long newState = touch.measure();
Serial.println(newState);
if (isTouched) {
uint32_t elapsed = millis() - touchTime;
if (elapsed >= FLAP_TIME_TOTAL) { // After all flaps are completed
isTouched = false; // Bat goes idle again
servo.write(0);
servo.detach();
} else {
elapsed %= FLAP_TIME_PER; // Time within current flap cycle
if (elapsed < FLAP_TIME_RISING) { // Over the course of 0 to FLAP_TIME_RISING...
servo.write(elapsed * 180 / FLAP_TIME_RISING); // Move 0 to 180 degrees
} else { // Over course of FLAP_TIME_FALLING, return to 0
servo.write(180 - ((elapsed - FLAP_TIME_RISING) * 180 / FLAP_TIME_FALLING));
}
}
} else {
// Bat is idle...check for capacitive touch...
if (newState > touchThreshold && oldState < touchThreshold) {
delay(100); // Short delay to debounce
newState = touch.measure(); // Verify whether still touched
if (newState > touchThreshold) { // It is!
isTouched = true; // Start a new flap session
touchTime = millis();
servo.attach(SERVO_PIN);
servo.write(0);
}
}
}
oldState = newState; // Save cap touch state
}
#endif // 0