Как переключить светодиод и двигатель при нажатии кнопки?

мы хотим, чтобы светодиод включался нажатием кнопки и становился все ярче и ярче с течением времени (в течение определенного периода времени), а когда он достигает максимальной яркости, выключался на пару секунд и затем начните снова. кроме того, мы пытаемся добавить двигатель, который будет вращаться на 720 градусов при нажатии кнопки. Наша главная проблема заключается в том, что когда мы отпускаем кнопку, светодиод гаснет. Как настроить кнопку так, чтобы при однократном нажатии включалось все, а светодиод работал в цикле, а моторчик нет; и когда мы нажимаем ее снова, весь светодиод полностью выключается, и двигатель вращается на 720 градусов в направлении, противоположном вращению, чем предыдущий.

Вот что нам пока удалось (мы еще не представили мотор, так как застряли):

const int switchPin = 11;
const int motorPin = 6;
int led = 9;
int switchState = LOW;
int previous = LOW;
int i = 0;
int fadeAmount = 5;

void setup() 
{
  pinMode(led, OUTPUT);
  pinMode(motorPin, OUTPUT);
  pinMode(switchPin, INPUT);
}

void loop() 
{
  int switchState = digitalRead(switchPin);

  for (int i = 0; i <= 255; i++) 
  {
    analogWrite(led, i);
  }

  if (switchState == HIGH && previous == LOW) 
  {
    if (i == 0) 
    {
      digitalWrite (led, HIGH);
      i = i + fadeAmount;
      delay(1000);
    }

    analogWrite(led, i);

    for (int i = 255; i <= 255; i--)
    {
      digitalWrite (led, LOW);
      i = 0;
    }
  }
  else 
  { 
    //toggle off
    digitalWrite(led, LOW);
    i = 0;
  }
}

ПС. МЫ начинающие. Спасибо за помощь и понимание!

, 👍1

Обсуждение

вас отвлекают затухающие огни и двигатель .... действие двигателя и действие затухающих огней полностью отделены от действия нажатия кнопки .... двигатель и свет могут запускаться по таймеру, по уровню напряжения или рядом других событий ....... освещение должно управляться логической переменной ... например, назовите ее lights_on ... кнопка должна установить значение переменной lights_on ... . значение должно быть установлено только переключателем в «переходе из состояния ненажатой кнопки в состояние нажатой кнопки», а не только в состоянии «нажато», @jsotola

начните с написания кода кнопки, которая управляет одним светодиодом... кнопка устанавливает переменную.... светодиод реагирует на переменную, @jsotola


2 ответа


1

Вот программа, которая должна затухать светодиод, как вы указали. Изначально светодиод выключен. Если вы нажмете кнопку, светодиод начнет тускнеть в пределах временного интервала до максимума. Потом переключается на ноль ждет пару секунд и начинает замирать с новой. Если вы нажмете кнопку второй раз, светодиод перестанет тускнеть и станет темным. ;-) Это происходит сразу же, но вы можете увидеть это, только если светодиод находится в фазе затухания.

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

Получение контакта кнопки в цикле было бы более сложной задачей. Для этого потребуется переменная состояния и некоторые правила перехода состояния. А мне было лень разбираться в этом. Если прерывания нельзя использовать по какой-либо причине, я бы изменил ответ. (Нет, мама, я не хочу...)

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

Я тестировал программу на Arduino UNO. Кнопка, которую я использовал, имеет низкое качество, поэтому мне пришлось ее устранить.

Если вам что-то непонятно, спросите в комментариях.

// Подключаем светодиод к выводу ШИМ UNO -> 3,5,6,9,10,11
const byte ledPin       = 9;

// УНО-> только контакт 2 или контакт 3 являются контактами прерывания
// поскольку мы используем подтяжки, кнопка должна быть подключена к GND
const byte interruptPin = 2; 

// в миллисекундах - время, необходимое светодиоду, чтобы полностью загореться
const int timeFrame  = 5000;

// в миллисекундах
const int aCoupleOfSeconds = 2000;

const int fadeAmount =    5;

volatile boolean fadeOn = false;
volatile long debounceTime = 800;
volatile long actTime = 0;

int brightness =   0;

int stepCount = 256       / fadeAmount;
int stepDelay = timeFrame /  stepCount;

void setup() 
{
  pinMode( ledPin,       OUTPUT       );
  pinMode( interruptPin, INPUT_PULLUP );

  attachInterrupt( digitalPinToInterrupt( interruptPin ), pressed, CHANGE );
}

void loop() 
{
  if ( fadeOn )
  {
    delay( stepDelay );
    brightness += fadeAmount;
    if ( brightness >= 255 )
    {
       brightness = 0;
       analogWrite( ledPin, brightness );
       delay( aCoupleOfSeconds );
    }
    analogWrite( ledPin, brightness );
  }
  else 
  { 
    brightness = 0;
    analogWrite( ledPin, brightness );
  }
}

void pressed() 
{
  // устранение дребезга работает не идеально

  if ( digitalRead( interruptPin ) == LOW )
  {
    if ( millis() - actTime > debounceTime )
    {
      fadeOn = !fadeOn;
    }
  }
  else
  {
    actTime = millis();
  }
}
,

«Наша главная проблема в том, что когда мы отпускаем кнопку, светодиод гаснет», @Juraj

@Juraj Аааа, нет, я совершенно неправильно понял вопрос. Спасибо, что дали мне подсказку., @Peter Paul Kiefer

просто измените логическое значение при нажатии кнопки и оттуда создайте код... if(switchstate == HIGH){bool1 = 1;} if(bool1 == 1){...}, @ElectronSurf

@Hamed Мне нужно синхронизировать кнопку, если она нажата дольше. ОП не хочет удерживать кнопку. Нажимают кнопку, затем начинается затухание, если светодиод полностью загорелся, то он должен погаснуть, подождать некоторое время и снова начать затухание. Если я нажимаю кнопку второй раз, я выключаю светодиод и гаснет. Просто удержание логического состояния будет переключаться, если я нажму кнопку в течение более длительного времени. Я планирую использовать прерывания., @Peter Paul Kiefer

миллис () в кли ()? он увеличивается прерыванием таймера, @Juraj

@Juraj Я действительно не думал об этом, но моя прога. работает отлично. Возможно, это работает, потому что можно прочитать фактическое время при входе в ISR (блок cli), но время не увеличивается, пока выполнение находится в ISR. (и это ненадолго). Но поскольку cli и sei никак не влияют на мою программу, я могу безопасно удалить их, чтобы упростить ее. Спасибо за подсказку., @Peter Paul Kiefer


0

Посмотрите на код на форуме от marcello.romani. Он опубликовал его 1 января 2013 года. Тема по теме называется : "кнопка нажата более 2 секунд сделайте что-нибудь другое" Код Марчелло настолько KISS (Keep It Simple Stupid) и эффективен, что заслуживает Нобелевской премии. Цель состоит в том, чтобы обрабатывать различные сигналы, поступающие от кнопки или переключателя: keyPress, keyRelease, longKeyPress и т. д., как вы можете найти в исходном скетче.

,

У ОП нет проблем с более длинными или короткими нажатиями клавиш. Она хочет только переключить состояние, нажав клавишу. Таким образом, код может быть хорошим, но он не отвечает на вопрос. Кстати: этот код предназначен для демонстрации, а не KISS. «Делай только то, что должно быть сделано». Но для демонстрации он использует методы только с одним оператором. Мне пришлось пройти по пути выполнения, чтобы узнать, что происходит. Нет, это не KISS, хотя ИМХО он идеален для демонстрационных целей, так как дает нам места, где мы можем его расширить., @Peter Paul Kiefer