// https://forum.arduino.cc/t/seeking-help-with-first-project-automatic-ball-launcher/1171365/1
/*
when the PIR sensor detect a signal
- a LED turns on
- the two motors needs to spin @ 100% power for 1 second
- then the servo motor needs to turn anti clockwise 90 degrees to release the tennis ball
- the two motors keeps spinning for a other 2 seconds before they powers down
- then 8 seconds delay before the PIR sensor looks for a signal again
*/
enum {IDLE, ACTIVATION, RELEASE, POST_RELEASE, WAITING } state = IDLE;
const unsigned long activationDuration = 1000; // 1s
const unsigned long releaseDuration = 2000; // 2s
const unsigned long minWaitPostTrigger = 8000; // 8s
const int lockBallAngle = 45;
const int releaseBalldAngle = 135;
unsigned long startTime;
#include <Servo.h>
const byte pirPin = 2;
const byte ledPin = 3;
const byte servoPin = 5;
const byte esc1Pin = 9;
const byte esc2Pin = 10;
Servo esc1, esc2, servo;
void stopMotors() {
esc1.writeMicroseconds(1000); // 0% throttle
esc2.writeMicroseconds(1000); // 0% throttle
}
void activateMotors() {
esc1.writeMicroseconds(1900); // 90% throttle
esc2.writeMicroseconds(1900); // 90% throttle
}
void lockBall() {
servo.write(lockBallAngle);
}
void releaseBall() {
servo.write(releaseBalldAngle);
}
void ledOn() {
digitalWrite(ledPin, HIGH);
}
void ledOff() {
digitalWrite(ledPin, LOW);
}
bool motionDetected() {
return digitalRead(pirPin) == HIGH;
}
void setup() {
stopMotors();
lockBall();
pinMode(ledPin, OUTPUT);
pinMode(pirPin, INPUT);
esc1.attach(esc1Pin);
esc2.attach(esc2Pin);
servo.attach(servoPin);
Serial.begin(115200);
}
void loop() {
switch (state) {
case IDLE:
if (motionDetected()) {
Serial.println(F("MOVEMENT DETECTED"));
Serial.println(F("SYSTEM ACTIVATION"));
ledOn();
activateMotors();
startTime = millis();
state = ACTIVATION;
}
break;
case ACTIVATION:
if (millis() - startTime >= activationDuration) {
Serial.println(F("BALL RELEASED"));
releaseBall();
startTime = millis();
state = RELEASE;
}
break;
case RELEASE:
if (millis() - startTime >= releaseDuration) {
Serial.println(F("POST RELEASE PHASE ENDED. SYSTEM DEACTIVATION"));
stopMotors();
lockBall();
startTime = millis();
state = POST_RELEASE;
}
break;
case POST_RELEASE:
if (millis() - startTime >= minWaitPostTrigger) {
Serial.println(F("PAUSE ENDED, WAITING FOR PIR TO BECOME IDLE."));
state = WAITING;
}
break;
case WAITING:
if (not motionDetected()) {
Serial.println(F("PIR IS IDLE, READY AGAIN."));
ledOff();
state = IDLE;
}
break;
}
}
ESC1
ESC2
SERVO
STOP
90%
90%
STOP
LOCKED
RELEASED