#include <Servo.h>
const uint8_t startButtonPin = A1;
const uint8_t servoPin = 3;
enum ePlayStates
{
ST_WAIT_START = 0, //waiting for the START button
ST_INTRO, //the intro
ST_RUN_GAME, //the actual game
ST_SHOW_RESULTS //show results for a period before going back to attract mode
};
Servo servo1;
int arrowCenterPosition = 90,
arrowSpeed = 20,
numberOfSweeps = 0,
previousNumber = arrowCenterPosition,
nextNumber = arrowCenterPosition;
//randon int gave too may naughties so I am weighing this nice heavy (more odds)
int sweepArray[10] = {7, 4, 5, 6, 9, 6, 7, 4, 5, 5, 7};
void setup() {
pinMode(startButtonPin, INPUT_PULLUP);
servo1.attach(servoPin);
servo1.write(arrowCenterPosition);
//random number used to pick actions
randomSeed(A0);
Serial.begin(9600);
}
void loop() {
static uint8_t
gameState = ST_WAIT_START;
switch (gameState)
{
case ST_WAIT_START:
if (bCheckStartResetButton())
{
gameState = ST_INTRO;
}//if
break;
case ST_INTRO:
//center arrow
servo1.write(arrowCenterPosition);
//use a sweepArray so we have weigh things more nice than a random()
numberOfSweeps = sweepArray[random(0, 10)];
Serial.println(numberOfSweeps);
previousNumber = arrowCenterPosition;
nextNumber = arrowCenterPosition;
gameState = ST_RUN_GAME;
break;
case ST_RUN_GAME:
playGame();
gameState = ST_SHOW_RESULTS;
break;
case ST_SHOW_RESULTS:
if (nextNumber < 90)
{
Serial.println("naughty");
}
else {
Serial.println("nice");
}
gameState = ST_WAIT_START;
break;
}//switch
}//loop
void playGame()
{
for (int i = 0; i <= numberOfSweeps; i++) {
previousNumber = nextNumber;
nextNumber = getRandomNumber(previousNumber);
sweepMotor(previousNumber, nextNumber);
}
}
void sweepMotor(int currentPosition, int newPosition)
{
int loopCount = 0;
arrowSpeed = 20;
//determine if we are going left or right
if (currentPosition < newPosition)
{
int fullChangeDifference = newPosition - currentPosition;
int centerOfFullDistance = fullChangeDifference / 2;
//inside loop keep a count, every X loops we add or subtract from arrowSpeed
for (int pos = currentPosition; pos <= newPosition; pos += 1) {
loopCount++;
if ((loopCount % 3) == 0)
{
Serial.println(arrowSpeed);
//if less than half way, speed up
if (pos < (currentPosition + centerOfFullDistance))
{
arrowSpeed = arrowSpeed - 1;
}
else {
arrowSpeed = arrowSpeed + 1;
}
//make sure I dont go under 0
if (arrowSpeed > 1000 || arrowSpeed <= 0)
{
arrowSpeed = 1;
}
}
servo1.write(pos);
delay(arrowSpeed);
}
}
else {
int fullChangeDifference = currentPosition - newPosition;
int centerOfFullDistance = fullChangeDifference / 2;
for (int pos = currentPosition; pos >= newPosition; pos -= 1) {
loopCount++;
if ((loopCount % 3) == 0)
{
//if less than half way, speed up
if (pos < (currentPosition - centerOfFullDistance))
{
arrowSpeed = arrowSpeed + 1;
}
else {
arrowSpeed = arrowSpeed - 1;
}
//make sure I dont go under 0
if (arrowSpeed > 1000 || arrowSpeed <= 0)
{
arrowSpeed = 1;
}
}
servo1.write(pos);
delay(arrowSpeed);
}
}
}
int getRandomNumber(int lastPosition)
{
if (lastPosition >= 90)
{
//naughty degrees
return random(20, lastPosition);
}
else {
//nice degrees
return random(lastPosition, 161);
}
}
bool bCheckStartResetButton( void )
{
static uint8_t
lastSR;
static uint32_t
tSR = 0ul;
uint32_t
tNow = millis();
//update the start/reset every 50mS
if ( tNow - tSR < 50ul )
return false;
//standard logic for button becoming pressed...
tSR = tNow;
uint8_t nowSR = digitalRead( startButtonPin );
if ( nowSR != lastSR )
{
lastSR = nowSR;
if ( nowSR == LOW )
{
return true; //return true if the switch became pressed
}
}//if
//not pressed so return false
return false;
}//bCheckStartResetButton