Reputation: 21
Ok this has been bugging me for awhile now!
I have a Tri-Metric battery monitor which serial outputs data to an Arduino, where I convert and scale the output to be sent over Modbus TCP to my Raspberry Pi where it is then descaled and added to a mysql table. I,m currently using php to do this but want to move it to python, feeling that it would be more efficient than PHP.
The data say the amphours used by the system which goes negative when the battery is discharging after the sun goes down.
I scale the data by multiplying by 10 and converting to an unsigned 16 bit integer to meet Modbus specifications.
I need to know how i can change this unsigned 16 bit integer back to a signed floating point number to add to my database.
for example this is the raw data from Modbus 65365 the unscaled equivalent should be -17.2 AmpHrs
.
Any assistance with this would be much appreciated.
This is how i convert it On the Arduino
cmdData[k] = '\0'; // add termination NULL char for float conversion:
cmdFloat = atof(cmdData); // convert char array upto NULL to float:
cmdValue = int(cmdFloat * 10); // convert to int16_t and scale up by 10:
amp_hours = (uint16_t)cmdValue;
Serial.print("Amp Hours: ");
}
Serial.println(cmdFloat); //serial print the float value
}
In python i have tried
amphours = usamphours/10 if (amphours & 0x80000000): amphours = -0x100000000 + amps
Also tried
amphours = amphours&0xffffffff
non of which works
Upvotes: 2
Views: 4453
Reputation: 308520
Converting from an unsigned integer to a signed integer of a specific size is easy in Python, if a bit tricky:
signed_value = unsigned_value if unsigned_value < (1 << bitsize-1) else unsigned_value - (1 << bitsize)
Once you have that, just divide by 10:
float_value = signed_value / 10.0
Upvotes: 3
Reputation: 1487
Dealing with signed/unsigned integer, or converting between 16-bit/32-bit/64-bit integers in Python is a nightmare.
You can use bitstring module to convert between these types. For example:
a = bitstring.BitArray(uint=65365, length=32)
print a.float
9.159587412059167e-41
Upvotes: 1
Reputation: 23216
This will depend entirely on how you are "converting to an unsigned 16 bit integer".
If this is being done as, for example, a raw cast from float to int (perhaps via a union), then you can decode this buffer within python using the struct
module. Pay attention to endianness.
Upvotes: 0