c++ - 伺服电机和电位器问题:程序插入板时不移动
问题描述
该代码旨在利用电位计来转动伺服电机。当我试图将它插入程序时,伺服器根本没有移动,我不知道这是我的电路板、我的接线还是我的代码的结果。如果有人可以帮助或提供一些帮助,将不胜感激。我使用的板是 Nucleo STM L476RG 板,电机是微型 SG90。
#include "mbed.h"
#include "Servo.h"
#include "iostream"
Servo myservo(D6);
AnalogOut MyPot(A1);
int main() {
float PotReading;
PotReading = MyPot.read();
while(1) {
for(int i=0; i<100; i++) {
myservo.SetPosition(PotReading);
wait(0.01);
}
}
}
此外,我使用的代码在已发布的库伺服中将此代码列为 Servo.h
#ifndef MBED_SERVO_H
#define MBED_SERVO_H
#include "mbed.h"
/** Class to control a servo on any pin, without using pwm
*
* Example:
* @code
* // Keep sweeping servo from left to right
* #include "mbed.h"
* #include "Servo.h"
*
* Servo Servo1(p20);
*
* Servo1.Enable(1500,20000);
*
* while(1) {
* for (int pos = 1000; pos < 2000; pos += 25) {
* Servo1.SetPosition(pos);
* wait_ms(20);
* }
* for (int pos = 2000; pos > 1000; pos -= 25) {
* Servo1.SetPosition(pos);
* wait_ms(20);
* }
* }
* @endcode
*/
class Servo {
public:
/** Create a new Servo object on any mbed pin
*
* @param Pin Pin on mbed to connect servo to
*/
Servo(PinName Pin);
/** Change the position of the servo. Position in us
*
* @param NewPos The new value of the servos position (us)
*/
void SetPosition(int NewPos);
/** Enable the servo. Without enabling the servo won't be running. Startposition and period both in us.
*
* @param StartPos The position of the servo to start (us)
* @param Period The time between every pulse. 20000 us = 50 Hz(standard) (us)
*/
void Enable(int StartPos, int Period);
/** Disable the servo. After disabling the servo won't get any signal anymore
*
*/
void Disable();
private:
void StartPulse();
void EndPulse();
int Position;
DigitalOut ServoPin;
Ticker Pulse;
Timeout PulseStop;
};
#endif
它还有一个 .cpp 文件与它在同一个地方,所以如果有人需要它作为参考,我会将它作为编辑发布。我也会把接线放好以防万一
伺服是SG90。
解决方案
立即观察
我现在看到五个问题,从“可能是问题”到“可能是问题”。我能够辨认出你照片上的别针标签,你的别针分配似乎是正确的。假设没有奇怪的电线或电压问题:
您的模拟引脚应该是一个
AnalogIn
,而不是一个AnalogOut
。虽然AnalogOut
有能力read
,但它用于反馈,以确保您的输出符合您的预期。现在,作为一个AnalogOut
,您实际上是在此引脚上充当电压源并设置电压而不是测量电压。你没有打电话
Servo::Enable
。该文档告诉您如何调用Servo::Enable
. 确保调用它。您甚至需要指定伺服的起始位置,这将允许您对输出和伺服进行故障排除(请参阅稍后的故障排除)。AnalogIn::read
返回一个float
between[0.0, 1.0]
来表示输入线上读取的电压与系统电压(通常为 5V 或 3.3V)之间的比率。但是,Servo::SetPosition
需要一个整数来表示int
脉冲信号正部分的长度(以微秒为单位 - 在您的情况下介于 0 和 20,000 之间)。如果您尝试将结果传递给AnalogIn::read
toServo::SetPosition
,那么您float
将被转换为 0 (除了一个罕见的情况,它是1
)。您需要将模拟输入转换为整数输出。现在在您的代码中,您只是在程序开始时读取模拟输入引脚的状态。您进入一个无限循环,并且再也不会读取此模拟输入。你可以随心所欲地转动那个旋钮,但它永远不会影响程序。您需要多次读取模拟输入。将其移动到循环内。
只是一个风格的东西,但你不需要那个内部
for
循环。除了使您的代码混乱之外,它不会做任何事情。如果您希望i
在将来的某个时间点使用 的值,则将其保留,否则请放弃它。
故障排除
幸运的是,许多系统可以被认为是许多盒子(子系统),它们之间画有箭头。如果所有的盒子都在正确地完成它们的工作并且它们被插入到正确的下一个盒子中,那么整个系统作为一个整体工作。您的系统如下所示:
+-----+ +-----+ +----------------+ +-------------+ +--------------------+ +-----+ +-------+
| Pot |-->| ADC |-->| AnalogIn::read |-->| Float-to-us |-->| Servo::SetPosition |-->| PWM |-->| Servo |
+-----+ +-----+ +----------------+ +-------------+ +--------------------+ +-----+ +-------+
所有这些子系统共同构成了您的整个系统。如果其中一个链接不能正常工作,整个事情就不能正常工作。通常(或者至少我们喜欢想象我们有时间时会这样做),我们对系统和子系统进行测试,以确保它们根据输入产生预期的输出。如果您将输入应用于其中一个框,并且输出是您所期望的,那么该框就很好。给它一个绿色复选标记并移动到下一个。
对这些中的每一个进行测试可能类似于:
电位器: 输入:旋动旋钮,输出:中间引脚电压为接近系统电压(5V或3.3V),一路旋转至另一端接近0,两者之间近似线性变化两端。你需要一个万用表来测量这个。
ADC(模数转换器): 输入:输入引脚上的一些电压。一旦你确认它工作正常,你可以通过扭转电位器来改变它。输出:这有点难,因为输出是微控制器中的一个寄存器。我不知道你的硬件的调试环境是什么样的,所以我不能告诉你如何测量这个输出。如果您不知道如何使用调试器,您可以假设这可行并继续下一个(但您确实应该学习如何使用硬件的调试器)
AnalogIn::read
: 输入: ADC的寄存器值。输出:一些介于 0.0 和 1.0 之间的浮点数。我们可以同时测试 ADC 和AnalogIn::read
功能,将它们视为一个子系统,以引脚电压作为输入,浮点值作为输出。再次为此,您将需要一些调试功能。打印语句或串行连接或开发环境或其他东西。浮点数到我们的转换: 输入: 0.0 和 1.0 之间的浮点数。输出:一个介于 0 和 20,000 之间的整数,与浮点输入成比例(或成反比,取决于所需的功能)。同样,由于我们正在查看变量,因此您需要使用调试环境。
Servo::SetPosition
输入:一个介于 0 和 20,000 之间的整数,表示输出脉冲宽度调制 (PWM) 信号的占空比(高周期)。输出:增加这个数字会增加观察到的占空比。减少会减少它。我们中占空比的长度大约等于代码中的设定长度。你需要一个示波器来观察占空比。或者,如果您的伺服系统正在工作,那么您应该看到它在变化时移动。伺服: 输入:一个PWM信号。输出:角度位置。0% 的占空比应该一直到一个极端,而 100% 的占空比应该旋转到另一个极端。
结论
将您的系统视为一系列子系统。独立测试每一项。你不能指望下一个子系统会“弥补”前一个子系统的不足。他们都需要工作。
推荐阅读
- flutter - 具有相同 key.jks 的颤振签名应用程序不起作用
- javascript - 订阅函数中未定义的组件变量
- javascript - 元素的值被 JavaScript 改变了两次
- azure - 如何知道 Azure PowerShell 中附加到 VM 的子网名称?
- java - 如何在单击按钮时更改列表项的背景颜色?
- java - Angular Post 请求进入挂起状态并且没有命中服务器
- linux - 列出文件夹中的基本文件,其中包含多个带有日期戳的文件版本
- java - 通过登录页面以使用 JSoup 进行网络爬虫
- recursion - 创建交错元素列表:Prolog
- sql - 将列移动到行