First post, hope I read all the rules correctly.
I have an RGB 7-segment display that I want to program as a clock. I designed it myself but did not realize the complexity of the code with the design that I have.
I'm going to do my best to explain everything so bear with me.
It has 6x 16-bit shift registers whose outputs are connected to short strips of those LED strip lights you can buy on Amazon. The main MCU is an Arduino Nano that is plugged in the back of the panel. (The shift registers are connected to the SPI pins so if i can use that it would be nice).
The problem I'm having is I need 21 bits for each digit. 7 segments * 3 colors. I have the data for the digits saved in an array:
const __uint24 blueNumbers[10]{
0b001001001001001001000,
0b000001001000000000000,
0b001001000001001000001,
0b001001001001000000001,
0b000001001000000001001,
0b001000001001000001001,
0b001000001001001001001,
0b001001001000000000000,
0b001001001001001001001,
0b001001001001001000001
};
with the first 3 bits left-padded with 0's.
The segments are connected in order: a(red) -> a(blue) -> a(green) -> b(red) -> b(green) -> b(blue) etc... where the a,b,c,d,e,f,g are the 7 segments. Some shift registers share the same digits.
E.g. a red number 4 would be 0b000 100 100 000 000 100 100 (I broke it up to show how each segement is 3 bits corresponding to RGB respectively.) I need to somehow cut off the first 3 bits and combine the 4 digits into 6x 16bit or 12x 8bit values so that I can shift the data out fast enough that the display doesn't flicker.
I tried doing this using 16bit variables and bit-shifting but it's not working and I cant figure out what im doing wrong. Is there an easy way to cut off the first 3 bits and create a sequence of bytes with the necessary values to shift out? I need the first 3 cut off because otherwise it shifts 0's when I don't want it to.
TL;DR: I need to cut off 3 MSB's from 4x 24-bit values and combine them into 6x words or 12x bytes. (I know the number of bits doesn't add up so I need the last 12 bits padded with 0's or whatever as they arent connected to any LED's).
OR I need to shift 21 bits using SPI which I dont think is possible because of the architecture of the SPI preipherals. (modified shiftOut as last resort as it causes flicker)
#include <SPI.h>
#include <Wire.h>
#define I2C_ADDR 104
const int latch = 10; // Pin assignment
const int outputEnable = 7; // ^^
uint16_t sr1;
uint16_t sr2;
uint16_t sr3;
uint16_t sr4;
uint16_t sr5;
uint16_t sr6;
const __uint24 blueNumbers[10]{
0b001001001001001001000,
0b000001001000000000000,
0b001001000001001000001,
0b001001001001000000001,
0b000001001000000001001,
0b001000001001000001001,
0b001000001001001001001,
0b001001001000000000000,
0b001001001001001001001,
0b001001001001001000001
};
void setup() {
Wire.begin();
Serial.begin(9600);
pinMode(latch, OUTPUT);
pinMode(outputEnable, OUTPUT);
pinMode(11, OUTPUT);
pinMode(13, OUTPUT);
}
void loop() {
// Turn LED's off
digitalWrite(outputEnable, HIGH);
// Datashift
createDisplayBytes(1,2,3,4); // Testing using 1-4 for now
shiftOut(11, 13, LSBFIRST, sr6);
shiftOut(11, 13, LSBFIRST, sr5);
shiftOut(11, 13, LSBFIRST, sr4);
shiftOut(11, 13, LSBFIRST, sr3);
shiftOut(11, 13, LSBFIRST, sr2);
shiftOut(11, 13, LSBFIRST, sr1);
// Latch
digitalWrite(latch, HIGH);
digitalWrite(latch, LOW);
// Turn LED's on
digitalWrite(outputEnable, LOW);
delay(250);
}
void createDisplayBytes(int num1, int num2, int num3, int num4) {
sr1 = blueNumbers[num1];
sr2 = (blueNumbers[num1] >> 16) + (blueNumbers[num2] << 5);
sr3 = (blueNumbers[num2] >> 11) + (blueNumbers[num3] << 10);
sr4 = (blueNumbers[num3] >> 6) + (blueNumbers[num4] << 15);
sr5 = blueNumbers[num4] >> 1;
sr6 = blueNumbers[num4] >> 17;
}
void readalltoconsole() {
int i;
Wire.beginTransmission(I2C_ADDR); // transmit to device #44 (0x2c)
Wire.write(byte(0x00));
Wire.endTransmission();
Wire.requestFrom(104, 8);
if (8 <= Wire.available()) { // if eight bytes were received
for(int j = 0; j < 8; j++){
int val = Wire.read();
Serial.print("0");
Serial.print(j);
Serial.print("h = ");
for(int i = 7; i >= 0; i--)
Serial.print(bitRead(val,i));
Serial.println();
}
}
Serial.println();
Serial.println();
}
Schematic_RGB_Clock.pdf (217 KB)