I'm having problems using an HC-SR04 ultrasonic sensor in conjunction with an LED display module. The sensor appears to work fine when outputting values to the serial monitor, measuring distances up to the rated maximum of around 3m. However when I connect the display module the maximum distance displayed drops to about 50 or 60cm.
I've tried both a TM1637 four-digit seven-segment display module using the TM1637Display library and a Max7219 eight-digit seven-segment display using the LedControl library. Using the NewPing library's ping_cm()
function for distance measurement instead of the pulseIn()
function makes no difference.
I'm tending to think it's either something in the LED module libraries that interferes with the measurement of pulses, or possibly noise and ripple on the power supply.
I tried twisting the longer power and data wires together. I've also added a 0.1uF ceramic capacitor across the power connections to the ultrasonic sensor and a 0.1uF ceramic and 2.2uF electrolytic capacitor across the power rails at the point of connection to the display module. This appeared to improve the reliability of the Max display, which previously showed a garbled display from time to time, but didn't make any difference to the range problem.
I've tried powering the Arduino with a 9V wall adapter and well as the USB supply from my PC. This makes no difference. As far as I can trust my multimeter, the supply voltage to the sensor is adequate; between 5.02V and 4.95V depending on the distance the sensor is measuring (the voltage reduces slightly when sensing longer distance). Unfortunately I don't have access to an oscilloscope so I can't see what's happening at a higher frequency. I had hoped the electrolytic capacitor would help smooth out voltage fluctuations.
My current work-around is to disable the display while the sensor measures distance. With the LedControl library, I can do this immediately before reading the pulse duration. With the the TM1637Display library I found I had to clear the display before triggering the sensor. In both cases, the display will then show the correct distance but flickers in proportion to the measurement distance (the longer the distance the longer pulseIn()
has to wait for the echo).
#include <TM1637Display.h>
// Module connection pins (Digital Pins)
#define CLK 7
#define DIO 6
#define ECHO 5
#define TRIG 4
TM1637Display display(CLK, DIO);
void setup(){
pinMode(TRIG, OUTPUT);
pinMode (ECHO, INPUT);
display.setBrightness(7, true);
}
void loop(){
long duration; // duration in us
long distance; // distance in cm
display.clear();
// This is the workaround described above; without this line
// the sensor cannot measure any more than about 50 or 60cm.
// With this line, the sensor measures up to about 3m but
// obviously the display flickers every time around the loop.
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
duration = pulseIn(ECHO, HIGH, 20000);
// a 20ms (20000us) timeout corresponds to the maximum sensor range (3.4m approx)
// Since the speed of sound is approx 340m/s, i.e. roughly 29 us/cm
// we can divide duration (us) by 29 and again by 2 (pulse travels
// out and back) to obtain a distance from sensor in cm:
distance = duration / 29 / 2;
display.showNumberDec(distance, false); // true shows leading zeros
delay(250);
}
Any suggestions?
display.clear()
display.clear()
is the only way I can actually get a decent reading (code commented to clarify). @arcube: I've measured the voltage to be between about 4.9V and 5.0V (paragraph on voltage measurement added).