0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Arduino plc和termux esp

丙丁先生的自学旅程 2025-12-06 06:41 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

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 完整通信脚本

一、核心前提(必做)

  1. 硬件连接:PLC 与 ESP32 用 TTL 串口交叉连接 (PLC TX → ESP32 RX,PLC RX → ESP32 TX,共地 GND);
  2. 环境准备:
    • PLC 端:安装 ModbusRTU 库(Arduino IDE 或 arduino-cli 均可);
    • Termux 端:已完成 ESP-IDF 搭建(参考上一轮命令),安装 modbus_slave 相关依赖(脚本内包含)。

二、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. 调试与验证

  1. 硬件上电:先给 PLC 上电,再给 ESP32 上电(避免串口冲击);
  2. PLC 端:打开串口监视器(波特率9600),可看到 ESP32 发送的传感器值和状态;
  3. ESP32(Termux)端:重新运行 idf.py -p /dev/ttyUSB0 monitor,可看到 PLC 输入引脚的状态;
  4. 交互测试:
    • 调整 ESP32 模拟传感器值(代码中 sensor_value),观察 PLC 输出引脚是否按条件切换;
    • 切换 PLC 输入引脚状态,观察 ESP32 引脚2是否同步响应,且 Termux 终端打印对应状态。

五、常见问题排查

  • 通信失败:检查串口接线(交叉连接)、波特率/校验位是否一致、Modbus从机地址是否匹配;
  • Termux 烧录失败:确认 ESP32 已进入烧录模式(按住BOOT键,再按EN键,松开EN键后松开BOOT键);
  • 数据乱码:检查串口接线是否松动,或更换 ESP32 串口(如从UART0改为UART1)。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Arduino
    +关注

    关注

    191

    文章

    6535

    浏览量

    197743
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    ESP32/ESP8266开发板单向多对一ESP-NOW无线通信

    本实验通过ESP-NOW无线通信协议实现多个ESP32/ESP 8266开发板向ESP32开发板发送数据。例如可以应用于从多个远程传感器上收集数据。
    的头像 发表于 03-30 10:14 311次阅读
    <b class='flag-5'>ESP</b>32/<b class='flag-5'>ESP</b>8266开发板单向多对一<b class='flag-5'>ESP</b>-NOW无线通信

    ESP32/ESP8266开发板单向一对多ESP-NOW无线通信

    通过ESP-NOW无线通信协议实现ESP32开发板向多个ESP32/ESP 8266开发板发送数据。
    的头像 发表于 03-13 09:23 396次阅读
    <b class='flag-5'>ESP</b>32/<b class='flag-5'>ESP</b>8266开发板单向一对多<b class='flag-5'>ESP</b>-NOW无线通信

    ESP_I2S库本身编译失败

    版本存在文件缺失问题,升级到稳定版本可直接解决: 卸载现有ESP32开发板包: 打开Arduino IDE → 点击「工具」→「开发板」→「开发板管理器」; 在搜索框输入esp32,找到「e
    发表于 01-22 07:11

    MCU 开发板大比拼:STM32、ESP32、Arduino、树莓派谁更强?

    嵌入式开发板琳琅满目,STM32、ESP32、Arduino、RaspberryPi各有特色。新手容易纠结:到底哪块板适合我的项目?本文整理了一份开发板对比速查表,帮你快速理清思路。一、STM32
    的头像 发表于 01-09 19:03 1661次阅读
    MCU 开发板大比拼:STM32、<b class='flag-5'>ESP</b>32、<b class='flag-5'>Arduino</b>、树莓派谁更强?

    Termux环境下实现康威生命游戏

    你想要在Termux环境下实现康威生命游戏,并专门展示经典的“滑翔机”模式,构建一个能持续运行的二维世界,同时需要完整的程序代码和调试说明。 一、实现思路康威生命游戏的核心是遵循4条规则:1. 活
    发表于 12-21 18:36

    termux wifi 另一台手机 对话框`405 Not Allowed`错误

    请求(无需修改服务端) 修改 Termux 的 send_msg.sh 脚本,将 POST 改为 GET 方式传参: # 替换原 POST 命令 curl -G -d \"content
    发表于 12-18 08:35

    Termux手机摄像头采集图像/视频流 部署 YOLO 模型推理

    Termux手机摄像头采集图像/视频流 部署 YOLO 模型推理
    的头像 发表于 12-14 07:26 3458次阅读

    Termux中调试圣诞树Python代码

    Termux中调试Python代码(以圣诞树立例)非常简单,核心分为环境准备、代码编写、运行调试三个步骤,下面一步步教你操作: 一、环境准备(首次使用需做) Termux默认可能没有Python
    发表于 12-09 09:02

    ESP8266和ESP32开发板常见的2种下载方式

    ESP8266全IO口引出,直接下载无需复位! ESP32功能框图 基于arduinoESP32/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

    乐鑫代理商飞睿科技ESP32 开发平台对比:ESP-IDF VS Arduino

    Arduino
    深圳市飞睿科技有限公司
    发布于 :2025年07月08日 14:36:27