2016-08-04 26 views
0

對於某些項目,我必須將有符號整數從Java over serial發送到微控制器上的C++程序。它對於正整數很好地工作,但負整數被包裹起來並在C++端顯示爲正整數。通過串行發送負整數

下面是發送在Java端的INT功能:

void writeIntToSerial(Serial port, int number) { 
    port.write(byte(number << 24)); 
    port.write(byte(number << 16)); 
    port.write(byte(number << 8)); 
    port.write(byte(number << 0)); 
} 

我不只是之前和之後的有效載荷發送原始整數,但一些控制字符。所有這一切正常。

接收(C++)端將輸入流讀入char的緩衝區數組,然後根據流中的控制字符用狀態機解釋流。

的字符流轉換回整數部分是一個基本的位位移:

int startAngle = 0; 
// [...] 
startAngle = (payload[0] << 24) + (payload[1] << 16) + (payload[2] << 8) + payload[3]; 

如前所述,它工作得很好,爲正值,但即-60將轉換爲196(256 - 60 )。

我意識到解決方案可能是微不足道的,但我一直在盯着這段代碼太久......我迷路了。

+1

這是你的實際的代碼?我很難相信即使對於正值,顯示的代碼也能工作。 – Kayaman

+0

是的。當發佈這個我意識到粘貼寫**浮動** ToSerial(),而不是寫在Java端的Java ** ToSerial(),但那是從那以後更正。代碼工作正常(對於正整數)。 – Oldaric

+1

那麼'port.write()'的定義是什麼?顯然它需要一個int參數,但它對它有什麼作用?由於您正在向左移動,因此在嘗試發送int'-1'時,它首先會寫入'0xFF000000',然後'0xFFFF0000',然後'0xFFFFFF00',最後寫入'0xFFFFFFFF'。我無法想象'write()'只會使用8個最重要的位。 – Kayaman

回答

0

它看起來就像你序列化的一端是float,另一端是int。由於這些數據類型在內部存儲的方式必然存在一些不一致之處。

因此,無論您發送/接收浮動INT,但不要混合起來

+0

是的,我剛剛意識到我粘貼了錯誤的功能。現在在OP中查看實際的writeIntToSerial()。 Sry對此 – Oldaric

0

這是因爲你將它們加在一起,所以它們會被標記爲32位。

如果你或他們在一起,你應該得到正確的結果。

+0

我剛剛將接收端更改爲此 startAngle =(payload [0] << 24)| (有效載荷[1] << 16)| (有效載荷[2] << 8)|有效載荷[3]; 具有相同的結果。這是你的意思嗎? – Oldaric

0

在您的例子,當您發送-60您發送的字節

0000 0000 
0000 0000 
0000 0000 
1100 0100 

,然後你重新給

0...1100 0100 

是196,所以代碼工作得很好。如果你發送了一個大於255的正數,你也應該在接收端僞造。這是因爲您正在向Java方向錯誤地移動

+0

溝通的一方是小端,另一端是大端。這就是爲什麼我以接收方字節順序發送字節。這可能是一個愚蠢的後續問題,但如果你說的是對的,我不會得到60,當我發送60,對嗎? – Oldaric

+0

你真的應該看看'htonl'和'ntohl'函數 - 在你的μC程序中使用它們,並且總是在你的java應用程序中轉換成/從網絡字節順序 - 這將確保你的協議不依賴於OS/μC依賴 – specializt

+0

如果將java int向左移位8位或更多位,然後將其轉換爲字節,則總是會得到0.所以是的,當您翻轉移位時,在發送60後應該接收60。對於60(這是<256),應該是沒有變化的情況 – RafToTheK

0

我猜那個有效載荷的類型是char或unsigned char? 然後有效載荷[x] < < y會移入無符號字符大小,顯然不會超過8位。如果我的假設是真的,你的代碼應該是

startAngle = (static_cast<unsigned int>payload[0]) << 24) + ((static_cast<unsigned int>payload[1]) << 16) + ((static_cast<unsigned int>payload[2]) << 8) + payload[3]; 
+0

你的推理很有意義,但不幸的是結果是相同的(60 - > 60,-60 - > 196) – Oldaric

+0

sry,static_cast ( - 60)對負數不正確。嘗試使用unsigned int來代替。相應地編輯我的回答 –

+0

可悲的是,沒有改變。我必須稍微更換一些括號以使其順便工作。我的轉換大氣壓是這樣的: (的static_cast (有效載荷[0])<< 24) +(的static_cast (有效載荷[1])<< 16) +(的static_cast (有效載荷[2])<< 8 ) +有效載荷[3]; – Oldaric

0

好吧。

在發送端我需要右移代替左移:

void writeIntToSerial(Serial port, int number) { 
    port.write((number >> 24)); 
    port.write((number >> 16)); 
    port.write((number >> 8)); 
    port.write(number); 
} 

而在接收端該位位移鑄序列的伎倆:

startAngle = (static_cast<uint32_t>(payload[0]) << 24) 
      | (static_cast<uint32_t>(payload[1]) << 16) 
      | (static_cast<uint32_t>(payload[2]) << 8) 
      | payload[3];