Help with HC-SRO4 Ultrasonic sensor controlling brightness of Neopixels

Hi, I'd be really appreciative of some help! I am trying to control the brightness of my Neopixel with a HC-SRO4 Ultrasonic sensor and so far my code works but quite clunkily. The transition of the brightness is not smooth and at some points the light even temporarily cuts out. Can anyone please help me get a smoother transition?

Here is my code:

#define echoPin 2 // attach pin D2 Arduino to pin Echo of HC-SR04
#define trigPin 3 //attach pin D3 Arduino to pin Trig of HC-SR04

// defines variables
long duration; // variable for the duration of sound wave travel
int distance; // variable for the distance measurement
int brightness; //variable for the brightness measurement

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

#define PIN      6
#define NUMPIXELS 7

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); //Determines the number of LEDs and Arduino pins.

#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels

void setup() {
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an OUTPUT
  pinMode(echoPin, INPUT); // Sets the echoPin as an INPUT
  Serial.begin(9600); // Serial Communication is starting with 9600 of baudrate speed

  pixels.begin();//Does the initialisations.
}
void loop() {
  
  // Clears the trigPin condition
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  
  // Sets the trigPin HIGH (ACTIVE) for 10 microseconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  
  // Calculating the distance
  distance = duration * 0.034 / 2; // Speed of sound wave divided by 2 (go and back)

  pixels.clear();
  pixels.setPixelColor(0, pixels.Color(253, 244, 200)); //Defines the LEDs color with the RGB system, after specifying the LED number (from 0 to NUMPIXELS-1). 
  pixels.setPixelColor(1, pixels.Color(253, 244, 200));
  pixels.setPixelColor(2, pixels.Color(253, 244, 200));
  pixels.setPixelColor(3, pixels.Color(253, 244, 200));
  pixels.setPixelColor(4, pixels.Color(253, 244, 200));
  pixels.setPixelColor(5, pixels.Color(253, 244, 200));
  pixels.setPixelColor(6, pixels.Color(253, 244, 200));
  
  if(distance <= 20) {
  brightness = map(distance, 0, 20, 255, 1);
  pixels.setBrightness(brightness); 
  delay(100);
  }
  else {
  pixels.setBrightness(0); 
  delay(100);
  }
  pixels.show(); //Displays the applied values.
 
  // Displays the distance on the Serial Monitor
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.print(" cm ");
  Serial.print("Brightness: ");
  Serial.println(brightness);
}

Thanks so much!

Do the values of distance and brightness look correct when you print them ?

1 Like

How about trying a median filter on the range values?

1 Like

Hi,
try this code.

#define echoPin 2 // attach pin D2 Arduino to pin Echo of HC-SR04
#define trigPin 3 //attach pin D3 Arduino to pin Trig of HC-SR04

// defines variables
long duration; // variable for the duration of sound wave travel
int distance; // variable for the distance measurement
int brightness; //variable for the brightness measurement
int lastBrightness;
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define PIN      6
#define NUMPIXELS 7
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); //Determines the number of LEDs and Arduino pins.
#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels
//---------------------------------------------------------------------
void setup() {
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an OUTPUT
  pinMode(echoPin, INPUT); // Sets the echoPin as an INPUT
  Serial.begin(9600); // Serial Communication is starting with 9600 of baudrate speed
  pixels.begin();//Does the initialisations.
}
//---------------------------------------------------------------------
void loop() {
  digitalWrite(trigPin, LOW);         // Clears the trigPin condition
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);        // Sets the trigPin HIGH (ACTIVE) for 10 microseconds
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);  // Reads the echoPin, returns the sound wave travel time in microseconds
  // Calculating the distance
  distance = duration * 0.034 / 2;    // Speed of sound wave divided by 2 (go and back)
  pixels.clear();
  pixels.setPixelColor(0, pixels.Color(253, 244, 200)); //Defines the LEDs color with the RGB system, after specifying the LED number (from 0 to NUMPIXELS-1).
  pixels.setPixelColor(1, pixels.Color(253, 244, 200));
  pixels.setPixelColor(2, pixels.Color(253, 244, 200));
  pixels.setPixelColor(3, pixels.Color(253, 244, 200));
  pixels.setPixelColor(4, pixels.Color(253, 244, 200));
  pixels.setPixelColor(5, pixels.Color(253, 244, 200));
  pixels.setPixelColor(6, pixels.Color(253, 244, 200));
  if (distance <= 20) {
    brightness = map(distance, 0, 20, 255, 1);
    brightness = (brightness + lastBrightness) / 2;
    lastBrightness = brightness;
  }
  else {
    brightness = (brightness - lastBrightness) / 2;
    if (brightness < 0)
      brightness = 0;
    lastBrightness = brightness;
  }
  pixels.setBrightness(brightness);
  //delay(100);
  pixels.show();                      //Displays the applied values.
  Serial.print("Distance: ");         // Displays the distance on the Serial Monitor
  Serial.print(distance);
  Serial.print(" cm ");
  Serial.print("Brightness: ");
  Serial.println(brightness);
}
1 Like

Thanks everyone for the replies, I really appreciate it! The values were fine, I realised that there was not a delay between each distance reading and so added one and now it works great!

The code you posted has a minimum 100ms delay between readings

out of curiosity tried this code and it's great, with an even better result! Thanks so much :slight_smile: