mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-29 13:46:37 +00:00
Add SM2135 support for BGR
Add SM2135 support for BGR and GRB color bulbs thanks to CrudelisPL (#9073)
This commit is contained in:
parent
9048da1617
commit
8760b8f03b
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
xlgt_04_sm2135.ino - sm2135 five channel led support for Tasmota
|
xlgt_04_sm2135.ino - sm2135 five channel led support for Tasmota
|
||||||
|
|
||||||
Copyright (C) 2020 Theo Arends
|
Copyright (C) 2020 Theo Arends and CrudelisPL
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -20,9 +20,12 @@
|
|||||||
#ifdef USE_LIGHT
|
#ifdef USE_LIGHT
|
||||||
#ifdef USE_SM2135
|
#ifdef USE_SM2135
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* SM2135 RGBCW Led bulbs like some Action LSC SmartLed
|
* SM2135 RGBCW Led bulbs like some Action LSC SmartLed or Polux
|
||||||
*
|
*
|
||||||
|
* Action LSC SmartLed (GreenRedBlue)
|
||||||
* {"NAME":"LSC RGBCW LED","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18}
|
* {"NAME":"LSC RGBCW LED","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18}
|
||||||
|
* Polux E14 (BlueGreenRed) - Notice GPIO00 = 9 (Switch1)
|
||||||
|
* {"NAME":"Polux RGBCW E14","GPIO":[9,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18}
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
#define XLGT_04 4
|
#define XLGT_04 4
|
||||||
@ -50,84 +53,110 @@
|
|||||||
#define SM2135_55MA 0x09
|
#define SM2135_55MA 0x09
|
||||||
#define SM2135_60MA 0x0A
|
#define SM2135_60MA 0x0A
|
||||||
|
|
||||||
|
enum Sm2135Color { SM2135_WCGRB, SM2135_WCBGR };
|
||||||
|
|
||||||
// RGB current CW current
|
// RGB current CW current
|
||||||
const uint8_t SM2135_CURRENT = (SM2135_20MA << 4) | SM2135_15MA; // See https://github.com/arendst/Tasmota/issues/6495#issuecomment-549121683
|
const uint8_t SM2135_CURRENT = (SM2135_20MA << 4) | SM2135_15MA; // See https://github.com/arendst/Tasmota/issues/6495#issuecomment-549121683
|
||||||
|
|
||||||
struct SM2135 {
|
struct SM2135 {
|
||||||
uint8_t clk = 0;
|
uint8_t clk = 0;
|
||||||
uint8_t data = 0;
|
uint8_t data = 0;
|
||||||
|
uint8_t model = SM2135_WCGRB;
|
||||||
} Sm2135;
|
} Sm2135;
|
||||||
|
|
||||||
uint8_t Sm2135Write(uint8_t data)
|
/*********************************************************************************************\
|
||||||
{
|
* SM2135 code
|
||||||
for (uint32_t i = 0; i < 8; i++) {
|
\*********************************************************************************************/
|
||||||
digitalWrite(Sm2135.clk, LOW);
|
|
||||||
digitalWrite(Sm2135.data, (data & 0x80));
|
const uint8_t SM2135_DELAY = 4;
|
||||||
digitalWrite(Sm2135.clk, HIGH);
|
|
||||||
data = data << 1;
|
void Sm2135SetLow(uint8_t pin) {
|
||||||
}
|
noInterrupts();
|
||||||
digitalWrite(Sm2135.clk, LOW);
|
digitalWrite(pin, LOW);
|
||||||
digitalWrite(Sm2135.data, HIGH);
|
pinMode(pin, OUTPUT);
|
||||||
pinMode(Sm2135.data, INPUT);
|
interrupts();
|
||||||
digitalWrite(Sm2135.clk, HIGH);
|
|
||||||
uint8_t ack = digitalRead(Sm2135.data);
|
|
||||||
pinMode(Sm2135.data, OUTPUT);
|
|
||||||
return ack;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sm2135Send(uint8_t *buffer, uint8_t size)
|
void Sm2135SetHigh(uint8_t pin) {
|
||||||
{
|
noInterrupts();
|
||||||
|
pinMode(pin, INPUT_PULLUP);
|
||||||
|
interrupts();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sm2135Init(void) {
|
||||||
digitalWrite(Sm2135.data, LOW);
|
digitalWrite(Sm2135.data, LOW);
|
||||||
for (uint32_t i = 0; i < size; i++) {
|
|
||||||
Sm2135Write(buffer[i]);
|
|
||||||
}
|
|
||||||
digitalWrite(Sm2135.clk, LOW);
|
digitalWrite(Sm2135.clk, LOW);
|
||||||
digitalWrite(Sm2135.clk, HIGH);
|
Sm2135SetHigh(Sm2135.data);
|
||||||
digitalWrite(Sm2135.data, HIGH);
|
Sm2135SetHigh(Sm2135.clk);
|
||||||
|
return (!((digitalRead(Sm2135.data) == LOW || digitalRead(Sm2135.clk) == LOW)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sm2135Write(uint8_t value) {
|
||||||
|
for (uint8_t curr = 0X80; curr != 0; curr >>= 1) {
|
||||||
|
if (curr & value) {
|
||||||
|
Sm2135SetHigh(Sm2135.data);
|
||||||
|
} else {
|
||||||
|
Sm2135SetLow(Sm2135.data);
|
||||||
|
}
|
||||||
|
Sm2135SetHigh(Sm2135.clk);
|
||||||
|
delayMicroseconds(SM2135_DELAY);
|
||||||
|
Sm2135SetLow(Sm2135.clk);
|
||||||
|
}
|
||||||
|
// get Ack or Nak
|
||||||
|
Sm2135SetHigh(Sm2135.data);
|
||||||
|
Sm2135SetHigh(Sm2135.clk);
|
||||||
|
delayMicroseconds(SM2135_DELAY / 2);
|
||||||
|
uint8_t ack = digitalRead(Sm2135.data);
|
||||||
|
Sm2135SetLow(Sm2135.clk);
|
||||||
|
delayMicroseconds(SM2135_DELAY / 2);
|
||||||
|
Sm2135SetLow(Sm2135.data);
|
||||||
|
return (0 == ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sm2135Start(uint8_t addr) {
|
||||||
|
Sm2135SetLow(Sm2135.data);
|
||||||
|
delayMicroseconds(SM2135_DELAY);
|
||||||
|
Sm2135SetLow(Sm2135.clk);
|
||||||
|
return Sm2135Write(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sm2135Stop(void) {
|
||||||
|
Sm2135SetLow(Sm2135.data);
|
||||||
|
delayMicroseconds(SM2135_DELAY);
|
||||||
|
Sm2135SetHigh(Sm2135.clk);
|
||||||
|
delayMicroseconds(SM2135_DELAY);
|
||||||
|
Sm2135SetHigh(Sm2135.data);
|
||||||
|
delayMicroseconds(SM2135_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
|
||||||
bool Sm2135SetChannels(void)
|
bool Sm2135SetChannels(void) {
|
||||||
{
|
|
||||||
uint8_t *cur_col = (uint8_t*)XdrvMailbox.data;
|
uint8_t *cur_col = (uint8_t*)XdrvMailbox.data;
|
||||||
uint8_t data[6];
|
uint8_t data[6];
|
||||||
|
|
||||||
|
Sm2135Start(SM2135_ADDR_MC);
|
||||||
|
Sm2135Write(SM2135_CURRENT);
|
||||||
if ((0 == cur_col[0]) && (0 == cur_col[1]) && (0 == cur_col[2])) {
|
if ((0 == cur_col[0]) && (0 == cur_col[1]) && (0 == cur_col[2])) {
|
||||||
// No color so must be Cold/Warm
|
Sm2135Write(SM2135_CW);
|
||||||
/*
|
Sm2135Stop();
|
||||||
if ((cur_col[3] + cur_col[4]) >= (1 * 256)) {
|
|
||||||
// Scale down to 255 total to fix max power usage of 9W (=40mA)
|
|
||||||
|
|
||||||
// cur_col[3] >>= 1; // Divide by 2
|
|
||||||
// cur_col[4] >>= 1; // Divide by 2
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
data[0] = SM2135_ADDR_MC;
|
|
||||||
data[1] = SM2135_CURRENT;
|
|
||||||
data[2] = SM2135_CW;
|
|
||||||
Sm2135Send(data, 3);
|
|
||||||
delay(1);
|
delay(1);
|
||||||
data[0] = SM2135_ADDR_C;
|
Sm2135Start(SM2135_ADDR_C);
|
||||||
data[1] = cur_col[4]; // Warm
|
Sm2135Write(cur_col[4]); // Warm
|
||||||
data[2] = cur_col[3]; // Cold
|
Sm2135Write(cur_col[3]); // Cold
|
||||||
Sm2135Send(data, 3);
|
|
||||||
} else {
|
} else {
|
||||||
// Color
|
Sm2135Write(SM2135_RGB);
|
||||||
/*
|
if (SM2135_WCBGR == Sm2135.model) {
|
||||||
if ((cur_col[0] + cur_col[1] + cur_col[2]) >= (3 * 256)) {
|
Sm2135Write(cur_col[2]); // Blue
|
||||||
// Scale down to 765 total to fix max power usage of 9W
|
Sm2135Write(cur_col[1]); // Green
|
||||||
// Currently not needed with setting 3 x 15mA = 45mA = 11W = 765
|
Sm2135Write(cur_col[0]); // Red
|
||||||
|
} else {
|
||||||
|
Sm2135Write(cur_col[1]); // Green
|
||||||
|
Sm2135Write(cur_col[0]); // Red
|
||||||
|
Sm2135Write(cur_col[2]); // Blue
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
data[0] = SM2135_ADDR_MC;
|
|
||||||
data[1] = SM2135_CURRENT;
|
|
||||||
data[2] = SM2135_RGB;
|
|
||||||
data[3] = cur_col[1]; // Green
|
|
||||||
data[4] = cur_col[0]; // Red
|
|
||||||
data[5] = cur_col[2]; // Blue
|
|
||||||
Sm2135Send(data, 6);
|
|
||||||
}
|
}
|
||||||
|
Sm2135Stop();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -138,14 +167,18 @@ void Sm2135ModuleSelected(void)
|
|||||||
Sm2135.clk = Pin(GPIO_SM2135_CLK);
|
Sm2135.clk = Pin(GPIO_SM2135_CLK);
|
||||||
Sm2135.data = Pin(GPIO_SM2135_DAT);
|
Sm2135.data = Pin(GPIO_SM2135_DAT);
|
||||||
|
|
||||||
pinMode(Sm2135.data, OUTPUT);
|
Sm2135.model = SM2135_WCGRB;
|
||||||
digitalWrite(Sm2135.data, HIGH);
|
if (PinUsed(GPIO_SWT1)) {
|
||||||
pinMode(Sm2135.clk, OUTPUT);
|
Sm2135.model = SM2135_WCBGR;
|
||||||
digitalWrite(Sm2135.clk, HIGH);
|
pinMode(Pin(GPIO_SWT1), INPUT); // Discard GPIO_SWT functionality
|
||||||
|
SetPin(Pin(GPIO_SWT1), AGPIO(GPIO_NONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
Sm2135Init();
|
||||||
|
|
||||||
light_type = LT_RGBWC;
|
light_type = LT_RGBWC;
|
||||||
light_flg = XLGT_04;
|
light_flg = XLGT_04;
|
||||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: SM2135 Found"));
|
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: SM2135 (%s) Found"), (SM2135_WCBGR == Sm2135.model) ? PSTR("BGR") : PSTR("GRB"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user