Как последовательно сдвигать двоичный файл в регистр сдвига (последовательный ввод, параллельный вывод)
Я пытаюсь создать тестер непрерывности работы, в котором я подключаю вход и выход жгута проводов к тестовому прибору, работающему от Arduino. Этот тестер проверяет, правильно ли закреплено положение соединений.
Вот схема моей первоначальной идеи:
С одного конца разъема (выход на схеме) я хочу выполнить сдвиг в двоичном коде, который находится в степени 2. Например, сдвиг в 0001
, проверка непрерывности путем считывания 75HC165 (параллельный ввод, последовательный вывод), затем очистка регистра и затем сдвиг в 0010
, а затем 0100
и так далее. Для правильно закрепленного жгута проводов двоичное вычитание записи и чтения будет равно нулю.
Вот мой цикл, который пытается выполнить описанное выше:
void loop() {
for (int i = 1; i < 4; i++) {
reset_SIPO_register();
shift_SIPO(pow(2,i));
delay(2000);
shift_SIPO(0x00));
check_continuity(); // еще не реализовано
}
}
void reset_SIPO_register() {
digitalWrite(reset_pin, LOW);
digitalWrite(reset_pin, HIGH);
}
void shift_SIPO(int sequence) {
digitalWrite(latch_pin, LOW);
shiftOut(data_pin, clock_pin, MSBFIRST, sequence);
digitalWrite(latch_pin, HIGH);
}
Я тестирую эту концепцию на макете со светодиодами, и все вышеперечисленное работает. Однако светодиод загорается по одному, и они не гаснут, не следуя двоичному коду.
Есть ли что-то, чего я здесь не понимаю? Спасибо!
@Brendon Cheung, 👍-1
Обсуждение1 ответ
Лучший ответ:
Не используйте pow()
. Это функция, которая работает с числами с плавающей
запятой. Это примерно эквивалентно (для y> 0)
double pow(double x, double y)
{
return exp(y * log(x));
}
Как и все трансцендентные функции, его реализация подвержена ошибкам округления. Это даже не гарантирует, что вы получите “правильно” округленную версию точного (т. е. бесконечной точности) результата. На самом деле, очень немногие функции с плавающей запятой дают такую гарантию.
В качестве примера, если вы вычислите pow(2, i)
для i = 3, вы получите
7.9999980926513671875. Это на 4 ULPs меньше точного значения.
Передача этого числа в shift_SIPO()
неявно преобразует его в
int
, и это преобразование всегда округляется до нуля. Таким образом, вы получаете 7, т.е.
0в0111
.
То, что вам нужно, - это целочисленная, точная реализация pow(2, i)
.
Оказывается, это довольно просто: возьмите целое число 1 в двоичном формате, затем сдвиньте
его i
раз влево. То есть
shift_SIPO(1 << i);
Спасибо! это сработало!, @Brendon Cheung
- Как использовать SPI на Arduino?
- Подключение HX711 к трехпроводному датчику нагрузки
- Правильное использование * и & при передаче объектов в методах.
- ISO C++ запрещает принимать адрес неквалифицированной или заключенной в скобки нестатической функции-члена для формирования указателя на функцию-член
- Разница между массивом char и массивом unsigned char
- Печать содержимого файла SD - карты на ЖК-дисплее
- Отправка строки из RPi в Arduino - Рабочий код
- Сообщение об ошибке: "exit status 1 expected initializer before 'void'."
да, вам не хватает полной принципиальной схемы и полного кода из вашего сообщения, @jsotola