Sending string from app to Arduino via BLE1

Hi!

I'm trying to send a simple string from MIT App inventor to Arduino 33 using the BLE1, but this code is not working and the Arduino is not receiving anything.
The other side of communication (Arduino -> App) works, so I know it's not an issue with the Bluetooth connection. I've attached the picture of the app code and the Arduino code.
Any help would be appreciated. Thanks!

image

You don't show procedure BLElive from your sketch.

You also don't have a case for where you don't recognize the incoming value.

It's easier if you upload the entire .ino file.

Regarding your app,
consider adding a Button with a Click event where you can send another message besides the one you send at connect time.

To verify your BLE extension version, export and post its .aia file here.

I've attached the entire .ino file!
My BLE extension is the one I downloaded
retry2wayconn.ino (6.7 KB)
from here, the most recent version aug 24
https://iot.appinventor.mit.edu/iot/reference/bluetoothle

I also added the button feature with click on the app

Here's your .ino file in a more board-friendly format:

#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <ArduinoBLE.h>
#include <SPI.h>

// Define TFT connections 
#define TFT_CS     10 
#define TFT_RST    9 
#define TFT_DC     8 

// Initialize TFT 
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); 

// char array to print to the screen 
char sensorPrintout[4]; 

// initialize global variable for UV
float uv_reading = 0;

// change this to however many samples you want per day
// end goal: data cap of 1440, only sample for it once a minute
const int data_cap = 4;
const int week_days = 7;
// initialize global array for UV data storage per day
int uv_daily_store[data_cap];
// keep track of position in daily store
int minute = 0;

// initialize global array for UV data storage per week
int uv_weekly_store[week_days];
// initialize variable to keep track of what day it is
int day = 0;

int lastUvReading = -1;  // Store last value

int connCheck = 1; //check if connected


// Set up BLE
BLEService sensorService("180c"); // Custom BLE Service
BLEStringCharacteristic sensorCharacteristic("2A56", BLERead | BLENotify, 20); // BLE Characteristic
BLEStringCharacteristic receiveCharacteristic("2A56", BLEWrite, 20); //receive data

void setup() { 
    Serial.begin(115200); 
    tft.initR(INITR_BLACKTAB);  // Initialize ST7735 with black tab settings 
    tft.fillScreen(ST77XX_BLACK); // Clear screen with black 
    tft.setTextSize(8); // Set text size 

    // BLE Integration
    if (!BLE.begin()) {
        Serial.println("Starting BLE failed!");
        while (1);
    }
    BLE.setDeviceName("UVNano");  // Change peripheral name
    BLE.setLocalName("UVNano");  // Change local name 
    BLE.setAdvertisedService(sensorService);
    sensorService.addCharacteristic(sensorCharacteristic);
    sensorService.addCharacteristic(receiveCharacteristic);
    BLE.addService(sensorService);
    receiveCharacteristic.setEventHandler(BLEWritten, onReceive);
    sensorCharacteristic.writeValue("Waiting...");
    
    BLE.advertise();
    Serial.println("Bluetooth Ready and Advertising");
} 

void loop() {  
  // Read UV
  UVRead();
    // BLE Device Connection Logic
    BLEDevice central = BLE.central(); // Wait for connection
    if (central & (connCheck ==0)) {
        Serial.print("Connected to ");
        Serial.println(central.address());
        connCheck = 1;
    }
    if(!central){
      connCheck = 0;
    }
}

void BLElive(){
            UVRead();
            //if (uv_reading != lastUvReading) {
                String value = "UV Index: " + String(uv_reading);
                sensorCharacteristic.writeValue(value);
                Serial.print('UV Live works');
                Serial.print('Bluetooth UV test: ');
                Serial.print(uv_reading);
                
                // Serial monitor after sending to Bluetooth for debugging
                Serial.print("Sent to Bluetooth: ");
                Serial.println(value);
}

void BLEstore(){
    String week_vals;
    for(int i=0; i<(week_days-1); i++){
      week_vals += String(uv_weekly_store[i]) + " ";
    }
                sensorCharacteristic.writeValue(week_vals);
                Serial.print('UV Stored works');
                Serial.print('UV test: ');
                Serial.print(uv_reading);
                
                // Serial monitor after sending to Bluetooth for debugging
                Serial.print("Sent to Bluetooth: ");
                Serial.println(week_vals);
}

// Function triggered when data is received
void onReceive(BLEDevice central, BLECharacteristic characteristic) {
    String receivedValue = receiveCharacteristic.value();
    Serial.print("Received via BLE: ");
    Serial.println(receivedValue);
    //int storageType = receivedValue.toInt();

    // Add logic for how to handle the received value
    // "0" for live, "1" for stored
    if (receivedValue == "0") {
       delay(1000);
      BLElive();
      
    } else if (receivedValue == "1") {
        delay(1000);
      
    }
}

// reads UV and stores UV index as global variable uv_reading
// outputs UV index onto LCD
void UVRead(){
  // read the input on analog pin 0: 
    int sensorValue = analogRead(A0);
    // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 3.3V):
    float voltage = sensorValue*3.3/1023.0;
    // calculate UV index
    float uv_reading_raw = voltage*10;
    uv_reading = round(uv_reading_raw); 
    Serial.print("Voltage: ");
    Serial.print(voltage);
    Serial.print(" | UV Index: ");
    Serial.println(uv_reading);
  
    // only print if changed (to reduce flickering)
    if(uv_reading != lastUvReading){
    // Choose text color based on value 
    uint16_t textColor; 
    if (uv_reading < 3) { 
        textColor = ST77XX_GREEN;  // Green for UV < 3 
    } else if (uv_reading < 6) { 
        textColor = ST77XX_YELLOW; // Yellow for UV = 4, 5 
    } else if (uv_reading < 8) { 
        textColor = ST77XX_ORANGE; // Orange for UV = 6, 7 
    } else if (uv_reading < 11) { 
        textColor = ST77XX_RED; // Red for UV = 8, 9, 10 
    } else { 
        textColor = ST77XX_MAGENTA;    // Purple for Extreme UV >10 
    } 

    // Clear previous text 
    tft.fillScreen(ST77XX_BLACK); // Clear screen with black 
    itoa(uv_reading, sensorPrintout, 10); // Convert integer to string 

    // Get the text width using getTextBounds() to correctly center the text 
    int16_t x, y; 
    uint16_t textWidth, textHeight; 
    tft.getTextBounds(sensorPrintout, 0, 0, &x, &y, &textWidth, &textHeight); 

    // Center the text based on the width of the text 
    x = (128 - textWidth) / 2; // 128 is screen width 

    tft.setTextColor(textColor); 
    tft.setCursor(x, 50); // Set cursor position for centered text 
    tft.print(sensorPrintout); // Display UV index 
    }
  
    lastUvReading = uv_reading;
  // store the data (change later to only store once a minute)
    UVStore();
    // Update every 1 second 
    delay(1000);

}

// store the UV data into daily array
void UVStore(){
  uv_daily_store[minute] = uv_reading;
  if(minute<(data_cap-1)){
    minute++;
  }
    // if whole day is stored (NEEDS MORE STUFF HERE)
  else{
    UVDaily();
  }
}

// call to convert the array of data from the whole day into a daily average
void UVDaily(){
float daily_sum = 0;
float daily_average = 0;
  for(int i=0; i<data_cap; i++){
    daily_sum += uv_daily_store[i];
  }
  daily_average = daily_sum/data_cap;
  uv_weekly_store[day] = daily_average;
  //reset uv_daily_store array
  minute = 0;
  //go to next day in uv_weekly_store array
  if(day<(week_days-1)){
    day++;
  }
    // if the whole week is stored (NEEDS MORE STUFF HERE)
  else{
    Serial.print("Out of data storage");
    Serial.print('Weekly data:');
    for(int i = 0; i<week_days; i++){
      Serial.print(uv_weekly_store[i]);
      Serial.print(", ");
    }
   // day = 0;
  }
}

Hopefully, one of our BLE experts will spot something.

(Canned Reply: ABG- Export & Upload .aia)
Export your .aia file and upload it here.

export_and_upload_aia

.

BasicIoTSetUp.aia (319.0 KB)
I've attached the .aia file! Again, any help would be appreciated

The BLE experts are out to vacation, I guess, so here's a guess for you.

Your receive code does not have a case for when the received text does not match either '0' or '1'.

Open yourself up to surprise.


// Function triggered when data is received
void onReceive(BLEDevice central, BLECharacteristic characteristic) {
    String receivedValue = receiveCharacteristic.value();
    Serial.print("Received via BLE: ");
    Serial.println(receivedValue);
    //int storageType = receivedValue.toInt();

    // Add logic for how to handle the received value
    // "0" for live, "1" for stored
    if (receivedValue == "0") {
       delay(1000);
      BLElive();
      
    } else if (receivedValue == "1") {
        delay(1000);
      
    }
}

Here's your latest blocks image, in case an expert notices.

I wonder if having two Characteristics with the same id ("2A56") makes sense.

Does one overwrite the other?

Or are they cumulative in their attributes?