SEEED Xiao Nrf52840 - Having trouble reading correct data from react native app

Hello,
I am working on a senior design project that calculates Vitamin D intake using UVI through a vitamin D tracker that my team is building. We are having trouble with sending the vitamin D data from our app back to the SEEED Xiao. For example, if we send a hex value (0x019) to get 25 in decimal using the Bluelight scanner app, we get the correct value. However, if we send the same hex value using our React native app. We get a really high value like 12,833. We do not know if this issue is caused by our SEEED xiao, our app, or if there is a conversion issue. Any help would be greatly appreciated! Thank you!

SEED Xiao code down below:

`#include <bluefruit.h>
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#define UUID16_CHR_VITAMIN_D BLEUuid((uint16_t)0x8de7)

BLEService environmentalSensingService = BLEService(UUID16_SVC_ENVIRONMENTAL_SENSING);
BLECharacteristic uvIndexSensor = BLECharacteristic(UUID16_CHR_UV_INDEX);
BLECharacteristic vitaminDCharacteristic = BLECharacteristic(UUID16_CHR_VITAMIN_D, BLENotify | BLERead | BLEWrite);
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, SCL, SDA, U8X8_PIN_NONE);
BLEDis bledis;

void displayWelcomeMessage() {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tom_thumb_4x6_mr);
int16_t textWidth = u8g2.getStrWidth(“Welcome”);
int16_t x = (128 - textWidth) / 2; // Calculate center position
int16_t y = (64 - 6) / 2; // Center vertically
u8g2.setCursor(x, y);
u8g2.print(“Welcome”);
u8g2.sendBuffer();
delay(2000); // Display for 2 seconds
}

void displayInfo() {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tom_thumb_4x6_mr); // Adjusted font size for smaller display
int16_t textWidth = u8g2.getStrWidth(“Enter info”);
int16_t x = (128 - textWidth) / 2; // Calculate center position
int16_t y = (64 - 6) / 2; // Center vertically
u8g2.setCursor(x, y);
u8g2.print(“Enter Info”);
u8g2.sendBuffer();
delay(2000); // Display for 2 seconds
}

void setup() {
Bluefruit.begin();
bledis.setManufacturer(“Seeed Studio”);
bledis.setModel(“UV Index Sensor w/ Vitamin D Tracker”);
bledis.begin();
environmentalSensingService.begin();

// Characteristic setup
uvIndexSensor.setProperties(CHR_PROPS_NOTIFY);
uvIndexSensor.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
uvIndexSensor.setFixedLen(1);
uvIndexSensor.begin();

vitaminDCharacteristic.begin();

startAdv();
u8g2.begin();

Serial.begin(115200);
displayWelcomeMessage();
displayInfo();
}

void startAdv(void) {
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
Bluefruit.Advertising.addService(environmentalSensingService);
Bluefruit.Advertising.addName();
Bluefruit.Advertising.restartOnDisconnect(true);
Bluefruit.Advertising.setInterval(32, 244);
Bluefruit.Advertising.setFastTimeout(30);
Bluefruit.Advertising.start(0);
}

void loop() {
u8g2.clearBuffer();
float tot_uv = 0;
float uv_value = 0;
float output = 0.0;

for (int i = 0; i < 3000; i++) {
uv_value = analogRead(A1);
uv_value = (uv_value / 1023.0) * 3.3;
tot_uv = tot_uv + uv_value;
}

output = tot_uv / 3000;
output = output / 0.1;
uint8_t rounded = round(output);

Serial.print("UV Reading: ");
Serial.println(output);

// Vitamin D Conversion and print out UV index value and Vitamin D value
uint16_t vitaminDValue = 0;
Serial.print("Reading Vitamin D Value… ");
uint16_t err = vitaminDCharacteristic.read(&vitaminDValue, sizeof(vitaminDValue));

Serial.println(err);

if (err) { // Check if the read was successful
// Swap bytes to fix endianness issue
vitaminDValue = (vitaminDValue >> 8) | (vitaminDValue << 8);

// Print the Vitamin D value in hexadecimal
Serial.print("Vitamin D Value (HEX): ");
Serial.println(vitaminDValue, HEX);

// Notify the updated Vitamin D value    
uint16_t vitaminDData[1] = {vitaminDValue};
vitaminDCharacteristic.notify(vitaminDData, sizeof(vitaminDData));

} else {
Serial.println(“Error reading Vitamin D Value.”);
}

// Display the UV and Vitamin D values
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_helvB08_tr);
int16_t x = (128 - u8g2.getStrWidth("UV: ")) / 2;
u8g2.setCursor(x, 30);
u8g2.print(“UV: “);
u8g2.print(rounded);
u8g2.setCursor(51, 45);
u8g2.print(“Vit D:”);
u8g2.setCursor(51,60);
u8g2.println(vitaminDValue);
u8g2.print(” UI”);
u8g2.sendBuffer();

uint8_t appValue = rounded;
uint8_t hrmdata[1] = { appValue };
uvIndexSensor.notify(hrmdata, sizeof(hrmdata));

delay(5000);
}`

Hi there, and Welcome

Could you edit your post and use the code tags above </> and paste it in there, Makes it easy to read and test.
I think the BLE Characteristic needs a tweek. make the edit and I’ll test it with Nrf_connect for Desktop and Mobile. :v:
HTH
GL :slight_smile: PJ

Thank you so much! I edited the post and used the code tag.

ok, great first issue is the non standard Quotation marks,
I had to replace those to get it to compile, so fyi?
GL :slight_smile: PJ

OK, Appears to work so far,


VD looks not right…

13:50:02.620 -> UV Reading: 1.59
13:50:02.620 -> Reading Vitamin D Value… 0
13:50:02.620 -> Error reading Vitamin D Value.
13:50:07.812 -> UV Reading: 1.58
13:50:07.812 -> Reading Vitamin D Value… 0
13:50:07.812 -> Error reading Vitamin D Value.
13:50:13.069 -> UV Reading: 1.59
13:50:13.069 -> Reading Vitamin D Value… 0
13:50:13.069 -> Error reading Vitamin D Value.
13:50:18.281 -> UV Reading: 1.58
13:50:18.281 -> Reading Vitamin D Value… 0
13:50:18.281 -> Error reading Vitamin D Value.
13:50:23.496 -> UV Reading: 1.59

Hi there,
Yea, that needs to be like THIS

#include <bluefruit.h>
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#define UUID16_CHR_VITAMIN_D BLEUuid((uint16_t)0x8de7)

BLEService environmentalSensingService = BLEService(UUID16_SVC_ENVIRONMENTAL_SENSING);
BLECharacteristic uvIndexSensor = BLECharacteristic(UUID16_CHR_UV_INDEX);
BLECharacteristic vitaminDCharacteristic = BLECharacteristic(UUID16_CHR_VITAMIN_D, BLENotify | BLERead | BLEWrite);
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, SCL, SDA, U8X8_PIN_NONE);
BLEDis bledis;

void displayWelcomeMessage() {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tom_thumb_4x6_mr);
int16_t textWidth = u8g2.getStrWidth("Welcome");
int16_t x = (128 - textWidth) / 2; // Calculate center position
int16_t y = (64 - 6) / 2; // Center vertically
u8g2.setCursor(x, y);
u8g2.print("Welcome");
u8g2.sendBuffer();
delay(2000); // Display for 2 seconds
}

void displayInfo() {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tom_thumb_4x6_mr); // Adjusted font size for smaller display
int16_t textWidth = u8g2.getStrWidth("Enter info");
int16_t x = (128 - textWidth) / 2; // Calculate center position
int16_t y = (64 - 6) / 2; // Center vertically
u8g2.setCursor(x, y);
u8g2.print("Enter Info");
u8g2.sendBuffer();
delay(2000); // Display for 2 seconds
}

void setup() {
Bluefruit.begin();
bledis.setManufacturer("Seeed Studio");
bledis.setModel("UV Index Sensor w/ Vitamin D Tracker");
bledis.begin();
environmentalSensingService.begin();

// Characteristic setup
uvIndexSensor.setProperties(CHR_PROPS_NOTIFY);
uvIndexSensor.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
uvIndexSensor.setFixedLen(1);
uvIndexSensor.begin();

vitaminDCharacteristic.begin();

startAdv();
u8g2.begin();

Serial.begin(115200);
displayWelcomeMessage();
displayInfo();
}

void startAdv(void) {
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
Bluefruit.Advertising.addService(environmentalSensingService);
Bluefruit.Advertising.addName();
Bluefruit.Advertising.restartOnDisconnect(true);
Bluefruit.Advertising.setInterval(32, 244);
Bluefruit.Advertising.setFastTimeout(30);
Bluefruit.Advertising.start(0);
}

void loop() {
u8g2.clearBuffer();
float tot_uv = 0;
float uv_value = 0;
float output = 0.0;

for (int i = 0; i < 3000; i++) {
uv_value = analogRead(A1);
uv_value = (uv_value / 1023.0) * 3.3;
tot_uv = tot_uv + uv_value;
}

output = tot_uv / 3000;
output = output / 0.1;
uint8_t rounded = round(output);

Serial.print("UV Reading: ");
Serial.println(output);

// Vitamin D Conversion and print out UV index value and Vitamin D value
uint16_t vitaminDValue = 0;
Serial.print("Reading Vitamin D Value… ");
uint16_t err = vitaminDCharacteristic.read(&vitaminDValue, sizeof(vitaminDValue));

Serial.println(err);

if (err) { // Check if the read was successful
// Swap bytes to fix endianness issue
vitaminDValue = (vitaminDValue >> 8) | (vitaminDValue << 8);

// Print the Vitamin D value in hexadecimal
Serial.print("Vitamin D Value (HEX): ");
Serial.println(vitaminDValue, HEX);

// Notify the updated Vitamin D value    
uint16_t vitaminDData[1] = {vitaminDValue};
vitaminDCharacteristic.notify(vitaminDData, sizeof(vitaminDData));
} else {
Serial.println("Error reading Vitamin D Value.");
}

// Display the UV and Vitamin D values
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_helvB08_tr);
int16_t x = (128 - u8g2.getStrWidth("UV: ")) / 2;
u8g2.setCursor(x, 30);
u8g2.print("UV: ");
u8g2.print(rounded);
u8g2.setCursor(51, 45);
u8g2.print("Vit D:");
u8g2.setCursor(51,60);
u8g2.println(vitaminDValue);
u8g2.print(" UI");
u8g2.sendBuffer();

uint8_t appValue = rounded;
uint8_t hrmdata[1] = { appValue };
uvIndexSensor.notify(hrmdata, sizeof(hrmdata));

delay(5000);
}

you paste it between the dots that this </>above gives you…
HTH
Gl :slight_smile: PJ

I write 20A0 hex to it… goes through ok
You see Y?

14:08:06.103 -> UV Reading: 1.59
14:08:06.103 -> Reading Vitamin D Value… 2
14:08:06.103 -> Vitamin D Value (HEX): 20A0
14:08:11.335 -> UV Reading: 1.59
14:08:11.335 -> Reading Vitamin D Value… 2
14:08:11.335 -> Vitamin D Value (HEX): A020
14:08:16.522 -> UV Reading: 1.59
14:08:16.522 -> Reading Vitamin D Value… 2
14:08:16.522 -> Vitamin D Value (HEX): 20A0
14:08:21.770 -> UV Reading: 1.59
14:08:21.770 -> Reading Vitamin D Value… 2
14:08:21.770 -> Vitamin D Value (HEX): A020
14:08:26.984 -> UV Reading: 1.59
14:08:26.984 -> Reading Vitamin D Value… 2
14:08:26.984 -> Vitamin D Value (HEX): 20A0

My guess is that these lines of code are switching the hex values you are talking about, but I’m not entirely sure.

if (err) { // Check if the read was successful
// Swap bytes to fix endianness issue
vitaminDValue = (vitaminDValue >> 8) | (vitaminDValue << 8);

[quote=“ticrocker, post:1, topic:276145”]
send a hex value (0x019) to get 25 in decimal using the Bluelight

Step 1 Multiply the rightmost digit 
9 * 16^0 = 9 
Step 2 Multiply the next digit 
1 * 16^1 =16
Step 3 Add the results.
9+16=25

HTH
GL :slight_smile: PJ :v: