diff --git a/README.md b/README.md index 323d68b..566711e 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ 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 device](src/main/java/com/pi4j/devices/sg90/README.md) ### Notes: diff --git a/assets/runDHT22.sh b/assets/runDHT22.sh index 3d9b119..a4f08cd 100644 --- a/assets/runDHT22.sh +++ b/assets/runDHT22.sh @@ -1,2 +1,2 @@ #!/usr/bin/env bash - java -classpath ./*:../classes com.pi4j.devices.dht22.DHT22_App $@ + java -classpath ./*:../classes com.pi4j.devices.dht22.DHT22_App $@ \ No newline at end of file diff --git a/assets/runSg90.sh b/assets/runSg90.sh new file mode 100644 index 0000000..40854e3 --- /dev/null +++ b/assets/runSg90.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + + + java -classpath ./*:../classes com.pi4j.devices.sg90.Sg90App $@ diff --git a/pom.xml b/pom.xml index b4292f8..9323460 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,7 @@ 25 ${java.version} ${java.version} - 3.2.0 + 3.2.0 3.3.1 5.1.9 3.3.2 @@ -33,9 +33,9 @@ 2.0.17 - 4.0.1 - + 5.0.0-SNAPSHOT + 2.0.0-SNAPSHOT 1.6.0 3.13.0 @@ -60,6 +60,17 @@ Sonatype OSS Maven2 Repository https://mvnrepository.com/artifact/org.apache.felix/maven-bundle-plugin + + sonatype-snapshots + Maven Central Snapshots + https://central.sonatype.com/repository/maven-snapshots + + false + + + true + + sonatype-oss-staging Sonatype Open Source Maven Repository @@ -84,27 +95,27 @@ pi4j-plugin-gpiod ${pi4j.version} - + - net.java.dev.jna - jna - 5.12.1 - + net.java.dev.jna + jna + 5.12.1 + - org.slf4j - slf4j-api - ${slf4j.version} - - - org.slf4j - slf4j-simple - ${slf4j.version} - - + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + slf4j-simple + ${slf4j.version} + + com.pi4j pi4j-core @@ -119,15 +130,15 @@ - + com.pi4j pi4j-drivers - 1.1.1-SNAPSHOT + ${pi4j-driver.version} org.jetbrains @@ -190,19 +201,19 @@ - + org.apache.maven.plugins maven-source-plugin - ${maven-source-plugin.version} - - - attach-sources - - jar - - - - + ${maven-source-plugin.version} + + + attach-sources + + jar + + + + + com.pi4j.devices.mcp23008/com.pi4j.devices.mcp23008.Mcp23008App @@ -373,7 +384,7 @@ maven-antrun-plugin ${maven-antrun-plugin.version} - + copySH install @@ -460,4 +471,4 @@ - + \ No newline at end of file diff --git a/src/main/java/com/pi4j/devices/mcp4725/MCP4725App.java b/src/main/java/com/pi4j/devices/mcp4725/MCP4725App.java index 59a2a94..682aade 100644 --- a/src/main/java/com/pi4j/devices/mcp4725/MCP4725App.java +++ b/src/main/java/com/pi4j/devices/mcp4725/MCP4725App.java @@ -15,7 +15,7 @@ public class MCP4725App { static void main(String[] args) { - System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "OFF"); + System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "INFO"); Logger logger = LoggerFactory.getLogger(MCP4725App.class); logger.trace(">>> Enter: init"); diff --git a/src/main/java/com/pi4j/devices/mcp4728/MCP4728App.java b/src/main/java/com/pi4j/devices/mcp4728/MCP4728App.java index dc97257..6644a85 100644 --- a/src/main/java/com/pi4j/devices/mcp4728/MCP4728App.java +++ b/src/main/java/com/pi4j/devices/mcp4728/MCP4728App.java @@ -41,7 +41,7 @@ public class MCP4728App { static void main(String[] args) { - System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "OFF"); + System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "iNFO"); Logger logger = LoggerFactory.getLogger(MCP4728App.class); logger.trace(">>> Enter: init"); diff --git a/src/main/java/com/pi4j/devices/sg90/README.md b/src/main/java/com/pi4j/devices/sg90/README.md new file mode 100644 index 0000000..21b2208 --- /dev/null +++ b/src/main/java/com/pi4j/devices/sg90/README.md @@ -0,0 +1,60 @@ +# SG90 servo motor + +https://www.scribd.com/document/420327552/Servo +https://www.friendlywire.com/projects/ne555-servo-safe/SG90-datasheet.pdf + +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 SG90 defines a specific PWM interface and exactly how the PWN signal +controls the servo. There are many different manufacturers of the SG90 servo. +The pulse width required for setting the servo at 0 degrees or 180 degrees 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 desired position, Example: to rotate closer to the 0 degree +point reduce the -low argument, to rotate closer to the 180 degree point 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. + + + + Connections between the SG90 servo and the Raspberry Pi + SG90 Pi +Grey/Brown Ground +Red 5V +Yellow GPIO18 config.sys contains dtoverlay=pwm-2chan + + + +1. ./mvnw clean package +2. cd target/distribution +3. ./runSg90.sh args + +-c channel (default 2) set the channel, depending on config.txt 1 2 3 4 +-low double pulse width for 0 degree microseconds +-high double pulse width for 180 degree microseconds +-q quit +-h help + +./runSg90.sh begins execution of the application, you then enter the desired servo degree of rotation. +Then continue entering the requested degree value, or any key will exist the program. + +Set ouput shaft at 120 degree +./runSg90.sh + 120 + +Driver defaults to 0 degree requires a 1000 micro second pulse, 180 degree requires a 2000 microsecond pulse +If your servo requires different pulse widths + +Set low high pulse widths, then set output shaft at 120 degree +./runSg90.sh -low 600 -high 2400 + 120 + +My Sg90 aligns correctly with these values +./runSg90.sh -low 550 -high 2450 + +If your configuration uses a channel other than 2 +./runSg90.sh -c 1 + 120 diff --git a/src/main/java/com/pi4j/devices/sg90/Sg90App.java b/src/main/java/com/pi4j/devices/sg90/Sg90App.java new file mode 100644 index 0000000..cee96e2 --- /dev/null +++ b/src/main/java/com/pi4j/devices/sg90/Sg90App.java @@ -0,0 +1,143 @@ +/* + * /* + * * + * + */ + +package com.pi4j.devices.sg90; + +import com.pi4j.Pi4J; +import com.pi4j.boardinfo.util.PwmChipUtil; +import com.pi4j.context.Context; +import com.pi4j.drivers.motor.sg90.SG90Driver; +import com.pi4j.io.pwm.Pwm; +import com.pi4j.io.pwm.PwmConfig; +import com.pi4j.io.pwm.PwmConfigBuilder; +import com.pi4j.io.pwm.PwmType; +import com.pi4j.util.Console; +import com.pi4j.util.Delay; + +/** + * SG90 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. + *

+ * See README.md for more information and detail. + */ +class Sg90App { + + 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 final double LOW_PULSSE = 1000.0; + private static final double HIGH_PULSE = 2000.0; + + private static Integer channel = DEFAULT_CHANNEL_NUMBER; + private static Console console; + private static SG90Driver sg90; + private static final Delay delay = new Delay(); + private static java.util.Scanner scanner; + private static double lowPulse = LOW_PULSSE; + private static double highPulse = HIGH_PULSE; + + + public Sg90App() { + super(); + + } + + + /** + *

main.

+ * + * @param args an array of {@link java.lang.String} objects. + * @throws java.lang.Exception if any. + */ + static void main(String[] args) throws Exception { + System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "INFO"); + + scanner = new java.util.Scanner(System.in); + + console = new Console(); + Context pi4j = Pi4J.newAutoContext(); + console.title("<-- The Pi4J V5 Project Extension -->", "Sg90App"); + String helpString = " Parms: -c channel -q quit -low microseconds -high microseconds -h HELP"; + + + String o; + for (int i = 0; i < args.length; i++) { + switch (o = args[i]) { + case "-low" -> { + lowPulse = Integer.parseInt(args[i + 1]); + i++; + } + case "-high" -> { + highPulse = Integer.parseInt(args[i + 1]); + i++; + } + case "-c" -> { + channel = Integer.parseInt(args[i + 1]); + i++; + } + case "-q" -> { + console.println("Exit"); + System.exit(40); + } + case "-h" -> { + console.println(helpString); + System.exit(41); + } + default -> { + console.println(" !!! Invalid Parm " + o); + console.println(helpString); + System.exit(42); + } + } + } + + + Pwm pwm = createPwm(SERVO_NUMBER, channel, pi4j); + + sg90 = new SG90Driver(pwm, lowPulse, highPulse); + + waitChange(10L); + + pwm.close(); + + } + + static void waitChange(long c) { + while (true) { + delay.setMillis(c).materialize(); + console.println("Enter degree value or enter any key to quit"); + if (scanner.hasNextInt()) { + double nextDegree = scanner.nextDouble(); + if ((nextDegree < 0.0) || (nextDegree > 180.0)) { + console.println(" degree must be in the range 0..180"); + } else { + sg90.setServoAngle(nextDegree); + } + } else { + break; + } + } + } + + + static Pwm createPwm(int servoNumber, Integer channel, Context pi4j) { + + final PwmConfig config = PwmConfigBuilder.newInstance(pi4j) + .id("sg90Number" + servoNumber) + .name("SG90 number " + servoNumber) + .channel(channel) + .pwmType(PwmType.HARDWARE) + .channel(channel) + .chip(PwmChipUtil.getPWMChip()) + .frequency(DEFAULT_PWM_FREQUENCY) + .build(); + + return pi4j.create(config); + } + +}