Skip to content

Instantly share code, notes, and snippets.

@tgoode451
Last active October 28, 2018 11:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tgoode451/550110222c5bc80c576c8734b5cbc8e8 to your computer and use it in GitHub Desktop.
Save tgoode451/550110222c5bc80c576c8734b5cbc8e8 to your computer and use it in GitHub Desktop.
UltrasonicServoFade.
#include <NewPing.h>
#include <Servo.h>
#include <FastLED.h>
//
// Mark's xy coordinate mapping code. See the XYMatrix for more information on it.
//
// Params for width and height
const uint8_t kMatrixWidth = 16;
const uint8_t kMatrixHeight = 16;
#define MAX_DIMENSION ((kMatrixWidth>kMatrixHeight) ? kMatrixWidth : kMatrixHeight)
#define NUM_LEDS (kMatrixWidth * kMatrixHeight)
// Param for different pixel layouts
const bool kMatrixSerpentineLayout = true;
uint16_t XY( uint8_t x, uint8_t y)
{
uint16_t i;
if( kMatrixSerpentineLayout == false) {
i = (y * kMatrixWidth) + x;
}
if( kMatrixSerpentineLayout == true) {
if( y & 0x01) {
// Odd rows run backwards
uint8_t reverseX = (kMatrixWidth - 1) - x;
i = (y * kMatrixWidth) + reverseX;
} else {
// Even rows run forwards
i = (y * kMatrixWidth) + x;
}
}
return i;
}
// The leds
CRGB leds[kMatrixWidth * kMatrixHeight];
// The 32bit version of our coordinates
static uint16_t x;
static uint16_t y;
static uint16_t z;
// We're using the x/y dimensions to map to the x/y pixels on the matrix. We'll
// use the z-axis for "time". speed determines how fast time moves forward. Try
// 1 for a very slow moving effect, or 60 for something that ends up looking like
// water.
// uint16_t speed = 1; // almost looks like a painting, moves very slowly
uint16_t speed = 6; // a nice starting speed, mixes well with a scale of 100
// uint16_t speed = 33;
// uint16_t speed = 100; // wicked fast!
// Scale determines how far apart the pixels in our noise matrix are. Try
// changing these values around to see how it affects the motion of the display. The
// higher the value of scale, the more "zoomed out" the noise iwll be. A value
// of 1 will be so zoomed in, you'll mostly see solid colors.
// uint16_t scale = 1; // mostly just solid colors
// uint16_t scale = 4011; // very zoomed out and shimmery
uint16_t scale = 50;
// This is the array that we keep our computed noise values in
uint8_t noise[MAX_DIMENSION][MAX_DIMENSION];
#define NUM_LEDS 16
#define NUM_STRIPS 2
Servo myServo; // create a servo object
#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN 11 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 160 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
const int numReadings = 42;
int readings1[numReadings]; // the readings from the analog input
int readIndex1 = 0; // the index of the current reading
int total1 = 0; // the running total
int average1 = 0; // the average
int readings2[numReadings]; // the readings from the analog input
int readIndex2 = 0; // the index of the current reading
int total2 = 0; // the running total
int average2 = 0; // the average
int thisReading = 0; // the current reading
int sensorPin = A0; // set the pin for the analog out of the light sensor
int analoglux = 0; // value read from the light sensor
int sensorValue = 0; // value read from the sensor
int lux = 0; // the value of the White LED output
int uvlux = 0; // the value of the UV LED
int angle = 0; // value output to the PWM (analog out)
int hue = 0; // value to derive the hue value from sensor input
int gBrightness = 0; // value to derive brightness from sensor input
int senseMax = 0; // the maximum value of the sensor pin (1023 for analog, 255 otherwise)
void setup() {
myServo.attach(9); // attaches the servo on pin 9 to the servo object
Serial.begin(9600); // Open serial monitor at 9600 baud to see sonar ping results.
// initialize all the readings to 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings1[thisReading] = 0;
}
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings2[thisReading] = 0;
}
// delay(3000);
LEDS.addLeds<WS2812,5,GRB>(leds,NUM_LEDS);
LEDS.addLeds<WS2812,6,GRB>(leds,NUM_LEDS);
// LEDS.setBrightness(96);
// Initialize our coordinates to some random values
x = random16();
y = random16();
z = random16();
}
// Fill the x/y array of 8-bit noise values using the inoise8 function.
void fillnoise8() {
for(int i = 0; i < MAX_DIMENSION; i++) {
int ioffset = scale * i;
for(int j = 0; j < MAX_DIMENSION; j++) {
int joffset = scale * j;
noise[i][j] = inoise8(x + ioffset,y + joffset,z);
}
}
z += speed;
}
void loop() {
delay(5);
// read the analog in value:
sensorValue = (sonar.ping_cm());
analoglux = analogRead(A0);
// decide whether to use sonar or light sensor
if (sensorValue < 30) {
angle = map(analoglux, 0, 1023, 10, 160);
lux = map(analoglux, 0, 1023, 42, 255);
hue = map(analoglux, 0, 1023, 25, 35);
}
if (sensorValue > 30) {
angle = map(sensorValue, 0, MAX_DISTANCE, 10, 160);
lux = map(sensorValue, 0, MAX_DISTANCE, 42, 255);
hue = map(sensorValue, 0, MAX_DISTANCE, 25, 35);
}
// map it to the range of the analog out:
gBrightness = map(average1, 0, 160, 45, 255);
// print the results to the Serial Monitor:
Serial.print("sensor = ");
Serial.print(sensorValue);
Serial.print("analoglux = ");
Serial.println(analoglux);
//Serial.print("\t average1 = ");
//Serial.println(average1);
// Serial.print("\t lux = ");
// Serial.println(lux);
Serial.print("\t average2 = ");
Serial.println(average2);
Serial.print("\t bright = ");
Serial.println(gBrightness);
// subtract the last reading:
total1 = total1 - readings1[readIndex1];
// read from the sensor:
readings1[readIndex1] = (angle);
// add the reading to the total:
total1 = total1 + readings1[readIndex1];
// advance to the next position in the array:
readIndex1 = readIndex1 + 1;
// subtract the last reading:
total2 = total2 - readings2[readIndex2];
// read from the sensor:
readings2[readIndex2] = (lux);
// add the reading to the total:
total2 = total2 + readings2[readIndex2];
// advance to the next position in the array:
readIndex2 = readIndex2 + 1;
// if we're at the end of the array...
if (readIndex1 >= numReadings) {
// ...wrap around to the beginning:
readIndex1 = 0;
}
// if we're at the end of the array...
if (readIndex2 >= numReadings) {
// ...wrap around to the beginning:
readIndex2 = 0;
}
// calculate the average:
average1 = total1 / numReadings;
average2 = total2 / numReadings;
uvlux = map(gBrightness, 45, 255, 128, 45);
delay(1); // delay in between reads for stability
// set the servo position
myServo.write(average1);
fillnoise8();
for(int i = 0; i < kMatrixWidth; i++) {
for(int j = 0; j < kMatrixHeight; j++) {
// We use the value at the (i,j) coordinate in the noise
// array for our brightness, and the flipped value from (j,i)
// for our pixel's hue.
// leds[XY(i,j)] = CHSV(64,255,noise[i][j]);
// You can also explore other ways to constrain the hue used, like below
leds[XY(i,j)] = CHSV(hue,((average2 + (noise[j][i]>>2)) +average2)/2,noise[i][j]);
}
}
// ihue+=1;
FastLED[0].showLeds(uvlux);
FastLED[1].showLeds(gBrightness);
//LEDS.show();
// delay(10);
}
@tgoode451
Copy link
Author

updated to merge noise.ino with ultrasonicservofade.ino

@tgoode451
Copy link
Author

now working on dual strings. All that remains is to implement a brightness function per string.

@tgoode451
Copy link
Author

Gist has been updated again... I was dissatisfied with the response from the HC-SR04 at close ranges (I might have a broken sensor) so I added a light sensor with either analog or digital output (high/low). This is feeding pin A0.

There is an if added to decide on whether to use the ultrasonic sensor or the light sensor depending on the value of sensorValue meeting a threshold.

No, I haven't slept yet...

Brightness function still outstanding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment