I am working on an embedded systems project these days which the core program is written in java to work on a raspberry pi 3 model b in raspbian os. We needed to connect few ultrasonic sensors for that device so i have written a java class to interface the HC-SR04 ultrasonic sensor with the raspberry pi using GPIO pins. I have used the pi4j library to controll the GPIO pins of the raspberry pi.
For the following test program, i have used GPIO pin 0 as the ECHO PIN and GPIO pin 1 as the TRIG PIN.
The third argument is REJECTION_START (long). To explain you what is the purpose of this argument, let me breifly explain you how we measure a distance from the HC-SR04 module. In order to get a distance reading from the ultrasonic sensor we need to keep the TRIG pin high state for 10us. If the TRIG pin kept high state for 10us, the sensor generate 8 cycle ultrasonic burst and put the ECHO pin state to high. The ECHO pin state change to low state once the echo reaches the sensor. Some times for various reasons eventhough we give signal to tigger the sensor it may not trigger that properly. In that case we would trigger that and wait so long and read incorrect reading. That is way i introduced the REJECTION_START parameter. What it will do is, after sending the trigger signal it will wait for REJECTION_START number of nano seconds and see whether the sensor identified that as a real trigger. If not, reading return you a negative value.
The fourth arugument is the REJECTION_TIME (long). Practically HC-SR04 has a maximum distance limit. In order to get accurate results we need to make sure our sensor reads and returns the mesurement if only whithin that range. So looking at the datasheets of your sensor, and considering about your need calculate a maximum allowable time for the echoed signal and put that value in nano seconds here.
See The GitHub Code
Test Program
public class Test_Ultrasonic{ public static void main(String[] args) throws Exception{ PiJavaUltrasonic sonic=new PiJavaUltrasonic( 0,//ECO PIN (physical 11) 1,//TRIG PIN (pysical 22) 1000,//REJECTION_START ; long (nano seconds) 23529411 //REJECTION_TIME ; long (nano seconds) ); System.out.println("Start"); while(true){ System.out.println("distance "+sonic.getDistance()+"mm"); Thread.sleep(1000); //1s } } }
Sensor Java Class
/** * HC-SR04 Ultrasonic sensor (return in mm) **/ import com.pi4j.io.gpio.GpioController; import com.pi4j.io.gpio.GpioFactory; import com.pi4j.io.gpio.GpioPinDigitalOutput; import com.pi4j.io.gpio.PinState; import com.pi4j.io.gpio.RaspiPin; import com.pi4j.io.gpio.*; public class PiJavaUltrasonic{ //bcm, GPIO_# private int PIN_ECHO,PIN_TRIG; private long REJECTION_START=1000,REJECTION_TIME=1000; //ns private GpioController gpio;//gpio controller ; using io.gpio private GpioPinDigitalOutput//gpio output pins; using io.gpio, digital pins pin_trig; private GpioPinDigitalInput pin_echo; public PiJavaUltrasonic(int ECHO, int TRIG, long REJ_START,long REJ_TIME){ //GPIO this.PIN_ECHO=ECHO; this.PIN_TRIG=TRIG; this.REJECTION_START=REJ_START; this.REJECTION_TIME=REJ_TIME; gpio=GpioFactory.getInstance();// create gpio controller , io.gpio pin_trig=gpio.provisionDigitalOutputPin(RaspiPin.getPinByAddress(PIN_TRIG), "pin_trig", PinState.HIGH);//pin,tag,initial-state pin_trig.setShutdownOptions(true, PinState.LOW); pin_echo=gpio.provisionDigitalInputPin(RaspiPin.getPinByAddress(PIN_ECHO),PinPullResistance.PULL_DOWN);//pin,tag,initial-state } public int getDistance() throws Exception{ //in milimeters int distance=0; long start_time, end_time,rejection_start=0,rejection_time=0; //Start ranging- trig should be in high state for 10us to generate ultrasonic signal //this will generate 8 cycle sonic burst. // produced signal would looks like, _|-----| pin_trig.low(); busyWaitMicros(2); pin_trig.high(); busyWaitMicros(10); pin_trig.low(); //echo pin high time is propotional to the distance _|----| //distance calculation while(pin_echo.isLow()){ //wait until echo get high busyWaitNanos(1); //wait 1ns rejection_start++; if(rejection_start==REJECTION_START) return -1; //something wrong } start_time=System.nanoTime(); while(pin_echo.isHigh()){ //wait until echo get low busyWaitNanos(1); //wait 1ns rejection_time++; if(rejection_time==REJECTION_TIME) return -1; //infinity } end_time=System.nanoTime(); distance=(int)((end_time-start_time)/5882.35294118); //distance in mm //distance=(end_time-start_time)/(200*29.1); //distance in mm return distance; } public static void busyWaitMicros(long micros){ long waitUntil = System.nanoTime() + (micros * 1_000); while(waitUntil > System.nanoTime()){ ; } } public static void busyWaitNanos(long nanos){ long waitUntil = System.nanoTime() + nanos; while(waitUntil > System.nanoTime()){ ; } } }