【问题标题】:Update speed while going to position定位时更新速度
【发布时间】:2022-11-16 21:51:26
【问题描述】:

需要随时更新电位器值,不仅一次,尝试不同的方法但没有任何效果:(

我认为主要问题是这个函数 while(digitalRead(gotoPositionAPin));积木

现在是读取值和保存速度

代码工作流程

按下按钮右保存位置a 按下按钮左保存位置 b 更新锅速(设定速度) 更新电位器加速度(设置加速度) 按下按钮转到位置 A(它与前一组速度和加速度一起移动) 按下按钮转到位置 B(它与前一组速度和加速度一起移动)

#include <AccelStepper.h>

// Define some steppers and the pins the will use
AccelStepper stepper1(1, 12, 11); 

#define stepsPerRev      1600
#define stepPin          12
#define dirPin           11
#define ledPin           13
#define rotateLeftPin    7
#define rotateRightPin   6
#define savePositionAPin 5
#define savePositionBPin 4
#define gotoPositionAPin 3
#define gotoPositionBPin 2
#define maxSpeedPin      0
#define accelPin         1

// Set this to zero if you don't want debug messages printed
#define printDebug       0

// These are the constants that define the speed associated with the MaxSpeed pot
#define MAX_STEPS_PER_SECOND  1000    // At 200 s/r and 1/8th microstepping, this will be 333 rev/minute
#define MIN_STEPS_PER_SECOND  27      // At 200 steps/rev and 1/8th microstepping, this will be 1 rev/minute

// Change this value to scale the acceleration pot's scaling factor
#define ACCEL_RATIO           1

int buttonState = 0;
int stepNumber = 0;
int curSpeed = 100;
int dir = 0;
int maxSpeed = 0;
int accel = 0;
long savedPosA = 0;
long savedPosB = 0;

int loopCtr = 0;
  
float fMaxSpeed = 0.0;
float fStepsPerSecond = 0.0;

void setup() 
{
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(rotateLeftPin, INPUT);
  pinMode(rotateRightPin, INPUT);
  pinMode(savePositionAPin, INPUT);
  pinMode(savePositionBPin, INPUT);
  pinMode(gotoPositionAPin, INPUT);
  pinMode(gotoPositionBPin, INPUT);
  
  if (printDebug)
  {
    // Initialize the Serial port
    Serial.begin(9600);
  }
  
  // blink the LED:
  blink(2);

  stepper1.setMaxSpeed(800.0);
  stepper1.setAcceleration(600.0);

  // Grab both speed and accel before we start
  maxSpeed = analogRead(maxSpeedPin);
  // Do the math to scale the 0-1023 value (maxSpeed) to 
  // a range of MIN_STEPS_PER_SECOND to MAX_STEPS_PER_SECOND
  fMaxSpeed = maxSpeed / 1023.0;
  fStepsPerSecond = MIN_STEPS_PER_SECOND + (fMaxSpeed * (MAX_STEPS_PER_SECOND - MIN_STEPS_PER_SECOND));
  if (fStepsPerSecond > 1000)
  {
    fStepsPerSecond = 1000;
  }
  accel = analogRead(accelPin)/ACCEL_RATIO;
}

void loop() 
{  
  // First, we need to see if either rotate button is down. They always take precidence.
  if(digitalRead(rotateLeftPin))
  {
    stepper1.setSpeed(-fStepsPerSecond);
    while(digitalRead(rotateLeftPin))
    {
      CheckPots();
      stepper1.runSpeed();
      stepper1.setSpeed(-fStepsPerSecond);
    }
  }
  else if (digitalRead(rotateRightPin))
  {
    stepper1.setSpeed(fStepsPerSecond);
    while(digitalRead(rotateRightPin))
    {
      CheckPots();
      stepper1.runSpeed();
      stepper1.setSpeed(fStepsPerSecond);
    }
  }

  // Go see if we need to update our analog conversions
  CheckPots();
  
  // Check to see if user is trying to save position A or B
  if(digitalRead(savePositionAPin))
  {
    savedPosA = stepper1.currentPosition();
    if (printDebug)
    {
      Serial.print("Saved A at :");
      Serial.println(savedPosA);
    }
    while(digitalRead(savePositionAPin));
  }
  if(digitalRead(savePositionBPin))
  {
    savedPosB = stepper1.currentPosition();
    if (printDebug)
    {
      Serial.print("Saved B at :");
      Serial.println(savedPosB);
    }
    while(digitalRead(savePositionBPin));
  }
    
  // Check to see if the user wants to go to position A or B
  if (digitalRead(gotoPositionAPin))
  {
    if (printDebug)
    {
      // Yup, let's go to position A
      Serial.print("cur pos = ");
      Serial.println(stepper1.currentPosition());
      Serial.print("Going to A = ");
      Serial.println(savedPosA);
      Serial.print("Speed = ");
      Serial.println(fStepsPerSecond);
      Serial.print("Accel = ");
      Serial.println(accel);
    }

    stepper1.setAcceleration(0);
    stepper1.runToNewPosition(stepper1.currentPosition());
    
    stepper1.setMaxSpeed(fStepsPerSecond);
    stepper1.setAcceleration(accel);
    stepper1.runToNewPosition(savedPosA);

    if (printDebug)
    {
      Serial.print("new pos = ");
      Serial.println(stepper1.currentPosition());
    }
    while(digitalRead(gotoPositionAPin));
  }
  else if (digitalRead(gotoPositionBPin))
  {
    // Yup, let's go to position B
    if (printDebug)
    {
      Serial.print("cur pos = ");
      Serial.println(stepper1.currentPosition());
      Serial.print("Going to B = ");
      Serial.println(savedPosB);
      Serial.print("Speed = ");
      Serial.println(fStepsPerSecond);
      Serial.print("Accel = ");
      Serial.println(accel);
    }

    stepper1.setAcceleration(0);
    stepper1.runToNewPosition(stepper1.currentPosition());

    stepper1.setMaxSpeed(fStepsPerSecond);
    stepper1.setAcceleration(accel);
    stepper1.runToNewPosition(savedPosB);

    if (printDebug)
    {
      Serial.print("new pos = ");
      Serial.println(stepper1.currentPosition());
    }
    while(digitalRead(gotoPositionBPin));
  }
}

// Blink the reset LED:
void blink(int howManyTimes) 
{
  int i;
  for (i=0; i < howManyTimes; i++) 
  {
    digitalWrite(ledPin, HIGH);
    delay(200);
    digitalWrite(ledPin, LOW);
    delay(200);
  }
}

void CheckPots(void)
{
  loopCtr++;

  // Only read these once in a while because they take a LONG time
  if (loopCtr == 100)
  {
    maxSpeed = analogRead(maxSpeedPin);

    // Do the math to scale the 0-1023 value (maxSpeed) to 
    // a range of MIN_STEPS_PER_SECOND to MAX_STEPS_PER_SECOND
    fMaxSpeed = maxSpeed / 1023.0;
    fStepsPerSecond = MIN_STEPS_PER_SECOND + (fMaxSpeed * (MAX_STEPS_PER_SECOND - MIN_STEPS_PER_SECOND));
    if (fStepsPerSecond > 1000)
    {
      fStepsPerSecond = 1000;
    }
  }

  // Read in the acceleration analog value
  // This needs to be scaled too, but to what?
  if (loopCtr >= 200)
  {
    accel = analogRead(accelPin)/ACCEL_RATIO;
    loopCtr = 0;
  } 
}

【问题讨论】:

  • 你的问题是什么?
  • 需要一直更新底池值
  • 需要一直更新电位器值,而不仅仅是一次.您可能需要将 loop 函数包装在无限循环中(例如 for (;;)while (true))。
  • @rturrado 这是 Arduino 代码,两个函数 setup()loop() 在那里被特殊对待(参见 docs.arduino.cc/built-in-examples/basics/BareMinimum)。
  • @Frodyne 非常感谢您的评论。这只是一个建议,但我认为情况并非如此。

标签: c++ arduino


【解决方案1】:

如果您正在研究“连续操作”但不想介绍中断在你的代码中(它本身会有特殊要求)有几件事你需要摆脱:

  1. 无限循环,如:while(digitalRead(savePositionAPin));
  2. 系统等待:delay(200); 与您的blink() 一样

    而是使用状态变量。状态变量或多或少如其名:保存状态的东西,所以你知道按钮、计时器或计数器的值是多少上次。

    所以,不用 while 循环等待按钮被释放,只需设置一个全球的或者静止的布尔值,它知道你上次 loop() 运行时处于什么状态,所以你不会再次触发按钮操作。每个按钮都需要一个布尔标志。

    而不是延迟,或者创建一个状态变量来保存“过去的时间”,例如,您可以从 millis() 获得。所以不要等待但是您应该只检查是否已经过了一定时间,以便您可以切换 LED 的状态。

    将闪烁的 LED 添加到 loop() -(未经测试的示例):

    #define LEDWAIT 300
    unsigned long myTime = 0;
    bool onoff = false;
    loop()
    {
        if (myTime == 0)
            myTime = millis();
        
        if ((millis() - myTime) > LEDWAIT) {
            digitalWrite(ledPin, onoff ? HIGH : LOW);
            onoff = !onoff;
            myTime = millis();
        }
    
        // do other things
    }
    

【讨论】:

    【解决方案2】:

    我不完全清楚你的程序应该做什么以及错误是什么,所以如果我错了请纠正我:你想根据按下哪个按钮更新一个值?您对使用中断触发更新有何看法?

    您可能想要编辑问题的格式。

    【讨论】:

    • 价值一直在更新,直到按下按钮并且价格在上涨,我需要一直更新价值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多