Incorrect BLE output depending on codes used

Hello

I am trying to create code to report temperature data measured from three temperature sensors in an automobile engine cooling system to my Android cell phone. I did successfully get the code to work well if I used the map function to map the sensor values as a percent range and then report them to the Android. When running the program the mapped values reported by the Android agree perfectly with the serial output.

However, when I tried to send un-mapped data (see the three variables commented out in the last subroutine) to the Android, the numbers reported by the Android were slightly less that 1/2 of what the serial monitor would print and occasionally they would be very low numbers < 10 when the serial monitor was reporting 500. The number produced by the serial monitor are known to be good.

What am I doing wrong here?

[code]
const int BatPin = A3;      // Battey monitoring pin
const int RadPin = A0;      // Radiator Input Thermister
const int CndPin = A1;      // Condenser Input Thermister
const int AuxPin = A2;      // Auxilary Input Not used at this time
const int FanPin = 9;       // Set Fan pin
const long Period = 10000;  // Recheck period

long previousMillis = 0;    // last time the temperature levels were checked, in ms




                    /*
                      Temperatur Monitor

                      This example creates a Bluetooth® Low Energy peripheral with the standard Temperature service and
                      level characteristic. Pins A0, A1 and A2 are used to calculate the temperatures of 3 sensors.
                      The data is calculated by the time set in the constant Period.

                      The circuit:
                      - Arduino MKR WiFi 1010, Arduino Uno WiFi Rev2 board, Arduino Nano 33 IoT,
                        Arduino Nano 33 BLE, or Arduino Nano 33 BLE Sense board.

                      You can use a generic Bluetooth® Low Energy central app, like LightBlue (iOS and Android) or
                      nRF Connect (Android), to interact with the services and characteristics
                      created in this sketch.

                      This example code is in the public domain.
                    */

#include <ArduinoBLE.h>

// Define the Temperature Service
BLEService TempService("53436b3f-5f91-474b-963e-8b09b170c670");        //*** BLEService Class Any Hex Name 128-bit UUID in String format *********************************************************

// Define Temperature Level Characteristics
BLEUnsignedCharCharacteristic RadLevelChar("694d181e-4421-47f3-9653-c4d6bb295a07",  // standard 128-bit characteristic UUID *******************************
    BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes
BLEUnsignedCharCharacteristic CndLevelChar("0407dd37-ae29-4ec7-ab40-a83898d610df",  // standard 128-bit characteristic UUID *******************************
    BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes
BLEUnsignedCharCharacteristic AuxLevelChar("ad43db8f-e3e6-4025-b745-43f2100f27e1",  // standard 128-bit characteristic UUID *******************************
    BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes

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 Bluetooth® Low Energy device
     This name will appear in advertising packets
     and can be used by remote devices to identify this Bluetooth® Low Energy device
     The name can be changed but maybe be truncated based on space left in advertisement packet
  */

  BLE.setLocalName("Testing 123"); //******************************************************************************

    BLE.setAdvertisedService(TempService); // add the service UUID
    TempService.addCharacteristic(RadLevelChar); // add the radiator level characteristic
    TempService.addCharacteristic(CndLevelChar); // add the condenser level characteristic
    TempService.addCharacteristic(AuxLevelChar); // add the aux level characteristic
    BLE.addService(TempService);  // Add the Temperature service
    RadLevelChar.writeValue(0);   // set initial value for this characteristic
    CndLevelChar.writeValue(0);   // set initial value for this characteristic
    AuxLevelChar.writeValue(0);   // set initial value for this characteristic

  // Start advertising Bluetooth® Low Energy.  It will start continuously transmitting Bluetooth® Low Energy
  // advertising packets and will be visible to remote Bluetooth® Low Energy central devices
  // until it receives a new connection

  BLE.advertise();  // start advertising

  //Serial.println("Bluetooth® device active, waiting for connections...");
}


  void loop() {
  // wait for a Bluetooth® Low Energy central
  BLEDevice central = BLE.central();

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

    // check the temperature levels every Period (ms)
    // while the central is connected:
    while (central.connected()) {
      long currentMillis = millis();
      // if Period ms have passed, check the temperature levels:
      if (currentMillis - previousMillis >= Period) {
        previousMillis = currentMillis;
        updateTemperatures();
      }
    }
    // when the central disconnects, turn off the LED:
    digitalWrite(LED_BUILTIN, LOW);
    Serial.print("Disconnected from central: ");
    Serial.println(central.address());
  }
  }

  void updateTemperatures() {
  // Read the current voltage level on each analog input pin.
  //   This is used here to simulate the charge level of temperaturs.

  int Rad = analogRead(RadPin);
  int Cnd = analogRead(CndPin);
  int Aux = analogRead(AuxPin);

  int RadLevel = map(Rad, 0, 1023, 0, 100);
  int CndLevel = map(Cnd, 0, 1023, 0, 100);
  int AuxLevel = map(Aux, 0, 1023, 0, 100);
   
  /*
  int RadLevel = Rad;
  int CndLevel = Cnd;
  int AuxLevel = Aux;
  */
  
  Serial.print("Rad Level % is now: "); Serial.println(RadLevel);
  Serial.print("Cnd Level % is now: "); Serial.println(CndLevel);
  Serial.print("Aux Level % is now: "); Serial.println(AuxLevel);

  RadLevelChar.writeValue(RadLevel);            // update the Radiator level characteristics
  CndLevelChar.writeValue(CndLevel);            // update the Condenser level characteristics
  AuxLevelChar.writeValue(AuxLevel);            // update the Aux level characteristics
  }
[/code]

I sort of figured out what is going on this morning but I still don't have a solution. If I change the code to put in constants > 255 the out put is as follows:

Serial Monitor Android
255 255
256 0
509 253

Apparently using the second form of the bleCharacteristic.writeValue can only handle 1 byte
Using the second form might work, but I can't figure out how to use it. The example presented in the reference, see last link is not making much sense to me.

bleCharacteristic.writeValue(buffer, length)

What is a buffer and how do I load it?

  int RadLevel = 255;
  int CndLevel = 256;
  int AuxLevel = 509;
  
  
  Serial.print("Rad Level % is now: "); Serial.println(RadLevel);
  Serial.print("Cnd Level % is now: "); Serial.println(CndLevel);
  Serial.print("Aux Level % is now: "); Serial.println(AuxLevel);

  RadLevelChar.writeValue(RadLevel);            // update the Radiator level characteristics
  CndLevelChar.writeValue(CndLevel);            // update the Condenser level characteristics
  AuxLevelChar.writeValue(AuxLevel);            // update the Aux level characteristics

Change your characteristics from BLEUnsignedCharCharacteristic to BLEUnsignedIntCharacteristic and when you update/write the value, multiple bytes will be available. I think with an integer characterisitic, you will have 4 bytes and they will be little endian.

What app are you running on the phone?

See this thread for some additional information about how to read the value.

https://forum.arduino.cc/t/analog-pin-reading-0-1023-but-characteristic-writevalue-writes-0-255-why/967951

1 Like

Thank you very much for the reply. It will be a while before I can get back to this as I'm back on the road now but it sounds promising.

I'm using BlueLight on an Android

@cattledog

Stayed up late and got it tested. That works perfectly. Many Thanks.

[code]
const int BatPin = A3;      // Battey monitoring pin
const int RadPin = A0;      // Radiator Input Thermister
const int CndPin = A1;      // Condenser Input Thermister
const int AuxPin = A2;      // Auxilary Input Not used at this time
const int FanPin = 9;       // Set Fan pin
const long Period = 10000;  // Recheck period

long previousMillis = 0;    // last time the temperature levels were checked, in ms




                    /*
                      Temperatur Monitor

                      This example creates a Bluetooth® Low Energy peripheral with the standard Temperature service and
                      level characteristic. Pins A0, A1 and A2 are used to calculate the temperatures of 3 sensors.
                      The data is calculated by the time set in the constant Period.

                      The circuit:
                      - Arduino MKR WiFi 1010, Arduino Uno WiFi Rev2 board, Arduino Nano 33 IoT,
                        Arduino Nano 33 BLE, or Arduino Nano 33 BLE Sense board.

                      You can use a generic Bluetooth® Low Energy central app, like LightBlue (iOS and Android) or
                      nRF Connect (Android), to interact with the services and characteristics
                      created in this sketch.

                      This example code is in the public domain.
                    */

#include <ArduinoBLE.h>

// Define the Temperature Service
BLEService TempService("53436b3f-5f91-474b-963e-8b09b170c670");        //*** BLEService Class Any Hex Name 128-bit UUID in String format *********************************************************

// Define Temperature Level Characteristics
BLEUnsignedIntCharacteristic RadLevelChar("694d181e-4421-47f3-9653-c4d6bb295a07",  // standard 128-bit characteristic UUID *******************************
    BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes
BLEUnsignedIntCharacteristic CndLevelChar("0407dd37-ae29-4ec7-ab40-a83898d610df",  // standard 128-bit characteristic UUID *******************************
    BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes
BLEUnsignedIntCharacteristic AuxLevelChar("ad43db8f-e3e6-4025-b745-43f2100f27e1",  // standard 128-bit characteristic UUID *******************************
    BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes

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 Bluetooth® Low Energy device
     This name will appear in advertising packets
     and can be used by remote devices to identify this Bluetooth® Low Energy device
     The name can be changed but maybe be truncated based on space left in advertisement packet
  */

  BLE.setLocalName("Testing 123"); //******************************************************************************

    BLE.setAdvertisedService(TempService); // add the service UUID
    TempService.addCharacteristic(RadLevelChar); // add the radiator level characteristic
    TempService.addCharacteristic(CndLevelChar); // add the condenser level characteristic
    TempService.addCharacteristic(AuxLevelChar); // add the aux level characteristic
    BLE.addService(TempService);  // Add the Temperature service
    RadLevelChar.writeValue(0);   // set initial value for this characteristic
    CndLevelChar.writeValue(0);   // set initial value for this characteristic
    AuxLevelChar.writeValue(0);   // set initial value for this characteristic

  // Start advertising Bluetooth® Low Energy.  It will start continuously transmitting Bluetooth® Low Energy
  // advertising packets and will be visible to remote Bluetooth® Low Energy central devices
  // until it receives a new connection

  BLE.advertise();  // start advertising

  //Serial.println("Bluetooth® device active, waiting for connections...");
}


  void loop() {
  // wait for a Bluetooth® Low Energy central
  BLEDevice central = BLE.central();

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

    // check the temperature levels every Period (ms)
    // while the central is connected:
    while (central.connected()) {
      long currentMillis = millis();
      // if Period ms have passed, check the temperature levels:
      if (currentMillis - previousMillis >= Period) {
        previousMillis = currentMillis;
        updateTemperatures();
      }
    }
    // when the central disconnects, turn off the LED:
    digitalWrite(LED_BUILTIN, LOW);
    Serial.print("Disconnected from central: ");
    Serial.println(central.address());
  }
  }

  void updateTemperatures() {
  // Read the current voltage level on each analog input pin.
  //   This is used here to simulate the charge level of temperaturs.

  int Rad = analogRead(RadPin);
  int Cnd = analogRead(CndPin);
  int Aux = analogRead(AuxPin);
/*
  int RadLevel = map(Rad, 0, 1023, 0, 100);
  int CndLevel = map(Cnd, 0, 1023, 0, 100);
  int AuxLevel = map(Aux, 0, 1023, 0, 100);
 */  
  
  int RadLevel = Rad;
  int CndLevel = Cnd;
  int AuxLevel = Aux;
  
  
  Serial.print("Rad Level % is now: "); Serial.println(RadLevel);
  Serial.print("Cnd Level % is now: "); Serial.println(CndLevel);
  Serial.print("Aux Level % is now: "); Serial.println(AuxLevel);

  RadLevelChar.writeValue(RadLevel);            // update the Radiator level characteristics
  CndLevelChar.writeValue(CndLevel);            // update the Condenser level characteristics
  AuxLevelChar.writeValue(AuxLevel);            // update the Aux level characteristics
  }
[/code]

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.