ШИМ на 3 светодиода. Неполучается.
- Войдите на сайт для отправки комментариев
Здравствуйте!
Не могу понять че не так. Толи лыжи не едут...
Arduino Nano на 328p. Пытаюсь сделать плавное независимое мерцание на 3 светодиода.
Сначала вроде мерцают, потом начинаются сбои и в конце концов или дергаются как попало или ровно светят.
Пытался смотреть переменные. Знак приращения значения меняется как попало, на любых значениях. Такое чувство будто переменные перемешиваются. Потому что условие if((brightness <= 0) || (brightness >= 155)){ fadeAmount = -fadeAmount;} не выполняется как надо. Лишние скобки просто от отчаяния.
Если включить только 1 светодиод, то работает нормально.
const int led_water = 3;
const int led_filter = 5;
const int led_empty = 6;
const int led_48hour = 13;
const int btn_water = A0;
const int btn_filter = 4;
const int btn_empty = 12;
const int sw_48hour = 7;
int fadeAmount = 1;
byte fade_water=0;
byte fade_filter=0;
byte fade_empty=0;
unsigned long fade_per = 3;
unsigned long fade_timer_water, fade_timer_filter, fade_timer_empty;
void setup() {
// put your setup code here, to run once:
fade_timer_water = millis();
delay(1000);
fade_timer_filter = millis();
delay(1000);
fade_timer_empty = millis();
//инициализируем выходы
pinMode(led_water, OUTPUT);
pinMode(led_filter, OUTPUT);
pinMode(led_empty, OUTPUT);
pinMode(led_48hour, OUTPUT);
//инициализируем входы
pinMode(btn_water, INPUT);
pinMode(btn_filter, INPUT);
pinMode(btn_empty, INPUT);
pinMode(sw_48hour, INPUT);
}
//плавное моргание
void fade(int led, byte &brightness, unsigned long &fade_timer){
int x=1;
/*
if(brightness<30) x=20;
if(brightness<10) x=50;
if(brightness-fadeAmount==0) x=200; */
if((millis()-fade_timer)>=fade_per*x){
analogWrite(led, brightness);
brightness = brightness+fadeAmount; // изменяем значение яркости
fade_timer = millis();
if((brightness <= 0) || (brightness >= 155)){ fadeAmount = -fadeAmount;} // изменяем знак шага при достижении границ
//if(led==5) Serial.println("L: "+String(led)+" B: "+String(brightness)+" min: "+String(min)+" max: "+String(max)+" A: "+String(fadeAmount));
//Serial.println(brightness);
}
}
void loop() {
// put your main code here, to run repeatedly:
fade(led_empty, fade_empty, fade_timer_empty); //6
fade(led_filter, fade_filter, fade_timer_filter); //5
fade(led_water, fade_water, fade_timer_water); //3
}
Потому что условие if((brightness <= 0) || (brightness >= 155)){ fadeAmount = -fadeAmount;} не выполняется как надо.
эта фраза - лучший ответ на вопрос, откуда берутся глюки.
Переменная brightness описана как беззнаковая, поэтому из идеи проверять ее на положительность условием (brightness <= 0) ничего хорошего не выйдет
const int led_water = 3; const int led_filter = 5; const int led_empty = 6; const int led_48hour = 13; const int btn_water = A0; const int btn_filter = 4; const int btn_empty = 12; const int sw_48hour = 7; int fadeAmount = 1; byte fade_water=0; byte fade_filter=0; byte fade_empty=0; unsigned long fade_per = 3; unsigned long fade_timer_water, fade_timer_filter, fade_timer_empty; void setup() { // put your setup code here, to run once: fade_timer_water = millis(); delay(1000); fade_timer_filter = millis(); delay(1000); fade_timer_empty = millis(); //инициализируем выходы pinMode(led_water, OUTPUT); pinMode(led_filter, OUTPUT); pinMode(led_empty, OUTPUT); pinMode(led_48hour, OUTPUT); //инициализируем входы pinMode(btn_water, INPUT); pinMode(btn_filter, INPUT); pinMode(btn_empty, INPUT); pinMode(sw_48hour, INPUT); } //плавное моргание void fade(int led, byte &brightness, unsigned long &fade_timer){ int x=1; /* if(brightness<30) x=20; if(brightness<10) x=50; if(brightness-fadeAmount==0) x=200; */ if((millis()-fade_timer)>=fade_per*x){ analogWrite(led, brightness); brightness = brightness+fadeAmount; // изменяем значение яркости fade_timer = millis(); if((brightness <= 0) || (brightness >= 155)){ fadeAmount = -fadeAmount;} // изменяем знак шага при достижении границ //if(led==5) Serial.println("L: "+String(led)+" B: "+String(brightness)+" min: "+String(min)+" max: "+String(max)+" A: "+String(fadeAmount)); //Serial.println(brightness); } } void loop() { // put your main code here, to run repeatedly: fade(led_empty, fade_empty, fade_timer_empty); //6 fade(led_filter, fade_filter, fade_timer_filter); //5 fade(led_water, fade_water, fade_timer_water); //3 }Верно. Ошибка. Хотел сумничать на случай изменения размера шага.
Поставил тип int. Поведение не поменялось.
При одном светодиоде и с byte нормально работает.
Поставил тип int.
в скольких местах исправили?
При одном светодиоде и с byte нормально работает.
добавьте диагностическую печать всех переменных в процедуре fade и посмотрите, в какой момент происходит срыв плавного изменения значений яркости
int fade_water=0; int fade_filter=0; int fade_empty=0; //плавное моргание void fade(int led, int &brightness, unsigned long &fade_timer){ int x=1; /* if(brightness<30) x=20; if(brightness<10) x=50; if(brightness-fadeAmount==0) x=200; */ if((millis()-fade_timer)>=fade_per*x){ analogWrite(led, (byte)brightness); brightness = brightness+fadeAmount; // изменяем значение яркости fade_timer = millis(); if((brightness <= 0) || (brightness >= 155)){ fadeAmount = -fadeAmount;} // изменяем знак шага при достижении границ //if(led==5) Serial.println("L: "+String(led)+" B: "+String(brightness)+" min: "+String(min)+" max: "+String(max)+" A: "+String(fadeAmount)); //Serial.println(brightness); } }del
dr_sollo, что это за кусок кода, зачем он тут?
Был вопрос: "в скольких местах исправили?"
Вот я и показал, где исправил.
Вывел все переменные из функции, но так и не понял почему работает неправильно.
Например:
23:23:45.309 -> L: 5 B: 11 F_t: 12725 F_p: 3 A: -1
23:23:45.343 -> L: 5 B: 10 F_t: 12763 F_p: 3 A: -1
23:23:45.378 -> L: 5 B: 9 F_t: 12801 F_p: 3 A: -1
23:23:45.412 -> L: 5 B: 8 F_t: 12836 F_p: 3 A: -1
23:23:45.447 -> L: 5 B: 7 F_t: 12873 F_p: 3 A: -1
23:23:45.482 -> L: 5 B: 6 F_t: 12909 F_p: 3 A: -1
23:23:45.516 -> L: 5 B: 5 F_t: 12946 F_p: 3 A: -1
23:23:45.585 -> L: 5 B: 4 F_t: 12982 F_p: 3 A: -1
23:23:45.620 -> L: 5 B: 3 F_t: 13019 F_p: 3 A: -1
23:23:45.654 -> L: 5 B: 2 F_t: 13054 F_p: 3 A: -1
23:23:45.689 -> L: 5 B: 3 F_t: 13091 F_p: 3 A: 1
23:23:45.724 -> L: 5 B: 4 F_t: 13126 F_p: 3 A: 1
23:23:45.759 -> L: 5 B: 5 F_t: 13162 F_p: 3 A: 1
23:23:56.855 -> L: 5 B: 5 F_t: 24267 F_p: 3 A: -1
23:23:56.890 -> L: 5 B: 4 F_t: 24303 F_p: 3 A: -1
23:23:56.924 -> L: 5 B: 5 F_t: 24340 F_p: 3 A: 1
23:23:56.958 -> L: 5 B: 6 F_t: 24375 F_p: 3 A: 1
23:24:07.945 -> L: 5 B: 7 F_t: 35373 F_p: 3 A: -1
23:24:07.979 -> L: 5 B: 6 F_t: 35408 F_p: 3 A: -1
23:24:08.049 -> L: 5 B: 7 F_t: 35445 F_p: 3 A: 1
23:24:08.082 -> L: 5 B: 8 F_t: 35480 F_p: 3 A: 1
23:24:18.897 -> L: 5 B: 9 F_t: 46333 F_p: 3 A: -1
23:24:18.931 -> L: 5 B: 8 F_t: 46370 F_p: 3 A: -1
23:24:18.965 -> L: 5 B: 9 F_t: 46406 F_p: 3 A: 1
23:24:18.999 -> L: 5 B: 10 F_t: 46442 F_p: 3 A: 1
23:24:29.732 -> L: 5 B: 11 F_t: 57150 F_p: 3 A: -1
23:24:29.766 -> L: 5 B: 10 F_t: 57187 F_p: 3 A: -1
23:24:29.800 -> L: 5 B: 11 F_t: 57225 F_p: 3 A: 1
23:24:29.835 -> L: 5 B: 12 F_t: 57262 F_p: 3 A: 1
int8_t fade_water_amount = 1; int8_t fade_filter_amount = 1; int8_t fade_empty_amount = 1; ... void fade(uint8_t led, uint8_t &brightness, uint32_t &fade_timer, int8_t &fade_amount) { if ((millis() - fade_timer) >= fade_per) { analogWrite(led, brightness); brightness = brightness + fade_amount; // изменяем значение яркости fade_timer = millis(); if ((brightness <= 0) || (brightness >= 155)) { fade_amount = -fade_amount; // изменяем знак шага при достижении границ } } } void loop() { fade(led_empty, fade_empty, fade_timer_empty, fade_water_amount); //6 fade(led_filter, fade_filter, fade_timer_filter, fade_filter_amount); //5 fade(led_water, fade_water, fade_timer_water, fade_empty_amount); //3 }Спасибо большое!
Вроде такая мелочь - fade_amount, а сколько нервов испортила.