#define NOTE_G3 196
#define NOTE_B3 247
#define NOTE_C4 262
#include <EEPROM.h>
const byte MIN_SENSOR_VALUE = 45;
const byte MIN_TASK_DIFFICULTY = 4;
const byte MAX_TASK_DIFFICULTY = 16;
byte TASK_DIFFICULTY = MIN_TASK_DIFFICULTY;
byte programmingPort = 49; // Digital port
byte relayPort = 31; // Digital port
byte tonePort = 3; // PWM port
byte sensors[4]={1,0,2,3}; // Analog ports
byte sensorLEDs[4]={7,5,6,4}; // PWM output (invert to +5V, HIGH=LOW and LOW=HIGH)
byte progressLEDs[MAX_TASK_DIFFICULTY]={26,28,30,32, 34,36,38,40, 42,44,46,48, 50,52,53,51}; // Digital ports
byte task[MAX_TASK_DIFFICULTY]={3,1,3,2, 3,1,4,1, 2,1,4,3, 2,1,4,1};
int melody1[] = {NOTE_B3, NOTE_G3, NOTE_C4}; //correct melody
int noteDurations1[] = {16,32,32};
int melody2[] = {NOTE_C4, NOTE_G3, NOTE_B3}; //wrong melody
int noteDurations2[] = {8,16,8};
int progress = 0; //current task/level
byte currentCode = 0;
boolean IsProgrammingMode = false;
boolean isTheEnd = false;
void Init()
{
IsProgrammingMode = false;
isTheEnd = false;
progress = 0;
currentCode = 0;
// getting settings from eeprom
TASK_DIFFICULTY = EEPROM.read(1);
if(TASK_DIFFICULTY <= MIN_TASK_DIFFICULTY)
{
TASK_DIFFICULTY = MIN_TASK_DIFFICULTY;
}
for(byte i=0; i<MAX_TASK_DIFFICULTY; i++)
{
pinMode(progressLEDs[i], OUTPUT);
}
for(int i=0; i<4; i++)
{
pinMode(sensorLEDs[i], OUTPUT);
}
pinMode(relayPort, OUTPUT);
pinMode(programmingPort, INPUT);
CorrectMelody();
}
void SaveSettings()
{
EEPROM.write(1,TASK_DIFFICULTY);
}
boolean ReadSensor(byte sensorId)
{
int val = analogRead(sensors[sensorId]);
//Serial.print(" SENSOR [");
//Serial.print(sensorId);
//Serial.print("]=");
//Serial.println(val);
return val>MIN_SENSOR_VALUE;
}
// reading
byte GetCurrentCode()
{
byte res=0;
for(int i=1; i<5; i++)
{
if(ReadSensor(i-1))
res+=i;
}
if(res>4)
res=0;
return res;
}
void CheckProgrammingMode()
{
if(digitalRead(programmingPort)==HIGH)
{
if(IsProgrammingMode)
{
// Stop the programming
IsProgrammingMode=false;
SetSensorLEDs(LOW);
SaveSettings();
Init();
ShowProgress(0);
CloseDoor();
}else
{
IsProgrammingMode=true;
SetSensorLEDs(HIGH);
// TODO: Зажечь все светодиоды и подсветить текущий уровень сложности
}
delay(1000);
}
}
void TurnOnSensorLED(byte id)
{
digitalWrite(sensorLEDs[id], LOW);
}
// indicate the shot
void SetSensorLEDs(int level)
{
for(byte i=0; i<4; i++)
if(level==LOW)
digitalWrite(sensorLEDs[i], HIGH);
else
digitalWrite(sensorLEDs[i], LOW);
}
void ShowProgress(byte progress)
{
for(byte i=0; i<MAX_TASK_DIFFICULTY; i++)
{
if(i<progress)
digitalWrite(progressLEDs[i], HIGH);
else
digitalWrite(progressLEDs[i], LOW);
}
}
void SimpleMelody(byte thisNote)
{
int noteDuration = 1000/noteDurations1[thisNote];
tone(tonePort, melody1[thisNote],noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(tonePort);
}
void CorrectMelody()
{
for (int thisNote = 0; thisNote < 1; thisNote++) {
int noteDuration = 1000/noteDurations1[thisNote];
tone(tonePort, melody1[thisNote],noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(tonePort);
}
}
void WrongMelody()
{
for (int thisNote = 0; thisNote < 2; thisNote++) {
int noteDuration = 1000/noteDurations2[thisNote];
tone(tonePort, melody2[thisNote],noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(tonePort);
}
}
void OpenDoor()
{
digitalWrite(relayPort, HIGH);
}
void CloseDoor()
{
digitalWrite(relayPort, LOW);
}
void setup() {
//Serial.begin(9600);
Init();
OpenDoor();
SetSensorLEDs(HIGH);
ShowProgress(16);
delay(500);
SetSensorLEDs(LOW);
ShowProgress(0);
CloseDoor();
//Serial.println("--- INIT COMPLETE ---");
}
void loop() {
CheckProgrammingMode();
//Serial.print("IsProgramming = ");
//Serial.println(IsProgrammingMode);
byte code = GetCurrentCode();
if(IsProgrammingMode)
{
//Serial.print("TASK_DIFFICULTY = ");
//Serial.println(TASK_DIFFICULTY);
if(code==1||code==2)
{
if(TASK_DIFFICULTY<MAX_TASK_DIFFICULTY)
{
TASK_DIFFICULTY+=1;
//ShowProgress(TASK_DIFFICULTY);
SimpleMelody(0);
delay(200);
}
}
if(code==3||code==4)
{
if(TASK_DIFFICULTY>MIN_TASK_DIFFICULTY)
{
TASK_DIFFICULTY-=1;
//ShowProgress(TASK_DIFFICULTY);
SimpleMelody(2);
delay(200);
}
}
ShowProgress(TASK_DIFFICULTY);
return;
}
// Serial.print("PrevCode = ");
// Serial.print(currentCode);
// Serial.print(" CurrCode = ");
// Serial.print(code);
// Serial.print(" RquredCode = ");
// Serial.print(task[progress]);
// Serial.print(" Progress = ");
// Serial.println(progress);
if(isTheEnd)
{
progress+=1;
if(progress>MAX_TASK_DIFFICULTY)
{
progress= -MAX_TASK_DIFFICULTY+1;
}
SetSensorLEDs(LOW);
byte led = abs(progress%4);
if(led==2)
led=3;
else
if(led==3)
led=2;
TurnOnSensorLED(led);
byte res = abs(progress);
ShowProgress(res);
delay(100);
return;
}
if(currentCode!=code && code!=0)
{
SetSensorLEDs(LOW);
TurnOnSensorLED(code-1);
if(code==task[progress])
{
currentCode=code;
progress+=1;
ShowProgress(progress);
CorrectMelody();
if(progress>=TASK_DIFFICULTY)
{
CorrectMelody();
CorrectMelody();
CorrectMelody();
isTheEnd=true;
OpenDoor();
}
}
else
{
isTheEnd=false;
progress=0;
ShowProgress(progress);
currentCode=0;
SetSensorLEDs(LOW);
WrongMelody();
}
}
}
Comments