MG90S pwm.setPWM() not working (solved)

Hey busy helpers and problem solvers out there.

following setup:
Arduino UNO R3,
Adafruit 16ch- 12 bit servo board.
seperate power supply to both.

1 MG90S on slot 0 of the servo controller.

if i run the demo script from adafruit the servo is doing a nice sweep as it is supposed to.
i can modify the values to get to the desired positions as long as it is still in a "for loop"

if i try to set a specific position it doesnt work at all. no clue why.

since the same code worked for 6 SG90S with the same controller board i am pretty confident, that its not the code.
and not the wiring.

and since i can move the servo if i connect it directly to the arduino, i assume the servo itself is not broken.

i have to admit that the servo, although its labeld as a "TOWER PRO MG90S" is probably fake since it looks differently.

this works:

void sweep(){
  int pulse1=0;
  for (pulse1=140; pulse1<=565; pulse1+=1){
  pwm.setPWM(0,0,pulse1);
  Serial.println(pulse1);
  delay(20);
  }

this doesn't:

 pwm.setPWM(0,0,250);

i have NOOOO CLUE at all what the problem is.
as i said, its moving in a loop, it worked fine with a bunch of SG90s.
same if i switch to microseconds. in a loop it works, just sending a microsecond value to move it, no response from the MG90

oh and i tried other MG90s too. same fake. but also same result

" in a loop it works, just sending a microsecond value to move it, no response from the MG90"

Below is some simple servo test code you can try. If this works, then the issue is probably something in your code.

// zoomkat 7-30-10 serial servo test
// type servo position 0 to 180 in serial monitor
// for writeMicroseconds, use a value like 1500
// Powering a servo from the arduino usually *DOES NOT WORK*.

String readString;
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);
  myservo.attach(9);
}

void loop() {

  while (Serial.available()) {

    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
      delay(3);
    } 
  }

  if (readString.length() >0) {
    Serial.println(readString);
    int n = readString.toInt();
    Serial.println(n);
    myservo.writeMicroseconds(n);
    //myservo.write(n);
    readString="";
  } 
}

That got a bit incoherent so lets check. Are you saying you have a complete program that sets a position using the one line you posted? And that exact program loaded into the same Arduino with the same PCA9685 board moves an SG90 to the correct position but won't move any of several MG90s at all? And nothing else is changed except you unplug an SG90 from the PCA9685 board slot 0 and plug in an MG90?

If so please post the COMPLETE program because really it sounds impossible.

Steve

steve that is exactly what i am saying.

here the code:

its a slightly altered version of the ADAFFRUIT demo code for the servo controller

/*************************************************** 
  This is an example for our Adafruit 16-channel PWM & Servo driver
  Servo test - this will drive 8 servos, one after the other on the
  first 8 pins of the PCA9685

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/products/815
  
  These drivers use I2C to communicate, 2 pins are required to  
  interface.

  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
// you can also call it with a different address and I2C interface
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40, Wire);

// Depending on your servo make, the pulse width min and max may vary, you 
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!
#define SERVOMIN  150 // This is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  600 // This is the 'maximum' pulse length count (out of 4096)
#define USMIN  600 // This is the rounded 'minimum' microsecond length based on the minimum pulse of 150
#define USMAX  3000 // This is the rounded 'maximum' microsecond length based on the maximum pulse of 600
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates

// our servo # counter
uint8_t servonum = 0;
uint16_t degrees=0;
void setup() {
  Serial.begin(9600);
  Serial.println("8 channel Servo test!");

  pwm.begin();
  // In theory the internal oscillator is 25MHz but it really isn't
  // that precise. You can 'calibrate' by tweaking this number till
  // you get the frequency you're expecting!
  //pwm.setOscillatorFrequency(27000000);  // The int.osc. is closer to 27MHz  
  pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates

  delay(10);
}


void angles(){
  int angle=0;
  int pulse=map(angle,0,180,150, 560);
  pwm.setPWM(servonum,0,pulse);
  delay(1000);
  Serial.println(angle);
  Serial.println(pulse);
  
  angle=90;
  pulse=map(angle,0,180,150, 560);
  pwm.setPWM(servonum,0,pulse);
  Serial.println(angle);
  Serial.println(pulse);
  delay(1000);
  angle=180;
  pulse=map(angle,0,180,150, 560);
  pwm.setPWM(servonum,0,pulse);
  Serial.println(angle);
  Serial.println(pulse);
  delay(1000);
  
}

void sweep(){
  int pulse1=0;
  for (pulse1=150; pulse1<=565; pulse1+=1){
  pwm.setPWM(servonum,0,pulse1);
  Serial.println(pulse1);
  delay(20);
  }
  delay(2000);

  pwm.setPWM(servonum,0,250);

  delay(2000);
  for (pulse1=550;pulse1>=150;pulse1-=1){
    pwm.setPWM(servonum,0,pulse1);
    Serial.println(pulse1);
    delay(25);
  }
  delay(2000);

  for (pulse1=150;pulse1<=550;pulse1+=1){
    pwm.setPWM(servonum,0,pulse1);
    Serial.println(pulse1);
    delay(25);
  }
  pwm.setPWM(servonum,0,140);
  delay(2000);
}
void loop() {


sweep();

angles();
Serial.println("TESTING");

my setup right now was a SG90 on slot1 and a MG90 slot 0 of the controller.

i started with the SG. Sweep was called, and it worked fine, sweeping in both directions.
after that the "angles()" where called and it moved to the 0, 90 and 180 position.

changed the "servonum" to 0 to get to the MG90.

sweep worked. but it did not move during the "angles" part.
as soon as the loop was back in the sweep it turned again.

and i dont know why its not moving.

we can close this....

over half of the shipment of faked clones of the MG90s is trash...

sorry for wasting your time. i just couldnt think of a reason why it wasnt working with the MGs i teste. turns out i had bad luck picking the 12 servos out of the 25 i have.

there are a couple of working ones. so i blame it on the servos not on the code.
will be ordering new ones that are just "clones" and not faked clones... i guess there was a reason for the low price.