#include <Arduino.h>
#include <SoftwareSerial.h>
#include <JQ6500_Serial.h>
#include <avr/pgmspace.h> // PROGMEM
#include <SPI.h>
#include <MFRC522.h>
#include <avr/sleep.h>
#include <avr/power.h>
#define adc_disable() (ADCSRA &= ~(1<<ADEN))
#define adc_enable() (ADCSRA |= (1<<ADEN))
#define RST_PIN 9
#define SS_PIN 10
#define mp3Pin 4
#define mp3Busy A0
#define readerPin 6
#define tonePin 5
#define ledPin 3
#define offDelay 70000
#define winkStep 1500
#define on 150
#define off 80
#define tOut1 0
#define tOut11 500
#define tOut2 14000
#define tOut21 15000
#define tOut3 29000
#define tOut31 30000
#define tOut4 44000
#define tOut41 45000
#define tOut5 60000
#define tOut51 65000
#define tShake 2000
#define nShakeQ 10
#define introQ 5
#define minVol 18
#define midVol 22
#define maxVol 25
unsigned long dimDelay, winkStepDelay, onDelay, ledOffDelay, tShakeDelay;
boolean ledOn, ledOff, eyes, pwm;
int wink;
int pwmVal;
boolean playON = false;
boolean pwmUp = false;
byte pwmStep = 1;
unsigned int playFile;
MFRC522 mfrc522(SS_PIN, RST_PIN);
unsigned long uidDec, uidDecTemp;
byte bCounter, readBit, nShake, rnd;
byte vol = midVol;
unsigned long ticketNumber;
unsigned long offTimeOut = 0;
boolean mp3ON = false;
boolean isInt = false;
byte ticketQ = 32;
byte fileQ = 0;
PROGMEM const uint32_t ticketSet[] = {2515217196, 2540548337, 2490970856, 2486466332, 2485920633, 35870611, 37836807, 37836806, 2377004330, 2522873668, 2514304566, 23472725, 2485702426, 2374853555, 2374391583, 2492957469, 2486467162, 2489280075, 2488031661, 2491726641, 2491720188, 2490968782, 2490968783, 2488900952, 2489969016, 2506562651, 2375447052, 2375449579, 2489276180, 2483389692, 2486466331, 2484789326};
JQ6500_Serial mp3(8,7);
void enterSleep()
{
mp3.playFileNumberInFolderNumber(01, 005);
mp3.playFileNumberInFolderNumber(01, 005);
delay(2500);
tone(tonePin, 800, 500);
delay(500);
digitalWrite(readerPin, LOW);
digitalWrite(mp3Pin, LOW);
digitalWrite(ledPin, LOW);
pinMode(ledPin, INPUT);
pinMode(readerPin, INPUT);
pinMode(mp3Pin, INPUT);
adc_disable();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_mode();
sleep_disable();
power_all_enable();
adc_enable();
tone(tonePin, 450, 500);
pinMode(ledPin, OUTPUT);
pinMode(readerPin, OUTPUT);
pinMode(mp3Pin, OUTPUT);
digitalWrite(ledPin, LOW);
digitalWrite(readerPin, HIGH);
digitalWrite(mp3Pin, HIGH);
SPI.begin();
mfrc522.PCD_Init();
mp3Init();
offTimeOut = millis();
ledOffDelay = millis();
mp3.playFileNumberInFolderNumber(01, 001);
mp3.playFileNumberInFolderNumber(01, 001);
delay(500);
playON = false;
mp3ON = true;
}
void wakeUp() {
detachInterrupt(0);
ledOffDelay = millis();
if (isInt == false) {
isInt = true;
}
attachInterrupt(0, wakeUp, LOW);
}
void setup() {
pinMode(2, INPUT_PULLUP);
attachInterrupt(0, wakeUp, LOW);
pinMode(readerPin, OUTPUT);
digitalWrite(readerPin, HIGH);
SPI.begin();
mfrc522.PCD_Init();
pinMode(mp3Pin, OUTPUT);
mp3Init();
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
eyes = false;
ledOn = false;
ledOff = false;
dimDelay = millis();
winkStepDelay = millis();
wink = 0;
pwmUp = true;
pwmVal = 0;
ledOffDelay = millis();
offTimeOut = millis();
mp3.playFileNumberInFolderNumber(01, 001);
mp3.playFileNumberInFolderNumber(01, 001);
delay(500);
playON = false;
mp3ON = true;
}
void loop() {
rnd = random(1, fileQ-1);
if ((millis() - offTimeOut) > offDelay) {
enterSleep();
} else {
ledWink();
if (isInt == true) {
offTimeOut = millis();
if (nShake == 0) {
tShakeDelay = millis();
}
if ((millis() - tShakeDelay) < tShake){
nShake = nShake + 1;
} else {
tShakeDelay = millis();
nShake = 0;
}
isInt = false;
}
if (nShake > nShakeQ) {
playRandom();
nShake = 0;
}
playPreset();
if (mp3ON == true) {
if (playON == true) {
offTimeOut = millis();
}
nShake = 0;
eyesPWM();
if(analogRead(mp3Busy) < 250) {
mp3ON = false;
playON = false;
digitalWrite(ledPin, LOW);
}
}
scanPlay();
}
}
void setBitsForGood(byte daBeat) {
if (daBeat == 1) {
bitSet(ticketNumber, bCounter);
bCounter=bCounter+1;
}
else {
bitClear(ticketNumber, bCounter);
bCounter=bCounter+1;
}
}
void mp3Init() {
digitalWrite(mp3Pin, HIGH);
delay(100);
mp3.begin(9600);
mp3.reset();
mp3.setVolume(vol);
mp3.setLoopMode(MP3_LOOP_NONE);
fileQ = mp3.countFiles(MP3_SRC_SDCARD);
fileQ = fileQ - introQ;
}
void playRandom() {
tone(tonePin, 450, 500);
delay(500);
playFile = rnd;
mp3ON = true;
playON = true;
mp3.playFileByIndexNumber(playFile);
mp3.playFileByIndexNumber(playFile);
mp3.playFileByIndexNumber(playFile);
delay(500);
}
void ledWink() {
if ((millis() - winkStepDelay) > winkStep) {
if (eyes == true) {
if (ledOn == false) {
onDelay = millis();
ledOn = true;
}
if ((millis() - onDelay) > on) {
digitalWrite(ledPin, LOW);
eyes = false;
}
}
if (eyes == false) {
if (ledOff == false) {
ledOffDelay = millis();
ledOff = true;
}
if ((millis() - ledOffDelay) > off) {
digitalWrite(ledPin, HIGH);
eyes = true;
}
}
if (ledOn == true && ledOff == true) {
wink = wink+1;
ledOn = false;
ledOff = false;
}
if (wink == 4) {
winkStepDelay = millis();
wink = 0;
}
}
}
void playPreset() {
if (mp3ON == false) {
if ((millis() - offTimeOut) > tOut2 && (millis() - offTimeOut) < tOut21) {
mp3.playFileNumberInFolderNumber(01, 002);
mp3ON = true;
delay(500);
}
if ((millis() - offTimeOut) > tOut3 && (millis() - offTimeOut) < tOut31) {
mp3.playFileNumberInFolderNumber(01, 003);
mp3ON = true;
delay(500);
}
if ((millis() - offTimeOut) > tOut4 && (millis() - offTimeOut) < tOut41) {
mp3.playFileNumberInFolderNumber(01, 004);
mp3ON = true;
delay(500);
}
}
}
void eyesPWM(){
if ((millis() - winkStepDelay) > (pwmStep)/4) {
if (pwmUp == true) {
if (pwmVal < 128) {
analogWrite(ledPin, pwmVal);
pwmVal = pwmVal + 1;
pwmStep = pwmStep - 1;
winkStepDelay = millis();
} else {
pwmUp = false;
pwmStep = 1;
pwmVal = 128;
}
}
if (pwmUp == false) {
if (pwmVal > pwmStep) {
analogWrite(ledPin, pwmVal);
pwmVal = pwmVal - 1;
pwmStep = pwmStep +1 ;
winkStepDelay = millis();
} else {
pwmUp = true;
pwmStep = 128;
pwmVal = 1;
}
}
}
}
void scanPlay() {
if (fileQ > 0) {
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
uidDec = 0;
byte status;
byte byteCount;
byte buffer[18];
byte pages[2]={4, 8};
byte pageByte;
byteCount = sizeof(buffer);
byte bCount=0;
mfrc522.MIFARE_Read(4, buffer, &byteCount);
bCounter = 0;
for (bCount=0; bCount<4; bCount++) {
readBit = bitRead(buffer[6], (bCount+4));
setBitsForGood(readBit);
}
for (pageByte=5; pageByte > 2; pageByte--) {
for (bCount=0; bCount<8; bCount++) {
readBit = bitRead(buffer[pageByte], bCount);
setBitsForGood(readBit);
}
}
for (bCount=0; bCount<4; bCount++) {
readBit = bitRead(buffer[2], bCount);
setBitsForGood(readBit);
}
for (byte ticketNum = 0; ticketNum < ticketQ; ticketNum++) {
unsigned long ticketTemp = pgm_read_dword_near(ticketSet + ticketNum);
if (ticketTemp == ticketNumber) {
tone(tonePin, 450, 500);
delay(500);
if (ticketNum < (ticketQ - 2)) {
if ((ticketNum+1) < fileQ) {
digitalWrite(ledPin, HIGH);
playFile = ticketNum+1;
mp3ON = true;
playON = true;
mp3.playFileByIndexNumber(playFile);
mp3.playFileByIndexNumber(playFile);
mp3.playFileByIndexNumber(playFile);
delay(500);
}
return;
} else {
if (ticketNum == ticketQ-1) {
enterSleep();
}
if (ticketNum == ticketQ-2) {
setVol();
}
}
}
}
mfrc522.PICC_HaltA();
}
}
void setVol() {
switch (vol) {
case maxVol:
vol = minVol;
break;
case midVol:
vol = maxVol;
break;
case minVol:
vol = midVol;
break;
}
mp3.setVolume(vol);
}