0% 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.

Uploaded by

popescucv
Copyright
© © All Rights Reserved
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% 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.

Uploaded by

popescucv
Copyright
© © All Rights Reserved
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
}

You might also like