介紹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 idmodbus_set_slave(ctx, mb_rtu_slaveId);//連線com portmodbus_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 10000modbus_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 lineschar 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寫到0132double 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 不用doublemodbus_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