I am working with the display max7219 to driver 8 digits display and when doing a simple counter, the displays jumps for example from 5 to 7 or 1 to 3 . Could not find any pattern.
This is my code
#define MAX7219_DIN 4
#define MAX7219_CS 3
#define MAX7219_CLK 2
int seg=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() {
initialise();
output(0x0f, 0x00); //not test mode
output(0x0c,0x01); // normal operation
output(0x09,0xff); // code B decode, ie regular numbers
output (0x0b,0x01); // turn on just 2 digits
}
void loop() {
seg++;
if (seg>99)
seg=0;
show_digits();
delay(1000);
}
void show_digits()
{
int u,t;
u=seg%10;
t=(seg/10)%10;
output (0x01,u); // show units in digit 1
output (0x02,t); // show tens in digit 2
}
#include <SPI.h>
/*
Arduino pins MAX7219 pins
SS 10 LOAD 12
MOSI 11 DIN 1
MISO 12 No Connection
SCK 13 CLK 13
*/
unsigned long TIME = 500ul;
char mode;
unsigned long timer1;
byte dp = 0;
unsigned long lastmillis = 0;
unsigned long i = 0;
//unsigned long nbr = 99999999ul; //(8 digits) largest number before overflow
unsigned long nbr = 9999999ul; //(7 digits) largest number before overflow
//7219 registers Register addresses
const byte MAX7219_REG_NOOP = 0x0;
// codes 1 to 8 are the digit positions 1(LSD) to 8(MSD)
const byte MAX7219_REG_DECODEMODE = 0x9;
const byte MAX7219_REG_INTENSITY = 0xA;
const byte MAX7219_REG_SCANLIMIT = 0xB;
const byte MAX7219_REG_SHUTDOWN = 0xC;
const byte MAX7219_REG_DISPLAYTEST = 0xF;
//****************************************************************
void setup ()
{
Serial.begin(9600);
pinMode (10, OUTPUT); //set up SS pin 10
digitalWrite(10, HIGH); //disable the 7219
pinMode ( 2, OUTPUT);
//SPI stuff
SPI.begin ();
clear7219();
} // end of setup()
//======================== END OF setup ==========================
void loop ()
{
//lets do some counting
if (millis() - timer1 >= TIME)
{
timer1 = millis();
i++;
displayNumber(i); //display the new number
}
} //END of loop()
//================================================================
// function to display up to eight digits on a 7-segment display
void displayNumber( unsigned long myNumber)
{
unsigned long number = myNumber;
for (byte digit = 1; digit < 9; digit++)
{
byte character = number % 10; // get the value of the rightmost decade
//replace leadings 0s with blanks
if (number == 0 && digit > 0)
{
character = 0xF; //value needed to blank a 7221 digit
}
//turn on the decimal point to act as a comma if number is > 999 or >999999
if ((digit == 7 && myNumber > 999999) || (digit == 4 && myNumber > 999))
{
//add a dp
character |= 0b10000000;
}
//if we have overflowed the maximum count turn on all the dp to indicate this
if (myNumber >= nbr)
{
// this adds the dp at overflow
character |= 0b10000000;
}
sendByte (9 - digit, character);
number = number / 10; //remove the LSD for the next iteration
}
} //End of displayNumber()
//================================================================
// Clear the bubble display
void clear7219()
{
//SPI.setBitOrder(MSBFIRST); // MAX7219 requires most signifigant bit first
sendByte (MAX7219_REG_SCANLIMIT, 7); // show 8 digits zero relative
//Change next line to 0xFF from 0x7F if you want all positions to display a number
sendByte (MAX7219_REG_DECODEMODE, 0xFF); // in the MSD use bit patterns not digits
sendByte (MAX7219_REG_DISPLAYTEST, 0); // no display test
sendByte (MAX7219_REG_INTENSITY, 0x9); // character intensity: range: 0 to 15
sendByte (MAX7219_REG_SHUTDOWN, 1); // not in shutdown mode (ie. start it up)
i = 0UL; // clear the digits. Leading 0s will be blanked.
displayNumber(i);
} //End of clear7219()
//================================================================
//write a byte to the 7219 register in question
void sendByte (const byte reg, const byte data)
{
digitalWrite (SS, LOW); //enable 7219
SPI.transfer (reg); //select the 7219 register
SPI.transfer (data); //send the data for this register
digitalWrite (SS, HIGH); //disable 7219
} //End of sendbyte()
//================================================================
And remember the MAX7219 doesn't use the conventional bit position to segment correspondece.
While most seven segments displays are based in the segments sorted as Dp|g|f|e|d|c|b|a, sent MSb or LSb depending of the display controller, the MAX7219 expects the segments to be sent in this sequence: Dp|a|b|c|d|e|f|g MSb. Good reason for a library or oneself to loose the decimal point.
I would. That library calls pinMode() and digitalWrite() in the constructor where there is no guarantee the hardware has been properly initialized and/or will be changed by the Arduino framework. Those calls need to be moved to a .begin() method.
when you post a link and/or a datasheet of what you have available we can check how to handle them, because usually we see 7 segments and a decimal point per digit...
Then its straight forward. Use print for the positions 0..3 and set digit for L1 L2 L3. You might need to experiment which bitmap needs to send but basically you can use the same functions as in the older LedControl.