Arduino включение/затухание 5 светодиодов, схема действия
У меня есть простой проект arduino с 5 светодиодами, проект должен начинаться с того, что светодиод 1 затухает через 50 миллисекунд, чтобы достичь полной яркости, затем светодиод 2 и так далее, пока светодиод 5 не выключит их все и не зациклится.
вот изображение для схемы (простите за грязный взгляд в мой первый раз):
"все светодиоды катода подключены" и вот код :
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 светодиода, и я забыл изменить размер, если кто-нибудь может объяснить, как это изменение помогло решить проблему ?
@AhmedH2O, 👍2
Обсуждение2 ответа
Лучший ответ:
Ваша проблема может быть в вашем коде обратного отсчета. Конкретно этот цикл:
for (int z = 5; z > -1; z--){
Z начинается с 5, и затем вы пытаетесь получить доступ к элементу 5 массива из 5 элементов. Это звучит разумно, пока вы не вспомните, что массивы основаны на 0, поэтому элемента 5 нет, а есть только элементы 0-4.
Таким образом, вы читаете данные, которые не должны читать. Однако простое чтение не должно иметь никакого эффекта, так что :пожимание плечами:...
Во всяком случае, есть некоторые "лучшие практики", которые вы должны сделать, чтобы улучшить свой код:
- Используйте 8-битные значения для хранения ваших контактов (
uint8_t
). - Сделайте свой массив
контактов
постоянным, чтобы его никогда нельзя было изменить - Замените
цикл while более простым для понимания и следования
циклом for
- Держите ваши циклы как простой подсчет и используйте математику, чтобы определить, какую запись массива вы хотите.
- Храните переменные в наименьшем объеме, необходимом для хранения значений, с которыми вы работаете.
Например (непроверено):
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
Вот вывод кода @Majenko
Код такой же, как и в другом ответе. Вы можете найти ссылку на симуляцию здесь --> https://wokwi.com/arduino/projects/318609194610590292
Я также подключил логический анализатор, и вот как это выглядит :) Вы можете посмотреть, как Дежурный кайл становится больше с каждым циклом.
- Как вывести истинное аналоговое напряжение на выходной контакт
- Мигните светодиодом 5 раз с помощью цикла for
- Не могу контролировать скорость двигателей постоянного тока с помощью analogWrite()
- L298N издает звуковые сигналы и дает сбой при получении определенных значений AnalogWrite
- Светодиод Arduino PWM с замиранием в сборке
- AnalogWrite никогда не выводит ненулевое напряжение
- Как повторить другое действие внутри цикла?
- «Вручную» генерация ШИМ-сигнала
Ваш второй цикл (
for (int z = 5; ...
) начинается с z=5, который является индексом массива вне привязки и может привести к непредсказуемому поведению. Это также объясняет, почему ваше "исправление" сработало (вы просто сделали массив больше). Сделайте так, чтобы цикл начинался с z=4., @StarCatВам нужен один резистор для каждого светодиода. В противном случае яркость одного светодиода влияет на яркость других., @PMF