The document describes a scoreboard control program for a horseshoe game. It uses Arduino Nanos and 16x32 dot matrix displays to show the scores of 6 horseshoe courts. When a player hits the foot switch, the corresponding score is incremented. If the switch is held too long, the score repeatedly decrements until it reaches zero. Adjacent scores are also reset to zero if one exceeds the maximum or their switches are held too long together.
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0 ratings0% found this document useful (0 votes)
198 views6 pages
DMD - Ver - 1 - 0 Code
The document describes a scoreboard control program for a horseshoe game. It uses Arduino Nanos and 16x32 dot matrix displays to show the scores of 6 horseshoe courts. When a player hits the foot switch, the corresponding score is incremented. If the switch is held too long, the score repeatedly decrements until it reaches zero. Adjacent scores are also reset to zero if one exceeds the maximum or their switches are held too long together.
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 6
// Scoreboard Control Program by P.
Clark (Arduino forum handle: Palomar)
// // Ver. 1.0 10/31/2014 // First release of Scoreboard Control Program // // -------------------------------------------------------------------- // A scoreboard was created for the game of Horseshoes. // Built in two halves, the left half covers courts 1, 2 and 3, while the right // half covers courts 4, 5 and 6. // Each half uses one Arduino Nano and is independent of the other half. // See photo: http://i351.photobucket.com/albums/q452/plclark3/IMJ_4700x.jpg // // This sketch is intended for use with the following hardware: // (one) Arduino USB Nano ATmega328 // (six) 16x32 Dot Matrix Display (DMD) panels // (six) External switches, normally open, connected to pins A0-A5 // // The DMD panels are arranged in pairs: 2-across and 3-down. // Each individual panel displays a 2-digit score, 6 inches high, using the full // 16-rows of LED's. // // The external foot switches are operated by the players themselves. // When a switch is closed, the corresponding pin goes LOW. // If switch is released within "delayPeriod" time, the score is incremented by 1. // If switch is held closed longer than "delayPeriod", the score is repeatedly // decremented by 1 until the switch is released, or the score reaches zero . // If an adjacent pair of switches are closed longer than "delayPeriod", both // scores are reset to zero. // When either score of an adjacent pair exceeds "maxScore", both scores are res et // to zero. // // For anyone attempting to connect a monochrome 16x32 DMD panel to Arduino, the // following diagram may be helpful. The 16-pin header on the back of the D MD // panel is wired to the following pins: // // D9 |_1|_2| D6 // GND |_3|_4| D7 // |_5|_6| // (slot) |_7|_8| D13 (the orientation slot is on the left side of the header) // |_9|10| D8 // |11|12| D11 // |13|14| // |15|16| // // You must supply 5V power directly to the DMD panel as Arduino cannot provide // nearly enough current. Lighting up all 512 LED's in a panel with 1/4 // multiplexing takes about 7 amps at 5V. // // -------------------------------------------------------------------- #include <SPI.h> #include <DMD.h> #include <TimerOne.h> #include <PLCBigFont.h> #include <TimedAction.h> // Operational parameters int maxScore = 25; // highest score possible int debounce = 25; // debounce time in millis unsigned long delayPeriod = 700; // decrement delay period, in mil lis unsigned long repeatPeriod = 300; // decrement repeat period, in mi llis unsigned long currTime = 0; // current time since start up, i n millis unsigned long closedPeriod = 0; // switch-closed period in, milli s unsigned long closedTime [] = {0, 0, 0, 0, 0, 0}; // switch-closed time, in mill is volatile int interruptFlag = 0; // interrupt flag int refreshFlag = 0; // refresh flag int decTimerFlag = 0; // decrement flag int i = 0; // index for switches and scores (0 thru 5) int j = 0; // score pair indicator (0, 2 or 4) int k = 0; // display column offset (0, 64 o r 128) int prevStatus [] = {0, 0, 0, 0, 0, 0}; // prev switch status int currStatus [] = {1, 1, 1, 1, 1, 1}; // curr switch status int score [] = {0, 0, 0, 0, 0, 0}; // curr scores int scoreStatus [] = {0, 0, 0, 0, 0, 0}; // score status for decrementing // scoreStatus values: 0=switch open, 1=switch closed, 2=switch closed & score d ecremented //String PL; // used with Serial.println // Example: PL = ""; PL = PL + i + " time: " + decTime [i]; Serial.println(PL); DMD dmd(2,3); // (DISPLAYS_ACROSS, DISPLAYS_DOW N) // initialize a timer to perform decrementing TimedAction decTimer = TimedAction(100,checkDecrement); // do it every 100 mill is // -------------------------------------------------------------------- void ScanDMD() // timer interrupt to drive displ ay refresh { dmd.scanDisplayBySPI(); } // -------------------------------------------------------------------- ISR (PCINT1_vect) // pin change interrupt A0-A5 { interruptFlag = 1; // set interrupt flag } // -------------------------------------------------------------------- void setup () { //Serial.begin(9600); //Serial.println("Start"); dmd.clearScreen( true ); // clear random pixels on display dmd.selectFont(MyBigFont); // select large font // Initialize pin change interrupt (PCINT1_vect) PCMSK1 = 63; // set interrupt mask for pins A0 -A5 PCIFR |= bit (PCIF1); // clear any outstanding interrup ts PCICR |= bit (PCIE1); // enable pin change interrupts // Initialize DMD interrupt used to refresh the display // Set period in microseconds to call ScanDMD // Anything longer than 4000 (4ms) may cause the display to flicker Timer1.initialize( 5000 ); Timer1.attachInterrupt( ScanDMD ); // set switch pins HIGH digitalWrite (A0, HIGH); // enable pull-down pin 14 digitalWrite (A1, HIGH); // enable pull-down pin 15 digitalWrite (A2, HIGH); // enable pull-down pin 16 digitalWrite (A3, HIGH); // enable pull-down pin 17 digitalWrite (A4, HIGH); // enable pull-down pin 18 digitalWrite (A5, HIGH); // enable pull-down pin 19 refreshBoard (); // initialize scoreboard to zeros } // -------------------------------------------------------------------- void checkSwitches () // check status of switches { //Serial.println(""); //Serial.println("checkSwitches"); delay (debounce); // debounce switch contacts for (i = 0; i <= 5; i++) // quick loop to read pins A0-A5 { prevStatus [i] = currStatus [i]; // save switch status to prev currStatus [i] = digitalRead (A0 + i); // read current switch status // NOTE: an open switch reads HIGH (1); a closed switch reads LOW (0) } currTime = millis(); // get current time for (i = 0; i <= 5; i++) // loop to save switch-closed tim e { if (prevStatus [i] == 1 && currStatus [i] == 0) // if a switch just closed... { // Serial.println("switch closed"); closedTime [i] = currTime; // save the time scoreStatus [i] = 1; // switch is closed decTimerFlag = 1; // set decTimer flag // PL = ""; PL = PL + i + " scoreStatus: " + scoreStatus [i]; Serial.println (PL); // PL = ""; PL = PL + " decTimer: " + decTimerFlag; Serial.println (PL); } } refreshFlag = 0; // clear refresh flag for (i = 0; i <= 5; i++) // loop to increment scores { if (prevStatus [i] == 0 && currStatus [i] == 1) // if a switch just opened... { // Serial.println("switch opened"); // PL = ""; PL = PL + i + " scoreStatus: " + scoreStatus [i]; Serial.println (PL); if (scoreStatus [i] == 1) // but not yet decremented... { checkPeriod (); // check switch-closed period } scoreStatus [i] = 0; // status is open // PL = ""; PL = PL + i + " scoreStatus: " + scoreStatus [i]; Serial.println (PL); } } if (refreshFlag > 0) refreshBoard (); // refresh if a score changed interruptFlag = 0; // clear interrupt flag } // -------------------------------------------------------------------- void checkPeriod () // check switch-closed period { //Serial.println("checkPeriod"); closedPeriod = currTime - closedTime [i]; // calculate switch-closed period //PL = ""; PL = PL + i + " closedPeriod: " + closedPeriod; Serial.println(PL); if (closedPeriod < delayPeriod) // if closed period < delay perio d... { incrementScore (); // increment the score refreshFlag = 1; // set refresh flag } } // -------------------------------------------------------------------- void incrementScore () // increment score { //Serial.println("incrementScore"); j = (i / 2) * 2; // determine which pair of scores //PL = ""; PL = PL + i + " score: " + score [i]; Serial.println(PL); if (score [i] >= maxScore) // if score is at max... { score [j] = 0; // reset both scores to zero score [j + 1] = 0; } else { score [i] += 1; // else increment score by 1 } //PL = ""; PL = PL + i + " score: " + score [i]; Serial.println(PL); } // -------------------------------------------------------------------- void checkDecrement () // decrement score { //Serial.println(""); //Serial.println("checkDecrement"); refreshFlag = 0; // clear refresh flag decTimerFlag = 0; // clear decTimer flag currTime = millis(); // get current time for (i = 0; i <= 5; i = i + 2) // check scores for reset to zero { j = i + 1; // i and j are a pair of scores if (scoreStatus [i] == 2 && scoreStatus [j] == 2) // if both are decrementing. .. { score [i] = 0; score [j] = 0; // reset both scores to zero scoreStatus [i] = 0; scoreStatus [j] =0; // status is open refreshFlag = 1; // set refresh flag } } //i = 0; //PL = ""; PL = PL + i + " scoreStatus: " + scoreStatus [i]; Serial.println(PL) ; for (i = 0; i <= 5; i++) // loop to handle decrementing { if (scoreStatus [i] > 0) // if switch is closed... { decrementScore (); // decrement decTimerFlag = 1; // set decTimer flag } } //PL = ""; PL = PL + " decTimer: " + decTimerFlag; Serial.println(PL) ; if (refreshFlag > 0) refreshBoard (); // refresh if a score changed } // -------------------------------------------------------------------- void decrementScore () // decrement score { //Serial.println("decrementScore"); closedPeriod = currTime - closedTime [i]; // calculate switch-closed period //PL = ""; PL = PL + i + " scoreStatus: " + scoreStatus [i]; Serial.println(PL) ; //PL = ""; PL = PL + i + " closedPeriod: " + closedPeriod; Serial.println(PL) ; // If switch is closed and closedPeriod >= delay period OR // If score is decremented and closedPeriod >= repeat period...then decrement if ((scoreStatus [i] == 1 && closedPeriod >= delayPeriod) || (scoreStatus [i] == 2 && closedPeriod >= repeatPeriod)) { // PL = ""; PL = PL + i + " score: " + score [i]; Serial.println(PL); if (score [i] > 0) score [i] -= 1; // decrement score by 1 // PL = ""; PL = PL + i + " score: " + score [i]; Serial.println(PL); scoreStatus [i] = 2; // score decremented refreshFlag = 1; // set refresh flag closedTime [i] = currTime; // reset the switch-closed time } } // -------------------------------------------------------------------- void refreshBoard () // refresh entire display { //Serial.println("refreshBoard"); dmd.clearScreen( true ); // clear display first for (j = 0; j <= 5; j = j + 2) // display scores in pairs { displayPair (); } } // -------------------------------------------------------------------- void displayPair () // display a pair of scores { int scoreA = score [j]; // get a pair of scores int scoreB = score [j + 1]; char scoreA1 = scoreA / 10; // breakdown score to individual digits char scoreA2 = scoreA - (scoreA1 * 10); char scoreB1 = scoreB / 10; char scoreB2 = scoreB - (scoreB1 * 10); if (scoreA1 == 0) scoreA1 = 32; // if leading zero, replace with ASCII blank else scoreA1 += 48; // else add offset for ASCII zero scoreA2 += 48; // add offset for ASCII zero if (scoreB1 == 0) scoreB1 = 32; // if leading zero, replace with ASCII blank else scoreB1 += 48; // else add offset for ASCII zero
scoreB2 += 48; // add offset for ASCII zero
k = 32 - (j * 8); // k is the y coordinate (0, 16 o
r 32) dmd.drawChar( 0, k, scoreA1, GRAPHICS_NORMAL ); // display the scores dmd.drawChar( 12, k, scoreA2, GRAPHICS_NORMAL ); dmd.drawChar( 42, k, scoreB1, GRAPHICS_NORMAL ); dmd.drawChar( 54, k, scoreB2, GRAPHICS_NORMAL ); } // -------------------------------------------------------------------- void loop () // main loop { if (interruptFlag > 0) checkSwitches (); // check switches after an interr upt if (decTimerFlag > 0) decTimer.check(); // check for decrementing }