import com.pi4j.wiringpi.SoftPwm;
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioPin;
/**
* Control class for servo motors
* @author Stefan Fambach (With help of many others)
* @version 0.1
*
* This class can either set position by values between posMin and posMax
* or it can caluculate the position by an angle where degMin <= angle <= degMax
*
* No warranty free for use see GPL v3.
*/
public class Servo
{
Pin pin;
int degMin = -90;
int degMax = 90;
int posMin = 4; // to have a center
int posMax = 25;
int pos = -1;
/**
* range between min and max degree
*/
double degDelta = degMax - degMin;
/**
* range between min and max position
*/
double posDelta = posMax - posMin;
/**
* multiplier for degree to pos calculation
*/
double multiplier = posDelta/degDelta;
/**
* Time in ms to wait after new position is set
*/
int timeout = 1000;
/**
* Default constructor, default pin is GPIO_27
*/
public Servo(){
this(RaspiPin.GPIO_27);
}
/**
* Constructor for objects of class Servo
*/
public Servo(Pin controlPin)
{
this.pin = controlPin;
// initialize wiringPi library
com.pi4j.wiringpi.Gpio.wiringPiSetup();
// create soft-pwm pins (min=0 ; max=100)
SoftPwm.softPwmCreate(this.pin.getAddress(), 0, 200);
moveCenter();
}
/**
* set position in degree, only 20 positions are possible, each step will be calculated
*/
boolean setDeg(int deg) throws Exception {
if(deg > degMax){
throw new Exception( "Entered deg: "+ deg + "is greater maxDeg "+degMax);
}
if(deg < degMin){
throw new Exception( "Entered deg: "+ deg + "is smaller maxDeg "+degMin);
}
if(deg < 0){
deg = (-degMin)+ deg;
}else{
deg -= degMin;
}
return setPos((int) (deg * multiplier));
}
/**
* set position posMin - posMax (default 0-21)
*/
public boolean setPos(int pos)throws Exception{
if(pos < 0 ){
throw new Exception (pos + " Pos to small (<0) ");
}
if(pos > posMax ){
throw new Exception (pos + " Pos to big > "+posMax+")");
}
if(pos != this.pos){
this.pos = pos;
SoftPwm.softPwmWrite(pin.getAddress(), posMin + pos);
sleep(timeout);
SoftPwm.softPwmWrite(pin.getAddress(), 0);
return true;
}
return false;
}
/**
* set Servo to center position
*/
public void moveCenter(){
try{
setPos((posMax-posMin+1)/2);
} catch (Exception ex){
// will hopefully never happen
}
}
/**
* set Servo to min position
*/
public void moveToMinPos(){
try{
setPos(0);
} catch (Exception ex){
// will hopefully never happen
}
}
/**
* set Servo to max position
*/
public void moveToMaxPos(){
try{
setPos(posMax-posMin);
} catch (Exception ex){
// will hopefully never happen
}
}
public int getPos(){
return this.pos;
}
public int getDegMin(){
return degMin;
}
public int getDegMax(){
return degMax;
}
public void setDegMin(int min){
this.degMin = min;
calculateVariables();
}
public void getDegMax(int max){
this.degMax = max;
calculateVariables();
}
public void setPosMin(int min){
this.posMin = min;
calculateVariables();
}
public void setPosMax(int max){
this.posMax = max;
calculateVariables();
}
public int getPosMin(){
return this.posMin;
}
public int getPosMax(){
return this.posMax;
}
/**
* calculate the ranges for deg and pos
* as well as the multiplier for degree positioning of the servo
*/
private void calculateVariables(){
degDelta = degMax - degMin;
posDelta = posMax - posMin;
multiplier = posDelta/degDelta;
}
private void sleep(int msec){
try
{
Thread.sleep(msec);
}
catch ( InterruptedException e)
{
}
}
public void release(){
SoftPwm.softPwmStop(pin.getAddress());
GpioController gpio = GpioFactory.getInstance();
gpio.unprovisionPin(new GpioPin[]{gpio.getProvisionedPin(pin)});
}
}