how to read data from the BNO085 sensor - i2c

How to read and write the data in the BNO085 sensor through I2C.
I2C interface is available sensor but no register data are available in datasheet.

It has something called a 'sensor-hub' and you can use SH2 specific commands, which are written through the I2C to configure BNO and get data. For instance, writing the following through I2C will configure BNO to stream orientation as 'ARVR-Stabilized Rotation Vector (0x28)' at 50
Hz (20us = 0x4e20).
CARGO_NO++;
START_BNO_ALGO[21] = {0x15, 0x00, 0x02, CARGO_NO, 0xFD, 0x28, 0x00, 0x00, 0x00, 0x20, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
I2C_Write(BNO085_ADDRESS, START_BNO_ALGO, 21);
Then you can simply I2C_Read the BNO at 50Hz (ideally at BNO interrupt) to get orientation. Hope this will help you to get started.
Please check the 'SH-2 Reference Manual' and the 'Sensor Hub Transport Protocol' for more details.

Related

STM32 HID Keyboard

I am trying to use and STM32F0-disco as a keyboard for a Windows PC. I'm having a problem with the characters that are being printed.
The code below waits until the onboard button is pressed then should print the three characters once.
/* USER CODE BEGIN 2 */
USBDelay = USBD_HID_GetPollingInterval(&hUsbDeviceFS);
while (HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == 0);
if (HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == 1) {
HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
buff[0] = 0x00;
buff[2] = 0x04;
buff[3] = 0x05;
buff[4] = 0x06;
USBD_HID_SendReport(&hUsbDeviceFS, buff, 8);
HAL_Delay(USBDelay);
buff[0] = 0x00;
buff[2] = 0x00;
buff[3] = 0x00;
buff[4] = 0x00;
USBD_HID_SendReport(&hUsbDeviceFS, buff, 8);
HAL_GPIO_TogglePin(LD4_GPIO_Port, LD4_Pin);
HAL_Delay(1000);
}
while (HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == 1);
/* USER CODE END 2 */
The problem I'm having is that the only the characters in the first two key positions of the buffer (which would be the third and fourth elements of the array since element one is the modifier and the second element is reserved). Also, instead of printing once, the characters print continuously without stopping.
Based on the LED's I've added for testing purposes, the characters that I want to print don't print until the second USB_SendReport, which should be sending blank characters to stop the printing.
I've made the necessary changes to usbd_hid.c and usbd_hid.h, as well as the Clock configuration and enabling USB and such. I've put my keyboard descriptor below.
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x95, 0x05, // REPORT_COUNT (5)
0x75, 0x01, // REPORT_SIZE (1)
0x05, 0x08, // USAGE_PAGE (LEDs)
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
0x29, 0x05, // USAGE_MAXIMUM (Kana)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x03, // REPORT_SIZE (3)
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
0x95, 0x06, // REPORT_COUNT (6)
0x75, 0x08, // REPORT_SIZE (8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0 // END_COLLECTION
Any ideas?
The USB HID protocol works differently than you assume. If the input report contains multiple pressed keys, the host (your Windows PC) assumes that they have been pressed at the same time. So they can be inserted in any order. And it might also be the reason the third key is not inserted.
So you need to send a separate output report for each key. And after the last report you need to send another empty one (with all 0s) to indicate the keys have been released (as you are already doing). Such an additional report is also needed between two presses of the same key.
The reason the keys are inserted continuously indicates the empty report was not received. Even though the function uses the term send (USBD_HID_SendReport()), the USB protocol works such that the host needs to pick up the input report. And since it is an USB interrupt endpoint, this only happens ever so often. If a report hasn't been picked up yet, USBD_HID_SendReport() does nothing. It not even returns an error.
While querying to polling interval (USBD_HID_GetPollingInterval()) looks ok at first, it's the polling interval declared in the USB endpoint descriptor. However, Windows only supports a few interval values and rounds up to the next supported value. So you have to increase the value.

Is there a way to print the APDU command generated by NFCISO7816APDU

I want to debug the following code and see what is the raw APDU it produces. I mean byte by byte from the header to the Le parameter.
let selectFileAPDU = NFCISO7816APDU(
instructionClass: 0x0C,
instructionCode: 0xA4,
p1Parameter: 0x02,
p2Parameter: 0x0C,
data: selectFileCommand,
expectedResponseLength: -1)

Creating NSString from byte array generates wrong characters using Swift language

I'm trying to decode some Unicode strings from a binary file. I know that they are encoded as UTF-16, and they have a 'big endian' BOM (0xFFFE). But when I try to turn them into a string I end up with a bunch of Chinese characters.
var bytes:[UInt8] = [0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x0E, 0xFE]
let text = NSString(bytes: &bytes, length: bytes.count, encoding:NSUTF16BigEndianStringEncoding)
print(text)
This prints Chinese ideograms and a [?] rather than "ABC‼︎", which is what (I believe) it should.
I've tried different encodings but nothing works correctly. Can anyone help?
The data sample you provide is coded little endian.
I don't know if it is you sample data or not.
Well, there's probably something wrong with your input.
First, BOM should be placed as a first sequence in the input. Second, the order of bytes you provided are reversed.
This example shows correct parsing:
var bytes:[UInt8] = [0xFF, 0xFE, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00]
var text = NSString(bytes: &bytes, length: bytes.count, encoding:NSUTF16LittleEndianStringEncoding)!
print(text) // prints "ABC\n"
bytes = [0xFE, 0xFF, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43]
text = NSString(bytes: &bytes, length: bytes.count, encoding:NSUTF16BigEndianStringEncoding)!
print(text) // "ABC\n"

Incorporate V and H wheel to HID report

I have been working with the HID reports and I have been able to compile and run a report for keyboard, 3 button mouse, and 3 button mouse with wheel (vertical only). Right now I have been trying to use the 5 buttons with vertical and horizontal wheel.
So following this
// Input report - 5 bytes
//
// Byte | D7 D6 D5 D4 D3 D2 D1 D0
// ------+---------------------------------------------------------------------
// 0 | 0 0 0 Forward Back Middle Right Left (Buttons)
// 1 | X
// 2 | Y
// 3 | Vertical Wheel
// 4 | Horizontal (Tilt) Wheel
Now I have this report descriptor
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x02, // COLLECTION (Logical)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
// ------------------------------ Buttons
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x05, // USAGE_MAXIMUM (Button 5)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x05, // REPORT_COUNT (5 Buttons)
0x81, 0x02, // INPUT (Data,Var,Abs)
// ------------------------------ Padding
0x75, 0x03, // REPORT_SIZE (8-5buttons 3)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
// ------------------------------ X,Y position
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x02, // REPORT_COUNT (2)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xa1, 0x02, // COLLECTION (Logical)
// ------------------------------ Vertical wheel res multiplier
0x09, 0x48, // USAGE (Resolution Multiplier)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x35, 0x01, // PHYSICAL_MINIMUM (1)
0x45, 0x04, // PHYSICAL_MAXIMUM (4)
0x75, 0x02, // REPORT_SIZE (2)
0x95, 0x01, // REPORT_COUNT (1)
0xa4, // PUSH
0xb1, 0x02, // FEATURE (Data,Var,Abs)
// ------------------------------ Vertical wheel
0x09, 0x38, // USAGE (Wheel)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x35, 0x00, // PHYSICAL_MINIMUM (0) - reset physical
0x45, 0x00, // PHYSICAL_MAXIMUM (0)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xc0, // END_COLLECTION
0xa1, 0x02, // COLLECTION (Logical)
// ------------------------------ Horizontal wheel res multiplier
0x09, 0x48, // USAGE (Resolution Multiplier)
0xb4, // POP
0xb1, 0x02, // FEATURE (Data,Var,Abs)
// ------------------------------ Padding for Feature report
0x35, 0x00, // PHYSICAL_MINIMUM (0) - reset physical
0x45, 0x00, // PHYSICAL_MAXIMUM (0)
0x75, 0x04, // REPORT_SIZE (4)
0xb1, 0x03, // FEATURE (Cnst,Var,Abs)
// ------------------------------ Horizontal wheel
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
0x0a, 0x38, 0x02, // USAGE (AC Pan)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xc0, // END_COLLECTION
0xc0, // END_COLLECTION
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
Which includes the 5 buttons, vertical and horizontal. This compiles without any issue, but I'm trying to send the following information to test if its working correctly
mouseReport.buttons = 0;
mouseReport.x = 0;
mouseReport.y = 0;
mouseReport.v = 1;
mouseReport.h = 0;
But that 1 on the Vertical wheel byte makes my mouse, click and scroll randomly.
Could anyone tell me what am I missing? I'm using the exact same code, with a different report and 4 bytes, and the scroll works perfect.
Well I found the issue. I was using a struct to send the byte array and it seems that my micro controller didn't like that because it was getting bad resolution, hence why the random movement and clicks. Changing it to an array of unint8_t fixed the issue.

How to set sockaddr_in6::sin6_addr byte order to network byte order?

I developing a network application and using socket APIs.
I want to set sin6_addr byte order of sockaddr_in6 structure.
For 16 bits or 32 bits variables, it is simple: Using htons or htonl:
// IPv4
sockaddr_in addr;
addr.sin_port = htons(123);
addr.sin_addr.s_addr = htonl(123456);
But for 128 bits variables, I dont know how to set byte order to network byte order:
// IPv6
sockaddr_in6 addr;
addr.sin6_port = htons(123);
addr.sin6_addr.s6_addr = ??? // 16 bytes with network byte order but how to set?
Some answers may be using htons for 8 times (2 * 8 = 16 bytes), or using htonl for 4 times (4 * 4 = 16 bytes), but I don't know which way is correct.
Thanks.
The s6_addr member of struct in6_addr is defined as:
uint8_t s6_addr[16];
Since it is an array of uint8_t, rather than being a single 128-bit integer type, the issue of endianness does not arise: you simply copy from your source uint8_t [16] array to the destination. For example, to copy in the address 2001:888:0:2:0:0:0:2 you would use:
static const uint8_t myaddr[16] = { 0x20, 0x01, 0x08, 0x88, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 };
memcpy(addr.sin6_addr.s6_addr, myaddr, sizeof myaddr);
The usual thing would be to use one of the hostname lookup routines and use the result of that, which is already in network byte order. How come you're dealing with hardcoded numeric IP addresses at all?