Servo 90 degrees off correction

Dear somebody, I am pretty new to Arduino but managed to build a MPU6050 gyroscope on Arduino Uno, it does control my servo, however it is 90 degrees off. This is part of the code:

Serial.print(mpu6050.getAngleX());

this command works great and shows on the terminal a range from minus -90 degrees to plus +90degrees depending on MPU6050 position, it starts off at 0 degrees

The terminal value I want to use to control the servo and wrote

Myservo.write(mpu6050.getAngleX());

This command does work but the servo begins at the end of its range instead of its midpoint so I have to rotate the MPU6050, 90 degrees first before Servo starts to move.
I would like the Servo to go to middle position when terminal says 0 degrees, to the left when terminal value is minus and to the right when terminal value is plus

Is there anybody who can help me with this, I would think it is just a small code to correct this but I can't find it. Thanks in advance, Ed

Servo.write() takes a value from 0 - 180 with the centre at 90. If you’re giving it -90 to 90 it’s not surprising that it behaves strangely. Try Myservo.write(mpu6050.getAngleX() + 90;

Steve

Dear Steve, I can not believe it was that simple, I tried so many things, now your answer solved a 2 week search, can’t thank you enough (AAA+++).

May I ask you this too: I bought a Adafruit Servo Shield to attach multiple servos, the build is easy and when I turn on the terminal it works fine but somehow I can not get the servo’s to do anything, they are fed with 5V. I realize I must code it different, not Myservo.write(mpu6050.getAngleX()); were Myservo is attached to e.g. pin 8.

I tried an example code using the Adafruit servo shield (see attached) which works great, but I have no clue how to implement the data " mpu6050.getAngleX" I want to the PWM pins. Is there a quick answer to this too ?

Once again thank you big time for your quick and correct solution.

Ed

051-Servo-Motor-Driver-16.ino (914 Bytes)

Please post code properly as described in How to use this forum

I'm assuming you mean the 16 channel PCA9685 servo board (a link would have helped). The mechanism it uses to connect servos to the Arduino is completely different from the standard way. So a change to using that is not so simple. But if you think of pwm.begin + pwm.setPWMFrequency() as equivalent to servo.attach() and pwm.setPWM() as equivalent to servo.write() you're getting there. In that example code you would basically change pulseWidth(10 or 170) to pulseWidth(mpu6050.getAngleX + 90)

Adafruit do an excellent tutorial for that board explaining what all the parameters to the commands are and how to use them. See Adafruit PCA9685 tutorial There are also some useful example programs with the Adafruit library.

Give it a try and if you have problems post again, this time including your complete program.

Steve

Hi Steve, I am sorry, please forgive my newbie errors.

Thanks again for your reply although it makes me puzzled, I included the code with what I think you said. This however generates an error invalid use of member function ‘float MPU6050::getAngleX()’ (did you forget the ‘()’ ?)

I think it should send mpu6050.getAngleX to PWM# 0, did I leave something out ? (to be honest I do not really understand what the last 5 lines of the code mean because the way I read this is that the data mpu6050.getAngleX has already be send to PWM# 0 before those lines)

Hope you can help out again ?
regards Ed

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

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

MPU6050 mpu6050(Wire);

#define MIN_PULSE_WIDTH       650
#define MAX_PULSE_WIDTH       2350
#define DEFAULT_PULSE_WIDTH   1500
#define FREQUENCY             50

void setup() {
  pwm.begin();
  pwm.setPWMFreq(FREQUENCY);
  mpu6050.begin();
  mpu6050.calcGyroOffsets(true);
}

void loop() {
  mpu6050.update();
  pwm.setPWM(0, 0, pulseWidth(mpu6050.getAngleX + 90));
  delay(1000);
}

int pulseWidth(int angle)
{
  int pulse_wide, analog_value;
  pulse_wide   = map(angle, 0, 180, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
  analog_value = int(float(pulse_wide) / 1000000 * FREQUENCY * 4096);
  return analog_value;
}

The error message that you posted told you EXACTLY what the problem was. Didn't you read it? Didn't you bother to look back at your earlier code and see how you wrote that command last time?

I made a small typo but you didn't need to just copy it without thinking.

Steve

Thanks Steve, I realize you think it is real stupid I did not see it but I was looking for the problem at the word "float" not at the line were it said "pulsewidth(mpu6050.getangleX + 90" not knowing enough about the hints Arduino gives (keep in mind I just started 3 weeks ago with Arduino).

so it should have been pwm.setPWM(0, 0, pulseWidth(mpu6050.getAngleX()+90)); and indeed the Servo moves.

you were of great help.

regards
Ed