ADDENDUM
In the above code, I tried putting Serial.println(micros()) in the screenUpdate() loop, but I git a very confusing results in which the time displayed seemed to increase and then decrease randomly. I did not understand why. Has it got to do something with ISRs? Sorry for the apparently clumsy question.
I executed the following code (from the same book) out, which includes a MAX7219 driver (with the usual setup) and creates scrollable text. It worked perfectly well. And I just want to understand how this ISR and multiplexing go together, and how do we make sure the frequency is appropriate. More of an academic question rather than a practical one.
#include <avr/pgmspace.h>
#include <TimerOne.h>
int DataPin = 2; // Pin 1 on MAX
int LoadPin = 3; // Pin 12 on MAX
int ClockPin = 4; // Pin 13 on MAX
byte buffer[8];
#define SCAN_LIMIT_REG 0x0B
#define DECODE_MODE_REG 0x09
#define SHUTDOWN_REG 0x0C
#define INTENSITY_REG 0x0A
static byte font[][8] PROGMEM = {
// The printable ASCII characters only (32-126)
}
void clearDisplay() {
for (byte x=0; x<8; x++) {
buffer[x] = B00000000;
}
screenUpdate();
}
void initMAX7219() {
pinMode(DataPin, OUTPUT);
pinMode(LoadPin, OUTPUT);
pinMode(ClockPin, OUTPUT);
clearDisplay();
writeData(SCAN_LIMIT_REG, B00000111); // scan limit set to 0:7
writeData(DECODE_MODE_REG, B00000000); // decode mode off
writeData(SHUTDOWN_REG, B00000001); // Set shutdown register to normal operation
intensity(15); // Values 0 to 15 only (4 bit)
}
void intensity(int intensity) {
writeData(INTENSITY_REG, intensity); //B0001010 is the Intensity Register
}
void writeData(byte msb, byte lsb) {
digitalWrite(LoadPin, LOW); // set loadpin ready to receive data
shiftOut(DataPin, ClockPin, MSBFIRST, (msb));
shiftOut(DataPin, ClockPin, MSBFIRST, (lsb));
digitalWrite(LoadPin, HIGH); // latch the data
}
void scroll(char myString[], int rate) {
byte firstChrRow, secondChrRow;
byte ledOutput;
byte chrIndex = 0; // Initialise the string position index
byte Char1, Char2;
byte scrollBit = 0;
byte strLength = 0;
unsigned long time;
unsigned long counter;
while (myString[strLength]) { // Increment count till we reach the end of the string
strLength++;}
counter = millis();
while (chrIndex < (strLength)) {
time = millis();
if (time > (counter + rate)) {
Char1 = constrain(myString[chrIndex],32,126);
Char2 = constrain(myString[chrIndex+1],32,126);
for (byte y= 0; y<8; y++) {
firstChrRow = pgm_read_byte(&font[Char1 - 32][y]);
secondChrRow = (pgm_read_byte(&font[Char2 - 32][y])) << 1
ledOutput = (firstChrRow << scrollBit)
| (secondChrRow >> (8 - scrollBit) );
buffer[y] = ledOutput;
}
scrollBit++;
if (scrollBit > 6) {
scrollBit = 0;
chrIndex++;
}
counter = millis();
}
}
}
void screenUpdate() {
for (byte row = 0; row < 8; row++) {
writeData(row+1, buffer[row]);
}
}
void setup() {
initMAX7219();
Timer1.initialize(10000); // initialize timer1 and set interrupt period
Timer1.attachInterrupt(screenUpdate);
Serial.begin(9600);
}
void loop() {
clearDisplay();
scroll(" BEGINNING ARDUINO ", 45);
scroll(" Chapter 7 - LED Displays ", 45);
scroll(" HELLO WORLD!!! :) ", 45);
}