JSN-SR04 ultrasonic distance sensor library for Gen 3 devices

The JSN-SR04 is an inexpensive ultrasonic distance sensor. There are many manufacturers, some are weather resistant, and they have somewhat different supported ranges, but usually in the range of a few centimeters to maybe a few meters. Also note: these sensors are generally not all that reliable. I would not use one in a life-safety situation and be sure to code defensively for the case when it fails.

Once characteristic of the sensor is that you need to measure the pulse width to within a microsecond or so, and measurement takes around 150 microseconds of setup time and up to 29 milliseconds of pulse width (at 5 meters). At a more reasonable 1 meter, it’s still around 9 milliseconds.

The problem on Gen 3 devices (nRF52840) is that even if you use interrupts, the interrupt latency is high, and extremely variable. The radio stack runs at a high interrupt priority and will delay other interrupts until completion. Because of the long time to sample, you don’t want to disable interrupts because it will adversely affect the BLE radio, and the reset of the system. But if you do not disable interrupts, the interrupt latency makes for very inaccurate readings.

The solution is the technique used in this library: The nRF52840 I2S, note this is I2S, as in sound, not I2C, peripheral is really just a high-speed digital input and output device with hardware DMA. The library is configured to use 32,000 samples per second, with 16 bits per sample, stereo. This works out to a bit clock of 1 MHz, or 1 µs per sample bit, which is perfect for the JSN-SR04.

It works on all Gen 3 Particle devices (Argon, Boron, B Series SoM, Tracker SoM using the nRF52840 MCU). It does so without ever disabling interrupts and it’s accurate to less than 0.3 cm even when using the BLE radio. It does not require any timer resources, which are scarce on the nRF52.

It’s completely non-blocking and you can theoretically measure a distance every 10 milliseconds with a range up to 1 meter. It only generates two MCU interrupts per measurement, and if the interrupt delayed by higher priority interrupts, or disabled interrupts, it does not affect the accuracy of the timing.

It requires a lot of GPIO (4 GPIO) and some RAM (2,080 bytes for the default maximum of 1 meter, reconfigurable).

Full documentation and more information in the Github repository


Are there any GPIOs on the nRF52840 that are not exposed via pins and also not used otherwise?
Since two of the four are not actively used by the library anyhow otherwise inaccessible GPIOs on the chip would be less of a sacrifice :wink:



Thanks so much for this library. I spent a few days working with the JSN-SR04T and the A02YYUW and the solution turned out to be fairly easy with your help and the feedback of others (Desperately Seeking Serial). I am currently using Mode 1 which is the continuous broadcast mode. (Waterproof Ultrasonic Distance Sensors with Arduino) and this seems to work as advertised but I will definitely give your library a try!

I just installed my first official Flood Dog (flooddog.com) water monitor and it has a JSN-SR04T attached. My goal is to place 42 Flood Dogs around Toronto Island to measure and monitor ground, surface and lake water levels. This first unit, FloodDog-001, is mounted on a pole at the end of the QCYC railway pier. The transducer capsule is inserted into a custom mounting plate that sits into the wooden deck surface - the sensor points down to the water beneath. So far it seems to work but I will be cross checking the accuracy of these measurements against other devices. The JSN-SR04T is just one type of level sensor I am using - I will be experimenting with other types.

I’ve custom designed the project case and 3D print every single part including the cable glands and rubber gaskets. So far the ASA I’m printing with is water tight and super strong after several months of testing and design. The Boron is mounted on Chip’s Carrier Board which all sits on a mounting bracket that slides into the project case. The sensor pcb’s (such as the breakout for the JSN-SR04T) are mounted to adapter plates inside the case as needed. The project case and solar panel holder have cutouts for zip ties to attach to a post or pole. There are also ‘wings’ that can be screwed into wooden posts or face boards such as on the side of a floating dock to measure the tilt angle.

Thanks again Rick for all the hard work.


This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.