0

I would like to control a brushless motor with a Java program running on a Raspberry Pi model b+.

This is the code that I am using:

package de.ye.boat_eng;

import com.pi4j.wiringpi.Gpio;
import com.pi4j.wiringpi.SoftPwm;

public class ON implements Runnable{


public static boolean stop = false;

@Override
public void run() {
    System.out.println("ON_ENG");
    Gpio.wiringPiSetup();
    SoftPwm.softPwmCreate(24, 0, 60);
    SoftPwm.softPwmWrite(24, 12);
    Thread.sleep(100);
    while((true)){
        SoftPwm.softPwmWrite(24, 12);
        Thread.sleep(100);
        SoftPwm.softPwmWrite(24, 20);
        Thread.sleep(100);

        if(stop){
            SoftPwm.softPwmWrite(24, 0);
            Thread.currentThread().destroy();
        }
    }
}
}

But the motor isn't running "stable", it turns on and off sometimes slower sometimes faster...

Thanks in advance.

cy8berpunk
  • 29
  • 7

3 Answers3

1

As mentioned before, indeed Raspbian OS is not real-time so software controlled PWM will never be fully stable.

But luckily there is hardware support on specific GPIOs! As it is well described on https://techetrx.com/raspberry-pi-tutorials/using-gpio-and-pwm-in-raspberry-pi/:

The Raspberry Pi supports software configurable PWM on all its GPIO pins. You can essentially program a GPIO to output a PWM pulse of a varying duty cycle. Apart from software PWM, it also provides hardware PWM on GPIO12, 13, 18 and 19. It has 2 separate channels for hardware PWM. Channel zero i.e. PWM0 consisting of GPIO12 and GPIO18 and PWM1 with GPIO13 and GPIO19.

To answer to the comment of @joan, the sleep value in Thread.sleep(100); is in milliseconds.

You can find a nice PWM example in https://github.com/Pi4J/pi4j/blob/master/pi4j-example/src/main/java/PwmExample.java

public static void main(String[] args) throws InterruptedException {
    // create Pi4J console wrapper/helper
    // (This is a utility class to abstract some of the boilerplate code)
    final Console console = new Console();

    // print program title/header
    console.title("<-- The Pi4J Project -->", "PWM Example");

    // allow for user to exit program using CTRL-C
    console.promptForExit();

    // create GPIO controller instance
    GpioController gpio = GpioFactory.getInstance();

    // All Raspberry Pi models support a hardware PWM pin on GPIO_01.
    // Raspberry Pi models A+, B+, 2B, 3B also support hardware PWM pins: GPIO_23, GPIO_24, GPIO_26
    //
    // by default we will use gpio pin #01; however, if an argument
    // has been provided, then lookup the pin by address
    Pin pin = CommandArgumentParser.getPin(
            RaspiPin.class,    // pin provider class to obtain pin instance from
            RaspiPin.GPIO_01,  // default pin if no pin argument found
            args);             // argument array to search in

    GpioPinPwmOutput pwm = gpio.provisionPwmOutputPin(pin);

    // you can optionally use these wiringPi methods to further customize the PWM generator
    // see: http://wiringpi.com/reference/raspberry-pi-specifics/
    com.pi4j.wiringpi.Gpio.pwmSetMode(com.pi4j.wiringpi.Gpio.PWM_MODE_MS);
    com.pi4j.wiringpi.Gpio.pwmSetRange(1000);
    com.pi4j.wiringpi.Gpio.pwmSetClock(500);

    // set the PWM rate to 500
    pwm.setPwm(500);
    console.println("PWM rate is: " + pwm.getPwm());

    console.println("Press ENTER to set the PWM to a rate of 250");
    System.console().readLine();

    // set the PWM rate to 250
    pwm.setPwm(250);
    console.println("PWM rate is: " + pwm.getPwm());


    console.println("Press ENTER to set the PWM to a rate to 0 (stop PWM)");
    System.console().readLine();

    // set the PWM rate to 0
    pwm.setPwm(0);
    console.println("PWM rate is: " + pwm.getPwm());

    // stop all GPIO activity/threads by shutting down the GPIO controller
    // (this method will forcefully shutdown all GPIO monitoring threads and scheduled tasks)
    gpio.shutdown();
}

Frank
  • 328
  • 1
  • 9
0

You are not using SoftPwm.softPwmWrite properly. You almost certainly want a delay between one call and the next.

SoftPwm.softPwmWrite(24, 5) will start to send pulses of I guess length 833 µs (1000000/60 * 5/100). It will send those pulses 60 times a second until told to change. You don't need to call the function 60 times a second.

At the moment you keep changing the pulse width so the motor never gets a chance to arrive and stay at the set throttle.

I would stop doing that. You will wear your motor out much faster than intended. Put a sleep of a tenth of a second or so between each call to give the motor time to reach the target speed.

joan
  • 71,852
  • 5
  • 76
  • 108
0

Raspberry Pi should be relatively bad for this task, because raspbian is not a real-time operating system. See this thread, hope it is helpful: Is it possible to run real time software?

Andy A
  • 1