介紹modbus slave 端 coding
Modbus server 簡介
modbus tcp 的流程也差不多,只是換成tcp 需要的參數
tcp寫法有很多種,可搭配Socket 的各種模式去接收request
以下簡介modbus rtu server
//new 一個modbus rtu 物件,設置device (俗稱serial port)、baud rate .. 等等 modbus_t *ctx = modbus_new_rtu( "/dev/ttyS0" , //device 9600, //baud 'N' , //parity 8, //data bits 1); //stop bits //設置slave id modbus_set_slave(ctx, mb_rtu_slaveId); //連線com port modbus_connect(ctx); //建立map及寫值 modbus_mapping_t *mb_mapping = modbus_mapping_new(0, 0, 0, MB_MAX_INPUT_REGISTER); mb_mapping->tab_input_registers[1] = oa_num; //開一個loop在main thread,等著request 進來 //若收到request,就用modbus_reply 丟入map,libmodbus 會自行判斷回應對應的register 值或error code //若要非同步更新map,就是開另一個thread 或callback function,去更新map 內容即可 (設全域變數) for (;;) { uint8_t query[MODBUS_MAX_ADU_LENGTH]; int rc = modbus_receive(ctx, query); if (rc > 0) { modbus_reply(ctx, query, rc, mb_mapping); } else if (rc == -1) { LOG_ERROR(my_log_type, "modbus error : %s\n" , modbus_strerror( errno )); } usleep(100); } modbus_mapping_free(mb_mapping); modbus_close(ctx); modbus_free(ctx); |
Modbus map
input register 為一種限制client read only 的array,array 每一個單位為2 bytes
所以若寫入的資料長度不等於2 bytes,須注意寫入及讀取的記憶體排列方式,會依照OS 平台或程式語言會不同
在下面code的registers 是個array,編號從0開始
但Modbus 卻是從1開始,所以要減1才會等於array 實際位置
另外一般是master端來遵守slave 端的資料排列,所以不一定要實作swap bytes 或是swap word等功能
以libmodbus 的程式碼對照下圖register 來簡單說明用法
#define MB_MAX_INPUT_REGISTER 10000 modbus_mapping_t *mb_mapping = modbus_mapping_new(0, 0, 0, MB_MAX_INPUT_REGISTER); //mb_mapping 是一個具有4種資料存取位置的結構,根據modbus_mapping_new 填入的參數會影像這4種資料存取的大小 //以復盛這個例子,只須要最後一個參數設10000 即可 mb_mapping->tab_input_registers[1] = oa_num; //寫入Address 0002 ,內容為Number of lines char oaName[] = "hello" ; mb_mapping->tab_input_registers[101] = (uint16_t) oaName[0]; //'h' mb_mapping->tab_input_registers[102] = (uint16_t) oaName[1]; //'e' mb_mapping->tab_input_registers[103] = (uint16_t) oaName[2]; //'l' mb_mapping->tab_input_registers[104] = (uint16_t) oaName[3]; //'l' mb_mapping->tab_input_registers[105] = (uint16_t) oaName[4]; //'o' mb_mapping->tab_input_registers[106] = (uint16_t) oaName[5]; //'\0' //寫入Address 0102~0107 ,內容為Name of this line,以ASCII 的方式存入 //Register map 寫,Quantity 32,代表只接受32個字,從0101寫到0132 double oaValue = 1.3145926; float *reg_oa_value = ( float *)&mb_mapping->tab_input_registers[141]; *reg_oa_value = oaValue; //寫入Address 142,內容為Value of this line //這邊暫時作法是將array 轉成float pointer,將oa 直接寫入 //問過AE 改成float 不用double modbus_mapping_free(mb_mapping); //release map |
Karl 的魔法書: Modbus Sample Code >>>>> Download Now
回覆刪除>>>>> Download Full
Karl 的魔法書: Modbus Sample Code >>>>> Download LINK
>>>>> Download Now
Karl 的魔法書: Modbus Sample Code >>>>> Download Full
>>>>> Download LINK