![](/img/trans.png)
[英]Qt/C++ communication with CMMO-ST-C5-1-LKP Festo controller over Modbus TCP
[英]MODBUS TCP answer convert to a float C++
我遇到了一個問題。 我有一個MODBUS TCP答案,十六進制編碼如下:0 0 0 0 0 7 1 4 4 41 B8 66 64.解釋:前五個零是Modbus規范,7是字節數在它之后。 1是Modbus網絡中的客戶端地址,不相關。 前4個是使用的功能代碼。 第二個4再次是后面的字節數。 最后四個字節是十六進制編碼的答案,應該轉換為double。 存儲它的數組是unsigned char數組。 這里有幾個例子我是怎么試的。 這是第一個例子:
value = (ibuf[9]<<24) + (ibuf[10]<<16) + (ibuf[11]<<8) + ibuf[12];
值是使用的double變量和ibuf使用的char數組。 這里是第二個:
for(i = 0; i < k; i++)
{
if (i==0)
{
sprintf(ergebnis, "%x%x", ibuf[9], ibuf[10]);
}
else
{
//sprintf(buffer,"%x%x",ibuf[9+i+i], ibuf[10+i+i]);
//strcat( ergebnis, buffer );
sprintf(ergebnis, "0x41b451e8");
sscanf(ergebnis, "%l %lf ", &Value);
}
printf("Ergebnis %s\n", ergebnis);
}
這里我使用了固定值,但問題始終是從十六進制到雙精度的轉換。 我很高興我得到的每一個幫助。
你快到了。 不幸的是,在升級過程中會自動進行轉換 - 繞過這種方式的最“直截了當”的方法是解除引用int的浮點指針,如下所示:
int ival = (ibuf[9]<<24)+(ibuf[10]<<16)+(ibuf[11]<<8)+ibuf[12];
float fval = *(float*)&ival;
對於提供的數據,這給出了23.049995而不是1.1026039e + 009,這是您從轉換中獲得的。
編輯:
正如Mike Seymour在下面的評論中所指出的,寫這個的首選方法是:
float fval = *reinterpret_cast<float*>(&ival);
請注意,您不能這樣做:
float fval = reinterpret_cast<float>(ival);
這會引發錯誤(如VS2005中所示):
error C2440: 'reinterpret_cast' : cannot convert from 'int' to 'float'
我會使用按位或運算符來重新創建浮點值。
unsigned int value = 0x00000000 | ibuf[9] << 24
| ibuf[10] << 16
| ibuf[11] << 8
| ibuf[12];
float floatValue = (float)value;
此代碼假定unsigned int在您的平台上的大小為四個字節。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.