Mearm problems (servo conflict?)

I am lasercut a Mearm:

I used the Tower Pro 9g Micro servos. The brains are an arduino uno r3.

I’ve run test code (turn, extend, pick up an object, turn, retract, drop it) successfully. However, when I begin to incorporate joysticks (2-axis joysticks with a select button: http://amzn.to/2tlKCBA) I have problems.

As long as I leave the claw off the board, it works as expected (albeit a little quickly). As soon as I plug in the servo on pin 8, all the servos go crazy.

I’m powering the joysticks from the 5v off the arduino (I have also tried powering them off their own 5v plug pack – same solution)

I’m powering the servos from a 4 AAA battery pack (but I have also tested them with a 5v supply).

If I remove another servo from the mix and plugin the claw servo it still jumps around.

Even if I use another servo that is not attached to the arm, it does the same thing.

Changing pins does not help. (I tried changing the claw from 8 to 6.)

Changing the mapped values doesn’t help.

I’m at my wit’s end. I have five kids begging to be able to control their finished robots (we’re building them as part of a library summer program) with joysticks and I can’t get my example to work. Thank you in advance!

mearm-joy.ino (2.84 KB)

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Do you have a DMM to measure your servo supply voltage?

Thanks.. Tom.. :slight_smile:

Hi Tom, thank you for the reply! Here’s the code. I need to draw up something for the circuit, as it’s not much more than the servos going to a breadboard for power and the switches doing the same. Everything else is directly plugged into the arduino at the pins listed in the code.

Today’s plan is to try the microWrite function and see if that corrects the speed issue. I also found some code using inverse kinematics which might yield better results: meArm/JoysticksIK.ino at master · yorkhackspace/meArm · GitHub

#include <Servo.h>
// This sketch shows the basic operation of the Thumb Joystick (COM-09032) and breakoutboard (BOB-09110).
// The joystick outputs two analog voltages (VERT and HORIZ), and one digital signal (SEL) forthe pushbutton.
// Connections to joystick (change if you use different pins):

Servo middle, left, right, claw ; // creates 4 "servo objects"
const int VERT = A1; // analog
const int HORIZ = A2; // analog
const int VERT2 = A3; // analog
const int HORIZ2 = A4; // analog

//const int SEL = 11; // digital
int idx_middle = 90;
int idx_right = 90;
int idx_left = 90;
int idx_claw = 25;
// Also connect the joystick VCC to Arduino 5V, and joystick GND to Arduino GND.
// This sketch outputs serial data at 9600 baud (open Serial Monitor to view).
void setup()
{
  // make the SEL line an input
  //pinMode(SEL,INPUT);
  // turn on the pull-up resistor for the SEL line (see http://arduino.cc/en/Tutorial/DigitalPins)
  //digitalWrite(SEL,HIGH);
  middle.attach(9); // Attach PIN number with Servo
  middle.write(idx_middle); // Initial Servo of an angle 90
  right.attach(10); // Attach PIN number with Servo
  right.write(idx_right); // Initial Servo of an angle 90
  left.attach(11); // Attach PIN number with Servo
  left.write(idx_left); // Initial Servo of an angle 90
  claw.attach(8); // Attach PIN number with Servo
  claw.write(idx_claw); // Initial Servo of an angle 25
  delay(3000);
  // set up serial port for output
  Serial.begin(9600);
}
void loop()
{
  int vertical, horizontal,vertical2, horizontal2, select;
  // read all values from the joystick
  vertical = analogRead(VERT); // will be 0-1023
  horizontal = analogRead(HORIZ); // will be 0-1023
  vertical2 = analogRead(VERT2); // will be 0-1023
  horizontal2 = analogRead(HORIZ2); // will be 0-1023
  //select = digitalRead(SEL); // will be HIGH (1) if not pressed, and LOW (0) if pressed
  // print out the values
  
  idx_middle = map(horizontal, 0, 1023, 150, 30);
  middle.write(idx_middle);
  
  idx_left = map(vertical, 0, 1023, 30, 150);//idx_left = map(vertical2, 100, 900, 90, 150);
  left.write(idx_left);
  
  idx_right = map(vertical2, 0, 1023, 50, 150);
  right.write(idx_right);
    
  idx_claw = map(horizontal2, 0,1023, 0, 50);//claw = map(horizontal2, 0, 1023, 0, 180);
  claw.write(idx_claw);
  
  Serial.print("vertical: ");
  Serial.print(vertical);
  Serial.print(" horizontal: ");
  Serial.print(horizontal);
  Serial.print("vertical2: ");
  Serial.print(vertical2);
  Serial.print(" horizontal2: ");
  Serial.print(horizontal2);
  Serial.print(" select: ");
  
    Serial.print(" ");  
  Serial.print(idx_left);
    Serial.print(" ");
  Serial.print(idx_right);
    Serial.print(" ");
  Serial.print(idx_middle);
    Serial.print(" ");
  Serial.print(idx_claw);
    Serial.print(" ");
  
  if(select == HIGH)
    Serial.println("not pressed");
  else    
    Serial.println("PRESSED!!!!!");
}

If you really want to slow the servos down you can try VarSpeedServo.h library instead of Servo.h. Though if they're being controlled by joysticks I'm not sure why that is a problem.

You say attaching the claw servo makes all servos "go crazy". But are you getting any values from your serial writes? E.g. are the joystick values still normal or have they also gone crazy? What about connecting ONLY the claw servo? I.e. is it that one in particular or is it having 4 connected at once?

It does sound a lot like a power supply problem or perhaps a power wiring problem. Are all the grounds connected together properly?

Steve

The servos should not move any faster than you move the joysticks. If they do, may your joysticks are noisy? You could try averaging the joystick inputs over time:

  vertical = (vertical * 0.9) + analogRead(VERT) * 0.1; // will be 0-1023
  horizontal = (horizontal * 0.9) + analogRead(HORIZ) * 0.1; // will be 0-1023
  vertical2 = (vertical2 * 0.9) + analogRead(VERT2) * 0.1; // will be 0-1023
  horizontal2 = (horizontal2 * 0.9) + analogRead(HORIZ2) * 0.1; // will be 0-1023

You could do the math in long integers to avoid the ovehead of floating-point math:

  vertical       = ((vertical * 90UL)      + analogRead(VERT) * 10UL) / 100; // will be 0-1023
  horizontal   = ((horizontal * 90UL)  + analogRead(HORIZ) * 10UL) / 100; // will be 0-1023
  vertical2     = ((vertical2 * 90UL)     + analogRead(VERT2) * 10UL) / 100; // will be 0-1023
  horizontal2 = ((horizontal2 * 90UL) + analogRead(HORIZ2) * 10UL) / 100; // will be 0-1023

(The math can't be done in 'int' because 1024*90 exceeds the range of an integer (32,767)

Well, I tried all the suggestions and John Wasser was the winner. It's still not as crisp as the Teachmover (Teachmover Robot - The Old Robot's Web Site) I picked up for $25 at a thrift shop, but it's close enough that a bunch of 9 year olds will love it. :slight_smile: