Go Down

Topic: Teensy and LED Matrix multiplexor (MAX7221) (Read 3849 times) previous topic - next topic

transfinite

I've been using this playground code 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

Coding Badly


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

Or this?
http://www.pjrc.com/teensy/td_libs_Matrix.html

transfinite

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 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

transfinite

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

transfinite

This is BroHogan's code from the playground http://www.arduino.cc/playground/Main/MultiplexMAX72xx modified to use the TimerOne library 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
}


Coding Badly


Go Up