C語言使用libmodbus庫的Modbus TCP協議讀取設備中的數據
- 2019 年 12 月 20 日
- 筆記
libmodbus是一個跨平台的modbus C語言庫,目前支援的平台有:Linux, Mac OS X, FreeBSD, QNX以及Windows,其官網是:https://libmodbus.org,其源程式碼託管在github libmodbus,其安裝和使用很簡單,本人在Windows10下的Visual Studio2017以及在CentOS7下都使用過。 由於本人最近從事的工作是環保設備方面的,很多時候設備採用簡單的Modbus工業協議,比如非甲烷總烴分析儀的Modbus地址定義如下表:
Modbus地址定義表
名稱 |
數據 |
地址 |
係數 |
值 |
---|---|---|---|---|
系統參數 |
儀器狀態 |
1 |
1 |
0 |
系統參數 |
運行狀態 |
2 |
1 |
1 |
系統參數 |
控制指令 |
3 |
1 |
8 |
取樣時間 |
年 |
10 |
1 |
2019 |
取樣時間 |
月 |
11 |
1 |
11 |
取樣時間 |
日 |
12 |
1 |
14 |
取樣時間 |
時 |
13 |
1 |
14 |
取樣時間 |
分 |
14 |
1 |
26 |
取樣時間 |
秒 |
15 |
1 |
22 |
TVOC |
狀態 |
20 |
1 |
0 |
TOVC |
峰面積 |
21 |
0.01 |
1908 |
總烴 |
濃度 |
22 |
0.01 |
254 |
CH4 |
狀態 |
23 |
1 |
0 |
CH4 |
峰面積 |
24 |
0.01 |
1729 |
CH4 |
濃度 |
25 |
0.01 |
200 |
NMHC |
狀態 |
26 |
1 |
0 |
NMHC |
峰面積 |
27 |
0.01 |
0 |
NMHC |
濃度 |
28 |
0.01 |
57 |
苯 |
狀態 |
29 |
1 |
8 |
苯 |
峰面積 |
30 |
0.01 |
0 |
苯 |
濃度 |
31 |
0.01 |
0 |
甲苯 |
狀態 |
32 |
1 |
8 |
甲苯 |
峰面積 |
33 |
0.01 |
0 |
甲苯 |
濃度 |
34 |
0.01 |
0 |
乙苯 |
狀態 |
35 |
1 |
8 |
乙苯 |
峰面積 |
36 |
0.01 |
0 |
乙苯 |
濃度 |
37 |
0.01 |
0 |
間二甲苯 |
狀態 |
38 |
1 |
8 |
間二甲苯 |
峰面積 |
39 |
0.01 |
0 |
間二甲苯 |
濃度 |
40 |
0.01 |
0 |
對二甲苯 |
狀態 |
41 |
1 |
8 |
對二甲苯 |
峰面積 |
42 |
0.01 |
0 |
對二甲苯 |
濃度 |
43 |
0.01 |
0 |
間-對二甲苯 |
狀態 |
44 |
1 |
8 |
間-對二甲苯 |
峰面積 |
45 |
0.01 |
0 |
間-對二甲苯 |
濃度 |
46 |
0.01 |
0 |
苯乙烯 |
狀態 |
47 |
1 |
8 |
苯乙烯 |
峰面積 |
48 |
0.01 |
0 |
苯乙烯 |
濃度 |
49 |
0.01 |
0 |
鄰二甲苯 |
狀態 |
50 |
1 |
8 |
鄰二甲苯 |
峰面積 |
51 |
0.01 |
0 |
鄰二甲苯 |
濃度 |
52 |
0.01 |
0 |
非甲烷總烴分析儀有三個關鍵參數,即總烴、CH4、NMHC的濃度,對應Modbus暫存器地址分別為:22,25,28,獲取對應暫存器數據後還需要乘以0.01
相應的程式碼如下:
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <time.h> #include "modbus.h" //#include <windows.h> int main(int argc, char* argv[]) { // 定義存放數據的數組 uint16_t tab_reg[20] = { 0 }; const char* ip = "15.18.23.56"; int port = 502; // 創建libmobus TCP實例 modbus_t *pmbs_ctx = modbus_new_tcp(ip, port); modbus_set_debug(pmbs_ctx, 1); modbus_set_slave(pmbs_ctx, 1); // 設置從機地址 // 連接設備 int nRet = modbus_connect(pmbs_ctx); // 連接失敗 if (-1 == nRet) { printf("connect failed:%sn", modbus_strerror(errno)); modbus_free(pmbs_ctx); return -1; } // 設置Modbus超時時間 struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 1000000; //設置modbus超時時間為1000毫秒 modbus_set_response_timeout(pmbs_ctx, tv.tv_sec, tv.tv_usec); // 每隔1秒鐘發送Modbus TCP請求,讀取對應暫存器並列印出數據 while (true) { printf("--------------------------------------------------n"); // 讀取保持暫存器的值,起始地址為22,暫存器個數為10,讀取到tab_reg數組中 int regs = modbus_read_registers(pmbs_ctx, 22, 10, tab_reg); // 獲取當前時間 // 獲取系統時間 time_t now_time = time(NULL); // 獲取本地時間 struct tm* t_tm = localtime(&now_time); // 將時間轉換為秒 //time_t mk_time = mktime(t_tm); // 輸出當前時間 printf("當前數據時間為:%04d-%02d-%02d %02d:%02d:%02dn", t_tm->tm_year + 1990, t_tm->tm_mon + 1, t_tm->tm_mday, t_tm->tm_hour, t_tm->tm_min, t_tm->tm_sec); /*SYSTEMTIME sysTm; GetLocalTime(&sysTm); printf("%4d-%02d-%02d %02d:%02d:%02d.%03d 星期%1dn", sysTm.wYear, sysTm.wMonth, sysTm.wDay, sysTm.wHour, sysTm.wMinute, sysTm.wSecond, sysTm.wMilliseconds, sysTm.wDayOfWeek);*/ // 名稱 數據 地址 係數 值 // 總烴 濃度 22 0.01 254 // CH4 濃度 25 0.01 200 // NMHC 濃度 28 0.01 57 printf("總烴的濃度為:%.3f ppmVn", tab_reg[0] * 0.01); printf("CH4的濃度為:%.3f ppmVn", tab_reg[3] * 0.01); printf("NMHC的濃度為:%.3f ppmVn", tab_reg[6] * 0.01); printf("--------------------------------------------------n"); Sleep(1000); } // 關閉modbus連接 modbus_close(pmbs_ctx); //釋放modbus資源,使用完libmodbus需要釋放掉 modbus_free(pmbs_ctx); getchar(); return 0; }
運行測試:
Connecting to 15.18.23.56:502 -------------------------------------------------- [00][01][00][00][00][06][01][03][00][16][00][0A] Waiting for a confirmation... <00><01><00><00><00><17><01><03><14><01><31><00><00><07><C9><00><E7><00><00><00> <00><00><4A><00><08><00><00><00><00> 當前數據時間為:2109-12-11 18:13:37 總烴的濃度為:3.050 ppmV CH4的濃度為:2.310 ppmV NMHC的濃度為:0.740 ppmV -------------------------------------------------- -------------------------------------------------- [00][02][00][00][00][06][01][03][00][16][00][0A] Waiting for a confirmation... <00><02><00><00><00><17><01><03><14><01><31><00><00><07><C9><00><E7><00><00><00> <00><00><4A><00><08><00><00><00><00> 當前數據時間為:2109-12-11 18:13:38 總烴的濃度為:3.050 ppmV CH4的濃度為:2.310 ppmV NMHC的濃度為:0.740 ppmV -------------------------------------------------- -------------------------------------------------- [00][03][00][00][00][06][01][03][00][16][00][0A] Waiting for a confirmation... <00><03><00><00><00><17><01><03><14><01><31><00><00><07><C9><00><E7><00><00><00> <00><00><4A><00><08><00><00><00><00> 當前數據時間為:2109-12-11 18:13:39 總烴的濃度為:3.050 ppmV CH4的濃度為:2.310 ppmV NMHC的濃度為:0.740 ppmV -------------------------------------------------- -------------------------------------------------- [00][04][00][00][00][06][01][03][00][16][00][0A] Waiting for a confirmation... <00><04><00><00><00><17><01><03><14><01><31><00><00><07><C9><00><E7><00><00><00> <00><00><4A><00><08><00><00><00><00> 當前數據時間為:2109-12-11 18:13:40 總烴的濃度為:3.050 ppmV CH4的濃度為:2.310 ppmV NMHC的濃度為:0.740 ppmV -------------------------------------------------- -------------------------------------------------- [00][05][00][00][00][06][01][03][00][16][00][0A] Waiting for a confirmation... <00><05><00><00><00><17><01><03><14><01><31><00><00><07><C9><00><E7><00><00><00> <00><00><4A><00><08><00><00><00><00> 當前數據時間為:2109-12-11 18:13:41 總烴的濃度為:3.050 ppmV CH4的濃度為:2.310 ppmV NMHC的濃度為:0.740 ppmV --------------------------------------------------