Go Down

Topic: Can't get Coburn's code for Buzz Wire Game to compile (Read 2026 times) previous topic - next topic

jjeffh

After I set it up for the full Buzz Wire game and nothing happened (except Monty Python), then I left it all as you see it and uploaded your LCD code. That didn't work either. It would seem that I must be doing something wrong, but I sure can't see it.

But without changing anything and uploading my test code the LCD works?  
If the bottom rails are getting power the backlight should light.
FYI, Charlie, I found my mistake. I set up just the LCD display on a different UNO and board, using your display code and it worked perfectly as I tested it with different placements of text. So I revisited the full Buzz Game set up and I found that I had connected LCD pin 16 to power instead of ground!

Now I see "Buzz Ready" and when I press the button I get the countdown from 20 seconds, resulting in a chirp from buzzer 2 when it reaches 0. When I manually change the variable "mode" to 1 in the code, then I get your flashing "Free" and "Play".

However, I'm still not getting a buzz when I touch the two leads together, so I'll investigate that set up.

- Jeff

jjeffh

I have not found another stupid mistake like the last one (yet), but there's something about the code I don't understand.

I see "pinMode(9, INPUT)" specified in the code, but I don't see any other reference to pin 9 in the code. Doesn't there have to be some place where the code says that if pin 9 is HIGH the buzzer should sound and the game should end? Or is that handled in a different way?

Pin 9 is connected to the "course" which is connected through two 220 resistors. The setup shows the lead to pin 9 goes to 1e on the board, with a 220 resistor in 1d. The resistor goes to 5d and another 220 resistor goes from 5e to 9e. The course is connected at 5a, and row 9 is grounded.

The the handle lead is connected directly to power. So if that circuit is completed, pin 9 should be HIGH and the buzzer should sound. I just can't see where in the code pin 9's input is read and the buzzer activated.

groundFungus

Quote
The the handle lead is connected directly to power. So if that circuit is completed, pin 9 should be HIGH and the buzzer should sound. I just can't see where in the code pin 9's input is read and the buzzer activated.
Code: [Select]
   if (digitalRead(10) == HIGH)
   {
      delay(25);
      if (digitalRead(10) == HIGH)
      {
         while (digitalRead(10) == HIGH)
         {
            buzz(8, NOTE_B0, 1000 / 24); //[This was changed from 11 to 8]
         }
      }
   }

It looks to me like the 10 in that part of the code should be 9.  Why would one read the buzzer1 output?

jjeffh

You got it! That worked.

So that's the whole project: music, display, two modes, and the wire-touch buzz. Now I just have to cut the pieces for the game board and lay out a suitable procedure that Chance and I can work on together to built this thing.

Thanks so much, Charlie! I've learned quite a bit from you in this thread. I've been looking at the Tutorials Point C++ training online. Perhaps as I go through their tutorials I can work on this code to test things out.

A few things I'd like to do are: 1) start and stop, or at least lower the volume of, the music; 2) stop the game and display "Game Over" when the wand touches the course; and 3) change between Free Play and Challenge Mode on the board instead of in the code.

For now, I'm just delighted to see it all working and to know this Christmas plan is actually going to work.

I doubt we're allowed to add more than one karma point at a time, but I'm going to see if I can give you a couple extra. You've been great.

- Jeff

groundFungus

Thank you.  Glad you got it working.  Hope that you and Chance have as enjoyment with this hobby as i have.

Merry Christmas to you and your's.

Charlie

jjeffh

Thank you.  Glad you got it working.  Hope that you and Chance have as enjoyment with this hobby as i have.

Merry Christmas to you and your's.

Charlie
Merry Christmas to you, too.

- Jeff

n_nip

Hi did you end up getting the circuit to work? I'm trying to make the same one but can't seem to get the buzzer to buzz when the handle touches the circuit

jjeffh

Well this is a blast from the past! It feels like long time since I was doing that project. Which is to say, memory fades.

I seem to remember there was an error in Coburn's published code regarding the buzzers. (Actually, there were a few errors and omissions which groundFungus graciously corrected and created for me.) I had thought the wire buzz and the Monty Python theme both sounded on both buzzers, but I think it turned out we had to separate them. Check out posts 31, 32, and 33 above.

I'll post what think was the code I ended up with in two subsequent posts (the posting limit is 9,000 characters and with the comments, the code is 9,600).

In the end, there were 3 button options:
1. The board's reset button restarts the game and displays, "BUZZ PLAY" and after a delay begins the music and displays "Press button for timed play;
2. The switch across rows 28-30 starts the timer;
3. A new switch added across rows 23-25 stops the music.

That last one is important! The Monty Python music is some real nice coding and gives the game a carnival feel, but it'll drive you crazy on that short loop.

In the final product, touching the wire with the wand beeps, stops the game, and displays, "Game Over! RESET to play again"

Good luck!!


jjeffh

Here's a link to pictures of the finished game: Buzz Game
And here's the first half of the code:

Code: [Select]
//PART 1 OF 2 PART POSTING
/*This version incorporates Charlie's solution
*for manually starting and stopping the music
*with the playMontyFlag.
*It also in the quit flag for ending the game
*as soon as the circuit on pin 9 is completed
*(i.e. when the handle touches the wire).
*/

#include <hd44780.h>
#include <hd44780ioClass/hd44780_pinIO.h> // Arduino pin i/o class header
#include "pitches.h" // include pitches

//Setting LCD pins 4, 6, 11, 12, 13, and 14
//Which correspond to UNO pins 4>11, 6>12, 11>4, 12>5, 13>6, 14>7
const int rs = 11, en = 12, db4 = 4, db5 = 5, db6 = 6, db7 = 7; // for all other devices (don't know what devices this refers to -jh)

//==== Charlie's code ====
//pins 3 and 13 are available
const int  buttonPin = 13;    // the pin that the pushbutton is attached to
const int ledPin = 3;       // the pin that the (built-in) LED is attached to

// Variables will change:
bool buttonState = 0;         // current state of the button
bool lastButtonState = 0;     // previous state of the button
bool playMontyFlag = true;  // initial value of play the tune flag
//^^^^ Charlie's code ^^^^

hd44780_pinIO lcd(rs, en, db4, db5, db6, db7);

// LCD geometry
const int LCD_COLS = 16;
const int LCD_ROWS = 2;

// music: Monty Python theme
int songState = 0;

int melody[] =
{
   NOTE_F4, NOTE_E4, NOTE_D4, NOTE_CS4,
   NOTE_C4, NOTE_B3, NOTE_AS3, NOTE_A3,
   NOTE_G3, NOTE_A3, NOTE_AS3, NOTE_A3,
   NOTE_G3, NOTE_C4, 0,

   NOTE_C4, NOTE_A3, NOTE_A3, NOTE_A3,
   NOTE_GS3, NOTE_A3, NOTE_F4, NOTE_C4,
   NOTE_C4, NOTE_A3, NOTE_AS3, NOTE_AS3,
   NOTE_AS3, NOTE_C4, NOTE_D4, 0,

   NOTE_AS3, NOTE_G3, NOTE_G3, NOTE_G3,
   NOTE_FS3, NOTE_G3, NOTE_E4, NOTE_D4,
   NOTE_D4, NOTE_AS3, NOTE_A3, NOTE_A3,
   NOTE_A3, NOTE_AS3, NOTE_C4, 0,

   NOTE_C4, NOTE_A3, NOTE_A3, NOTE_A3,
   NOTE_GS3, NOTE_A3, NOTE_A4, NOTE_F4,
   NOTE_F4, NOTE_C4, NOTE_B3, NOTE_G4,
   NOTE_G4, NOTE_G4, NOTE_G4, 0,

   NOTE_G4, NOTE_E4, NOTE_G4, NOTE_G4,
   NOTE_FS4, NOTE_G4, NOTE_D4, NOTE_G4,
   NOTE_G4, NOTE_FS4, NOTE_G4, NOTE_C4,
   NOTE_B3, NOTE_C4, NOTE_B3, NOTE_C4, 0
};

int tempo[] =
{
   8, 16, 8, 16,
   8, 16, 8, 16,
   16, 16, 16, 8,
   16, 8, 3,

   12, 16, 16, 16,
   8, 16, 8, 16,
   8, 16, 8, 16,
   8, 16, 4, 12,

   12, 16, 16, 16,
   8, 16, 8, 16,
   8, 16, 8, 16,
   8, 16, 4, 12,

   12, 16, 16, 16,
   8, 16, 8, 16,
   8, 16, 8, 16,
   8, 16, 4, 16,

   12, 17, 17, 17,
   8, 12, 17, 17,
   17, 8, 16, 8,
   16, 8, 16, 8, 1
};

// non blocking setup (what is "non blocking"? -jh)
// free play
unsigned long previousMillis1 = 0; // time words last changed
const long interval1 = 1500; // interval between changing

// music
unsigned long previousMillis2 = 0; // time last changed
const long interval2 = 100; // interval between notes

int displayStatus = 0; // keep track of what's displayed
int mode = 0; // keep track of game mode: change to 0 (challenge) or 1 (free play) for different modes

bool countdown = false;

unsigned long previousMillis3 = 0; // time last changed (used in showCountdown)
const long interval3 = 1000; // interval between countdown (1 second)
int count = 21; // challenge mode timer

//Exit flag
bool quit = false;

void setup()
{
   //==== Charlie's code ====
   // initialize the button pin as an input with internal pullup enabled
   pinMode(buttonPin, INPUT_PULLUP);
   // initialize the LED as an output:
   pinMode(ledPin, OUTPUT);
   // initialize serial communication:
   Serial.begin(9600);
   //^^^^ Charlie's code ^^^^
  
  
   // setup code runs once:
   pinMode(9, INPUT); // setup circuit
   pinMode(10, OUTPUT); // setup buzzer 1
   pinMode(8, OUTPUT); // setup buzzer 2
   pinMode(2, INPUT); // setup button

   lcd.begin(LCD_COLS, LCD_ROWS);
   lcd.print("   BUZZ READY");
   delay(5000);
   lcd.clear();
   lcd.setCursor(2,0);
   lcd.print("Press button");
   lcd.setCursor(1,1);
   lcd.print("for timed play");
}

void loop()
{
  //==== Charlie's code ====
  // read the pushbutton input pin:
   buttonState = digitalRead(buttonPin);
   // compare the buttonState to its previous state
   if (buttonState != lastButtonState)
   {
      if (buttonState == LOW)
      {
         // if the current state is LOW then the button
         // went from not pressed to pressed:        
         digitalWrite(ledPin, !digitalRead(ledPin));
         // toggle a flag to run the sing function or not
         playMontyFlag = !playMontyFlag;
         if(playMontyFlag == true)
         {
          Serial.println("playing Monty Python tune");
         }
         else
         {
          Serial.println("Blessed Silence");
         }
      }
      lastButtonState = buttonState;    
   }
  //^^^^ Charlie's code ^^^^
 //END OF PART 1 POSTING


(I can only post again after five minutes...)

jjeffh

I'm going to attempt to upload my Fritz diagram as a jpg. I seem to remember attachments are tricky on this forum, so I may not be able to. Unfortunately, this diagram doesn't include the button that turns off the music, but other than that I think it is up to date.

And here's part 2 of the code:

Code: [Select]
//START OF PART 2 OF 2 POSTINGS
  /*============== START of TIMER BUTTON PRESS ===================*/
  // Change mode manually here, in the code. 0 = challenge; 1 = free play
  // NOTE: Challenge mode is Free Play until the button is pressed to start countdown
   if (mode == 0)
   {
      // challenge mode
      if (digitalRead(2) == HIGH) //Pin 2 is the button
      {
         delay(25); //Presumably there needs to be a 25ms delay to ensure the button was pressed
         if (digitalRead(2) == HIGH)
         {
            countdown = true; // start the countdown
         }
         else
         {
            countdown = false; // stop the countdown
         }
      }
      if (countdown)
      {
         showCountdown(); // advance countdown
      }
   }
   else
   {
      // free play
      toggleFreePlay();
   }
  /*============== END of TIMER BUTTON PRESS ===================*/

  //Pin 9 is the course-handle circuit. When 9 is activated "Game Over" is displayed and game ends.
  //Press the white reset button on the UNO board to reload and play again.
   if (digitalRead(9) == HIGH)
   {
      delay(25);
      if (digitalRead(9) == HIGH)
      {
         quit = true; //When the course circuit is complete the quit flag is set.
         while (digitalRead(9) == HIGH)
         {
            buzz(8, NOTE_B0, 1000 / 24);
           
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Game Over! RESET");
            lcd.setCursor(0,1);
            lcd.print("to play again");
         }
         // Regarding exiting the loop, see Zoul007's post here: https://stackoverflow.com/questions/23096366/how-to-stop-a-loop-arduino
         if (quit == true){exit(0);} //When the course circuit is broken again, the game ends
      }
   }
   else
   {
      if (playMontyFlag == true)
      {
       sing();
      }
    }
} // END OF 'VOID LOOP'

void showCountdown()
{
   // countdown the time remaining
   unsigned long currentMillis = millis(); // current time
   if (currentMillis - previousMillis3 >= interval3)
   {
      previousMillis3 = currentMillis;
      --count;
      showNumber(count);
      if (count == 0)
      {
         // game over
         quit = true; //TEST
         countdown = false;
         // reset countdown
         count = 21;
         // buzz 3 times
         buzz(8, NOTE_B0, 1000 / 24); //[changed from 11 to 8]
         delay(100);
         buzz(8, NOTE_B0, 1000 / 24); //[changed from 11 to 8]
         delay(100);
         buzz(8, NOTE_B0, 1000 / 24); //[changed from 11 to 8]
         lcd.clear();
         lcd.setCursor(0,0);
         /*lcd.print("Handle down");
         lcd.setCursor(0,1);
         lcd.print("Game Over!");*/

         lcd.print("Game Over! RESET");
         lcd.setCursor(0,1);
         lcd.print("to play again");

         if (quit == true){exit(0);} //TEST

      }
   }
}

void showNumber(int number)
{
  lcd.clear();
  lcd.setCursor(4,0);
  lcd.print("-- "); 
  lcd.setCursor(7,0);
  lcd.print(number);
  lcd.print(" --");
}

void toggleFreePlay()
{
   // scroll between words without blocking
   unsigned long currentMillis = millis(); // current time
   if (currentMillis - previousMillis1 >= interval1)
   {
      previousMillis1 = currentMillis;
      if (displayStatus == 1)
         showPlay();
      else
         showFree();
   }
}

void showPlay()
{
   // write "PLAY" to the display
   lcd.clear();
   lcd.setCursor(6,1);
   lcd.print("PLAY");
   displayStatus = 2;
}

void showFree()
{
   // write "Free" to the display
   lcd.clear();
   lcd.setCursor(6,0);
   lcd.print("FREE");
   displayStatus = 1;
}

void buzz(int targetPin, long frequency, long length)
{
   /* Buzzer example function by Rob Faludi
      http://www.faludi.com
      https://gist.github.com/AnthonyDiGirolamo/1405180
   */
   long delayValue = 1000000 / frequency / 2; // calculate the delay value between transitions
   //// 1 second's worth of microseconds, divided by the frequency, then split in half since
   //// there are two phases to each cycle
   long numCycles = frequency * length / 1000; // calculate the number of cycles for proper timing
   //// multiply frequency, which is really cycles per second, by the number of seconds to
   //// get the total number of cycles to produce
   for (long i = 0; i < numCycles; i++) // for the calculated length of time...
   {
      digitalWrite(targetPin, HIGH); // write the buzzer pin high to push out the diaphragm
      delayMicroseconds(delayValue); // wait for the calculated delay value
      digitalWrite(targetPin, LOW); // write the buzzer pin low to pull back the diaphragm
      delayMicroseconds(delayValue); // wait again for the calculated delay value
   }
}

void sing()
{
   // play the song in a non blocking way
   unsigned long currentMillis = millis();

   if (currentMillis - previousMillis2 >= interval2)
   {
      previousMillis2 = currentMillis;
      int noteDuration = 1000 / tempo[songState];
      buzz(10, melody[songState], noteDuration);
      int pauseBetweenNotes = noteDuration;
      delay(pauseBetweenNotes);

      // stop the tone playing:
      buzz(10, 0, noteDuration);

      ++songState;
      // start song again if finished
      if (songState > 79)
      {
         songState = 14; // skip intro
      }
   }
}
//END OF PART 2 POSTING

groundFungus


jjeffh

Hey Charlie, nice to hear from you!
In the meantime I went ahead and updated my Fritz. (Hope I get the Modify and Insert Image procedure right.) (...which I didn't, but no matter n_nip, you can download the jpg to see how the second button goes in. I don't know why it needed a 10k-ohm resistor, but it works.)

Anyway, I had wanted to get back to you to let you know Chance and I spent and lovely afternoon putting the project together and it works perfectly. I had set it up as a kit with all the base pieces and the Arduino components in little groups and he really took to it.




groundFungus


Go Up