From bc5663a5d7e705e9e7bcfb4a6a80be85676a89c5 Mon Sep 17 00:00:00 2001 From: Leandru Martin Date: Fri, 27 Sep 2024 10:29:54 -0500 Subject: [PATCH 1/9] Added initial files for DC Motor support based on Servo motor files --- .../controllers/DCMotorController.java | 33 ++++++ components/src/main/resources/application.yml | 7 ++ .../outputdevices/DCMotorHelper.java | 112 ++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 components/src/main/java/com/opensourcewithslu/components/controllers/DCMotorController.java create mode 100644 pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/DCMotorHelper.java diff --git a/components/src/main/java/com/opensourcewithslu/components/controllers/DCMotorController.java b/components/src/main/java/com/opensourcewithslu/components/controllers/DCMotorController.java new file mode 100644 index 00000000..70101035 --- /dev/null +++ b/components/src/main/java/com/opensourcewithslu/components/controllers/DCMotorController.java @@ -0,0 +1,33 @@ +package com.opensourcewithslu.components.controllers; + +import com.opensourcewithslu.outputdevices.DCMotorHelper; +import com.pi4j.io.pwm.Pwm; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import jakarta.inject.Named; + +//tag::ex[] +@Controller("/DCMotor") +public class DCMotorController { + private final DCMotorHelper DCMotorHelper; + + public DCMotorController(@Named("DC-motor") Pwm DCMotor) { + this.DCMotorHelper = new DCMotorHelper(DCMotor); + } + + @Get("/enable") + public void enableDCMotor() { + DCMotorHelper.enable(); + } + + @Get("/disable") + public void disableDCMotor() { + DCMotorHelper.disable(); + } + + @Get("/setAngle/{angle}") + public void setAngle(int angle) { + DCMotorHelper.setAngle(angle); + } +} +//end::ex[] diff --git a/components/src/main/resources/application.yml b/components/src/main/resources/application.yml index 4599e380..312d41ac 100644 --- a/components/src/main/resources/application.yml +++ b/components/src/main/resources/application.yml @@ -35,6 +35,13 @@ pi4j: provider: pigpio-pwm initial: 0 shutdown: 0 + dc-motor: + name: DC Motor + address: # TODO: Add address + pwmType: # TODO: Add pwmType + provider: pigpio-pwm + initial: 0 + shutdown: 0 # end::pwm[] # tag::i2c[] diff --git a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/DCMotorHelper.java b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/DCMotorHelper.java new file mode 100644 index 00000000..98d55211 --- /dev/null +++ b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/DCMotorHelper.java @@ -0,0 +1,112 @@ +package com.opensourcewithslu.outputdevices; + +import com.pi4j.io.pwm.Pwm; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Helper class to control a DC motor using PWM (Pulse Width Modulation). + * This class provides methods to enable, disable, and set the angle of a DC motor. + */ +public class DCMotorHelper { + + private static final Logger log = LoggerFactory.getLogger(DCMotorHelper.class); + private static final int FREQUENCY = 50; // Frequency for PWM signal in Hz, typical for DC motors. + private static final int PWM_CYCLE_MICROSECONDS = 20000; // Total cycle length in microseconds, corresponding to 50 Hz. + private static final int MIN_ANGLE = 0; // Minimum angle for DC operation. + private static final int MAX_ANGLE = 180; // Maximum angle for DC operation. + private static final int DC_MIN_PULSE = 500; // Minimum pulse width in microseconds corresponding to 0 degrees. + private static final int DC_MAX_PULSE = 2500; // Maximum pulse width in microseconds corresponding to 180 degrees. + private boolean isEnabled = false; // State tracking variable for the DC motor. + private double speed = 0; // Speed of the DC motor, as a percentage 0 to 1. + private final Pwm DCMotor; // PWM interface for the DC motor. + + /** + * Constructs a new DCMotorHelper. + * + * @param DCMotor A PWM interface to control the DC motor. + */ + public DCMotorHelper(Pwm DCMotor) { + this.DCMotor = DCMotor; + } + + /** + * Enables the DC motor by setting an initial duty cycle and frequency. + * The DC motor remains disabled until this method is called. + */ + public void enable() { + log.info("Enabling DC motor"); + DCMotor.on(0, FREQUENCY); // Initializes PWM signal with 0% duty cycle. + isEnabled = true; + } + + /** + * Disables the DC motor, effectively stopping any ongoing PWM signal. + */ + public void disable() { + log.info("Disabling DC motor"); + DCMotor.off(); // Stops the PWM signal. + isEnabled = false; + } + + /** + * Maps the given angle to the corresponding pulse width for the DC motor. + * + * @param value the angle in degrees to be mapped to pulse width. + * @return the calculated pulse width in microseconds. + */ + private float map(float value) { + return DC_MIN_PULSE + ((value - MIN_ANGLE) * (DC_MAX_PULSE - DC_MIN_PULSE) / (MAX_ANGLE - MIN_ANGLE)); + } + + /** + * Sets the DC motor to a specific angle. + * This method calculates the necessary pulse width and duty cycle to achieve the specified angle. + * + * @param angle the target angle for the DC motor, between 0 and 180 degrees. + */ + public void setAngle(int angle) { + if (!isEnabled) { + log.info("You must enable the DC motor first."); + return; + } + + if (angle < MIN_ANGLE || angle > MAX_ANGLE) { + log.info("You must enter an angle between 0 and 180 degrees."); + return; + } + + float pulseWidth = map(angle); + float dutyCycle = (pulseWidth / PWM_CYCLE_MICROSECONDS) * 100; + + log.info("Setting DC to {} degrees, Pulse Width: {} us, Duty Cycle: {}%", angle, pulseWidth, dutyCycle); + + DCMotor.on(dutyCycle, FREQUENCY); + try { + Thread.sleep(100); // Pauses the thread to allow the DC to reach the set angle. + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); // Properly handle thread interruption. + log.info("Thread was interrupted, failed to complete rotation"); + } + } + + public void setSpeed(double speed) { + if (!isEnabled) { + log.info("You must enable the DC motor first."); + return; + } + + if (speed < 0 || speed > 1) { + log.info("You must enter a speed between 0 and 1."); + return; + } + + this.speed = speed; + float pulseWidth = map((float) (speed * 180)); + float dutyCycle = (pulseWidth / PWM_CYCLE_MICROSECONDS) * 100; + + log.info("Setting DC speed to {}%, Pulse Width: {} us, Duty Cycle: {}%", speed * 100, pulseWidth, dutyCycle); + + DCMotor.on(dutyCycle, FREQUENCY); + } +} From a6b9cc11a6dd84f7803d2e5ea7e79f88a48f25c4 Mon Sep 17 00:00:00 2001 From: Leandru Martin Date: Fri, 27 Sep 2024 10:50:06 -0500 Subject: [PATCH 2/9] Swapped angle controls for speed controls --- .../controllers/DCMotorController.java | 6 +-- .../outputdevices/DCMotorHelper.java | 41 ++++--------------- 2 files changed, 10 insertions(+), 37 deletions(-) diff --git a/components/src/main/java/com/opensourcewithslu/components/controllers/DCMotorController.java b/components/src/main/java/com/opensourcewithslu/components/controllers/DCMotorController.java index 70101035..f1e14b5a 100644 --- a/components/src/main/java/com/opensourcewithslu/components/controllers/DCMotorController.java +++ b/components/src/main/java/com/opensourcewithslu/components/controllers/DCMotorController.java @@ -25,9 +25,9 @@ public void disableDCMotor() { DCMotorHelper.disable(); } - @Get("/setAngle/{angle}") - public void setAngle(int angle) { - DCMotorHelper.setAngle(angle); + @Get("/setSpeed/{speed}") + public void setSpeed(double speed) { + DCMotorHelper.setSpeed(speed); } } //end::ex[] diff --git a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/DCMotorHelper.java b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/DCMotorHelper.java index 98d55211..401c4dfb 100644 --- a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/DCMotorHelper.java +++ b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/DCMotorHelper.java @@ -6,15 +6,13 @@ /** * Helper class to control a DC motor using PWM (Pulse Width Modulation). - * This class provides methods to enable, disable, and set the angle of a DC motor. + * This class provides methods to enable, disable, and set the speed of a DC motor. */ public class DCMotorHelper { private static final Logger log = LoggerFactory.getLogger(DCMotorHelper.class); private static final int FREQUENCY = 50; // Frequency for PWM signal in Hz, typical for DC motors. private static final int PWM_CYCLE_MICROSECONDS = 20000; // Total cycle length in microseconds, corresponding to 50 Hz. - private static final int MIN_ANGLE = 0; // Minimum angle for DC operation. - private static final int MAX_ANGLE = 180; // Maximum angle for DC operation. private static final int DC_MIN_PULSE = 500; // Minimum pulse width in microseconds corresponding to 0 degrees. private static final int DC_MAX_PULSE = 2500; // Maximum pulse width in microseconds corresponding to 180 degrees. private boolean isEnabled = false; // State tracking variable for the DC motor. @@ -50,46 +48,21 @@ public void disable() { } /** - * Maps the given angle to the corresponding pulse width for the DC motor. + * Maps the given speed to the corresponding pulse width for the DC motor. * - * @param value the angle in degrees to be mapped to pulse width. + * @param value the speed in degrees to be mapped to pulse width. * @return the calculated pulse width in microseconds. */ private float map(float value) { - return DC_MIN_PULSE + ((value - MIN_ANGLE) * (DC_MAX_PULSE - DC_MIN_PULSE) / (MAX_ANGLE - MIN_ANGLE)); + return DC_MIN_PULSE + (value * (DC_MAX_PULSE - DC_MIN_PULSE)); } /** - * Sets the DC motor to a specific angle. - * This method calculates the necessary pulse width and duty cycle to achieve the specified angle. + * Sets the speed of the DC motor. + * This method calculates the necessary pulse width and duty cycle to achieve the specified speed. * - * @param angle the target angle for the DC motor, between 0 and 180 degrees. + * @param speed the target speed for the DC motor, as a percentage between 0 and 1. */ - public void setAngle(int angle) { - if (!isEnabled) { - log.info("You must enable the DC motor first."); - return; - } - - if (angle < MIN_ANGLE || angle > MAX_ANGLE) { - log.info("You must enter an angle between 0 and 180 degrees."); - return; - } - - float pulseWidth = map(angle); - float dutyCycle = (pulseWidth / PWM_CYCLE_MICROSECONDS) * 100; - - log.info("Setting DC to {} degrees, Pulse Width: {} us, Duty Cycle: {}%", angle, pulseWidth, dutyCycle); - - DCMotor.on(dutyCycle, FREQUENCY); - try { - Thread.sleep(100); // Pauses the thread to allow the DC to reach the set angle. - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); // Properly handle thread interruption. - log.info("Thread was interrupted, failed to complete rotation"); - } - } - public void setSpeed(double speed) { if (!isEnabled) { log.info("You must enable the DC motor first."); From 8fc1af0ba81b1f47106c3392983521f43b31e599 Mon Sep 17 00:00:00 2001 From: Leandru Martin Date: Mon, 30 Sep 2024 10:49:24 -0500 Subject: [PATCH 3/9] Added GPIO input address and PWM type, added speed control, stubbed out direction control --- .../controllers/DCMotorController.java | 33 ------------ .../controllers/MotorController.java | 43 +++++++++++++++ components/src/main/resources/application.yml | 4 +- .../{DCMotorHelper.java => MotorHelper.java} | 52 +++++++++++-------- 4 files changed, 76 insertions(+), 56 deletions(-) delete mode 100644 components/src/main/java/com/opensourcewithslu/components/controllers/DCMotorController.java create mode 100644 components/src/main/java/com/opensourcewithslu/components/controllers/MotorController.java rename pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/{DCMotorHelper.java => MotorHelper.java} (61%) diff --git a/components/src/main/java/com/opensourcewithslu/components/controllers/DCMotorController.java b/components/src/main/java/com/opensourcewithslu/components/controllers/DCMotorController.java deleted file mode 100644 index f1e14b5a..00000000 --- a/components/src/main/java/com/opensourcewithslu/components/controllers/DCMotorController.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.opensourcewithslu.components.controllers; - -import com.opensourcewithslu.outputdevices.DCMotorHelper; -import com.pi4j.io.pwm.Pwm; -import io.micronaut.http.annotation.Controller; -import io.micronaut.http.annotation.Get; -import jakarta.inject.Named; - -//tag::ex[] -@Controller("/DCMotor") -public class DCMotorController { - private final DCMotorHelper DCMotorHelper; - - public DCMotorController(@Named("DC-motor") Pwm DCMotor) { - this.DCMotorHelper = new DCMotorHelper(DCMotor); - } - - @Get("/enable") - public void enableDCMotor() { - DCMotorHelper.enable(); - } - - @Get("/disable") - public void disableDCMotor() { - DCMotorHelper.disable(); - } - - @Get("/setSpeed/{speed}") - public void setSpeed(double speed) { - DCMotorHelper.setSpeed(speed); - } -} -//end::ex[] diff --git a/components/src/main/java/com/opensourcewithslu/components/controllers/MotorController.java b/components/src/main/java/com/opensourcewithslu/components/controllers/MotorController.java new file mode 100644 index 00000000..f0aa394f --- /dev/null +++ b/components/src/main/java/com/opensourcewithslu/components/controllers/MotorController.java @@ -0,0 +1,43 @@ +package com.opensourcewithslu.components.controllers; + +import com.opensourcewithslu.outputdevices.MotorHelper; +import com.pi4j.io.pwm.Pwm; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import jakarta.inject.Named; + +//tag::ex[] +@Controller("/DCMotor") +public class MotorController { + private final MotorHelper MotorHelper; + + public MotorController(@Named("DC-motor") Pwm DCMotor) { + this.MotorHelper = new MotorHelper(DCMotor); + } + + @Get("/enable") + public void enableDCMotor() { + MotorHelper.enable(); + } + + @Get("/disable") + public void disableDCMotor() { + MotorHelper.disable(); + } + + @Get("/setSpeed/{speed}") + public void setSpeed(double speed) { + MotorHelper.setSpeed(speed); + } + + @Get("/setClockwise/{clockwise}") + public void setClockwise(boolean clockwise) { + MotorHelper.setClockwise(clockwise); + } + + @Get("/switchDirection") + public void switchDirection() { + MotorHelper.switchDirection(); + } +} +//end::ex[] diff --git a/components/src/main/resources/application.yml b/components/src/main/resources/application.yml index 312d41ac..77a583d4 100644 --- a/components/src/main/resources/application.yml +++ b/components/src/main/resources/application.yml @@ -37,8 +37,8 @@ pi4j: shutdown: 0 dc-motor: name: DC Motor - address: # TODO: Add address - pwmType: # TODO: Add pwmType + address: 18 + pwmType: SOFTWARE provider: pigpio-pwm initial: 0 shutdown: 0 diff --git a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/DCMotorHelper.java b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java similarity index 61% rename from pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/DCMotorHelper.java rename to pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java index 401c4dfb..00d87924 100644 --- a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/DCMotorHelper.java +++ b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java @@ -8,23 +8,21 @@ * Helper class to control a DC motor using PWM (Pulse Width Modulation). * This class provides methods to enable, disable, and set the speed of a DC motor. */ -public class DCMotorHelper { +public class MotorHelper { - private static final Logger log = LoggerFactory.getLogger(DCMotorHelper.class); + private static final Logger log = LoggerFactory.getLogger(MotorHelper.class); private static final int FREQUENCY = 50; // Frequency for PWM signal in Hz, typical for DC motors. - private static final int PWM_CYCLE_MICROSECONDS = 20000; // Total cycle length in microseconds, corresponding to 50 Hz. - private static final int DC_MIN_PULSE = 500; // Minimum pulse width in microseconds corresponding to 0 degrees. - private static final int DC_MAX_PULSE = 2500; // Maximum pulse width in microseconds corresponding to 180 degrees. private boolean isEnabled = false; // State tracking variable for the DC motor. - private double speed = 0; // Speed of the DC motor, as a percentage 0 to 1. + private double speed = 0; // Speed of the DC motor, as a value 0 to 100. private final Pwm DCMotor; // PWM interface for the DC motor. + private boolean isClockwise = true; // Direction of the DC motor. /** * Constructs a new DCMotorHelper. * * @param DCMotor A PWM interface to control the DC motor. */ - public DCMotorHelper(Pwm DCMotor) { + public MotorHelper(Pwm DCMotor) { this.DCMotor = DCMotor; } @@ -47,16 +45,6 @@ public void disable() { isEnabled = false; } - /** - * Maps the given speed to the corresponding pulse width for the DC motor. - * - * @param value the speed in degrees to be mapped to pulse width. - * @return the calculated pulse width in microseconds. - */ - private float map(float value) { - return DC_MIN_PULSE + (value * (DC_MAX_PULSE - DC_MIN_PULSE)); - } - /** * Sets the speed of the DC motor. * This method calculates the necessary pulse width and duty cycle to achieve the specified speed. @@ -75,11 +63,33 @@ public void setSpeed(double speed) { } this.speed = speed; - float pulseWidth = map((float) (speed * 180)); - float dutyCycle = (pulseWidth / PWM_CYCLE_MICROSECONDS) * 100; - log.info("Setting DC speed to {}%, Pulse Width: {} us, Duty Cycle: {}%", speed * 100, pulseWidth, dutyCycle); + log.info("Setting DC speed to {}%", speed); + + DCMotor.on(speed, FREQUENCY); + } + + /** + * Sets the direction of the DC motor. + * + * @param clockwise whether the DC motor should rotate clockwise. + */ + public void setClockwise(boolean clockwise) { + if (!isEnabled) { + log.info("You must enable the DC motor first."); + return; + } + + log.info("Setting DC motor direction clockwise to {}", clockwise); + // TODO: Implement logic to set the direction of the DC motor. + + isClockwise = clockwise; + } - DCMotor.on(dutyCycle, FREQUENCY); + /** + * Switches the direction of the DC motor. + */ + public void switchDirection() { + setClockwise(!isClockwise); } } From 7c7b637883f7deb9d9a951d133dea02469b4f5e8 Mon Sep 17 00:00:00 2001 From: Leandru Martin Date: Mon, 30 Sep 2024 10:50:14 -0500 Subject: [PATCH 4/9] Moved variable --- .../java/com/opensourcewithslu/outputdevices/MotorHelper.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java index 00d87924..33e62ca3 100644 --- a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java +++ b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java @@ -13,7 +13,6 @@ public class MotorHelper { private static final Logger log = LoggerFactory.getLogger(MotorHelper.class); private static final int FREQUENCY = 50; // Frequency for PWM signal in Hz, typical for DC motors. private boolean isEnabled = false; // State tracking variable for the DC motor. - private double speed = 0; // Speed of the DC motor, as a value 0 to 100. private final Pwm DCMotor; // PWM interface for the DC motor. private boolean isClockwise = true; // Direction of the DC motor. @@ -62,8 +61,6 @@ public void setSpeed(double speed) { return; } - this.speed = speed; - log.info("Setting DC speed to {}%", speed); DCMotor.on(speed, FREQUENCY); From ecc7983af5e9891dfaaf6e2f55414a4c5e332662 Mon Sep 17 00:00:00 2001 From: Leandru Martin Date: Fri, 4 Oct 2024 19:22:11 -0500 Subject: [PATCH 5/9] Added support for changing motor direction by switching pins --- .../components/controllers/MotorController.java | 6 ++++-- .../outputdevices/MotorHelper.java | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/components/src/main/java/com/opensourcewithslu/components/controllers/MotorController.java b/components/src/main/java/com/opensourcewithslu/components/controllers/MotorController.java index f0aa394f..309385c7 100644 --- a/components/src/main/java/com/opensourcewithslu/components/controllers/MotorController.java +++ b/components/src/main/java/com/opensourcewithslu/components/controllers/MotorController.java @@ -1,6 +1,7 @@ package com.opensourcewithslu.components.controllers; import com.opensourcewithslu.outputdevices.MotorHelper; +import com.pi4j.io.gpio.digital.DigitalOutput; import com.pi4j.io.pwm.Pwm; import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.Get; @@ -11,8 +12,9 @@ public class MotorController { private final MotorHelper MotorHelper; - public MotorController(@Named("DC-motor") Pwm DCMotor) { - this.MotorHelper = new MotorHelper(DCMotor); + public MotorController(@Named("DC-motor") Pwm DCMotor, @Named("pin1") DigitalOutput pin1, + @Named("pin2") DigitalOutput pin2) { + this.MotorHelper = new MotorHelper(DCMotor, pin1, pin2); } @Get("/enable") diff --git a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java index 33e62ca3..f131c678 100644 --- a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java +++ b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java @@ -1,5 +1,6 @@ package com.opensourcewithslu.outputdevices; +import com.pi4j.io.gpio.digital.DigitalOutput; import com.pi4j.io.pwm.Pwm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,6 +15,8 @@ public class MotorHelper { private static final int FREQUENCY = 50; // Frequency for PWM signal in Hz, typical for DC motors. private boolean isEnabled = false; // State tracking variable for the DC motor. private final Pwm DCMotor; // PWM interface for the DC motor. + private final DigitalOutput pin1; // GPIO pin 1 for motor direction. + private final DigitalOutput pin2; // GPIO pin 2 for motor direction. private boolean isClockwise = true; // Direction of the DC motor. /** @@ -21,8 +24,10 @@ public class MotorHelper { * * @param DCMotor A PWM interface to control the DC motor. */ - public MotorHelper(Pwm DCMotor) { + public MotorHelper(Pwm DCMotor, DigitalOutput pin1, DigitalOutput pin2) { this.DCMotor = DCMotor; + this.pin1 = pin1; + this.pin2 = pin2; } /** @@ -78,7 +83,13 @@ public void setClockwise(boolean clockwise) { } log.info("Setting DC motor direction clockwise to {}", clockwise); - // TODO: Implement logic to set the direction of the DC motor. + if (clockwise) { + pin1.high(); + pin2.low(); + } else { + pin1.low(); + pin2.high(); + } isClockwise = clockwise; } From 542a4c5dc95b62bc4b0d6d91db6e8797dacb0104 Mon Sep 17 00:00:00 2001 From: Leandru Martin Date: Fri, 4 Oct 2024 20:03:33 -0500 Subject: [PATCH 6/9] Added AsciiDoc tags --- .../outputdevices/MotorHelper.java | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java index f131c678..27ef0f40 100644 --- a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java +++ b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java @@ -24,7 +24,10 @@ public class MotorHelper { * * @param DCMotor A PWM interface to control the DC motor. */ - public MotorHelper(Pwm DCMotor, DigitalOutput pin1, DigitalOutput pin2) { + //tag::const[] + public MotorHelper(Pwm DCMotor, DigitalOutput pin1, DigitalOutput pin2) + //end::const[] + { this.DCMotor = DCMotor; this.pin1 = pin1; this.pin2 = pin2; @@ -34,7 +37,10 @@ public MotorHelper(Pwm DCMotor, DigitalOutput pin1, DigitalOutput pin2) { * Enables the DC motor by setting an initial duty cycle and frequency. * The DC motor remains disabled until this method is called. */ - public void enable() { + //tag::[method] + public void enable() + //end::[method] + { log.info("Enabling DC motor"); DCMotor.on(0, FREQUENCY); // Initializes PWM signal with 0% duty cycle. isEnabled = true; @@ -43,7 +49,10 @@ public void enable() { /** * Disables the DC motor, effectively stopping any ongoing PWM signal. */ - public void disable() { + //tag::[method] + public void disable() + //end::[method] + { log.info("Disabling DC motor"); DCMotor.off(); // Stops the PWM signal. isEnabled = false; @@ -55,7 +64,10 @@ public void disable() { * * @param speed the target speed for the DC motor, as a percentage between 0 and 1. */ - public void setSpeed(double speed) { + //tag::[method] + public void setSpeed(double speed) + //end::[method] + { if (!isEnabled) { log.info("You must enable the DC motor first."); return; @@ -76,7 +88,10 @@ public void setSpeed(double speed) { * * @param clockwise whether the DC motor should rotate clockwise. */ - public void setClockwise(boolean clockwise) { + //tag::[method] + public void setClockwise(boolean clockwise) + //end::[method] + { if (!isEnabled) { log.info("You must enable the DC motor first."); return; @@ -97,7 +112,10 @@ public void setClockwise(boolean clockwise) { /** * Switches the direction of the DC motor. */ - public void switchDirection() { + //tag::[method] + public void switchDirection() + //end::[method] + { setClockwise(!isClockwise); } } From b3a7744703f703486139895b1284c9bbe4c807a9 Mon Sep 17 00:00:00 2001 From: Leandru Martin Date: Sat, 5 Oct 2024 10:05:59 -0500 Subject: [PATCH 7/9] Fixed MotorHelper documentation, changed names of motor variables --- .../components/controllers/MotorController.java | 6 +++--- components/src/main/resources/application.yml | 4 ++-- .../com/opensourcewithslu/outputdevices/MotorHelper.java | 2 ++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/components/src/main/java/com/opensourcewithslu/components/controllers/MotorController.java b/components/src/main/java/com/opensourcewithslu/components/controllers/MotorController.java index 309385c7..8eb449ba 100644 --- a/components/src/main/java/com/opensourcewithslu/components/controllers/MotorController.java +++ b/components/src/main/java/com/opensourcewithslu/components/controllers/MotorController.java @@ -8,13 +8,13 @@ import jakarta.inject.Named; //tag::ex[] -@Controller("/DCMotor") +@Controller("/motor") public class MotorController { private final MotorHelper MotorHelper; - public MotorController(@Named("DC-motor") Pwm DCMotor, @Named("pin1") DigitalOutput pin1, + public MotorController(@Named("motor") Pwm motor, @Named("pin1") DigitalOutput pin1, @Named("pin2") DigitalOutput pin2) { - this.MotorHelper = new MotorHelper(DCMotor, pin1, pin2); + this.MotorHelper = new MotorHelper(motor, pin1, pin2); } @Get("/enable") diff --git a/components/src/main/resources/application.yml b/components/src/main/resources/application.yml index 77a583d4..5207dd46 100644 --- a/components/src/main/resources/application.yml +++ b/components/src/main/resources/application.yml @@ -35,8 +35,8 @@ pi4j: provider: pigpio-pwm initial: 0 shutdown: 0 - dc-motor: - name: DC Motor + motor: + name: Motor address: 18 pwmType: SOFTWARE provider: pigpio-pwm diff --git a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java index 27ef0f40..b7dc8363 100644 --- a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java +++ b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java @@ -23,6 +23,8 @@ public class MotorHelper { * Constructs a new DCMotorHelper. * * @param DCMotor A PWM interface to control the DC motor. + * @param pin1 A DigitalOutput interface for the first GPIO pin. + * @param pin2 A DigitalOutput interface for the second GPIO pin. */ //tag::const[] public MotorHelper(Pwm DCMotor, DigitalOutput pin1, DigitalOutput pin2) From dd5f12217ba87fbf07775cd0b369b833f9ca7d93 Mon Sep 17 00:00:00 2001 From: Leandru Martin Date: Sat, 5 Oct 2024 10:10:32 -0500 Subject: [PATCH 8/9] Renamed more variables and comments from "DC motor" to simply "motor", fixed bug with motor speed checking --- .../outputdevices/MotorHelper.java | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java index b7dc8363..d7ef8ca6 100644 --- a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java +++ b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java @@ -7,56 +7,56 @@ /** * Helper class to control a DC motor using PWM (Pulse Width Modulation). - * This class provides methods to enable, disable, and set the speed of a DC motor. + * This class provides methods to enable, disable, and set the speed of a motor. */ public class MotorHelper { private static final Logger log = LoggerFactory.getLogger(MotorHelper.class); - private static final int FREQUENCY = 50; // Frequency for PWM signal in Hz, typical for DC motors. - private boolean isEnabled = false; // State tracking variable for the DC motor. - private final Pwm DCMotor; // PWM interface for the DC motor. + private static final int FREQUENCY = 50; // Frequency for PWM signal in Hz. + private boolean isEnabled = false; // State tracking variable for the motor. + private final Pwm motor; // PWM interface for the motor. private final DigitalOutput pin1; // GPIO pin 1 for motor direction. private final DigitalOutput pin2; // GPIO pin 2 for motor direction. - private boolean isClockwise = true; // Direction of the DC motor. + private boolean isClockwise = true; // Direction of the motor. /** - * Constructs a new DCMotorHelper. + * Constructs a new MotorHelper. * - * @param DCMotor A PWM interface to control the DC motor. + * @param motor A PWM interface to control the motor. * @param pin1 A DigitalOutput interface for the first GPIO pin. * @param pin2 A DigitalOutput interface for the second GPIO pin. */ //tag::const[] - public MotorHelper(Pwm DCMotor, DigitalOutput pin1, DigitalOutput pin2) + public MotorHelper(Pwm motor, DigitalOutput pin1, DigitalOutput pin2) //end::const[] { - this.DCMotor = DCMotor; + this.motor = motor; this.pin1 = pin1; this.pin2 = pin2; } /** * Enables the DC motor by setting an initial duty cycle and frequency. - * The DC motor remains disabled until this method is called. + * The motor remains disabled until this method is called. */ //tag::[method] public void enable() //end::[method] { log.info("Enabling DC motor"); - DCMotor.on(0, FREQUENCY); // Initializes PWM signal with 0% duty cycle. + motor.on(0, FREQUENCY); // Initializes PWM signal with 0% duty cycle. isEnabled = true; } /** - * Disables the DC motor, effectively stopping any ongoing PWM signal. + * Disables the motor, effectively stopping any ongoing PWM signal. */ //tag::[method] public void disable() //end::[method] { log.info("Disabling DC motor"); - DCMotor.off(); // Stops the PWM signal. + motor.off(); // Stops the PWM signal. isEnabled = false; } @@ -64,7 +64,7 @@ public void disable() * Sets the speed of the DC motor. * This method calculates the necessary pulse width and duty cycle to achieve the specified speed. * - * @param speed the target speed for the DC motor, as a percentage between 0 and 1. + * @param speed the target speed for the motor, as a percentage between 0 and 1. */ //tag::[method] public void setSpeed(double speed) @@ -75,20 +75,20 @@ public void setSpeed(double speed) return; } - if (speed < 0 || speed > 1) { - log.info("You must enter a speed between 0 and 1."); + if (speed < 0 || speed > 100) { + log.info("You must enter a speed between 0 and 100."); return; } - log.info("Setting DC speed to {}%", speed); + log.info("Setting motor speed to {}%", speed); - DCMotor.on(speed, FREQUENCY); + motor.on(speed, FREQUENCY); } /** * Sets the direction of the DC motor. * - * @param clockwise whether the DC motor should rotate clockwise. + * @param clockwise whether the motor should rotate clockwise. */ //tag::[method] public void setClockwise(boolean clockwise) @@ -99,7 +99,7 @@ public void setClockwise(boolean clockwise) return; } - log.info("Setting DC motor direction clockwise to {}", clockwise); + log.info("Setting motor direction clockwise to {}", clockwise); if (clockwise) { pin1.high(); pin2.low(); @@ -112,7 +112,7 @@ public void setClockwise(boolean clockwise) } /** - * Switches the direction of the DC motor. + * Switches the direction of the motor. */ //tag::[method] public void switchDirection() From e978d4d5cb8833376924fcf15206d9b95a1f0631 Mon Sep 17 00:00:00 2001 From: Leandru Martin Date: Sat, 5 Oct 2024 12:10:15 -0500 Subject: [PATCH 9/9] Added MotorHelper tests --- .../outputdevices/MotorHelper.java | 11 +- .../outputdevices/MotorHelperTest.java | 135 ++++++++++++++++++ 2 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 pi4micronaut-utils/src/test/java/com/opensourcewithslu/outputdevices/MotorHelperTest.java diff --git a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java index d7ef8ca6..753b128b 100644 --- a/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java +++ b/pi4micronaut-utils/src/main/java/com/opensourcewithslu/outputdevices/MotorHelper.java @@ -11,7 +11,7 @@ */ public class MotorHelper { - private static final Logger log = LoggerFactory.getLogger(MotorHelper.class); + private static Logger log = LoggerFactory.getLogger(MotorHelper.class); private static final int FREQUENCY = 50; // Frequency for PWM signal in Hz. private boolean isEnabled = false; // State tracking variable for the motor. private final Pwm motor; // PWM interface for the motor. @@ -120,4 +120,13 @@ public void switchDirection() { setClockwise(!isClockwise); } + + /** + * Sets the logger object. + * + * @param log Logger object to set the logger to. + */ + public void setLog(Logger log) { + this.log = log; + } } diff --git a/pi4micronaut-utils/src/test/java/com/opensourcewithslu/outputdevices/MotorHelperTest.java b/pi4micronaut-utils/src/test/java/com/opensourcewithslu/outputdevices/MotorHelperTest.java new file mode 100644 index 00000000..5a534ab6 --- /dev/null +++ b/pi4micronaut-utils/src/test/java/com/opensourcewithslu/outputdevices/MotorHelperTest.java @@ -0,0 +1,135 @@ +package com.opensourcewithslu.outputdevices; + +import com.pi4j.io.gpio.digital.DigitalOutput; +import com.pi4j.io.pwm.Pwm; +import org.junit.jupiter.api.*; +import org.slf4j.Logger; + +import static org.mockito.Mockito.*; + +public class MotorHelperTest { + DigitalOutput pin1 = mock(DigitalOutput.class); + DigitalOutput pin2 = mock(DigitalOutput.class); + Pwm motor = mock(Pwm.class); + MotorHelper motorHelper = new MotorHelper(motor, pin1, pin2); + Logger log = mock(Logger.class); + + @BeforeEach + public void openMocks() { + motorHelper.setLog(log); + } + + @Test + void enables() { + motorHelper.enable(); + verify(motor).on(0, 50); + verify(log).info("Enabling DC motor"); + } + + @Test + void disables() { + motorHelper.disable(); + verify(motor).off(); + verify(log).info("Disabling DC motor"); + } + + @Test + void setSpeedWorksWhenEnabled() { + motorHelper.enable(); + verify(log).info("Enabling DC motor"); + motorHelper.setSpeed(10); + verify(motor).on(10.0d, 50); + verify(log).info("Setting motor speed to {}%", 10.0d); + } + + @Test + void setSpeedFailsWhenDisabled() { + motorHelper.setSpeed(10); + verify(log).info("You must enable the DC motor first."); + verify(motor, never()).on(10.0d, 50); + verify(log, never()).info("Setting motor speed to {}%", 10); + } + + @Test + void setSpeedFailsWhenSpeedIsNegative() { + motorHelper.enable(); + verify(log).info("Enabling DC motor"); + motorHelper.setSpeed(-10); + verify(log).info("You must enter a speed between 0 and 100."); + verify(motor, never()).on(-10.0d, 50); + verify(log, never()).info("Setting speed to {}%", -10.0d); + } + + @Test + void setSpeedFailsWhenSpeedIsAbove100() { + motorHelper.enable(); + verify(log).info("Enabling DC motor"); + motorHelper.setSpeed(110); + verify(log).info("You must enter a speed between 0 and 100."); + verify(motor, never()).on(110.0d, 50); + verify(log, never()).info("Setting motor speed to {}%", 110.0d); + } + + @Test + void setClockwiseTrueWorksWhenEnabled() { + motorHelper.enable(); + verify(log).info("Enabling DC motor"); + motorHelper.setClockwise(true); + verify(pin1).high(); + verify(pin2).low(); + verify(log).info("Setting motor direction clockwise to {}", true); + } + + @Test + void setClockwiseFalseWorksWhenEnabled() { + motorHelper.enable(); + verify(log).info("Enabling DC motor"); + motorHelper.setClockwise(false); + verify(pin1).low(); + verify(pin2).high(); + verify(log).info("Setting motor direction clockwise to {}", false); + } + + @Test + void setClockwiseFailsWhenDisabled() { + motorHelper.setClockwise(true); + verify(log).info("You must enable the DC motor first."); + verify(pin1, never()).high(); + verify(pin2, never()).low(); + verify(log, never()).info("Setting motor direction clockwise to {}", true); + } + + @Test + void switchDirectionFromClockwiseWorksWhenEnabled() { + motorHelper.enable(); + verify(log).info("Enabling DC motor"); + motorHelper.setClockwise(true); + motorHelper.switchDirection(); + verify(pin1).low(); + verify(pin2).high(); + verify(log).info("Setting motor direction clockwise to {}", false); + } + + @Test + void switchDirectionToClockwiseWorksWhenEnabled() { + motorHelper.enable(); + verify(log).info("Enabling DC motor"); + motorHelper.setClockwise(false); + motorHelper.switchDirection(); + verify(pin1).high(); + verify(pin2).low(); + verify(log).info("Setting motor direction clockwise to {}", false); + } + + @Test + void switchDirectionFailsWhenDisabled() { + motorHelper.switchDirection(); + verify(log).info("You must enable the DC motor first."); + verify(pin1, never()).high(); + verify(pin1, never()).low(); + verify(pin2, never()).high(); + verify(pin2, never()).low(); + verify(log, never()).info("Setting motor direction clockwise to {}", true); + verify(log, never()).info("Setting motor direction clockwise to {}", false); + } +}