伺服响应伺服测试仪,而不响应微控制器。信号看起来一样


8

我有一个TowerPro MG90D伺服器(制造商链接)(ServoDatabase Link)。
它具有180度范围(非连续)。

TowerPro MG90D

它对我的伺服测试仪反应很好:
伺服测试仪

在测试仪上观察以下7%的占空比(大约90度):

示波器伺服测试仪

示波器伺服测试仪

伺服响应良好。


但是,当我servo.write()与Arduino Mega 2560克隆一起使用时,伺服器不会响应任何角度输出。我还有其他几个伺服器,它们在相同的引脚上使用相同的代码也可以正常工作。

使用以下命令在Arduino上观察以下7%的占空比servo.write(90)

范围arduino伺服90度

没有反应。伺服是“一跳”;它没有担任任何职务。


在写这个问题时,我想到了尝试servo.writeMicroseconds()

这里是servo.writeMicroseconds(1450)

范围arduino伺服1450ms

伺服响应!

这是servo.writeMicroseconds(1472)(工作中),时间间隔与prevoius非工作中相同servo.write(90)

示波器arduino伺服器1472ms

servo.writeMicroseconds(1550) (工作中):

示波器arduino伺服1550ms


有什么区别?
伺服测试仪的工作频率servo.write()为49.5Hz ,而失败的频率为49.9Hz。我想知道0.4Hz是否会有所不同,但是后来我看到它servo.writeMicroseconds()也以49.9Hz起作用。

在上面的范围捕获中,可以看出两者servo.write(90)servo.writeMicroseconds(1472)具有相同的时间间隔:
 1,474,560ns HIGH
18,544,640ns LOW

信号是如此相似... 是什么原因导致servo.write()无法工作?

我的代码是尽可能基本的:

#include <Servo.h>
Servo serv1;

void setup() {
  serv1.attach(3); // Pin 3
}

void loop() {
  serv1.write(90); // No response
  delay(3000);

  serv1.writeMicroseconds(1472); // Works
  delay(3000);

  serv1.write(0); // No response
  delay(3000);

  serv1.writeMicroseconds(1800); // Works
  delay(3000);
}

原理图

模拟此电路 –使用CircuitLab创建的原理图


我既尝试了台式线性电源,也尝试使用降压转换器从9V降压。
2016年

1
使用时,您确定整整3秒钟都有稳定的波浪write吗?确实没有理由使伺服器不工作,所以我会质疑您的信号。
德米特里·格里戈里耶夫

1
@博特然后我很难相信你的故事。
德米特里·格里戈里耶夫

2
@BigHomie:就示波器图像而言,信号是相同的。除了信号之外,还有其他事情在发生。接地不良是一件事,可能会对名义上相同的信号产生不同的反应。
JRE

2
如果可能,在连接了伺服器的情况下在伺服信号线上捕获两条示波器迹线。仅使用serv1.write()的一条跟踪,仅使用serv1.writeMicroseconds()的一条跟踪。张贴两个痕迹。为了获得更多的魅力,请在连接了伺服器的情况下从测试仪中插入第三条迹线。
neonzeon

Answers:


0

首先,先说一句。您似乎对伺服器的工作方式有些误解。伺服不受PWM控制,它们不知道或不在乎您是否以49 Hz的频率发送脉冲。他们不知道脉冲是某个任意周期的某个百分比。伺服器不在乎脉冲之间的时间是多少。我之所以这样说,是因为您似乎异常地专注于实际上并不重要的事情。

Servos甚至不真正知道或关心给定时间的电压高低。他们只关心一件事:上升沿和下降沿之间的时间。

通过检测电压上升沿并测量直到出现下降沿的时间来控制伺服。有效时间通常在1.0到2.0毫秒之间,但随伺服系统的不同而不同。

您可以将其控制为1Hz,10Hz,50Hz,100Hz。大多数人将对更高的脉冲率做出响应,但这又是可变的。我要说的是,频率,占空比,脉冲之间的持续时间都与您的问题不太相关,这就是伺服器在您期望的时候没有响应。

唯一相关的是您的脉冲边缘,您没有对其进行任何关注。如果您想弄清楚这一点,请先查看重要的事物,并仔细捕捉您的脉搏边缘,诸如此类的事物。在这些屏幕快照中,您没有捕获到任何有用的信息,这可能就是为什么似乎没有问题或差异的原因。有很多问题或差异是您所测得的永远看不到的。

我看到的是,无论是脉冲还是地面,对非工作脉冲序列的捕获都比其他任何一个都更脏。这很奇怪,因为它应该调用与其他函数相同的函数。为什么这么吵呢?

更重要的是,在非工作状态捕获中,请查看“下降时间”。809µs?示波器认为下降时间持续0.8ms。那很不好。显然这是不正确的,但事实仍然存在,那就是它所能衡量的。

这是边缘肮脏的经典标志。想一想。如果此脉冲使示波器的高端测试设备愚蠢地看到了很长的边沿或下降时间,或者太脏了,以至于无法始终正确地检测到下降沿(或谁知道),那么那个差劲cr脚的$ 8伺服器有什么机会拾起像样的下降边缘?

如果伺服器未在可接受的脉冲范围内获得有效脉冲(例如下降沿时间过长,太脏或错过了),并且伺服器根据可能会或可能没有任何作用的边沿进行估算对您认为的脉冲边沿进行处理,然后其响应就好像已关闭一样。

换句话说,它不仅不会移动,而且不会阻止其轴移动。就像您所看到的那样,它将只是li行。

现在,这引出了一个问题。... 为什么调用伺服。写入会影响边缘质量?

你说一个克隆人。像这个?在此处输入图片说明

由于极差的去耦作用,这些克隆尤其表现出不稳定的行为。每个电源引脚上都应有去耦电容,并应尽可能靠近mega2560。在实际的arduino上,确实存在。但是,在这些克隆上,它们相距太远,或者可能丢失了,很难分辨。从板上看,很明显它不会可靠运行,这很重要。

那有什么区别呢?

当您调用servo.write时,它将堆栈推入的位置比调用writeMicroseconds时要高。鉴于mega2560的3字节堆栈指针(17位),它必须翻转一堆关键的位,而在您调用writemicroseconds时则不需要。我知道这似乎是不太可能的差异,但是我经历了相当多的去耦不良的微控制器,尤其是atmega,尤其是在使用计时器和/或推入或弹出堆栈时,atmegas似乎表现出奇怪的行为。对我来说,发生了类似的事情,当我尝试使用PWM驱动LED时,只有堆栈损坏了,但是如果我将所有内容都串联放置而不推入堆栈,那么它就会起作用。不良的去耦最终是问题所在。

我完全希望由于atmega2560众所周知的原因而导致的去耦不良,会对脉冲的边缘质量产生不利影响,但是只有在您将堆栈推入之前。该伺服器只是不能完全处理这些边缘被污损的方式,因此在这种情况下它看不到任何有效脉冲。其他伺服器显然可以管理它。

像这样,去耦的东西总是很奇怪而且很具体。这就是为什么去耦如此重要的原因。让问题陷入噩梦般的境地,电容不足会导致您戴着漂亮的胖陶瓷电容,并尽可能地靠近芯片。


0

这可能与.write()例程完成的输出引脚设置有关。请尝试使用1K下拉电阻,该电阻不起作用,然后将其卸下并使用上拉电阻。这样可以平衡例程可能设置的任何内部星期上拉/下拉电阻的影响。当您使用示波器测量信号时,探头的内部电阻充当下拉电阻。
如果未连续连续设置10个脉冲的信号,大多数伺服器还将释放内部电动机的电源。这用于节省电量。


恐怕您的答案不正确。Servo.write()将角度作为输入,而不是时间。人们不应该盲目地投票赞成答案。
BORT

是的,我的错误,我没有很好地阅读代码。这可能与.write()例程完成的输出引脚设置有关。
555年

2
这本来是我的第一个想法,但示波器痕迹似乎反驳了这一点。地面缺失和上拉/下移情况不同可能是导致发送了相同信号但没有到达那里(探头位置之后)。
KalleMP '02

我认为@KallieMP可能是正确的。上拉/下拉电阻器很可能是答案。他们可以限制电流。脉冲可能正确形成,但没有足够的驱动力。因此,无论Servo.write()的特定功能如何,电流水平都必须与伺服测试仪的输出精确匹配才能获得相同的结果。
SDsolar '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.