I have adapted a sketch for a stopwatch using an I2C 16 x 2 LCD display but would like something bigger. I thought about a 32 x 8 LED matrix but can't find a sketch for a stopwatch. Has anyone done this already, or can anyone offer any help as to how to display a stopwatch on an LED matrix.
If a user is asking for pretty general help I look up his profile.
Joined in 2018, 1h read time, 25 topics created.
hm well my assumption is that you seem to be on a very basic level about programming-knowledge.
like any program a stop-watch has multiple functional parts
where each functional part can be coded on its own and then can be combined with other parts.
You wrote
Does this mean you have a stop-watch that displays the time on a 16 x 2 LCD up and running?
If yes: The next step is to write a test-program for the 32x8 LED-matrix.
If the test-program for the 32 x 8 LED-Matrix is running
the next step is to integrate the "display digits on 32 x 8 LED-Matrix-functionality in your stop-watch-code.
The propablity that there exists a library for 32 x 8 LED-matrix is pretty high.
From your former 25 threads with 64 posts you should now that it is essential to post a link to the datasheets of the components that you use.
As soon as you start to give more detailed informations the better the support will be.
Stefan,
Thank you for your reply and thank you for taking the time to look at my profile. Yes I have a stopwatch sketch up and running for a 16 x 2 LCD but have not yet purchased the 32 x 8 LED matrix as I didn't want to spend the money if I couldn't get it working.
I don't get a lot of time on Arduino, so yes my knowledge is limited. I will see about ordering what I need, get it tested and take it from there.
Steve
I have purchased an 8 x 32 LED MAX7219 matrix and have connected it up and can get it to display text no problem.
I have adapted a stopwatch sketch that works fine on a 16 x 2 LCD display. However when I connect up the LED matrix, it will only display two columns on the LHS of the display. Can anyone help me to get minutes, seconds and milliseconds to display on the LED Matrix. See below the code that I used.
/*
Stopwatch
Run stopwatch with arduino.
Code based on: http://danthompsonsblog.blogspot.com/2008/11/timecode-based-stopwatch.html
Coded by: arduinoprojects101.com
*/
// include the library code:
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CLK_PIN 13
#define DATA_PIN 11
#define CS_PIN 3
// Hardware SPI connection
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Arbitrary output pins
// MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
//int ledPin = 13; // LED connected to digital pin 13
int buttonPin = 2; // button on pin 2
int value = LOW; // previous value of the LED
int buttonState; // variable to store button state
int lastButtonState; // variable to store last button state
int blinking; // condition for blinking - timer is timing
int frameRate = 100; // the frame rate (frames per second) at which the stopwatch runs - Change to suit
long interval = (1000/frameRate); // blink interval
long previousMillis = 0; // variable to store last time LED was updated
long startTime; // start time for stop watch
long elapsedTime; // elapsed time for stop watch
int fractional; // variable used to store fractional part of Frames
int fractionalSecs; // variable used to store fractional part of Seconds
int fractionalMins; // variable used to store fractional part of Minutes
int elapsedFrames; // elapsed frames for stop watch
int elapsedSeconds; // elapsed seconds for stop watch
int elapsedMinutes; // elapsed Minutes for stop watch
char buf[10]; // string buffer for itoa function
void setup()
{
P.begin(); // intialise the LED Matrix.
//P.clear();
P.print("Test!");
delay (2000);
//pinMode(ledPin, OUTPUT); // sets the digital pin as output
pinMode(buttonPin, INPUT); // not really necessary, pins default to INPUT anyway
digitalWrite(buttonPin, HIGH); // turn on pullup resistors. Wire button so that press shorts pin to ground.
}
void loop(){
//digitalWrite(ledPin, LOW); // Initiate LED and Step Pin States
buttonState = digitalRead(buttonPin); // Check for button press, read the button state and store
// check for a high to low transition if true then found a new button press while clock is not running - start the clock
if (buttonState == LOW && lastButtonState == HIGH && blinking == false){
startTime = millis(); // store the start time
blinking = true; // turn on blinking while timing
delay(10); // short delay to debounce switch
lastButtonState = buttonState; // store buttonState in lastButtonState, to compare next time
}
// check for a high to low transition if true then found a new button press while clock is running - stop the clock and report
else if (buttonState == LOW && lastButtonState == HIGH && blinking == true){
blinking = false; // turn off blinking, all done timing
lastButtonState = buttonState; // store buttonState in lastButtonState, to compare next time
// Routine to report elapsed time
elapsedTime = millis() - startTime; // store elapsed time
elapsedMinutes = (elapsedTime / 60000L);
elapsedSeconds = (elapsedTime / 1000L); // divide by 1000 to convert to seconds - then cast to an int to print
elapsedFrames = (elapsedTime / interval); // divide by 100 to convert to 1/100 of a second - then cast to an int to print
fractional = (int)(elapsedFrames % frameRate); // use modulo operator to get fractional part of 100 Seconds
fractionalSecs = (int)(elapsedSeconds % 60L); // use modulo operator to get fractional part of 60 Seconds
fractionalMins = (int)(elapsedMinutes % 60L); // use modulo operator to get fractional part of 60 Minutes
//P.clear(); // clear the LDC
if (fractionalMins < 10){ // pad in leading zeros
P.print("0"); // add a zero
}
P.print(itoa(fractionalMins, buf, 10)); // convert the int to a string and print a fractional part of 60 Minutes to the LCD
P.print(":"); //print a colan.
if (fractionalSecs < 10){ // pad in leading zeros
P.print("0"); // add a zero
}
P.print(itoa(fractionalSecs, buf, 10)); // convert the int to a string and print a fractional part of 60 Seconds to the LCD
P.print(":"); //print a colan.
if (fractional < 10){ // pad in leading zeros
P.print("0"); // add a zero
}
P.print(itoa(fractional, buf, 10)); // convert the int to a string and print a fractional part of 25 Frames to the LCD
}
else{
lastButtonState = buttonState; // store buttonState in lastButtonState, to compare next time
}
// run commands at the specified time interval
// blink routine - blink the LED while timing
// check to see if it's time to blink the LED; that is, the difference
// between the current time and last time we blinked the LED is larger than
// the interval at which we want to blink the LED.
if ( (millis() - previousMillis > interval) ) {
if (blinking == true){
previousMillis = millis(); // remember the last time we blinked the LED
//digitalWrite(ledPin, HIGH); // Pulse the LED for Visual Feedback
elapsedTime = millis() - startTime; // store elapsed time
elapsedMinutes = (elapsedTime / 60000L); // divide by 60000 to convert to minutes - then cast to an int to print
elapsedSeconds = (elapsedTime / 1000L); // divide by 1000 to convert to seconds - then cast to an int to print
elapsedFrames = (elapsedTime / interval); // divide by 40 to convert to 1/25 of a second - then cast to an int to print
fractional = (int)(elapsedFrames % frameRate);// use modulo operator to get fractional part of 25 Frames
fractionalSecs = (int)(elapsedSeconds % 60L); // use modulo operator to get fractional part of 60 Seconds
fractionalMins = (int)(elapsedMinutes % 60L); // use modulo operator to get fractional part of 60 Minutes
//P.clear(); // clear the LDC
if (fractionalMins < 10){ // pad in leading zeros
P.print("0"); // add a zero
}
P.print(itoa(fractionalMins, buf, 10)); // convert the int to a string and print a fractional part of 60 Minutes to the LCD
P.print(":"); //print a colan.
if (fractionalSecs < 10){ // pad in leading zeros
P.print("0"); // add a zero
}
P.print(itoa(fractionalSecs, buf, 10)); // convert the int to a string and print a fractional part of 60 Seconds to the LCD
P.print(":"); //print a colan.
if (fractional < 10){ // pad in leading zeros
P.print("0"); // add a zero
}
P.print(itoa((fractional), buf, 10)); // convert the int to a string and print a fractional part of 25 Frames to the LCD
}
else{
//digitalWrite(ledPin, LOW); // turn off LED when not blinking
}
}
}
Thanks for getting back to me Stefan, when I load the sketch, then press the button to start, the count counts up very quickly ( I assume it's the milliseconds). When I press the button to stop the count, I get two digits showing at the left hand side of the LED matrix. I have tried other sample codes and the LED matrix is fully functional.
From what I can glean, I need to change the variables to strings then print the strings but I cannot print multiple strings in a single command in MD_Parola and if I print them separately, the screen clears before each command.
I can't see your LED matrix. So from this discription i'm unsure what you see on the LED-Matrix.
Just post what you expect to see as digits
and post what you is shown by the LED-matrix.
If you replace the itoa-functions by different fixed strings what do you see then?
It might be that each p.print starts printing new at the left most digit.
Just for debugging purposes to find out about this
the function delay() could be used (one of the rare cases where delay() is handy to use)
If you insert a delay(2000);
after each p.print this does what the name says
delay program-execution for 2000 milliseconds. which in this case means
show LED-matrix for two seconds after each print instead run through all p.prints
If this is the case the solution is to concenate all numbers into one string and do only one p.print
Me personal I prefer using the SafeString-library because it makes handling with strings easier. You smple assign bytes, integers, longs and even float-variables to the safestring by writing "=" or concenating them by "+="
here is a demo-code how safestrings can be used.
The demo includes some useful functions
#include <SafeString.h>
createSafeString(myDemo_SS, 32);
createSafeString(mySecondDemo_SS, 32);
unsigned long myCounter;
// if program starts printout the source-code filename etc. to the serial monitor
void PrintFileNameDateTime() {
Serial.println( F("Code running comes from file ") );
Serial.println(__FILE__);
Serial.print( F(" compiled ") );
Serial.print(__DATE__);
Serial.print( F(" ") );
Serial.println(__TIME__);
}
//useful function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &periodStartTime, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - periodStartTime >= TimePeriod )
{
periodStartTime = currentMillis; // set new expireTime
return true; // more time than TimePeriod) has elapsed since last time if-condition was true
}
else return false; // not expired
}
unsigned long MyTestTimer = 0; // variables MUST be of type unsigned long
const byte OnBoard_LED = 13; // Arduino-Uno Onboard-LED is IO-pin 13
// make onboard-LED blink to show: "program is running"
void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
static unsigned long MyBlinkTimer;
pinMode(IO_Pin, OUTPUT);
if ( TimePeriodIsOver(MyBlinkTimer,BlinkPeriod) ) {
digitalWrite(IO_Pin,!digitalRead(IO_Pin) );
}
}
void setup() {
Serial.begin(115200);
Serial.println( F("Setup-Start") );
PrintFileNameDateTime();
myCounter = 0;
myDemo_SS = "Hello world!";
}
void loop() {
BlinkHeartBeatLED(OnBoard_LED,500);
myCounter++;
// loop is running very fast counting up very fast
// but only once every 1234 milliseconds print
if ( TimePeriodIsOver(MyTestTimer,1234) ) {
mySecondDemo_SS = myDemo_SS; // assigning a SafeString to another SafeString
mySecondDemo_SS += " "; // append a SPACE
mySecondDemo_SS += myCounter; // append integer-number
Serial.println(mySecondDemo_SS);
}
}
you can install the SafeString-library through the library-manager of the Arduino-IDE
best regards Stefan
Thank you once again for taking the time to answer me, I will need to spend a bit of time trying to get my head around this, as you know my knowledge is limited. I will be away for the next week or so but will try all of your suggestions and see how I get on. What I am trying to achieve is a count up timer readout giving mm:ss:msmsms ie 00:00:000 then counting up, what I see is for example 56 in the left hand two columns and these are milliseconds. The digits are full size also, i will need to create smaller numbers.
Parola will print the c-string you pass it. If you give it another string, you will clear the previous one and display the new one. This is something you have already discovered.
So you need to build up your message in the c-string and the display the complete message instead of doing a sequence of .print statements. I would suggest that you learn about the sprintf() function. Something like
is what you need to get to. This will print the time in hh:mm:ss with leading zeros on the digits. If you read the documentation for sprintf it will make sense.
You can then .print charBuffer or use one of the animations.
I have managed to get the display operating the way I want using SafeString, the only issue is that the font is too wide! Is it possible to get a smaller font to display? I tried searching and I did find something but was not sure how to install it! It had a file SmallDigits.h from Max Banton but I don't know what to do with it. Thank you for your assistance in getting me this far, it is very much appreciated.
I have installed the MD_Parola library, one of the example sketches, Parola_Fonts, has the Parola_Fonts_data.h file attached. I did a search for Parola Fonts Library but nothing turned up in the manage libraries option. Is there a separate Parola_Fonts library?