C++ 伺服电机和电位计问题:程序插入电路板时不移动
此代码旨在利用电位计转动伺服电机。当我试图将其插入程序时,伺服根本没有移动,我不知道这是我的电路板、接线或代码造成的。如果有人能为此事提供帮助,我们将不胜感激。我使用的板是Nucleo STM L476RG板,电机是micro SG90C++ 伺服电机和电位计问题:程序插入电路板时不移动,c++,embedded,stm32,mbed,C++,Embedded,Stm32,Mbed,此代码旨在利用电位计转动伺服电机。当我试图将其插入程序时,伺服根本没有移动,我不知道这是我的电路板、接线或代码造成的。如果有人能为此事提供帮助,我们将不胜感激。我使用的板是Nucleo STM L476RG板,电机是micro SG90 #include "mbed.h" #include "Servo.h" #include "iostream" Servo myservo(D6); AnalogOut MyPot(A1); int main() { float PotReadi
#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);
}
}
}
#包括“mbed.h”
#包括“伺服.h”
#包括“iostream”
伺服myservo(D6);
模拟MyPot(A1);
int main(){
浮雕;
PotReading=MyPot.read();
而(1){
用于(int i=0;i 1000;位置-=25){
*伺服1.设置位置(pos);
*等待(20);
* }
* }
*@endcode
*/
类伺服{
公众:
/**在任何mbed引脚上创建新的伺服对象
*
*@mbed上连接伺服的参数引脚
*/
伺服(PinName引脚);
/**改变伺服的位置。在美国的位置
*
*@param NewPos伺服位置的新值(us)
*/
无效设置位置(int NewPos);
/**启用伺服。未启用伺服将无法运行。启动位置和周期均在美国。
*
*@param StartPos伺服启动位置(us)
*@param Period每个脉冲之间的时间。20000 us=50 Hz(标准)(us)
*/
无效启用(int StartPos,int期间);
/**禁用伺服。禁用伺服后,将不再获得任何信号
*
*/
无效禁用();
私人:
无效启动脉冲();
void EndPulse();
内部位置;
数字输出伺服销;
股票脉冲;
超时脉冲停止;
};
#恩迪夫
它还有一个.cpp文件在它的同一个地方,所以如果有人需要它作为参考,我会把它作为一个编辑发布。我也会把接线以防万一
伺服系统是一个控制系统
电路板的布线:
即时观察
我现在看到五个问题,从“可能有问题”到“可能有问题”。我能辨认出你照片上的pin标签,你的pin分配似乎是正确的。假设没有奇怪的电线或电压问题:
模拟输入
,而不是模拟输出
。虽然模拟输出
具有读取
的能力,但它用于反馈,以确保您的输出是您所期望的。现在,作为模拟输出
,您实际上充当了该管脚上的电压源并进行了设置测量电压,而不是测量电压Servo::Enable
。文档告诉您如何调用Servo::Enable
。请确保调用它。您甚至需要指定伺服的起始位置,这将允许您对输出和伺服进行故障排除(请参阅后面的故障排除)AnalogIn::read
返回介于[0.0,1.0]
之间的浮点值,以表示输入线上读取的电压与系统电压之间的比率(通常为5V或3.3V)。但是,伺服::设置位置
需要一个表示长度的整数(作为脉冲信号正部分的int
(微秒-在您的情况下介于0和20000之间)。如果您尝试将AnalogIn::read
的结果传递给Servo::SetPosition
,则您的浮点值将转换为0(除非是1
时的一种罕见情况)。您需要将模拟输入转换为整数输出
循环中使用。它除了扰乱你的代码外,什么都不做。如果你希望在将来某个时候使用i
的值,那么就把它留在里面,否则就放弃它
+-----+ +-----+ +----------------+ +-------------+ +--------------------+ +-----+ +-------+
| Pot |-->| ADC |-->| AnalogIn::read |-->| Float-to-us |-->| Servo::SetPosition |-->| PWM |-->| Servo |
+-----+ +-----+ +----------------+ +-------------+ +--------------------+ +-----+ +-------+
所有这些子系统一起构成了整个系统。如果其中一个链接不能正常工作,整个系统就不能正常工作。通常情况下(或者至少我们愿意想象我们有时间时会正常工作),我们对系统和子系统应用测试,以确保它们根据输入生成预期的输出。如果将输入应用到其中一个框中,并且输出是预期的,则该框是良好的。为其打上绿色复选标记,然后移到下一个框中
对其中每一项的测试可能类似于:
AnalogIn::read
+-----+ +-----+ +----------------+ +-------------+ +--------------------+ +-----+ +-------+
| Pot |-->| ADC |-->| AnalogIn::read |-->| Float-to-us |-->| Servo::SetPosition |-->| PWM |-->| Servo |
+-----+ +-----+ +----------------+ +-------------+ +--------------------+ +-----+ +-------+
Servo output( D6 ) ;
output.Enable( 1500, 20000 ) ; // Centre position, 50Hz
AnalogOut input(A1);
_______
| |
V |
get-input | <repeat>
set-output |
|_______|
float set_point = input.read() ;
output.SetPosition( (int)( (set_point * 1000) + 1000 ) ; // Scale to 1 to 2ms
uint16_t set_point = input.read_u16() ;
output.SetPosition( ((set_point * 1000) >> 16) + 1000 ) ;
#include "mbed.h"
#include "Servo.h"
int main()
{
// Hardware parameters
static const int SERVO_FREQ = 50 ; // Hz
static const int SERVO_PERIOD = 1000000 / SERVO_FREQ ; // microseconds
static const int SERVO_MIN = 1000 ; // 1ms in microseconds
static const int SERVO_MAX = 2000 ; // 2ms in microseconds
static const int SERVO_RANGE = SERVO_MAX - SERVO_MIN ;
// I/O configuration
AnalogIn input( A1 ) ;
Servo output( D6 ) ;
output.Enable( SERVO_MIN, SERVO_PERIOD ) ;
// Control loop
for(;;)
{
float set_point = input.read() ; // 0.0 to 1.0
output.SetPosition( set_point * SERVO_RANGE + SERVO_MIN ) ; // 1 to 2ms
wait_us( SERVO_PERIOD ) ; // wait for one complete PWM cycle.
}
}
uint16_t set_point = input.read_u16() ; // 0 to 2^16
output.SetPosition( ((set_point * SERVO_RANGE) >> 16) // 1 to 2ms
+ SERVO_MIN ) ;
output.SetPosition_u16( input.read_u16() ) ;
wait_us( SERVO_PERIOD ) ;