I am trying to copy the functionality of this C++ line :
(uint8_t ) structureManaged
where structureManaged is an object. The object might be different every time.
This reads structureManaged as a uint8, but i have’t found any way of doing this in python.
What is an example of one of your objects?
Are they int types in your C++ world?
If so you can simple mask the low 8bits like this in python.
a = 42356322
x = a&0xff
I am trying to send the data through UART to a LoRa module. I’m using an Arduino on the other side, and the Arduino library uses this line of code. For the Python side, I’m using a port of the same library, but it doesn’t work with structs (which I’m using because they allow you to send values (in,float,byte…)) so I’m trying to replace structs with objects, and I still need to read it as uint8 for the UART.
I have to say Your post confuses me . I know C++ and I know structs there are used to store many data into one variable. On the other hand, uint8 is just… a number (I know it is a big simplification, but still). So, writing a big structure/object into a small type…huh?
I suspect two things: either
- You are trying to read a structure send from your Arduino byte-by-byte, or
- You are using
struct
as a container for a single uint8 value, as a bypass (for which I don’t know) to send a byte to your Python program
From what I understood from reding the libraries, sending data through UART to the LoRa module requires sending data as a bunch of bytes. In C++, this can be done with the (uint8-t)variablename , which reads variablename as a bunch of separate bytes (not an array). I am trying to replicate that in python. I checked and the python library I’m using also sends its data like this, but it uses methods that aren’t compatible with what I’m trying to do.
Oh, so You aren’t trying to brute-force fit a structure to a byte, but to get its binary representation (or more specifically, to its C representation)
So then, you should look at the struct
library from the Python’s standard library (I swear, I’m recommending this library, like, 3rd time in a row
)
For example, if your C struct is:
struct MyStruct {
int number;
float ratio;
uint64_t big_data;
}
then you have to pack your data like this:
number = ...
ratio = ...
big_data = ...
output = struct.pack("ifq", number, ratio, big_data)
and you will receive raw bytes
data in the output
variable. Then you give that output to your library
In the C++ code, it’s probably not (uint8_t)data
but (uint8_t*)data
(note the *
) and sizeof(data)
.
Hi,
I was looking into this issue a bit. Generally, if you want to send a uint8
unsigned 8-bit integer type, you have to import the ctypes
package. You then have to wrap the value via the following method:
test_var = ctypes.c_uint8(178) # assuming you want to send a value of 178
if you want to get the value of the variable test_var
, you obtain it via:
print(test_var.value) # you have to use the `.value` keyword otherwise you get the following result:
c_ubyte(178)
As @FelixLeg stated, you might be able to make use of the struc
library to send binary data (i.e., byte streams).
When you itemize it in the pack
method, you will have to include the .value
along with the variable name and not just the variable name as is done with the other variables. However, you can use the i
designator as the variable type. You can also use the i
type at the receiver end (i.e., unpack
method).
For example, at the sender (client) side, you include it as:
import ctypes
# ... not listing other packages for simplity
# Data you wish to send as an example:
first_name = 'Paul'
last_name = 'Bunyan'
age = 31
gender = 'm'
occupation = 'lumberjack'
weight = ctypes.c_uint8(178) # no decimal places for simplicity
data = pack('10s 10s i s 15s i', first_name.encode(), last_name.encode(),
age, gender.encode(), occupation.encode(), weight.value)
… and at the receiver (server) end, you set it up as:
first_name, last_name, age, gender, occupation, weight = unpack("10s 10s i s 15s i", data)
Also note that because it is uint8
type, the highest number that you can send is 255
. Anything above this will be truncated. For example, if you attempt to send:
weight = ctypes.c_uint8(278)
what will be sent is: 22
I feel we’re still missing details of your software stack.
You can just write bytes to your open serial port from Python.
If you need to serialise various larger things like floats you need to:
- decide how they are to be serialised eg straight binary or some decimal representation?
- serialise the relevant values and write the resulting bytes
Or, of course, the reverse if you’re reading.
There’s no magic here. Your C++ code is either more complex than
you’ve suggested, or have a library with various of the above decisions
already made for you.
Please show us some of the working C++ code you are trying to reproduce.
If you’re writing raw binary data the struct
module’s pack
functions
provide ways to serialise many basic types like floats and various
string packings. Don’t forget to ensure you’re using the same endianness
at both ends of your serial link