Почему он пропускает первый индекс - проблема с сдвиговым регистром
Итак, я сам написал этот код и я новичок в этом вопросе. Мой код заработал, но я не могу понять, почему он должен быть таким, какой он есть.
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.
Спасибо за отзыв. Мое непонимание не касается цикла или массива. Чего я не могу понять, так это того, почему сдвиговые регистры выводят цикл именно так. Поможет ли фотография установки?
@Arie, 👍2
Обсуждение3 ответа
Лучший ответ:
Проблема в том, в каком направлении получает ShiftRegister.
Так это работает
...
digitalWrite(2, ledValue[counter - 1]);
digitalWrite(4, 1); //высокий уровень тактового контакта
digitalWrite(4, 0);
digitalWrite(3, 1); //фиксирующий штифт высоко
digitalWrite(3, 0);
digitalWrite(2, 0);
...
Тактовый сигнал и защелка должны снова перейти на низкий уровень, прежде чем сигнал снова переключится на 0.
В обновленной версии я поместил часы и защелку в функцию.
Правильный способ перебора массива длиной 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
Сделайте проблему как можно меньшей. Например:
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.
- if(Serial.available()>0) VS while(Serial.available()>0)
- 74HC595 к 4 значному 7 сегменту с использованием библиотеки SevSegShift
- 74HC595 регистр сдвига не работает
- LSB/MSB и shiftOut
- Прочитать значение регистра в arduino
- Как обнаружить нажатия кнопок с помощью сдвигового регистра 74HC595?
- Сдвиговый регистр с релейной платой ведет себя хаотично
- Проблема с подключением 2 8-разрядных сдвиговых регистров 74HC595 в каскадном соединении
Что вы подразумеваете под «ожидаемым результатом»? Для большинства светодиодов установлены фиксированные значения, значит, вы хотите сказать, что светодиод на контакте 2 должен показывать код 10111111? Поскольку вы просматриваете массив в обратном порядке (от 8 до 0), я ожидаю увидеть 11111101., @Nick Gammon
*Но как это может быть -1?* - целое число может быть -1. Что вы подразумеваете под «как это может быть»?, @Nick Gammon
@NickGammon; Я имел в виду; Как индекс массива может быть равен -1? Так как это работает, если считать до (включительно) -1. И ожидаемый результат; потому что в сдвиговом регистре первое введенное значение является последним значением в строке. Итак, если я хочу, чтобы он воспроизвел заданный шаблон в светодиодах, мне следует выполнить обработку в обратном порядке. То есть, насколько я сейчас понимаю сдвиговые регистры., @Arie