
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); */ }