I'm using the LightBlue app on Android to send data to an Arduino Nano 33 IOT with BLE. When I try to send integers in hex format with the LightBlue app it works unless I send something bigger than one byte. When I send "FF" which is 255 or 1 byte I also see 255 in the serial monitor but if I send "100" which is 256 I get 1 again. Basically, everything over 1 byte makes it produce garbage numbers after that. I can fix the issue by spamming it with a bunch of zeros. Presumably, that clears a buffer and there's a mismatch in the packet size or something.
Here is my code:
#include <ArduinoBLE.h>
BLEService stepperService("19B10000-E8F2-537E-4F6C-D104768A1214"); // BLE LED Service
// BLE LED Switch Characteristic - custom 128-bit UUID, writable by central
BLEIntCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLEWrite);
const int ledPin = LED_BUILTIN; // pin to use for the LED
int delayStepper = 100;
void setup() {
Serial.begin(9600);
while (!Serial);
// set LED pin to output mode
pinMode(ledPin, OUTPUT);
// begin initialization
if (!BLE.begin()) {
Serial.println("starting BLE failed!");
while (1);
}
// set advertised local name and service UUID:
BLE.setLocalName("Stepper motor control");
BLE.setAdvertisedService(stepperService);
// add the characteristic to the service
stepperService.addCharacteristic(switchCharacteristic);
// add service
BLE.addService(stepperService);
// set the initial value for the characeristic:
switchCharacteristic.writeValue(100);
// start advertising
BLE.advertise();
Serial.println("BLE LED Peripheral");
}
void loop() {
// listen for BLE peripherals to connect:
BLEDevice central = BLE.central();
Serial.println("No central found");
// if a central is connected to peripheral:
if (central) {
Serial.print("Connected to central: ");
// print the central's MAC address:
Serial.println(central.address());
// while the central is still connected to peripheral:
while (central.connected()) {
// if the remote device wrote to the characteristic,
// use the value to control the LED:
if (switchCharacteristic.written()) {
delayStepper = switchCharacteristic.value();
Serial.print("New value is: ");
Serial.println(delayStepper);
}
}
// when the central disconnects, print it out:
Serial.print(F("Disconnected from central: "));
Serial.println(central.address());
}
}
Here's the serial monitor log after sending 0x00, 0xFF, 0x0100, 0x0101, 0x0102 from the LightBlue app:
18:56:59.632 -> No central found
18:56:59.632 -> No central found
18:56:59.632 -> No central found
18:56:59.632 -> No central found
18:56:59.632 -> No central found
18:56:59.632 -> Connected to central: 59:20:d4:80:e5:e9
Unfortunately, all the BLE apps are as generic as possible and do not support data types. They just handle bytes and sometimes strings.
The bad thing is the Bluetooth specification has defined some descriptors that allow you to describe the data type (e.g., 32 bit integer) and even units (volt, ampere, ... ). But it seems they are not used.
What do you want to use as a central when developed your peripheral devices?
Ah I thought it would use nibbles as a unit for some reason, bytes makes way more sense. It looks like the "Signed little endian" encoding works for integers. If I want to move to sending long ints later I assume I will have to switch to unsigned little endian, correct?
You can use unsigned and signed data types. You just need to remember how signed data types are created (twos complement). The app will show you the bytes but it is harder to create/decode them by hand. I am not even sure if you can set 32-bit data in the apps.
If you use two Arduinos this is all not a problem. You can just use whatever data type is best for your application. Also when you would write your own apps this would be fine.
I want to start of easy and just control the speed and the direction of the stepper motor. That means that for the first version I just need a simple GUI with a knob and a slider. I think you can do this with the Blynk BLE app. Later I want to control the speed of a leadscrew in m/s and add slow deacceleration to reduce vibrations. So first a generic app and then maybe more.
The end goal is that I can control a mounting platform for a telescope without touching physical knobs on the machine so that I don't induce vibrations but that will have to wait.
Eventually I'm going to need to write my own program anyways for my PC + phone with code for smoothing etc. Do you know any BLE libraries? I can write Python, C#, Java, Javascript and C++. I listed the languages that I think are most fit for a job like this first.
Ok thanks I'll take a look. With nrf Connect I don't seem to have the problem. I think I'll just write my python programs and then convert if necessary on the microcontroller or before sending the data. I'll mark the post as solved and thanks again guys.