Случайное сервомоторное движение с помощью Arduino Uno

Недавно я работал над проектом, включающим 8 сервоприводов Tower Pro sg90 и Arduino Uno. Проблема, с которой я сталкиваюсь, заключается в том, что сервоприводы будут случайным образом двигаться при подключении, даже не получая сигнала от Arduino.

В частности, иногда сервоприводы будут работать идеально, и входное движение сервоприводов будет прекрасным, но затем внезапно сервоприводы начнут дергаться и беспорядочно двигаться вперед и назад. Затем я отключаю питание и подключаю его обратно, и я иногда буду работать снова, а иногда нет.

Я не думаю, что проблема в мощности, потому что я питаю сервоприводы внешне с помощью источника питания 5,5 В, который может обеспечить 2,5 ампера. Я также убедился, что между Arduino и блоком питания есть общая земля. Кроме того, я не думаю, что это проблема сломанного сервопривода, потому что у меня есть эта проблема со всеми восемью. В моем коде у меня есть входные контакты для управления сервоприводами, которые являются просто кнопками. Эти кнопки также имеют опущенные резисторы, поэтому я не думаю, что проблема также заключается во входе. Я использую библиотеку сервоприводов Arduino.

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

Если у кого-то есть идеи о решении моей проблемы, которые я еще не пробовал, это было бы удивительно!
Спасибо - Ксандер

#include <Servo.h>

Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;
Servo servo7;
Servo servo8;

void setup(){
  pinMode(5, INPUT);
  pinMode(4, INPUT);
  pinMode(3, INPUT);
  pinMode(2, INPUT);
  pinMode(1, INPUT);
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  servo1.attach(13);
  servo2.attach(12);
  servo3.attach(11);
  servo4.attach(10);
  servo5.attach(9);
  servo6.attach(8);
  servo7.attach(7);
  servo8.attach(6);
}

void loop(){
  if(digitalRead(5)==LOW){
    servo1.write(120);
    delay(20);
  }
  else{
    servo1.write(50);
    delay(20);
  }
  if(digitalRead(4)==LOW){
    servo2.write(110);
    delay(20);
  }
  else{
    servo2.write(200);
    delay(20);
  }
  if(digitalRead(3)==LOW){
    servo3.write(120);
    delay(20);
  }
  else{
    servo3.write(50);
    delay(20);
  }
  if(digitalRead(2)==LOW){
    servo4.write(110);
    delay(20);
  }
  else{
    servo4.write(200);
    delay(20);
  }
  if(digitalRead(1)==LOW){
    servo5.write(120);
    delay(20);
  }
  else{
    servo5.write(50);
    delay(20);
  }
  if(digitalRead(A3)==LOW){
    servo6.write(110);
    delay(20);
  }
  else{
    servo6.write(200);
    delay(20);
  }
  if(digitalRead(A2)==LOW){
    servo7.write(120);
    delay(20);
  }
  else{
    servo7.write(50);
    delay(20);
  }
  if(digitalRead(A1)==LOW){
    servo8.write(110);
    delay(20);
  }
  else{
    servo8.write(200);
    delay(20);
  }
}

, 👍0

Обсуждение

Сервоприводы нагреваются?, @Ritesh Sharma

Нет, вовсе нет. На самом деле они тоже не находятся под какой-либо нагрузкой., @Xander

Пожалуйста, покажите свой код. Вы можете отредактировать вопрос, включить его туда и правильно отформатировать., @chrisl

Как говорит Джроберт, вам захочется (точно) развенчать и поддерживать текущее состояние. Я бы также позаботился о том, чтобы задержка была достаточно большой для того, чтобы сервопривод достиг своего конечного положения. Я бы также уменьшил количество сервоприводов вдвое и посмотрел, не исчезнет ли проблема, но теоретически восемь сервоприводов должны быть в порядке на Uno. Вы также можете попробовать неблокирующую "задержку", но я не думаю, что это должно иметь значение. Перекрестные разговоры маловероятны. Я думаю, что завершение каждой комбинации кнопок и сервоприводов было бы хорошим способом начать работу., @Dave Newton


1 ответ


1

Вы вызываете servoX.write() неоднократно, даже когда ни одна кнопка не изменилась. Каждый вызов отключается на короткое время, пока значение сервопривода обновляется. Это происходит, возможно, 40 раз/сек и может испортить синхронизацию сервопривода каким-то непостоянным образом. Попробуйте вызвать функции servoX.write() только один раз, только когда его состояние кнопки перешло в новое состояние.

Обновление:

не могли бы вы привести пример, пожалуйста

  bool prevButton5 = LOW;            // один из них для каждой кнопки
    :                                // вне loop() func.
    :

  if(digitalRead(5) != prevButton5){  // кнопка изменилась?
    prevButton5 = !prevButton5;       // сохранить новое состояние кнопки
    if(preButton5 == LOW){            // (ваш же код отсюда вниз)
      servo1.write(120);
      delay(20);
    }
    else{
      servo1.write(50);
      delay(20);
    }
  }
  • Сделайте логическое значение для каждой кнопки.
  • Оберните каждый из ваших сегментов кнопки, как я сделал для button5. Обратите внимание, что ваш код теперь выполняется только в том случае, если соответствующая кнопка изменилась, поэтому у вас будет гораздо меньше вызовов servoX.write ().

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

Я также проигнорировал концепцию switch-bounce, чтобы сохранить количество изменений на низком уровне, но вы должны посмотреть ее и рассмотреть. Switch-bounce-это явное подпрыгивание контактов переключателя в течение нескольких миллисекунд во время перехода от открытого к закрытому или наоборот, что приводит к нескольким циклам make-break-make....-make (или обратному) при нажатии или отпускании кнопки. Я бы, вероятно, сделал (или искал) функцию сброса кнопки и вызвал ее для конкретной кнопки, которую я тестирую, если бы увидел, что эта кнопка изменилась.

Сначала попробуйте "грубое и грубое" исправление, которое я предложил, и заставьте его работать. Затем, если вам интересно, попробуйте сделать одно или несколько уточнений.

Обновление:

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

Это предполагает либо одно, либо оба

  • перекрестные разговоры;
  • соединения штекерных проводов менее прочны, особенно когда провода движутся.

Попробуйте:

  • прокладывать сервокабели так, чтобы они были как можно дальше друг от друга;
  • проводка только нескольких сервоприводов, причем в разных комбинациях;
  • также попробуйте закомментировать код - или нет - для тех сервоприводов, которые вы отключили на предыдущем шаге.

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

,

Это звучит многообещающе, но я немного смущен, не могли бы вы привести пример, пожалуйста. Спасибо, @Xander

Ну, я попробовал код, и он работает, но через определенное время сервопривод снова начинает дрожать. Я бы сказал, что сервопривод дрожит меньше, но он все равно дрожит и дергается. Я также заметил, что если я прикоснусь к контакту 5 В Arduino, то на Arduino загорится индикатор "TX", и сервопривод переместится на большое расстояние по часовой стрелке. Я думаю, что код помог, но он еще не исправил это. Любые другие мысли, спасибо, @Xander

Я просто отсоединяю входные контакты от кнопок, и сервоприводы все еще дрожат и дергаются, особенно когда я перемещаю весь arduino и провода. Это говорит мне о том, что проблема не в моей схеме, а, вероятно, как-то связана с самим arduino. Как вы думаете, он сломан или что-то еще?, @Xander

@Xander, если он дрожит и дергается, когда вы "перемещаете arduino и провода", это звучит как проблема с проводкой., @Dave Newton