简体   繁体   中英

Problems with controlling a servo with java and Pi4J on a Raspberry PI 2

I want to control a MG90S Servo via the GPIO pins of my Raspberry PI using Pi4J.

I have created a Java application with an hz and a duty cycle("High in ms:") keyboard input.

import java.util.Scanner;

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        GpioController gpioFactory = GpioFactory.getInstance();
        GpioPinDigitalOutput myServo =  gpioFactory.provisionDigitalOutputPin(
                    RaspiPin.GPIO_07, PinState.LOW);

        //Input of hz and duty cycle
        System.out.println("Hz:");
        Scanner scanner = new Scanner(System.in);
        float hz = scanner.nextFloat();
        System.out.println("High in ms:");
        float highTime = scanner.nextFloat();
        scanner.close();

        //Calculate GPIO low time: hz period time - duty time
        float lowTime = 1000 / hz - highTime;

        while (true) {
            myServo.high();
            long upMs = new Float(highTime).longValue(); // Up time miliseconds
            int upNanos = new Float(highTime * 1000000 % 1000000).intValue(); // Up time nanoseconds
            java.lang.Thread.sleep(upMs, upNanos);

            myServo.low();
            long lowMs = new Float(lowTime).longValue();
            int lowNanos = new Float(lowTime * 1000000 % 1000000).intValue();

            java.lang.Thread.sleep(lowMs, lowNanos);

        }
    }
}

Example 1: With the following input I expect that the servo is at Rotation.

hz: 50 high in ms: 1

Result: The servo is at as expected.

Example 2: With the following input I expect that the servo is at 180° Rotation.

hz: 50 high in ms: 2

Result: The servo is at ~80° rotation.

Has anyone an idea what I'm doing wrong?

I had a similar problem with another servo (i think it was arduino stuff).

I just calibrated the given values that way that the result is correct. I don't know where it comes from but the servo did what i want to.

The problem had nothing to do with Pi4J. The sleep period wasn't exact enougth.

"The granularity of sleeps is generally bound by the thread scheduler's interrupt period. In Linux, this interrupt period is generally 1ms in recent kernels. In Windows, the scheduler's interrupt period is normally around 10 or 15 milliseconds" - qwerty https://stackoverflow.com/a/11498647/5049836

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM