Charity project

New version. If this one gets to max excitement, it'll do the final display and reset back to nothing. If it is at a lower excitement level and doesn't get a coin, it will go back through the previous levels until it gets back to zero.

// Cake Controller V004

// Changes
// Now another level of excitement and a new pattern
// Tones for levels moved to an array
// One Led pin per pattern
// Final tone phases in and out four times
// Flip HIGH/LOW on LEDs to take care of active low relay board
// After peak excitement, go back to zero

const byte LedPins[]={2,3,4,5};            // Arbitrary Led pins in an array so I can loop through them

const byte NumLeds = sizeof LedPins / sizeof LedPins[0]; 
const byte LedPatterns[5][NumLeds] = { // Patterns for the various led effects, including the special case of all off
                                       {LOW, LOW, LOW, LOW},
                                       {HIGH,LOW, LOW, LOW},
                                       {LOW ,HIGH,LOW ,LOW},
                                       {LOW ,LOW ,HIGH,LOW},
                                       {HIGH,HIGH,HIGH,HIGH}
                                     };

const int Tones[]={0,262,300,392,523};     // Tones for different exitement levels

const byte SoundPin = 10;                  // Used with Tone function to make noise with as yet unknown hardware
const byte CoinDetectPin = 11;             // The coin detector - active LOW
const byte MaxExcitementLevel=4;           

byte ExcitementLevel=0; 

const unsigned long ExitementInterval=6000;      // Milliseconds. How long do users have to add an extra coin
const unsigned long PatternChangeInterval=1000;  // Milliseconds
const unsigned long ToneChangeInterval=250;      // Milliseconds
const byte MaxToneChanges=8;

unsigned long LevelChangeTime;
unsigned long PatternChangeTime;           // When did the pattern last change - used for flashing effect
unsigned long ToneChangeTime;              // When did the tone last change - used for pulsing effect
byte NumToneChanges;
bool PatternOn=false;                      // Flash controller

void setup() 
{
Serial.begin(115200);
Serial.println("Start");
for(byte i=0;i<NumLeds;i++)
  { 
  pinMode(LedPins[i],OUTPUT);
  }
pinMode(SoundPin,OUTPUT);
pinMode(CoinDetectPin,INPUT_PULLUP);
}

void loop() 
{
if(digitalRead(CoinDetectPin)==LOW)
  {
  HandleNewCoin();  
  }
if(millis()-LevelChangeTime > ExitementInterval)
  {
  if(ExcitementLevel==MaxExcitementLevel)
    {
    ExcitementLevel=0;
    LightsOff();  
    }
  if(ExcitementLevel>0)  
    {
    ExcitementLevel--;
    LevelChangeTime = millis();    
    }
  }
HandleSounds();
HandleLedPatterns();
}

void   HandleNewCoin()
{
if(millis()-LevelChangeTime < ExitementInterval)
  {
   Serial.println("coin");
   delay(250);                 // Ugly delay to stop cointing coins more than one
  if(ExcitementLevel< MaxExcitementLevel)  
    {
    ExcitementLevel++;
    ToneChangeTime=millis();
    NumToneChanges=MaxToneChanges;
    }  
  }
LevelChangeTime = millis();
}

void HandleSounds()
{
switch(ExcitementLevel)
  {
  case 0:
    noTone(SoundPin);  
    break;
  case MaxExcitementLevel:
    HandleMaxExitementTones();
    break;
  default:  
    tone(SoundPin,Tones[ExcitementLevel]);  
    break;
  }
}

void HandleMaxExitementTones()
{
static bool ToneOn;  

if(NumToneChanges)
  {
  if(millis()-ToneChangeTime > ToneChangeInterval)
    {
    NumToneChanges--;
    ToneOn=!ToneOn;
    Serial.print("ToneOn: ");
    Serial.println(ToneOn);
    if(ToneOn)
      tone(SoundPin,Tones[ExcitementLevel]);  
    else    
      noTone(SoundPin);  
    ToneChangeTime=millis();  
    }
  }  
}

void HandleLedPatterns()
{
if(millis()-PatternChangeTime > PatternChangeInterval)
  {
  Serial.print("Excite: ");
  Serial.println(ExcitementLevel);
  PatternOn = !PatternOn;
  if(PatternOn)
    {
    for(byte i=0;i<NumLeds;i++)
       digitalWrite(LedPins[i],LedPatterns[ExcitementLevel][i]==HIGH ? LOW : HIGH);
    }
  else
    {
    LightsOff();  
    }
  PatternChangeTime=millis();  
  }
}

void LightsOff()
{
for(byte i=0;i<NumLeds;i++)
  digitalWrite(LedPins[i],HIGH);  
}

Thank you again, I am still struggling, could I phone you?

Sure, just be aware that It will be an international call. I'll message you the number.

thank you

The lights are still staying on once activated. I think I should choose the simpler option of just all lights and one tone when any coin is dropped in, and all off afterwards, if this is not too late to ask please?

We will have another opportunity with the candle later in the year, so could still work on the more complex pattern for then.

Here's the simple version:

// Cake Controller V005

// Simpler version: turn all lights on and play sound for every coin.

// Changes

const byte LedPins[]={2,3,4,5};            // Arbitrary Led pins in an array so I can loop through them

const byte NumLeds = sizeof LedPins / sizeof LedPins[0]; 

const int Tones[]={0,262,300,392,523};     // Tones for different exitement levels

const byte SoundPin = 10;                  // Used with Tone function to make noise with as yet unknown hardware
const byte CoinDetectPin = 11;             // The coin detector - active LOW

const unsigned long ExitementInterval=6000;      // Milliseconds. How long do users have to add an extra coin
unsigned long LightsOnTime;

void setup() 
{
Serial.begin(115200);
Serial.println("Start");
for(byte i=0;i<NumLeds;i++)
  { 
  pinMode(LedPins[i],OUTPUT);
  }
pinMode(SoundPin,OUTPUT);
pinMode(CoinDetectPin,INPUT_PULLUP);
LightsOff();
}

void loop() 
{
if(digitalRead(CoinDetectPin)==LOW)
  {
  HandleNewCoin();  
  }
if(millis()-LightsOnTime > ExitementInterval)
  {
  LightsOff();
  noTone(SoundPin);
  }
}

void   HandleNewCoin()
{
Serial.println("coin");
LightsOn();
tone(SoundPin,Tones[4]);  
delay(250);                 // Ugly delay to stop cointing coins more than once
}

void LightsOn()
{
LightsOnTime = millis();
for(byte i=0;i<NumLeds;i++)
  digitalWrite(LedPins[i],LOW);  
}

void LightsOff()
{
for(byte i=0;i<NumLeds;i++)
  digitalWrite(LedPins[i],HIGH);  
}

Thank you, I will try it.