Why are uint16_t values inaccurate when transmitted via BLE [SOLVED]

I'm trying to transmit the value 800 using BLE by invoking writeValue() but I've come to realize that the central device which is an iPhone receives the characteristic value as 0x20. I don't know what seems to be wrong, but printing out the variable that holds 800 before writing to the characteristic, I haven't noticed anything wrong. The code for the program can be found below

#include <ArduinoBLE.h>
#include "model.h"

// BLE Battery Service
BLEService transferService("f7828236-7a6c-488f-950b-31bdda5f20ad");

// BLE Battery Level Characteristic
BLEUnsignedCharCharacteristic transferPacketCountChar("9d4a4fc1-8eeb-4785-859b-32c584a46f5e", BLERead | BLENotify);       // remote clients will be able to get notifications if this characteristic changes

int initialValue = 800;

void setup()
{
  Serial.begin(9600); // initialize serial communication

  while (!Serial)
    ;

  pinMode(LED_BUILTIN, OUTPUT); // initialize the built-in LED pin to indicate when a central is connected

  // begin initialization
  if (!BLE.begin())
  {
    Serial.println("starting BLE failed!");
    while (1)
      ;
  }

  /* Set a local name for the BLE device
     This name will appear in advertising packets
     and can be used by remote devices to identify this BLE device
     The name can be changed but maybe be truncated based on space left in advertisement packet
  */
  BLE.setLocalName("BLESpeedTest2.0");
  BLE.setAdvertisedService(transferService); // add the service UUID

  transferService.addCharacteristic(transferPacketCountChar); 

  BLE.addService(transferService);         // Add the transfer service

  /* Start advertising BLE.  It will start continuously transmitting BLE
     advertising packets and will be visible to remote BLE central devices
     until it receives a new connection */

  // start advertising
  BLE.advertise();
  Serial.println("Bluetooth device active, waiting for connections...");
}

void loop()
{
  // wait for a BLE central
  BLEDevice central = BLE.central();

  // if a central is connected to the peripheral:
  if (central)
  {
    Serial.print("Connected to central: ");
    Serial.println(central.address());
    // turn on the LED to indicate the connection:
    digitalWrite(LED_BUILTIN, HIGH);

    // while the central is connected:
    while (central.connected())
    {
        Serial.print("Init val: ");
        Serial.println(initialValue);  // Prints 800
        transferPacketCountChar.writeValue(initialValue);
    }
    // when the central disconnects, turn off the LED:
    digitalWrite(LED_BUILTIN, LOW);
    Serial.print("Disconnected from central: ");
    Serial.println(central.address());
  }
}

And the central device (iPhone) reads the character as follows

<CBCharacteristic: 0x2812bc780, UUID = 9D4A4FC1-8EEB-4785-859B-32C584A46F5E, properties = 0x12, value = {length = 1, bytes = 0x20}, notifying = YES>

loosely translating that the value in the characteristic is 0x20.

I've also tried to use setValue and ended up getting the same result. Any reason as to why this happens?

Thank you in advance

800 decimal is 0x0320 in hex or as the byte string sent by the "writeValue()" method.

It appears that you are correctly receiving the least significant byte of that byte string.

int initialValue = 800;

It appears you are using an unsigned char(1 byte) characteristic to sent an int value which is going to be four bytes or two bytes depending on the platform you are using. If you really want a uint16_t like the topic suggests, you need to explicitly declare it so.

One recommendation would be to convert the int to a text character string and send the value as text.

Alternatively, you can send the four or two bytes of the int using an integer characterisitc and work out the details of endianess on the receiving end.

You need to explore the ArduinoBLE.h library to see some of the other characteristics available to you.

Nice catch. I mostly just copied most of the content from the BatteryMonitor example. Thank you!