1

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();
}
asked Apr 30 at 22:05
2
  • 1
    add debugging code so that you know which part of the program is printing unexpected values Commented May 1 at 1:22
  • 1
    Do not use log10() and pow() 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;} Commented May 1 at 8:44

1 Answer 1

3

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 1s in chars[0][6] to chars[0][1].

answered May 1 at 8:23

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.