Problem with the program measuring the distance with the HC-SR04 sensor and using bluetooth

Hello, I have a problem with a program written in arduinio using seeed xiao board nrf52840, HC-SR04 distance sensor.

The board is supposed to connect to the phone via the built-in bluetooth module.
I wrote the program using the arduinoBLE.h library, based on the
examples from this library. When the program is simple and is supposed to turn off
or turn on the LED after receiving data sent from the application there is no
problem. The same with the control of a servo motor powered by a separate
inverter.

The problem arises when trying to read the distance using the aforementioned
aforementioned sensor. In this case, when trying to connect, it pops up a
information about the time lapse being too long. The sensor at that time works and
shows the correct distance and sends it to the serial monitor.

Does anyone know why I can’t make the connection, or how to modify the program so I can connect to the board.

I am attaching my program below.

#include <ArduinoBLE.h>

#define trigPin 0
#define echoPin 1
#define SOUND_SPEED 34300               // cm/s
#define TIME_TO_DIST 0.5 * SOUND_SPEED  // cm/us

BLEService sensor("23a157c2-14f7-4e5f-88cd-bc39298c1579");  

BLEIntCharacteristic move("23a157c3-14f7-4e5f-88cd-bc39298c1579", BLERead | BLEWrite);

long distance;

void setup() {
  Serial.begin(115200);

  if (!BLE.begin()) {
    Serial.println("starting Bluetooth® Low Energy module failed!");

    while (1)
      ;
  }
  pinMode(LEDB, OUTPUT);     
  digitalWrite(LEDB, HIGH);  
  pinMode(trigPin, OUTPUT);  // Sets the trigPin as an Output
  pinMode(echoPin, INPUT);   // Sets the echoPin as an Input

  BLE.setLocalName("sensor");
  BLE.setAdvertisedService(sensor);

  sensor.addCharacteristic(move);

  BLE.addService(sensor);

  move.writeValue(0);

  BLE.advertise();

  Serial.println("starting Bluetooth®");
}
delayMicroseconds

void loop() {
  BLEDevice central = BLE.central();
  if (central) {
    digitalWrite(LEDB, LOW);
    Serial.print("Connected to central: ");
    Serial.println(central.address());
    if (central.connected()) {
      while (central.connected()) {
        digitalWrite(trigPin, LOW);
        delayMicroseconds(2);
        digitalWrite(trigPin, HIGH);
        delayMicroseconds(10);
        digitalWrite(trigPin, LOW);
        long duration = pulseIn(echoPin, HIGH);

        distance = duration * TIME_TO_DIST;
        delay(1);
        Serial.print("Distance: ");
        Serial.print(distance);
        Serial.println(" cm");
        delay(1);
      }
    }
    Serial.print("Disconnected from central: ");
    Serial.println(central.address());
    digitalWrite(LEDB, HIGH);
  }
}

Hi there, and Welcome.
Have you tried swapping the echo and trigger pins?
Are you able to leave the BLE stuff out and get it to display the reading on the serial port?
Also maybe inverting the logic for the 10us. pulse generation. The error sounds like it’s NOT liking the timing of it?
Are you saying when you try the BLE connection it throws the error?
In your Read BLE , Do you define the length of the string or vale (digits)
What Board support package , mbed or non? for the Nrf52840
You are close though…
HTH
GL :slight_smile: PJ

1 Like

Hi MagnusBuzard,

The following link may be helpful.
Arduino pulseIn() With Interrupts - The Robotics Back-End

The attached code will probably work fine.
nRF52_XIAO_mbed_HC-SR04_INT_periphrral.zip (1.1 KB)

1 Like

You can modify the code like this:

void loop() {
  BLEDevice central = BLE.central();

  if (central) {
    digitalWrite(LEDB, LOW);
    Serial.print("Connected to central: ");
    Serial.println(central.address());

    while (central.connected()) {
      readDistance(); // Separate function for distance reading
      delay(1000);    // Adjust delay based on your requirements
    }

    Serial.print("Disconnected from central: ");
    Serial.println(central.address());
    digitalWrite(LEDB, HIGH);
  }
}

void readDistance() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  long duration = pulseIn(echoPin, HIGH);
  distance = duration * TIME_TO_DIST;

  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");
}

It turned out that this library doesn’t like much with the pulsein function, which blocks rest of the code. I simply did the time counting with micros() and everything works as expected, thanks for your help.

1 Like