Add ability for PWM controlled RGB.

This commit is contained in:
Robert Marshall 2019-03-03 08:32:20 +00:00
parent 059ebad84e
commit 0e18b3371b
3 changed files with 71 additions and 18 deletions

View file

@ -3,8 +3,7 @@
#define MAX_HEAT_INDEX 240.0 #define MAX_HEAT_INDEX 240.0
Lighting::Lighting(int ledCount, NaturalLight* naturalLight, Weather* weather, float cloudCoverLimit) { Lighting::Lighting(NaturalLight* naturalLight, Weather* weather, float cloudCoverLimit) {
_ledCount = ledCount;
_naturalLight = naturalLight; _naturalLight = naturalLight;
_weather = weather; _weather = weather;
_cloudCoverLimit = cloudCoverLimit; _cloudCoverLimit = cloudCoverLimit;
@ -41,6 +40,22 @@ float Lighting::getPaletteBrightness(){
return getBrightness() * 255.0; return getBrightness() * 255.0;
} }
int Lighting::byteToAnalogue(byte input){
float fraction = input / 255.0;
return fraction * 1024;
}
void Lighting::outputColour(CRGB colour){
if (_useStrip)
FastLED.showColor(colour);
if (_usePWM){
analogWrite(_rPin, byteToAnalogue(colour.r));
analogWrite(_gPin, byteToAnalogue(colour.g));
analogWrite(_bPin, byteToAnalogue(colour.b));
}
}
void Lighting::updateRGB(int now) { void Lighting::updateRGB(int now) {
byte heatIndex = getPaletteHeatIndex(now); byte heatIndex = getPaletteHeatIndex(now);
byte brightness = getPaletteBrightness(); byte brightness = getPaletteBrightness();
@ -50,16 +65,15 @@ void Lighting::updateRGB(int now) {
if (_weather->getCondition() == WeatherCondition::Thunder && millis() >= _nextLightningFlash) { if (_weather->getCondition() == WeatherCondition::Thunder && millis() >= _nextLightningFlash) {
int flashes = random8(2, 8); int flashes = random8(2, 8);
for (int i = 0; i < flashes; i++) { for (int i = 0; i < flashes; i++) {
FastLED.showColor(CRGB::White); outputColour(CRGB::White);
delay(random8(10, 20)); delay(random8(10, 20));
FastLED.showColor(colour); outputColour(colour);
delay(random8(40, 80)); delay(random8(40, 80));
} }
_nextLightningFlash = millis() + (random8(1, 60) * 1000); _nextLightningFlash = millis() + (random8(1, 60) * 1000);
} }
fill_solid(_leds, _ledCount, colour); outputColour(colour);
FastLED.show();
} }
_lastHeatIndex = heatIndex; _lastHeatIndex = heatIndex;
_lastBrightness = brightness; _lastBrightness = brightness;
@ -69,7 +83,7 @@ void Lighting::updateWhite(){
float brightness = (_heatIndex - 0.5) / 0.5; float brightness = (_heatIndex - 0.5) / 0.5;
if (brightness<0) if (brightness<0)
brightness = 0; brightness = 0;
analogWrite(_whitePin, 1024 * brightness); analogWrite(_whitePin, PWMRANGE * brightness);
} }
void Lighting::update(int now) { void Lighting::update(int now) {

View file

@ -12,7 +12,7 @@ DEFINE_GRADIENT_PALETTE(_sunrise_p) {
}; };
class Lighting { class Lighting {
int _ledCount, _whitePin; int _ledCount, _whitePin, _rPin, _gPin, _bPin;
NaturalLight* _naturalLight; NaturalLight* _naturalLight;
Weather* _weather; Weather* _weather;
float _cloudCoverLimit; float _cloudCoverLimit;
@ -22,6 +22,7 @@ class Lighting {
float _heatIndex; float _heatIndex;
float _brightness; float _brightness;
byte _lastHeatIndex, _lastBrightness; byte _lastHeatIndex, _lastBrightness;
bool _useStrip, _usePWM;
float _currentHeatIndex(); float _currentHeatIndex();
float getIndexMultiplier(int now, int startTime, int endTime, bool swap); float getIndexMultiplier(int now, int startTime, int endTime, bool swap);
@ -29,17 +30,39 @@ class Lighting {
float getPaletteHeatIndex(int time); float getPaletteHeatIndex(int time);
float getBrightness(); float getBrightness();
float getPaletteBrightness(); float getPaletteBrightness();
int byteToAnalogue(byte input);
void outputColour(CRGB colour);
void updateRGB(int now); void updateRGB(int now);
void updateWhite(); void updateWhite();
public: public:
Lighting(int ledCount, NaturalLight* _naturalLight, Weather* _weather, float cloudCoverLimit); Lighting(NaturalLight* _naturalLight, Weather* _weather, float cloudCoverLimit);
template<uint8_t DATA_PIN, int WHITE_PIN> void setup() { template<uint8_t DATA_PIN, int LED_COUNT, int WHITE_PIN> void setupStrip() {
_ledCount = LED_COUNT;
FastLED.addLeds<WS2811, DATA_PIN, GRB>(_leds, _ledCount).setCorrection(TypicalSMD5050).setTemperature(Tungsten40W); FastLED.addLeds<WS2811, DATA_PIN, GRB>(_leds, _ledCount).setCorrection(TypicalSMD5050).setTemperature(Tungsten40W);
_whitePin = WHITE_PIN; _whitePin = WHITE_PIN;
pinMode(_whitePin, OUTPUT); pinMode(_whitePin, OUTPUT);
analogWrite(_whitePin, 0);
_useStrip = true;
} }
template<int R_PIN, int G_PIN, int B_PIN, int WHITE_PIN> void setupPWM() {
_rPin = R_PIN;
_gPin = G_PIN;
_bPin = B_PIN;
_whitePin = WHITE_PIN;
pinMode(_rPin, OUTPUT);
pinMode(_gPin, OUTPUT);
pinMode(_bPin, OUTPUT);
pinMode(_whitePin, OUTPUT);
analogWrite(_rPin, 0);
analogWrite(_gPin, 0);
analogWrite(_bPin, 0);
analogWrite(_whitePin, 0);
_usePWM = true;
}
void update(int time); void update(int time);
float getCurrentHeatIndex() { return _heatIndex; } float getCurrentHeatIndex() { return _heatIndex; }
float getCurrentBrightness() { return _brightness; } float getCurrentBrightness() { return _brightness; }

View file

@ -6,23 +6,32 @@
#include "NaturalLight.h" #include "NaturalLight.h"
#include "Weather.h" #include "Weather.h"
#define HOSTNAME "Fishtank" #define HOSTNAME "72L_Aquarium"
#define MQTT_SERVER "192.168.1.3" #define MQTT_SERVER "192.168.1.3"
#define SSID "GCHQ Surveillance Van" #define SSID "GCHQ Surveillance Van"
#define PASSWORD "cocklol." #define PASSWORD "cocklol."
#define PH_TOPIC "/home/sensors/fishtank/ph" #define BASE_TOPIC "/home/sensors/" HOSTNAME
#define TEMPERATURE_TOPIC "/home/sensors/fishtank/temperature"
#define PH_TOPIC BASE_TOPIC "/ph"
#define TEMPERATURE_TOPIC BASE_TOPIC "/temperature"
#define TEMPERATURE_PIN D5 #define TEMPERATURE_PIN D5
#define LED_USE_STRIP
#define RGB_PIN D3 #define RGB_PIN D3
#define WHITE_PIN D2
#define LED_COUNT 41 #define LED_COUNT 41
#define LED_USE_PWM
#define R_PIN D8
#define G_PIN D7
#define B_PIN D6
#define WHITE_PIN D2
#define LATITUDE "20.548103" #define LATITUDE "20.548103"
#define LONGITUDE "96.916835" #define LONGITUDE "96.916835"
#define TIMEZONE_OFFSET 30600 // 8.5 hours in seconds #define TIMEZONE_OFFSET 30600 // 8.5 hours in seconds
#define LIGHT_INDEX_TOPIC "/home/sensors/fishtank/lightindex" #define LIGHT_INDEX_TOPIC BASE_TOPIC "/lightindex"
#define BRIGHTNESS_TOPIC "/home/sensors/fishtank/brightness" #define BRIGHTNESS_TOPIC BASE_TOPIC "/brightness"
#define CLOUD_COVER_LIMIT 50.0 // percent; #define CLOUD_COVER_LIMIT 50.0 // percent;
#define NTP_POOL "uk.pool.ntp.org" #define NTP_POOL "uk.pool.ntp.org"
@ -40,12 +49,20 @@ Networking _networking = Networking(HOSTNAME, SSID, PASSWORD ,MQTT_SERVER);
Sensors _sensors = Sensors(TEMPERATURE_PIN, TEMPERATURE_TOPIC, PH_TOPIC, &_networking, &sensors); Sensors _sensors = Sensors(TEMPERATURE_PIN, TEMPERATURE_TOPIC, PH_TOPIC, &_networking, &sensors);
NaturalLight _naturalLight = NaturalLight(LATITUDE, LONGITUDE, TIMEZONE_OFFSET); NaturalLight _naturalLight = NaturalLight(LATITUDE, LONGITUDE, TIMEZONE_OFFSET);
Weather _weather = Weather(LATITUDE, LONGITUDE); Weather _weather = Weather(LATITUDE, LONGITUDE);
Lighting _lighting = Lighting(LED_COUNT, &_naturalLight, &_weather, CLOUD_COVER_LIMIT); Lighting _lighting = Lighting(&_naturalLight, &_weather, CLOUD_COVER_LIMIT);
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
#ifdef LED_USE_STRIP
_lighting.setupStrip<RGB_PIN, LED_COUNT, WHITE_PIN>();
#endif
#ifdef LED_USE_PWM
_lighting.setupPWM<R_PIN, R_PIN, G_PIN, WHITE_PIN>();
#endif
_networking.setup(); _networking.setup();
_sensors.setup(); _sensors.setup();
@ -54,7 +71,6 @@ void setup() {
_naturalLight.update(); _naturalLight.update();
_weather.update(); _weather.update();
_lighting.setup<RGB_PIN, WHITE_PIN>();
} }
void publishFloat(char* topic, float value){ void publishFloat(char* topic, float value){