How to create 16-bit output for LED driver?

Hi there!

I'm relatively new to this. I'm programming an ATTiny2313 from my Arduino UNO. The ATTiny2313 controls a 16 channel LED driver that is connected to two separate seven segment displays (no multiplexing).

My current code confirms that I can individually set each segment with a 16-bit data stream latched to the LED driver:

#include <avr/io.h>

// Pins that the LED driver is connected to
#define DATA_PIN 9
#define CLOCK_PIN 8
#define LATCH_PIN 7
#define BLANK_PIN 6

// 16-bit data string to turn on all LEDs
#define ALL_LEDS_ON 0xFFFF

void setup() {
  // Set the pins as outputs
  pinMode(DATA_PIN, OUTPUT);
  pinMode(CLOCK_PIN, OUTPUT);  
  pinMode(LATCH_PIN, OUTPUT); 
  pinMode(BLANK_PIN, OUTPUT); 
  digitalWrite(BLANK_PIN, HIGH);
}

void loop() {

  // Set all LEDs on
  setAllLedsOn();

  digitalWrite(BLANK_PIN, LOW);

}

// Function to set all LEDs on
void setAllLedsOn() {

  // Send the data for the segment
  shiftOut(ALL_LEDS_ON);

  // Latch the data
  digitalWrite(LATCH_PIN, HIGH);
  digitalWrite(LATCH_PIN, LOW);

}

// Function to shift out a 16-bit data
void shiftOut(uint16_t data) {
  // Shift out the data one bit at a time
  for (int i = 0; i < 16; i++) {
    // Set the data pin to the current bit of the data
    if (data & 1) {
      digitalWrite(DATA_PIN, HIGH);
    } else {
      digitalWrite(DATA_PIN, LOW);
    }

    // Clock the data
    digitalWrite(CLOCK_PIN, HIGH);
    digitalWrite(CLOCK_PIN, LOW);

    // Shift the data one bit to the right
    data >>= 1;
  }
}

However, I would like to make a countdown timer that starts at 99 and counts down. So I can't simply input 0xFFFF to switch all segments on. I gather I have to somehow separate the two digits of my decimal number, convert them into binary (or HEX, which would then be converted to binary again during shiftOut, which seems like an unnecessary additional step), and then combine the two 8-bit bytes into a 16-bit data stream again.

How do I best go about this?

I know that I can separate the numbers with "% 10" and "/ 10 % 10", but where do I go from there? How do I convert them into binary and save them somewhere in a byte to be shifted out?

I guess I could simply use the shiftOut function to first shift out the first byte, then the second byte, and only then use the latch, so that the LED driver receives a single 16-bit data stream, but the whole "splitting-apart, converting-into-binary and then stichting-together-again" process eludes me...

I'd be very glad if you could help me with this! Thanks in advance.

You are on the right track. I've not done what you are trying to do but your plan looks reasonable.

First off, stop thinking that numbers are in any way stored in decimal, they are not, they are stored in binary, but usually displayed in decimal.

You know how to split your number up into 2 digits, so do that and store each digit in a separate variable, or better still in an array with 2 elements. As you only need 0 to 9 uint8_t will be adequate.

As you want your numbers to correspond to a 7 segment display you need an array of uint8_t and 10 elements, each of which will hold the pattern of segments for the corresponding number. You read the array with the number you have to get the bit pattern, you can put that in another variable. If you use uint16_t then it will hold both digits, you just need to shift it out.

That should keep you busy for now.

2 Likes

The exact model of led driver might affect how you need to do this, so please post a link to the specs of that chip, and, ideally, a schematic so we can check you have wired it correctly to the displays and the attiny.

Hopefully you will have wired the two displays in a consistent way, so that the connections from the segments "a" to "g" on the left display are in the same sequence as they are on the right display when they connect to the output pins of the led driver. For example if the segments a,b,c,d of the left display are connected to outputs 0,1,2,3, then the segments a,b,c,d of the right display are connected to outputs 8,9,10,11. If not, it would be good to re-wire them that way, otherwise your code will be more complex.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.