Brandan34 Posted March 5, 2020 Posted March 5, 2020 I am getting variables from an arduino. I now have it so I can send or receive bytes with which I can control the arduino. I am now to the point where the arduino is sending me a signed int as two bytes. (high and low byte). I can view the two bytes as a number 0-255. How would I go about taking those two numbers and getting a number that would be the same as the signed int the Arduino put into it?
Brandan34 Posted March 5, 2020 Author Posted March 5, 2020 This is something of a work around but seems to work. Leaving this here for other people who may have such a problem. It does require the baseconv.au3 lib found on this site to turn the bytes into readable 1s and 0s. If someone has a simpler answer I would be interested. expandcollapse popup#include <BaseConv.au3> $HighByte=255 $LowByte=255 ConsoleWrite('Int from byte: '&byte_to_int($HighByte,$LowByte)& @CRLF) Func byte_to_int($r,$r2) Local $countArray[]=[32768,16384,8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1] ;~ High Bite if $r <>0 Then $r=_ToBase($r,2) ConsoleWrite('$r '&$r & @CRLF) While StringLen($r) <8 $r="0"&$r WEnd Local $aArray =StringToASCIIArray($r) ;~ Low Bite if $r2 <>0 Then $r2=_ToBase($r2,2) ConsoleWrite('$r2 '&$r2 & @CRLF) While StringLen($r2) <8 $r2="0"&$r2 WEnd Local $bArray =StringToASCIIArray($r2) ;~ We now have two arrays that are holding our bytes 48=0 and 49=1 ;~ Now how to turn the bits into an int? Local $count=0 For $i=1 to 15 Step 1 ;start at one, we will need to do place 0 later as this is a signed int. If $i<8 Then if $aArray[$i]=49 Then $count= $count+$countArray[$i] EndIf Else if $bArray[$i-8]=49 Then $count= $count+$countArray[$i] EndIf EndIf ConsoleWrite('$aArray '&$i&' and ' & $countArray[$i]& " $count="& $count& @CRLF) Next if $aArray[0]=49 Then $count=$count+1 $count=$count*-1 EndIf return ($count) EndFunc
water Posted March 5, 2020 Posted March 5, 2020 I use the following function in my AD UDF: ; #INTERNAL_USE_ONLY#============================================================================================================ ; Name...........: __AD_LargeInt2Double ; Description ...: Converts a large Integer value to an Integer (Double Word) value. ; Syntax.........: __AD_LargeInt2Double($iLow, $iHigh) ; Parameters ....: $iLow - Lower Part of the Large Integer ; $iHigh - Higher Part of the Large Integer ; Return values .: Integer (Double Word) value ; Author ........: Sundance ; Modified.......: water ; Remarks .......: This function is used internally ; Related .......: ; Link ..........: http://www.autoitscript.com/forum/index.php?showtopic=49627&view=findpost&p=422402 ; Example .......: ; =============================================================================================================================== Func __AD_LargeInt2Double($iLow, $iHigh) Local $iResultLow, $iResultHigh If $iLow < 0 Then $iResultLow = 2 ^ 32 + $iLow Else $iResultLow = $iLow EndIf If $iHigh < 0 Then $iResultHigh = 2 ^ 32 + $iHigh Else $iResultHigh = $iHigh EndIf Return $iResultLow + $iResultHigh * 2 ^ 32 EndFunc ;==>__AD_LargeInt2Double My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki
RTFC Posted March 5, 2020 Posted March 5, 2020 (edited) Either I'm missing something, or you're missing something; What's wrong with this? Global $twobytes=DllStructCreate("align 1; byte[2]") Global $short=DllStructCreate("align 1; ushort", DllStructGetPtr($twobytes)) $Low=123 $High=1 ConsoleWrite(_LowHighByte2Short($Low, $High) & @CRLF) ConsoleWrite(__AD_LargeInt2Short($Low, $High) & @CRLF) Func _LowHighByte2Short($lo,$hi) DllStructSetData($twobytes,1,$lo,1) DllStructSetData($twobytes,1,$hi,2) Return DllStructGetData($short,1) EndFunc Func __AD_LargeInt2Short($iLow, $iHigh) ; corrected version Local $iResultLow, $iResultHigh If $iLow < 0 Then $iResultLow = 2 ^ 8 + $iLow Else $iResultLow = $iLow EndIf If $iHigh < 0 Then $iResultHigh = 2 ^ 8 + $iHigh Else $iResultHigh = $iHigh EndIf Return $iResultLow + $iResultHigh * 2 ^ 8 EndFunc and @water, the OP asked for short from two-byte input, so power should be 8 everywhere, not 32, I would think. NB I'm assuming ushort here (i.e., unsigned = range 0-pos) replace with "short" if a signed interpretation is needed. Edited March 5, 2020 by RTFC My Contributions and Wrappers Spoiler BitMaskSudokuSolver BuildPartitionTable CodeCrypter CodeScanner DigitalDisplay Eigen4AutoIt FAT Suite HighMem MetaCodeFileLibrary OSgrid Pool RdRand SecondDesktop SimulatedAnnealing Xbase I/O
Nine Posted March 5, 2020 Posted March 5, 2020 Streamlined : $Low=123 $High=1 MsgBox (0,"",_LowHighByte2Short1($Low,$High)) Func _LowHighByte2Short1($lo,$hi) Return Dec(hex($hi,2) & hex($lo,2)) EndFunc “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
Brandan34 Posted March 6, 2020 Author Posted March 6, 2020 This is what I like about a good coding forum there is almost always a different and often better way to do something than I can think of. I played with everyone's code and, you all have better answers than I did to get a unsigned short. I took a few minutes and ran a test script and was surprised that the performance was almost the same. Just calling the function 10k times each and all of these examples were around 2.1 seconds. @water I was trying to find the exponent command, for what ever reason I could not find it before, that makes a big improvement. I changed yours to work with bytes and it works as expected for unsigned. @RFTC I had not come across that before. I will have to look into it more. I did try to get it to give me a short by changing ushort to short on the second line, that seems to cause an error. @Nine Very nice code, gives me the wrong answer half the time but very nice. Yours is perfect for unsigned short. Mine is signed, have a clever way to add that feature? The best I have is. $HighByte=255 $LowByte=255 ConsoleWrite(HighLowByte2Short1($HighByte,$LowByte)& @CRLF) Func HighLowByte2Short1($hi,$lo) $hold=Dec(hex($hi,2) & hex($lo,2)) if $hold >32767 Then $hold=($hold-32767)*(-1) Return $hold EndFunc
Nine Posted March 6, 2020 Posted March 6, 2020 (edited) I misread the part about a signed integer. So here you go : $HighByte=255 $LowByte=255 ConsoleWrite(HighLowByte2Short($HighByte,$LowByte)& @CRLF) Func HighLowByte2Short($hi,$lo) Return Dec(hex(BitAnd($hi,0x7F),2)&hex($lo,2))-(BitAnd($hi,0x80)?0x8000:0) EndFunc Edited March 6, 2020 by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
RTFC Posted March 6, 2020 Posted March 6, 2020 (edited) $Low=1 $High=128 ConsoleWrite(_LowHighByte2Int($Low, $High, True) & @CRLF) ConsoleWrite(_LowHighByte2Int($Low, $High, False) & @CRLF) Func _LowHighByte2Int($lo,$hi, $signed=False) Local $twobytes=DllStructCreate("align 1; byte[2]") Local $short=DllStructCreate("align 1; "&(($signed)?(""):("u"))&"short", DllStructGetPtr($twobytes)) DllStructSetData($twobytes,1,$lo,1) DllStructSetData($twobytes,1,$hi,2) Return DllStructGetData($short,1) EndFunc And because I really don't like ad-hoc solutions, the one below handles all possible cases: $Low=1 $High=128 ConsoleWrite(_ConvertRawBytes2Type("short", $low, $high) & @CRLF) ConsoleWrite(_ConvertRawBytes2Type("ushort", $low, $high) & @CRLF) Func _ConvertRawBytes2Type($type, $b1=0, $b2=0, $b3=0, $b4=0, $b5=0, $b6=0, $b7=0, $b8=0) Local $bytes, $bytebuffer=DllStructCreate("align 1; byte[8]") Switch StringUpper($type) Case "BYTE","BOOLEAN","CHAR" $bytes=1 Case "WCHAR","SHORT","USHORT","WORD" $bytes=2 Case "INT","LONG","BOOL","UINT","ULONG","DWORD","FLOAT" $bytes=4 Case "INT64","UINT64","DOUBLE" $bytes=8 Case "PTR","HWND","HANDLE","INT_PTR","LONG_PTR","LRESULT","LPARAM", _ "UINT_PTR","ULONG_PTR","DWORD_PTR","WPARAM" $bytes=((@AutoItX64)?(8):(4)) Case Else Return SetError(1,0,"") EndSwitch Local $result=DllStructCreate("align 1; "&$type, DllStructGetPtr($bytebuffer)) For $bc=1 to $bytes DllStructSetData($bytebuffer,1,Eval("b"&$bc),$bc) Next Return DllStructGetData($result,1) EndFunc Edited March 6, 2020 by RTFC My Contributions and Wrappers Spoiler BitMaskSudokuSolver BuildPartitionTable CodeCrypter CodeScanner DigitalDisplay Eigen4AutoIt FAT Suite HighMem MetaCodeFileLibrary OSgrid Pool RdRand SecondDesktop SimulatedAnnealing Xbase I/O
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now