Как я могу вызвать три разные функции в зависимости от того, была ли моя кнопка A) только нажата, B) удержана и C) только что отпущена? - PullRequest
0 голосов
/ 20 апреля 2020

Я пишу программу Arduino для управления мини-пушкой для косплея друга. Мне нужно написать программу, чтобы при нажатии кнопки двигатель увеличивался с 0 до заданного значения (сейчас давайте скажем «analogWrite (output_pin, 200);»), а затем l oop на этих оборотах, пока кнопка не будет отпущена , в этот момент он должен вернуться к нулю.

Когда я пытаюсь ввести линейное изменение в oop, код не заканчивается sh. I

Мне нужно что-то подобное в коде c ++ для кнопки Arduino. (Я пробовал похожие вещи, используя функцию «задержки», но безрезультатно)

motorspeed = 0 
if buttonpress == True:
    buttonheld = True
    for i in range (0,10):
        delay(1)
        motorspeed =+ 20
if buttonpress == False:
    motorspeed = 0

if buttonheld == True:
    motorspeed = 200 
    if buttonpress == False: 
        for i in range(0,10):
            delay(1)
            motorspeed =- 20
else:
    #shut off motor 
    #Play error sound

Вот текущий код, который запускает двигатель только на одной скорости, когда кнопка удерживается нажатой.

const int button1 =4;
int BUTTONstate1 = 0;

void setup()
{
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(button1, INPUT);
}

void loop()
{
  //set button to read
  BUTTONstate1 = digitalRead(button1);
  //if button is pressed
  if (BUTTONstate1 == HIGH)
  {
    //run current through motor
    digitalWrite(2, LOW); 
    digitalWrite(3, HIGH);
    //set speed
    //Rampup 
    analogWrite(9,200);
  }
  else 
  {
    digitalWrite(2, LOW); 
    digitalWrite(3, LOW);
  }
}

Вот виртуальная среда для схемы

https://www.tinkercad.com/things/cLOBc9JJuTz-copy-of-dayloncircuitrefinecode/editel?sharecode=b6cqTLlNqUCCN09-mQ_zykp5sMnXx6KLt_KNqlXJmcs

Ответы [ 3 ]

0 голосов
/ 20 апреля 2020

Вы можете использовать прерывания, чтобы обрабатывать нажатие / отпускание, устанавливать значение и обрабатывать линейное изменение вверх / вниз в l oop.

Имейте в виду, что вам также следует отменить нажатие кнопки.

Ниже приведен псевдокод:

const byte maxLevel = 200;  // some example values (max 255)
const int rampDelay = 5;

volatile byte targetLevel = 0;
byte currentLevel = 0;

// ...

ISR for Button {    // Could be in one ore two ISR's

    if pressed
        targetLevel = maxLevel;
        // possible other calls

    if released
        targetLevel = 0;
        // possible other calls
}

void loop()
{
    if (currentLevel < targetLevel) {
        SetLevel(++currentLevel);
    }
    else if (currentLevel > targetLevel) {
        SetLevel(--currentLevel);
    }
    // if currentLevel == targetLevel nothing changes

    // if your device is battery powered you could even put the mcu
    // to sleep when both levels are zero (and wake up from the ISR)
    // no need for constantly polling the button when using ISR

    delay(rampDelay);
}

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

0 голосов
/ 20 апреля 2020

Вот пример, который не зависит от прерываний. Просто прочитайте кнопку и запомните состояние переменной и запомните время последнего шага в переменной, чтобы проверить ее по отношению к millis () (скомпилировано, но не проверено)

int buttonPin = 5;
int lastButtonState = HIGH;

unsigned long lastRampStep;
unsigned int stepTime = 10;  //  10ms steps.  Set to whatever you want.  

int analogPin = 3;
int analogLevel = 0;
int maxLevel = 200;
int analogStepSize = 10;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);  // will read LOW when pressed    
}

void loop() {

  int buttonState = digitalRead(buttonPin);

  if (buttonState != lastButtonState) {
    //  The button just changed!
    if (buttonState == LOW) {
      //  was just now pressed
      analogLevel = 0; // start ramp up
      lastRampStep = millis();  // note the time that we took this step
    } else {
      //  Button just released.
      // not sure what you want to happen here
    }
  }
  else if (buttonState == LOW) {
    // While button is held ramp until we reach the max level
    if(analogLevel < maxLevel){
      if(millis() - lastRampStep >= stepTime){
        analogLevel += analogStepSize;
        lastRampStep = millis();
      }
    }
  } else {
    // While button is released (HIGH) ramp back down:
    if(analogLevel > 0){
      if(millis() - lastRampStep >= stepTime){
        analogLevel -= analogStepSize;
        lastRampStep = millis();
      }
    }
  }
  analogWrite(analogPin, analogLevel);
  lastButtonState = buttonState;
}
0 голосов
/ 20 апреля 2020

Я бы порекомендовал использовать прерывания, это довольно хорошо задокументировано в справочнике Arduino:

Справочник Arduino - прерывания

Наиболее полезными являются "Параметры" и "Пример кода" раздел. Я думаю, вам следует подготовить два метода и прикрепить прерывание к входному контакту (кнопки) на триггере RISING и FALLING.

Убедитесь, что контакт кнопки можно использовать для прерывания (на Arduino UNO / NANO только контакт 2 и 3).

Я думаю, это должно выглядеть примерно так (я этого не проверял):

#define buttonPin 2; // pin usable for interrupt
#define outputPin 9;
#define powerPinA 3;
#define powerPinB 4;  
bool running = false;
int currentSpeed = 0;

void buttonUp()
{
  digitalWrite(powerPinA, LOW); 
  digitalWrite(powerPinB, LOW);
  running = false;
}

void buttonDown()
{
  digitalWrite(powerPinA, LOW); 
  digitalWrite(powerPinB, HIGH);
  running = true;
}

void setup()
{
  pinMode(outputPin, OUTPUT);
  pinMode(powerPinA, OUTPUT);
  pinMode(powerPinB, OUTPUT);
  pinMode(buttonPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(interruptPin), buttonUp, RAISING);
  attachInterrupt(digitalPinToInterrupt(interruptPin), buttonDown, FALLING);
}

void loop()
{
  delay(1);
  if (running && currentSpeed < 200)
    currentSpeed += 20;
  else if (!running && currentSpeed > 0)
    currentSpeed -= 20;

  analogWrite(outputPin, currentSpeed);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...