UART/Serial Port Emulation over BLE protocol

My device can only take commands over the uart serial port. But since arduino and device can not be connected by wires, so I am trying to use bluetooth for communication. My end goal is to send data over bluetooth but for other arduino it must consider it is a uart data. I found HardwareBLESerial library which helps me do this over the phone app but not between two Arduinos.

Below is the code I used to connect other Arduino nano BLE 33 and send

#include <HardwareBLESerial.h>

HardwareBLESerial &bleSerial = HardwareBLESerial::getInstance();

 BLEDevice peripheral;
 BLECharacteristic peripheralCharacteristic;
 
void setup() {
Serial.begin(19200);
  while (!Serial);
  // initialize the BLE hardware
  BLE.begin();
  Serial.println("BLE Central Scan - control");
  // start scanning for BLE peripherals

 // while (!BLE.scanForName("AP-8400-_C8C0")){
 while (!BLE.scanForName("Echo")){
    delay(500);
    Serial.println(".");
  }

  // check if a peripheral has been discovered
  peripheral = BLE.available();

  while (!peripheral){
    peripheral = BLE.available();
     Serial.print(":");
     delay(500);
  }

// retrieve the BLE characteristic
peripheralCharacteristic = peripheral.characteristic("Echo");

    while (peripheral.connect()){
    Serial.println("Connected");
    
    // discovered a peripheral, print out address, local name, 
    Serial.println("Found ");
    Serial.println(peripheral.address());
    Serial.println(" '");
    Serial.println(peripheral.localName());
    Serial.println("' ");
    Serial.println("----------");

    Serial.print("RSSI = ");
    Serial.println(BLE.rssi());

 //   peripheral.connect();
    }

    while(!peripheral.connect()){
     delay(500);  
    }
   bleSerial.print("Hello");
//   bleSerial.write('H');
//   bleSerial.write('e'); 
//   bleSerial.write('l');
//   bleSerial.write('l');
//   bleSerial.write('o');
}

void loop() {
    // this must be called regularly to perform BLE updates
    bleSerial.poll();
  
      bleSerial.print("You said: ");
      char line[128]; bleSerial.readLine(line, 128);
     Serial.println(line);

    delay(1000);
  }

On the other Arduino I was only spitting back what I heard from first Arduino.

#include <HardwareBLESerial.h>

HardwareBLESerial &bleSerial = HardwareBLESerial::getInstance();

void setup() {
  if (!bleSerial.beginAndSetupBLE("Echo")) {
    Serial.begin(19200);
    while (true) {
      Serial.println("failed to initialize HardwareBLESerial!");
      delay(1000);
    }
  }
}

void loop() {
  // this must be called regularly to perform BLE updates
  bleSerial.poll();

  while (bleSerial.availableLines() > 0) {
    bleSerial.print("You said: ");
    char line[128]; bleSerial.readLine(line, 128);
   // bleSerial.println(line);
   Serial.println(line);
  }
  delay(500);
}

But I don't see any data receiving onn either end. Can someone help me with this?

May I ask why? BLE was explicitly designed to not being a serial replacement but a modern, cheap and energy efficient protocol that provides a simple application layer interface trough characteristics and services.

Bluetooth Classic might be a better choice. Why are you using Nano 33 BLE's in your project?

My device can receive data over BLE but to run it as a command for the device it must consider it as a uart data.

Can you explain a bit more about this please? I can change my device if that helps having a UART port emulation over BLE protocol.

Can you please provide more documentation about the device you are trying to communicate with? What is the documented communication protocol?

When I connect it to my laptop I use Modbus protocol over RS-485 which is a UART type. This is all I could find. The device also has a BLE on board with which I am trying to communicate.

To begin with, I want to use two Arduinos and test if this works. When I used the example codes in the HardwareBLESerial library it worked great with the mobile bluefruit LE connect App by Adafruit. But when I am trying to connect two Arduinos it doesn't work.

Also, upon reading a bit more on Bluetooth classic and BLE ; since my application doesn't need to send a lot of data but the Arduino only needs to send it local address or BLE name, something to be unique identified for other device to know that it is present.

I think for this application Nano 33 BLE does make sense to me. But I am open for ideas that might provide me a working solution.

Did you consider separating the BLE interface and the protocol over Modbus?

I do not know enough about your application to be more specific. Let say there are a couple of characteristics that represent some settings for a machine. You can set them individually and then the device handling modbus creates a sequence of bytes that are send. The bytes can come from different characteristics.

If you can describe your system a bit more we can probably provide you some better advice.

I understood the problem. I was not writing to their characteristic value. I didn't know how the blueooth protocol works. And Arduino nano 33 BLE uses UART for physical portocol for its BLE. So my problem is solved.

Why do you believe that? The Arduino Nano 33 BLE uses a Nordic nRF52840 that has a fully featured build-in 2.4GHz radio. The UART is not used for BLE or any other radio protocol.
Your Arduino sketch runs on the same processor as the BLE stack.

BLE uses UART or USB for physical communication, right? I remember reading something like that.

The Nano 33 BLE board uses UART or USB for wired communication to another device. The BLE radio and the M4 processor in the nRF52840 are integrated and do not communicate with each other over UART or USB.

I'm not certain what you read in the past, but either you are misinterpreting the article or it is wrong.

1 Like

Just confirming what cattledog said.

There are other solutions that use separate Bluetooth modules that are controlled over UART. That is not the case for the Arduino Nano 33 BLE.

1 Like

I took a look at the library you used, and we have been at cross purposes throughout this thread and not understanding each other.

That library uses Nordic Semiconductor UART service and the Tx, Rx Characteristics associated with that service.

BLEService uartService = BLEService("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
BLECharacteristic receiveCharacteristic = BLECharacteristic("6E400002-B5A3-F393-E0A9-E50E24DCCA9E", BLEWriteWithoutResponse, BLE_ATTRIBUTE_MAX_VALUE_LENGTH);
BLECharacteristic transmitCharacteristic = BLECharacteristic("6E400003-B5A3-F393-E0A9-E50E24DCCA9E", BLENotify, BLE_ATTRIBUTE_MAX_VALUE_LENGTH);

It would appear that the device you are trying to send/receive data from the Nano33 BLE is configured to use the Nordic UART service by default.

It appears that you have figured out how to connect with the Nano33 BLE and communicate.

1 Like

Hey @cattledog ,

Thank you for this explanation. I am using Microchip RN4871 BLE module with Arduino. The BLE module on device is designed to take data over bluetooth and send send it to other microcontroller over UART. This is my assumption, I might be wrong.

What I noticed was, the microchip has uuid on it. But my device didn't so I had to connect to it using its name and then trying to write to characteristic uuid which is where I was making mistake. I was writing to the wrong uuid.