This is unfinished code for driving a 4 digit 7 segment display. When I run my data function that should output the data to send to the shift register, I get a very weird output.
0 00111111 1 00111111 2 00111111 3 00111111 After this, it repeats.
I am under the impression that it should give this output: 0111111. I have tried to replace the data loop starting number with 7 which I think is correct, but it still gives me a weird output with the weird starting numbers. Is there something I'm missing or is more information needed.
int chars[10][7] = {
{ 0, 1, 1, 1, 1, 1, 1 },
{ 0, 0, 0, 0, 1, 1, 0 },
{ 1, 0, 1, 1, 0, 1, 1 },
{ 1, 0, 0, 1, 1, 1, 1 },
{ 1, 1, 0, 0, 1, 1, 0 },
{ 1, 1, 0, 1, 1, 0, 1 },
{ 1, 1, 1, 1, 1, 0, 1 },
{ 0, 0, 0, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 0, 1, 1, 1, 1 }
};
int nums[4][4] = {
{ 1, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 1 }
};
int data = 8;
int clk = 10;
int latch = 9;
int light = 0;
void setup() {
Serial.begin(9600);
pinMode(data, OUTPUT);
pinMode(clk, OUTPUT);
pinMode(latch, OUTPUT);
initilize();
delay(1000);
}
void initilize() {
start();
for (int i = 12; i > -1; i--) {
digitalWrite(data, 0);
digitalWrite(clk, 1);
digitalWrite(clk, 0);
}
Latch();
}
void numprocess() {
long number = millis();
long size = 0;
long num1 = 0;
long num2 = 0;
long num3 = 0;
long num4 = 0;
number = millis();
size = trunc(log10(number));
num1 = fmod(number / pow(10, size - 0), 10);
num2 = fmod(number / pow(10, size - 1), 10);
num3 = fmod(number / pow(10, size - 2), 10);
num4 = fmod(number / pow(10, size - 3), 10);
}
void Light() {
Serial.println(light);
light++;
if (light >= 4) {
light = { 0 };
};
}
void start() {
digitalWrite(data, 0);
digitalWrite(clk, 0);
digitalWrite(latch, 0);
}
void Data() {
for (int j = 8; j >= 1; j--) {
Serial.println(chars[0][j]);
};
}
void Latch() {
digitalWrite(latch, 1);
digitalWrite(latch, 0);
}
void loop() {
start();
Light();
Serial.println();
Data();
delay(10000);
Latch();
start();
}
1 Answer 1
Your error is the index into the chars[10][7]
array. Your code uses indexes from 8 down to and including 1. But the second dimension holds only 7 elements, with indexes in the range 0 to 6.
This is a corrected version of the function Data()
:
const int DIGITS = 10;
const int SEGMENTS_PER_DIGIT = 7;
int chars[DIGITS][SEGMENTS_PER_DIGIT] = {
//...
};
//...
void Data() {
for (int j = SEGMENTS_PER_DIGIT - 1; j >= 0; j--) {
Serial.println(chars[0][j]);
}
}
Why does the out-of-bounds access work at all and produce the observed output?
The two-dimensional array chars[10]7]
holds all its elements directly in sequence. Therefore chars[0][8]
accesses actually chars[1][1]
and chars[0][7]
accesses actually chars[1][0]
, which are both 0
. These are the two zeroes you see printed. The following ones are the 1
s in chars[0][6]
to chars[0][1]
.
log10()
andpow()
for integer arithmetic: these floating point functions are slow and produce rounding errors. Use repeated division and modulo instead, like:for(int i=0;i<4;++i) {digits[i]=number%10; number/=10;}