0

我目前正在尝试使用托管在 RPi 上的 Nodebot johnny-five.io 来控制连接到 Arduinos 的伺服系统的配置。我的主要目标是从头开始制作六足动物;我不喜欢套件的想法,因为它是你拼凑起来的所有千篇一律的代码和零件,它或多或少是一辆你没有学到任何东西的遥控汽车。

我刚刚学习了伺服系统的基础知识(我选择伺服系统而不是步进电机)。不幸的是,默认情况下,伺服速度不能通过 PWM 控制,只能通过位置控制。所以解决这个问题的方法是创建一个循环,每次增加伺服 1 度(或更多),循环中有 X ms 延迟,直到伺服到达所需位置。现在,这很好,如果您一次只控制一个伺服器或一次控制 X 个伺服器以移动到另一个设定位置。但我在这里拍摄的是流畅的动作;我希望一条腿在另一条腿停止之前开始移动。真正的运动流动性,为了实现这一点,我需要一个无限循环来检查由 API 接收的控制命令设置的输入状态。

这里的问题是while循环不是异步的。所以,我需要找到一种方法来启动一个循环,将不同的伺服系统设置在不同的速度范围和不同的位置,并在循环结束时检查新的输入状态更新。我需要在不造成内存泄漏的情况下做到这一点。

一种方法是为每个伺服系统创建一组异步工作的依赖脚本(每条腿 3 个伺服器,6 条腿,18 个伺服器,因此有 18 个迷你依赖项),但我不确定这是否会产生太多开销或给 RPi 带来了很大的压力。

这是我想太多了吗?

4

1 回答 1

0

您可以创建一个简单的伺服类,并使用“更新”方法为每个实例提供自己的速度和起始位置。使用更长的延迟使伺服器移动得更慢。在主循环中,您可以不断检查一些输入,如果需要,告诉舵机移动,使用更新方法。

#include <Servo.h>

class HexapodLegServo
{
  Servo servo;         // Servo instance
  int pos;             // Position/angle of the servo
  int delay_millis;    // 'Delay' between each update
  long prev_millis;
  int degree_change;       // Angle increase each update
  int start_pos;       // Position to start at
  int pin;             // Pin servo is connected to

  public:
    HexapodLegServo (int whichPin, int delayMillis=15, int startPos=0)
    {
      pin = whichPin;
      delay_millis = delayMillis;
      start_pos = startPos;
      degree_change = 1;
     }

     void attachToPin()
     {
       servo.attach(pin);
       setStartPos();
     }

     void setStartPos()  // Set initial position of the servo
     {
       servo.write(start_pos);
       pos = start_pos;
     }

    void update()  // Servo sweeps from end to end, and back
    {
      if (millis()-prev_millis > delay_millis)
      {
        prev_millis = millis();
        servo.write(pos);
        pos += degree_change;

        if ((pos <= 0) || (pos >= 180))
        {
          degree_change *= -1;  // Start moving in the reverse direction
        }
      }
    }
  };

// Main script
const int BUTTON = 4;  // Button on pin 4
HexapodLegServo right_leg(9);
HexapodLegServo left_leg(10, 30, 90);

void setup()
{
  Serial.begin(9600);
  pinMode(BUTTON, INPUT_PULLUP);  // Using a button to tell servos when to move

  right_leg.attachToPin();
  left_leg.attachToPin();
}

void loop()
{
  if (digitalRead(BUTTON) == LOW)  // If button is pushed (can be any type of input)
  {                                // update the position of the servos continuously 
    right_leg.update();
    left_leg.update();
  }
}
于 2018-09-15T20:41:32.553 回答