поведение for-l oop меняется с, казалось бы, не связанного кода - PullRequest
0 голосов
/ 12 февраля 2020

Пример кода используется для создания двоичного счетчика с использованием ряда светодиодов. Я проверял онлайн-учебник, который выдал это как вызов. Моя цель состояла в том, чтобы сделать это способом, который является масштабируемым.

Код ниже работает, но у меня есть проблема. В функции настройки я вызываю функцию Serial.begin, которую я использовал для регистрации при написании кода. Как таковой, код циклически переходит от 0 до 16. Мигает соответствующий соответствующий светодиод.

Когда я удаляю строку Serial.begin, l oop ломается, но в странной точке. Он проходит до 16 раз (ie все 4 светодиода горят), а затем возвращается назад, а затем застревает, мигая только одним светодиодом (указывает 1). Очевидно, для меня загадкой является то, что l oop начинается с 0, на самом деле он проходит до второй итерации l oop, когда он не работает.

В остальном я не использую никакие другие функции Serial, и, поскольку он работает с Serial.begin, я чувствую, что это математически правильно. Это наводит меня на мысль, что это Arduino специфицирует c, и мне бы очень хотелось понять, что здесь происходит, чтобы получить разные результаты.

Я также новичок в C ++ и Arduino в целом, поэтому общие советы или отзывы также приветствуются!

/*
 * The following code runs an Arduino powering 4 LEDs counting in binary
 * Mission was to do this dynamically using for-loops, so that it is scalable for adding say, more LEDs
 * To add an LED, all one needs to do is update the variable 'bits', increase the size of the 'ledArray' and 'myArray' and assign Arduino pins to the new LEDs 
 */

// using Arduino pins 3, 5, 6 & 9. While I'm using PWM pins, this code uses digital write and there's no need to stick to these for the purpose of this code
int led1 = 3; 
int led2 = 5;
int led3 = 6;
int led4 = 9;
int bits = 4; // the number of bits AKA the number of LEDs in the circuit
int del = 350; // the interval for each flash
int topNumber = pow(2,bits); // define the decimal number that can be counted to on a given set. 
int ledArray[4] = {led1, led2, led3, led4}; // this array is made up of the Arduino pins. The array size should be the same as the number of bits
int myArray[4] = {0}; // this array is the array that creates the binary string. The array size should be the same as the number of bits

void setup() {
  Serial.begin(9600); // Getting some odd behaviour with this :/ originally here for troubleshooting
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);  
}

void loop() {    
 // the following for-loop iterates each number in the set from 0 to the ceiling (topNumber) 
  for (int n = 0; n <= topNumber; n++) {     

    int tempValue = n; // set a temporary variable for n - we're going to manipulate n to format our binary, but we want to come back to this value before this loop concludes to increment on it

    // the following for-loop builds an array to present the binary string eg 1,0,0,1 for 1001
      for (int i = 0; n > 0; i++) {
        myArray[i] = n % 2;
        n /= 2;        
      }     

    // the following for-loop matches the leds in the ledArray with the binary array and sets the voltage high as required
      for (int i = 0; i <= bits; i++) {
        if(myArray[i] == 1) {            
          digitalWrite(ledArray[i], HIGH);     
        } else {
        }      
      }      

      delay(del);

    // the following for-loop iterates through the ledArray and switches them all off after completion
      for (int i = 0; i <= bits; i++) {
        digitalWrite(ledArray[i],LOW);
      }

      n = tempValue; // return n to its original value so that the for-loop will iterate as intended

    }
}      

1 Ответ

0 голосов
/ 12 февраля 2020

n <= topNumber должен быть n <topNumber. </p>

Вот что делает записанный код: topNumber = 2, повышенный до 4-й степени, то есть 16. 16 в двоичном виде - 10000; обратите внимание, что используется 5 битов, а не 4. Когда l oop () для for () l oop достигает n = 16, он записывает в myArray [4], которого не существует.

Поскольку C и C ++ не защищают от доступа к массиву вне границ, l oop записывает значение в другое место в памяти. Я предполагаю, что добавление или удаление строки Serial.begin (), вероятно, немного реорганизует память, что меняет эффект записи в этот несуществующий myArray [4].

Одна C языковая вещь, которую вы, вероятно, знать: массивы объявляют количество элементов в массиве; не индекс последнего члена массива. Поэтому myArray [4] объявляет массив с myArray [0], myArray [1], myArray [2] и myArray [3]. MyArray [4] не существует.

...