Ultrasonic Sensor, pulseIn() [SOLVED]

I want to use my ultrasonic sensor on the Core. I have used it before on arduino.
I tried to use an old arduino script, but it seems that pulseIn() is not recognized in the core.

Where can I find example code ?

Hi @Jack

See this thread for some details:

Searching for pulseIn is how I found this again.


Hi @Jack,
You can find the library and sample code for Ultrasonic rangefinder in the web ide (Particle Build). Just go to libraries and search for “HC_SR04” .
Hope this helps.web Ide


@VigneshA, yes, that was a big help. I tried it, and it seems to be working as well as can be expected of an ultrasonic sensor. I will add some averaging to the results, and may prevent it from jumping around so much. I have tested it on the work bench, but not yet with water. I am not sure how well ultrasonic will detect water. When I test with water, I will post an update here. Thanks

1 Like

You can also try to use a float on the water, of wich the ultrasonic can bounce. Might help.

Thanks Moors7, I will try that if the water surface does not provide enough accuracy.

@Jack, I ported and tried @timb’s pulseIn code and it totally unreliable and unusable IMO.

1 Like

Thanks @peekay123, for checking the pulseIn() code out.
I have since found an example, and library for Ultrasonic Sensor for the Core. @VigneshA pointed me to the HC_SR04 in the library, and I am testing it today with good results.

1 Like

@peekay123, my ultrasonic sensor is putting out readings all around. I need a good averaging calculation, to average like the last 25 readings. How is a good way to do that?

@Jack, two ways. One, accumulate 25 readings and divide by 25. Or, do a rolling average where you take the first two readings, add them and divide by 2. On the third reading, add it to the previous average and divide by 2 and so on. The first requires 25 readings before you get an average. The second gives you a value after the first two readings with subsequent readings (hopefully) converging that value to a stable average.

I suggest that with either method you do some bounds checking to make sure your values are not out of whack and knock you average out. :smile:


Oh, I think I see. the rolling average is really a weighted average, giving more weight to the most recent reading, rather than a flat average of the last 25 readings. Actually it does not take into account 25 at all. That may be the best, since my water level will change fairly slowly.

The hc_sr04 library already checks bounds, and will return -1 if out of bound, so makes it easier for me (only use values greater than 0).

1 Like

The name of the library is HC_SR04, which is what you need to search for in order to find it. Note the underscore vs. dash.


@jogleasonjr Thanks for pointing out . I have corrected it now .

1 Like

I appreciate you correcting the typo I had,
In my library, all you need to type is HC and it is found (only one on the list then). So, in order to find it, just type HC

Thanks, Jack

I’ve been working on creating a water tank level monitor also, and rather than using pulseIn, I used an interrupt approach. I connected the echo pin of the HC_SR04 to both D2 and D4. Both of these pins are attached to interrupts, one to detect the rising edge, and the other to detect the falling edge. This seems to work fine, so I would be interested to know if anyone knows if the pulseIn approach is better (more accurate, more stable) for some reason.

int trigPin = D0;  
int echoRisingPin = D2;
int echoFallingPin = D4;
unsigned long startTime;
unsigned long endTime;
long distance;

void setup() {
    pinMode(trigPin, OUTPUT);
    attachInterrupt(echoRisingPin, risingDetect, RISING);
    attachInterrupt(echoFallingPin, fallingDetect, FALLING);
    digitalWrite(trigPin, LOW);

void loop() {
    digitalWrite(trigPin, HIGH);
    digitalWrite(trigPin, LOW);

void risingDetect() {
    startTime = micros();

void fallingDetect() {
    endTime = micros();
    distance = (endTime - startTime)/5.82; // distance in millimeters;
    if (distance > 0 && distance < 2000) {

I can’t talk from experience, but an advantage of pulseIn() (which doesn’t seem to be an official function on the Particles) is that it only uses one pin.
But with a CHANGE trigger and a flag, you can do the same thing.

If you want, you can have a look in the link in the second post to see how pulseIn() does it.
This way you can see which approach you prefer.