人機與電腦通訊問題

您好想來詢問各位前輩,目前是想在人機上面顯示Double含有小數點數值,在人機上面操作是確實可以的,且在Labview有把數值型態改成Double,但是當我寫入為帶有小數點的數值時,在透過電腦讀取出來會被四捨五入且沒辦法輸入小數點,請問有辦法解決這個問題嗎?
HMI部分也有同意顯示小數點,下面是我的程式。

程式操作影片檔.7z (1.1 MB)




你必須先進階去了解 modbus read 輸出的資料型態.(To Long Integer)
在邏輯上你是不是理解錯誤了… register values 並不是被 四捨五入…

MODBUS是轉成16進制來發送,它可以送小數點的資料嗎?

是不是沒辦法…?

有辦法更改modbus read這個VI的輸出型態嗎? 我點他VI進去他鎖起來沒辦法直接更改他原始檔

查了一下資料好像小數點還是可以的?

我看到的好像是都寫整數…

请高手帮忙:labview的modbus应用 - NI Community

有看到這個好像連有負號的都不能輸出…

負號是可以,我有輸出過,只是負數的16進制編碼不太一樣

照文章所講,
1.整數小數分開轉
2.我以前寫PLC用過,先乘100,傳輸後,後面再除100

負數編碼舉例:(用小算盤程式設計人員模式來看)
1000->x0000 03E8
-1000->xFFFF FC18,這樣送出,對方解碼後即得負數

但Proface HMI讀取資料格式好像是固定的,所以我輸入負數他目前是沒辦法讀取,我也有發現輸入小數值進Labview會有差100倍的問題,所以我現在也是用您上面提到的方法去做轉換!

剛剛發現是我沒打開正負號顯示…

只是我發現打開正負號顯示輸入進去的數值會被 / 2,而且好像Labview modbus這個mod本身就是無符號輸出了,所以沒有負號?

會差100倍跟除以2這個我沒遇過
但負號可以輸入,就是編碼方式要用我上面提的那樣做
附圖是我之前控制器的範例,
要傳30000時,要送0x7530 0000
要傳-30000時,要送0x8AD0 FFFF

由於 Modbus 使用 16 位寄存器來保存值,因此必須在兩個寄存器之間拆分 32 位浮點數。Modbus 沒有聲明如何表示浮點數的標準,因此設備處理浮點數的方式可能與 LabVIEW 不同。以下文章討論了可以使用兩個寄存器表示浮點數的不同形式: Modbus RTU 消息中如何對實數(浮點)和 32 位數據進行編碼

下面的圖 1 顯示瞭如何使用 IEEE 754 標准定義浮點數。最低有效位存儲在第一個寄存器中。
圖 1:最不重要的值優先
在此形式中,如果您嘗試將數字 123456.00 存儲在寄存器 F400001 中,則字節“A B”將存儲在第一個寄存器 F40001 中。字節“C D”存儲在第二個寄存器 F400002 中。在 LabVIEW 2011 及更早版本中, 當使用 Modbus Slave I/O 服務器時,LabVIEW並不是 這樣表示 Modbus 寄存器中的浮點數。如果您的設備期望首先出現最低有效位,那麼您的數據將如圖 2 中的十進制值所示。

圖 2:首先出現最高有效位

圖 2 顯示了 LabVIEW 如何將最高有效字節“C D”放置在第一個寄存器中。然後最低有效字節“A B”被放置在第二個寄存器中。這種形式通常稱為“單詞交換”。

如果您的設備遵循圖1的形式,則可以在將值寫入設備之前在LabVIEW中對單個浮點值執行“字交換”。下圖顯示瞭如何反轉順序,步驟說明瞭如何設置它。

圖 3:字交換浮點值
:該圖是 LabVIEW 代碼片段,其中包含可在項目中重複使用的 LabVIEW 代碼。要使用代碼片段,請右鍵單擊圖像,將其保存到計算機,然後將文件拖到 LabVIEW 圖表上。

  1. 在程序框圖上放置一個類型轉換函數。將數值數組常量連接到 類型 輸入。將單個浮點數連接到 x 輸入。
  2. 右鍵單擊 數組中的 數值常量,然後選擇 表示法»I16
  3. Place Reverse 1D Array 函數將第一個類型轉換連接到 數組 輸入。
  4. 放置第二個類型轉換函數。將單個浮點數連接到 類型 輸入。將反轉數組輸出連接到 x 輸入。
  5. 現在可以將交換的單個浮點值寫入 Modbus 寄存器。此示例使用綁定到 Modbus 寄存器的共享變量。

給你一個 方向…參考看看
方法也就是… 你可以自己 寫一個 Modbus Parser

寫入 時 先把浮點資料型態 轉換成 整數 (To Unsigned Byte Integer)
讀取 後 再將整數資料型態 轉換成 浮點數 (To Double Precision Float)

另外 想請問 下圖 紅框中的 VI 你是如何做轉換的

(這個 紅框中的 VI 應該可以直接轉換成 unsigned byte array 寫入 Modbus )
image


這大概是那個子VI的功能,因為我目前是接Stm32連接mpu6050讀取gyro值,想說把陀螺儀數值嘗試顯示在人機上面看看!
對於string直接寫入Modbus方法可能不好因為子VI算是一個解編碼的動作,不過還是謝謝前輩提供這個方法。

有點看不太懂這部分在幹嘛…

另外想詢問前輩,為何人機輸入帶有小數點的數值在Labview上讀取時會差100倍呢?
Labview輸入給人機的數值也有相同問題,例如人機上面Key 5.00時,Labview這邊會讀取500,Labview這邊輸入-123時,人機上會顯示-1.23,請問這是在轉換成16bit時,對於位置識別碼上面的認知不同嗎?