Nano BLE Sense and ultrasonic sensor

Hi Arduiners,

I was so excited about getting this Nano BLE Sense that I have not thought about all potential compatibility issues. Probably the newbie's (lack of) mindset.

I am currently using an ultrasonic sensor JSN-SR04T (very similar to HC-SR04 - the code works very well for both). But when I compile the same code as used with Arduino Nano v3, an error occurs on 'PulseIn' function : " undefined reference to 'PulseIn' " / "collect2.exe: error: ld returned 1 exit status"

Do you have any idea how I can get that function to work for Nano BLE sense ?

Thanks for your support,
B.

Unfortunately, the pulseIn function has not yet been added to the core library of the Nano 33 BLE sense.

Is there any possible alternative ?
Can we help in this matter ?

Boibelo:
Is there any possible alternative ?

It's easy enough to write our own version of pulseIn() using digitalRead(). Just add this to the top of your sketch:

// function prototype to define default timeout value
static unsigned int newPulseIn(const byte pin, const byte state, const unsigned long timeout = 1000000L);

// using a macro to avoid function call overhead
#define WAIT_FOR_PIN_STATE(state) \
  while (digitalRead(pin) != (state)) { \
    if (micros() - timestamp > timeout) { \
      return 0; \
    } \
  }

static unsigned int newPulseIn(const byte pin, const byte state, const unsigned long timeout) {
  unsigned long timestamp = micros();
  WAIT_FOR_PIN_STATE(!state);
  WAIT_FOR_PIN_STATE(state);
  timestamp = micros();
  WAIT_FOR_PIN_STATE(!state);
  return micros() - timestamp;
}

and then change the pulseIn() calls to newPulseIn.

Arduino's pulseIn function is much superior to this one because it's highly optimized for performance. Using the high level code like I have done in my newPulseIn() is not appropriate when you are trying to get very precise timing of pulses that are in the microseconds. There is much more overhead to this high level code that will make newPulseIn less accurate. Since the Nano 33 BLE is pretty fast, hopefully it won't be as significant as if we were doing this on one of the lower performance boards.

Boibelo:
Can we help in this matter ?

Sure! You are welcome to submit a pull request adding the pulseIn (and hopefully pulseInLong too) code to the Arduino nRF528x Boards (Mbed OS) core library:

There is already a function prototype for the function here:

(ArduinoCore-API is put in the cores/arduino/api subfolder of the Arduino nRF528x Boards (Mbed OS) hardware package when it is released)
So you only need to add the definition of the function. I would follow the Arduino SAMD Boards core's convention of defining it in cores/arduino/pulse.c and cores/arduino/pulse_asm.S:

I should note that it's possible I have diverged a bit from the timeout behavior of the official Arduino pulseIn() in my newPulseIn() implementation. I grabbed this code out of a project I did a few years ago using an ESP8266 and an ultrasonic sensor, where I didn't like the timeout behavior of their pulseIn. I had written this comment:

//This is a modified version of pulseIn() that times out if there has not been a state change on the pin in longer than the timeout duration(instead of timing out after the set duration from the call of the function as in the original pulseIn()). The reason for this change is that I want to set a maximum return value and the original function always gives a shorter return value than the timeout because of the time waiting for the pin to go !state the first time.

I don't remember whether the problem was that the ESP8266 version of the function had a different behavior from the official Arduino pulseIn (the ESP8266 developers have been known to do that sort of thing), or whether I was unhappy with the pulseIn behavior in general. So if you are going to submit a pull request, make sure to use the official pulseIn code as your reference for how it should work, rather than my newPulseIn.

Hi,

It took me quite a long time to answer as I was debugging other things (and eventually opening some bottles for the xmas break...).

!! HAPPY NEW YEAR TO YOU !!

Thanks a lot Pert for you clear answers. Unfortunately I don't have the skills to get my hands into the genuine low level PulseIn code for this new MCU. But I have tested your code and it works pretty well as I would need today.

If time comes when I need more efficiency/accuracy within my system, I'll let you know.

BR,
B.

You're welcome. I'm glad to hear it's working now. Enjoy!
Per

I got the same trouble. I changed ultrasonic.cpp in the library and common.h in api folder. The result was not good. Could you tell us how to do step by step ?

  1. change pulseIn() to newPulseIn() in ultrasonic.cpp and insert codes shown above on the top of the ultrasonic.cpp.
  2. change old common.h to new one included in the cores/arduino/api folders.
    Are these steps wrong ?

Thank you, Hiroshi