I have built a setup with WS2812 Leds, that follow the movement of your hand over the ledstrip, quite magic. I have used a Sharp GP2Y0A02YK0F IRSensor. This one has trouble reading distance between 0 and 20 cm. Because the are obstacles, I tried to "guide/aim" the sensor through a 32mm tube, painted black on the inside. It will still detect something and the measurement is not correct. I now stubled over the HC-SR04 Ultrasonic, which operates from 2cm on. So I decided I need this one. The coding of these two sensors is completely different!
For the IRSensor I used this code (from makerblog.at, nice tutorials in german but not updated anymore, so no help from there, I am afraid. The link below leads to a video of what I want with the Ultra Sonic Sensor)
/* WS2812B LED Stripe Magic - Demo
*
* Sharp IR Sensor: Analog Pin A0
* WS 2812B NeoPixel Pin: Digital 6
*
* More information http://www.makerblog.at/2016/12/der-magische-ws2812b-led-streifen/
*
*/
#include <Adafruit_NeoPixel.h>
#define PIN 6
#define NUMPIXELS 58
#include <SharpIR.h>
#define ir A0
// Running average variables
const int numReadings = 20;
int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
int newValue = 0;
int lastpixel = 0;
SharpIR sharp(GP2Y0A02YK0F, A0);
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(115200);
pixels.begin(); // This initializes the NeoPixel library.
//pixels.brightness(250,250,250);
// Reset running average array
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
}
}
void loop() {
int dis=sharp.getDistance(); // this returns the distance to the object
// map distance to LED strip
// map 20-110cm distance to LEDs #0 to #59
// play with this value to match your LED strip
int dispix = map(dis,18,80,0,58);
// Ignore results out of bound, send -10 to average array instead
// This leads to LED marker gliding to end of strip when no object is within distance
if ((dispix >= 0) && (dispix < 58)) {
newValue = dispix;
} else {
newValue = -10;
}
// Running average code from
// https://www.arduino.cc/en/Tutorial/Smoothing
// subtract the last reading:
total = total - readings[readIndex];
// read from the sensor:
readings[readIndex] = newValue;
// add the reading to the total:
total = total + readings[readIndex];
// advance to the next position in the array:
readIndex = readIndex + 1;
// if we're at the end of the array...
if (readIndex >= numReadings) {
// ...wrap around to the beginning:
readIndex = 0;
}
// calculate the average:
int avePos = total / numReadings;
// set LEDs with following function and show them
draw(avePos);
pixels.show();
}
// Simple function resetting all pixels and lighten some around desired distance
void draw(int pix) {
for (int i=0; i<58; i++) {
pixels.setPixelColor(i, pixels.Color(2,1,1));
}
pixels.setPixelColor(pix-2, pixels.Color(150,0,30));
pixels.setPixelColor(pix-1, pixels.Color(80,0,100));
pixels.setPixelColor(pix, pixels.Color(10,0,250));
pixels.setPixelColor(pix+1, pixels.Color(80,0,50));
pixels.setPixelColor(pix+2, pixels.Color(150,0,20));
}
Now I am trying to adapt this code to the new sensor, the HC-SR04 Ultrasonic but I get lost in translation:
/* WS2812B LED Stripe Magic - Demo
*
* Sharp IR Sensor: Analog Pin A0
* WS 2812B NeoPixel Pin: Digital 6
*
* More information http://www.makerblog.at/2016/12/der-magische-ws2812b-led-streifen/
*
*/
#include <Adafruit_NeoPixel.h>
#define PIN 6
#define NUMPIXELS 58
#include <NewPing.h>
#define trigPin 12
#define echoPin 11
#define MAX_DISTANCE 80
// Running average variables
const int numReadings = 20;
int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
int newValue = 0;
int lastpixel = 0;
NewPing sonar(trigPin, echoPin, MAX_DISTANCE);
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(9600);
pixels.begin(); // This initializes the NeoPixel library.
// Reset running average array
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
}
}
void loop() {
int ping_cm(); // this returns the distance to the object ??
// map distance to LED strip
// map 20-110cm distance to LEDs #0 to #59
// play with this value to match your LED strip
int convert_cm = map(2,80,0,58);
// Ignore results out of bound, send -10 to average array instead
// This leads to LED marker gliding to end of strip when no object is within distance
if ((dispix >= 0) && (dispix < 58)) {
newValue = dispix;
} else {
newValue = -10;
}
// Running average code from
// https://www.arduino.cc/en/Tutorial/Smoothing
// subtract the last reading:
total = total - readings[readIndex];
// read from the sensor:
readings[readIndex] = newValue;
// add the reading to the total:
total = total + readings[readIndex];
// advance to the next position in the array:
readIndex = readIndex + 1;
// if we're at the end of the array...
if (readIndex >= numReadings) {
// ...wrap around to the beginning:
readIndex = 0;
}
// calculate the average:
int avePos = total / numReadings;
// set LEDs with following function and show them
draw(avePos);
pixels.show();
}
// Simple function resetting all pixels and lighten some around desired distance
void draw(int pix) {
for (int i=0; i<58; i++) {
pixels.setPixelColor(i, pixels.Color(2,0,0));
}
pixels.setPixelColor(pix-2, pixels.Color(0,0,30));
pixels.setPixelColor(pix-1, pixels.Color(0,0,100));
pixels.setPixelColor(pix, pixels.Color(0,0,250));
pixels.setPixelColor(pix+1, pixels.Color(50,0,50));
pixels.setPixelColor(pix+2, pixels.Color(20,0,20));
}