MSQ6441C Four Digit Stick Hex Display, Arduino Driver

Photo: Arduino driving MSQ6441C
Video: Hex Display with Arduino and MSQ6441C

For learning purposes I am programming my Uno to drive a hex display on a MSQ6441C Four Digit Stick Display. The display has no built in driver, so you must drive it by controlling voltages to anodes and cathodes. At first, I assumed this would be quite simple, but to be honest it was more challenging then I expected. Due to the common cathode design (reducing the number of pins required) you are not simply setting all the pins you want at once, but instead you must cycle through each of the cathodes, setting one digit at a time while blanking the others. So, you must take advantage of “flicker fusion” in human vision, similar to what is done in movies and animation.

At this point, I could either tie this functionality into a processor interrupt, so the Arduino could do other tasks as well, or set up an SPI communication line so that another microcontroller could send simple commands to the driver microcontroller. The Atmega328P of the Uno seems a bit overkill for just running an LED display, however.

Here is some code for those interested. Pins 1-12 on the display should be mapped into pins 2-13 on the Uno. The code could be improved by replacing those expensive digitalWrite calls with assignments directly into the digital pin registers. Also I have not gotten around to coding the dot segment yet.

/*
  Copyright 2020 Christopher Howard

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#define LP1 2
#define LP2 3
#define LP3 4
#define LP4 5
#define LP5 6
#define LP6 7
#define LP7 8
#define LP8 9
#define LP9 10
#define LP10 11
#define LP11 12
#define LP12 13

#define SA LP11
#define SB LP7
#define SC LP4
#define SD LP2
#define SE LP1
#define SF LP10
#define SG LP5
#define SDOT LP3

enum characters
  {
   ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT,
   NINE, ALPHA, BRAVO, CHARLIE, DELTA, ECHO, FOXTROT, BLANK
  };

enum digit {
	D_ONE, D_TWO, D_THREE, D_FOUR
};

void setup() {
	pinMode(2, OUTPUT);
	pinMode(3, OUTPUT);
	pinMode(4, OUTPUT);
	pinMode(5, OUTPUT);
	pinMode(6, OUTPUT);
	pinMode(7, OUTPUT);
	pinMode(8, OUTPUT);
	pinMode(9, OUTPUT);
	pinMode(10, OUTPUT);
	pinMode(11, OUTPUT);
	pinMode(12, OUTPUT);
	pinMode(13, OUTPUT);
}

void set_led_pins(byte ch, byte dig, bool point) {
	digitalWrite(LP1, LOW);
	digitalWrite(LP2, LOW);
	digitalWrite(LP3, LOW);
	digitalWrite(LP4, LOW);
	digitalWrite(LP5, LOW);
	digitalWrite(LP7, LOW);
	digitalWrite(LP10, LOW);
	digitalWrite(LP11, LOW);
	digitalWrite(LP6, HIGH);
	digitalWrite(LP8, HIGH);
	digitalWrite(LP9, HIGH);
	digitalWrite(LP12, HIGH);
	switch(dig) {
	case D_ONE:
		digitalWrite(LP12, LOW);
		break;
	case D_TWO:
		digitalWrite(LP9, LOW);
		break;
	case D_THREE:
		digitalWrite(LP8, LOW);
		break;
	case D_FOUR:
		digitalWrite(LP6, LOW);
		break;
	}
	switch(ch)
    {
    case BLANK :
      break;
    case ZERO :
      digitalWrite(SA, HIGH);
      digitalWrite(SB, HIGH);
      digitalWrite(SF, HIGH);
      digitalWrite(SC, HIGH);
      digitalWrite(SD, HIGH);
      digitalWrite(SE, HIGH);
      break;
    case ONE :
      digitalWrite(SB, HIGH);
      digitalWrite(SC, HIGH);
      break;
    case TWO :
      digitalWrite(SA, HIGH);
      digitalWrite(SB, HIGH);
      digitalWrite(SG, HIGH);
      digitalWrite(SE, HIGH);
      digitalWrite(SD, HIGH);
      break;
    case THREE :
      digitalWrite(SA, HIGH);
      digitalWrite(SB, HIGH);
      digitalWrite(SG, HIGH);
      digitalWrite(SC, HIGH);
      digitalWrite(SD, HIGH);
      break;
    case FOUR :
      digitalWrite(SF, HIGH);
      digitalWrite(SG, HIGH);
      digitalWrite(SB, HIGH);
      digitalWrite(SC, HIGH);
      break;
    case FIVE :
      digitalWrite(SA, HIGH);
      digitalWrite(SF, HIGH);
      digitalWrite(SG, HIGH);
      digitalWrite(SC, HIGH);
      digitalWrite(SD, HIGH);
      break;
    case SIX :
      digitalWrite(SA, HIGH);
      digitalWrite(SF, HIGH);
      digitalWrite(SG, HIGH);
      digitalWrite(SC, HIGH);
      digitalWrite(SD, HIGH);
      digitalWrite(SE, HIGH);
      break;
    case SEVEN :
      digitalWrite(SA, HIGH);
      digitalWrite(SB, HIGH);
      digitalWrite(SC, HIGH);
      break;
    case EIGHT :
      digitalWrite(SA, HIGH);
      digitalWrite(SB, HIGH);
      digitalWrite(SF, HIGH);
      digitalWrite(SG, HIGH);
      digitalWrite(SC, HIGH);
      digitalWrite(SD, HIGH);
      digitalWrite(SE, HIGH);
      break;
    case NINE :
      digitalWrite(SA, HIGH);
      digitalWrite(SB, HIGH);
      digitalWrite(SF, HIGH);
      digitalWrite(SG, HIGH);
      digitalWrite(SC, HIGH);
      digitalWrite(SD, HIGH);
      break;
    case ALPHA :
      digitalWrite(SA, HIGH);
      digitalWrite(SB, HIGH);
      digitalWrite(SF, HIGH);
      digitalWrite(SG, HIGH);
      digitalWrite(SC, HIGH);
      digitalWrite(SE, HIGH);
      break;
    case BRAVO :
      digitalWrite(SF, HIGH);
      digitalWrite(SG, HIGH);
      digitalWrite(SC, HIGH);
      digitalWrite(SD, HIGH);
      digitalWrite(SE, HIGH);
      break;
    case CHARLIE :
      digitalWrite(SF, HIGH);
      digitalWrite(SA, HIGH);
      digitalWrite(SD, HIGH);
      digitalWrite(SE, HIGH);
      break;
    case DELTA :
      digitalWrite(SB, HIGH);
      digitalWrite(SG, HIGH);
      digitalWrite(SC, HIGH);
      digitalWrite(SD, HIGH);
      digitalWrite(SE, HIGH);
      break;
    case ECHO :
      digitalWrite(SA, HIGH);
      digitalWrite(SF, HIGH);
      digitalWrite(SG, HIGH);
      digitalWrite(SE, HIGH);
      digitalWrite(SD, HIGH);
      break;
    case FOXTROT :
      digitalWrite(SA, HIGH);
      digitalWrite(SF, HIGH);
      digitalWrite(SG, HIGH);
      digitalWrite(SE, HIGH);
      break;
    }
}

byte tc = 0;
unsigned int dc = 0;

void loop() {
	set_led_pins((dc >> 12) & 0xF, D_ONE, false);
	delay(1);
	set_led_pins((dc >> 8) & 0xF, D_TWO, false);
	delay(1);
	set_led_pins((dc >> 4) & 0xF, D_THREE, false);
	delay(1);
	set_led_pins(dc & 0xF, D_FOUR, false);
	delay(1);
  tc++;
  if(tc % 64 == 0) dc++;
  /* PORTB &= ~(1<<PB0); */
	/* PORTB |= (1<<PB0); */
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s