I'm working on a project where I display the distance from the VL53L0X ToF Distance Sensor to my hand on a led strip which is working fine. But when I remove my hand the sensor value obviously jumps up. Is there a way that I can let it act more like a potentiometer or a rotary encoder, where you can change the value but after changing it it stays on that value?
If anyone has a good reference I can read into or can point me in a certain direction, it would be very much appreciated.
Thanks!
#include <FastLED.h>
#include <Wire.h>
#include <VL53L0X.h>
#include <MedianFilter.h>
#define NUM_LEDS 60
#define DATA_PIN 3
// Define the array of leds
CRGB leds[NUM_LEDS];
VL53L0X sensor;
MedianFilter test(10, 0);
int val = 0;
void setup() {
FastLED.addLeds<WS2813, DATA_PIN, GRB>(leds, NUM_LEDS); // GRB ordering is typical
Serial.begin(9600);
Wire.begin();
sensor.setTimeout(500);
if (!sensor.init())
{
Serial.println("Failed to detect and initialize sensor!");
while (1) {}
}
#if defined LONG_RANGE
// lower the return signal rate limit (default is 0.25 MCPS)
sensor.setSignalRateLimit(0.1);
// increase laser pulse periods (defaults are 14 and 10 PCLKs)
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
#endif
#if defined HIGH_SPEED
// reduce timing budget to 20 ms (default is about 33 ms)
sensor.setMeasurementTimingBudget(20000);
#elif defined HIGH_ACCURACY
// increase timing budget to 200 ms
sensor.setMeasurementTimingBudget(200000);
#endif
}
void loop() {
//Median filter
val = sensor.readRangeSingleMillimeters();
test.in(val / 10);
val = test.out();
Serial.print(val);
if (sensor.timeoutOccurred()) {
Serial.print(" TIMEOUT");
}
Serial.println();
//Turning leds on and off
if (val >= 15) {
leds[0] = CRGB::Red;
FastLED.show();
} else {
leds[0] = CRGB:: Black;
FastLED.show();
}
if (val >= 17) {
leds[1] = CRGB::Red;
FastLED.show();
} else {
leds[1] = CRGB:: Black;
FastLED.show();
}
if (val >= 19) {
leds[2] = CRGB::Red;
FastLED.show();
} else {
leds[2] = CRGB:: Black;
FastLED.show();
}
if (val >= 20) {
leds[3] = CRGB::Red;
FastLED.show();
} else {
leds[3] = CRGB:: Black;
FastLED.show();
}
if (val >= 21) {
leds[4] = CRGB::Red;
FastLED.show();
} else {
leds[4] = CRGB:: Black;
FastLED.show();
}
if (val >= 22) {
leds[5] = CRGB::DarkOrange;
FastLED.show();
} else {
leds[5] = CRGB:: Black;
FastLED.show();
}
if (val >= 23) {
leds[6] = CRGB::DarkOrange;
FastLED.show();
} else {
leds[6] = CRGB:: Black;
FastLED.show();
}
if (val >= 24) {
leds[7] = CRGB::DarkOrange;
FastLED.show();
} else {
leds[7] = CRGB:: Black;
FastLED.show();
}
if (val >= 25) {
leds[8] = CRGB::DarkOrange;
FastLED.show();
} else {
leds[8] = CRGB:: Black;
FastLED.show();
}
delay(20);
}
How is the program supposed to know "31" is the value you want to keep?
There an intervening "41" in there. If the value going up is the signal to keep a value there are a whole load of examples of the value "going up" in your example, including the increase from 41 to 819.
Perhaps you should only keep the value if it is less than some threshold.
if (val < 800)
{
kept_val = val;
}
Also I doubt your code compiles. There doesn't seem to be a declaration for variable 'val' anywhere.
Edit: I see you modified your post (after I copied and pasted your sketch) and corrected that. Thanks.
Also you only need one call to FastLED.show(); Just put it at the bottom of loop.
Edit: Karma added for using code tags on a first post. Well done.
pcbbc:
How is the program supposed to know "31" is the value you want to keep?
There an intervening "41" in there. If the value going up is the signal to keep a value there are a whole load of examples of the value "going up" in your example, including the increase from 41 to 819.
Perhaps you should only keep the value if it is less than some threshold.
if (val < 800)
{
kept_val = val;
}
~~Also I doubt your code compiles. There doesn't seem to be a declaration for variable 'val' anywhere.~~
Edit: I see you modified your post (after I copied and pasted your sketch) and corrected that. Thanks.
Also you only need one call to FastLED.show(); Just put it at the bottom of loop.
Edit: Karma added for using code tags on a first post. Well done.
I tried using a threshold and it solves the problem but there is still this jump in the signal which can be removed with a longer delay but also makes it less responsive on my input.
But from the structure of what you have posted, I think...
It might help a lot if you used the value read from the sensor as the threshold before adding it into the median filter.
If you add the 800+ value into the median filter before you get the new median value, you have of course artificially increased the median by the value of one out-of-range sample.
So sequence of events should be...
a) Read sensor value
b) if sensor value < threshold: read median value, illuminate LEDs accordingly
c) Add new sensor value into median
Even better results are probably to be had by never adding any out-of-range sensor values into the median at all.
maximaalmax:
I tried using a threshold and it solves the problem but there is still this jump in the signal which can be removed with a longer delay but also makes it less responsive on my input.
my master's thesis was abnormal arrhythmia (heartbeat) detection. the code captured the last so many samples, would recognize peaks and valleys and at some point decide the capture buffer has a complete heartbeat and process it.
sometimes you need to recognize that the event you're interested in has already occurred and you need to look at a past set of samples.