1

So, I wrote this code myself and I'm a noob on the issue. I did get my code working, but cannot understand why it has to be the way it is.

int counter;
int ledValue[] = {
  1,0,1,1,1,1,1,1
}; 

void setup()
{
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
}

void loop(){
  digitalWrite(5, HIGH);
  for (counter = 8; counter >= 0; --counter) {
  // turn the pin on:
    digitalWrite(2, ledValue[counter - 1]);
    digitalWrite(3, 1);
    digitalWrite(4, 1);
    digitalWrite(2, 0);
    digitalWrite(3, 0);
    digitalWrite(4, 0);
    delay(100);
  // turn the pin off:
  }
  delay(1000);
  digitalWrite(5, LOW);
}

Now, I am puzzled by both the counter = 8 and the [counter -1]. To me it looks like I am loop-ing this 9 times, though I only got 8 items in the array

A. If I make it counter = 7 and [counter -1] my output is 10111110. This loops 8 times (I think), but gives me 7 leds.

B. If I make it counter = 7 and [counter] my output is 01111110. This loops 8 times (I think), gives me 7 leds but also an extra led burning up front, hence braking the prescribed pattern.

C. If I make it counter = 7; counter >= -1 my output is 10111111.(as it should). But how can it be -1?

My guess is that I am doing something wrong at the beginnen, but I can't find what. Tried several tutorials and explanations, but it still puzzles me why the correct running code is that way.

Just to be sure, I am familiar with an array being 0-indexed.

Please helpt me understand my code ;-)

Edit: Small addition:

  • pin 2 is connected to ShiftRegister pin 14
  • pin 3 is connected to ShiftRegister pin 12
  • pin 4 is connected to ShiftRegister pin 11
  • pin 5 is connected to ShiftRegister pin 10

Thanks for the feedback. My lack of understanding does not concern the loop or array. What I can't get my head around is why the shift registers outputs the loop as it does. Would a picture of the setup help?

  • What do you mean by "expected output"? Most of the LEDs are set to fixed values, so are you saying that the LED on pin 2 should show the pattern 10111111? Since you are going through the array backwards (8 down to 0) I would expect to see 11111101. – Nick Gammon Dec 8 '18 at 21:16
  • But how can it be -1? - an integer can be -1. What do you mean by "how can it be"? – Nick Gammon Dec 8 '18 at 21:18
  • @NickGammon; I meant; How can the index of an array be -1? Since it does work if it counts until (including) -1. And expected output; because with the shift register, the first value put in, is the last value in the row. So, if I want it to replicate a given pattern in LED's I should process backwards. That is, for as far as I do understand shift registers now. – Arie Dec 9 '18 at 13:18
2

The correct way to loop through an array of length 8 is:

for (int counter = 0; counter < 8; ++counter) {
    digitalWrite(2, ledValue[counter]);
    // ...
}

If you want to loop through the array backwards, then:

for (int counter = 7; counter >= 0; --counter) {
    digitalWrite(2, ledValue[counter]);
    // ...
}

This loop will visit, in this order, the indices 7, 6, 5... 1 and 0.

For extra clarity, you could define a constant that holds the length of the array, then replace the numbers 8 and 7 above by VALUES_COUNT and VALUES_COUNT-1 respectively.

You wrote:

If I make it [...] my output is [...]

Not sure what you mean by that. This code should not have much visible output, as the LEDs are turned off only microseconds after being turned on. How do you determine what the program's "output" is? Maybe there is an issue with the way you are trying to diagnose the problem.

  • S/he has a delay in the loop, Edgar. – Nick Gammon Dec 8 '18 at 21:15
  • @NickGammon: I saw that delay but, in order to see the pattern, another one would be needed right before digitalWrite(2, 0);. – Edgar Bonet Dec 8 '18 at 21:23
  • Oh yeah, good point. – Nick Gammon Dec 8 '18 at 21:29
1

Make the problem as small as possible. For example:

void setup() {
  Serial.begin(9600);

  for( int i=8; i>=0; --i) {
    Serial.println(i);
  }
}

void loop() {
}

The output is:

8
7
6
5
4
3
2
1
0

Those are indeed nine numbers. An array in c++ starts at zero. Your array is from ledValue[0] up to (inclusive) ledValue[7]. See the answer by Edgar Bonet how the for-statements are used.

0

The problem is in the directions the ShiftRegister gets.

This way, it works

...
digitalWrite(2, ledValue[counter - 1]);
digitalWrite(4, 1); //clock pin high
digitalWrite(4, 0);
digitalWrite(3, 1); //latch pin high
digitalWrite(3, 0);
digitalWrite(2, 0);
...

The clock and latch have to be low again before switching the signal back to 0.

In the upgraded version I put the clock and latch in a function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.