Add support for SM2135

Add support for SM2135 as used in Action LSC Smart Led E14 (#6495)
This commit is contained in:
Theo Arends 2019-10-04 16:45:05 +02:00
parent 22dbe597a2
commit 2d194f427f
27 changed files with 126 additions and 31 deletions

View File

@ -2,6 +2,7 @@
* 6.6.0.15 20191003
* Change command PulseTime JSON message format and allow display of all pulsetimer information (#6519)
* Add support for Chint DDSU666 Modbus energy meter by Pablo Zerón
* Add support for SM2135 as used in Action LSC Smart Led E14 (#6495)
*
* 6.6.0.14 20190925
* Change command Tariffx to allow time entries like 23 (hours), 1320 (minutes) or 23:00. NOTE: As this is development branch previous tariffs are lost! (#6488)

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "А"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "А"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "安"

View File

@ -620,6 +620,8 @@
#define D_SENSOR_DDS2382_RX "DDS238-2 Rx"
#define D_SENSOR_DDSU666_TX "DDSU666 Tx"
#define D_SENSOR_DDSU666_RX "DDSU666 Rx"
#define D_SENSOR_SM2135_CLK "SM2135 Clk"
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
// Units
#define D_UNIT_AMPERE "安"

View File

@ -315,6 +315,7 @@
#define USE_ARMTRONIX_DIMMERS // Add support for Armtronix Dimmers (+1k4 code)
#define USE_PS_16_DZ // Add support for PS-16-DZ Dimmer and Sonoff L1 (+2k code)
//#define ROTARY_V1 // Add support for MI Desk Lamp
#define USE_SM2135 // Add support for SM2135 RGBCW led control (+0k6 code)
//#define USE_SHUTTER // Add Shutter support for up to 4 shutter with different motortypes (+6k code)
// -- Counter input -------------------------------

View File

@ -204,6 +204,8 @@ enum UserSelectablePins {
GPIO_DDS2382_RX, // DDS2382 Serial interface
GPIO_DDSU666_TX, // DDSU666 Serial interface
GPIO_DDSU666_RX, // DDSU666 Serial interface
GPIO_SM2135_CLK, // SM2135 Clk
GPIO_SM2135_DAT, // SM2135 Dat
GPIO_SENSOR_END };
// Programmer selectable GPIO functionality
@ -280,6 +282,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_A4988_DIR "|" D_SENSOR_A4988_STP "|" D_SENSOR_A4988_ENA "|" D_SENSOR_A4988_MS1 "|" D_SENSOR_A4988_MS2 "|" D_SENSOR_A4988_MS3 "|"
D_SENSOR_DDS2382_TX "|" D_SENSOR_DDS2382_RX "|"
D_SENSOR_DDSU666_TX "|" D_SENSOR_DDSU666_RX "|"
D_SENSOR_SM2135_CLK "|" D_SENSOR_SM2135_DAT "|"
;
// User selectable ADC0 functionality
@ -554,6 +557,10 @@ const uint8_t kGpioNiceList[] PROGMEM = {
GPIO_SM16716_DAT, // SM16716 DATA
GPIO_SM16716_SEL, // SM16716 SELECT
#endif // USE_SM16716
#ifdef USE_SM2135
GPIO_SM2135_CLK, // SM2135 CLOCK
GPIO_SM2135_DAT, // SM2135 DATA
#endif // USE_SM2135
#ifdef USE_TUYA_MCU
GPIO_TUYA_TX, // Tuya Serial interface
GPIO_TUYA_RX, // Tuya Serial interface

View File

@ -2014,6 +2014,10 @@ void LightAnimate(void)
XdrvMailbox.data = (char*)cur_col;
XdrvMailbox.data_len = sizeof(cur_col);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "R%d G%d B%d, C%d W%d"),
cur_col[0], cur_col[1], cur_col[2], cur_col[3], cur_col[4]);
if (XdrvCall(FUNC_SET_CHANNELS)) {
// Serviced
}

View File

@ -1,5 +1,5 @@
/*
xdrv_26_sm2135.ino - sm2135 I2C five channel led support for Sonoff-Tasmota
xdrv_26_sm2135.ino - sm2135 five channel led support for Sonoff-Tasmota
Copyright (C) 2019 Theo Arends
@ -20,60 +20,95 @@
#ifdef USE_LIGHT
#ifdef USE_SM2135
/*********************************************************************************************\
* SM2135 I2C RGBCW Led bulbs like Action LSC SmartLed
* SM2135 RGBCW Led bulbs like Action LSC SmartLed
*
* {"NAME":"LSC RGBCW LED","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18}
\*********************************************************************************************/
#define XDRV_26 26
#define SM2135_ADDR 0x40 // 0x40 .. 0x46
#define SM2135_ADDR 0xC0
//#define SM2135_CURRENT 0x24 // Defaults: 20mA for RGB, 30mA for CW
#define SM2135_CURRENT 0x16 // 3 x 15mA for RGB, 2 x 40mA/2 for CW
//#define SM2135_CURRENT 0x12 // 3 x 15mA for RGB, 2 x 20mA for CW - Get really hot
//#define SM2135_CURRENT 0x11 // 3 x 15mA for RGB, 2 x 15mA for CW
#define SM2135_CURRENT 0x20 // 3 x 20mA for RGB, 2 x 10mA for CW
#define SM2135_RGB 0x00
#define SM2135_CW 0x80
struct SM2135 {
uint8_t clk = 0;
uint8_t data = 0;
bool found = true;
} Sm2135;
uint8_t Sm2135Write(uint8_t data)
{
for (uint32_t i = 0; i < 8; i++) {
digitalWrite(Sm2135.clk, LOW);
digitalWrite(Sm2135.data, (data & 0x80));
digitalWrite(Sm2135.clk, HIGH);
data = data << 1;
}
digitalWrite(Sm2135.clk, LOW);
digitalWrite(Sm2135.data, HIGH);
pinMode(Sm2135.data, INPUT);
digitalWrite(Sm2135.clk, HIGH);
uint8_t ack = digitalRead(Sm2135.data);
pinMode(Sm2135.data, OUTPUT);
return ack;
}
void Sm2135Send(uint8_t *buffer, uint8_t size)
{
digitalWrite(Sm2135.data, LOW);
for (uint32_t i = 0; i < size; i++) {
Sm2135Write(buffer[i]);
}
digitalWrite(Sm2135.clk, LOW);
digitalWrite(Sm2135.clk, HIGH);
digitalWrite(Sm2135.data, HIGH);
}
bool Sm2135SetChannels(void)
{
char *buffer = XdrvMailbox.data;
// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SM1: R %d G %d B %d, C %d W %d"), buffer[0], buffer[1], buffer[2], buffer[3], buffer[4]);
uint8_t data[8];
if (('\0' == buffer[0]) && ('\0' == buffer[1]) && ('\0' == buffer[2])) {
// No color so must be Cold/Warm
/*
if ((buffer[3] + buffer[4]) >= (1 * 256)) {
// Scale down to 255 total to fix max power usage of 9W (=40mA)
// Currently not needed with setting 2 x 40mA/2 = 40mA = 9W = 255 (handled by lights.ino)
buffer[3] >>= 1; // Divide by 2
buffer[4] >>= 1; // Divide by 2
// buffer[3] >>= 1; // Divide by 2
// buffer[4] >>= 1; // Divide by 2
}
Wire.beginTransmission(SM2135_ADDR);
Wire.write(SM2135_CURRENT); // Set current to 40mA
Wire.write(SM2135_CW); // Select CW - Shutdown RGB?
Wire.endTransmission();
*/
data[0] = SM2135_ADDR;
data[1] = SM2135_CURRENT;
data[2] = SM2135_CW;
Sm2135Send(data, 3);
delay(1);
Wire.beginTransmission(SM2135_ADDR +5);
Wire.write(buffer[3]); // Cold
Wire.write(buffer[4]); // Warm
Wire.endTransmission();
data[0] = SM2135_ADDR +5;
data[1] = buffer[4]; // Warm
data[2] = buffer[3]; // Cold
Sm2135Send(data, 3);
} else {
// Color
/*
if ((buffer[0] + buffer[1] + buffer[2]) >= (3 * 256)) {
// Scale down to 765 total to fix max power usage of 9W
// Currently not needed with setting 3 x 15mA = 45mA = 11W = 765
}
Wire.beginTransmission(SM2135_ADDR);
Wire.write(SM2135_CURRENT); // Set current to 15mA
Wire.write(SM2135_RGB); // Select RGB - Shutdown CW?
Wire.write(buffer[0]); // Red
Wire.write(buffer[1]); // Green
Wire.write(buffer[2]); // Blue
Wire.endTransmission();
*/
data[0] = SM2135_ADDR;
data[1] = SM2135_CURRENT;
data[2] = SM2135_RGB;
data[3] = buffer[1]; // Green
data[4] = buffer[0]; // Red
data[5] = buffer[2]; // Blue
Sm2135Send(data, 6);
}
return true;
@ -81,14 +116,17 @@ bool Sm2135SetChannels(void)
bool Sm2135ModuleSelected(void)
{
if (I2cDevice(SM2135_ADDR)) {
if ((pin[GPIO_SM2135_CLK] < 99) && (pin[GPIO_SM2135_DAT] < 99)) {
Sm2135.clk = pin[GPIO_SM2135_CLK];
Sm2135.data = pin[GPIO_SM2135_DAT];
// Make sure it is the SM2135 chip as it's address is also used by HTU21, INA219, INA226
// EXPERIMENTAL: Need further testing
pinMode(Sm2135.data, OUTPUT);
digitalWrite(Sm2135.data, HIGH);
pinMode(Sm2135.clk, OUTPUT);
digitalWrite(Sm2135.clk, HIGH);
light_type = LT_RGBWC;
AddLog_P2(LOG_LEVEL_DEBUG, S_LOG_I2C_FOUND_AT, "SM2135", SM2135_ADDR);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: SM2135 Found"));
} else {
Sm2135.found = false;
}
@ -103,7 +141,7 @@ bool Xdrv26(uint8_t function)
{
bool result = false;
if (i2c_flg && Sm2135.found) {
if (Sm2135.found) {
switch (function) {
case FUNC_SET_CHANNELS:
result = Sm2135SetChannels();