проблема с декрементом в цикле

Я пытаюсь написать скетч, в котором яркость светодиода увеличивается с шагом 15, пока не достигнет 255. В этот момент я хочу сделать декременты на 15, пока они не достигнут 0. Инкрементная часть программы работает хорошо, но декрементная часть выходит из строя. Он застревает между 255 и 240. Я не уверен, как я могу это исправить. Не могли бы вы сказать, как я могу заставить его работать?

Вот мой скетч:

int led = 9; //led pin
int fade = 0; // pwm value

void setup() {
  // put your setup code here, to run once:

  Serial.begin(9600);
  pinMode(led, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:

   analogWrite(led,fade);
   fade += 15;
   Serial.println(fade);
   delay(250);

  if (fade >= 240){
    fade = fade - 15;
    analogWrite(led, fade);
    Serial.println(fade);
    delay(250);
  }

} 

, 👍0

Обсуждение

часть декремента не испорчена ... он делает именно то, что вы сказали ему сделать, @jsotola

см. Пример выцветания в Arduino IDE, @Juraj

Возможно, с циклом for это проще реализовать, как в примере Fading, но я пытался сделать это с помощью условного оператора., @Zaffresky

извините, я подумал, что пример лучше, @Juraj

Это ответ на ваш вопрос? Задержка ШИМ без блокировки кода, @Juraj


2 ответа


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

4

Проблема в том, что вы добавляете 15, а если оно >= 240, вы уменьшаете 15, так что это не изменится (хотя я бы не стал считать это неправильным).

Вы можете лучше использовать указатель направления. Ниже приведен только соответствующий код (не функциональность GPIO). В цикле он делает следующее: в случае, если up истинен, он добавляет пятнадцать, в противном случае он вычитает 15. При достижении 255 начинается обратный отсчет (вверх-ложь), при достижении 0 начинается обратный отсчет (вверх-правда). Это работает только в том случае, если 255 / сумма для сложения/вычитания достигает ровно 255, в противном случае вам придется проверить наличие <= 0 и >= 255.<= 0 и >

bool up = true;
int fade = 0;

void loop()
{
    fade += up ? 15 : -15;
    if (fade == 0)
    {
      up = true;
    }
    else if (fade == 255)
    {
      up = false;
    }
}

Не считается хорошей практикой кодирования:

Последнее утверждение if можно заменить следующей строкой, что означает: если достигнуто повышение и 255, спускайтесь, иначе, если достигнуто снижение и 0, поднимайтесь, в противном случае не меняйте направление. Но это гораздо менее читаемо, поэтому я предпочитаю более длинное утверждение if.

up = (up && (fade == 255)) ? false : ((!up && (fade == 0)) ? true : up);

Другая версия: если значение fade равно 0 или 255 (только две возможности), поднимитесь, если достигнуто значение 0, или (может быть только 255) спуститесь, остальное не изменится.

up = (fade % 255 == 0) ? (fade == 0) : up;
,

Спасибо. Да, я понял, почему цикл декремента застрял. Это не выходило из-под контроля. Я новичок в программировании, и циклы внутри циклов на самом деле не моя сильная сторона :) Нужно больше практиковаться, но спасибо за объяснение., @Zaffresky

Пожалуйста. Просто следуйте первой части ("хорошая практика кодирования"), используйте правильные имена переменных и разбирайте свои проблемы небольшими шагами. Удачи вам в вашем проекте., @Michel Keijzers


1

Условие if вызывает проблему. Когда глобальная переменная fade достигает 240, при входе в цикл ()вы увеличиваете ее на 15, делая fade = 255. Таким образом, условие if становится истинным, и 15 вычитается из 255, что снова делает fade равным 240. Это постоянно повторяется, и, следовательно, переменная value fade застревает между значениями 240 и 255.

,

Спасибо. Теперь я вижу ошибку в своей логике :), @Zaffresky

Отлично! Удачи!, @techenthu