MAX7219 Clock

Hey!

I have been trying to build a clock with the max7219 chip with this code.

My aim is to make it count much faster then a normal clock, but even with the delay(1) it counts at around 0,5s/digit, is there a way to make it faster?

I assume something is wrong at the output part but I am not sure what.

Note the code is not ready, just a sketch, and the minutes and hours part is missing.

LEDclock.ino (1.71 KB)

#define MAX7219_DIN 10
#define MAX7219_CS  9
#define MAX7219_CLK 12

int max9 = 9;     
int max6 = 5;
int max4 = 4;
int max2 = 2;
int s5 = 0;       
int s9 = 0;
int m5 = 0;
int m9 = 0;
int h2 = 0;
int h4 = 0;

void initialise()
{
  digitalWrite(MAX7219_CS, HIGH);
  pinMode(MAX7219_DIN, OUTPUT);
  pinMode(MAX7219_CS, OUTPUT);
  pinMode(MAX7219_CLK, OUTPUT);
}

void output(byte address, byte data)
{
  digitalWrite(MAX7219_CS, LOW);
  shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, address);
  shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, data);
  digitalWrite(MAX7219_CS, HIGH);
  
}



void setup() {
  // put your setup code here, to run once:
  output(0x0c, 0x01); //shutdown register - normal operation
  output(0x0b, 0x07); //scan limit register - display digits 0 thru 7
  output(0x0a, 0x0f); //intensity register - max brightness
  output(0x09, 0xff); //decode mode register - CodeB decode all digits

}

void loop() {
  // put your main code here, to run repeatedly:
   if (s9 < max9) { s9++; }
   else {s9 = 0; s5++;}
   
   if (s5 > max6){s5 = 0;}
   //if (s5 = 0){m9++;}
   
   /*if (m9 = max9){m9 = 0;}
   if (m9=0){m5++;}
   
   if (m5 = max6){m5 = 0;}
   if (m5=0){h4++;}
   
   if (h4 = max4){h4 = 0;}
   if (h4=0){h2++;}
   
   if ((h2 = 2) && (h4 = 4) && (m5 = 5) && (m9= 9) && (s5= 5) && (s9= 9)) {h2 = 0; h4 = 0; m5 = 0; m9= 0; s5= 0; s9= 0;}*/

  
    initialise();
  output(0x0f, 0x00); //display test register - test mode off
  output(0x0a, 0x0f); //intensity register - max brightness
  output(0x09, 0xff); //decode mode register - CodeB decode all digits
  output(0x06, h2);
  output(0x05, h4);
  output(0x04, m5);
  output(0x03, m9);
  output(0x02, s5);
  output(0x01, s9); //digit 0 (rightmost digit) data
   delay (1);




}
 if (m5 = max6)

Oops

AWOL:

 if (m5 = max6)

Oops

That code is commented out anyway…

But shouldn’t this code be in setup() rather than loop()?

  initialise();
  output(0x0f, 0x00); //display test register - test mode off
  output(0x0a, 0x0f); //intensity register - max brightness
  output(0x09, 0xff); //decode mode register - CodeB decode all digits

I know, but it is going to trip someone base-over-apex when it is uncommented. :smiley:

Thanks for the replays. I tried to move that part to the setup, but it doesn't seem to speed up the count :confused:

I also tried disabling digit decoding but it didn't help neither.

But! I managed to speed it up significantly by removing output 6-3 in the loops, but as I would need them this is no help. Maybe this is the "max speed" of the chip for 6 outputs?

kraszadam:
Thanks for the replays. I tried to move that part to the setup, but it doesn't seem to speed up the count :confused:

I also tried disabling digit decoding but it didn't help neither.

But! I managed to speed it up significantly by removing output 6-3 in the loops, but as I would need them this is no help. Maybe this is the "max speed" of the chip for 6 outputs?

Even with that code in the wrong place, the code in loop() cannot be taking 0.5s to execute. More like 0.5ms.

The max chip is not slowing the Arduino down. It can't do that.

What happens if you change the delay(1) to delay(1000)?

If you want it faster, change this to use SPI.transfer:

[color=#222222]void output(byte address, byte data)[/color][color=#222222][/color]
[color=#222222]{[/color][color=#222222][/color]
[color=#222222]  digitalWrite(MAX7219_CS, LOW);[/color][color=#222222][/color]
[color=#222222]  shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, address);[/color][color=#222222][/color]
[color=#222222]  shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, data);[/color][color=#222222][/color]
[color=#222222]  digitalWrite(MAX7219_CS, HIGH);[/color][color=#222222][/color]
[color=#222222]  [/color][color=#222222][/color]
[color=#222222]}

clock from D13, data from D11, assume cs from 10:

[color=#222222]PORTB = PORTB & 0b11111011; // d10 low[/color]
[color=#222222]SPI.transfer(address);[/color]
[color=#222222]SPI.transfer(data);[/color]
[color=#222222]PORTB = PORTB | 0b00000100; // d10 high[/color]
[color=#222222]

With SPI defaults - MSBFIRST, Mode 0 and SPI clock at 4 MHz - will be a big time difference.
Import the SPI library. Sketch:Import Library:SPI

And fix all these
if (m9=0)

as has been pointed out.

You don't need all this in loop.

[color=#222222]    initialise();[/color][color=#222222][/color]
[color=#222222]  output(0x0f, 0x00); //display test register - test mode off[/color][color=#222222][/color]
[color=#222222]  output(0x0a, 0x0f); //intensity register - max brightness[/color][color=#222222][/color]
[color=#222222]  output(0x09, 0xff); //decode mode register - CodeB decode all digi[/color][color=#222222]ts[/color][color=#222222]
[/color]
[color=#222222]  output(0x06, h2);[/color][color=#222222][/color]
[color=#222222]  output(0x05, h4);[/color][color=#222222][/color]
[color=#222222]  output(0x04, m5);[/color][color=#222222][/color]
[color=#222222]  output(0x03, m9);[/color][color=#222222][/color]
[color=#222222]  output(0x02, s5);[/color][color=#222222][/color]
[color=#222222]  output(0x01, s9); //digit 0 (rightmost digit) data[/color][color=#222222][/color]
[color=#222222]   delay (1);[/color]
[color=#222222]

Freaking forum, adding all color /color nonsense. I'm too tired to fix it.

If you want it faster, change this to use SPI.transfer:

Bob, we all know shiftOut() is a hundred times slower than using SPI, but look at the OP's code. There's nothing there that should take any significant time to run. Yet the OP says the digits update every 0.5s. Something is wrong, and switching to SPI probably won't do much to fix whatever that is. If the OP's code was doing a couple of thousands of shiftOut() in loop(), would agree with you but the code only does less than 20 x shiftout().

PaulRB:
Even with that code in the wrong place, the code in loop() cannot be taking 0.5s to execute. More like 0.5ms.

The max chip is not slowing the Arduino down. It can't do that.

What happens if you change the delay(1) to delay(1000)?

Increasing the delay works, it'll slow down to to the correct speed. I removed the delay and
output(0x06, h2);
output(0x05, h4);
output(0x04, m5);
output(0x03, m9);
now it goes pretty fast, so I assume it's the source of the slowness.

kraszadam:
Increasing the delay works, it'll slow down to to the correct speed. I removed the delay and
output(0x06, h2);
output(0x05, h4);
output(0x04, m5);
output(0x03, m9);
now it goes pretty fast, so I assume it's the source of the slowness.

I don't understand what you are saying. What do you think is the source of the slowness?

PaulRB:
I don’t understand what you are saying. What do you think is the source of the slowness?

Sorry. So the original loop (with the slow count) was something like this:

void loop() {
// put your main code here, to run repeatedly:
if (s9 < max9) { s9++; }
else {s9 = 0; s5++;}

if (s5 > max6){s5 = 0;}

initialise();
output(0x06, h2);
output(0x05, h4);
output(0x04, m5);
output(0x03, m9);
output(0x02, s5);
output(0x01, s9); //digit 0 (rightmost digit) data
delay (10);
}

The new one:

void loop() {
// put your main code here, to run repeatedly:
if (s9 < max9) { s9++; }
else {s9 = 0; s5++;}
if (s5 > max6){s5 = 0;}
output(0x02, s5);
output(0x01, s9); //digit 0 (rightmost digit) data
}

Removing those extra outputs (output 6-3) speeded up the count a lot.
Maybe it doesn’t matter but I use a Galileo gen1.