# Raspberry Pi 用 Java 控制直流電機的速度和方向
> [https://javatutorial.net/raspberry-pi-control-dc-motor-speed-and-direction-java](https://javatutorial.net/raspberry-pi-control-dc-motor-speed-and-direction-java)
在本教程中,我將向您展示如何使用 Raspberry Pi 和 Java 控制直流電機的方向和速度。
我收到了一些要求創建有關使用 Raspberry Pi 和 Java 控制電機速度和方向的教程的請求,所以我們開始吧! 在本教程中,我將向您展示如何使用 L293D 芯片同時控制和兩個電機的的**方向和速度**。

## 硬體需求
您將需要以下組件來遵循本教程:
* 已安裝最新 Raspbian 的 Raspberry Pi(了解如何[安裝和配置 Raspbian](https://javatutorial.net/install-raspbian-to-sd-card "Install Raspbian to SD Card") )
* 用于連接所有組件的面包板
* 一顆 L293D 芯片
* 1 或 2 個直流電機(第二個為可選),額定電壓為 4.5V 至 36V
* 電池組可為您的電機提供正確的電壓
* 幾根電纜可以連接一切

硬件部件
## L293D
L293D 是用于直流或步進電機的雙 H 橋電機驅動器,這意味著您可以雙向驅動兩個直流電機或一個步進電機。 L293D 的優點在于,它內置有回彈保護功能,可防止損壞 Raspberry Pi。
**切勿將電機直接連接到 Raspberry Pi。 這可能會嚴重損壞您的 Pi!**

L293D 資料表
該芯片有兩個+ V 引腳。 引腳號 8(+ Vmotor)為電機供電,而引腳 16 為芯片本身供電。 我們將引腳 8 連接到電池組,將引腳 16 連接到 Raspberry 的 5V 引腳。
## 選擇合適的直流電機
您需要選擇 4.5V 至 36V 的直流電機。 L293D 無法在 3V 電機上正常工作,并且每個通道的限制為 600mA。
## 軟件需求
我的所有教程都使用 [Pi4J](http://pi4j.com/) 。 Pi4J 是一個很棒的庫,您可以使用 Java 編程語言來控制 Pi 的 GPIO 引腳。 您可以在 [Raspberry Pi Java 教程](https://javatutorial.net/raspberry-pi-java-tutorial)入門中找到有關如何在 Raspberry 和 IDE 上安裝和配置 Pi4J 的詳細說明。
## 組裝電路
組裝電路時,請務必斷開 Raspberry Pi 的電源! 否則可能會損壞 Pi 或組件。 插入 Pi 之前,請務必仔細檢查接線!
請使用下圖組裝電路。

Raspberry Pi 3 的硬件設置,以通過 L293D 和 Java 雙向控制一臺直流電機
在本教程中,我將使用 GPIO 引腳的物理編號。 物理編號指的是通過簡單地從左上角的插針 1 算起并向下計數的插針。
查看下圖,該圖顯示了物理引腳編號和 Pi4J 映射。 例如,物理針腳編號 12 在 Pi4J 中被命名為針腳#1。 在本教程后面的部分中編寫 Java 程序時,請牢記這一點。 [您可以在 Pi4J 官方網站中找到有關引腳編號的更多詳細信息](http://pi4j.com/pins/model-3b-rev1.html)。

Raspberry Pi 3 Model B 引腳和 Pi4J 映射
注意:本教程是針對 Raspberry Pi 3 B 型制作的,當然,您可以在 Raspberry Pi 1 或 2 中構建相同的電路并使用相同的 Java 代碼 - 只需注意引腳編號即可。
1. 將 L293D 引腳#16 連接到 Pi 物理引腳#2(5.0 VDC 電源)
2. 將 L293D 的針腳 4,針腳 5,針腳 12 和針腳 13 連接到 Pi 物理針腳 6(接地)
3. 將 L293D 的 8 號針腳連接到電池組
4. 將 L293D 的針腳#3 和#6 連接到電機
5. 將 L293D 引腳 1 連接到 Pi 物理引腳 22
6. 將 L293D 引腳 2 連接到 Pi 物理引腳 18
7. 將 L293D 針腳#7 連接到 Pi 物理針腳#16
我還將在此處發布電路原理圖以供參考

Raspberry Pi 和 L293D 一臺電機原理圖
具有 1 個電機的組裝電路的照片

1 電機設置的圖片
## Java 程序:控制一臺直流電機的方向
這里是有趣的部分。 連接完所有內容后,您可以打開自己喜歡的 Java IDE 并編寫代碼。 下面的代碼將使電機沿一個方向旋轉 3 秒鐘,然后使電機沿相反方向旋轉 6 秒鐘。
```java
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.RaspiPin;
/**
* Controls motor direction of a single motor
* @author https://javatutorial.net
*/
public class ControlOneMotorDirection {
public static void main(String[] args) throws InterruptedException {
// get a handle to the GPIO controller
final GpioController gpio = GpioFactory.getInstance();
final GpioPinDigitalOutput pinA = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_04, "PinA");
final GpioPinDigitalOutput pinB = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_05, "PinB");
final GpioPinDigitalOutput pinE = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_06, "PinE");
System.out.println("rotate motor clockwise for 3 seconds");
pinA.high();
pinB.low();
pinE.high();
// wait 3 seconds
Thread.sleep(3000);
System.out.println("rotate motor in oposite derection for 6 seconds");
pinA.low();
pinB.high();
// wait 6 seconds
Thread.sleep(6000);
// stop motor
System.out.println("Stopping motor");
pinE.low();
gpio.shutdown();
}
}
```
首先,我們將數字輸出 pinA 映射到 GPIO 引腳 4,將 pinB 映射到 GPIO 引腳 5,將 pinE 映射到 GPIO 引腳 6。 如果您想知道為什么在代碼中使用引腳 4、5 和 6,請再次查看上面發布的 Pi4J 映射圖。 pinE 名稱來自“ pin enable”。
如果 pinE 為高電平,則說明電機已打開。 將 pinE 置于低電平將關閉電機。 我們通過將引腳 A 或 B 之一切換到高電平并將另一個引腳切換到低電平來確定旋轉方向。 例如,如果我們將 pinA 設置為高電平并將 pinB 設置為低電平,則電機將順時針旋轉。 交換銷釘,電機將以相反的方向旋轉。
使用以下命令在 Raspberry 上執行程序
```java
sudo java -classpath .:classes:/opt/pi4j/lib/'*' ControlOneMotorDirection
```
以下視頻演示了結果
<https://www.youtube.com/embed/pim_hLJD5IE>
## 添加第二臺電機(可選)
使用 L293D,我們可以獨立控制 2 個電機的方向,那么為什么不嘗試這樣做呢? 在電路中添加第二個電機很容易–只需將第二個電機插入面包板,并使用 3 條額外的電纜將 L293D 芯片的另外 3 個引腳連接到 Raspberry Pi。

樹莓派控制 2 臺電機
這是組裝電路的圖片– 2 個電機設置

具有 L293D 和兩個直流電機的 Raspberry Pi 電路
## Java 程序:控制兩個直流電機的方向
我們將我們的第一電機稱為`motor1`,第二個電機稱為`motor2`。 我們為 Raspberry Pi 分配了 3 個 GPIO 引腳,分別是 0、2 和 3。
下面的 Java 程序將兩個電機沿一個方向旋轉 3 秒鐘,然后將第一電機反向旋轉 3 秒鐘,將第二電機旋轉 6 秒鐘。
```java
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.RaspiPin;
/**
* Controls motor direction of a two DC motors
* @author https://javatutorial.net
*/
public class ControlTwoMotorsDirection {
public static void main(String[] args) throws InterruptedException {
// get a handle to the GPIO controller
final GpioController gpio = GpioFactory.getInstance();
final GpioPinDigitalOutput motor1pinA = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_04, "m1A");
final GpioPinDigitalOutput motor1pinB = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_05, "m1B");
final GpioPinDigitalOutput motor1pinE = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_06, "m1E");
final GpioPinDigitalOutput motor2pinA = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_00, "m2A");
final GpioPinDigitalOutput motor2pinB = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_02, "m2B");
final GpioPinDigitalOutput motor2pinE = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_03, "m2E");
System.out.println("rotate both motors clockwise for 3 seconds");
motor1pinA.high();
motor1pinB.low();
motor1pinE.high();
motor2pinA.high();
motor2pinB.low();
motor2pinE.high();
// wait 3 seconds
Thread.sleep(3000);
System.out.println("rotate motor 1 in oposite derection for 3 seconds "
+ "and motor 2 in oposite direction for 6 seconds");
motor1pinA.low();
motor1pinB.high();
motor2pinA.low();
motor2pinB.high();
// wait 3 seconds
Thread.sleep(3000);
System.out.println("Stopping motor 1");
motor1pinE.low();
// wait 3 seconds
Thread.sleep(3000);
System.out.println("Stopping motor 2");
motor2pinE.low();
gpio.shutdown();
}
}
```
我們在此處使用相同的規則:如果 pinE(啟用)為高,則表明電機已打開。 將 pinE 置于低電平將關閉電機。 我們通過將引腳 A 或 B 之一切換到高電平并將另一個引腳切換到低電平來確定旋轉方向。
使用以下命令在 Raspberry 上執行程序
```java
sudo java -classpath .:classes:/opt/pi4j/lib/'*' ControlTwoMotorsDirection
```
以下視頻演示了結果
<https://www.youtube.com/embed/b7Fx7Q_qfUs>
## Java 程序:控制兩個直流電機的速度和方向
最后,我將向您展示如何控制兩個直流電機的**速度和方向**。 我們將為兩個電機設置使用相同的電路。 另外,我們將以編程方式依靠 Soft PWM 來控制電機的速度。 您可以在我的教程中閱讀有關 PWM 的更多信息。[具有 PWM 和 Java 的 Raspberry Pi 調光 LED](https://javatutorial.net/raspberry-pi-dim-led-pwm-java)
看下面的 java 代碼。 注意,電機 1 和 2 的引腳 A 和 B 設置為 Soft PWM 引腳。 對于使能引腳(`motor1pinE`和`motor2pinE`),我們使用與先前代碼完全相同的定義。
一旦執行,程序將:
1. 以 15% 的速度順時針旋轉電機 1 2 秒鐘
2. 以 60% 的速度順時針旋轉電機 1 2 秒鐘
3. 以全速將電機 1 順時針旋轉 2 秒
4. 以 50% 的速度沿相反方向旋轉電機 1 3 秒鐘
5. 停止馬達 1
6. 以 30% 的速度順時針旋轉電機 2 2 秒
7. 以相反的方向將電機 2 全速旋轉 3 秒鐘
8. 停止馬達 2
```java
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.wiringpi.SoftPwm;
/**
* Controls motor speed and direction of two DC motors
* @author https://javatutorial.net
*/
public class ControlMotorsDirectionAndSpeed {
private static int MOTOR_1_PIN_A = 4;
private static int MOTOR_1_PIN_B = 5;
private static int MOTOR_2_PIN_A = 0;
private static int MOTOR_2_PIN_B = 2;
public static void main(String[] args) throws InterruptedException {
// get a handle to the GPIO controller
final GpioController gpio = GpioFactory.getInstance();
// init soft PWM pins
// softPwmCreate(int pin, int value, int range)
// the range is set like (min=0 ; max=100)
SoftPwm.softPwmCreate(MOTOR_1_PIN_A, 0, 100);
SoftPwm.softPwmCreate(MOTOR_1_PIN_B, 0, 100);
SoftPwm.softPwmCreate(MOTOR_2_PIN_A, 0, 100);
SoftPwm.softPwmCreate(MOTOR_2_PIN_B, 0, 100);
// init GPIO pins
final GpioPinDigitalOutput motor1pinE = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_06, "m1E");
final GpioPinDigitalOutput motor2pinE = gpio.provisionDigitalOutputPin(RaspiPin.GPIO_03, "m2E");
System.out.println("rotate motor 1 clockwise at 15% speed for 2 seconds");
motor1pinE.high();
SoftPwm.softPwmWrite(MOTOR_1_PIN_A, 15);
// wait 2 seconds
Thread.sleep(2000);
System.out.println("rotate motor 1 clockwise at 60% speed for 2 seconds");
SoftPwm.softPwmWrite(MOTOR_1_PIN_A, 60);
// wait 2 seconds
Thread.sleep(2000);
System.out.println("rotate motor 1 clockwise at full speed for 2 seconds");
SoftPwm.softPwmWrite(MOTOR_1_PIN_A, 100);
// wait 2 seconds
Thread.sleep(2000);
System.out.println("rotate motor 1 in opposite direction at 50% speed for 3 seconds");
SoftPwm.softPwmWrite(MOTOR_1_PIN_A, 0);
SoftPwm.softPwmWrite(MOTOR_1_PIN_B, 50);
// wait 3 seconds
Thread.sleep(3000);
// disable motor 1
SoftPwm.softPwmWrite(MOTOR_1_PIN_B, 0);
motor1pinE.low();
System.out.println("rotate motor 2 clockwise at 30% speed for 2 seconds");
motor2pinE.high();
SoftPwm.softPwmWrite(MOTOR_2_PIN_A, 30);
// wait 2 seconds
Thread.sleep(2000);
System.out.println("rotate motor 2 in opposite direction at 100% speed for 3 seconds");
SoftPwm.softPwmWrite(MOTOR_2_PIN_A, 0);
SoftPwm.softPwmWrite(MOTOR_2_PIN_B, 100);
// wait 3 seconds
Thread.sleep(3000);
// disable motor 2
SoftPwm.softPwmWrite(MOTOR_2_PIN_B, 0);
motor2pinE.low();
gpio.shutdown();
}
}
```
使用以下命令在 Raspberry 上執行程序
```java
sudo java -classpath .:classes:/opt/pi4j/lib/'*' ControlMotorsDirectionAndSpeed
```
運行程序時,您應該看到此控制臺輸出

程序控制臺輸出
以下視頻演示了結果
<https://www.youtube.com/embed/Jfuu-h_NYY0>
## 結論
你還在讀這個嗎? 謝謝! 這是一個很長的教程??現在,在您知道如何使用 Raspberry Pi 控制電機之后,也許您可??以考慮構建一些很酷的項目甚至是一個小型機器人并與我們分享結果??
與往常一樣,我喜歡閱讀您的評論并回答您的問題。 如果您喜歡本教程或其他教程,請傳播!
您可以在 GitHub 中找到所有項目文件: [https://github.com/JavaTutorialNetwork/Tutorials/tree/master/RaspberryPiControlMotors](https://github.com/JavaTutorialNetwork/Tutorials/tree/master/RaspberryPiControlMotors)
資料來源:
[使用 Pi 和 Python 控制直流電機](https://business.tutsplus.com/tutorials/controlling-dc-motors-using-python-with-a-raspberry-pi--cms-20051)
- JavaTutorialNetwork 中文系列教程
- Java 基礎
- Java 概述
- 在 Ubuntu 上安裝 Java 8 JDK
- Java Eclipse 教程
- Eclipse 快捷方式
- 簡單的 Java 示例
- Java 基本類型
- Java 循環
- Java 數組
- Java 讀取文件示例
- Java 對象和類教程
- 什么是面向對象編程(OOP)
- Java 封裝示例
- Java 接口示例
- Java 繼承示例
- Java 抽象示例
- Java 多態示例
- Java 中的方法重載與方法覆蓋
- Java 控制流語句
- Java 核心
- 如何在 Windows,Linux 和 Mac 上安裝 Maven
- 如何使用 Maven 配置文件
- 如何將自定義庫包含到 Maven 本地存儲庫中
- 如何使用 JUnit 進行單元測試
- 如何使用 Maven 運行 JUnit 測試
- 如何在 Java 中使用 Maven 創建子模塊
- 如何使用 Maven 創建 Java JAR 文件
- 如何使用 Maven 創建 Java WAR 文件
- JVM 解釋
- Java 內存模型解釋示例
- 捕獲 Java 堆轉儲的前 3 種方法
- Java 垃圾收集
- Java 互斥量示例
- Java 信號量示例
- Java 并行流示例
- Java 線程同步
- Java 線程池示例
- Java ThreadLocal示例
- Java 中的活鎖和死鎖
- Java Future示例
- Java equals()方法示例
- Java Lambda 表達式教程
- Java Optional示例
- Java 11 HTTP 客戶端示例
- Java 類加載器介紹
- Java 枚舉示例
- Java hashCode()方法示例
- 如何測試獨立的 Java 應用程序
- SWING JFrame基礎知識,如何創建JFrame
- Java SWING JFrame布局示例
- 在JFrame上顯示文本和圖形
- 與JFrame交互 – 按鈕,監聽器和文本區域
- 如何使用 Maven 創建 Java JAR 文件
- Java Collection新手指南
- 選擇合適的 Java 集合
- Java ArrayList示例
- Java LinkedList示例
- Java HashSet示例
- Java TreeSet示例
- Java LinkedHashSet示例
- Java EnumSet示例
- Java ConcurrentHashSet示例
- Java HashMap示例
- Java LinkedHashMap示例
- Java TreeMap示例
- Java EnumMap示例
- Java WeakHashMap示例
- Java IdentityHashMap示例
- Java SortedMap示例
- Java ConcurrentMap示例
- Java Hashtable示例
- Java 中ArrayList和LinkedList之間的區別
- Java HashMap迭代示例
- Java HashMap內聯初始化
- Java 中HashMap和TreeMap之間的區別
- Java 圖示例
- Java 深度優先搜索示例
- Java 廣度優先搜索示例
- 不同的算法時間復雜度
- Java 序列化示例
- Java 反射示例
- Java 中的弱引用
- Java 8 日期時間 API
- Java 基本正則表達式
- 使用 Java 檢索可用磁盤空間
- Java 生成 MD5 哈希和
- Java 增加內存
- Java 屬性文件示例
- 如何在 Eclipse 上安裝 Java 9 Beta
- Java 9 JShell 示例
- Java 9 不可變列表示例
- Java 9 不可變集示例
- Java 9 不可變映射示例
- Java 單例設計模式示例
- Java 代理設計模式示例
- Java 觀察者設計模式示例
- Java 工廠設計模式
- Java 構建器設計模式
- Java 比較器示例
- Java 發送電子郵件示例
- Java volatile示例
- Java Docker 和 Docker 容器簡介
- 安裝和配置 MySQL 數據庫和服務器以供 Spring 使用
- 如何在 Java 中使用 MySQL 連接器
- 如何使用 Eclipse 調試 Java
- Java EE
- 如何在 Windows 10 中設置JAVA_HOME
- JavaBeans 及其組件簡介
- 如何安裝和配置 Tomcat 8
- 如何在 Tomcat 中部署和取消部署應用程序
- 從 Eclipse 運行 Tomcat
- Java Servlet 示例
- Java Servlet POST 示例
- Servlet 請求信息示例
- Servlet 注解示例
- 使用初始化參數配置 Java Web 應用程序
- Java Servlet 文件上傳
- Java JSP 示例
- Glassfish 啟用安全管理
- 如何使用 MySQL 配置 Glassfish 4
- Java 文件上傳 REST 服務
- Glassfish 和 Jetty 的 Java WebSockets 教程
- 基于 Glassfish 表單的身份驗證示例
- 如何使用 Java EE 和 Angular 構建單頁應用程序
- Spring
- 在 Eclipse 中安裝 Spring STS
- 使用 STS 創建簡單的 Spring Web App
- Spring Web Framework 簡介
- Java Docker 和 Docker 容器簡介
- 在 Spring 中實現控制器
- Spring 中的PathVariable注解
- Spring 中的RequestBody注解
- Spring 中的RequestParam注解
- Spring 攔截器
- Spring IOC
- Java Spring IoC 容器示例
- Spring 中的DispatcherServlet
- Spring 示例中的依賴注入
- 實現 Spring MVC 控制器
- Spring ORM 簡介
- 什么是 DAO 以及如何使用它
- 如何對 DAO 組件進行單元測試
- 如何對控制器和服務執行單元測試
- 安裝和配置 MySQL 數據庫和服務器以供 Spring 使用
- 如何在 Spring 中處理登錄身份驗證
- Spring Security 簡介及其設置
- 如何使用 Spring 創建 RESTful Web 服務
- Spring CSRF 保護
- Spring 中基于 OAuth2 的身份驗證和授權
- Spring Boot 簡介
- Spring MVC 框架介紹
- Spring JDBC 簡介
- 如何 docker 化 Spring 應用程序
- Spring 的@Autowired注解
- Spring AOP 中的核心概念和建議類型
- Sping Bean 簡介
- 如何在 Java 中使用 MySQL 連接器
- 安卓
- 安裝和配置 Android Studio
- 將 Android 設備連接到 Android Studio
- Android 簡介,活動,意圖,服務,布局
- 創建一個簡單的 Android 應用
- 運行和調試 Android 應用程序
- 在虛擬設備上運行 Android 應用程序
- Android 活動示例
- Android 意圖示例
- Android 服務示例
- Android 線性布局示例
- Android 相對布局示例
- Android Web 視圖示例
- Android 列表視圖示例
- Android 網格視圖示例
- 帶有ListAdapter的 Android ListView示例
- Android SQLite 數據庫介紹
- Android SQLite 數據庫示例
- Android 動畫教程
- Android 中的通知
- Android 中的事件處理
- 如何在 Android 中發送帶有附件的電子郵件
- 雜項
- 選擇您的 JAVA IDE:Eclipse,NetBeans 和 IntelliJ IDEA
- Java S3 示例
- 如何在 Ubuntu 上為多個站點配置 Apache
- 如何在 Liferay DXP 中替代現成的(OOTB)模塊
- 簡單的 Git 教程
- 使用 Java 捕獲網絡數據包
- Selenium Java 教程
- 使用特定工作區運行 Eclipse
- 在 Eclipse 中安裝 SVN
- 如何運行 NodeJS 服務器
- SQL 內連接示例
- SQL 左連接示例
- SQL 右連接示例
- SQL 外連接示例
- 樹莓派
- Raspberry Pi 3 規格
- 將 Raspbian 安裝到 SD 卡
- Raspberry Pi 首次啟動
- 遠程連接到 Raspberry Pi
- 建立 Raspberry Pi 遠程桌面連接
- Raspberry Pi Java 教程
- 使用 PWM 的 Raspberry Pi LED 亮度調節
- Raspberry Pi 控制電機速度
- Raspberry Pi 用 Java 控制直流電機的速度和方向