1. Arduino PLC 核心操作(命令行/腳本化)
Arduino PLC(如Arduino Industrial 101)可通過arduino-cli實現命令行編譯/上傳,替代圖形化IDE:
# 安裝arduino-cli(Linux/macOS)
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh
# 初始化配置
arduino-cli config init
# 安裝PLC核心(以Industrial 101為例)
arduino-cli core install arduino:avr
# 編譯PLC程序(替換為你的 sketch 路徑)
arduino-cli compile --fqbn arduino:avr:industrial101 /path/to/your/sketch
# 上傳到PLC(替換串口名,如/dev/ttyUSB0)
arduino-cli upload -p /dev/ttyUSB0 --fqbn arduino:avr:industrial101 /path/to/your/sketch
2. Termux 操作 ESP32 關鍵步驟
Termux(安卓終端)中可搭建ESP32開發環境,核心命令:
# 安裝依賴
pkg install git python3 py3-pip gcc make libffi openssl
# 安裝esptool(燒錄工具)
pip3 install esptool
# 克隆ESP-IDF(適配ESP32的版本)
git clone --depth 1 --branch v4.4 https://github.com/espressif/esp-idf.git
# 安裝ESP-IDF依賴
cd esp-idf
./install.sh esp32
# 配置環境變量
. ./export.sh
# 燒錄固件到ESP32(替換串口名/固件路徑,Termux串口通常為/dev/ttyUSB0或/dev/ttyACM0)
esptool.py --port /dev/ttyUSB0 write_flash 0x1000 /path/to/your/esp32_firmware.bin
3. 兩者聯動(PLC ? ESP32)
若需Arduino PLC與ESP32通信,可通過串口/Modbus實現,核心代碼片段(Arduino PLC端):
#include < ModbusRTU.h >
ModbusRTU mb;
void setup() {
Serial.begin(9600); // 與ESP32串口波特率一致
mb.begin(&Serial);
mb.slave(1); // 從機地址
}
void loop() {
mb.poll();
// 讀取ESP32發送的寄存器數據(示例:讀取寄存器0的值)
uint16_t val = mb.Hreg(0);
// 控制PLC輸出(示例:根據值控制數字輸出)
digitalWrite(13, val > 0 ? HIGH : LOW);
}
Arduino PLC 與 ESP32(Termux 環境)Modbus 完整通信腳本
一、核心前提(必做)
- 硬件連接:PLC 與 ESP32 用 TTL 串口交叉連接 (PLC TX → ESP32 RX,PLC RX → ESP32 TX,共地 GND);
- 環境準備:
- PLC 端:安裝
ModbusRTU庫(Arduino IDE 或arduino-cli均可); - Termux 端:已完成 ESP-IDF 搭建(參考上一輪命令),安裝
modbus_slave相關依賴(腳本內包含)。
- PLC 端:安裝
二、1. Arduino PLC 端(Modbus 主機,讀取/控制 ESP32)
#include < ModbusRTU.h >
// 定義Modbus對象
ModbusRTU mb;
// 定義PLC引腳(根據實際型號調整,以Industrial 101為例)
const int PLC_OUTPUT_PIN = 13; // PLC數字輸出引腳
const int PLC_INPUT_PIN = 2; // PLC數字輸入引腳
void setup() {
// 1. 初始化串口(與ESP32波特率、校驗位一致)
Serial.begin(9600, SERIAL_8N1);
while (!Serial) {} // 等待串口就緒
// 2. 初始化Modbus主機
mb.begin(&Serial);
mb.master(); // 配置為Modbus主機
mb.setTimeOut(1000); // 通信超時時間(1秒)
// 3. 初始化PLC引腳
pinMode(PLC_OUTPUT_PIN, OUTPUT);
pinMode(PLC_INPUT_PIN, INPUT);
}
void loop() {
uint16_t esp_data[2]; // 存儲從ESP32讀取的數據(寄存器0:傳感器值,寄存器1:ESP32狀態)
uint8_t result; // Modbus通信結果
// 1. 讀取ESP32的2個保持寄存器(地址0和1,從機地址1)
result = mb.readHreg(1, 0, 2, esp_data);
if (result == mb.ku8MBSuccess) {
// 讀取成功:打印ESP32數據
Serial.print("ESP32 傳感器值:");
Serial.println(esp_data[0]);
Serial.print("ESP32 狀態:");
Serial.println(esp_data[1] == 1 ? "正常" : "異常");
// 2. 根據ESP32數據控制PLC輸出
if (esp_data[0] > 500) { // 示例:傳感器值大于500時,PLC輸出高電平
digitalWrite(PLC_OUTPUT_PIN, HIGH);
} else {
digitalWrite(PLC_OUTPUT_PIN, LOW);
}
} else {
// 讀取失敗:打印錯誤代碼
Serial.print("Modbus讀取失敗,錯誤代碼:");
Serial.println(result);
}
// 3. 讀取PLC輸入狀態,發送給ESP32(寫入ESP32的線圈0)
bool plc_input_state = digitalRead(PLC_INPUT_PIN);
result = mb.writeCoil(1, 0, plc_input_state); // 寫入ESP32線圈0(從機地址1)
if (result != mb.ku8MBSuccess) {
Serial.print("Modbus寫入失敗,錯誤代碼:");
Serial.println(result);
}
delay(1000); // 通信間隔(1秒,可調整)
}
三、2. Termux + ESP32 端(Modbus 從機,上傳數據/接收控制)
步驟1:創建 ESP32 項目(Termux 命令行操作)
# 1. 進入ESP-IDF目錄,加載環境變量
cd ~/esp-idf
. ./export.sh
# 2. 創建新的ESP32項目(項目名:esp32_modbus_slave)
idf.py create-project esp32_modbus_slave
cd esp32_modbus_slave
# 3. 配置項目(選擇ESP32開發板,如ESP32-WROOM-32)
idf.py set-target esp32
idf.py menuconfig
# (可選)在menuconfig中設置串口波特率(默認9600,需與PLC一致)
# 路徑:Component config → Modbus → UART Baud Rate → 9600
步驟2:替換項目代碼(main.c)
#include < stdio.h >
#include < string.h >
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "modbus_slave.h"
// 1. 串口配置(與PLC一致)
#define UART_NUM UART_NUM_0 // ESP32串口0(可替換為UART_NUM_1)
#define BAUD_RATE 9600 // 波特率
#define TX_PIN GPIO_NUM_1 // ESP32 TX引腳(連接PLC RX)
#define RX_PIN GPIO_NUM_3 // ESP32 RX引腳(連接PLC TX)
#define BUF_SIZE (1024) // 串口緩沖區大小
// 2. Modbus從機配置
#define MODBUS_SLAVE_ADDR 1 // 從機地址(需與PLC主機一致)
#define REG_HOLDING_START 0 // 保持寄存器起始地址
#define REG_HOLDING_SIZE 2 // 保持寄存器數量(2個:傳感器值、狀態)
#define COIL_START 0 // 線圈起始地址
#define COIL_SIZE 1 // 線圈數量(1個:接收PLC輸入狀態)
// 3. 模擬傳感器數據(可替換為實際傳感器讀取代碼)
uint16_t sensor_value = 0;
// 4. Modbus寄存器和線圈存儲區
uint16_t holding_regs[REG_HOLDING_SIZE] = {0}; // 保持寄存器(供PLC讀取)
bool coils[COIL_SIZE] = {false}; // 線圈(接收PLC寫入)
// 串口初始化函數
void uart_init() {
const uart_config_t uart_config = {
.baud_rate = BAUD_RATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_APB,
};
// 配置串口參數
uart_param_config(UART_NUM, &uart_config);
// 設置串口引腳
uart_set_pin(UART_NUM, TX_PIN, RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
// 安裝串口驅動(中斷模式)
uart_driver_install(UART_NUM, BUF_SIZE * 2, 0, 0, NULL, 0);
}
// Modbus從機初始化函數
void modbus_slave_init() {
// 1. 初始化Modbus從機(串口0,從機地址1)
modbus_slave_init_port(UART_NUM, MODBUS_SLAVE_ADDR);
// 2. 注冊保持寄存器(供PLC讀取)
modbus_slave_register_holding_regs(REG_HOLDING_START, REG_HOLDING_SIZE, holding_regs);
// 3. 注冊線圈(接收PLC寫入)
modbus_slave_register_coils(COIL_START, COIL_SIZE, coils);
// 4. 啟動Modbus從機任務
modbus_slave_start_task();
}
// 模擬傳感器數據更新任務
void sensor_update_task(void *pvParameters) {
while (1) {
// 模擬傳感器值遞增(0~1000,循環)
sensor_value = (sensor_value + 10) % 1000;
// 更新保持寄存器(寄存器0:傳感器值,寄存器1:狀態1=正常)
holding_regs[0] = sensor_value;
holding_regs[1] = 1; // 固定為正常狀態,可替換為實際狀態判斷
vTaskDelay(500 / portTICK_PERIOD_MS); // 500ms更新一次
}
}
// 讀取PLC寫入的線圈狀態任務
void plc_coil_read_task(void *pvParameters) {
while (1) {
// 讀取線圈0的狀態(PLC輸入引腳狀態)
bool plc_input = coils[0];
// 打印PLC輸入狀態
printf("PLC輸入狀態:%sn", plc_input ? "高電平" : "低電平");
// (可選)根據PLC狀態控制ESP32引腳
gpio_set_level(GPIO_NUM_2, plc_input ? 1 : 0); // ESP32引腳2輸出對應電平
vTaskDelay(1000 / portTICK_PERIOD_MS); // 1秒讀取一次
}
}
void app_main(void) {
// 1. 初始化GPIO(ESP32引腳2,用于響應PLC控制)
gpio_reset_pin(GPIO_NUM_2);
gpio_set_direction(GPIO_NUM_2, GPIO_MODE_OUTPUT);
// 2. 初始化串口和Modbus從機
uart_init();
modbus_slave_init();
// 3. 創建傳感器更新和PLC線圈讀取任務
xTaskCreate(sensor_update_task, "sensor_task", 2048, NULL, 5, NULL);
xTaskCreate(plc_coil_read_task, "coil_task", 2048, NULL, 5, NULL);
}
步驟3:編譯并燒錄到 ESP32(Termux 命令)
# 1. 編譯項目
idf.py build
# 2. 燒錄固件(替換串口名,Termux中通常為/dev/ttyUSB0或/dev/ttyACM0)
idf.py -p /dev/ttyUSB0 flash monitor
# 燒錄成功后,按Ctrl+]退出monitor,ESP32將自動運行程序
四、3. 調試與驗證
- 硬件上電:先給 PLC 上電,再給 ESP32 上電(避免串口沖擊);
- PLC 端:打開串口監視器(波特率9600),可看到 ESP32 發送的傳感器值和狀態;
- ESP32(Termux)端:重新運行
idf.py -p /dev/ttyUSB0 monitor,可看到 PLC 輸入引腳的狀態; - 交互測試:
- 調整 ESP32 模擬傳感器值(代碼中
sensor_value),觀察 PLC 輸出引腳是否按條件切換; - 切換 PLC 輸入引腳狀態,觀察 ESP32 引腳2是否同步響應,且 Termux 終端打印對應狀態。
- 調整 ESP32 模擬傳感器值(代碼中
五、常見問題排查
- 通信失敗:檢查串口接線(交叉連接)、波特率/校驗位是否一致、Modbus從機地址是否匹配;
- Termux 燒錄失敗:確認 ESP32 已進入燒錄模式(按住BOOT鍵,再按EN鍵,松開EN鍵后松開BOOT鍵);
- 數據亂碼:檢查串口接線是否松動,或更換 ESP32 串口(如從UART0改為UART1)。
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
Arduino
+關注
關注
190文章
6517瀏覽量
196095
發布評論請先 登錄
相關推薦
熱點推薦
termux wifi 另一臺手機 對話框`405 Not Allowed`錯誤
請求(無需修改服務端)
修改 Termux 的 send_msg.sh 腳本,將 POST 改為 GET 方式傳參:
# 替換原 POST 命令
curl -G -d \"content
發表于 12-18 08:35
Termux中調試圣誕樹Python代碼
在Termux中調試Python代碼(以圣誕樹立例)非常簡單,核心分為環境準備、代碼編寫、運行調試三個步驟,下面一步步教你操作:
一、環境準備(首次使用需做)
Termux默認可能沒有Python
發表于 12-09 09:02
晶科鑫 | 國產26MHz晶振匹配Espressif(樂鑫) ESP8285/ESP8266芯片案例
【應用】國產26MHz頻率晶振應用于物聯網WIFI物聯網模塊(串口轉WiFi模塊),Espressif(樂鑫)ESP8285/ESP8266芯片匹配測試OKESP8285其實是ESP8266的升級版
ESP8266和ESP32開發板常見的2種下載方式
ESP8266全IO口引出,直接下載無需復位!
ESP32功能框圖
基于arduino的ESP32/ESP8266開發環境搭建
1.在
發表于 10-24 18:04
使用 LinkBoy 將程序導出為 C 語言代碼并燒錄至 Arduino ESP32 開發板
以下是使用 LinkBoy 將程序導出為 C 語言代碼并燒錄至 Arduino ESP32 開發板的詳細步驟指南:
一、準備工作
? 硬件需求:
項目
要求
開發板
Arduino ESP
發表于 10-16 12:41
如何在 NuMaker-IoT-M467 板上使用 Arduino IDE 控制 Wi-Fi 模塊?
在NuMaker開發板上,有一個ESP-12F Wi-Fi模塊;但是,Arduino IDE 中的 NuMaker UNO 包不提供該模塊的相關控制。如果您希望在 Arduino IDE 中控制此模塊,您應該如何進行?
發表于 09-04 08:28
termux調試python猜數字游戲
用termux做一個猜數字游戲
下面是在Termux中創建猜數字游戲的步驟及完整實現方案,結合Python實現(最適配Termux環境):
? 一、環境準備(Termux基礎
發表于 08-29 17:15
termux輸出Hello termux
~ $ nano hello.py
~ $ python hello.py
File \"/data/data/com.termux/files/home/hello.py\"
發表于 08-29 12:16
termux如何搭建python游戲
termux如何搭建python游戲
Termux搭建Python游戲開發環境的完整指南
一、Termux基礎環境準備
Termux是一款無需root即可在安卓設備上運行的L
發表于 08-29 07:06
《ESP32S3 Arduino開發指南》第二章 Arduino基礎知識
周邊資料,其中包括社區、驅動庫以及示例代碼等,如下圖2.1.1所示: 圖2.1.1 Arduino生態圖 現今,Arduino開發板有很多,正點原子ESP32-S3開發板也是屬于Arduino
發表于 05-13 09:28
如何使用PLC控制myCobot 320機械臂
根據持續的用戶反饋,目前市場對 PLC 與 myCobot 系統集成的需求很大,因此本文提供的案例介紹了如何使用 PLC(可編程邏輯控制器)來控制 myCobot 320 機械臂。本案例重點介紹

Arduino plc和termux esp
評論