I have a BLE app running on nrf51822 on Zephyr. Application is reading data from humidity and temperature sensor and exposes environmental sensing characteristic.
Main exposed value is temperature (uuid:2A6E).
I have trouble reading this data via Bluez on linux. With nrfConnect app everything works no problem - I connect to the device and can see temperature reading - somewhere
between 20 and 26 degrees (assigned to said uuid).
Via Bluez I can connect and read characteristic handle but the values does not make any sense to me. Here is my workflow:
$ sudo gatttool -t random -b <ADDR> -I
$ [<ADDR>][LE]> connect
$ Attempting to connect to <ADDR>
$ Connection successful
$ [<ADDR>][LE]> char-desc
# there are a lot of other chars here, I list the one that interests me
$ handle: 0x0017, uuid: 00002a6e-0000-1000-8000-00805f9b34fb
$ [<ADDR>][LE]> char-read-hnd 0x17
$ Characteristic value/descriptor: 2e 09
So I get this value, and I cannot convert this in any way I know of to something that would make sense. I am familiar with this document:
temperature xml
but I cannot figure out how this might help me. Somehow Nordic's app can make sense out of it, and I would like to do that too.
The temperature measurement follows the following rules:
it’s in little endian format so you first need to switch it to read as 0x092e
you convert that to decimal and you get (9x256+2x16+14) = 2350
then the value has an implied decimal exponent of -2, which means you take the value and divide by 100
This means the value read in this case is 23.50 Celsius
Related
I tried to provision a device via Bluez and mesh-cfgclient on my Raspberry Pi.
Bluez: 5.65
Raspberry Pi: 3B+
First I am looking for provisionable devices and get:
Scan result:
rssi = -38
UUID = DDDD00000000000000000000000000DD
OOB = 0000
URI Hash = 00000000
If I am stating the provision process with:
provision dddd00000000000000000000000000dd
I get the error:
Failed to generate UUID array from dddd00000000000000000000000000dd
If I am trying this:
provision dddd0000-0000-0000-0000-0000000000dd
I get:
Requires UUID
So I don't know which UUID mesh-cfgclient like to get from me. Do someone know what I missed here.
Thanks for your help.
I'm encountering this as well. I don't know if it's a new issue because this is my first foray into BLE mesh...
My findings so far has led me to the UUID needs to comply with RFC-4122.
This is my conclusion based on downloading the bluez source (specifically 5.65), along with the ell source (specifically 0.55) and walking through add_node_setup, which led me to l_util_from_hexstring, which seemed fine.
It was l_uuid_is_valid that doesn't like the format...
It's expecting the variant (==2) and version (between 1 & 5) to be included.
Mind you, when I mention those values, they are the result of bit-shifting, so variant == 0x80, and version between 0x16 and 0x80, and this is all after the UUID we are provided is converted into hexidecimal.
I haven't done it yet, but you can probably use a uuid generator online or in linux (uuidgen).
I will say that at the moment, I don't know why ell is expecting variant to == 2.
Looking at the RFC, section 4.1.1, I'm not seeing any bit combination that equates to 2.
Actually, looking at the wikipedia for it, I see the UUID number 2 doesn't equate to the bit combination, but rather the zero-based position of the list, which is 110 ("Reserved, Microsoft Corporation backward compatiblity").
If we were to alter your dddd00000000000000000000000000dd, I think it might look like dddd00000000 40 00 80 000000000000dd.
I chose 0x40 for version 4, and 0x80 for the variant #2 mentioned earlier (bit-shifted).
I'm making a project with Esp32 whroom, so I bought the yj-16009 iBeacon DataSheet and I'm trying to get it to work as wireless Bluetooth proximity sensor like in this Video
I used the this code from the video and the esp32 is monitoring and showing BLT scanning results like this the results shown are after I turned off any BLT device around so first I don't understand what it is reading, and second after I turn on the iBeacon the results remain with the same range of numbers no matter if I get the iBeacon closer or farther, therefor I came to the conclusion that it doesn't recognize the iBeacon sensor for some reason.
I also download an app named LightBlue which does recognize the iBeacon sensor.
My question is if anyone knows how to make the esp32 recognize the iBeacon sensor. Another thing I tried to find any information about this sensor and there is no info about it anywhere. I have read on other questions here that it might need to be programmed somehow which I don't know how to do because there is no info online. So if anyone is familiar with this kind of sensor and can help me figure how to make the ibeacon to work like the video above as a Bluetooth Proximity device it would be a blessing.
The code you reference is just scanning for any BLE advertisements (iBeacon or otherwise) and printing out the RSSI signal strength of each detection. The reason you do not see the RSSI change when you move the beacon is because the ESP32 is probably picking up non-iBeacon adverts from your phone, laptop and other Bluetooth enabled devices in the vicinity which are not moving (there are more around you than you think!)
In order to make the device detect iBeacon only (and not all the other devices) you need to change the C code to do a few more things:
Access the bytes of the advertisement payload and use them as follows:
Compare the beginning of these bytes to see if they include the iBeacon byte sequence FF 4C 00 02 15
If the above byte sequence is not in the advertising data, ignore that detection — it is not an iBeacon advert
If it does include that byte sequence, decode the next 16 bytes as the iBeacon uuid, the next two bytes as the major and the next two bytes as the minor. See my answer here: What is the iBeacon Bluetooth Profile
Print out the identifiers along with the RSSI that the code already prints.
TLDR:
Is there a way to create a hex value between 0x20 and 0x7E with 5 volts? Is there a cheap component on the market or circuit logic that can achieve this?
I'm not sure what the proper terminology for this is, but here's what I'm trying to do:
I have a bluetooth module connected to my pico via UART0 TX and UART0 RX. The use for this is a bit long to explain, but essentially, I want the bluetooth module to work without my pico attached to it. I have a device that outputs a signal, the pico reads the signal, then it tells the bluetooth module to transmit to the receiver. However, since the data to transmit isn't actually important, it makes sense to cut out the pico and simply have the bluetooth module read the signal directly then transmit.
I have the device that outputs exactly when I want, but it outputs the equivalent of 00 in hex. My computer is connected via bluetooth and can read it just fine. However, the pico, reading the input through RX, can't. I've found no way for micropython using UART to read 00 - UART.any() and UART.read() want a character, and 00 only corresponds to NULL.
So essentially, I need some way to transmit a hex value between 0x20 and 0x7E without using the raspberry pi pico. Is there some kind of component that is able to do this? In practice, the bluetooth module will be connected to 5V power with up to 5 amps.
Any idea on how to get the Pico to read 00 in hex through the RX pin is welcomed too. The purpose of this is to not need multiple Picos, since the receiver and the transmitter will be a good distance from each other.
I found the issue. The pico actually can accept 0 through the UART RX pin. The issue was me having a wire misplaced. My computer saw the 0 input which made me think the pico couldn't handle it, but in fact it was never receiving it. Thanks for the help Kotzjan. Would have been interesting to fake a value into the port though!
I've been working doing some reverse engineering to different BLE based devices and I have a weight scale where I can't find a pattern to find/decode/interpret the weight value that I can get from the android app. I was also able to get the services and characteristics of this device but did not found a SIG standard match with the UUIDs from the bluetooth site.
I'm using an nRF51 dongle to sniffing data packets between the android app and the weight scale and I can look the ble traffic, but there are several events during the communication that I can't really understand what's the relation and I can't be able to convert those values to readable weight in kg or pounds.
My target value is: 71.3kg readed from the weight scale app.
Let me show you what I get from the ble sniffer.
first I see that the master is sending notification/indication requests to the handles 0x0009(notify), 0x000c(indication) and 0x000f(notify) in each characteristic of one service.
Then I start to read notification/indications values mixed with write commands. At the end of the communication, I see some packets that I feel that they are the ones with the weight scale data and BMI.
Packets number 574, 672 and 674 in the image.
So that give us the following candidates:
1st. packet_number_574 = '000002c9070002
2nd. packet_number_672 = '420001000000005ed12059007f02c9011d01f101'
3rd. packet_number_674 = '42018c016b00070237057d001a01bc001d007c'
1st packet during the communication exchange looks more like a counter/RT/clock than a real measurement because of the data behavior, so I feel this one is not a real option.
2nd and 3rd looks more like real candidates, I have split them and convert them to decimal values and I have not found a relation, even combining bytes since this values are floating point data types. So my real question is, Am I missing something that you might see with this information? Do you know if there is a relation between this data packets and my target?
Thank you for taking your time reading me and any help could be good, thanks!
EDIT:
I have a python script that allows me to check the services and their characteristics hierarchy and some useful data like properties, their handles and descriptors.
Service 'fff0' (0000fff0-0000-1000-8000-00805f9b34fb):
Characteristic 'fff1' (0000fff1-0000-1000-8000-00805f9b34fb):
Handle: 8 (8)
Readable: False
Pro+perties: WRITE NOTIFY
Descriptor: Descriptor <Client Characteristic Configuration> (handle 0x9; uuid 00002902-0000-1000-8000-00805f9b34fb)
Characteristic 'fff2' (0000fff2-0000-1000-8000-00805f9b34fb):
Handle: 11 (b)
Readable: False
Properties: WRITE NO RESPONSE INDICATE
Descriptor: Descriptor <Client Characteristic Configuration> (handle 0xc; uuid 00002902-0000-1000-8000-00805f9b34fb)
Characteristic 'fff3' (0000fff3-0000-1000-8000-00805f9b34fb):
Handle: 14 (e)
Readable: False
Properties: NOTIFY
Descriptor: Descriptor <Client Characteristic Configuration> (handle 0xf; uuid 00002902-0000-1000-8000-00805f9b34fb)
This are the characteristics related to the notifications and indications that I see in wireshark. I think the packet number 574 (which characteristics has only a notifiy property) is more important than I think.
I solve it by myself.
This post gives me the idea to take the values (2 bytes) and multiply them by 0.1, that way I could get the weight.
In bytes I could look for my target value without decimals 713, which is in hex = 0x02c9
If we look at the packet number 574:
000002c9070002 and split it 00:00:02:c9:07:00:02
I could see that 2nd and 3rd bytes match with this pattern!
The only thing required to do is to group this bytes and multiply the decimal value 713 x 0.1 = 71.3. I made different tests and found that this pattern is constant so I feel is accurate for my solution. Hope this could help someone in the future.
I am using beaglebone to access digital input from specific pin using sysfs interface. And I can change the output states but not the input :(. What I did is, I have two pins pinA and pinB. pinA I made it output and pinB I made input. Connected pinA to pinB. Configured pinA as output pin by sending out to direction attribute in sysfs and pinB as input by passing in. And I changed value of PinA to 1 and it is giving 1 as output (I tested using LED). But when I read the value of PinB it is giving 0 only, even I pass 0 to value of pinA. what may be the reason ?
Thank you :)
As I understood, the steps you followed:
echo 7 > /sys/kernel/debug/omap_mux/gpmc_ad6
echo 38 > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio38/direction
cat /sys/class/gpio/gpio38/value
I also did the same mistake and it took me hours, but the answer was simple: The first line starting with "echo 7" is the problem. Look at the muxing bits:
Bit 5: 1 - Input, 0 - Output
Bit 4: 1 - Pull up, 0 - Pull down
Bit 3: 1 - Pull disabled, 0 - Pull enabled
Bit 2 \
Bit 1 |- Mode
Bit 0 /
You were entering echo 7 which is --> 0 0 0111 and it means: bit 0,1 and 2 is 1, so the mode is set. No problem. However you just forgot to set whether it's an input or output. And it should be like this:
echo 0x27 > /sys/kernel/debug/omap_mux/gpmc_ad6
your bits are now: 1 0 0111 binary which is 0x27 (hex).
When you write "cat /sys/class/gpio/gpio38/value" while giving input, you can see a wonderful 1 :) I’m sure you will be very happy as much as I was :)
Also, one more thing, you are right for Analog input about 1.8V, but GPIO operates with 3.3v.
Several possible causes:
1) Did you set the IO direction of the input pin?
eg. echo "in" > /sys/class/gpio/gpioN/direction
2) (less likely) Is the GPIO pin you're using as an input multiplexed as a GPIO line and in the right direction? Most of the GPIO pins on the OMAP SoCs are multi-function. You're kernel might have set it for an alternate function.
You can check it with:
cat /sys/kernel/debug/omap_mux/board/core
Which dumps the configurations of all IO pins. The output looks like this:
OMAP4_MUX(CSI22_DY1, OMAP_PIN_INPUT | OMAP_MUX_MODE0),
/* gpio_81 */
OMAP4_MUX(CAM_SHUTTER, OMAP_PIN_OUTPUT | OMAP_MUX_MODE3),
OMAP4_MUX(CAM_STROBE, OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
/* gpio_83 */
In this case, CAM_SHUTTER is set an output, and routed as to the GPIO module (OMAP_MUX_MODE3)
[Caveat: this is from my OMAP4 board - without having the OMAP3 data sheet to hand - there will be a fair amount of similarity]
You can't change this through sysfs - instead you'll need to modify either your kernel (or possibly boot-loader if the kernel uses the configuration it set up).
In the board-file for your system - which I think in your case will be in <linux_source_root>/arch/arm/mach-omap2/board-omap3beagle.c - you'll find a initialiser for the MUX table. You will need the board's schematics, the kernel source tree and the SoC data sheet to get between the primary function name of the pin (in my example above CAM_SHUTTER) and a GPIO number.
3) I was a bit confused by even I pass 0 to value of pinA - I wonder whether you meant that? This does however point to another thing to watch for - there is the programmable pull-up or -down on each IO pin. These are set with the MUX settings. There may conceivably be an external one as well - again you'll need the schematics to be sure.
Yes. The internal pull up and down is configured in the same register as the mux-mode - so it might be that you can configure this in the same way you're setting the mux-mode. Get the AM335x TRM (for OMAP4 the chapter is called Control Module).
In terns of the kernel, look in <linux_source_root>/arch/arm/mach-omap2/mux.h where a bunch of macros are defined
As an example for use I have in my board file:
/* PIC -> OMAP4 interrupt line 2 - GPIO81 */
OMAP4_MUX(CAM_SHUTTER, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP),
and
OMAP4_MUX(GPMC_AD11, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
From memory you get a choice of either a pull-up or pull-down but can't select neither.