Unable to send the Medicine and List over via bluetooth

Hi all my objective is to send a text and list via bluetooth however, an error has appeared during this process. I am currently trying to identify the cause of this error. Any help would be appreciated :slight_smile:

photo_6298831795038306040_x
The error that occured

The aia file if it helps thank you :slight_smile:
PhoneAppPrototype.aia (239.3 KB)

Why are you multiplying the medicine name (hey) by 1?

Hi I multiplied it by 1 to change it into a integer which will be read by arduino :slight_smile: is there a better way to do this?

Upload your .ino file here so we can see how you handle the medicine name?

BLE_1.9.ino (4.7 KB)

im working with epyx on this project. We have a pillbox of 7 compartments, the plan is to have the mit app send data of the compartments and the variables attached to it to the arduino where an lcd will display when the pillbox is opened. However, we are currently just reading the value of the variable of the characteristic NotifCharacteristic and displaying it on an lcd.

I am planning to send all of the data from the MIT app in one packet and splitting it to our needs in arduino. However i am not sure whether it is a feasible option.

I am seeing contradictions in the ways you are using data types within the sketch and your app.

Here you are defining Notif_var as an unsigned 32 bit integer:
image

Here you are expecting a compartment number in it:
image

But I don't see any place in your sketch where you are expecting text to arrive from your NotifCharacteristic...

#include <ArduinoBLE.h>
#include <LiquidCrystal.h>

uint32_t value = 0;
uint32_t Notif_Var = 0;
bool alarm_On = false;
bool reminder_On = false;

const int rs = 9,
          en = 10,
          d4 = 18,
          d5 = 21,
          d6 = 38,
          d7 = 47;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

BLEService PillService("19b10000-e8f2-537e-4f6c-d104768a1214");

// Bluetooth® Low Energy LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEUnsignedIntCharacteristic CountCharacteristic("76462190-1639-4f68-9af2-f9f5b3e8f549", BLENotify);
BLEByteCharacteristic NotifCharacteristic("975f4177-fba7-4374-868a-d52603e6b740", BLERead | BLEWrite | BLENotify);
BLEByteCharacteristic FindCharacteristic("875f4177-fba7-4374-868a-d52603e6b741", BLERead | BLEWrite);

void setup() {
  Serial.begin(9600);
  //while (!Serial);   // Uncomment to wait for serial port to connect.

  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, INPUT);

  lcd.begin(16, 2);

  // Begin initialization
  if (!BLE.begin()) {
    Serial.println("Starting Bluetooth® Low Energy failed!");

    // Stop if Bluetooth® Low Energy couldn't be initialized.
    while (1)
      ;
  }

  // Set advertised local name and service UUID:
  BLE.setLocalName("Nano-ESP32");
  BLE.setAdvertisedService(PillService);

  // Add the characteristic to the service
  PillService.addCharacteristic(CountCharacteristic);
  PillService.addCharacteristic(NotifCharacteristic);
  PillService.addCharacteristic(FindCharacteristic);

  // Add service
  BLE.addService(PillService);

  // Set the initial value for the characeristic:
  CountCharacteristic.writeValue(value);
  NotifCharacteristic.writeValue(Notif_Var);

  // start advertising
  BLE.advertise();
}

void loop() {
  // Listen for Bluetooth® Low Energy peripherals to connect:
  BLEDevice central = BLE.central();
  lcd.setCursor(0, 0);
  lcd.print("Device");
  lcd.setCursor(0, 1);
  lcd.print("Disconnected");

  // If a central is connected to peripheral
  if (central) {
    Serial.print("Connected to central: ");
    // Print the central's MAC address
    Serial.println(central.address());
    lcd.clear();

    // Wait until the central disconnects
    while (central.connected()) {
      CountCharacteristic.writeValue(value);
      value++;
      Serial.print("Count value: ");
      Serial.println(value);
      lcd.setCursor(0, 1);
      lcd.print(value);
      lcd.setCursor(0, 0);
      lcd.print("Device connected");

      reminder_On = digitalRead(8);
      Serial.println(reminder_On);

      if (NotifCharacteristic.written() && !reminder_On) {
        NotifCharacteristic.readValue(Notif_Var);
        Serial.println(Notif_Var);

        unsigned long startMillis = millis();
        bool alarmStopped = true;

        while (millis() - startMillis < 10000) {  // 10-second alarm
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Compartment:");
          lcd.setCursor(0, 1);
          lcd.print(Notif_Var);
          digitalWrite(5, HIGH);
          digitalWrite(6, HIGH);
          delay(1000);
          digitalWrite(5, LOW);
          digitalWrite(6, LOW);
          delay(1000);

          reminder_On = digitalRead(8);
          if (reminder_On) {
            digitalWrite(5, LOW);
            digitalWrite(6, LOW);
            alarmStopped = false;  // Mark that the alarm was stopped by the button
            lcd.clear();
            break;  // Exit the alarm loop if reminder_On is pressed
          }
        }

        // Write back to the characteristic only after the 10-second timer and if the alarm was not stopped by the button
        if (alarmStopped) {
          int32_t SMS = 1;
          NotifCharacteristic.writeValue(SMS);
          Serial.print("Emergency contact: ");
          Serial.println(SMS);
          lcd.clear();
        }
      }


      if (FindCharacteristic.written()) {
        alarm_On = !alarm_On;
        Serial.println(alarm_On);
        if (alarm_On) {
          digitalWrite(6, HIGH);
          digitalWrite(7, HIGH);
          delay(200);
          digitalWrite(6, LOW);
          digitalWrite(7, LOW);
          delay(200);
          digitalWrite(6, HIGH);
          digitalWrite(7, HIGH);
          delay(200);
          digitalWrite(6, LOW);
          digitalWrite(7, LOW);
          delay(200);
        } else {
          digitalWrite(6, LOW);
          digitalWrite(7, LOW);
        }
      }

      delay(1000);
    }

    // When the central disconnects, print it out
    Serial.print("Disconnected from central: ");
    Serial.println(central.address());
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Device");
    lcd.setCursor(0, 1);
    lcd.print("Disconnected");
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
  }
}

If you are hoping to send a medicine name as text using a Byte stream, you would need blocks to do that conversion. I have some you can use, good only for ASCII text (no accent marks).

1 Like

If your intention is to send a medicine name and a list of 7 pill numbers, how do you expect to separate out that variable length medicine name from the 7 pill numbers when they arrive in the sketch? Maybe you need a text characteristic just for the medicine name?

By the way, global Pillnumbers is a list and can't be multiplied using math blocks, which know nothing of lists.

1 Like

Hi ABG, apologies for the rookie mistake, i have decided to instead just send comma separated vales without text for the app. It looks fine on the app

With the same code to send the global Medicine via BLE, I'm not sure if this is the right way to go for comma separated values or if there are better ways of sending separated data via BLE

image

The code to read is the same arduino code as above. However i have not split the values or done anything to Notif_Var and it has come out to become always 50? No matter what values i input in the app. I will try to read more tutorials on this in the meanwhile. Just wondering if anyone knows how to fix my issue, thanks.

Also is it possible to change the topic title to Bluetooth Low Energy for more accuracy?

I have tried sending with no spacings and successfully sent it via BLE however, it wouldn't show any indexing and just send eg (213) which i require to differenciate which compartment it belongs to (eg. first number is compartment 1, second number is compartment 2 and so forth so on) If i add any thing to space the numbers out like a comma or a dash it would just read 50 on the arduino. I can achieve different numbers depending on the characteristic type i assigned it in my arduino code. I will continue experimenting

Get an ASCII table and look up decimal 50

I have decided instead to make it so that every compartment is initialised to 0 and will send a 0 if untouched and to split it in the arduino code, according to which number comes first eg(2212342 then split it so the first number belongs to compartment one etc..etc..) to make life easier.
image
image

You need something between the hour and minute to distinguish between one minute after 11 o'clock and 11 minutes after 1 o'clock

Most people use a colon

image
Yep we have done it here at clock 2.

I have another question to ask though. When i send the PillData, if compartment 1 is a 0 it will not be shown and given to the arduino. So instead of 0502201 the arduino sees 502201, with the 0 missing.What are some workarounds to make sure that every digit is passed on to the arduino?

Let's talk data types.

You are building up global PillData using a text JOIN block instead of a Make List block, so you are sending just a single integer with maybe 7 digits over that BLE WriteIntegersWithResponse block for characteristic ...UUID2.

(Pause while I take my shoes off to see if a seven digit number will fit in a BLE Integer.)

Okay, I don't know.

But while I put my socks back on, I thought of a way to encode 7 values in the range 0-15 (who is that sick?) into a single number below 2^32.

Use a base 16 polynomial for your list of 7 pill quantities, and decode it at the receiving end.

Another alternative would be to send a list instead of that big JOIN, but I don't have any code samples for how to receive a list in your .ino

Im not sure what you mean by using a 16 base polynomial for my list sorry im not good at this type of thing yet, so i opted for the list method however when it tries to send the list PillData, an error appears
image

By the way the method i used before with just the numbers combined, this is part of the arduino code for to separate it. It only works if the first compartment number is inputted anything other than a 0.
image

Here's an old trick to force leading zeroes, usually used for hour and minute displays:

If you want to force n digits, add 10^n to the number, send it, and at the receiving end skip past the leading '1' to get to the rest of the digits. This works for all n digit numbers.

2 Likes

Show us how you are sending the list PillData?

Thanks for this !! The trick worked and it shows all of the values i need at each compartment perfectly. Thanks alot! :smiley:

i am sending it the same as always :sunglasses:
image

Take care with that Clock3 Timer Interval. If it's too small, you will send multiple messages during the desired minute.

If it's too large, you will skip past the desired minute.

Also, what's keeping that global NowTime up to date, and why not use the Clock's FormatDateTime block to build a hhmm text for the comparison, using Clock1.Now()?