I need some help interpreting a formula. This is from the documentation of a beacon I am experimenting with. I have written it in Swift but I can't get it to work. No matter the values the temperature variable ends up as 0.
From documentation:
*The major ID broadcasts the most significant 8 bits of the humidity and the most significant 8 bits of the temperature, and the
minor ID broadcasts the next 2 bits of temperature (for a total of the 10 most significant bits) and the 14 least significant bits
of the minor ID as the really Minor configured by user.
So the humidity is 8 bits in total, and the temperature is 10 bits in total.
Example:
So the humidity:
uint16_t Humidity = Major(As Hex value) & 0xFF00;
The temperature:
uint16_t temperature = ((Major(As Hex value) & 0x00FF) << 8 ) & ((Minor(As Hex value) &
0xC000) >> 8);
The really Minor:
uint16_t Real Minor = Minor(As Hex value) & 0x03FF;
This is what I came up with and it seems correct but the result from the last bitwise AND returns 0*
let majorAnd = UInt16(beacon.major) & 0x00FF
let majorShift = majorAnd << 8
let minorAnd = UInt16(beacon.minor) & 0xC000
let minorShift = minorAnd >> 8
let temperatureResult = majorShift & minorShift
Your problem is here:
let temperatureResult = majorShift & minorShift
replace it with:
let temperatureResult = majorShift | minorShift
Bitwise AND & is only going to give a result when there are bits in common between the two operands. In your case, they are mutually exclusive, You should combine them with bitwise OR |.
There is also a problem with the way you are shifting the values. Here is the corrected solution:
let majorAnd = UInt16(beacon.major) & 0x00FF
let majorShift = majorAnd << 2 // make space for the last 2 bits
let minorAnd = UInt16(beacon.minor) & 0xC000
let minorShift = minorAnd >> 14 // shift off the unwanted 14 bits
let temperatureResult = majorShift | minorShift
You'll need to shift your humidity as well:
let humidity = UInt16(beacon.major) & 0xFF00 >> 8
In the two shift right >> cases above, as a shortcut, you can skip the masking because those bits are being tossed anyway:
let minorShift = UInt16(beacon.minor) >> 14
let humidity = UInt16(beacon.major) >> 8
Related
I am new to flutter and I am working on an app that reads data from a BLE beacon. I have scanned the device and got the manufacturer data as {256:[0,0,0,16,1,57,33,18,0,0,154,10,0,0,94,0]}
the device manufacturer told me to device data like :
KCBAdvDataManufacturerData = <.. .. .. .. .. .. .. .. be 21 01 00 50 08 00 00 5e ..>
The UUID - kCBAdvDataManufacturerData packet contains the sensor data as shown below:
Byte index 8 – 11 = Pressure 32bit value
Byte index 12 – 15 = Temperature 32bit value
Byte index 16 = Battery level in percentage
I am totally not getting any idea that in Dart how can I achieve it from
{256:[0,0,0,16,1,57,33,18,0,0,154,10,0,0,94,0]}
to
Byte index 8 – 11 = Pressure 32bit value
Byte index 12 – 15 = Temperature 32bit value
Byte index 16 = Battery level in percentage
and then
in a human-understandable form
here temperature is in C pressure in PSI and battery is in %.
There is a list of bytes so you can get sublists from that list with https://api.dart.dev/stable/2.9.1/dart-core/List/sublist.html
That sublist can be converted from 4 bytes into a signed integer for the pressure and temperature values:
Convert 4 byte into a signed integer
I am not sure the index values you have been given look quite right. I am assuming the data is in little endian format so my assumption on the data is:
Pressure = [33,18,0,0] = 4641 (Are you expecting a value of about 46.41psi?)
Temperature = [154,10,0,0] = 2714 (Are you expecting a value of about 27.14c?)
Battery = [94] = 94 (Are you expecting a value of 94%?)
This might be done like the following:
import 'dart:typed_data';
var manufacturerData = Uint8List.fromList([0,0,0,16,1,57,33,18,0,0,154,10,0,0,94,0]);
var pressure = ByteData.sublistView(manufacturerData, 6, 10);
var temperature = ByteData.sublistView(manufacturerData, 10, 14);
var battery = ByteData.sublistView(manufacturerData, 14, 15);
main() {
print(pressure.getUint32(0, Endian.little));
print(temperature.getUint32(0, Endian.little));
print(battery.getUint8(0));
}
Gives me the output:
4641
2714
94
If we have a given number, say 9 (binary representation is 1001). How can we most efficiently get it's inverse 6 (binary representation is 0110)? i.e replacing 0 with 1 and 1 with 0.
I have written a code of order O(1) complexity? But can there be a better way? Does Swift provide an elegant way of handling this?
Note negate function ~9 results in -10. This is not what I am seeking.
func inverse(of givenNumber: Int) -> Int // eg. 9
{
let binaryRepresentation = String(givenNumber, radix: 2) // "1001"
let binaryRepresentationLength = binaryRepresentation.count // 4
let maxValueInLength = (1 << binaryRepresentationLength) - 1 // 15, i.e., 1111
let answer = givenNumber ^ maxValueInLength // 6, i.e., 0110
return answer
}
Edit 1: givenNumber > 0
For positive numbers you can use the following:
func intInverse<T: FixedWidthInteger>(of givenNumber: T) -> T
{
assert(!T.isSigned || givenNumber & (T(1) << (givenNumber.bitWidth - 1)) == 0)
let binaryRepresentationLength = givenNumber.bitWidth - givenNumber.leadingZeroBitCount
let maxValueInLength = givenNumber.leadingZeroBitCount > 0 ? (~(~T(0) << binaryRepresentationLength)) : ~0
let answer = givenNumber ^ maxValueInLength
return answer
}
Which is identical to your algorithm but doesn't require stringifying the number. It doesn't work for negative numbers, but then neither does your algorithm because your algorithm sticks a - on the front of the number.
Probably the easiest way to extend this to cover negative numbers is to invert all the bits to get the binaryRepresentationLength
EDIT
I changed the way the exclusive or mask is created because the old one crashed for unsigned values with the top bit set and for signed values with the second highest bit set.
The code becomes much simpler using the property binade of a floating-point value.
func inverse(of givenNumber: Int) -> Int // eg. 9
{
let maxValueInLength = Int((Double(givenNumber).binade * 2) - 1) // 15, i.e., 1111
let answer = givenNumber ^ maxValueInLength // 6, i.e., 0110
return answer
}
I need to find the value (or position) of the most significant bit (MSB) of an integer in Swift.
Eg:
Input number: 9
Input as binary: 1001
MS value as binary: 1000 -> (which is 8 in decimal)
MS position as decimal: 3 (because 1<<3 == 1000)
Many processors (Intel, AMD, ARM) have instructions for this. In c, these are exposed. Are these instructions similarly available in Swift through a library function, or would I need to implement some bit twiddling?
The value is more useful in my case.
If a position is returned, then the value can be easily derived by a single shift.
Conversely, computing position from value is not so easy unless a fast Hamming Weight / pop count function is available.
You can use the flsl() function ("find last set bit, long"):
let x = 9
let p = flsl(x)
print(p) // 4
The result is 4 because flsl() and the related functions number the bits starting at 1, the least significant bit.
On Intel platforms you can use the _bit_scan_reverse intrinsic,
in my test in a macOS application this translated to a BSR
instruction.
import _Builtin_intrinsics.intel
let x: Int32 = 9
let p = _bit_scan_reverse(x)
print(p) // 3
You can use the the properties leadingZeroBitCount and trailingZeroBitCount to find the Most Significant Bit and Least Significant Bit.
For example,
let i: Int = 95
let lsb = i.trailingZeroBitCount
let msb = Int.bitWidth - 1 - i.leadingZeroBitCount
print("i: \(i) = \(String(i, radix: 2))") // i: 95 = 1011111
print("lsb: \(lsb) = \(String(1 << lsb, radix: 2))") // lsb: 0 = 1
print("msb: \(msb) = \(String(1 << msb, radix: 2))") // msb: 6 = 1000000
If you look at the disassembly(ARM Mac) in LLDB for the Least Significant Bit code, it uses a single instruction, clz, to count the zeroed bits. (ARM Reference)
** 15 let lsb = i.trailingZeroBitCount
0x100ed947c <+188>: rbit x9, x8
0x100ed9480 <+192>: clz x9, x9
0x100ed9484 <+196>: mov x10, x9
0x100ed9488 <+200>: str x10, [sp, #0x2d8]
Pretty basic question here:
I'm currently trying to control a sensortag 2.0 via Swift 3.0.
I'm trying to simultaneously turn on the acc, gyro, and magnetometer.
According to Texas Instruments documentation, the following applies for the IMU:
Axis enable bits:gyro-z=0,gyro-y,gyro-x,acc-z=3,acc-y,acc-x,mag=6 Range: bit 8,9
I have written "0x023F" in the following manner, which turns on the gyro and the accelerometer with great success.
let value = OperationDataHolder(data:[0x023F])
var parameter = 0x023F
let data = NSData(bytes: ¶meter, length: 2)
self.sensorTagPeripheral.writeValue(data as Data, for: thisCharacteristic, type: CBCharacteristicWriteType.withResponse)
However, I'm not able to figure out the value to write to turn turn on all 3 units simultaneously. Would someone be able to provide me with this value?
Thanks!
When you convert the current value you are using (0x023F) to binary, you get 0b1000111111. Each of the bits represents the on/off (on=1/off=0) state of a given sensor component.
If you read the binary number from right to left, and map each bit by referencing the table below, you will see that the gyro z/y/x and accelerometer z/y/x are all enabled. If you want to enable the magnetometer, simply change 'bit 6' to a '1' and convert that binary number to a hexadecimal number.
So, Google says: 0b1001111111 is 0x027F in hexadecimal
Mapping:
bit 0 => gyro z-axis
bit 1 => gyro y-axis
bit 2 => gyro x-axis
bit 3 => acc z-axis
bit 4 => acc y-axis
bit 5 => acc x-axis
bit 6 => mag (enables all axes)
bit 7 => Wake-on-motion enable
bits 8 & 9 => Accelerometer range
bits 10-15 => not used
For more info about the mapping (i.e. what bits 8 & 9 do), see the Sensor Tag Wiki Page
Building on peters answer, the swifty way to do this is with an option set, which is admittedly more work up front, but much more readable than hex:
struct SensorOptions: OptionSet {
let rawValue: Int32
static let gyroZ = SensorOptions(rawValue: 1 << 0)
static let gyroY = SensorOptions(rawValue: 1 << 1)
static let gyroX = SensorOptions(rawValue: 1 << 2)
static let accZ = SensorOptions(rawValue: 1 << 3)
static let accY = SensorOptions(rawValue: 1 << 4)
static let accX = SensorOptions(rawValue: 1 << 5)
static let mag = SensorOptions(rawValue: 1 << 6)
static let wakeOnMotion = SensorOptions(rawValue: 1 << 7)
static let accelerometerRange1 = SensorOptions(rawValue: 1 << 8)
static let accelerometerRange2 = SensorOptions(rawValue: 1 << 9)
}
let options: SensorOptions = [.gyroZ, .gyroY, .gyroX, .accZ, .accY, .accX, .mag, .accelerometerRange2]
var parameter = options.rawValue
let data = NSData(bytes: ¶meter, length: 2)
self.sensorTagPeripheral.writeValue(data as Data, for: thisCharacteristic, type: CBCharacteristicWriteType.withResponse)
Also if you don't like the option set swift has binary literals so you can write var parameter = 0b1001111111 in your code instead of 0x027F
I've got an 16bit bitmap image with each colour represented as a single short (2 bytes), I need to display this in a 32bit bitmap context. How can I convert a 2 byte colour to a 4 byte colour in C++?
The input format contains each colour in a single short (2 bytes).
The output format is 32bit RGB. This means each pixel has 3 bytes I believe?
I need to convert the short value into RGB colours.
Excuse my lack of knowledge of colours, this is my first adventure into the world of graphics programming.
Normally a 16-bit pixel is 5 bits of red, 6 bits of green, and 5 bits of blue data. The minimum-error solution (that is, for which the output color is guaranteed to be as close a match to the input colour) is:
red8bit = (red5bit << 3) | (red5bit >> 2);
green8bit = (green6bit << 2) | (green6bit >> 4);
blue8bit = (blue5bit << 3) | (blue5bit >> 2);
To see why this solution works, let's look at at a red pixel. Our 5-bit red is some fraction fivebit/31. We want to translate that into a new fraction eightbit/255. Some simple arithmetic:
fivebit eightbit
------- = --------
31 255
Yields:
eightbit = fivebit * 8.226
Or closely (note the squiggly ≈):
eightbit ≈ (fivebit * 8) + (fivebit * 0.25)
That operation is a multiply by 8 and a divide by 4. Owch - both operations that might take forever on your hardware. Lucky thing they're both powers of two and can be converted to shift operations:
eightbit = (fivebit << 3) | (fivebit >> 2);
The same steps work for green, which has six bits per pixel, but you get an accordingly different answer, of course! The quick way to remember the solution is that you're taking the top bits off of the "short" pixel and adding them on at the bottom to make the "long" pixel. This method works equally well for any data set you need to map up into a higher resolution space. A couple of quick examples:
five bit space eight bit space error
00000 00000000 0%
11111 11111111 0%
10101 10101010 0.02%
00111 00111001 -1.01%
Common formats include BGR0,
RGB0, 0RGB, 0BGR. In the code below I have assumed 0RGB. Changing this
is easy, just modify the shift amounts in the last line.
unsigned long rgb16_to_rgb32(unsigned short a)
{
/* 1. Extract the red, green and blue values */
/* from rrrr rggg gggb bbbb */
unsigned long r = (a & 0xF800) >11;
unsigned long g = (a & 0x07E0) >5;
unsigned long b = (a & 0x001F);
/* 2. Convert them to 0-255 range:
There is more than one way. You can just shift them left:
to 00000000 rrrrr000 gggggg00 bbbbb000
r <<= 3;
g <<= 2;
b <<= 3;
But that means your image will be slightly dark and
off-colour as white 0xFFFF will convert to F8,FC,F8
So instead you can scale by multiply and divide: */
r = r * 255 / 31;
g = g * 255 / 63;
b = b * 255 / 31;
/* This ensures 31/31 converts to 255/255 */
/* 3. Construct your 32-bit format (this is 0RGB): */
return (r << 16) | (g << 8) | b;
/* Or for BGR0:
return (r << 8) | (g << 16) | (b << 24);
*/
}
Multiply the three (four, when you have an alpha layer) values by 16 - that's it :)
You have a 16-bit color and want to make it a 32-bit color. This gives you four times four bits, which you want to convert to four times eight bits. You're adding four bits, but you should add them to the right side of the values. To do this, shift them by four bits (multiply by 16). Additionally you could compensate a bit for inaccuracy by adding 8 (you're adding 4 bits, which has the value of 0-15, and you can take the average of 8 to compensate)
Update This only applies to colors that use 4 bits for each channel and have an alpha channel.
There some questions about the model like is it HSV, RGB?
If you wanna ready, fire, aim I'd try this first.
#include <stdint.h>
uint32_t convert(uint16_t _pixel)
{
uint32_t pixel;
pixel = (uint32_t)_pixel;
return ((pixel & 0xF000) << 16)
| ((pixel & 0x0F00) << 12)
| ((pixel & 0x00F0) << 8)
| ((pixel & 0x000F) << 4);
}
This maps 0xRGBA -> 0xRRGGBBAA, or possibly 0xHSVA -> 0xHHSSVVAA, but it won't do 0xHSVA -> 0xRRGGBBAA.
I'm here long after the fight, but I actually had the same problem with ARGB color instead, and none of the answers are truly right: Keep in mind that this answer gives a response for a slightly different situation where we want to do this conversion:
AAAARRRRGGGGBBBB >>= AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB
If you want to keep the same ratio of your color, you simply have to do a cross-multiplication: You want to convert a value x between 0 and 15 to a value between 0 and 255: therefore you want: y = 255 * x / 15.
However, 255 = 15 * 17, which itself, is 16 + 1: you now have y = 16 * x + x
Which is actually the same as doing a for bits shift to the left and then adding the value again (or more visually, duplicating the value: 0b1101 becomes 0b11011101).
Now that you have this, you can compute your whole number by doing:
a = v & 0b1111000000000000
r = v & 0b111100000000
g = v & 0b11110000
b = v & 0b1111
return b | b << 4 | g << 4 | g << 8 | r << 8 | r << 12 | a << 12 | a << 16
Moreover, as the lower bits wont have much effect on the final color and if exactitude isnt necessary, you can gain some performances by simply multiplying each component by 16:
return b << 4 | g << 8 | r << 12 | a << 16
(All the left shifts values are strange because we did not bother doing a right shift before)