Когда я запускаю цикл for, последовательный монитор выдает очень странные результаты.
Это незаконченный код для управления четырёхразрядным семисегментным дисплеем. Когда я запускаю функцию обработки данных, которая должна выводить данные для отправки в сдвиговый регистр, я получаю очень странный вывод.
0 00111111 1 00111111 2 00111111 3 00111111 После этого всё повторяется.
У меня сложилось впечатление, что он должен выдать такой вывод: 0111111. Я попробовал заменить начальное число цикла данных на 7, что, по-моему, правильно, но всё равно выдаёт странный результат со странными начальными числами. Может, я что-то упускаю или нужна дополнительная информация?
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();
}
1 ответ
Ваша ошибка — это индекс в массиве chars[10][7]. Ваш код использует индексы от 8 до 1 включительно. Но второе измерение содержит всего 7 элементов с индексами в диапазоне от 0 до 6.
Это исправленная версия функции 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]);
}
}
Почему доступ за пределами диапазона вообще работает и даёт наблюдаемый результат?
Двумерный массив chars[10]7] хранит все свои элементы последовательно. Следовательно, chars[0][8] обращается к chars[1][1], а chars[0][7] обращается к chars[1][0], которые оба равны 0. Это два нуля, которые вы видите на экране. Следующие — это 1 в интервалах от chars[0][6] до chars[0][1].
- Команда strtok() с Serial связью
- Как изменить переменную при нажатии кнопки, подключенной к контакту 2
- Как программно обнаружить последовательный порт Arduino на разных платформах?
- Почему нужно использовать latin-1 вместо utf-8 при использовании python с arduino?
- Java NetBeans отправляет значение и получает значение от Arduino
- Акцептант векселей ИКТ
- Использование последовательной связи в .c-файлах
- Потребление ATtiny84 против ATtiny85
добавить отладочный код, чтобы знать, какая часть программы выводит неожиданные значения, @jsotola
Не используйте
log10()иpow()для целочисленной арифметики: эти функции с плавающей точкой работают медленно и приводят к ошибкам округления. Вместо этого используйте многократное деление и взятие по модулю, например:for(int i=0;i<4;++i) {digits[i]=number%10; number/=10;}, @Edgar Bonet