Saturday, November 12, 2016

IOT: Java + Raspberry Pi + Pi4j+ Stepper Motor

Objective: The Objective of this exercise is to configure the Stepper Motor with Raspberry Pi and control it (by rotating the Motor in Forward and Backward direction) using GPIO pins on Raspberry Pi.

YouTube Video:
The YouTube Video for this tutorial is available at this link

GitHub Source:
https://github.com/agilerules/IOT/tree/master/iot-pi4j-raspi-steppermotor
Overview about Stepper Motor:
Stepper Motor uses a cogged wheel and electro magnet to nudge the wheel round a 'step’ at a time, when DC Voltage is applied. Stepper motors effectively have multiple "toothed" electromagnets arranged around a central gear-shaped piece of iron. The electromagnets are energized by an external driver circuit or a micro controller. To make the motor shaft turn, first, one electromagnet is given power, which magnetically attracts the gear's teeth. When the gear's teeth are aligned to the first electromagnet, they are slightly offset from the next electromagnet. This means that when the next electromagnet is turned on and the first is turned off, the gear rotates slightly to align with the next one. From there the process is repeated. Each of those rotations is called a "step", with an integer number of steps making a full rotation. In that way, the motor can be turned by a precise angle.
Animation of Stepper Motor:
Note: The above image is taken from Wikipedia.
The following is the explanation of the above animation image of stepper motor (unipolar):
Frame 1: The top electromagnet (1) is turned on, attracting the nearest teeth of the gear-shaped iron rotor. With the teeth aligned to electromagnet 1, they will be slightly offset from right electromagnet (2).
Frame 2: The top electromagnet (1) is turned off, and the right electromagnet (2) is energized, pulling the teeth into alignment with it. This results in a rotation of 3.6° in this example.
Frame 3: The bottom electromagnet (3) is energized; another 3.6° rotation occurs.
Frame 4: The left electromagnet (4) is energized, rotating again by 3.6°. When the top electromagnet (1) is again enabled, the rotor will have rotated by one tooth position; since there are 25 teeth, it will take 100 steps to make a full rotation in this example.
More details on the Stepper Motor stepping can be found in the following link:


Software:

  • Pi4j
  • Java
  • Maven (Please find my blog here on how to install Maven on Raspberry Pi)


Hardware:

  • Raspberry Pi (installed with Java, Maven)
  • 5 Jumper wires
  • Stepper Motor (28BYJ-48-5V)
  • Driver Board ULN2003 with drive Test Module Machinery Board
  • Breadboard
  • GPIO Ribbon Cable

Steps:
1.  Complete the following Wiring process of Raspberry Pi, Driver Board ULN2003 and with few jumper wires as shown in the below diagram. Ensure that the Raspberry Pi is in Power OFF mode, while doing the wiring process.
Wiring Diagram:
Breadboard Diagram:
  1. A wire from Pin 11 (GPIO 0) to Board LED 0
  2. A wire from Pin 12 (GPIO 1) to Board LED 1
  3. A wire from Pin 13 (GPIO 2) to Board LED 2
  4. A wire from Pin 15 (GPIO 3) to Board LED 3
  5. A wire from Pin 2 (5 V Power) to Board Anode (+)
  6. A wire from Pin 6 (Ground) to Board Cathode (-)
2.  Once the above connection is complete, Power ON the Raspberry Pi. Now connect to Raspberry Pi using Putty with your Raspberry Pi Credentials and by-default, you will in the path /home/pi. 
3.  For proper organization purpose, I created folders (using mkdir command) \projects. But this is not mandatory. You can even skip this step and move to next step.
mkdir projects
4.  From the \projects folder, execute the following command to Git clone the code to your local raspberry Pi.
git clone https://github.com/agilerules/IOT.git
5.  Once the git clone is complete, you will see IOT folder created in \projects folder. Now go to IOT folder (using the command cd IOT) and you will see the folder iot-pi4j-raspi-steppermotor inside this folder IOT.
6.  Move to this iot-pi4j-raspi-steppermotor folder (using the command cd iot-pi4j-raspi-steppermotor)
7.  Now run the following commands to perform maven clean and maven package. (Incase if mvn command is not recognized then it means that maven is not installed on your Raspberry Pi.  Please follow my blog on how to install Maven on Raspberry Pi.
mvn clean

mvn package

8. Now execute the following command to start the maven build and run the Java class StepperMotor.java in standalone mode. (Incase if mvn command is not recognized then it means that maven is not installed on your Raspberry Pi.  Please follow my blog on how to install Maven on Raspberry Pi.
mvn exec:java -Dexec.mainClass="stepper.motor.StepperMotor" -Dexec.classpathScope=runtime


9.  If all the wiring is done correctly, now you should see the Stepper Motor should be in action – i.e start its rotation, with the above options listed.
10. Here is the source code explanation below:
The complete project structure is available here:
a) Pom.xml:
The below is the library dependency that we need for this application:
pi4j-core – This is for Pi4J to communicate with Raspberry Pi GPIO pins.
pi4j-device – This is for Pi4J to communicate with Stepper Motor.
<dependencies>
            <dependency>
                  <groupId>com.pi4j</groupId>
                  <artifactId>pi4j-core</artifactId>
                  <version>1.1-SNAPSHOT</version>
            </dependency>
<dependency>
                  <groupId>com.pi4j</groupId>
                  <artifactId>pi4j-device</artifactId>
                  <version>1.2-SNAPSHOT</version>
            </dependency>
   </dependencies>
Note:
1. Maven Compiler configuration should be set to Java 1.7 or above for this program to run because we are using the byte API’s which will work only with Java 1.7 or above.
<build>
<plugins>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>3.5.1</version>
               <configuration>
                  <source>1.7</source>
                  <target>1.7</target>
               </configuration>
            </plugin>
      </plugins>
      </build>
2. At the time of wiring this program, the Pi4j 1.1 is available as a SNAPSHOT version and is not available in Maven repository yet. So had to use the OSS Sonatype Repository URL.
<repository>
            <id>oss-snapshots-repo</id>
            <name>Sonatype OSS Maven Repository</name>
            <url>https://oss.sonatype.org/content/groups/public</url>
            <snapshots>
                  <enabled>true</enabled>
                  <updatePolicy>always</updatePolicy>
            </snapshots>
</repository>

b) StepperMotor.java:
This java class has one method named controlStepperMotor(), which will rotate the Stepper Motor at various steps. Here are the steps involved:
1.  Pi4j programs can be run with sudo user only. But with version 1.1, it is no more required if the program is enabled to run with Non Privileged Access using the following command. 
//This is required to enable Non Privileged Access to avoid applying sudo to run Pi4j programs
GpioUtil.enableNonPrivilegedAccess();
2.  As shown in the wiring diagram section, we are going to use the 4 GPIO pins – GPIO_00, GPIO_01, GPIO_02, and GPIO_03 of Raspberry Pi to communicate with Stepper Motor. Now provision these 4 pins as output pins and ensure they are in LOW state with the following lines of code: 
// provision gpio pins #00 to #03 as output pins and ensure in LOW state
        final GpioPinDigitalOutput[] pins = {
  gpio.provisionDigitalOutputPin(RaspiPin.GPIO_00, PinState.LOW),
        gpio.provisionDigitalOutputPin(RaspiPin.GPIO_01, PinState.LOW),
        gpio.provisionDigitalOutputPin(RaspiPin.GPIO_02, PinState.LOW),
        gpio.provisionDigitalOutputPin(RaspiPin.GPIO_03,PinState.LOW)};
3.  Set the GPIO Shutdown options to ensure that the motor is stopped when the program terminates.
// this will ensure that the motor is stopped when the program terminates
gpio.setShutdownOptions(true, PinState.LOW, pins);
4.  Create a Stepper Motor Component instance motor using the following code:
GpioStepperMotorComponent motor = new GpioStepperMotorComponent(pins);
5. There are 4 types of step sequencing that is possible with Stepper Motor – Single Step Sequence, Double Step Sequence, Half Step Sequence and Micro Step Sequence. 
a)  Single-step sequence:
This is the most basic method, turning on a single electromagnet every time. This sequence requires the least amount of energy and generates the smoothest movement.
Coil 4
Coil 3
Coil 2
Coil 1
Step Number
Off
Off
Off
On
1
Off
Off
On
Off
2
Off
On
Off
Off
3
On
Off
Off
Off
4

Animation:
Java code definition:
Define ByteArray as follows to demonstrate the Single-step sequencing for the Stepper Motor:
byte[] single_step_sequence = new byte[4];
      single_step_sequence[0] = (byte) 0b0001;
            single_step_sequence[1] = (byte) 0b0010;
      single_step_sequence[2] = (byte) 0b0100;
   single_step_sequence[3] = (byte) 0b1000;
b)  Double-step sequence:
In this method, two coils are turned on simultaneously. This method does not generate a smooth movement as the previous method, and it requires double the current, but as a return, it generates double the torque.
Coil 4
Coil 3
Coil 2
Coil 1
Step Number
Off
Off
On
On
1
Off
On
On
Off
2
On
On
Off
Off
3
On
Off
Off
On
4

Animation:
Java code definition:
Define ByteArray as follows to demonstrate the Double-step sequencing for the Stepper Motor:
byte[] double_step_sequence = new byte[4];
         double_step_sequence[0] = (byte) 0b0011;
         double_step_sequence[1] = (byte) 0b0110;
         double_step_sequence[2] = (byte) 0b1100;
double_step_sequence[3] = (byte) 0b1001;
c)  Half-step sequence:
In this method, two coils are turned on simultaneously. This method does not generate a smooth movement as the previous method, and it requires double the current, but as a return, it generates double the torque.
Coil 4
Coil 3
Coil 2
Coil 1
Step Number
Off
Off
Off
On
1
Off
Off
On
On
2
Off
Off
On
Off
3
Off
On
On
Off
4
Off
On
Off
Off
5
On
On
Off
Off
6
On
Off
Off
Off
7
On
Off
Off
On
8
Animation:
Java code definition:
Define ByteArray as follows to demonstrate the Half-step sequencing for the Stepper Motor:
byte[] half_step_sequence = new byte[8];
         half_step_sequence[0] = (byte) 0b0001;
         half_step_sequence[1] = (byte) 0b0011;
         half_step_sequence[2] = (byte) 0b0010;
         half_step_sequence[3] = (byte) 0b0110;
         half_step_sequence[4] = (byte) 0b0100;
         half_step_sequence[5] = (byte) 0b1100;
         half_step_sequence[6] = (byte) 0b1000;
half_step_sequence[7] = (byte) 0b1001;
You will define the step sequence using motor.stepsequence() method of the GpioStepperMotorComponent instance. For example, if you would like to set the step sequence to double step, set it as follows, where motor is the instance of GpioStepperMotorComponent.
motor.setStepSequence(double_step_sequence);

6.  Now identify the steps required in the Stepper motor to make one Revolution. Usually, this information will be available in the specifications of your Stepper Motor model that you are using. In my case, there are 32 steps per revolution on my sample motor, and inside is a ~1/64 reduction gear set. Gear reduction is actually as (32/9)/(22/11)x(26/9)x(31/10)=63.683950617. This means is that there are really 32*63.683950617 steps per revolution = 2037.88641975 ~ 2038 steps! 
   int oneRevolution = 2038;
         int quarterRevolution = oneRevolution / 4;
         int halfRevolution = oneRevolution / 2;
int oneDegreeRevolution = oneRevolution / 360;
7.  Now define the Stepper Motor parameters before attempting to control the Stepper Motor by setting the Step internal and step sequence. Set the Step internal to 2 milliseconds and anything lower than 2 milliseconds does not work for my sample motor using single step sequence. 
motor.setStepInterval(2);
motor.setStepSequence(single_step_sequence);
motor.setStepsPerRevolution(oneRevolution);
8.  Now perform the various Stepper Motor rotation combinations based on the direction (FORWARD and REVERSE) and number of Revolutions (Full, Half, Quarter, One Degree) using the following API's: 
motor.step(oneRevolution) -- performs Motor FORWARD for 1 Revolution = 2038 steps
motor.step(-oneRevolution) -- performs Motor FORWARD for 1 Revolution = 2038 steps
motor.rotate(2) -- performs Motor FORWARD for 2 Revolutions = 2 x 2038 = 4076 steps
motor.rotate(-2) -- performs Motor REVERSE for 2 Revolutions = 2 x 2038 = 4076 steps
motor.forward(5000) -- performs Motor FORWARD for 5 seconds
motor.reverse(5000) -- performs Motor REVERSE for 5 seconds
motor.step(halfRevolution) -- performs Motor FORWARD for Half Revolution = 2038/2 = 1019 steps
motor.step(-halfRevolution) -- performs Motor REVERSE for Half Revolution = 2038/2 = 1019 steps
motor.step(quarterRevolution) -- performs Motor FORWARD for Quarter Revolution = 2038/4 = 509.5 steps
motor.step(-quarterRevolution) -- performs Motor REVERSE for Quarter Revolution = 2038/4 = 509.5 steps
motor.step(oneDegreeRevolution) -- performs Motor FORWARD for One Degree Revolution = 2038/360 = 5.66 steps
motor.step(-oneDegreeRevolution) -- performs Motor REVERSE for One Degree Revolution = 2038/360 = 5.66 steps
Just need to add few additional setters as shown below to perform the Stepper Motor FORWARD with slower speed and higher torque for 1 Revolution = 2038 steps.
motor.setStepSequence(double_step_sequence);
motor.setStepInterval(10);
motor.rotate(1);
9.  That’s the end of the tutorial. Hope it was useful.

No comments:

Post a Comment