Pages: [1]   Go Down
Author Topic: MAX6921 - need help  (Read 1478 times)
0 Members and 1 Guest are viewing this topic.
Sweden
Offline Offline
Full Member
***
Karma: 1
Posts: 185
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi!

I am trying to get MAX6921 to drive my display.
http://datasheets.maximintegrated.com/en/ds/MAX6921-MAX6931.pdf

The segments is hooked up to OUT0-OUT6. Digits is connected to OUT7-OUT14.

From datasheet:
The MAX6921/MAX6931 are normally written using the following sequence:
1) Take CLK low.
2) Clock 20 bits of data in order D19 first to D0 last into DIN, observing the data setup and hold times.
3) Load the 20 output latches with a falling edge on LOAD.
LOAD can be high or low during a transmission. If LOAD is high, then the data shifted into the shift register at DIN appear at the OUT0 to OUT19 outputs.

I have tried to use shiftout and a self made "shiftout" funtion.
 
The output seems a bit random to me (digits lights up but not in the way I want smiley )

Here is one of my code examples:

Code:
     byte dummy=0; //Just to fill out the upper 4 bits
     byte digit=1;     // Try to lit one digit

     digitalWrite(clockPin, LOW);
     digitalWrite(loadPin, LOW);
     shiftOut(dataPin, clockPin, MSBFIRST, dummy);
     shiftOut(dataPin, clockPin, MSBFIRST, digit);
     shiftOut(dataPin, clockPin, MSBFIRST, segFont[2]);   // segFont is a byte
 
     digitalWrite(loadPin, HIGH);       

Example 2:

Code:
void send_word(long data)
{
   digitalWrite(clockPin, LOW);
   digitalWrite(loadPin, LOW);

   for(byte i=0; i<20; i++)
   {
         if (data & (1 << i))
    {
      digitalWrite(dataPin, HIGH);
    }
    else
    {
      digitalWrite(dataPin, LOW);     
    }
      digitalWrite(clockPin, HIGH);
      digitalWrite(clockPin, LOW);
   }
   digitalWrite(loadPin, HIGH);
}


I really would like to have some working Arduino code. I have looked at the code from Adafruits "Ice Tube Clock" but do not understand it.

/Olof
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 145
Posts: 5469
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

3) Load the 20 output latches with a falling edge on LOAD.

You seem to have this pin backwards...

Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Sweden
Offline Offline
Full Member
***
Karma: 1
Posts: 185
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Fungus, thanks for the reply.

I do not understand what "Load the 20 output latches with a falling edge on LOAD" means.
I thought that was bringing load pin LOW before shifting in the 20 bits?

/Olof
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 145
Posts: 5469
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Fungus, thanks for the reply.

I do not understand what "Load the 20 output latches with a falling edge on LOAD" means.
I thought that was bringing load pin LOW before shifting in the 20 bits?

No, it means the data is latched when load goes from high to low.

So:
1) Transfer your data to the chip
2) Make LOAD pin go HIGH then LOW to latch the data
Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A couple possibilities:

1) I didn't spend enough time to see how the device does with 20+ pulses - I think it takes the last twenty. You may want to investigate into that.
2) pulse width: the device is fairly slow so you want to make sure that there is sufficient delay there.

I would rewrite your code as such:

Code:
void send_word(long data)
{
   digitalWrite(clockPin, LOW);
   digitalWrite(loadPin, LOW);

   for(byte i=0; i<20; i++)
   {
      digitalWrite(clockPin, LOW); //data on rising edge

      if (data & (1 << i)) digitalWrite(dataPin, HIGH);
      else digitalWrite(dataPin, LOW);     

      digitalWrite(clockPin, HIGH);
   }

You may want to take a scope on the clk pin to make sure that it is close to 50%.
Logged

Sweden
Offline Offline
Full Member
***
Karma: 1
Posts: 185
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Now it works, thanks for the help smiley

This is a great forum!


I changed segments to OUT19-OUT13 and digits to OUT14-OUT16.

Code:
void RefreshIV18()
{
  long data=0;
  for (byte iDigit=1; iDigit<9;iDigit++)
  {
    data=0;
    data = (data << 8) + segFont[iDigit]; 
    data ^= (1 << 6+iDigit);
    digitalWrite(loadPin, LOW);

    for(byte i=0; i<20; i++)
    {
      digitalWrite(clockPin, LOW); //data on rising edge
      if (data & (1 << i)) digitalWrite(dataPin, HIGH);
      else digitalWrite(dataPin, LOW);     
      digitalWrite(clockPin, HIGH);
    }
    digitalWrite(loadPin, HIGH);
  }
}

/Olof
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 83
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

can you post your complete code
i would also like to use it if i may
Logged

Sweden
Offline Offline
Full Member
***
Karma: 1
Posts: 185
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi!

No problem, the function is part of my "IV-18 Clock" project (http://forum.arduino.cc/index.php?topic=140456.0).
I used the digitalWriteFast library but you can change digitalWriteFast to digitalWrite (or access the ports direct).

I copied and pasted the important part of my code.


Code:
#include <digitalWriteFast.h>

#define  dataPin  7
#define  clockPin  4
#define  loadPin  8


//A F B G E C D H
//19-12 SEG
const byte segFont[] =
{
  B00111111, B00000110, B01011011, B01001111, // 0123
  B01100110, B01101101, B01111100, B00000111, // 4567
  B01111111, B01100111, B01000000               // 89-
};

unsigned long nowMicros=0;
unsigned long ulRefreshcounter;
byte bDigit=0;
byte bDot=0;
int iDots=0;
byte bChars[10];


void setup()
{
  pinModeFast(loadPin, OUTPUT);
  pinModeFast(clockPin, OUTPUT);
  pinModeFast(dataPin, OUTPUT);

  //timetoIV18(hours,minutes,seconds);
  timetoIV18(10,10,10);
  setDots(1);  

}

void loop()
{
  nowMicros=micros();


  if ((nowMicros-ulRefreshcounter)>1000)
  {
    RefreshIV18();
    ulRefreshcounter=nowMicros;
  }
}

void RefreshIV18()
{
  // Need 20 bits variable  
  long data=0;
  //Refresh one digit for each call of RefreshIV18
  bDigit++;
  //Shift in 8 bits (segFont)
  //bChars is set with function timetoIV18
  data = (data << 8) + segFont[bChars[bDigit]];
  //Select position for digit.
  data ^= ((long)1 << 7+bDigit);
  //Set decimal dots
  //Stored in variable iDots
  if (iDots & (1 << (bDigit-1)))
  {  
    data ^= (1 << 7);
  }
  //Set loadPin low
  digitalWriteFast(loadPin, LOW);
  //Shiftin 20 bits
  for(byte i=0; i<20; i++)
  {
    //clockPin LOW
    //data on rising edge
    digitalWriteFast(clockPin, LOW);
    //datapin bit to 1 OR 0
    digitalWriteFast(dataPin, (bool)(data & ((long)1 << i)) );
    //Set clockPin HIGH
    digitalWriteFast(clockPin, HIGH);
  }
  //Done
  digitalWriteFast(loadPin, HIGH);
  //If digit = 9
  //Start from beginning with digit 1
  if (bDigit==9)
  {
    bDigit=0;
  }
}

void timetoIV18(byte h,byte m,byte s)
{
  if (h>9)
  {
    bChars[7]=h % 10;
    bChars[8]=h / 10;
  }
  else
  {
    bChars[8]=0;
    bChars[7]=h;
  }  

  bChars[6]=10;

  if (m>9)
  {
    bChars[4]=m % 10;
    bChars[5]=m / 10;
  }
  else
  {
    bChars[5]=0;
    bChars[4]=m;
  }  

  bChars[3]=10;

  if (s>9)
  {
    bChars[1]=s % 10;
    bChars[2]=s / 10;
  }
  else
  {
    bChars[2]=0;
    bChars[1]=s;
  }  
}

void setDots(byte bWhere)
{
  switch (bWhere)
  {
  case 0:
    //Ta bort på timmar och minuter
    iDots &= ~((1 << (5-1)) | (1 << (4-1)));
    iDots &= ~( (1 << (8-1)) | (1 << (7-1)));
    break;
  case 1:
    //Hours
    iDots |= (1 << (8-1));
    iDots |= (1 << (7-1));
    iDots &= ~((1 << (5-1)) | (1 << (4-1)));
    break;
  case 2:
    //Minutes
    iDots |= (1 << (5-1));
    iDots |= (1 << (4-1));
    iDots &= ~( (1 << (8-1)) | (1 << (7-1)));
    break;    
  case 3:
    //Alarm
    iDots |= (1 << (9-1));
    break;          
  case 4:
    //No alarm
    iDots &= ~( (1 << (9-1)) );
    break;
  }  
}
« Last Edit: August 15, 2013, 12:55:35 pm by olof_n » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I did a blog post about this very thing, and I used a portion of your code! Do you have a website or any way I can credit you? the blog is here: http://doayee.co.uk/vfd-tube-clock/ smiley hope this helps!
Logged

Pages: [1]   Go Up
Jump to: