I'm trying to get a strip of Neopixels to circle through its length, one LED at a time, I want it to do it faster as the value received from the sensor increases
#include <FastLED.h>
#define NUM_LEDS 34
#define DATA_PIN 6
#define SENSOR_PIN A0
int airPressure,
barometricToRGB,
frequency = 0,
high = 0,
low = 600,
interval = 50;
long previousMillis = 0;
CRGB leds[NUM_LEDS];
void setup() {
Serial.begin(115200);
pinMode(SENSOR_PIN,INPUT);
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
}
void loop() {
airPressure = analogRead(SENSOR_PIN);
autoTune();
unsigned long currentMillis = millis();
Serial.print("frequency ");
Serial.println(frequency);
Serial.print("Time to beat ");
Serial.println(frequency*interval);
Serial.print("Last Called ");
Serial.println(currentMillis - previousMillis);
if(currentMillis - previousMillis > (frequency/interval)) {
previousMillis = currentMillis;
for (int i=0; i<NUM_LEDS; i++) {
leds[i].setRGB( barometricToRGB, 68, 255/barometricToRGB);
FastLED.show();
}
}
}
void autoTune() {
if (airPressure < low) {
low = airPressure;
}
if (airPressure > high) {
high = airPressure;
}
barometricToRGB = map(airPressure, low, high, 1, 255);
barometricToRGB = constrain(barometricToRGB, 1, 255);
frequency = map(airPressure, low, high, 1, 100);
frequency = constrain(frequency, 1, 100);
}
While I had managed to cause the color to change based on the sensor, I can't seem to understand how to control how fast it will go, every how long.
-
1Can you copy and paste the code into the question please? It isn't long.Nick Gammon– Nick Gammon ♦2015年10月02日 00:43:53 +00:00Commented Oct 2, 2015 at 0:43
2 Answers 2
Ok, if I understood what you meant, you want that a single led in the ring is on and the refresh rate is dependent on the pressure, right?
If so, you did not write any "select this led" code, so it can't work.
I fixed a couple of things in your code. Mainly:
- added the circularity to the ring (with variable
currentlyOnLed
) - fixed some types (use the
byte
unless you need a bigger type) - removed some
constrain
s, which were reduntant frequency*interval
instead offrequency/interval
(I guess it was a typo)- I prefer summing the step instead of setting
previousMillis
tocurrentMillis
, so you will not add error with time passing - moved
FastLED.show()
outside the loop: I'm not sure about this, but I think that you don't need to call it every loop. I can't test it, anyway.
So, here is the fixed code. Let us know if it works for you
#include <FastLED.h>
#define NUM_LEDS 34
#define DATA_PIN 6
#define SENSOR_PIN A0
int airPressure;
int high = 0;
int low = 600;
byte barometricToRGB;
int frequency = 0;
byte interval = 50;
byte currentlyOnLed;
long previousMillis = 0;
CRGB leds[NUM_LEDS];
void setup() {
Serial.begin(115200);
pinMode(SENSOR_PIN,INPUT);
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
currentlyOnLed = 0;
}
void loop() {
airPressure = analogRead(SENSOR_PIN);
autoTune();
unsigned long currentMillis = millis();
Serial.print("frequency ");
Serial.println(frequency);
Serial.print("Time to beat ");
Serial.println(frequency*interval);
Serial.print("Last Called ");
Serial.println(currentMillis - previousMillis);
if(currentMillis - previousMillis > (frequency*interval)) {
previousMillis += (frequency*interval);
//Set next on led
if (currentlyOnLed >= NUM_LEDS - 1)
currentlyOnLed = 0;
else
currentlyOnLed++;
for (byte i=0; i<NUM_LEDS; i++) {
if (i == currentlyOnLed)
leds[i].setRGB( barometricToRGB, 68, 255/barometricToRGB);
else
leds[i] = CRGB::Black;
}
FastLED.show();
}
}
void autoTune() {
airPressure = constrain(airPressure, low, high);
barometricToRGB = map(airPressure, low, high, 1, 255);
frequency = map(airPressure, low, high, 1, 100);
}
-
That's amazing! This is very thorough, and thoughtful. Thank you so muchNir Benita– Nir Benita2015年12月01日 16:01:56 +00:00Commented Dec 1, 2015 at 16:01
-
You are welcome ;) and... I don't know if it is you or someone else who needs to accept the edits in the original post. I just added the code (so it was cleaner and, moreover, links can break)frarugi87– frarugi872015年12月01日 17:27:59 +00:00Commented Dec 1, 2015 at 17:27
Are these reversed?
high = 0,
low = 600,
It looks like high and low both get set to airPressure on the first pass through autoTune(). If the pressure drops after this, for example, low will track airPressure and high will stay the same.
Also, with frequency 1 to 100 and interval 50 the largest time difference is 2 milliseconds and the smallest is 0. Your loop could be taking 2 ms without the if statement.