acidportal

- 😈 Worlds smallest Evil Portal on a LilyGo T-QT
git clone git://git.acid.vegas/acidportal.git
Log | Files | Refs | Archive | README | LICENSE

user_bat.cpp (3110B)

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