Arduino Forum

Using Arduino => Microcontrollers => Topic started by: transfinite on Dec 28, 2011, 11:08 pm

Title: Teensy and LED Matrix multiplexor (MAX7221)
Post by: transfinite on Dec 28, 2011, 11:08 pm
I've been using this playground code  http://www.arduino.cc/playground/Main/MultiplexMAX72xx (http://www.arduino.cc/playground/Main/MultiplexMAX72xx) for a while that uses 2 MAX7221's to control a red/green 8x8 LED matrix.  And it works well on my Diecimilias.

Today, I tried to use it on a teensy 2.0 (http://www.pjrc.com/teensy/teensyduino.html) and I cannot get it to work at all.  I think the ISR is causing problems.  Does the teensy handle interrupts differently?

Thanks,

-transfinite
Title: Re: Teensy and LED Matrix multiplexor (MAX7221)
Post by: Coding Badly on Dec 28, 2011, 11:13 pm

Does this help?
http://www.pjrc.com/teensy/td_libs_LedControl.html

Or this?
http://www.pjrc.com/teensy/td_libs_Matrix.html
Title: Re: Teensy and LED Matrix multiplexor (MAX7221)
Post by: transfinite on Dec 29, 2011, 12:48 am
I had already checked those pages, but just to verify my wiring, I tried the first example on http://www.pjrc.com/teensy/td_libs_Matrix.html (http://www.pjrc.com/teensy/td_libs_Matrix.html) and it does work.  No interrupts to worry about there.  Of course, I'm only seeing one color with that example.  That's the point of the interrupts in the playground example- to be able to set red or green or both.

I've tried changing the ISR_FREQ but still no joy.

-transfinite
Title: Re: Teensy and LED Matrix multiplexor (MAX7221)
Post by: transfinite on Dec 29, 2011, 06:46 am
It seems the teensy 2.0 does not play well with timer2.  I finally got it to work when I substituted the timer2 calls with timer1 (using the TimerOne library).  I'll post the working code here tomorrow.

-transfinite
Title: Re: Teensy and LED Matrix multiplexor (MAX7221)
Post by: transfinite on Dec 29, 2011, 11:22 pm
This is BroHogan's code from the playground http://www.arduino.cc/playground/Main/MultiplexMAX72xx (http://www.arduino.cc/playground/Main/MultiplexMAX72xx) modified to use the TimerOne library http://arduino.cc/playground/Code/Timer1 (http://arduino.cc/playground/Code/Timer1) .  Thanks to BroHogan for commenting the code well enough to make it easy to transition from Timer2 to Timer1. 

Note that using TimerOne breaks analogWrite() for digital pins 9 and 10 on Arduino.

Code: [Select]

// http://www.arduino.cc/playground/Main/MultiplexMAX72xx

/* RG Matrix Example   v.2 8/1/08  BroHogan
* Demos 2 color 8x8 matrix driven by 2 MAX7821's
*/

// 12/29/2011 transfinite modified to use TimerOne

#include "WProgram.h"                   // needed to compile with Rel. 0013 WHY?!
#include "LedControl.h"                 // to drive the matrix
#include <TimerOne.h>

// #define ISR_FREQ 210     //190=650Hz    // Sets the speed of the ISR - LOWER IS FASTER

// prescaler is /128 -  125,000/ISR_FREQ+1 (i.e 249=500Hz, 190=650Hz)
// Tweaked depending on the overhead in the ISR & and other factors in the sketch
// Display will be slow if too FAST. Sketch will hang on delay() if way too fast!

#define T1FREQ 1538     // 1538 ms = 650Hz

#define GREEN 0                         // The address of the MAX7221 for the green leds
#define RED 1                           // The address of the MAX7221 for the red leds
int maxInShutdown=GREEN;                // tells which MAX7221 is currently off
// unsigned long ISRTime;                   // DEBUG to test how long in ISR

// LedControl lc=LedControl(10,9,8,2); // pins 10=DataIn, 9=CLK, 8=LOAD + 2 MAX7221s
LedControl lc=LedControl(10,9,5,2); // pins 10=DataIn, 9=CLK, 5=LOAD + 2 MAX7221s

void setup() {
  lc.setIntensity(GREEN,15);            // 0 = dim, 15 = full brightness
  lc.setIntensity(RED,12);              // red needs less brightness
  // setISRtimer();                        // setup the timer
  // startISR();                           // start the timer to toggle shutdown
  Timer1.initialize(T1FREQ); // set a timer of length 1538 microseconds (or 650Hz)
  Timer1.attachInterrupt( timerIsr ); // attach the service routine here
}

void loop() {
  // Simple demo, but gives 2 colors a pretty good workout
  SkipRows();
  delay(1000);
  ClearMatrix();
  delay(500);
}

/////////////////////////////ISR Timer Functions ///////////////////////////
// ISR(TIMER2_COMPA_vect) {  //This ISR toggles shutdown between the 2MAX7221's
void timerIsr() {
  if(maxInShutdown==RED){
    lc.shutdown(GREEN,true);  // The order here is critical - Shutdown first!
    lc.shutdown(RED,false);   // . . . Then restart the other.
    maxInShutdown=GREEN;
  }
  else {
    lc.shutdown(RED,true);
    lc.shutdown(GREEN,false);
    maxInShutdown=RED;
  }

void startISR(){  // Starts the ISR
  Timer1.resume();
}

void stopISR(){    // Stops the ISR
  Timer1.stop();
}

/*
void setISRtimer(){  // setup ISR timer controling toggleing
  TCCR2A = 0x02;                        // WGM22=0 + WGM21=1 + WGM20=0 = Mode2 (CTC)
  TCCR2B = 0x05;                // CS22=1 + CS21=0 + CS20=1 = /128 prescaler (125kHz)
  TCNT2 = 0;                            // clear counter
  OCR2A = ISR_FREQ;                     // set TOP (divisor) - see #define
}

void startISR(){  // Starts the ISR
  TCNT2 = 0;                            // clear counter (needed here also)
  TIMSK2|=(1<<OCIE2A);                  // set interrupts=enabled (calls ISR(TIMER2_COMPA_vect)
}

void stopISR(){    // Stops the ISR
  TIMSK2&=~(1<<OCIE2A);                  // disable interrupts
}
*/

//////////////////////// simple LED display routine /////////////////////////////
void SkipRows() { // 1st pass alternates green & red, 2nd adds green to red making orange
  byte greenOn = true;                  // flag for lighting green for orange
  for(int row=0;row<8;row++) {
    for(int col=0;col<8;col++) {
      if (greenOn == true) SetLed(GREEN,row,col,true);
      else SetLed(RED,row,col,true);
      greenOn = !greenOn;
    }
  }
  delay(500);                           // only so you can see the first pass
  greenOn = !greenOn;
  for(int row=0;row<8;row++) {
    for(int col=0;col<8;col++) {
      delay(4);                         // only so you can see the update
      if (greenOn == true) SetLed(GREEN,row,col,true);
      greenOn = !greenOn;
    }
  }
}

/////////   Wrappers for LedControl functions . . . //////////
void SetLed(byte Color, byte Row,byte Col, byte State){
  stopISR();            // disable interrupts - stop toggling shutdown when updating
  lc.setLed(Color,Row,Col,State);
  startISR();           // enable interrupts again
}

void SetRow(byte Color, byte Row, byte State){
  stopISR();            // disable interrupts - stop toggling shutdown when updating
  lc.setRow(Color,Row,State);
  startISR();           // enable interrupts again
}

void SetColumn(byte Color, byte Col, byte State){
  stopISR();            // disable interrupts - stop toggling shutdown when updating
  lc.setColumn(Color,Col,State);
  startISR();           // enable interrupts again
}

void ClearMatrix(){
  stopISR();            // disable interrupts - stop toggling shutdown when updating
  lc.clearDisplay(GREEN);
  lc.clearDisplay(RED);
  startISR();           // enable interrupts again
}

Title: Re: Teensy and LED Matrix multiplexor (MAX7221)
Post by: Coding Badly on Dec 29, 2011, 11:43 pm

Thank you for the follow-up.