1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

Max7221 x 3 cascading problem

Discussion in 'Oshonsoft' started by Superdat, Aug 1, 2016.

  1. Superdat

    Superdat Member

    Joined:
    Mar 3, 2015
    Messages:
    114
    Likes:
    3
    Hi
    I've built a pcb as part of a bigger project which has 3 x Max7221 driving 3 banks of 7 segment LEDs x 8 digits
    I.e. 8 digits per Max7221.
    It is being driven with an Atmega328P on a development board using SPI.
    I am using Oshonsoft AVR IDE and it's the latest version.
    This is the 1st time I've tried cascading and after fixing the pcb problems and figuring out how to cascade, I've got it working.
    However there is one problem, the LEDs on the 3rd bank flicker.
    I noticed that the flicker is the difference between the character displayed in bank 1 and its equivalent digit in bank 3.
    E.g. If bank 1 digit 1 is 7 and bank 3 digit 1 is 1, the top of the 7 (-) flickers in bank 3 digit 1
    If I make bank 1 digit 1 blank, the flicker in bank 3 stops.

    I thought it might be a timing problem and tried numerous variations but no success.
    It's not the pcb hardware because I strung 3 ready made 8 digit 7 segment LEDs together and I get the same problem.

    Any suggestions? Preferably based on some sort of logic :)
     
    Last edited: Aug 1, 2016
  2. Tony Stewart

    Tony Stewart Well-Known Member Most Helpful Member

    Joined:
    Aug 31, 2012
    Messages:
    3,151
    Likes:
    281
    Location:
    Richmond Hill , ON Canada near Toronto
    need schematic , timing details.
     
  3. Superdat

    Superdat Member

    Joined:
    Mar 3, 2015
    Messages:
    114
    Likes:
    3
    Schematic as per data sheet, As I said before I've tried numerous variations on timing. E.g. after each 16 bit word, after each digits set of data, separately and together, vaious durations, makes no difference.
    What I didn't mention is I'm using an 8Mhz crystal oscillator, but I've tried lower speeds and Int RC, again no difference so I don't think that's relevant.
    What exactly do you mean by "need timing details"?
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. throbscottle

    throbscottle Well-Known Member

    Joined:
    Feb 1, 2012
    Messages:
    1,781
    Likes:
    113
    Location:
    Nuneaton, Warwickshire, UK

    Assuming there's no strange stray connection between the bank 3 anodes and the bank 1 anodes...
    It might be worth your while to draw a timing diagram showing exactly when each segment is supposed to be on, based on working through the code you have written. Tedious (and in your case, a huge task) I know but you might have a magic face-palm moment!
    It might also be worth getting the code pulse through each digit at a speed you can actually see, this might reveal what's going on. You might find your bank 3 digits are being lit at the same time as bank 1 on every 23rd loop, or something along those lines. Impossible to spot at full speed, but obvious if it is happening at human speed.
     
  6. Tony Stewart

    Tony Stewart Well-Known Member Most Helpful Member

    Joined:
    Aug 31, 2012
    Messages:
    3,151
    Likes:
    281
    Location:
    Richmond Hill , ON Canada near Toronto
    Is NO DECODE mode being used?

    Bank sequence is 123...123...repeating
    problem is .. flicker on Bank 3 sometimes shows Bank1
    Can you determine exact flicker rate? Random ? Interleaved? relative to refresh rate?

    Sounds like a crosstalk issue. Does touching the digits alter the flickering?
     
  7. Superdat

    Superdat Member

    Joined:
    Mar 3, 2015
    Messages:
    114
    Likes:
    3
    Decode mode is being used. Flicker is maybe every 500Ms and very consistent. It's like there's an overlap of bank1 and bank3 but only bank 3 flickers.
    Can't say if it's Interleaved or not, I can't see anything in the Max7221 datasheet that allows you to change it. Once it's been latched the Max7221 seems to handle everything.
    So slowing down SPI data delivery as I think was suggested before won't achieve anything, if my understanding is correct.
    I've also swapped the 3 x Max7221 about to see if one was not working properly, same result.
    I've reduced the program down to Bank 1-3 and digit 1 only so not much to get in the way, I'll try some experiments with that.
    It can't be hardware because it does it on my pcb and 3 x cascaded 8 digit 7 segment displays (bought not made).
     
  8. Tony Stewart

    Tony Stewart Well-Known Member Most Helpful Member

    Joined:
    Aug 31, 2012
    Messages:
    3,151
    Likes:
    281
    Location:
    Richmond Hill , ON Canada near Toronto
    I can't see how to do it even if one tried. Is it possible to look at the data and addresses on a DSO with CS?
     
  9. Superdat

    Superdat Member

    Joined:
    Mar 3, 2015
    Messages:
    114
    Likes:
    3
    I've solved the problem!
    Seems I didn't understand how to send the cascade data well enough.
    I was trying to send data to one digit at a time. I should have send data to 3 digits in each column in one SPION/OFF block
    e.g. For simplicity I haven't shown address register data which goes before the digit data.
    Method that did not work well:
    SPIOn
    C1data
    SPIOFF
    SPIOn
    C2data
    NOP
    SPIOFF
    SPIOn
    C3data
    NOP
    NOP
    SPIOFF
    The method that works is:
    SPION
    C3data
    C2data
    C1data
    SPIOFF

    YaaHoo!
     
  10. JimB

    JimB Super Moderator Most Helpful Member

    Joined:
    Sep 11, 2004
    Messages:
    6,328
    Likes:
    585
    Location:
    Peterhead, Scotland
    ONLINE
    Nothing to beat that feeling of elation when you find the quick and easy way to do something, and it works far better than the hard way!

    Been there, done that, many times.

    JimB
     
  11. throbscottle

    throbscottle Well-Known Member

    Joined:
    Feb 1, 2012
    Messages:
    1,781
    Likes:
    113
    Location:
    Nuneaton, Warwickshire, UK
    Am I right in thinking you got confused by bit about no-op codes in the datasheet? I just read through it and it took me a minute to realise it refers to addressing a chip in isolation. Your second method just ripples the data through, which is what it says should happen, elsewhere in the sheet.
    Well done for getting there :)
     
  12. Superdat

    Superdat Member

    Joined:
    Mar 3, 2015
    Messages:
    114
    Likes:
    3
    Well I didn't get confused by the references to No-Op, this is how it suggests multiple Max7221/7219 should be addressed and that is exactly what their written example shows (N0-Op Register). This is how I programmed it.
    It isn't referring to single chips at this point, you can't cascade to a single chip.

    All data is loaded into a Load buffer while CS/Load is low, when CS goes high it is transferred into the buffer used to display the data and latched. So even if the MicroP is removed the LEDs continue to display data.
    Single chips are easy(ish) just send the digit address followed by its value (Decode Mode).
    Non decode is harder because each segment has to be selected so you have to work out the data value.
    If you send 32 bits (4 x 8 bits using SPI) to a single chip the 1st 16 bits (addr + data) get pushed out of the load buffer by the 2nd 16 bits. It is pushed out of the data out pin. When CS goes high the 2nd set of data is transferred to the LEDs buffer. The term "ripples through"sounds nice but doesn't really explain what's happening.

    This all seems incredibly obvious now but it's taken me quite some time to figure it out.
    Once you get it clear in your mind it all makes sense, hence the solution!!
    Data sheets aren't IMO the most friendly documents I've ever seen.

    Must say I'm pretty pleased with myself having gone from being totally confused by the data sheet (some time ago) to
    being able to explain what parts of it mean :) I won't claim enlightenment for all of the datasheet.
    Lessons now available for a fee ;-)

    Think I'll change my name to Super7SEGMan LOL
     
  13. throbscottle

    throbscottle Well-Known Member

    Joined:
    Feb 1, 2012
    Messages:
    1,781
    Likes:
    113
    Location:
    Nuneaton, Warwickshire, UK
    I meant a single chip within the cascade, Mr Super7SEGMan :)

    I agree about datasheets. You have to read them with care. A bit like reading man pages.
     
  14. Superdat

    Superdat Member

    Joined:
    Mar 3, 2015
    Messages:
    114
    Likes:
    3
    Yes it was a bit confusing using the method suggested which is data to one chip in the cascade only, and this method is what casued the flicker.
    There's a clue in the name of Man pages, Real Men only :)
    I think the main problem with data sheets is that the person writing them either:
    a. Understands exactly how it works and can't see any difficulty. To them it's totally obvious.
    b. doesn't fully understand what they are trying to explain.
    The result either way is a document that's difficult to understand especially when people just want a quick reference to make "it" go.
     
    Last edited: Mar 3, 2017
  15. Superdat

    Superdat Member

    Joined:
    Mar 3, 2015
    Messages:
    114
    Likes:
    3
    Follow up to above. The circuit works perfectly with one annoying "feature". At power on either all Segments show zero and stick on zero or only the first column of 2 x 8 7segs (outputs from 1 x 7221). If I powered off and waited until all LEDs had turned off, then powered on quickly, all 6 x 8 7segment displays worked as intended. Although the LEDs didn't work as expected, the rest of the circuit, temperature monitoring etc all worked OK. So it looked like the programming rather than the electronics. Who did the programming? Oh, it was me ;-)

    After a few hours of fiddling I made the following discovery:
    Both methods of addressing the 3 x 7221/7219 work i.e. 3 sequential commands or using No Op.
    Don't know what was different this time but no flicker.
    The method without No Op is much more compact, so I stayed with it.

    The fix was rediculously easy but I'm not sure why it was necessary.
    Test On x3, a small delay of 10ms followed by Test Off x 3, both after all the other Setup commands, just before loop:

    I also did some experiments with the setup commands e.g. Intensity, scan length, Normal mode On/Off. etc to see if they all needed x3 of each.

    They did, if you don't, the push out to the next 7221/7219 gets out of sync with odd results. Each 7221/7219 needs its own command

    Hope this helps someone else!
     
  16. granddad

    granddad Active Member

    Joined:
    Jan 18, 2015
    Messages:
    750
    Likes:
    75
    Location:
    Worcestershire UK
    Hi super... I understand your 'fiddling' I've been using 3 x 7921 +3 x 8x8 led matrix for a clock,( 4 digits and colon ) it took me hours of fiddling to get the two middle leds to flash for the colon... (PIC24 & C ) , I hope to 'pinch' two unused matrix columns to show seven seg seconds, or date .
     
  17. Superdat

    Superdat Member

    Joined:
    Mar 3, 2015
    Messages:
    114
    Likes:
    3
    Hi G
    I'm assuming 7921 is a typo? 7219 I hope. I would think 8x8 matrix are even more of challenge to visualise. I've not done much with 8x8 matrix, only a few proof of concept programs, but you've just given me a thought I have a couple of them :) I've done several 3/4 x 7 segs with DIY character sets though which is similar. Do you use "Lookup" to define what each row/column (depending which way up the array is mounted)? Bit of work needed to see what code does what, but then way easier to trouble shoot if things don't work out. You don't have to keep trying to visualise everything.
    n.b. "Super" is just my lazy way of getting the user name I want i.e. dat, it's not meant to imply any special ability.
     
  18. granddad

    granddad Active Member

    Joined:
    Jan 18, 2015
    Messages:
    750
    Likes:
    75
    Location:
    Worcestershire UK
    Typo ! Hi S. My sw (C) is that of a 4 year old, so what i post here is what i got to work , that's all :eek::) . http://www.electro-tech-online.com/threads/just-a-clock.149289/page-2#post-1281287

    One of several arrays ... this one for the time ....
    Code (text):

                                             
                               //------ digit Posiiton 1--|                     |--------digit 2------|
    unsigned int Time_frame[]={0x0600,0x0500,0x0400,0x0300,0x0800,0x0700,0x0200,0x0100,0X0800,0x0700,
    //--d2|----- GAP  ---------//------- D3----------------|      |------------- D4----------|
    0x0600,0x0500,0x0400,0x0300,0x0200,0x0100,0x0800,0x0700,0x0600,0x0500,0x0400,0x0300,0x0200,0x0100}; //
     
    several font characters.
    Code (text):

    // SMOOTH FONT
    unsigned char SM_font[]={0x3E,0x41,0x41,0x3E,    0x40,0x7F,0x42,0x00,  0x6E,0x49,0x49,0x72,
                            // ZERO                    ONE                   TWO          
                               0x3E,0x49,0x49,0x22,    0x7E,0x08,0x08,0x0F,  0x30,0x49,0x49,0x2F,
                           // THREE                   FOUR                   FIVE
                               0x30,0x49,0x49,0x3E,    0x7F,0x01,0x01,0x03,  0x36,0x49,0x49,0x36,
                            // SIX                     SEVEN                 EIGHT
                               0x3E,0x49,0x49,0x26,    0x00,0x7C,0x10,0x7C,  0x00,0x7C,0x08,0x7C,
                            // NINE                    'H'10                 'M'11
                               0x78,0x14,0x78,0x00,    0x62,0x14,0x08,0x7F,  0x00,0x00,0x00,0x00,
                            // 'A'12                    'K'13                 ' blank' 14
                               0x09,0x09,0x09,0x7F,    0x30,0x48,0x48,0x30,  0x70,0x08,0x08,0x70,
                            // 'F' 15                   'o'16                'n' 17
                               0x02,0x42,0x7F,0x02,    0x41,0x41,0x41,0x3E,  0x00,0x68,0x14,0x7C,
                            // 't' 18                  'C'19                 'R' 20
                              0x48,0x30,0x30,0x48,    0x41,0x41,0x41,0x41,  0x00,0x68,0x14,0x41};
                            // 'x' 21                  ''22                 ''23
     
    then fills frame with font for digits set positions.
    Code (text):

    void Load_dots(unsigned int position,unsigned char value, unsigned int *frame)
    {
        unsigned int dotp;
        int x;
        int Blank=0;
        value=value*4;
        if(position==1)dotp=0;
        if(position==2)dotp=7;
        if(position==3)dotp=14;
        if(position==4)dotp=19;
        if((position==4)&&(value==0x00)) Blank=1;
        if(C_Font==1) // Square font
        {
        for ( x = 0; x < 4 ; x++)
        {
          frame[dotp+x]=frame[dotp+x]&(0xFF00);
          if(!Blank)
          {
          frame[dotp+x]=frame[dotp+x]|(SQ_font[value+x]);
          }
        }
        }else{  // Smooth font
         for ( x = 0; x < 4 ; x++)
        {
          frame[dotp+x]=frame[dotp+x]&(0xFF00);
          if(!Blank)
          {
          frame[dotp+x]=frame[dotp+x]|(SM_font[value+x]);
           }
         }
       }
     }
     
    send to MAX chips.
    Code (text):


    void Send_dots(unsigned int  *frame)
    {
      int x;
      for ( x = 0; x <= 7; x++)
      {
      MAX_dot_bb(frame[x],0);    // send to MAXIM display chip...
      MAX_dot_bb(frame[x+8],0);    //
      MAX_dot_bb(frame[x+16],1);
      }
    }
     
    The BitBang.
    Code (text):

    void MAX_dot_bb(unsigned int test,int chip_load)
    {
    #define MAX_data LATBbits.LATB1
    #define MAX_clock LATBbits.LATB2
     
      unsigned int x ;
      MAX_load = 0;       // load MAX7219
      for ( x = 0; x <= 15 ; x++)
      {
      if (test & 0x8000) {
        MAX_data = 1;
      }else{
        MAX_data = 0;
      }
      Nop();
      MAX_clock = 1;       // Clock high
      Nop();
      MAX_clock = 0;       // low
      test = test << 1;
      }
      if(chip_load)
      {
      MAX_load = 1;  // load  MAX7219
      MAX_data = 0;  // drop data line
      }
    }
     
    The PIC24FV32KA302 @ 4MIPS has loads of spare memory so I want to do more with the date and alarm / sleep stuff .
     
    Last edited: Mar 3, 2017
  19. Superdat

    Superdat Member

    Joined:
    Mar 3, 2015
    Messages:
    114
    Likes:
    3
    Hi
    Didn't realise you were using C, Oshonsoft uses Basic so you're likely in the wrong forum. I can just about make out what a C program is doing, but I don't know enough to comment on your program.
     
  20. granddad

    granddad Active Member

    Joined:
    Jan 18, 2015
    Messages:
    750
    Likes:
    75
    Location:
    Worcestershire UK
    Hi Super, C is not that far removed from Basic , I found the move from basic with Z80 to asm harder, than going from basic to C . I commented because i saw your reference to a delay 10ms solving your problems, and I don't have any delays coded for data or initialization.....
     
  21. Superdat

    Superdat Member

    Joined:
    Mar 3, 2015
    Messages:
    114
    Likes:
    3
    Hi
    Well Basic has different flavours, e.g. Proton, GCB, MEL etc each one slighlty different. Sufficiently so that there is usual a forum for each.
    From what I've seen Basic is more similar to JAL or Arduino than it is to C. I've looked at C and find it quite a lot different, sufficiently so that I decided not to invest any time learning it. I''m not exactly in the first flush of youth and can't see any real benefit, Basic is fine for my needs.
    I can understand JAL and other Basics but I can't understand C
    So I don't agree with your comment.
    I have programmed with JAL, but I don't think giving someone a working example in JAL is very useful to someone who has a problem with any other type of language unless it is very generic and well commented.

    If an example is specific to an IC that's fair enough, but if it's in code, it needs to be well commented, otherwise IMO it's just showing off or laziness.

    Your example has some comment and I can figure out the general flow but I would not be able to readily convert it into Basic. To be cruel, why did you post it? It didn't help me and I can't help you. Neither of us had a problem.

    To answer my own question "Did you use Lookup?"
    Answer:
    "No because I'm using C, but I did use C's version of lookup tables."

    I'm sure you are very pleased with your program as am I with most of mine, but I don't think posting it here is very helpful.
    The program I wrote for this project includes routines for Max7221, ADC with thermisters, DHT22, Very Low Frequency PWM etc and it is enormous. Because of this I would not consider posting it. Bits of it maybe if someone had problems in that area and asked.

    The fix wasn't a delay of 10mS, it was turning Test ON then Test Off.
     

Share This Page