ШИМ на 3 светодиода. Неполучается.

dr_sollo
Offline
Зарегистрирован: 07.09.2020

Здравствуйте!

Не могу понять че не так. Толи лыжи не едут...

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
}

b707
Онлайн
Зарегистрирован: 26.05.2017

dr_sollo пишет:

Потому что условие if((brightness <= 0) || (brightness >= 155)){ fadeAmount = -fadeAmount;} не выполняется как надо.

эта фраза - лучший ответ на  вопрос, откуда берутся глюки.

Переменная brightness описана как беззнаковая, поэтому из идеи проверять ее на положительность условием (brightness <= 0) ничего хорошего не выйдет

 

dr_sollo
Offline
Зарегистрирован: 07.09.2020
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
}

 

dr_sollo
Offline
Зарегистрирован: 07.09.2020

Верно. Ошибка. Хотел сумничать на случай изменения размера шага.

Поставил тип int. Поведение не поменялось.

При одном светодиоде и с byte нормально работает.

b707
Онлайн
Зарегистрирован: 26.05.2017

dr_sollo пишет:

Поставил тип int.

в скольких местах исправили?

Цитата:

При одном светодиоде и с byte нормально работает.

добавьте диагностическую печать всех переменных в процедуре fade и посмотрите, в какой момент происходит срыв плавного изменения значений яркости

dr_sollo
Offline
Зарегистрирован: 07.09.2020
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);      
    }  
  }

 

v258
Offline
Зарегистрирован: 25.05.2020

del

b707
Онлайн
Зарегистрирован: 26.05.2017

dr_sollo, что это за кусок кода, зачем он тут?

dr_sollo
Offline
Зарегистрирован: 07.09.2020

Был вопрос: "в скольких местах исправили?"

Вот я и показал, где исправил.

Вывел все переменные из функции, но так и не понял почему работает неправильно.

Например:

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

 

sadman41
Offline
Зарегистрирован: 19.10.2016
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
}

 

dr_sollo
Offline
Зарегистрирован: 07.09.2020

Спасибо большое!

Вроде такая мелочь - fade_amount, а сколько нервов испортила.