Circuitpython servo not rotating full 180 degrees with Raspberry Pi Pico

50 Views Asked by At

I am writing a circuit python code to rotate a servo 180 degrees

import time
import board
import busio

from adafruit_servokit import ServoKit


kit = ServoKit(channels=16, i2c=(busio.I2C(board.GP1, board.GP0)))

while True:
    kit.servo[0].angle = 180
    time.sleep(1)
    kit.servo[0].angle = 0
    time.sleep(1)

The servo is a simple TowerPro SG90 servo connected to a PCA9685 servo controller which is connected to a Raspberry Pi Pico.

Running a servo rotation code in Arduino gives a full 180-degree rotation but somehow Circuitpython (or the controller) gives roughly 150-degree rotation only.

How do I get a 180-degree rotation in Circuitpython and Raspberry Pi Pico?

1

There are 1 best solutions below

0
Lee-xp On

This could possibly be a power supply issue. Common Arduino boards such as the Uno are 5 volt devices, while the Pico is 3.3v. If you are not using an independent power supply for your servos, then this could be the problem.

If not then you should check the pulse width of the signal that your Pico is generating, and documentation for your servo to check what pulse width range it is expecting. The hobbyist servos that I have come across require around 500uS pulses for 0 degrees, and 2400/2500uS for 180.

The code below is for a simple pulse-width reader which runs on an Arduino, printing pulse widths to the serial monitor. If you run this on an Arduino to read signals from a Pico, you will need to ensure that the Pico sees 3 volt signals rather than 5 volt. You can do this by using a 3 volt Arduino such as an ESP32 or a 3 volt Pro Mini, or by using a voltage level shifter.

In tests, I generated a servo signal on an Arduino (nano), and read it back using the code below on an Arduino Uno. Zero degrees gave me around 530uS, while 180 degrees gave around 2400uS.

// Pulse width reader    
#include <Servo.h>

#define SERVO_IN 3

Servo myservo;

void setup()
{
    Serial.begin(9600);
    myservo.attach(SERVO_IN);
    pinMode(SERVO_IN, INPUT); //for pulse-in
    delay(2000);
}

void loop() {
    int reading = pulseIn(SERVO_IN, HIGH);
    Serial.println(String(reading) + "uS");    
    delay(200);
}

This is a 'scope image of the Arduino output set to 180 degrees showing a pulse width of 2.40mS, and which the test program read at around 2370uS.

enter image description here