Guitar Hero Project - coding performance

Hey Guys,

Little bit of bio: (If you’re interested)
I live in Australia, and work at Jaycar Electronics [http://www.jaycar.com.au/](we sell kits, components, Arduino equivalents, project hardware, tools - and a whole lot of other non-arduino related products).
I build all types of electronic projects as a side hobby for fun, or to build things to solve problems. Of them, obviously Arduino is a major player in my electronics collection.
I’m in my 3rd year studying IT at uni, which contains a fair bit of programming - but by no means a great programmer. Of the simple code I’ve written - I understand it pretty well.

Guitar Hero Project bio: (as above, if interested)
I love guitar hero, for both recreation and a good challenge. I play on XBOX 360, and of course there’s this one song I can’t get 5 stars on to get the achievement. (Because I’m just such an achievement whore). So using my ingenuity, and hardware skills - I soon created an Arduino-enabled guitar and this is where I stand… the code.
It’s supposed to work like this:
-LDRs are placed against LCD TV
-Arduino scans for brightness level of LDR
-Calculates appropriate action
-Plays note if required
But it’s a bit more complicated than that.

Hardware:
6 LEDs - Green, red, yellow, blue and orange notes. + additional system LED
5 LDRs - Green, red, yellow, blue and orange notes. (Light Dependant Resistor). To detect notes on screen
6 relays - Green, red, yellow, blue and orange notes. + Strum relay to ‘strum’ the notes ‘held down’ by the other relays.
3 momentary buttons - Arduino connected. Used for changing sensitivity/timings/software features.
misc. hardware: (not relevant to direct operation)
1 DPDT toggle switch - to disconnect the strum relay, and LDR common ground. To stop false triggers due to menu browsing etc
1 RJ12 6P6C socket. External connection to LDRs placed on screen. 5 signals and common round.
1 2.1mm socket. Easily supply external power.

Allocation of Arduino IC pins: (all 14 digital and 6 analog pins are used)
greenLED = 2
redLED = 3
yellowLED = 4
blueLED = 7
orangeLED = 8
systemLED = 6

greenRelay = 12
redRelay = 11
yellowRelay = 10
blueRelay = 9
orangeRelay = 5
strumRelay = 13

blueLDR = A0
yellowLDR = A1
greenLDR = A2
redLDR = A3
orangeLDR = A4

menuButton = A5
plusButton = 0
minusButton = 1

Problem:
I’ve written some basic code, with basic functionality. It’s worked well on easy for simple notes. But here is what the code needs to do:
-Play stand-alone - I’d like the functionality to be dynamic (played live with notes on screen). Not to have songs ‘saved’ in memory and recalled.
-Detect chords - Single strum to be played with multiple notes held down. (if note detected, check status of other notes before strum)
-Detect sustains - extended holding down of note with possible new notes to be played while note is held down ([new note detected] if original note still active, keep note held down)
-Disengage after a note has finished playing. (determine if note has passed [brightness will drop] and disengage relay) I tried playing around with this, but it wasn’t very clean [I was getting false triggers as it was jumping between off and on detection states. Relays were clicking madly], so I disabled the code I wrote. But that means if there is a string of the same note to be played (ie, 4 red notes in sequence) then it will only play the first note and look for other notes that need to be played. This problem severely needs to be fixed. Example of this is seen in the video I’ve uploaded.
-Adjust sensitivity on the fly. I’ve done this with code, by dynamically changing the </=/> values that it’s looking for. These could have also been done with a trimpot. But I didn’t want that getting bumped. View menu options at the bottom of the code.
[There were other things, but I can’t remember them right now. I will advise if I recall them]

So my question is this… Can anyone help me refine my code and make it run faster. The faster the code runs, the more notes it will be able to hit. I know the set up right now is horribly inefficient and uses repeated code many times. But this is why I’m reaching out for help.

Here is the code:
(Sorry, the code was so inefficient that it helped pull my post over the character limit).
It’s uploaded in a comment below.

Pictures of hardware:

http://img221.imageshack.us/img221/4839/image657f.jpg
For those who are interested in what it looks like.


http://img209.imageshack.us/img209/23/image642b.jpg
Sorry if this isn’t the clearest. It was just my sketch of the layout. But thought it was worth uploading. Things aren’t labelled, but it was mainly just a guide for me when I was soldering it all together and running those trace tracks.

Any feedback is appreciated!
Thanks,
Alex.

14122011036.mp4 (3.81 MB)

/*
Automated Guitar Hero Player
09/12/11
*/

const int greenLED = 2;
const int redLED = 3;
const int yellowLED = 4;
const int blueLED = 7;
const int orangeLED = 8;
const int systemLED = 6;

const int greenRelay = 12;
const int redRelay = 11;
const int yellowRelay = 10;
const int blueRelay = 9;
const int orangeRelay = 5;
const int strumRelay = 13;

const int blueLDR = A0;
const int yellowLDR = A1;
const int greenLDR = A2;
const int redLDR = A3;
const int orangeLDR = A4;

const int menuButton = A5;
const int plusButton = 0;
const int minusButton = 1;

int infiniteLoop = 0;

int LDRsensitivity = 250;
int strumTime = 50;

int greenState = 0;
int redState = 0;
int yellowState = 0;
int blueState = 0;
int orangeState = 0;

void setup()
{
  pinMode(greenLED, OUTPUT);    
  pinMode(redLED, OUTPUT);    
  pinMode(yellowLED, OUTPUT);    
  pinMode(blueLED, OUTPUT);    
  pinMode(orangeLED, OUTPUT);    
  pinMode(systemLED, OUTPUT);    
  
  pinMode(greenRelay, OUTPUT);
  pinMode(redRelay, OUTPUT);
  pinMode(yellowRelay, OUTPUT);    
  pinMode(blueRelay, OUTPUT);       
  pinMode(orangeRelay, OUTPUT);
  pinMode(strumRelay, OUTPUT);    
  
  pinMode(greenLDR, INPUT);
  pinMode(redLDR, INPUT);
  pinMode(yellowLDR, INPUT);
  pinMode(blueLDR, INPUT);
  pinMode(orangeLDR, INPUT);
  
  pinMode(menuButton, INPUT);
  pinMode(plusButton, INPUT);
  pinMode(minusButton, INPUT);
  
  digitalWrite(systemLED, HIGH);
}

void loop()
{
  
// Green Fret Initiation
if (analogRead(greenLDR) >= LDRsensitivity && greenState == 0)
{
  digitalWrite(greenLED, HIGH);
  digitalWrite(greenRelay, HIGH);
  
  if (analogRead(redLDR) >= LDRsensitivity)
  {
    digitalWrite(redLED, HIGH);
    digitalWrite(redRelay, HIGH);
  }
  else
  {
    digitalWrite(redLED, LOW);
    digitalWrite(redRelay, LOW);
    redState = 0;
  }
  
  if (analogRead(yellowLDR) >= LDRsensitivity)
  {
    digitalWrite(yellowLED, HIGH);
    digitalWrite(yellowRelay, HIGH);
  }
  else
  {
    digitalWrite(yellowLED, LOW);
    digitalWrite(yellowRelay, LOW);
    yellowState = 0;
  }
  
  if (analogRead(blueLDR) >= LDRsensitivity)
  {
    digitalWrite(blueLED, HIGH);
    digitalWrite(blueRelay, HIGH);
  }
  else
  {
    digitalWrite(blueLED, LOW);
    digitalWrite(blueRelay, LOW);
    blueState = 0;
  }
  
  if (analogRead(orangeLDR) >= LDRsensitivity)
  {
    digitalWrite(orangeLED, HIGH);
    digitalWrite(orangeRelay, HIGH);
  }
  else
  {
    digitalWrite(orangeLED, LOW);
    digitalWrite(orangeRelay, LOW);
    orangeState = 0;
  }
  
  digitalWrite(systemLED, LOW);
  digitalWrite(strumRelay, HIGH);
  delay(strumTime);
  digitalWrite(strumRelay, LOW);
  digitalWrite(systemLED, HIGH);
  
  greenState = 1;
}
 else if (analogRead(greenLDR) >= LDRsensitivity && greenState == 1)
  {
    digitalWrite(greenLED, LOW);
    digitalWrite(greenRelay, LOW);
    greenState = 0;
  }




// Red Fret Initiation
if (analogRead(redLDR) >= LDRsensitivity && greenState == 0)
{
  digitalWrite(redLED, HIGH);
  digitalWrite(redRelay, HIGH);
  
  if (analogRead(greenLDR) >= LDRsensitivity)
  {
    digitalWrite(greenLED, HIGH);
    digitalWrite(greenRelay, HIGH);
  }
  else
  {
    digitalWrite(greenLED, LOW);
    digitalWrite(greenRelay, LOW);
    greenState = 0;
  }
  
  if (analogRead(yellowLDR) >= LDRsensitivity)
  {
    digitalWrite(yellowLED, HIGH);
    digitalWrite(yellowRelay, HIGH);
  }
  else
  {
    digitalWrite(yellowLED, LOW);
    digitalWrite(yellowRelay, LOW);
    yellowState = 0;
  }
  
  if (analogRead(blueLDR) >= LDRsensitivity)
  {
    digitalWrite(blueLED, HIGH);
    digitalWrite(blueRelay, HIGH);
  }
  else
  {
    digitalWrite(blueLED, LOW);
    digitalWrite(blueRelay, LOW);
    blueState = 0;
  }
  
  if (analogRead(orangeLDR) >= LDRsensitivity)
  {
    digitalWrite(orangeLED, HIGH);
    digitalWrite(orangeRelay, HIGH);
  }
  else
  {
    digitalWrite(orangeLED, LOW);
    digitalWrite(orangeRelay, LOW);
    orangeState = 0;
  }
  
  digitalWrite(systemLED, LOW);
  digitalWrite(strumRelay, HIGH);
  delay(strumTime);
  digitalWrite(strumRelay, LOW);
  digitalWrite(systemLED, HIGH);
  
  redState = 1;
}
else if (analogRead(redLDR) >= LDRsensitivity && redState == 1)
  {
    digitalWrite(redLED, LOW);
    digitalWrite(redRelay, LOW);
    redState = 0;
  }




// Yellow Fret Initiation
if (analogRead(yellowLDR) >= LDRsensitivity && yellowState == 0)
{
  digitalWrite(yellowLED, HIGH);
  digitalWrite(yellowRelay, HIGH);
  
  if (analogRead(greenLDR) >= LDRsensitivity)
  {
    digitalWrite(greenLED, HIGH);
    digitalWrite(greenRelay, HIGH);
  }
  else
  {
    digitalWrite(greenLED, LOW);
    digitalWrite(greenRelay, LOW);
    greenState = 0;
  }
  
  if (analogRead(redLDR) >= LDRsensitivity)
  {
    digitalWrite(redLED, HIGH);
    digitalWrite(redRelay, HIGH);
  }
  else
  {
    digitalWrite(redLED, LOW);
    digitalWrite(redRelay, LOW);
    redState = 0;
  }
  
  if (analogRead(blueLDR) >= LDRsensitivity)
  {
    digitalWrite(blueLED, HIGH);
    digitalWrite(blueRelay, HIGH);
  }
  else
  {
    digitalWrite(blueLED, LOW);
    digitalWrite(blueRelay, LOW);
    blueState = 0;
  }
  
  if (analogRead(orangeLDR) >= LDRsensitivity)
  {
    digitalWrite(orangeLED, HIGH);
    digitalWrite(orangeRelay, HIGH);
  }
  else
  {
    digitalWrite(orangeLED, LOW);
    digitalWrite(orangeRelay, LOW);
    orangeState = 0;
  }
  
  digitalWrite(systemLED, LOW);
  digitalWrite(strumRelay, HIGH);
  delay(strumTime);
  digitalWrite(strumRelay, LOW);
  digitalWrite(systemLED, HIGH);
  
  yellowState = 1;
}
  else if (analogRead(yellowLDR) >= LDRsensitivity && yellowState == 1)
  {
    digitalWrite(yellowLED, LOW);
    digitalWrite(yellowRelay, LOW);
    yellowState = 0;
  }




// Blue Fret Initiation
if (analogRead(blueLDR) >= LDRsensitivity && blueState == 0)
{
  digitalWrite(blueLED, HIGH);
  digitalWrite(blueRelay, HIGH);
  
  if (analogRead(greenLDR) >= LDRsensitivity)
  {
    digitalWrite(greenLED, HIGH);
    digitalWrite(greenRelay, HIGH);
  }
  else
  {
    digitalWrite(greenLED, LOW);
    digitalWrite(greenRelay, LOW);
    greenState = 0;
  }
  
  if (analogRead(redLDR) >= LDRsensitivity)
  {
    digitalWrite(redLED, HIGH);
    digitalWrite(redRelay, HIGH);
  }
  else
  {
    digitalWrite(redLED, LOW);
    digitalWrite(redRelay, LOW);
    redState = 0;
  }
  
  if (analogRead(yellowLDR) >= LDRsensitivity)
  {
    digitalWrite(yellowLED, HIGH);
    digitalWrite(yellowRelay, HIGH);
  }
  else
  {
    digitalWrite(yellowLED, LOW);
    digitalWrite(yellowRelay, LOW);
    yellowState = 0;
  }
  
  if (analogRead(orangeLDR) >= LDRsensitivity)
  {
    digitalWrite(orangeLED, HIGH);
    digitalWrite(orangeRelay, HIGH);
  }
  else
  {
    digitalWrite(orangeLED, LOW);
    digitalWrite(orangeRelay, LOW);
    orangeState = 0;
  }
  
  digitalWrite(systemLED, LOW);
  digitalWrite(strumRelay, HIGH);
  delay(strumTime);
  digitalWrite(strumRelay, LOW);
  digitalWrite(systemLED, HIGH);
  
  blueState = 1;
}
  else if (analogRead(blueLDR) >= LDRsensitivity && blueState == 1)
  {
    digitalWrite(blueLED, LOW);
    digitalWrite(blueRelay, LOW);
    blueState = 0;
  }




// Orange Fret Initiation
if (analogRead(orangeLDR) >= LDRsensitivity && orangeState == 0)
{
  digitalWrite(orangeLED, HIGH);
  digitalWrite(orangeRelay, HIGH);
  
  if (analogRead(greenLDR) >= LDRsensitivity)
  {
    digitalWrite(greenLED, HIGH);
    digitalWrite(greenRelay, HIGH);
  }
  else
  {
    digitalWrite(greenLED, LOW);
    digitalWrite(greenRelay, LOW);
    greenState = 0;
  }
  
  if (analogRead(redLDR) >= LDRsensitivity)
  {
    digitalWrite(redLED, HIGH);
    digitalWrite(redRelay, HIGH);
  }
  else
  {
    digitalWrite(redLED, LOW);
    digitalWrite(redRelay, LOW);
    redState = 0;
  }
  
  if (analogRead(yellowLDR) >= LDRsensitivity)
  {
    digitalWrite(yellowLED, HIGH);
    digitalWrite(yellowRelay, HIGH);
  }
  else
  {
    digitalWrite(yellowLED, LOW);
    digitalWrite(yellowRelay, LOW);
    yellowState = 0;
  }
  
  if (analogRead(blueLDR) >= LDRsensitivity)
  {
    digitalWrite(blueLED, HIGH);
    digitalWrite(blueRelay, HIGH);
  }
  else
  {
    digitalWrite(blueLED, LOW);
    digitalWrite(blueRelay, LOW);
    blueState = 0;
  }
  
  digitalWrite(systemLED, LOW);
  digitalWrite(strumRelay, HIGH);
  delay(strumTime);
  digitalWrite(strumRelay, LOW);
  digitalWrite(systemLED, HIGH);
  
  orangeState = 1;
}
else if (analogRead(orangeLDR) >= LDRsensitivity && orangeState == 1)
  {
    digitalWrite(orangeLED, LOW);
    digitalWrite(orangeRelay, LOW);
    orangeState = 0;
  }

digitalWrite(systemLED, HIGH);
}

Sorry guys, even my main code was too big for the character limit. Here's the menu code used for adjusting things while the code is running.

//Enter Menu
if (analogRead(menuButton) >= 800)
{
  digitalWrite(systemLED, LOW);
  delay(1500);
  //LDR sensivity - Green Menu
  digitalWrite(greenLED, HIGH);
  while(infiniteLoop == 0)
  {
    if (analogRead(menuButton) >= 800)
    {
      delay(1000);
      break;
    }
    if (digitalRead(plusButton == HIGH))
    {
      LDRsensitivity += 10;
      digitalWrite(greenLED, LOW);
      delay(100);
      digitalWrite(greenLED, HIGH);
      delay(100);
      digitalWrite(greenLED, LOW);
      delay(100);
      digitalWrite(greenLED, HIGH);
      delay(100);
      digitalWrite(greenLED, LOW);
      delay(100);
      digitalWrite(greenLED, HIGH);
      delay(100);
    }
    if (digitalRead(minusButton == HIGH))
    {
      LDRsensitivity -= 10;
      digitalWrite(greenLED, LOW);
      delay(100);
      digitalWrite(greenLED, HIGH);
      delay(100);
      digitalWrite(greenLED, LOW);
      delay(100);
      digitalWrite(greenLED, HIGH);
      delay(100);
      digitalWrite(greenLED, LOW);
      delay(100);
      digitalWrite(greenLED, HIGH);
      delay(100);
    }
  }
digitalWrite(greenLED, LOW);
// Strum Time - Blue Menu
digitalWrite(blueLED, HIGH);
  while(infiniteLoop == 0)
  {
    if (analogRead(menuButton) >= 800)
    {
      delay(1000);
      break;
    }
    if (digitalRead(plusButton == HIGH))
    {
      strumTime += 50;
      digitalWrite(blueLED, LOW);
      delay(100);
      digitalWrite(blueLED, HIGH);
      delay(100);
      digitalWrite(blueLED, LOW);
      delay(100);
      digitalWrite(blueLED, HIGH);
      delay(100);
      digitalWrite(blueLED, LOW);
      delay(100);
      digitalWrite(blueLED, HIGH);
      delay(100);
    }
    if (digitalRead(minusButton == HIGH))
    {
      strumTime -= 50;
      digitalWrite(blueLED, LOW);
      delay(100);
      digitalWrite(blueLED, HIGH);
      delay(100);
      digitalWrite(blueLED, LOW);
      delay(100);
      digitalWrite(blueLED, HIGH);
      delay(100);
      digitalWrite(blueLED, LOW);
      delay(100);
      digitalWrite(blueLED, HIGH);
      delay(100);
    }
  }
digitalWrite(blueLED, LOW);
//END MENUS
}

try [ code] your code [ /code]

(leave out the spaces)

mmcp42: try [ code] your code [ /code]

(leave out the spaces)

Sorry, in the rush I forgot to put it in code tags.

easily done! :) meanwhile your code seems to do similar things to similar pins why not write functions and pass the pin as a parameter it'll be smaller at least and probably easier to understand (and modify)

also consider using arrays

Due to the amount of work being done on the pins, you can benefit greatly from port mapping. Try and implement fat16lib's template class. Not only will the pin control be faster but the sketch will compile smaller.

http://arduino.cc/forum/index.php/topic,86931.0.html

Hello Alxndr,

I am planning to do a similar build, but with a computer’s help for image processing.
I’m interested in the hardware part, what did you use for the arduino/xbox interface ?

Regards,