Сервопривод реагирует на сервотестер, а не на микроконтроллер. Сигналы выглядят одинаково

У меня есть сервопривод TowerPro MG90D ( ссылка производителя ) ( ссылка на ServoDatabase ).
Он имеет диапазон 180 градусов (прерывистый).

БашняПро MG90D

Он отлично реагирует на мой тестер сервоприводов:
Сервотестер

Наблюдайте за следующим рабочим циклом 7% (около 90 градусов) на тестере:

тестер сервопривода

тестер сервопривода

Сервопривод нормально реагирует.


Однако, когда я использую servo.write()свой клон Arduino Mega 2560, сервопривод не реагирует ни на какой угол. У меня есть несколько других сервоприводов, которые прекрасно работают с тем же кодом на тех же контактах.

Соблюдайте следующий рабочий цикл 7% на Arduino с помощью servo.write(90):

прицел ардуино сервопривод 90 градусов

Нет ответа. Сервопривод «хромает»; он не занимает никаких позиций.


Пока я писал этот вопрос, я подумал о том, чтобы попробовать servo.writeMicroseconds().

Вот servo.writeMicroseconds(1450):

прицел ардуино сервопривод 1450мс

Сервопривод отвечает!

Вот servo.writeMicroseconds(1472)(рабочий), у которого такие же временные промежутки , как и у предыдущего нерабочего servo.write(90)!

прицел ардуино сервопривод 1472мс

servo.writeMicroseconds(1550)(работающий):

прицел ардуино сервопривод 1550мс


В чем разница?
Сервотестер работал на частоте 49,5 Гц, но servo.write()не работал на частоте 49,9 Гц. Я задавался вопросом, имеет ли какое-то значение 0,4 Гц, но потом я вижу, что это servo.writeMicroseconds()работает и при 49,9 Гц.

В приведенных выше снимках области видно, что оба 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

Я пробовал как настольный линейный источник питания, так и понижающий преобразователь для понижения напряжения с 9 В.
Вы уверены, что у вас есть устойчивая волна в течение полных 3 секунд при использовании write? На самом деле нет причин, чтобы сервопривод не работал, поэтому я бы поставил под сомнение ваши сигналы.
@DmitryGrigoryev Мне он кажется довольно устойчивым. Никаких рывков или мерцаний на моем прицеле, которые я вижу.
@Bort Тогда мне трудно поверить в твою историю.
@DmitryGrigoryev Я тоже. Но я продолжаю щипать себя и чувствую, что это не сон.
Я бы проверил землю между сервоприводом и Arduino. Возможно, разъем немного отошел и лучше контактирует с выводами сервотестера.
Земля @JRE не имеет значения, по какой-то причине servo.write()посылает сигнал , отличный от сервотеста и servo.writeMilliseconds(uS) . Я думаю , что ОП ищет фактическую разницу между сигналами, потому что для всех намерений и целей они кажутся одинаковыми.
@BigHomie: сигналы идентичны в том, что касается изображений прицела. Помимо сигнала, что-то происходит. Плохое заземление — это то, что может вызвать разную реакцию на номинально идентичные сигналы.
Куда вы подключаете прицел? на входе сервопривода или на плате?
@ ноутбук2d От платы идет провод ~ 8 см, который подключается к проводу ~ 8 см сервопривода. Это соединение, где мой прицел прикреплен.
Глядя на servo.write()код , он вызывает servo.writeMicroseconds(). Поэтому очень удивительно, что вы говорите, что writeMicroseconds()работает, а write()что нет.
Если возможно, зафиксируйте две трассировки осциллографа на линии сигнала сервопривода с подключенным сервоприводом . Одна трассировка только с serv1.write() и одна трассировка только с serv1.writeMicroseconds(). Опубликуйте обе трассировки. Для дополнительного шарма добавьте третью кривую от вашего тестера с подключенным сервоприводом .
Вы упомянули, что другие сервоприводы работают, верно? Это сервоприводы одной модели? Вы пробовали их на этой конкретной булавке?
Я согласен с JRE. Где-то есть разница, которую вы не учитываете.

Ответы (2)

Сначала короткое отступление. Вы, кажется, немного не понимаете, как работают сервоприводы. Сервоприводы не контролируются ШИМ, и они не знают и не заботятся о том, что вы отправляете импульсы с частотой 49 Гц. Они не знают, что импульс составляет какой-то процент от произвольного периода. Сервоприводу все равно, какое время между импульсами. Я говорю это, потому что вы кажетесь необычайно сосредоточенным на вещах, которые на самом деле не имеют значения.

Сервоприводы даже не знают и не заботятся о том, высокое или низкое напряжение в данный момент времени. Их волнует только одно: время между нарастающим и спадающим фронтами.

Сервопривод управляется путем обнаружения нарастающего фронта напряжения и измерения времени до появления спадающего фронта. Допустимое время обычно составляет от 1,0 до 2,0 мс, но может варьироваться от сервопривода к сервоприводу.

Вы можете управлять им на 1 Гц, 10 Гц, 50 Гц, 100 Гц. Большинство из них отреагируют на еще более высокую частоту пульса, но, опять же, это может быть разным. Я пытаюсь сказать, что частота, рабочий цикл, продолжительность между импульсами - все это не может быть менее важным для вашей проблемы, заключающейся в том, что сервопривод не отвечает, когда вы этого ожидаете.

Единственное, что имеет значение, это края вашего пульса, на которые вы не обратили никакого внимания. Если вы хотите в этом разобраться, пожалуйста, начните с того, что имеет значение, сфотографируйте фронты пульса крупным планом и тому подобное. Вы не зафиксировали ничего полезного на этих снимках экрана, поэтому, вероятно, здесь нет проблем или различий. Есть много проблем или различий, которые никогда не были бы видны с тем, что вы измерили.

Что я вижу, так это то, что захват нерабочей последовательности импульсов заметно грязнее, как импульса, так и земли, чем любой другой. Что странно, поскольку он должен вызывать ту же функцию, что и другие. Почему он такой шумный?

Что еще более важно, в нерабочем захвате посмотрите на «время падения». 809 мкс? Ваш осциллограф считает, что время спада составляет 0,8 мс. Это плохо. Ясно, что это неверно, но факт остается фактом: именно это он и измеряет.

Это классический признак грязного края. Подумай об этом. Если этот импульс обманывает ваше высококачественное тестовое оборудование, то есть ваш осциллограф, заставляя видеть смехотворно длинный фронт или время спада, или, может быть, настолько грязный, что он просто не может правильно определить спадающий фронт все время (или кто знает), тогда какие шансы у этого бедного дрянного маленького сервопривода за 8 долларов уловить приличный спадающий фронт?

Если сервопривод не получает действительный импульс (например, если задний фронт занимает слишком много времени, слишком грязный или пропущен) в пределах допустимого диапазона импульсов, и сервоприводы считают по фронтам, которые могут иметь или не иметь ничего общего делайте с тем, что вы считаете краями импульса, тогда он реагирует так же, как если бы он был выключен.

Другими словами, он не только не движется, но и не сопротивляется движению своего вала. Он просто будет вялым, именно так, как вы видите.

Теперь возникает вопрос... почему вызов servo.write влияет на качество края?

Вы сказали клон. Как этот?введите описание изображения здесь

Эти клоны, в частности, имеют тенденцию вести себя хаотично из-за невероятно плохой развязки. Развязывающие конденсаторы должны быть на каждом выводе питания и как можно ближе к mega2560. А на собственно ардуино действительно есть. Однако на этих клонах они слишком далеко или, возможно, отсутствуют, трудно сказать. Глядя на плату, очевидно, что она не будет работать надежно, это главное.

Так в чем же разница?

Когда вы вызываете servo.write, он перемещает стек выше, чем если бы вы вызывали writeMicroseconds. Учитывая 3-байтовый указатель стека mega2560 (17 бит), ему приходится переворачивать кучу критических битов, которые ему не нужны, когда вы вызываете writemicroseconds. Я знаю, что это кажется маловероятным, но я испытал свою долю плохо развязанных микроконтроллеров, и, в частности, atmegas, кажется, демонстрируют странное поведение, особенно при использовании таймеров и / или проталкивании или извлечении стека. У меня было нечто похожее, только стек был поврежден, когда я пытался управлять светодиодами с помощью ШИМ, но если я поставил все в строку, не проталкивая стек, это сработало. Плохая развязка была в конечном счете проблемой.

Я полностью ожидаю, что плохая развязка сможет по причинам, известным только atmega2560 и никому другому, иметь пагубное влияние на качество фронта этого импульса, но только когда вы толкаете стек прямо перед этим. Этот сервопривод просто не в состоянии справиться с загрязнением этих краев, поэтому в этом случае он не видит действительных импульсов. Другие сервоприводы, очевидно, справляются с этим.

Разделение вещей всегда причудливо и гиперспецифично, как это. Вот почему так важна развязка. Избавьтесь от кошмарного ада проблем, связанных с недостатком емкости, с хорошими толстыми керамическими колпачками и как можно ближе к чипу, насколько это физически возможно.

Это может быть связано с настройками выходного вывода, выполненными подпрограммой .write(). Пожалуйста, попробуйте использовать подтягивающий резистор 1K, если он не работает, удалите его и используйте подтягивающий резистор. это сбалансирует действие любого внутреннего подтягивающего/подтягивающего резистора, который может быть установлен программой. Когда вы измеряете сигнал с помощью осциллографа, внутреннее сопротивление пробника действует как понижающее.
Большинство сервоприводов также отключают питание внутреннего двигателя, если сигнал не задан в течение 10 импульсов подряд. Это используется для экономии энергии.

Боюсь, ваш ответ неверен. servo.write() принимает в качестве входных данных угол , а не время. Люди не должны слепо голосовать за ответы.
Да, моя ошибка, я плохо прочитал код. это может быть связано с настройками выходного вывода, выполненными подпрограммой .write().
Это было бы моей первой мыслью, хотя следы прицела, кажется, опровергают это. Отсутствие заземления и другая ситуация подтягивания вверх/вниз могут быть причиной того, что один и тот же сигнал отправляется, но не достигает цели (после местоположения зонда).
Я думаю, что @KallieMP, вероятно, прав. Подтягивающие/нижающие резисторы вполне могут быть ответом. Они могли ограничить ток. Импульсы могут формироваться правильно, но с недостаточным драйвом. Таким образом, независимо от конкретной функции servo.write(), текущие уровни должны точно соответствовать выходным данным сервотестера, чтобы получить тот же результат.