一、硬件:
二、软件:
先用Arduino IDE

三、操作:
1、接线
| 连接对象 | Arduino 端引脚 | 另一端设备及引脚 | 说明 |
|---|---|---|---|
| RS485 模块 | 8 号引脚 | RS485 模块的 RE 引脚 | 控制 RS485 接收使能 |
| RS485 模块 | 7 号引脚 | RS485 模块的 DE 引脚 | 控制 RS485 发送使能 |
| RS485 模块 | 2 号引脚 | RS485 模块的 TX(R0)引脚 | 软件串口接收端(Arduino 接收 RS485 数据) |
| RS485 模块 | 3 号引脚 | RS485 模块的 RX(DI) 引脚 | 软件串口发送端(Arduino 向 RS485 发送数据) |
| RS485 模块与传感器 | - | RS485 模块 A 引脚 → 传感器 A (黄色)引脚 | RS485 总线 A 线连接 |
| RS485 模块与传感器 | - | RS485 模块 B 引脚 → 传感器 B (蓝色)引脚 | RS485 总线 B 线连接 |
| 电源 | 5V 引脚 | RS485 模块 VCC、传感器 VCC(棕色) | 提供工作电源(需与设备电压匹配) |
| 地 | GND 引脚 | RS485 模块 GND、传感器 GND(黑色) | 共地,保证通信电平参考一致 |


2、程序
#include <SoftwareSerial.h>
#include <Wire.h>
// RE 和 DE 控制 RS485 方向
#define RE 8
#define DE 7
// Modbus RTU 指令(不同传感器可能不同,这里是常见 NPK 土壤传感器协议)
const byte nitro[] = {0x01,0x03,0x00,0x1E,0x00,0x01,0xE4,0x0C};
const byte phos[] = {0x01,0x03,0x00,0x1F,0x00,0x01,0xB5,0xCC};
const byte pota[] = {0x01,0x03,0x00,0x20,0x00,0x01,0x85,0xC0};
// 存放 Modbus 返回值
byte values[11];
// 软件串口(用 2,3 管脚)
SoftwareSerial mod(2, 3);
void setup() {
Serial.begin(4800);
mod.begin(4800);
pinMode(RE, OUTPUT);
pinMode(DE, OUTPUT);
digitalWrite(RE, LOW);
digitalWrite(DE, LOW);
delay(500);
}
void loop() {
int N = nitrogen();
delay(250);
int P = phosphorous();
delay(250);
int K = potassium();
delay(250);
Serial.print("Nitrogen: ");
Serial.print(N);
Serial.println(" mg/kg");
Serial.print("Phosphorous: ");
Serial.print(P);
Serial.println(" mg/kg");
Serial.print("Potassium: ");
Serial.print(K);
Serial.println(" mg/kg");
Serial.println("-------------------------");
delay(2000);
}
// ====== 函数定义 ======
int nitrogen() {
return readSensor(nitro);
}
int phosphorous() {
return readSensor(phos);
}
int potassium() {
return readSensor(pota);
}
// 读取传感器通用函数
int readSensor(const byte *cmd) {
digitalWrite(DE, HIGH);
digitalWrite(RE, HIGH);
delay(10);
mod.write(cmd, 8); // 发送 8 字节命令
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
delay(100); // 等待传感器返回
byte i = 0;
unsigned long startTime = millis();
while ((millis() - startTime) < 1000) { // 最多等 1 秒
if (mod.available()) {
values[i] = mod.read();
i++;
if (i >= 7) break; // 正常响应帧 7 个字节
}
}
// 调试打印
Serial.print("Response: ");
for (byte j = 0; j < i; j++) {
Serial.print(values[j], HEX);
Serial.print(" ");
}
Serial.println();
// 确保有足够的数据
if (i < 5) return -1;
// 合并高低字节
int result = values[3] << 8 | values[4];
return result;
}
3、串口显示

四、备注
1、在不同环境下的典型情况
-
空气中 → 一般返回
0(或有些固定假值)。 -
清水中(自来水/纯净水) → 接近
0,有时会有微量杂质导致几个毫克数值。 -
肥料溶液 / 水培液 → 会显示明显数值(几十 ~ 几百 mg/L)。
-
土壤中 → 算法校准过,显示较接近真实的土壤养分浓度。
2、串口参数需要留意
NPK 传感器可能默认 4800 / 19200。
要查一下传感器说明书里的 默认波特率,改成正确的。


1786

被折叠的 条评论
为什么被折叠?



