I have the RedBearLab BLE shield connected to Arduino UNO R3. I can connect to it using gatttool from a Rasp-Pi (attached CSR4.0 dongle). I have some sensors (FSR) connected to the analog pin and LED connected to digital pin in Arduino. My goal is to read/write to anything that is connected to the Arduino through BLE.
As a sample, I was looking into this link. It seems I need to know the handle of the sensor, config register # etc. to read/write.But I am not sure how to find the handle/uuid related to the sensor that is attached to the shield.
For example I see below.
[xx:xx:xx:xx:xx:xx][LE]> char-desc
handle: 0x0001, uuid: 2800
handle: 0x0002, uuid: 2803
handle: 0x0003, uuid: 2a00
handle: 0x0004, uuid: 2803
handle: 0x0005, uuid: 2a01
handle: 0x0006, uuid: 2803
handle: 0x0007, uuid: 2a04
handle: 0x0008, uuid: 2800
handle: 0x0009, uuid: 2800
handle: 0x000a, uuid: 2803
handle: 0x000b, uuid: 713d0003-503e-4c75-ba94-3148f18d941e
handle: 0x000c, uuid: 2803
handle: 0x000d, uuid: 713d0002-503e-4c75-ba94-3148f18d941e
handle: 0x000e, uuid: 2902
handle: 0x000f, uuid: 2800
handle: 0x0010, uuid: 2803
handle: 0x0011, uuid: 2a27
Discover descriptors finished: No attribute found within the given range
[xx:xx:xx:xx:xx:xx][LE]> char-read-hnd 0x0001
Characteristic value/descriptor: 00 18
[xx:xx:xx:xx:xx:xx][LE]> char-read-hnd 0x000b
Error: Characteristic value/descriptor read failed: Attribute can't be read
How do I know which of them is the FSR I have attached to the shield?
update
I am using RedBearLab example - simplecontrol
So Arduino and iOS/Android code both are there. My goal is to understand from gatttool's perspective so I can develop something similar (of iOS/Android) in Java running at Raspberry Pi.
From the code, I can figure out which address to write. For example - to turn on the LED attached to the digital out pin, below works
char-write-cmd 0x000b 010100
Similarly, to turn on the sensor reading capability, I need to write below
char-write-cmd 0x000b A00100
I know this works. I see expected output in the Arduino serial monitor. I am pretty sure it is reading the sensor but I can't see that in the RaspPi prompt. I think I need to enable broadcast reading capability at RaspPi end.
Any suggestion?
well, to beging working with BLE, you have to understand how the whole GATT stuff is working. Basically, you need to have some code on your arduino that sets up a profile in the nRF8001 component on your shield that defines "pipes" which is the link between a characteristic exposed by the radio (and seen using the gatttool) and a function from which you can read data or to which you can send data.
To modify and work on gatt profiles, and define those pipes, you need to use the nrfgo tool distributed by Nordic. It's windows only, but it works perfectly fine using wine on OSX or linux (I do it every day).
There you can load a profile and modify it or create a new one, it's up to you. I'd also advice you to look at the nordic examples in their devzone on how to setup a profile for nrf8001 + Arduino, those example are pretty clear.
Then once you've made all your characteristics, you can only read/write the characteristics you're handling. Having a characteristic available does not mean it can be read/written to, you may need to subscribe to it or it may always return an error. Remember that most of the characteristics you list are characteristics used by the gatt for having the whole gatt system work and usually is hidden by libraries abstracting the BLE stuff.
Related
I am stuck with a project of a BLE Keyboard to PS2 adapter with the ESP32 microcontroller. For the BLE part, I use the NimBLE library. My bluetooth keyboard is a Microsoft Surface Ergonomic Keyboard. I have no previous experience with BLE.
These are the services and their characteristics of the bluetooth keyboard:
0x1800: Generic Access
Characteristics:
0x2a00: Device Name
0x2a01: Appearance
0x2a04: Peripherial Preferred Connection Parameters
0x1801: Generic Attribute
0x180a: Device Information
Characteristics:
0x2a29: Manifacturer Name
0x2a50: PNP Id
0x180f: Battery Service
Characteristic:
0x2a19: Battery Level
0x1812: HID Service
Characteristics:
0x2a4e: Protocol Mode
0x2a4d: Report
0x2a4b: Report Map
0x2a22: Boot Keyboard Input Report
0x2a32: Boot Keyboard Output Report
0x2a4a: HID Information
0x2a4c: HID Control Point
After I find it and pair it by entering the PIN, I can successfully read the battery level and receive notifications when it changes, so I got the pairing, notification registering and reading values from characteristics alright.
Now I want obviously to read key presses. I take the "Report Map" characteristic of the HID service and read its values that describe the report. Meaning of the values here in section E.6.
0x05, 0x01 -> Usage Page (Generic Desktop)
0x09, 0x06 -> Usage (Keyboard)
0xA1, 0x01 -> Collection (Application)
0x85, 0x01 -> ???
0x15 -> Logical Minimum? (0)
I don't know what to do with this information. I assume I will need this later to interpret the incoming reports of key presses. However, I don't know how to receive them.
I continue with the "Report" characteristic because I assume this is the place where key presses come in?
I read the characteristic's value: It has the handle 0x0047 and the value 0x78. I register for notifications.
Then I get the same characteristic a second time, now it has the handle 0x0016, same value and a 2902 descriptor with value 1 (meaning it is in report mode and not in boot mode). I register again for notifications, but I receive no notification when I press keys.
How do I read reports from the device? They obviously do not come as notifications.
Screen grab from WireShark showing traffic when problem occurs
Short question - Referring to WireShark image, What is causing Master to send LL_CHANNEL_MAP_IND and why is it taking so long?
We are working on a hardware/software project that is utilizing the TI WL18xx as a Bluetooth controller. One of the main functions of this product is to communicate with our sensor hardware over a Bluetooth Low Energy connection. We have encountered an issue that we have had difficulty pinpointing, but feel may reside in the TI WL18xx hardware/firmware. Intermittently, after a second Bluetooth Low Energy device is connected, the response times from writing and notification of one of the characteristics on one of the connected devices becomes very long.
Details
The host product device is running our own embedded Linux image on a TI AM4376x processor. The kernel is 4.14.79 and our communication stack sits on top of Bluez5. The wifi/bluetooth chip is the Jorjin WG7831-BO, running TIInit_11.8.32.bts firmware version 4.5. It is based on the TI WL1831. The sensor devices that we connect to are our own and we use a custom command protocol which uses two characteristics to perform command handshakes. These devices work very well on a number of other platforms, including Mac, Windows, Linux, Chrome, etc.
The workflow that is causing problems is this;
A user space application allows the user to discover and connect to our sensor devices over BLE, one device at a time.
The initial connection requires a flurry of command/response type communication over the aforementioned BLE characteristics.
Once connected, the traffic is reduced significantly to occasional notifications of new measurements, and occasional command/response exchanges triggered by the user.
A single device always seems stable and performant.
When the user connects to a second device, the initial connection proceeds as expected.
However, once the second device's connection process completes, we start to see that the command/response response times become hundreds of times longer on the initially connected device.
The second device communication continues at expected speeds.
This problem only occurs with the first device about 30% of the time we follow this workflow.
Traces
Here is a short snippet of the problem that is formed from a trace log that is a mix of our library debug and btmon traces.
Everything seems fine until line 4102, at which we see the following:
ACL Data TX: Handle 1025 flags 0x00 dlen 22 #1081 [hci0] 00:12:48.654867
ATT: Write Command (0x52) len 17
Handle: 0x0014
Data: 580fd8c71bff00204e000000000000
D2PIO_SDK: GMBLNGIBlobSource.cpp(1532) : Blob cmd sent: 1bh to GDX-FOR 07100117; length = 15; rolling counter = 216; timestamp = 258104ms .
HCI Event: Number of Completed Packets (0x13) plen 5 #1082 [hci0] 00:12:49.387892
Num handles: 1
Handle: 1025
Count: 1
ACL Data RX: Handle 1025 flags 0x02 dlen 23 #1083 [hci0] 00:12:51.801225
ATT: Handle Value Notification (0x1b) len 18
Handle: 0x0016
Data: 9810272f1bd8ff00204e000000000000
D2PIO_SDK: GMBLNGIBlobSource.cpp(1745) : GetNextResponse(GDX-FOR 07100117) returns 1bh cmd blob after 3139=(261263-258124) milliseconds.
The elapsed time reported by GetNextResponse() for most cmds should be < 30 milliseconds. Response times were short when we opened and sent a bunch of cmds to device A.
The response times remained short when we opened and sent a bunch of cmds to device B. But on the first subsequent cmd sent to device A, the response time is more than 3 seconds!
Note that a Bluetooth radio can only do one thing at a time. Receive or transmit. On one single frequency. If you have two connections and two connection events happen at the same time, the firmware must decide which one to prioritize, and which one to skip. Maybe the firmware isn't smart enough to handle your specific case. Try with other connection parameters to see if something gets better. You can also try another Bluetooth dongle from a different manufacturer.
I am trying to read temperature from this little sensor https://www.aliexpress.com/item/temperature-sensor-and-humidity-sensor-HTS221/32953862359.html?spm=a2g0s.9042311.0.0.e3534c4dT9GRz3
There are 4 GattServices available
GattService 00001800-0000-1000-8000-00805f9b34fb - Generic Access
here are characteristics:
00002a00-0000-1000-8000-00805f9b34fb Device Name
00002a01-0000-1000-8000-00805f9b34fb Appearance
00002a04-0000-1000-8000-00805f9b34fb Peripheral Preferred Connection Parameters
GattService 00001801-0000-1000-8000-00805f9b34fb - Generic Attribute
no characteristics
GattService 0000180a-0000-1000-8000-00805f9b34fb - Device Information
here is characteristic:
00002a29-0000-1000-8000-00805f9b34fb Manufacturer Name String
GattService 6e400000-b5a3-f393-e0a9-e50e24dcca9e - ???
It looks that HTS221 is not sending data by default, what should I do to be able to read the temperature ?
I have a bluetooth HM-10 configured in central mode. I have successfully connected it to another bluetooth device (a hexiwear bluetooth wearable). The problem now is that the hexiwear requires me to provide a 6 digit pin before it will bond with my HM-10.
Would anyone know the AT command that I could use to send the 6 digit pin from the HM-10 to the hexiwear?
Thank you.
Default code of HM 10 is 000000 , you can change it with At+PASS{new_pin} command. However if you match the two pins (the HM10 pin and the hexiwear pin) the devices will connect together! So put 000000 in your peripheral device (hexiwear). Else, if you can't put the pin in the hexiwear, change the default pin on the HM10.
I'm building a USB HID device using Arduino Leonardo mini clone, based on ATmega32u4. That particular IC has got a USB controller built in, and turning it in to a HID device is simple. You just need to include Keyboard.h and then use Keyboard.print...
Where can I set/define the name of the device that is shown, when that Arduino is connected to a PC, because at the moment it is named Arduino Leonardo.
The default automated name for tty is usbmodemHIDP1.
In system preferences, I can see:
ID product: 0x8036
ID vendor: 0x2341
Wersion: 1.00
Serial number: HIDPC
Speed: do 12 Mb/sek.
Vendor: Arduino LLC
ID location: 0x14200000 / 16
So where in Arduino is file Keyboard.h? Can I change that name, or ID's?
Is it possible?
Because in my opinion it should be, but I just can't find the right place, and I do not have experience with Arduino AVR as I was working with Microchips Mplab X before for different ICs ;).
The "iProduct" string sent by the board on enumeration tells the operating system to give it the human-readable name. The value of that string is set near the top of USBCore.cpp in hardware/arduino/cores/arduino/. It's a Unicode string, so we need looking for 'L', 'e', 'o', 'n' [...], not "Leonardo". The string used depends on the PID number of the device (also sent during enumeration) which is given in boards.txt.
For distributing own custom hardware based on the Leonardo, there is a need to provide your own VID.
Also there can be used alternative firmware.
The Arduino '32U4 bootloader, Caterina, can be found under hardware/arduino/bootloaders/caterina. It requires LUFA in order to build.