84 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			84 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
// 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
 |