Затухание светодиода с помощью петли геркона

Я надеялся, что мне помогут с исчезающим светодиодом, над которым я работаю.

Для моего проекта мне нужен светодиод, который, когда его помещают рядом с магнитом, постоянно светится, но как только его убирают, он должен через определенное время потухнуть. Пока что мне удалось написать код, который определяет, когда свет убирается от магнита и гаснет, но когда магнит снова оказывается рядом, светодиод загорается и продолжает светить, независимо от того, убираю я его от магнита или нет. Итак, как я мог решить это? Я попытался выйти из функции цикла, но тогда этот процесс происходит только один раз, а это не то, чего я хочу. Я также использую геркон для обнаружения магнита, но если у вас есть предложения по другим датчикам, дайте мне знать. Я включаю код сюда.

Заранее спасибо за помощь :)

int ledPin = 9;        
int brightness = 255; 
int fadeAmount = 5;
const int reedPin = 2;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(reedPin, INPUT_PULLUP);
}

void loop() {
  int proximity = digitalRead(reedPin);
  if (proximity == HIGH) {
    Serial.println("Switch opened");
    while (brightness >= 0) {
      analogWrite(ledPin, brightness);
      brightness = brightness - fadeAmount;
      delay(30);
      Serial.println(brightness);
    }
  }
  else {
    Serial.println("Switch closed");
    analogWrite(ledPin, brightness);
    Serial.println(brightness);
  }
}

, 👍1

Обсуждение

Во-первых, пожалуйста, не предоставляйте код в виде изображения. Вместо этого скопируйте и вставьте код в виде текста в вопрос и отформатируйте его правильно, выбрав код и нажав кнопку {} в редакторе вопросов., @chrisl


1 ответ


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

0

Ваша текущая проблема, вероятно, связана с тем, что вы выполняете цикл затухания, даже если brightness уже равен нулю, и что вы не сбрасываете его до нуля после затухания.

while(brightness >= 0){
   ...
   brightness = brightness - fadeAmount;
   ...
}

Представьте, что мы находимся в точке, где brightness равно 5. Условие while истинно, так как 5 > 0. Затем выполняем код в цикле, устанавливая brightness в 0. Снова проверяем условие while. Это по-прежнему верно, поскольку 0>=0. Итак, после повторного выполнения кода в цикле brightness теперь равно -5. Но analogWrite() принимает только 1-байтовое беззнаковое (!) целое число, также известное как uint8_t, а int — 2-байтовое целое число со знаком (!) . Таким образом, только младший байт этого целого числа будет использоваться и интерпретироваться как беззнаковый. Таким образом, -5 интерпретируется как 251, что вы видите как загорание на полную яркость.

Простым решением будет установка brightness на ноль после цикла while:

brightness = 0;

Тем не менее, я бы предложил совершенно другой путь, который сделает ваш код более отзывчивым, используя принцип неблокирующего кодирования из примера BlinkWithoutDelay, поставляемого с Arduino IDE.

Как и вы, я бы использовал глобальную переменную brightness и fadeAmount, а также одну для хранения метки времени:

unsigned long timestamp=0;

Затем в loop() мы можем сначала выполнить затухание до нуля, используя функцию millis() в качестве часов:

if(millis()-timestamp > 30){
    brightness = brightness - fadeAmount;
    if(brightness < 0) brightness = 0;
    timestamp = millis();
}

Это уменьшит переменную brightness до нуля без блокировки с помощью delay(). Скорость можно изменить, изменив число 30 на другое. Это число измеряется миллисекундами.

Затем мы можем проверить наличие геркона и установить brightness на 255, если он активирован:

if(!digitalRead(reedPin)){
    // reedPin НИЗКИЙ
    brightness = 255;
}

Таким образом, пока магнит находится на герконе, этот код установит brightness на 255.

И, наконец, нам нужно записать значение brightness на выходной контакт:

analogWrite(ledPin, brightness);

Полный код:

int ledPin = 9;
int reedPin = 2;

int brightness = 0;
int fadeAmount = 5;
unsigned long timestamp = 0;

void setup(){
    pinMode(ledPin, OUTPUT);
    pinMode(reedPin, INPUT_PULLUP);
}

void loop(){
    if(millis()-timestamp > 30){
        brightness = brightness - fadeAmount;
        if(brightness < 0) brightness = 0;
        timestamp = millis();
    }

    if(!digitalRead(reedPin)){
        // reedPin НИЗКИЙ
        brightness = 255;
    }

    analogWrite(ledPin, brightness);
}

Я проверил это с помощью обычной кнопки (в настоящее время здесь нет геркона). Он должен работать как положено.

,

Я проверил это, это работает. Спасибо огромное!, @Igne