Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ The following table the currently supported devices within this project:
| Sensor | 1-Wire | (1) | [DHT22 Temp/Humidity sensor](src/main/java/com/pi4j/devices/dht22/README.md)
| Sensor | | | [HC-SR04 Ultrasonic Sensor](src/main/java/com/pi4j/devices/hcsr04/README.md)
| Sensor | I2C | (1) | [MPL3115A2 Temp/Pressure/Altitude device](src/main/java/com/pi4j/devices/mpl3115a2/README.md)
| Servo | PWM | | [SG90 180 degree servo motor device](src/main/java/com/pi4j/devices/sg90/README.md)
| Servo | PWM | | [FS90R 360 degree continuous servo motor device](src/main/java/com/pi4j/devices/fs90r/README.md)


### Notes:
Expand Down
5 changes: 5 additions & 0 deletions assets/runFs90r.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash



java -classpath ./*:../classes com.pi4j.devices.fs90r.Fs90rApp $@
196 changes: 196 additions & 0 deletions src/main/java/com/pi4j/devices/fs90r/Fs90rApp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
/*
* /*
* *
*
*/

package com.pi4j.devices.fs90r;


import com.pi4j.drivers.motor.fs90r.Fs90RDriver;
import com.pi4j.io.pwm.Pwm;
import com.pi4j.io.pwm.PwmConfigBuilder;
import com.pi4j.boardinfo.util.PwmChipUtil;
import com.pi4j.Pi4J;
import com.pi4j.context.Context;
import com.pi4j.io.pwm.PwmConfig;
import com.pi4j.io.pwm.PwmType;
import com.pi4j.util.Console;
import com.pi4j.util.Delay;

/**
* Example implementation for a FS90R servo motor.
* The Fs90R defines a specific PWM interface and exactly how the PWN signal
* controls the servo
*
* https://www.pololu.com/product/2820
*
* See the README.md file for example usage and explanation.
*
* FS90R servo motor control. The driver will use the PWM device created by
* this app. It is assumed the device is a HardWare PWM. Hardware PWM creates
* a more consistent PWM signal.
*/
public class Fs90rApp {

private static final int DEFAULT_PWM_FREQUENCY = 50;
private static final int DEFAULT_CHANNEL_NUMBER = 2;
private static final int SERVO_NUMBER = 1;


private static double degree = 90.0;
private static Integer channel = DEFAULT_CHANNEL_NUMBER ;
private static Console console ;
private static Fs90RDriver fs90R ;
private static final Delay delay = new Delay();
private static java .util.Scanner scanner;
private static double lowPulse = 1000.0;
private static double highPulse = 2000.0;


public Fs90rApp() {
super();

}


/**
* <p>main.</p>
* See the README.md file for example usage.
* @param args an array of {@link java.lang.String} objects.
* @throws java.lang.Exception if any.
*/
static void main(String[] args) throws Exception {
Comment thread
stefanhaustein marked this conversation as resolved.
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "INFO");

int onlyOne = 0; // numerous parms a mutually exclusive

scanner = new java.util.Scanner(System.in);

console = new Console();
Context pi4j = Pi4J.newAutoContext();
console.title("<-- The Pi4J V5 Project Extension -->", "Fs90rApp");
String helpString = " Parms: -c channel -cw (clockwise) S M F -ccw (counter-clockwise) S M F -h HELP \n" +
" -low microseconds -high microseconds -cw -ccw mutually exclusive -d degree \n" +
" degree must be in the range 0..180. 90 stop, 0..89 CW, 91..180 CCW ";


for (int i = 0; i < args.length; i++) {
String o = args[i];
if (o.contentEquals("-low")) {
String a = args[i + 1];
lowPulse = Double.parseDouble(a.substring(0));
i++;
} else if (o.contentEquals("-high")) {
String a = args[i + 1];
highPulse = Double.parseDouble(a.substring(0));
i++;
} else if (o.contentEquals("-d")) {
String a = args[i + 1];
degree = Double.parseDouble(a.substring(0));
if((!Double.isFinite(degree) || degree < 0) || (degree > 180)){
Comment thread
taartspi marked this conversation as resolved.
console.println("-d degree must be in range 0..180");
System.exit(40);
}
onlyOne++;
i++;
} else if (o.contentEquals("-c")) {
String a = args[i + 1];
channel = Integer.parseInt(a.substring(0));
i++;
} else if (o.contentEquals("-cw")) { /* 0-89 */
String a = args[i + 1];
onlyOne++;
i++;
if (a.equalsIgnoreCase("S")) {
degree = 75.0;
} else if (a.equalsIgnoreCase("M")) {
degree = 40.0;
} else if (a.equalsIgnoreCase("F")) {
degree = 0.0;
} else {
console.println(" -cw invalid ");
System.exit(41);
}
} else if (o.contentEquals("-ccw")) { /* 191-180 */
String a = args[i + 1];
i++;
onlyOne++;
if (a.equalsIgnoreCase("S")) {
degree = 105.0;
} else if (a.equalsIgnoreCase("M")) {
degree = 140.0;
} else if (a.equalsIgnoreCase("F")) {
degree = 180.0;
} else {
console.println(" -ccw invalid ");
System.exit(42);
}
} else if (o.contentEquals("-q")) {
console.println("Exit");
System.exit(0);
} else if (o.contentEquals("-h")) {
console.println(helpString);
System.exit(0);
}else {
console.println(" !!! Invalid Parm " + o);
console.println(helpString);
System.exit(43);
}
}

if (onlyOne > 1 ) {
console.println(" mutually exclusive parms used.");
console.println(helpString);
System.exit(44);
}
Pwm pwm = createPwm(SERVO_NUMBER, channel, pi4j);

fs90R = new Fs90RDriver(pwm, lowPulse, highPulse);

// if user did not provide a -cw -ccw or -d default sets stop
fs90R.setServoRotation(degree);

waitChange( 10l);

pi4j.shutdown(pwm);

}


static Pwm createPwm(int servoNumber, Integer channel, Context pi4j) {

final PwmConfig config = PwmConfigBuilder.newInstance (pi4j)
.id ("fs90RNumber" + servoNumber)
.name ("fs90R number " + servoNumber)
.pwmType(PwmType.HARDWARE)
.channel(channel)
.chip(PwmChipUtil.getPWMChip())
.frequency(DEFAULT_PWM_FREQUENCY)
.build ();

return pi4j.create (config);
}

static void waitChange(long c){
while(true){
delay.setMillis(c).materialize();
console.println("Enter q - quit, or degree value ");
if (scanner.hasNextInt() ) {
double nextDegree = scanner.nextDouble();
if((!Double.isFinite(nextDegree) || nextDegree < 0) || (nextDegree > 180)){
console.println(" degree must be in the range 0..180. 90 stop, 0..89 CW, 91..180 CCW");
}else {
fs90R.setServoRotation(nextDegree);
}
} else{
break;
}
}
}
}





74 changes: 74 additions & 0 deletions src/main/java/com/pi4j/devices/fs90r/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@


##Device application to operate a Fs90r stepping servo. This servo can rotate 360 degree continuously.
The PWM signal sent to the servo device set the direction and RPM of rotation.



Driver for a Fs90r servo motor.
The Fs90r defines a specific PWM interface and exactly how the PWN signal
controls the servo

https://www.pololu.com/product/2820


These devices do not have a customary DataSheet. Most servo devices provide limited specifications
for required pulse width, they just say 1 - 2 millisecond.

The FS90 R 360 defines a specific PWM interface and exactly how the PWN signal
controls the servo. There are many different manufacturers of the FS90 servo.
The pulse width required for setting the servo at 0 degrees MAX Clockwise (CW) or 180 degrees
MAX CounterClockWise (CCW) varies by manufacturer. The driver by default uses the pulse width timing as
(low)1000 - (high)2000 microseconds. The user of this example application can change these defaults
when first invoking the program.

If the servo does not rotate to the expected RPM,Example to rotate faster CW reduce the -low
argument, to rotate CCW faster increase the -high argument. The -low -high change should be balanced or 90 degree will not properly align.
Meaning if you reduce the -low by 200, you should increase the -high by 200, or visa-versa.




https://www.pololu.com/product/2820



Fs90r Pi
Grey/Brown Ground
Red 5V
Yellow GPIO18 config.sys contains dtoverlay=pwm-2chan



1. ./mvnw clean package
2. cd target/distribution
3. ./runFs90r.sh args

-h help
-c channel (default 2) set the channel, depending on config.txt 1 2 3 4
-cw clockwise S M F
-ccw counter-clockwise S M F
-low double pulse width for 0 degree microseconds
-high double pulse width for 180 degree microseconds
-q quit servo will stop


Application running, awaiting input of 0-180 degree
./runFs90r.sh

Application running CCW, then awaiting input of 0-180 degree
./runFs90r.sh 160



Set output shaft Fast ClockWise, then enter 90 for stop
./runFs90r.sh -cw F
90


Set output shaft Slow CounterClockWise, then enter 0 for MAX soeed
./runFs90r.sh -ccw S
0

My Fs90r appears faster rotation wih these values for the -low and -high limmits
./runFs90r.sh -low 550 -high 2450
Loading