Arduino включение/затухание 5 светодиодов, схема действия

У меня есть простой проект arduino с 5 светодиодами, проект должен начинаться с того, что светодиод 1 затухает через 50 миллисекунд, чтобы достичь полной яркости, затем светодиод 2 и так далее, пока светодиод 5 не выключит их все и не зациклится.

вот изображение для схемы (простите за грязный взгляд в мой первый раз): leds connected to the first 5 pwm pins 3-10

"все светодиоды катода подключены" и вот код :

 int led[5]={3,5,6,9,10};
// массив светодиодных контактов (ШИМ)
void setup() {
  // поместите свой установочный код здесь, чтобы запустить один раз:
  for (int i = 0; i < 5; i++){
    pinMode(led[i], OUTPUT);
    }
    // установить каждый вывод в качестве выхода
}

void loop() {
  for (int i = 0; i < 5; i++){
    int pin = led[i];
    // сохранение значения текущего пина в переменной
    int j = 0;
    while(j <= 50){
      j++;
      delay(1);
      analogWrite(pin,j*2);
    }
    /* the while loop is used to make the fade effect
    by increasing the duty cycle by 2% each millisec 
    over 50 millisec */
  }
  delay(200);
  
  for (int z = 5; z > -1; z--){
    int pin = led[z];
    analogWrite(pin,0);
    }
    // выключение всех светодиодов
    delay(50);
}

проблема заключается в следующем : в первом раунде цикла схема действует так, как ожидалось, светодиод 1 включен, затем 2 и т. Д. Затем все они выключаются и снова зацикливаются, в цикле 16 светодиод 1 выключается, и цикл продолжается только со светодиодами от 2-5, а в цикле 31 светодиод 4 и 5 выключается и только светодиоды 2 и 3 продолжают гореть.

Edit 1 : я только что нашел что-то интересное на официальной странице arduino (контакты, поддерживающие pwm 3, 5, 6, 9, 10, 11 ) частота ШИМ 490 Гц (контакты 5 и 6: 980 Гц) так может ли частота привести к этой ошибке?

Edit 2 : проблема была решена с действительно странным изменением кода самая первая строка кода " int led[5]={3,5,6,9,10};" я изменил размер массива с 5 на 6 следующим образом " int led[6]={3,5,6,9,10};" и проблема была решена, я обнаружил это, когда пытался использовать 4 светодиода, и я забыл изменить размер, если кто-нибудь может объяснить, как это изменение помогло решить проблему ?

, 👍2

Обсуждение

Ваш второй цикл (for (int z = 5; ...) начинается с z=5, который является индексом массива вне привязки и может привести к непредсказуемому поведению. Это также объясняет, почему ваше "исправление" сработало (вы просто сделали массив больше). Сделайте так, чтобы цикл начинался с z=4., @StarCat

Вам нужен один резистор для каждого светодиода. В противном случае яркость одного светодиода влияет на яркость других., @PMF


2 ответа


Лучший ответ:

2

Ваша проблема может быть в вашем коде обратного отсчета. Конкретно этот цикл:

for (int z = 5; z > -1; z--){

Z начинается с 5, и затем вы пытаетесь получить доступ к элементу 5 массива из 5 элементов. Это звучит разумно, пока вы не вспомните, что массивы основаны на 0, поэтому элемента 5 нет, а есть только элементы 0-4.

Таким образом, вы читаете данные, которые не должны читать. Однако простое чтение не должно иметь никакого эффекта, так что :пожимание плечами:...

Во всяком случае, есть некоторые "лучшие практики", которые вы должны сделать, чтобы улучшить свой код:

  1. Используйте 8-битные значения для хранения ваших контактов (uint8_t).
  2. Сделайте свой массив контактов постоянным, чтобы его никогда нельзя было изменить
  3. Замените цикл while более простым для понимания и следования циклом for
  4. Держите ваши циклы как простой подсчет и используйте математику, чтобы определить, какую запись массива вы хотите.
  5. Храните переменные в наименьшем объеме, необходимом для хранения значений, с которыми вы работаете.

Например (непроверено):

const uint8_t led[5] = { 3,5,6,9,10 };
// led pins array (pwm)

void setup() {
  for (uint8_t i = 0; i < 5; i++) {
    pinMode(led[i], OUTPUT);
  }
}

void loop() {
  for (uint8_t i = 0; i < 5; i++){
    int pin = led[i];
    for (uint8_t j = 0; j < 50; j++) {
      delay(1);
      analogWrite(pin, j * 2);
    }
  }

  delay(200);
  
  for (int z = 0; z < 5; z++) {
    int pin = led[4 - z];
    analogWrite(pin, 0);
  }

  delay(50);
}

Кроме того, как отмечалось в комментариях, вы должны иметь один резистор на светодиод и никогда не соединять все катоды вместе. Яркость каждого светодиода определяется протекающим через него током. Этот ток-это ток через резистор, который определяется прямым напряжением светодиодов. Чем больше у вас светодиодов, тем больше этот ток распределяется между светодиодами. И разные светодиоды будут иметь разные прямые напряжения, и самый низкий из них "выиграет", влияя на ток, который допускает резистор. Все это ужасный беспорядок, и его нужно избегать любой ценой. Единственные случаи, когда вы можете иметь только один резистор для нескольких светодиодов, - это а) если у вас есть последовательная цепочка светодиодов, делающая их фактически только одним светодиодом с более высоким прямым напряжением, или б) вы можете абсолютно гарантировать, что один и только один светодиод когда-либо будет включен одновременно.

,

это звучит как самый разумный вопрос, я попробую и приму ответ, если он решит проблему, но почему изменение размера массива решило проблему, @AhmedH2O

@AhmedH2O Изменив его на 6-элементный массив, можно получить доступ к элементам 0-5. Недопустимо обращаться к ним с помощью массива из 5 элементов., @Majenko


1

Вот вывод кода @Majenko

Код такой же, как и в другом ответе. Вы можете найти ссылку на симуляцию здесь --> https://wokwi.com/arduino/projects/318609194610590292

Я также подключил логический анализатор, и вот как это выглядит :) Вы можете посмотреть, как Дежурный кайл становится больше с каждым циклом.

,