I am receiving a packet through a serial port but when I receive the packet it is of class bytes and looks like this:
b'>0011581158NNNNYNNN +6\r'
How do I convert this to a normal string? When I try to take information from this string, it comes out as a decimal representation it appears.
You can call decode on the bytes object to convert it to a string, but that only works if the bytes object actually represents text:
>>> bs = b'>0011581158NNNNYNNN +6\r'
>>> bs.decode('utf-8')
'>0011581158NNNNYNNN +6\r'
To really parse the input, you need to know the format, and what it actually means. To do that, identify the device that is connected to the serial port (A scanner? A robot? A receiver of some kind?). And look up the protocol. In your case, it may be a text-based protocol, but you'll often find that bytes stand for digits, in which you'll probably want to have a look at the struct module.
Related
I have this using Buffer in node.
string hex_message = "7E01000036015211601385025E";
var chunk = Buffer.from(hex_message, 'hex'); //
var message = chunk.toString('utf-8'); //
var bu = Buffer.from(message, 'utf-8');
var message3 = bu.toString('hex').toUpperCase();
// 7E010000360152116013EFBFBD025E
Note that makes 7E010000360152116013EFBFBD025E
I want using string to pass buffer between microservices, and i want to convert all buffer in string, but in the other when I need to rebuild the buffer I got different information.
This step here:
var message = chunk.toString('utf-8');
creates a problem because after calling this:
var chunk = Buffer.from(hex_message, 'hex');
the Buffer contains binary data. If you do console.log(chunk), you will see this:
<Buffer 7e 01 00 00 36 01 52 11 60 13 85 02 5e>
which shows the binary representation of your original hex string:
"7E01000036015211601385025E"
Calling chunk.toString('utf-8') on that Buffer containing the binary data will attempt to interpret it as utf-8, but that won't be correct on purely binary data. In fact, it will take your binary data and try to interpret it as something other than the pure binary data. It will look at the incoming data and see utf-8 escape sequences in some places causing it to interpret the data wrongly.
When you say you want to pass the data between microservices, we need to know how you're passing it between the microservices and what the capabilities of that transport are. For some transports, you can just send the binary Buffer directly (like with TCP). For other transports, you have to encode it to something that transport can handle, in which case the original hex_message string is a safe way to send it. You could also put the binary into an array of numbers and the use JSON to encode/decode it.
The point is that you have to either just send the original hex_message string which is likely safe with any transport you're using or you have to properly encode that to something your transport can handle and then properly decode it on the receiving end to get back the binary it represents.
To summarize, here are the initial steps:
You first need to decide what encoding you're going to use for whatever transport you are using to communicate with the microservice. You need to pick an encoding that can properly represent your binary data. To help you pick that encoding, we would have to know how you're sending the data and what types of encoding it can handle.
Then, you need to take your ascii hex data and properly convert it to the desired encoding.
And here are some options for encoding:
Just send the original hex_message string you started with since the whole purpose of the "hex" encoding is to represent binary data in plain ascii strings. This is likely safe with any transport you're using between microservices. The receiving end can process the ascii string it receives to a binary buffer if required to use it.
Put the binary data into an array of numbers and encode that array as JSON and send the JSON. Though sending the hex string in option #1 will likely be more efficient as it is represented in fewer bytes and is already available.
If your transport is capable of sending/receiving binary (which TCP can), then you can do const chunk = Buffer.from(hex_message, 'hex'); and send the binary data in the Buffer directly. The receiving end will get the binary Buffer and can then treat that according to its needs.
In Python 2.x I can Serial port write a list of bytes like this:
numbers=[0x40,0x00,0x99,0x54,0x78,0x13]
for x in numbers:
ser.write(x)
Now I'm converting to Python 3.8.6 it doesn't work. From what I read, in Python 3 all serial writes must be strings or "byte literals". What is the best way to convert my list of numbers into "byte literals" that I can send out the serial port? I don't really understand what "byte literal" means...
I figured it out.
numbers=[0x40,0x00,0x99,0x54,0x78,0x13]
numbers=bytes(numbers)
ser.write(numbers)
What confused me was when I tried testing the bytes() operation on a single number, that creates a byte literal string filled with zeros. But if you do the bytes() operation on a list, it converts the list to a byte literal string.
we are trying to process a 152 bytes UDP data frame from a remote service. By following the PeerToPeer Beckhoff infosys example (https://infosys.beckhoff.com/content/1033/tf6310_tc3_tcpip/18014398593720075.html?id=9052404215823027436) we are not able to see the entire 152 bytes message, just a couple of bytes.
Is it possible that the String variable would be only showing the characters until the first 00 bytes or similar (null delimiter)?
In the image below you can see the full UDP frame and what we get as message.
Thanks in advance.
You are correct, the Beckhoff PeerToPeer example will not work with binary data because it uses strings that will cut off at zero value. So it doesn't like the UDP data you have for it.
Instead you should use function blocks like e.g. ReceiveData which will work with a data array and pointers, thus allowing any byte value received. You can do a google search for 'Beckhoff ReceiveData' to get the precise information.
I'm trying to communicate with a bluetooth thermometer. It's not BLE, it uses serial ports. I've made it as far as receiving REQ signals from the device, but it requires a ACK signal or it cuts the connection after a few seconds.
The problem is, I can't decipher what the ACK signal is supposed to be. Going off the documentation, it says:
<ACK Format> ADH,01H
<REQ Format> ADH,00H,n
The third byte of REQ is the can be multiplied by 0.01310547 to get the voltage of the battery
<Data Format> ADH,03H,1EH," IRSTP3xx.yyy.HhhSss,nnn,tt.t"+0D+0A
xx: LotNo.(base 16) "01"~"FF"
yyy: S/N(base 16) "001"~"FFF"
...
...
Nothing in the Data Format mentions the first 3 bytes(?) either.
That's pretty much all I've got to work with. I'm trying decoding REQ with different encodings like ascii and utf-8 to see if I can get it to match the REQ format, and then use that same encoding to format and send ACK, but I haven't had any luck.
Is the format just in some kind of standard notation that I'm not familiar with?
The H apparently stands for hexidecimal.
ADH is a two byte message, the first byte being a hex A and the second a hex D. I have not seen that notation before.
I am currently attempting to communicate with an external application over TCP/IP based socket. I have successfully established a connection with the client and received some data. This manual here states that
After this command is received, the client must read an acknowledgement
octet from the daemon. A positive acknowledgement is an octet of zero bits. A negative acknowledgement is an octet of any other pattern.
I would like to send a positive acknowledgment and I am sending it this way
My server listening code was obtained from here
void WriteData(std::string content)
{
send(newsockfd,content.c_str(),content.length(),0);
}
WriteData("00000000");
My question is if I am sending this data corectly (octet of zero bits) ?
Update:
I have read this post here
which states that send only allows to send a char* array. So I am not sure how I can send a byte over a socket. I know i could do something like this
std::bitset<8> b1 ; // [0,0,0,0,0,0,0,0]
but i am not sure how i would send that over a socket.
Try
WriteData(std::string("\0",1));
using your function or even:
const char null_data(0);
send(newsockfd,&null_data,1,0);
to send it directly.
WriteData("00000000");
Will actually sends 8 octets of 48 [decimal] (assuming your platform is ASCII which all modern systems are compatible with).
However \0 is the escape sequence used in string literals to represent the null character (that is the zero octet).
There's a conflation (mixing together) in C++ between the notions of characters and bytes that dates back to the earliest days of C and is pretty much baked in.