Когда я запускаю цикл 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

Обсуждение

добавить отладочный код, чтобы знать, какая часть программы выводит неожиданные значения, @jsotola

Не используйте log10() и pow() для целочисленной арифметики: эти функции с плавающей точкой работают медленно и приводят к ошибкам округления. Вместо этого используйте многократное деление и взятие по модулю, например: for(int i=0;i<4;++i) {digits[i]=number%10; number/=10;}, @Edgar Bonet


1 ответ


2

Ваша ошибка — это индекс в массиве 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].

,