Вы находитесь на странице: 1из 5

#define

#define
#define
#define
#define

rightLDR A1
leftLDR A3
rightMotor 1
leftMotor 0
buzzer 4

waitButton();
// White Calibration
l_white = 0;
r_white = 0;
for (int i=0; i<pacmanLen; i++) {
int l = analogRead(leftLDR);
int r = analogRead(rightLDR);
l_white += analogRead(leftLDR);
r_white += analogRead(rightLDR);
// Sound effects
play(pacman[i]);
delay(200);
}
l_white /= pacmanLen;
r_white /= pacmanLen;
noTone(buzzer);

int leftVal;
int rightVal;
int tol = 40;
int l_mean;
int r_mean;
int l_white;
int r_white;
int whiteDist = 0;
int e_old=0, e_sum=0;
int actionNumber = 1;
int lapCount = 0;
int laps = 1;
// Music stuff
int noteDuration;
int noteCount = 0;
int laBamba[] =
{50,0,54,57,55,0,59,57,0,45,49,52,55,55,54,52};
int laBambaLen = 16;
int beatles[] =
{0,0,59,55,57,59,0,55,0,0,59,57,0,55,0,52,0,55,59,57,0,55,0,5
2,54,52,54,55,0,57,0,0};
int beatlesLen = 32;
int victory[] = {60,60,60,60,-1,0,56,-1,0,58,1,0,60,0,58,60,-1,-1,-1,-1};
int victoryLen = 20;

void setup() {
int pacman[] = {52,64,59,56,64,59,56,0};
int pacmanLen = 8;
int readySetGo[] = {40,0,40,0,40,0,52,-1};
int readySetGoLen = 8;
// Settings
pinMode(leftLDR, INPUT);
pinMode(rightLDR, INPUT);
pinMode(leftMotor, OUTPUT);
pinMode(rightMotor, OUTPUT);
pinMode(buzzer, OUTPUT);

waitButton();
// Track calibration
l_mean = 0;
r_mean = 0;
for (int i=0; i<readySetGoLen; i++) {
l_mean = l_mean + analogRead(leftLDR);
r_mean = r_mean + analogRead(rightLDR);
// Sound effects
play(readySetGo[i]);
delay(300);
}
l_mean /= readySetGoLen;
r_mean /= readySetGoLen;
delay(500);
noTone(buzzer);
}

void loop() {
// Read light values
leftVal = analogRead(leftLDR);
rightVal = analogRead(rightLDR);
// Dark marker
if (leftVal > l_mean+tol && rightVal > r_mean+tol) {
delay(100);
if (leftVal > l_mean+2*tol && rightVal > r_mean+2*tol) {
// Acknowledge
drive(-1);
play(60);
delay(100);
play(0);
delay(500);
// Perform action
action(actionNumber);
}
// Even brighter than white paper - Traffic Light!
} else if (leftVal < l_white-3*tol && rightVal < r_white-3*tol) {

pause(); // Pause and wait for button press


// Close to calibrated white values
} else if (leftVal<l_white+tol && rightVal<r_white+tol) {
followLine();
whiteDist++;
if (whiteDist > 200) { // End of line
end_of_line();
while(true); // Infinite loop
}
// Normal track
} else {
if (whiteDist > 0) whiteDist -= 10;
followLine();
}
}

int bound(int x, int low, int high) {


if (x > high) {
return high;
} else if (x < low) {
return low;
} else {
return x;
}
}

void drive(int val) {


if (val == -1) {
analogWrite(leftMotor, 0);
analogWrite(rightMotor, 0);
} else {
int damp = 60;
analogWrite(leftMotor, bound(val-damp,0,255));
analogWrite(rightMotor, bound(255-val-damp,0,255));
}
}

int absolute(int num) {


if (num>0) {
return num;
} else {
return (-num);
}
}

void play(int noteNum) {


int freq[] =
{262,277,294,311,330,349,370,392,415,440,466,494,523,554,587,
622,659,698,740,784,831,880,932,988,1047,1109};
if (noteNum == 0) {
noTone(buzzer);
} else if (noteNum == -1) {
; // Hold the note!
} else {
noTone(buzzer);
tone(buzzer, freq[noteNum-40]);
}
}
void playSong(int song[], int len, int noteDur) {
for (int i=0; i<len; i++) {
play(song[i]);
delay(noteDur);
}
noTone(buzzer);
}
void followLine() {
int error = (rightVal-r_mean)-(leftVal-l_mean);
int kP=800, kI=0, kD=0;
// Differential
int diff = error - e_old;
e_old = error;
// Integral
e_sum = e_sum + error;
// PID
int pid = 128 + (kP*error + kI*e_sum + kD*diff)/100;
pid = bound(pid, 0, 255);
if (absolute(error)<35) {
// PID for smooth following
drive(pid);
} else if (error < -35) {
// Sharp left turn
drive(0);
} else if (error > 35) {
// Sharp right turn
drive(255);
}
}

void end_of_line() {
// Acknowledge
drive(-1);
play(55);
delay(200);
play(53);
delay(200);
play(51);
delay(200);
noTone(buzzer);
// Straight
for (int i=0; i<225; i++) {
if (i%2==0) drive(0);
else drive(255);
delay(10);
}
// Spiral
drive(-1);
for (int i=0; i<50; i++) {
analogWrite(leftMotor, 255);
analogWrite(rightMotor, 60-i);
delay(200);
}
// Finish
drive(-1);
playSong(victory, victoryLen, 200);
}

void action(int number) {


if (number == 1) {
playSong(beatles, beatlesLen, 200);
} else if (number == 2) {
playSong(laBamba, laBambaLen, 300);
} else if (number == 3) {
lap();
}
// Drive past marker
drive(255);
delay(100);
drive(0);
delay(100);
drive(-1);
}

void lap() {
if (lapCount == 0) { // Setup
laps = countPresses();
} else if (lapCount >= laps) {
drive(-1);
play(60);
delay(500);
play(59);
delay(500);
play(58);
delay(500);
play(57);
delay(1500);
play(0);
delay(1000);
lapCount = 0;
pause();
}
// Playback number of remaining laps
delay(500);
for (int i=0; i<laps-lapCount; i++) {
play(50);
delay(100);
play(0);
delay(300);
}
lapCount++;
}

void pause() {
// Acknowledge
drive(-1);
play(48);
delay(200);
play(60);
delay(200);
noTone(buzzer);
whiteDist = 0; // Start afresh
if (waitButton()==true) { // Long press
int p = countPresses();
while (p > 3) { // Invalid number of presses
play(40);
delay(700);
play(0);
delay(500);
// Try again
p = countPresses();
}
// Playback number of presses
delay(500);
for (int i=0; i<p; i++) {
play(50);
delay(100);
play(0);
delay(300);
}
actionNumber = p;
} else { // Short press
; // Do nothing
}
play(60);
delay(200);
play(48);
delay(200);
noTone(buzzer);
}

boolean waitButton() {
boolean longgg = false;
int duration = 0;
while (analogRead(rightLDR) < 800) {
; // Wait for press
}
while (analogRead(rightLDR) > 700) {
// Check for long button press
if (duration > 200) {
longgg = true;
// Acknowledge
play(65);
delay(70);
play(0);
delay(80);
play(65);
delay(70);
play(0);
delay(500);
while (analogRead(rightLDR) > 700); // Wait for release
}
delay(10);
duration++;
}
delay(500);
if (longgg) return true;
else return false;
}

int countPresses() {
int numPress = 1;
int duration = 0;
// Prompt
play(60);
delay(70);
play(62);
delay(70);
play(64);
delay(80);
play(0);
// First press is compulsory
while (analogRead(rightLDR) < 800) ; // Wait for press
while (analogRead(rightLDR) > 700) ; // Wait for release
delay(100);
// Check for further presses
while (duration < 200) { // Wait at most 2 seconds for the
next button press
if (analogRead(rightLDR) > 700) {
while (analogRead(rightLDR) > 700) ;// Wait for release
numPress++;
delay(100);
}
delay(10);
duration++;
}
return numPress;
}

Вам также может понравиться