人機與電腦通訊問題

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

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

请高手帮忙: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時,對於位置識別碼上面的認知不同嗎?

你搜尋 modbus 關鍵字
Multipliers to change data to/from integer.

學會舉一反三,PLC與變頻器之間的MODBUS通訊方法如此簡單

FYI
image

1個讚

竟然有這個關鍵字,
雖然沒找到專門說明的文章,但大概了解了一些
謝謝分享

需將浮點轉換後再傳送…
例 : -12.5 轉成16進制後 將 0x00 0x00 0x48 0xC1 寫入 MODBUS VI.

資料來源 : 參閱下列連結
連結 1. 为什么浮点变量值-12.5的十进制为:0xc1480000
連結 2. @ IEEE 规範
連結 3. @ 浮點數

一個浮點數 a由 兩個數me 來表示:
a = m × b^em(即尾數), e是指數。

S : represents the sign bit where 1 is negative and 0 is positive.
E : is the exponent with an offset of 127.
M : is the 24-bit mantissa (stored in 23 bits).

Zero is a special value denoted with an Exponent field of 0 and a Mantissa of 0.

Using the above format,
the floating-point number -12.5 is stored as a hexadecimal value of 0xC1480000.

In memory, this value appears as follows:
Address+0 Address+1 Address+2 Address+3
Contents 0x00 0x00 0x48 0xC1

S 代表符號位,1是負,0是正
E 偏移127的冪,二進制階碼=(EEEEEEEE)-127。
M 24位的尾數保存在23位中,只存儲23位,最高位固定爲1。

從這個例子可以得到下面的信息:

符號位是1 表示一個負數

冪是二進制10000010或十進制130,130減去127是3,就是實際的冪。
尾數是後面的二進制數10010000000000000000000

在尾數的左邊有一個省略的小數點和1,
這個1在浮點數的保存中經常省略
,加上一個1和小數點到尾數的開頭,得到尾數值如下:
1.10010000000000000000000

接着,根據指數調整尾數.
一個負的指數向左移動小數點.
一個正的指數向右移動小數點.因爲指數是3,尾數調整如下:
1100.10000000000000000000

結果是一個二進制浮點數,小數點左邊的二進制數代表所處位置的2的冪
例如:1100 表示 (12^3)+(12^2)+(02^1)+(02^0) = 12。
小數點的右邊也代表所處位置的2的冪,只是冪是負的。
例如:.100…表示(12^(-1))+(02^(-2))+(0*2^(-2))…=0.5。

這些值的和是12.5。
因爲設置的符號位表示這數是負的,
因此十六進制值0xC1480000表示 -12.5。


浮點數 16進制轉換.vi (187.7 KB)

2個讚

原來如此,數值轉換好複雜@@

感謝前輩分享,我跟樓下也不知道有這個可以搜尋!