Browse Source

Merge branch 'light_ir' into light

fastled
Xose Pérez 7 years ago
parent
commit
a73799a6a7
10 changed files with 423 additions and 267 deletions
  1. +1
    -0
      code/espurna/config/arduino.h
  2. +114
    -1
      code/espurna/config/general.h
  3. +11
    -73
      code/espurna/config/hardware.h
  4. +129
    -21
      code/espurna/dht.ino
  5. +6
    -0
      code/espurna/espurna.ino
  6. +107
    -0
      code/espurna/ir.ino
  7. +24
    -10
      code/espurna/light.ino
  8. +30
    -159
      code/espurna/light_ir.ino
  9. +1
    -1
      code/espurna/web.ino
  10. +0
    -2
      code/platformio.ini

+ 1
- 0
code/espurna/config/arduino.h View File

@ -68,6 +68,7 @@
//#define HOMEASSISTANT_SUPPORT 0 //#define HOMEASSISTANT_SUPPORT 0
//#define I2C_SUPPORT 1 //#define I2C_SUPPORT 1
//#define INFLUXDB_SUPPORT 0 //#define INFLUXDB_SUPPORT 0
//#define IR_SUPPORT 1
//#define MDNS_SUPPORT 0 //#define MDNS_SUPPORT 0
//#define NOFUSS_SUPPORT 1 //#define NOFUSS_SUPPORT 1
//#define NTP_SUPPORT 0 //#define NTP_SUPPORT 0


+ 114
- 1
code/espurna/config/general.h View File

@ -518,6 +518,7 @@ PROGMEM const char* const custom_reset_string[] = {
#endif #endif
#define LIGHT_MAX_BRIGHTNESS 255 // Maximun brightness value #define LIGHT_MAX_BRIGHTNESS 255 // Maximun brightness value
#define LIGHT_STEP 32 // Step size
#define LIGHT_USE_COLOR 1 // Use 3 first channels as RGB #define LIGHT_USE_COLOR 1 // Use 3 first channels as RGB
#define LIGHT_USE_WHITE 0 // Use white channel whenever RGB have the same value #define LIGHT_USE_WHITE 0 // Use white channel whenever RGB have the same value
#define LIGHT_USE_GAMMA 0 // Use gamma correction for color channels #define LIGHT_USE_GAMMA 0 // Use gamma correction for color channels
@ -709,10 +710,122 @@ PROGMEM const char* const custom_reset_string[] = {
// Both ALEXA_SUPPORT and alexaEnabled should be 1 for Alexa support to work. // Both ALEXA_SUPPORT and alexaEnabled should be 1 for Alexa support to work.
#define ALEXA_ENABLED 1 #define ALEXA_ENABLED 1
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// RFBRIDGE // RFBRIDGE
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#define RF_SEND_TIMES 4 // How many times to send the message #define RF_SEND_TIMES 4 // How many times to send the message
#define RF_SEND_DELAY 250 // Interval between sendings in ms #define RF_SEND_DELAY 250 // Interval between sendings in ms
// -----------------------------------------------------------------------------
// IR
// -----------------------------------------------------------------------------
#ifndef IR_SUPPORT
#define IR_SUPPORT 0 // Do not build with IR support by default
#endif
#ifndef IR_PIN
#define IR_PIN 4 // IR LED
#endif
// 24 Buttons Set of the IR Remote
#ifndef IR_BUTTON_SET
#define IR_BUTTON_SET 1
#endif
// IR Button modes
#define IR_BUTTON_MODE_NONE 0
#define IR_BUTTON_MODE_RGB 1
#define IR_BUTTON_MODE_HSV 2
#define IR_BUTTON_MODE_BRIGHTER 3
#define IR_BUTTON_MODE_STATE 4
#define IR_BUTTON_MODE_EFFECT 5
#define LIGHT_EFFECT_SOLID 0
#define LIGHT_EFFECT_FLASH 1
#define LIGHT_EFFECT_STROBE 2
#define LIGHT_EFFECT_FADE 3
#define LIGHT_EFFECT_SMOOTH 4
//Remote Buttons SET 1 (for the original Remote shipped with the controller)
#if IR_BUTTON_SET == 1
#define IR_BUTTON_COUNT 24
const unsigned long IR_BUTTON[IR_BUTTON_COUNT][3] PROGMEM = {
{ 0xFF906F, IR_BUTTON_MODE_BRIGHTER, 1 },
{ 0xFFB847, IR_BUTTON_MODE_BRIGHTER, 0 },
{ 0xFFF807, IR_BUTTON_MODE_STATE, 0 },
{ 0xFFB04F, IR_BUTTON_MODE_STATE, 1 },
{ 0xFF9867, IR_BUTTON_MODE_RGB, 0xFF0000 },
{ 0xFFD827, IR_BUTTON_MODE_RGB, 0x00FF00 },
{ 0xFF8877, IR_BUTTON_MODE_RGB, 0x0000FF },
{ 0xFFA857, IR_BUTTON_MODE_RGB, 0xFFFFFF },
{ 0xFFE817, IR_BUTTON_MODE_RGB, 0xD13A01 },
{ 0xFF48B7, IR_BUTTON_MODE_RGB, 0x00E644 },
{ 0xFF6897, IR_BUTTON_MODE_RGB, 0x0040A7 },
{ 0xFFB24D, IR_BUTTON_MODE_EFFECT, LIGHT_EFFECT_FLASH },
{ 0xFF02FD, IR_BUTTON_MODE_RGB, 0xE96F2A },
{ 0xFF32CD, IR_BUTTON_MODE_RGB, 0x00BEBF },
{ 0xFF20DF, IR_BUTTON_MODE_RGB, 0x56406F },
{ 0xFF00FF, IR_BUTTON_MODE_EFFECT, LIGHT_EFFECT_STROBE },
{ 0xFF50AF, IR_BUTTON_MODE_RGB, 0xEE9819 },
{ 0xFF7887, IR_BUTTON_MODE_RGB, 0x00799A },
{ 0xFF708F, IR_BUTTON_MODE_RGB, 0x944E80 },
{ 0xFF58A7, IR_BUTTON_MODE_EFFECT, LIGHT_EFFECT_FADE },
{ 0xFF38C7, IR_BUTTON_MODE_RGB, 0xFFFF00 },
{ 0xFF28D7, IR_BUTTON_MODE_RGB, 0x0060A1 },
{ 0xFFF00F, IR_BUTTON_MODE_RGB, 0xEF45AD },
{ 0xFF30CF, IR_BUTTON_MODE_EFFECT, LIGHT_EFFECT_SMOOTH }
};
#endif
//Remote Buttons SET 2 (another identical IR Remote shipped with another controller)
#if IR_BUTTON_SET == 2
#define IR_BUTTON_COUNT 24
const unsigned long IR_BUTTON[IR_BUTTON_COUNT][3] PROGMEM = {
{ 0xFF00FF, IR_BUTTON_MODE_BRIGHTER, 1 },
{ 0xFF807F, IR_BUTTON_MODE_BRIGHTER, 0 },
{ 0xFF40BF, IR_BUTTON_MODE_STATE, 0 },
{ 0xFFC03F, IR_BUTTON_MODE_STATE, 1 },
{ 0xFF20DF, IR_BUTTON_MODE_RGB, 0xFF0000 },
{ 0xFFA05F, IR_BUTTON_MODE_RGB, 0x00FF00 },
{ 0xFF609F, IR_BUTTON_MODE_RGB, 0x0000FF },
{ 0xFFE01F, IR_BUTTON_MODE_RGB, 0xFFFFFF },
{ 0xFF10EF, IR_BUTTON_MODE_RGB, 0xD13A01 },
{ 0xFF906F, IR_BUTTON_MODE_RGB, 0x00E644 },
{ 0xFF50AF, IR_BUTTON_MODE_RGB, 0x0040A7 },
{ 0xFFD02F, IR_BUTTON_MODE_EFFECT, LIGHT_EFFECT_FLASH },
{ 0xFF30CF, IR_BUTTON_MODE_RGB, 0xE96F2A },
{ 0xFFB04F, IR_BUTTON_MODE_RGB, 0x00BEBF },
{ 0xFF708F, IR_BUTTON_MODE_RGB, 0x56406F },
{ 0xFFF00F, IR_BUTTON_MODE_EFFECT, LIGHT_EFFECT_STROBE },
{ 0xFF08F7, IR_BUTTON_MODE_RGB, 0xEE9819 },
{ 0xFF8877, IR_BUTTON_MODE_RGB, 0x00799A },
{ 0xFF48B7, IR_BUTTON_MODE_RGB, 0x944E80 },
{ 0xFFC837, IR_BUTTON_MODE_EFFECT, LIGHT_EFFECT_FADE },
{ 0xFF28D7, IR_BUTTON_MODE_RGB, 0xFFFF00 },
{ 0xFFA857, IR_BUTTON_MODE_RGB, 0x0060A1 },
{ 0xFF6897, IR_BUTTON_MODE_RGB, 0xEF45AD },
{ 0xFFE817, IR_BUTTON_MODE_EFFECT, LIGHT_EFFECT_SMOOTH }
};
#endif

+ 11
- 73
code/espurna/config/hardware.h View File

@ -700,6 +700,11 @@
#define LIGHT_CH3_INVERSE 0 #define LIGHT_CH3_INVERSE 0
#define LIGHT_CH4_INVERSE 0 #define LIGHT_CH4_INVERSE 0
// IR
#define IR_SUPPORT 1
#define IR_PIN 4
#define IR_BUTTON_SET 1
#elif defined(MAGICHOME_LED_CONTROLLER_20) #elif defined(MAGICHOME_LED_CONTROLLER_20)
// Info // Info
@ -709,6 +714,8 @@
#define LIGHT_PROVIDER LIGHT_PROVIDER_DIMMER #define LIGHT_PROVIDER LIGHT_PROVIDER_DIMMER
#define DUMMY_RELAY_COUNT 1 #define DUMMY_RELAY_COUNT 1
//#define LIGHT_PROVIDER_EXPERIMENTAL_RGB_ONLY_HSV_IR
// LEDs // LEDs
#define LED1_PIN 2 #define LED1_PIN 2
#define LED1_PIN_INVERSE 1 #define LED1_PIN_INVERSE 1
@ -724,79 +731,10 @@
#define LIGHT_CH3_INVERSE 0 #define LIGHT_CH3_INVERSE 0
#define LIGHT_CH4_INVERSE 0 #define LIGHT_CH4_INVERSE 0
#define LIGHT_IR_PIN 4 // IR LED
#define LIGHT_PROVIDER_EXPERIMENTAL_RGB_ONLY_HSV_IR 0
// 24 Buttons Set of the IR Remote
#ifndef IR_BUTTONS_SET
#define IR_BUTTONS_SET 1
#endif
//Remote Buttons SET 1 (for the original Remote shipped with the controller)
#if IR_BUTTONS_SET == 1
#define IR_BUTTON_0 0xFF906F // Brightness +
#define IR_BUTTON_1 0xFFB847 // Brightness -
#define IR_BUTTON_2 0xFFF807 // OFF
#define IR_BUTTON_3 0xFFB04F // ON
#define IR_BUTTON_4 0xFF9867 // RED
#define IR_BUTTON_5 0xFFD827 // GREEN
#define IR_BUTTON_6 0xFF8877 // BLUE
#define IR_BUTTON_7 0xFFA857 // WHITE
#define IR_BUTTON_8 0xFFE817 // "Red" 1
#define IR_BUTTON_9 0xFF48B7 // "Green" 1
#define IR_BUTTON_10 0xFF6897 // "Blue" 1
#define IR_BUTTON_11 0xFFB24D // FLASH Mode
#define IR_BUTTON_12 0xFF02FD // "Red" 2
#define IR_BUTTON_13 0xFF32CD // "Green" 2
#define IR_BUTTON_14 0xFF20DF // "Blue" 2
#define IR_BUTTON_15 0xFF00FF // STROBE Mode
#define IR_BUTTON_16 0xFF50AF // "Red" 3
#define IR_BUTTON_17 0xFF7887 // "Green" 3
#define IR_BUTTON_18 0xFF708F // "Blue" 3
#define IR_BUTTON_19 0xFF58A7 // FADE Mode
#define IR_BUTTON_20 0xFF38C7 // "Red" 4
#define IR_BUTTON_21 0xFF28D7 // "Green" 4
#define IR_BUTTON_22 0xFFF00F // "Blue" 4
#define IR_BUTTON_23 0xFF30CF // SMOOTH Mode
#endif
//Remote Buttons SET 2 (another identical IR Remote shipped with another controller)
#if IR_BUTTONS_SET == 2
#define IR_BUTTON_0 0xFF00FF // Brightness +
#define IR_BUTTON_1 0xFF807F // Brightness -
#define IR_BUTTON_2 0xFF40BF // OFF
#define IR_BUTTON_3 0xFFC03F // ON
#define IR_BUTTON_4 0xFF20DF // RED
#define IR_BUTTON_5 0xFFA05F // GREEN
#define IR_BUTTON_6 0xFF609F // BLUE
#define IR_BUTTON_7 0xFFE01F // WHITE
#define IR_BUTTON_8 0xFF10EF // "Red" 1
#define IR_BUTTON_9 0xFF906F // "Green" 1
#define IR_BUTTON_10 0xFF50AF // "Blue" 1
#define IR_BUTTON_11 0xFFD02F // FLASH Mode
#define IR_BUTTON_12 0xFF30CF // "Red" 2
#define IR_BUTTON_13 0xFFB04F // "Green" 2
#define IR_BUTTON_14 0xFF708F // "Blue" 2
#define IR_BUTTON_15 0xFFF00F // STROBE Mode
#define IR_BUTTON_16 0xFF08F7 // "Red" 3
#define IR_BUTTON_17 0xFF8877 // "Green" 3
#define IR_BUTTON_18 0xFF48B7 // "Blue" 3
#define IR_BUTTON_19 0xFFC837 // FADE Mode
#define IR_BUTTON_20 0xFF28D7 // "Red" 4
#define IR_BUTTON_21 0xFFA857 // "Green" 4
#define IR_BUTTON_22 0xFF6897 // "Blue" 4
#define IR_BUTTON_23 0xFFE817 // SMOOTH Mode
#endif
// IR
#define IR_SUPPORT 1
#define IR_PIN 4
#define IR_BUTTON_SET 1
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// HUACANXING H801 & H802 // HUACANXING H801 & H802


+ 129
- 21
code/espurna/dht.ino View File

@ -8,20 +8,139 @@ Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
#if DHT_SUPPORT #if DHT_SUPPORT
#include <DHT.h>
#include <Adafruit_Sensor.h>
DHT dht(DHT_PIN, DHT_TYPE, DHT_TIMING);
double _dhtTemperature = 0; double _dhtTemperature = 0;
unsigned int _dhtHumidity = 0; unsigned int _dhtHumidity = 0;
// -----------------------------------------------------------------------------
// HAL
// https://github.com/gosouth/DHT22/blob/master/main/DHT22.c
// -----------------------------------------------------------------------------
#define DHT_MAX_DATA 5
#define DHT_MAX_ERRORS 5
#define DHT_MIN_INTERVAL 2000
#define DHT_OK 0
#define DHT_CHECKSUM_ERROR -1
#define DHT_TIMEOUT_ERROR -2
#define DHT11 11
#define DHT22 22
#define DHT21 21
#define AM2301 21
unsigned long _getSignalLevel(unsigned char gpio, int usTimeOut, bool state) {
unsigned long uSec = 1;
while (digitalRead(gpio) == state) {
if (++uSec > usTimeOut) return 0;
delayMicroseconds(1);
}
return uSec;
}
int readDHT(unsigned char gpio, unsigned char type) {
static unsigned long last_ok = 0;
if (millis() - last_ok < DHT_MIN_INTERVAL) return DHT_OK;
unsigned long low = 0;
unsigned long high = 0;
static unsigned char errors = 0;
uint8_t dhtData[DHT_MAX_DATA] = {0};
uint8_t byteInx = 0;
uint8_t bitInx = 7;
// Send start signal to DHT sensor
if (++errors > DHT_MAX_ERRORS) {
errors = 0;
digitalWrite(gpio, HIGH);
delay(250);
}
pinMode(gpio, OUTPUT);
digitalWrite(gpio, LOW);
delay(20);
noInterrupts();
digitalWrite(gpio, HIGH);
delayMicroseconds(40);
pinMode(gpio, INPUT_PULLUP);
delayMicroseconds(10);
// DHT will keep the line low for 80 us and then high for 80us
low = _getSignalLevel(gpio, 85, LOW);
if (low==0) return DHT_TIMEOUT_ERROR;
high = _getSignalLevel(gpio, 85, HIGH);
if (high==0) return DHT_TIMEOUT_ERROR;
// No errors, read the 40 data bits
for( int k = 0; k < 40; k++ ) {
// Starts new data transmission with >50us low signal
low = _getSignalLevel(gpio, 56, LOW);
if (low==0) return DHT_TIMEOUT_ERROR;
// Check to see if after >70us rx data is a 0 or a 1
high = _getSignalLevel(gpio, 75, HIGH);
if (high==0) return DHT_TIMEOUT_ERROR;
// add the current read to the output data
// since all dhtData array where set to 0 at the start,
// only look for "1" (>28us us)
if (high > low) dhtData[byteInx] |= (1 << bitInx);
// index to next byte
if (bitInx == 0) {
bitInx = 7;
++byteInx;
} else {
--bitInx;
}
}
interrupts();
// Verify checksum
if (dhtData[4] != ((dhtData[0] + dhtData[1] + dhtData[2] + dhtData[3]) & 0xFF)) {
return DHT_CHECKSUM_ERROR;
}
// Get humidity from Data[0] and Data[1]
if (type == DHT11) {
_dhtHumidity = dhtData[0];
} else {
_dhtHumidity = dhtData[0] * 256 + dhtData[1];
_dhtHumidity /= 10;
}
// Get temp from Data[2] and Data[3]
if (type == DHT11) {
_dhtTemperature = dhtData[2];
} else {
_dhtTemperature = (dhtData[2] & 0x7F) * 256 + dhtData[3];
_dhtTemperature /= 10;
if (dhtData[2] & 0x80) _dhtTemperature *= -1;
}
last_ok = millis();
errors = 0;
return DHT_OK;
}
int readDHT() {
return readDHT(DHT_PIN, DHT_TYPE);
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Values // Values
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
double getDHTTemperature(bool celsius) {
return celsius ? _dhtTemperature : _dhtTemperature * 1.8 + 32;
}
double getDHTTemperature() { double getDHTTemperature() {
return _dhtTemperature;
return getDHTTemperature(true);
} }
unsigned int getDHTHumidity() { unsigned int getDHTHumidity() {
@ -30,8 +149,6 @@ unsigned int getDHTHumidity() {
void dhtSetup() { void dhtSetup() {
dht.begin();
#if WEB_SUPPORT #if WEB_SUPPORT
apiRegister(DHT_TEMPERATURE_TOPIC, DHT_TEMPERATURE_TOPIC, [](char * buffer, size_t len) { apiRegister(DHT_TEMPERATURE_TOPIC, DHT_TEMPERATURE_TOPIC, [](char * buffer, size_t len) {
dtostrf(_dhtTemperature, 1-len, 1, buffer); dtostrf(_dhtTemperature, 1-len, 1, buffer);
@ -50,21 +167,12 @@ void dhtLoop() {
if ((millis() - last_update > DHT_UPDATE_INTERVAL) || (last_update == 0)) { if ((millis() - last_update > DHT_UPDATE_INTERVAL) || (last_update == 0)) {
last_update = millis(); last_update = millis();
unsigned char tmpUnits = getSetting("tmpUnits", TMP_UNITS).toInt();
// Read sensor data // Read sensor data
double h = dht.readHumidity();
double t = dht.readTemperature(tmpUnits == TMP_FAHRENHEIT);
// Check if readings are valid
if (isnan(h) || isnan(t)) {
DEBUG_MSG_P(PSTR("[DHT] Error reading sensor\n"));
} else {
if (readDHT(DHT_PIN, DHT_TYPE) == DHT_OK) {
_dhtTemperature = t;
_dhtHumidity = h;
unsigned char tmpUnits = getSetting("tmpUnits", TMP_UNITS).toInt();
double t = getDHTTemperature(tmpUnits == TMP_CELSIUS);
unsigned int h = getDHTHumidity();
char temperature[6]; char temperature[6];
char humidity[6]; char humidity[6];


+ 6
- 0
code/espurna/espurna.ino View File

@ -294,6 +294,9 @@ void setup() {
#if RF_SUPPORT #if RF_SUPPORT
rfSetup(); rfSetup();
#endif #endif
#if IR_SUPPORT
irSetup();
#endif
#if DOMOTICZ_SUPPORT #if DOMOTICZ_SUPPORT
domoticzSetup(); domoticzSetup();
#endif #endif
@ -356,5 +359,8 @@ void loop() {
#if RF_SUPPORT #if RF_SUPPORT
rfLoop(); rfLoop();
#endif #endif
#if IR_SUPPORT
irLoop();
#endif
} }

+ 107
- 0
code/espurna/ir.ino View File

@ -0,0 +1,107 @@
/*
IR MODULE
Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
Copyright (C) 2017 by François Déchery
*/
#if IR_SUPPORT
#include <IRremoteESP8266.h>
#include <IRrecv.h>
IRrecv * _ir_recv;
decode_results _ir_results;
// -----------------------------------------------------------------------------
// PRIVATE
// -----------------------------------------------------------------------------
void _irProcessCode(unsigned long code) {
static unsigned long last_code;
boolean found = false;
// Repeat last valid code
DEBUG_MSG_P(PSTR("[IR] Received 0x%06X\n"), code);
if (code == 0xFFFFFFFF) {
DEBUG_MSG_P(PSTR("[IR] Processing 0x%06X\n"), code);
code = last_code;
}
for (unsigned char i = 0; i < IR_BUTTON_COUNT ; i++) {
unsigned long button_code = pgm_read_dword(&IR_BUTTON[i][0]);
if (code == button_code) {
unsigned long button_mode = pgm_read_dword(&IR_BUTTON[i][1]);
unsigned long button_value = pgm_read_dword(&IR_BUTTON[i][2]);
if (button_mode == IR_BUTTON_MODE_STATE) {
relayStatus(0, button_value);
}
#if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
if (button_mode == IR_BUTTON_MODE_BRIGHTER) {
lightBrightnessStep(button_value ? 1 : -1);
delay(150); //debounce
}
if (button_mode == IR_BUTTON_MODE_RGB) {
lightColor(button_value);
}
/*
#if LIGHT_PROVIDER == LIGHT_PROVIDER_FASTLED
if (button_mode == IR_BUTTON_MODE_EFFECT) {
_buttonAnimMode(button_value);
}
#endif
*/
/*
if (button_mode == IR_BUTTON_MODE_HSV) {
lightColor(button_value);
}
*/
lightUpdate(true, true);
#endif
found = true;
last_code = code;
break;
}
}
if (!found) {
DEBUG_MSG_P(PSTR("[IR] Ignoring code\n"));
}
}
// -----------------------------------------------------------------------------
// PUBLIC API
// -----------------------------------------------------------------------------
void irSetup() {
_ir_recv = new IRrecv(IR_PIN);
_ir_recv->enableIRIn();
}
void irLoop() {
if (_ir_recv->decode(&_ir_results)) {
unsigned long code = _ir_results.value;
_irProcessCode(code);
_ir_recv->resume(); // Receive the next value
}
}
#endif // IR_SUPPORT

+ 24
- 10
code/espurna/light.ino View File

@ -61,6 +61,21 @@ const unsigned char gamma_table[] = {
// UTILS // UTILS
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void _fromLong(unsigned long value, bool brightness) {
if (brightness) {
_channels[0].value = (value >> 24) & 0xFF;
_channels[1].value = (value >> 16) & 0xFF;
_channels[2].value = (value >> 8) & 0xFF;
_brightness = (value & 0xFF) * LIGHT_MAX_BRIGHTNESS / 255;
} else {
_channels[0].value = (value >> 16) & 0xFF;
_channels[1].value = (value >> 8) & 0xFF;
_channels[2].value = (value) & 0xFF;
}
}
void _fromRGB(const char * rgb) { void _fromRGB(const char * rgb) {
char * p = (char *) rgb; char * p = (char *) rgb;
@ -75,16 +90,7 @@ void _fromRGB(const char * rgb) {
unsigned long value = strtoul(p, NULL, 16); unsigned long value = strtoul(p, NULL, 16);
// RGBA values are interpreted like RGB + brightness // RGBA values are interpreted like RGB + brightness
if (strlen(p) > 7) {
_channels[0].value = (value >> 24) & 0xFF;
_channels[1].value = (value >> 16) & 0xFF;
_channels[2].value = (value >> 8) & 0xFF;
_brightness = (value & 0xFF) * LIGHT_MAX_BRIGHTNESS / 255;
} else {
_channels[0].value = (value >> 16) & 0xFF;
_channels[1].value = (value >> 8) & 0xFF;
_channels[2].value = (value) & 0xFF;
}
_fromLong(value, strlen(p) > 7);
} }
@ -475,6 +481,10 @@ void lightColor(const char * color) {
_fromRGB(color); _fromRGB(color);
} }
void lightColor(unsigned long color) {
_fromLong(color, false);
}
String lightColor() { String lightColor() {
char rgb[8]; char rgb[8];
_toRGB(rgb, 8, false); _toRGB(rgb, 8, false);
@ -502,6 +512,10 @@ void lightBrightness(unsigned int b) {
_brightness = constrain(b, 0, LIGHT_MAX_BRIGHTNESS); _brightness = constrain(b, 0, LIGHT_MAX_BRIGHTNESS);
} }
void lightBrightnessStep(int steps) {
lightBrightness(_brightness + steps * LIGHT_STEP);
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// SETUP // SETUP
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------


+ 30
- 159
code/espurna/light_ir.ino View File

@ -3,7 +3,7 @@
LIGHT (EXPERIMENTAL) IR LIGHT (EXPERIMENTAL) IR
Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com> Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
Copyright (C) 2017 by François Déchery
Copyright (C) 2017 by François Déchery
------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------
Features : Features :
@ -24,8 +24,6 @@ Not currently Implemented :
#ifdef LIGHT_PROVIDER_EXPERIMENTAL_RGB_ONLY_HSV_IR #ifdef LIGHT_PROVIDER_EXPERIMENTAL_RGB_ONLY_HSV_IR
#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <FastLED.h> #include <FastLED.h>
// #### Defined ########################################################################## // #### Defined ##########################################################################
@ -37,64 +35,9 @@ Not currently Implemented :
#define ANIM3_SPEED 100 // fade speed #define ANIM3_SPEED 100 // fade speed
#define ANIM4_SPEED 700 // smooth speed #define ANIM4_SPEED 700 // smooth speed
#define ANIM5_SPEED 200 // party speed #define ANIM5_SPEED 200 // party speed
#define BUTTONS_COUNT 24
#define LED_DURATION 70 // Status led ON duration #define LED_DURATION 70 // Status led ON duration
// #### Variables ######################################################################## // #### Variables ########################################################################
unsigned long r_but_codes[]={ // IR remote buttons codes
IR_BUTTON_0 , // Brightness +
IR_BUTTON_1 , // Brightness -
IR_BUTTON_2 , // OFF
IR_BUTTON_3 , // ON
IR_BUTTON_4 , // Red
IR_BUTTON_5 , // Green
IR_BUTTON_6 , // Blue
IR_BUTTON_7 , // White
IR_BUTTON_8 , // R1
IR_BUTTON_9 , // G1
IR_BUTTON_10 , // B1
IR_BUTTON_11 , // Flash
IR_BUTTON_12 , // R2
IR_BUTTON_13 , // G2
IR_BUTTON_14 , // B2
IR_BUTTON_15 , // Strobe
IR_BUTTON_16 , // R3
IR_BUTTON_17 , // G3
IR_BUTTON_18 , // B3
IR_BUTTON_19 , // Fade
IR_BUTTON_20 , // R4
IR_BUTTON_21 , // G4
IR_BUTTON_22 , // B4
IR_BUTTON_23 // Smooth
};
unsigned long r_but_colors[]={ // IR remote buttons colors
0, // Brightness +
0, // Brightness -
0, // OFF
0, // ON
0xFF0000, // Red
0x00FF00, // Green
0x0000FF, // Blue
0xFFFFFF, // White
0xD13A01, // R1
0x00E644, // G1
0x0040A7, // B1
0, // Flash
0xE96F2A, // R2
0x00BEBF, // G2
0x56406F, // B2
0, // Strobe
0xEE9819, // R3
0x00799A, // G3
0x944E80, // B3
0, // Fade
0xFFFF00, // R4
0x0060A1, // G4
0xEF45AD, // B4
0 // Smooth
};
// variables declarations ############################################################### // variables declarations ###############################################################
CHSV _cur_color = CHSV(0,255,255); CHSV _cur_color = CHSV(0,255,255);
@ -108,9 +51,6 @@ unsigned long _anim_last_update = millis();
unsigned long _last_ir_button = 0; unsigned long _last_ir_button = 0;
unsigned long _last_status_led_time = 0; unsigned long _last_status_led_time = 0;
IRrecv _ir_recv(LIGHT_IR_PIN); //IRrecv _ir_recv(IR_PIN, IR_LED_PIN); dont work. Why ?
decode_results _ir_results;
// ####################################################################################### // #######################################################################################
// #### PRIVATE ########################################################################## // #### PRIVATE ##########################################################################
@ -129,75 +69,6 @@ void _flashStatusLed(){
_last_status_led_time=millis(); _last_status_led_time=millis();
} }
// ---------------------------------------------------------------------------------------
void _loopProcessIR() {
if (_ir_recv.decode(&_ir_results)) {
//dumpIR(&_ir_results);
//DEBUG_MSG_P(PSTR(".\n"));
unsigned long code = _ir_results.value;
DEBUG_MSG_P(PSTR("[IR] received : 0x%X "), code );
if( code == 0xFFFFFFFF){
code = _last_ir_button;
DEBUG_MSG_P(PSTR("(Repeat : %X) "), code );
}
DEBUG_MSG_P(PSTR("=> ") );
_processIrButtons(code);
_ir_recv.resume(); // Receive the next value
}
}
// ---------------------------------------------------------------------------------------
void _processIrButtons(unsigned long code) {
//DEBUG_MSG_P(PSTR("IR code : %X\n"), code );
boolean done=false;
for (int i = 0; i < BUTTONS_COUNT ; i = i + 1) {
if( code == r_but_codes[i] ){
//DEBUG_MSG_P(PSTR(" : %X -> "), r_but_colors[i] );
_last_ir_button = 0; //no repat else if specified
if(i == 0){
_buttonBrightness(true);
_last_ir_button = code;
delay(150); //debounce
}
else if(i == 1){
_buttonBrightness(false);
_last_ir_button = code;
delay(150); //debounce
}
else if(i == 2){
_buttonPower(false);
}
else if(i == 3){
_buttonPower(true);
}
else if(i == 11){
_buttonAnimMode(1);
}
else if(i == 15){
_buttonAnimMode(2);
}
else if(i == 19){
_buttonAnimMode(3);
}
else if(i == 23){
_buttonAnimMode(4);
}
else{
_buttonColorRVB(r_but_colors[i],0);
}
done=true;
lightUpdate(true, true);
}
}
if(!done){
_last_ir_button = 0;
//DEBUG_PRINTHEX(code);
DEBUG_MSG_P(PSTR("ignored!\n"));
}
}
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
void _buttonPower(boolean on){ void _buttonPower(boolean on){
_flashStatusLed(); _flashStatusLed();
@ -289,7 +160,7 @@ CHSV _dimHSV(CHSV color, int offset){
offset=offset*10; offset=offset*10;
int bright=color.v + offset; int bright=color.v + offset;
if(offset ==0){ if(offset ==0){
return color;
return color;
} }
else if(bright < 1){ else if(bright < 1){
bright=1; // no off bright=1; // no off
@ -316,7 +187,7 @@ void _setBrightness(byte val){
if(val==0){ if(val==0){
_cur_status=0; _cur_status=0;
} }
_buttonColorHSV(_cur_color,0);
_buttonColorHSV(_cur_color,0);
} }
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
@ -330,7 +201,7 @@ void _setAnimSpeed(unsigned long speed){
void _setLedsRGB(CRGB rgb){ void _setLedsRGB(CRGB rgb){
analogWrite(LIGHT_CH1_PIN, rgb.r); analogWrite(LIGHT_CH1_PIN, rgb.r);
analogWrite(LIGHT_CH2_PIN, rgb.g); analogWrite(LIGHT_CH2_PIN, rgb.g);
analogWrite(LIGHT_CH3_PIN, rgb.b);
analogWrite(LIGHT_CH3_PIN, rgb.b);
if(_cur_anim_mode == 0){ if(_cur_anim_mode == 0){
DEBUG_MSG_P(PSTR("RGB=%3u,%3u,%3u\n"), rgb.r, rgb.g, rgb.b); DEBUG_MSG_P(PSTR("RGB=%3u,%3u,%3u\n"), rgb.r, rgb.g, rgb.b);
} }
@ -528,9 +399,9 @@ void _anim5(boolean init){
_cur_anim_color.v= 255; _cur_anim_color.v= 255;
} }
unsigned long now= millis(); unsigned long now= millis();
if(_cur_anim_step == 1 && now > (_anim_last_update + _cur_anim_speed) ){
if(_cur_anim_step == 1 && now > (_anim_last_update + _cur_anim_speed) ){
DEBUG_MSG_P(PSTR("[ANIM_%d] Update : "), _cur_anim_mode); DEBUG_MSG_P(PSTR("[ANIM_%d] Update : "), _cur_anim_mode);
_cur_anim_color.h = random(0,255);
_cur_anim_color.h = random(0,255);
_setLedsHSV(_cur_anim_color); _setLedsHSV(_cur_anim_color);
_cur_anim_step = 0; _cur_anim_step = 0;
_anim_last_update = now; _anim_last_update = now;
@ -796,14 +667,14 @@ void lightSetup() {
DEBUG_MSG_P(PSTR("[LIGHT] LIGHT_PROVIDER = %d (With IR)\n"), LIGHT_PROVIDER); DEBUG_MSG_P(PSTR("[LIGHT] LIGHT_PROVIDER = %d (With IR)\n"), LIGHT_PROVIDER);
pinMode(LIGHT_CH1_PIN, OUTPUT);
pinMode(LIGHT_CH1_PIN, OUTPUT);
pinMode(LIGHT_CH2_PIN, OUTPUT); pinMode(LIGHT_CH2_PIN, OUTPUT);
pinMode(LIGHT_CH3_PIN, OUTPUT); pinMode(LIGHT_CH3_PIN, OUTPUT);
_ir_recv.enableIRIn(); // Start the receiver _ir_recv.enableIRIn(); // Start the receiver
//confirmRgb(); //confirmRgb();
_cur_color = _romLoadColor(); _cur_color = _romLoadColor();
_lightColorRestore(); _lightColorRestore();
@ -849,12 +720,12 @@ void lightUpdate(bool save, bool forward) {
//root["color_hsv"] = lightColor(); //root["color_hsv"] = lightColor();
//root["brightness"] = _cur_color.v; //root["brightness"] = _cur_color.v;
// RGB channels
// RGB channels
//JsonArray& channels = root.createNestedArray("channels"); //JsonArray& channels = root.createNestedArray("channels");
//for (unsigned char id=0; id < lightChannels(); id++) { //for (unsigned char id=0; id < lightChannels(); id++) {
// channels.add(lightChannel(id)); // channels.add(lightChannel(id));
//} //}
// Relay // Relay
JsonArray& relay = root.createNestedArray("relayStatus"); JsonArray& relay = root.createNestedArray("relayStatus");
relay.add(_cur_status); relay.add(_cur_status);
@ -927,7 +798,7 @@ unsigned int lightChannel(unsigned char id) {
return current_rvb.b; return current_rvb.b;
} }
else{ else{
DEBUG_MSG_P(PSTR(" [ERROR] GET lightChannel : %s\n"), id);
DEBUG_MSG_P(PSTR(" [ERROR] GET lightChannel : %s\n"), id);
return 0; return 0;
} }
} }
@ -935,27 +806,27 @@ unsigned int lightChannel(unsigned char id) {
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Set Channel's Value // Set Channel's Value
void lightChannel(unsigned char id, unsigned int value) { void lightChannel(unsigned char id, unsigned int value) {
DEBUG_MSG_P(PSTR("[WEB|API] Set Color Channel "));
DEBUG_MSG_P(PSTR("[WEB|API] Set Color Channel "));
value= constrain(value, 0, 255); value= constrain(value, 0, 255);
CRGB current_rvb = CHSV(_cur_color); CRGB current_rvb = CHSV(_cur_color);
if(id == 0 ){ if(id == 0 ){
DEBUG_MSG_P(PSTR("RED to : %d => "), value);
DEBUG_MSG_P(PSTR("RED to : %d => "), value);
current_rvb.r=value; current_rvb.r=value;
_buttonColorRVB(current_rvb,0); _buttonColorRVB(current_rvb,0);
} }
else if(id == 1 ){ else if(id == 1 ){
DEBUG_MSG_P(PSTR("GREEN to : %d => "), value);
DEBUG_MSG_P(PSTR("GREEN to : %d => "), value);
current_rvb.g=value; current_rvb.g=value;
_buttonColorRVB(current_rvb,0); _buttonColorRVB(current_rvb,0);
} }
else if(id == 2 ){ else if(id == 2 ){
DEBUG_MSG_P(PSTR("BLUE to : %d => "), value);
DEBUG_MSG_P(PSTR("BLUE to : %d => "), value);
current_rvb.b=value; current_rvb.b=value;
_buttonColorRVB(current_rvb,0); _buttonColorRVB(current_rvb,0);
} }
else{ else{
DEBUG_MSG_P(PSTR(" [ERROR] SET lightChannel %s To %d \n"), id, value);
DEBUG_MSG_P(PSTR(" [ERROR] SET lightChannel %s To %d \n"), id, value);
} }
} }
@ -969,10 +840,10 @@ unsigned int lightBrightness() {
// Set Brightness // Set Brightness
void lightBrightness(unsigned int b) { void lightBrightness(unsigned int b) {
b=constrain(b, 0, 255); b=constrain(b, 0, 255);
DEBUG_MSG_P(PSTR("[WEB|API] Set Brightness to : %d\n"), b);
DEBUG_MSG_P(PSTR("[WEB|API] Set Brightness to : %d\n"), b);
_cur_color.v=b; _cur_color.v=b;
_setLedsHSV(_cur_color); _setLedsHSV(_cur_color);
//set status //set status
if(b > 0){ if(b > 0){
_cur_status=1; _cur_status=1;
@ -1011,34 +882,34 @@ void lightColor(const char * color) {
void _SetLightColorRGB(const char * color) { void _SetLightColorRGB(const char * color) {
//used only from settings //used only from settings
DEBUG_MSG_P(PSTR("[WEB|API] Set (#RGB) Color to : "));
DEBUG_MSG_P(PSTR("[WEB|API] Set (#RGB) Color to : "));
if( _charColorIsValid(color) ){ if( _charColorIsValid(color) ){
DEBUG_MSG_P(PSTR("%s \n"), color);
DEBUG_MSG_P(PSTR("%s \n"), color);
_buttonColorRVB(_charToRgb(color), 0); _buttonColorRVB(_charToRgb(color), 0);
} }
else{ else{
DEBUG_MSG_P(PSTR(" Canceled ('%s' is invalid) !\n"), color);
DEBUG_MSG_P(PSTR(" Canceled ('%s' is invalid) !\n"), color);
} }
} }
void _SetLightColorHSV(const char * color) { void _SetLightColorHSV(const char * color) {
DEBUG_MSG_P(PSTR("[WEB|API] Set (#HSV) Color to : "));
DEBUG_MSG_P(PSTR("[WEB|API] Set (#HSV) Color to : "));
if( _charColorIsValid(color) ){ if( _charColorIsValid(color) ){
DEBUG_MSG_P(PSTR("%s \n"), color);
DEBUG_MSG_P(PSTR("%s \n"), color);
_buttonColorHSV(_charToHsv(color), 0); _buttonColorHSV(_charToHsv(color), 0);
} }
else{ else{
DEBUG_MSG_P(PSTR(" Canceled ('%s' is invalid) !\n"), color);
DEBUG_MSG_P(PSTR(" Canceled ('%s' is invalid) !\n"), color);
} }
} }
void setLightColor (const char * h, const char * s, const char * v){ void setLightColor (const char * h, const char * s, const char * v){
DEBUG_MSG_P(PSTR("[WEB|API] Set Color from (%s,%s,%s) "), h, s, v);
DEBUG_MSG_P(PSTR("[WEB|API] Set Color from (%s,%s,%s) "), h, s, v);
CHSV color; CHSV color;
color.h=strtoul(h, NULL, 10); color.h=strtoul(h, NULL, 10);
color.s=strtoul(s, NULL, 10); color.s=strtoul(s, NULL, 10);
color.v=strtoul(v, NULL, 10); color.v=strtoul(v, NULL, 10);
DEBUG_MSG_P(PSTR("to (%d,%d,%d) "), color.h, color.s, color.v);
DEBUG_MSG_P(PSTR("to (%d,%d,%d) "), color.h, color.s, color.v);
_buttonColorRVB(color, 0); _buttonColorRVB(color, 0);
} }
@ -1062,7 +933,7 @@ bool lightState() {
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Set State // Set State
void lightState(bool state){ void lightState(bool state){
DEBUG_MSG_P(PSTR("[WEB|API] Set Relay to : %u => "), state);
DEBUG_MSG_P(PSTR("[WEB|API] Set Relay to : %u => "), state);
//if(state != _cur_status){ //if(state != _cur_status){
_buttonPower(state); _buttonPower(state);
//} //}
@ -1074,7 +945,7 @@ String lightAnimMode(){
return String(_cur_anim_mode); return String(_cur_anim_mode);
} }
void lightAnimMode(const char * val){ void lightAnimMode(const char * val){
DEBUG_MSG_P(PSTR("[WEB|API] Set AnimMode to %s\n"), val);
DEBUG_MSG_P(PSTR("[WEB|API] Set AnimMode to %s\n"), val);
_setAnimMode(strtoul(val, NULL, 10)); _setAnimMode(strtoul(val, NULL, 10));
} }
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
@ -1082,7 +953,7 @@ String lightAnimSpeed(){
return String(_cur_anim_speed); return String(_cur_anim_speed);
} }
void lightAnimSpeed(const char * val){ void lightAnimSpeed(const char * val){
DEBUG_MSG_P(PSTR("[WEB|API] Set AnimSpeed to %s \n"), val);
DEBUG_MSG_P(PSTR("[WEB|API] Set AnimSpeed to %s \n"), val);
_setAnimSpeed(strtoul(val, NULL, 10)); _setAnimSpeed(strtoul(val, NULL, 10));
} }
@ -1138,7 +1009,7 @@ void _lightMQTTCallback(unsigned int type, const char * topic, const char * payl
_setAnimSpeed(atoi(payload)); _setAnimSpeed(atoi(payload));
lightUpdate(true, mqttForward()); lightUpdate(true, mqttForward());
} }
// Brightness // Brightness
if (t.equals(MQTT_TOPIC_BRIGHTNESS)) { if (t.equals(MQTT_TOPIC_BRIGHTNESS)) {
_setBrightness (constrain(atoi(payload), 0, LIGHT_MAX_BRIGHTNESS)); _setBrightness (constrain(atoi(payload), 0, LIGHT_MAX_BRIGHTNESS));


+ 1
- 1
code/espurna/web.ino View File

@ -215,7 +215,7 @@ void _wsParse(AsyncWebSocketClient *client, uint8_t * payload, size_t length) {
if (lightHasColor()) { if (lightHasColor()) {
if (action.equals("color") && root.containsKey("data")) { if (action.equals("color") && root.containsKey("data")) {
lightColor(root["data"]);
lightColor((const char *) root["data"]);
lightUpdate(true, true); lightUpdate(true, true);
} }


+ 0
- 2
code/platformio.ini View File

@ -13,8 +13,6 @@ build_flags_1m = ${common.build_flags} -Wl,-Tesp8266.flash.1m0.ld
#https://github.com/me-no-dev/ESPAsyncTCP#9b0cc37 // 2.3.0 compatible #https://github.com/me-no-dev/ESPAsyncTCP#9b0cc37 // 2.3.0 compatible
#https://github.com/me-no-dev/ESPAsyncTCP#3795e16 // 2.4.0-rc2 compatible #https://github.com/me-no-dev/ESPAsyncTCP#3795e16 // 2.4.0-rc2 compatible
lib_deps = lib_deps =
DHT sensor library
Adafruit Unified Sensor
https://github.com/xoseperez/Time https://github.com/xoseperez/Time
ArduinoJson ArduinoJson
https://github.com/me-no-dev/ESPAsyncTCP#9b0cc37 https://github.com/me-no-dev/ESPAsyncTCP#9b0cc37


Loading…
Cancel
Save