JDRenk 1 Posted February 14, 2022 First, I am new to programming, but have many, many years experience as an EE/designer. I am trying to read an A/D that sends 24 bit two's complement data out a UART using Winsoft Comport. It is working to the point I can read data as an ANSI String, but I don't know how to read it as two's complement data. Any help would be greatly appreciated. Share this post Link to post
PeterBelow 238 Posted February 14, 2022 Can't you read it one byte at a time? I'm not familiar with the component you use. Share this post Link to post
FPiette 383 Posted February 14, 2022 Please show the code you are currently using. Share this post Link to post
JDRenk 1 Posted February 14, 2022 When I use this I get integer values that don't make sense. procedure TForm2.ComPort4RxChar(Sender: TObject); var Text: String; Result: Integer; begin Result := ComPort4.ReadWord; Text := IntToStr(Result); Memo2.Text := string(Text); end; When I use this I get the correct ANSI String. procedure TForm2.ComPort4RxChar(Sender: TObject); var Text: AnsiString; begin Text := ComPort4.ReadAnsiString; Memo2.SelText := string(Text); end; Share this post Link to post
Roger Cigol 103 Posted February 14, 2022 What you are really asking is "how to convert data in a string of a particular format" into a binary integer. But you are asking this question without giving us the actual string. So with the code where you "get the correct string" - what string do you get? maybe offer a few examples with different inputs on the ADC. Share this post Link to post
qubits 20 Posted February 14, 2022 pretty sure your integers are 24 bits, 3 bytes not 4. Reading words won't help. Need to read bytes and pad it. Share this post Link to post
FPiette 383 Posted February 14, 2022 What looks the string like ? Does the component have a ReadByte function ? Share this post Link to post
MichaelT 6 Posted February 14, 2022 34 minutes ago, FPiette said: What looks the string like ? Does the component have a ReadByte function ? Winsoft's ComPort.dll indeed does offer a function called ReadByte. I hope the same counts for the component. Share this post Link to post
FPiette 383 Posted February 14, 2022 Using ReadByte you can read 24 bits from the UART, probably as 32 bits padded with zeros. You can build a 32 bits signed integer with that. Delphi compiler use 2's complement. You didn't answered my question: What does the string looks like ? Share this post Link to post
JDRenk 1 Posted February 14, 2022 The A/D only sends 3 bytes at a time. I am looking at WinSoft's ComPort demo to get an idea of what to do. Share this post Link to post
MichaelT 6 Posted February 15, 2022 10 hours ago, JDRenk said: The A/D only sends 3 bytes at a time. I am looking at WinSoft's ComPort demo to get an idea of what to do. Give the Read function/method a try As far as I see the function in the ComPort.dll does offer to pass a Pointer as a Buffer and a Count(er). I'm not sure if that's included in the component itself and offered. I think this is not the first time I read about this issue in a discussion. Share this post Link to post
FPiette 383 Posted February 15, 2022 By the way, there are lots of serial component which are free and include full source code. Or commercial products with good documentation. Share this post Link to post
limelect 48 Posted February 15, 2022 (edited) I use this FREE component on D10.2.3 -------------------------------------------------+ | ComPort Library version 4.10 | | for Delphi 5, 6, 7, 2005, 2006, 2007, 2010, XE | | and C++ Builder 3, 4, 5, 6 | | | | by Dejan Crnila 1998-2002 | | maintained by Lars Dybdahl and Paul Doland | | maintained by Brian Gochnauer Nov 2010 | +-------------------------------------------------+ But there are other free and with full source and NOOOOO DLL Edited February 15, 2022 by limelect Share this post Link to post
JDRenk 1 Posted February 18, 2022 Thank you all for your advice. As I said I am new to programming and simply need to understand things better. Share this post Link to post
JDRenk 1 Posted February 28, 2022 Ok, I have a better handle on this. Since I am getting data back from different sensors via 3 UARTs, I found the best way for all is to read an ANSIString or byte by byte into a buffer. The data contains other information I need to discard. So how would I select characters i->j out of k total? "xxxxxxxxixxxxxxjxxxxxxxxxxk" Thanks, Jeff Share this post Link to post
PeterBelow 238 Posted March 1, 2022 18 hours ago, JDRenk said: Ok, I have a better handle on this. Since I am getting data back from different sensors via 3 UARTs, I found the best way for all is to read an ANSIString or byte by byte into a buffer. The data contains other information I need to discard. So how would I select characters i->j out of k total? "xxxxxxxxixxxxxxjxxxxxxxxxxk" Thanks, Jeff You never told us which Delphi version you are using. If it has a System.Ansistrings unit: that contains a number of routines to work with ansistrings. Use the AnsiPos function to search for a character or substring; it returns the index of the found item. Use AnsiMidStr to extract a range of characters from an Ansistring (or the good old Copy function, it has an overload for Ansistrings). Share this post Link to post
JDRenk 1 Posted March 1, 2022 I am using Delphi 10.4 Community Edition. I don't believe it has a Systems.AnsiStrings unit. The COPY function seems to work. My next issue is......... Copy gives me an eight character string of a HEX value, (eg. 1289ABEF). How do I convert that to its Integer value (eg. 311012335)? Share this post Link to post
Lajos Juhász 293 Posted March 1, 2022 35 minutes ago, JDRenk said: I am using Delphi 10.4 Community Edition. I don't believe it has a Systems.AnsiStrings unit. The COPY function seems to work. My next issue is......... Copy gives me an eight character string of a HEX value, (eg. 1289ABEF). How do I convert that to its Integer value (eg. 311012335)? I am sure it has System.AnsiStrings unit. The easiest way is to use StrToInt('$1289ABEF'). Share this post Link to post
JDRenk 1 Posted March 1, 2022 This is what I have: procedure TForm2.ComPort1RxChar(Sender: TObject); var A : integer; Buffer1 : AnsiString; Result1 : AnsiString; begin Buffer1 := ComPort1.ReadAnsiString; Result1 := Copy(Buffer1,21,8); A := StrToInt ($Result1); end; But it is saying StrToInt is overloaded, not sure what that means. Share this post Link to post
FPiette 383 Posted March 1, 2022 Quote A := StrToInt ($Result1); Should be: A := StrToInt ('$' + Result1); Share this post Link to post
JDRenk 1 Posted March 7, 2022 Thank you. Now I'm having success in debugger mode, but when I run without debugger on I get "'$' is not a valid integer value." The result is correct, just the pop up issue. It is coming from the StrToInt because if I change the $ to 0x I get the 0x in the message. Share this post Link to post
Lajos Juhász 293 Posted March 7, 2022 (edited) 48 minutes ago, JDRenk said: Thank you. Now I'm having success in debugger mode, but when I run without debugger on I get "'$' is not a valid integer value." The result is correct, just the pop up issue. It is coming from the StrToInt because if I change the $ to 0x I get the 0x in the message. In your code you never check for length of the buffer. When reading the com port it's not guaranteed that you receive all the data in one read. You've to check whenever you received everything and after that you can try to process it. Edit. In this case most probably the length of the result is less than 21 bytes and result1 will be an empty string. Try: if result1<>'' then A := StrToInt ('$' + Result1) else begin ShowMessage('Result1='''''); end; Edited March 7, 2022 by Lajos Juhász Share this post Link to post
JDRenk 1 Posted March 7, 2022 I am aware that the data doesn't come in one read so I delayed the read to allow the buffer to fill and also am using a comport monitor to verify the correct # of bytes. All looks correct. Share this post Link to post
Lajos Juhász 293 Posted March 7, 2022 6 minutes ago, JDRenk said: I am aware that the data doesn't come in one read so I delayed the read to allow the buffer to fill and also am using a comport monitor to verify the correct # of bytes. All looks correct. You should also check in ComPort1RxChar how many bytes the comport reads from the buffer. Share this post Link to post
JDRenk 1 Posted March 8, 2022 Thanks, I now have that Com Port and sensor working OK. Now I have another sensor and Com Port that are totally different. This one returns a 4 byte float32_t value. I have the 4 bytes in an array of bytes. How would I convert that to a decimal string? Share this post Link to post