Fractions over BLE

My project revolves around calculating an electric longboards velocity. The current setup is simplified to where both the RPM and Wheel Diameter variables are characteristics of my main service, velocityService.
The three characteristics look like this:

BLEUnsignedCharCharacteristic rpmCharacteristic("19B10011-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
BLEUnsignedCharCharacteristic diameterCharacteristic("19B10012-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
BLEDoubleCharacteristic velocityCharacteristic("19B10013-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);

My current problem is that RPM will be a 4-byte number, Diameter will be 2 or 3 bytes, and velocity will need to be a fraction of up to 6 bytes in length.

Every time I set the third argument, maxLen, to any value it gives me this error: no matching function for call to 'BLEUnsignedCharCharacteristic::BLEUnsignedCharCharacteristic(const char [37], int, int)' I need to be able to modify this because when I edit the value of the RPM characteristic it leaves me with only the first two bytes of information. For instance, writing 3200 to the RPM characteristic then reads 32. So the velocity is way lower than expected.

I need to be able to output velocity to my i-phone as a fraction.
So I tried using BLEDoubleCharacteristic velocityCha........ but its output makes no sense to me. And I could not convert it to decimal to check its accuracy.

The app I am using, nrf connect, does not convert the hex to decimal values. So for instance, if the Arduino is trying to tell me that velocity is 25.89 I would instead read a hex number. And I have not found an online calculator to translate hex to decimal especially when the app value doesn't specify a decimal point. For ex. 30.1 = 0x9A99999999193E40. And I have no idea how to go from that back to 30.1.

So to sum up what I am failing to understand:
How to make a characteristic of a greater lenght than 2 bytes.
And how to send fractions or non integers accross my BLE connection.

I am using an Arduino 101, with the Curie stuff installed.

Velocity_Calculation.zip (3.95 KB)

Atledbet_11:
My project revolves around calculating an electric longboards velocity. The current setup is simplified to where both the RPM and Wheel Diameter variables are characteristics of my main service, velocityService.
The three characteristics look like this:

BLEUnsignedCharCharacteristic rpmCharacteristic("19B10011-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
BLEUnsignedCharCharacteristic diameterCharacteristic("19B10012-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
BLEDoubleCharacteristic velocityCharacteristic("19B10013-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);

My current problem is that RPM will be a 4-byte number, Diameter will be 2 or 3 bytes, and velocity will need to be a fraction of up to 6 bytes in length.

Every time I set the third argument, maxLen, to any value it gives me this error: no matching function for call to 'BLEUnsignedCharCharacteristic::BLEUnsignedCharCharacteristic(const char [37], int, int)' I need to be able to modify this because when I edit the value of the RPM characteristic it leaves me with only the first two bytes of information. For instance, writing 3200 to the RPM characteristic then reads 32. So the velocity is way lower than expected.

I need to be able to output velocity to my i-phone as a fraction.
So I tried using BLEDoubleCharacteristic velocityCha........ but its output makes no sense to me. And I could not convert it to decimal to check its accuracy.

The app I am using, nrf connect, does not convert the hex to decimal values. So for instance, if the Arduino is trying to tell me that velocity is 25.89 I would instead read a hex number. And I have not found an online calculator to translate hex to decimal especially when the app value doesn't specify a decimal point. For ex. 30.1 = 0x9A99999999193E40. And I have no idea how to go from that back to 30.1.

So to sum up what I am failing to understand:
How to make a characteristic of a greater lenght than 2 bytes.
And how to send fractions or non integers accross my BLE connection.

I am using an Arduino 101, with the Curie stuff installed.

Using an Arduino 101. good choice with builtin accelerometer and gyroscope.

Which version of Arduino IDE are you using?
What operating system are you using?
Linux, MacOSX, MS WIndows, other

What is the project that you are working on?
I read it that you want to determine the velocity of an electric skateboard and you want to send that information to your phone.

what application on your telephone are you using to receive the BLE communication?

Hi @Atledbet_11

Float and double characteristic values are sent as IEEE 754 representation, please see: Single-precision floating-point format - Wikipedia or Double-precision floating-point format - Wikipedia

@artisticforge

I am using the web editor since sometimes I need to work on this away from home, but I do have the Arduino IDE 1.8.5 installed on both. On my desktop and laptop, I use Windows 10.

I am using nRF connect to the apple app store. Because it is the only app I have found that allows me to actually work with this without developing an app myself for the short term.

The basic idea of the project is to have the RPM of the motor read in through one of the i/o pins on the Arduino in the future, but I have no way to source that input as of now so I am temporarily changing the RPM and Diameter through my phone. When I make an app, the only input for velocity from the iPhone is going to be the wheel diameter(mm).

Also before anyone mentions it, I have corrected the velocity calculation.

sandeepmistry:
Hi @Atledbet_11

Float and double characteristic values are sent as IEEE 754 representation, please see: Single-precision floating-point format - Wikipedia or Double-precision floating-point format - Wikipedia

Hey, this helped me a lot actually. I changed all of my characteristics to regular float characteristics. Then using the wiki page you linked on single precision floats I now understand what the phone reads to be correct.

I only found one problem, this being that the given number 3200 reads as 0x00004845 on the iPhone. The correct data read 0x45480000. So its easy to read back out by reordering the bits, but I was curious as to why the iPhone reads in the wrong order.

for example, correct notation is 0xAaBbCcDd and the iPhone displays 0xDdCcBbAa. It would have made slightly more sense to me if the iPhone displayed 0xdDcCbBaA since that would be the proper notation in reverse, for example instead of 0x00004845, it would have read 0x54840000. But it doesn't xD.

Besides this slight issue, the program works and calculates the accurate velocity given that input according to this weird dada order: 0xDdCcBbAa. And in the Serial monitor I get the exact values I expect from this format.

Velocity_Calculation(1).zip (2.88 KB)

By default, CurieBLE will use little endian format, the tool you are using most likely displays values as big endian. "characteristic.setValueBE(...)" can be used to set the value in big endian format.

sandeepmistry:
By default, CurieBLE will use little endian format, the tool you are using most likely displays values as big endian. "characteristic.setValueBE(...)" can be used to set the value in big endian format.

What a wizard, it works great now. Thanks!