Почему он пропускает первый индекс - проблема с сдвиговым регистром

Итак, я сам написал этот код и я новичок в этом вопросе. Мой код заработал, но я не могу понять, почему он должен быть таким, какой он есть.

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) {
  // включаем пин:
    digitalWrite(2, ledValue[counter - 1]);
    digitalWrite(3, 1);
    digitalWrite(4, 1);
    digitalWrite(2, 0);
    digitalWrite(3, 0);
    digitalWrite(4, 0);
    delay(100);
  // выключаем пин:
  }
  delay(1000);
  digitalWrite(5, LOW);
}

Теперь меня озадачивают как counter = 8, так и [counter -1]. Мне кажется, что я повторяю это 9 раз, хотя в массиве у меня только 8 элементов

А. Если я сделаю это counter = 7 и [counter -1], мой результат будет 10111110. Это повторяется 8 раз (я думаю), но дает мне 7 светодиодов.

Б. Если я сделаю это counter = 7 и [counter], мой результат будет 01111110. Это повторяется 8 раз (я думаю), дает мне 7 светодиодов, но также горит дополнительный светодиод. вперед, тем самым тормозя заданную схему.

С. Если я сделаю это, counter = 7; counter >= -1 мой вывод — 10111111.(как и должно быть). Но как может быть -1?

Я предполагаю, что вначале я делаю что-то не так, но не могу понять, что именно. Перепробовал несколько руководств и объяснений, но меня все еще удивляет, почему правильный работающий код именно такой.

На всякий случай, я знаком с массивом, индекс которого равен 0.

Пожалуйста, помогите мне понять мой код ;-)

Изменить: Небольшое дополнение:

  • контакт 2 подключен к контакту ShiftRegister 14
  • контакт 3 подключен к контакту ShiftRegister 12
  • контакт 4 подключен к контакту ShiftRegister 11
  • Пин 5 подключен к контакту ShiftRegister 10.

Спасибо за отзыв. Мое непонимание не касается цикла или массива. Чего я не могу понять, так это того, почему сдвиговые регистры выводят цикл именно так. Поможет ли фотография установки?

, 👍2

Обсуждение

Что вы подразумеваете под «ожидаемым результатом»? Для большинства светодиодов установлены фиксированные значения, значит, вы хотите сказать, что светодиод на контакте 2 должен показывать код 10111111? Поскольку вы просматриваете массив в обратном порядке (от 8 до 0), я ожидаю увидеть 11111101., @Nick Gammon

*Но как это может быть -1?* - целое число может быть -1. Что вы подразумеваете под «как это может быть»?, @Nick Gammon

@NickGammon; Я имел в виду; Как индекс массива может быть равен -1? Так как это работает, если считать до (включительно) -1. И ожидаемый результат; потому что в сдвиговом регистре первое введенное значение является последним значением в строке. Итак, если я хочу, чтобы он воспроизвел заданный шаблон в светодиодах, мне следует выполнить обработку в обратном порядке. То есть, насколько я сейчас понимаю сдвиговые регистры., @Arie


3 ответа


Лучший ответ:

1

Проблема в том, в каком направлении получает ShiftRegister.

Так это работает

...
digitalWrite(2, ledValue[counter - 1]);
digitalWrite(4, 1); //высокий уровень тактового контакта
digitalWrite(4, 0);
digitalWrite(3, 1); //фиксирующий штифт высоко
digitalWrite(3, 0);
digitalWrite(2, 0);
...

Тактовый сигнал и защелка должны снова перейти на низкий уровень, прежде чем сигнал снова переключится на 0.

В обновленной версии я поместил часы и защелку в функцию.

,

1

Правильный способ перебора массива длиной 8:

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

Если вы хотите пройтись по массиву в обратном порядке, то:

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

Этот цикл посетит в указанном порядке индексы 7, 6, 5... 1 и 0.

Для большей ясности вы можете определить константу, которая будет содержать длину массив, затем замените числа 8 и 7 на VALUES_COUNT. и VALUES_COUNT-1 соответственно.

Вы написали:

Если я это сделаю [...], мой результат будет [...]

Не знаю, что вы имеете в виду. Этот код не должен быть сильно видимым выход, так как светодиоды выключаются только через микросекунды после включения на. Как определить, что такое «выход» программы? Может быть, есть проблема в том, как вы пытаетесь диагностировать проблему.

,

У него/нее задержка в цикле, Эдгар., @Nick Gammon

@NickGammon: Я видел эту задержку, но чтобы увидеть закономерность, потребуется еще одна прямо перед digitalWrite(2, 0);., @Edgar Bonet

О да, хороший момент., @Nick Gammon


1

Сделайте проблему как можно меньшей. Например:

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

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

void loop() {
}

Выход:

8
7
6
5
4
3
2
1
0

Это действительно девять чисел. Массив в C++ начинается с нуля. Ваш массив имеет диапазон отledValue[0] до (включительно)ledValue[7]. См. ответ Эдгара Боне, как используются операторы for.

,