Arduino + RS485測溫裝置
因為專案需要,在網上購買了一款T10S-B-HW RS485紅外線測溫變送器,
引數如下:
| 額定電壓 | DC5V~DC12V |
|---|---|
| 探頭作業溫度 | -40~125℃ |
| 測量范圍 | -70℃~380℃ |
| 測量精度 | ±0.5℃(作業溫度0~60℃ 目標溫度0~60℃) |
| 物距比 | D:S = 12:1 (目標直徑:測量距離) |
| 測量解析度 | 0.1℃ |
| 回應時間 | 1s |
| 輸出介面 | RS485 |
| 通訊協議 | MODBUS RTU |
| 波特率 | 1200 bit/s,2400 bit/s, 4800 bit/s, 9600 bit/s(默認), 19200 bit/s |
| 通訊地址 | 1-247 |
| 功 耗 | <0.1W |
| 產品尺寸 | 直徑14mm,長69mm |
測量資料通過RS485串口輸出,使用MODUBS RTU 協議標準,
比如讀取溫度,發送:01 03 00 00 00 01 84 0A
回傳:01 03 04 01 13 00 01 CB CA
即 256 * 1 + 16 * 1 + 3 = 275 (對應溫度:27.5℃)
之后想通過Arduino處理資料,涉及到十六進制資料的發送與接收,以及Arduino的資料決議,花費了一些時間,在這里記錄一下,
接線方面我是用一個9V電池為測溫裝置供電,之后RS485資料介面接一個RS485轉TTL模塊,通過設定軟串口與Arduino通信,
撰寫如下程式:
#include <SoftwareSerial.h>
unsigned char item[8] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B}; //16進制測溫命令
String data = ""; // 接收到的16進制字串
SoftwareSerial tempSerial(8, 7); // RX, TX
float getTemp(String temperature); // 函式宣告
void setup()
{
tempSerial.begin(9600);
Serial.begin(9600);
}
void loop()
{
delay(500); // 放慢輸出頻率
for (int i = 0 ; i < 8; i++) { // 發送測溫命令
tempSerial.write(item[i]); // write輸出
}
delay(100); // 等待測溫資料回傳
data = "";
while (tempSerial.available()) {//從串口中讀取資料
unsigned char in = (unsigned char)tempSerial.read(); // read讀取
Serial.print(in, HEX);
Serial.print(',');
data += in;
data += ',';
}
if (data.length() > 0) { //先輸出一下接收到的資料
Serial.println();
Serial.println(data);
Serial.print(getTemp(data));
Serial.println("Temp");
}
}
float getTemp(String temp) {
int commaPosition = -1;
String info[9]; // 用字串陣列存盤
for (int i = 0; i < 9; i++) {
commaPosition = temp.indexOf(',');
if (commaPosition != -1)
{
info[i] = temp.substring(0, commaPosition);
temp = temp.substring(commaPosition + 1, temp.length());
}
else {
if (temp.length() > 0) { // 最后一個會執行這個
info[i] = temp.substring(0, commaPosition);
}
}
}
return (info[3].toInt() * 256 + info[4].toInt()) / 10.0;
}
串口監視器輸出決議后的溫度資料:
第一行是十六進制的輸出,第二行是十進制輸出,第三行才是決議后的溫度值,
將GPS模塊和測溫模塊集成
#include <SoftwareSerial.h>
// 配置軟串口
SoftwareSerial gpsSerial(4, 3); // RX, TX
SoftwareSerial bleSerial(6, 5); // RX, TX
SoftwareSerial tempSerial(8, 7); // RX, TX
// 變數宣告
String command = ""; // 用戶發送的命令
unsigned char tempCommand[8] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B}; //16進制測溫命令
String tempData = ""; // 接收到的16進制字串
String gngga = ""; // 讀取到的GNGGA資訊
String info[15]; // 存盤GPS資料
// 函式宣告
float getTemp(String temperature); // 獲取溫度值函式宣告
String getTime(); // 獲取北京時間
String getLat(); // 獲取緯度dd.mmssss
String getLng(); // 獲取經度dd.mmssss
String getStatus(); // 獲取當前定位狀態,0=未定位,1 = 非差分定位,2=差分定位
void setup() {
Serial.begin(9600);
gpsSerial.begin(38400);
bleSerial.begin(9600);
tempSerial.begin(9600);
}
void loop() {
bleSerial.listen();
command = "";
while (bleSerial.available() > 0) {
command += char(bleSerial.read());
delay(10);
}
if (command.length() > 0) {
Serial.println("command:" + command);
//在這里進行命令的決議
if (command.equals("0")) { // 獲取gps資料
Serial.println("獲取GPS資料");
gpsSerial.listen(); // 監聽GPS串口
gngga = "";
delay(200); // 延遲等待GPS資料進入串口
while (gpsSerial.available() > 0) {
gngga += char(gpsSerial.read());
delay(1);
}
if (gngga.length() > 0) {
Serial.println(gngga);
int commaPosition = -1;
for (int i = 0; i < 15; i++) {
commaPosition = gngga.indexOf(',');
if (commaPosition != -1)
{
info[i] = gngga.substring(0, commaPosition);
gngga = gngga.substring(commaPosition + 1, gngga.length());
}
else {
if (gngga.length() > 0) { // 最后一個會執行這個
info[i] = gngga.substring(0, commaPosition);
}
}
}
Serial.println("time: " + getTime());
Serial.println("lat: " + getLat());
Serial.println("lng: " + getLng());
Serial.println("status: " + getStatus());
bleSerial.println(getTime() + ',' + getLat() + ',' + getLng());
}
} else if (command.equals("1")) { // 獲取溫度資料
Serial.println("獲取溫度資料");
tempSerial.listen(); // 監聽溫度串口
for (int i = 0 ; i < 8; i++) { // 發送測溫命令
tempSerial.write(tempCommand[i]); // write輸出
}
delay(100); // 等待測溫資料回傳
tempData = "";
while (tempSerial.available()) {//從串口中讀取資料
unsigned char in = (unsigned char)tempSerial.read(); // read讀取
Serial.print(in, HEX);
Serial.print(',');
tempData += in;
tempData += ',';
}
if (tempData.length() > 0) { //先輸出一下接收到的資料
float temp = getTemp(tempData);
Serial.println();
Serial.println(tempData);
Serial.println(temp);
bleSerial.println(temp);
}
tempSerial.end();
}
else {
Serial.println("命令無效!");
bleSerial.println("命令無效!");
}
}
}
float getTemp(String temp) {
int commaPosition = -1;
String info[9]; // 用字串陣列存盤
for (int i = 0; i < 9; i++) {
commaPosition = temp.indexOf(',');
if (commaPosition != -1)
{
info[i] = temp.substring(0, commaPosition);
temp = temp.substring(commaPosition + 1, temp.length());
}
else {
if (temp.length() > 0) { // 最后一個會執行這個
info[i] = temp.substring(0, commaPosition);
}
}
}
return (info[3].toInt() * 256 + info[4].toInt()) / 10.0;
}
String getTime() {
return info[1];
}
String getLat() {
return info[2];
}
String getLng() {
return info[4];
}
String getStatus() {
return info[6];
}
串口輸出:
藍牙輸出:
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/198958.html
標籤:其他
下一篇:樹莓派+新型混合無人機
