Skip to content

Commit

Permalink
Support for 5 channel lights, backwards incompatible
Browse files Browse the repository at this point in the history
  • Loading branch information
xoseperez committed Aug 26, 2017
1 parent 9cf1e88 commit 3126ab2
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 104 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Expand Up @@ -3,6 +3,13 @@
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [2.0.0] 2017-08-26
### Added
- Support for 5 channels bulbs

### Changed
- Color has now 5 components, check examples

## [1.0.1] 2017-02-26
### Added
- Support for AVR architecture (untested)
Expand Down
5 changes: 3 additions & 2 deletions README.md
Expand Up @@ -13,11 +13,12 @@ A simple example, turning the red LEDs on.
#define MY9291_DI_PIN 13
#define MY9291_DCKI_PIN 15
#define CHANNELS 4
my9291 _my9291 = my9291(MY9291_DI_PIN, MY9291_DCKI_PIN, MY9291_COMMAND_DEFAULT);
my9291 _my9291 = my9291(MY9291_DI_PIN, MY9291_DCKI_PIN, MY9291_COMMAND_DEFAULT, CHANNELS);
void setup() {
_my9291.setColor((my9291_color_t) { 255, 0, 0, 0 }); // RED 100% duty cycle
_my9291.setColor((my9291_color_t) { 255, 0, 0, 0, 0 }); // RED 100% duty cycle (even if only 4 channels color has 5 components)
_my9291.setState(true);
}
Expand Down
10 changes: 5 additions & 5 deletions examples/esp8285/esp8285_rainbow.cpp
Expand Up @@ -35,13 +35,13 @@ void wifiSetup() {
void rainbow(unsigned char index) {

if (index < 85) {
_my9291->setColor((my9291_color_t) { (unsigned int) index * 3, (unsigned int) 255 - index * 3, 0, 0 });
_my9291->setColor((my9291_color_t) { (unsigned int) index * 3, (unsigned int) 255 - index * 3, 0, 0, 0 });
} else if (index < 170) {
index -= 85;
_my9291->setColor((my9291_color_t) { (unsigned int) 255 - index * 3, 0, (unsigned int) index * 3, 0 });
_my9291->setColor((my9291_color_t) { (unsigned int) 255 - index * 3, 0, (unsigned int) index * 3, 0, 0 });
} else {
index -= 170;
_my9291->setColor((my9291_color_t) { 0, (unsigned int) index * 3, (unsigned int) 255 - index * 3, 0 });
_my9291->setColor((my9291_color_t) { 0, (unsigned int) index * 3, (unsigned int) 255 - index * 3, 0, 0 });
}

}
Expand Down Expand Up @@ -78,8 +78,8 @@ void setup() {
});
ArduinoOTA.begin();

// MY9291
_my9291 = new my9291(MY9291_DI_PIN, MY9291_DCKI_PIN, MY9291_COMMAND_DEFAULT);
// MY9291 with 4 channels (like the AiThinker Ai-Light)
_my9291 = new my9291(MY9291_DI_PIN, MY9291_DCKI_PIN, MY9291_COMMAND_DEFAULT, 4);
_my9291->setState(true);

}
Expand Down
9 changes: 5 additions & 4 deletions examples/uno/uno_rainbow.cpp
Expand Up @@ -4,18 +4,19 @@
#define MY9291_DCKI_PIN 15
#define RAINBOW_DELAY 10

my9291 _my9291 = my9291(MY9291_DI_PIN, MY9291_DCKI_PIN, MY9291_COMMAND_DEFAULT);
// MY9291 with 4 channels (like the AiThinker Ai-Light)
my9291 _my9291 = my9291(MY9291_DI_PIN, MY9291_DCKI_PIN, MY9291_COMMAND_DEFAULT, 4);

void rainbow(unsigned char index) {

if (index < 85) {
_my9291.setColor((my9291_color_t) { (unsigned int) index * 3, (unsigned int) 255 - index * 3, 0, 0 });
_my9291.setColor((my9291_color_t) { (unsigned int) index * 3, (unsigned int) 255 - index * 3, 0, 0, 0 });
} else if (index < 170) {
index -= 85;
_my9291.setColor((my9291_color_t) { (unsigned int) 255 - index * 3, 0, (unsigned int) index * 3, 0 });
_my9291.setColor((my9291_color_t) { (unsigned int) 255 - index * 3, 0, (unsigned int) index * 3, 0, 0 });
} else {
index -= 170;
_my9291.setColor((my9291_color_t) { 0, (unsigned int) index * 3, (unsigned int) 255 - index * 3, 0 });
_my9291.setColor((my9291_color_t) { 0, (unsigned int) index * 3, (unsigned int) 255 - index * 3, 0, 0 });
}

}
Expand Down
2 changes: 1 addition & 1 deletion library.json
Expand Up @@ -6,7 +6,7 @@
"type": "git",
"url": "https://github.com/xoseperez/my9291.git"
},
"version": "1.0.1",
"version": "2.0.0",
"license": "GPL-3.0",
"frameworks": "arduino",
"platforms": "espressif8266",
Expand Down
2 changes: 1 addition & 1 deletion library.properties
@@ -1,5 +1,5 @@
name=my9291
version=1.0.1
version=2.0.0
author=Xose Pérez <xose.perez@gmail.com>
maintainer=Xose Pérez <xose.perez@gmail.com>
sentence=MY9291 LED driver library for Arduino ESP8266
Expand Down
162 changes: 75 additions & 87 deletions src/my9291.cpp
@@ -1,6 +1,6 @@
/*
MY9291 LED Driver Arduino library 1.0.1
MY9291 LED Driver Arduino library 2.0.0
Based on the C driver by MaiKe Labs
Copyright (c) 2016 - 2026 MaiKe Labs
Expand Down Expand Up @@ -36,92 +36,92 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#endif

void my9291::_di_pulse(unsigned int times) {
unsigned int i;
for (i = 0; i < times; i++) {
for (unsigned int i = 0; i < times; i++) {
digitalWrite(_pin_di, HIGH);
digitalWrite(_pin_di, LOW);
}
}

void my9291::_dcki_pulse(unsigned int times) {
unsigned int i;
for (i = 0; i < times; i++) {
for (unsigned int i = 0; i < times; i++) {
digitalWrite(_pin_dcki, HIGH);
digitalWrite(_pin_dcki, LOW);
}
}

void my9291::_set_cmd(my9291_cmd_t command) {
void my9291::_write(unsigned int data, unsigned char bit_length) {

unsigned int mask = (0x01 << (bit_length - 1));

for (unsigned int i = 0; i < bit_length / 2; i++) {
digitalWrite(_pin_dcki, LOW);
digitalWrite(_pin_di, (data & mask));
digitalWrite(_pin_dcki, HIGH);
data = data << 1;
digitalWrite(_pin_di, (data & mask));
digitalWrite(_pin_dcki, LOW);
digitalWrite(_pin_di, LOW);
data = data << 1;
}

unsigned char i;
unsigned char command_data = *(unsigned char *) (&command);
_command = command;
}

void my9291::_set_cmd(my9291_cmd_t command) {

// ets_intr_lock();
// TStop > 12us.

// TStop > 12us.
os_delay_us(12);
// Send 12 DI pulse, after 6 pulse's falling edge store duty data, and 12

// Send 12 DI pulse, after 6 pulse's falling edge store duty data, and 12
// pulse's rising edge convert to command mode.
_di_pulse(12);
// Delay >12us, begin send CMD data

// Delay >12us, begin send CMD data
os_delay_us(12);
// Send CMD data

for (i = 0; i < 4; i++) {
// DCK = 0;
digitalWrite(_pin_dcki, LOW);
if (command_data & 0x80) {
// DI = 1;
digitalWrite(_pin_di, HIGH);
} else {
// DI = 0;
digitalWrite(_pin_di, LOW);
}
// DCK = 1;
digitalWrite(_pin_dcki, HIGH);
command_data = command_data << 1;
if (command_data & 0x80) {
// DI = 1;
digitalWrite(_pin_di, HIGH);
} else {
// DI = 0;
digitalWrite(_pin_di, LOW);
}
// DCK = 0;
digitalWrite(_pin_dcki, LOW);
// DI = 0;
digitalWrite(_pin_di, LOW);
command_data = command_data << 1;
}
// Send CMD data
unsigned char command_data = *(unsigned char *) (&command);
_write(command_data, 8);

// TStart > 12us. Delay 12 us.
os_delay_us(12);
// Send 16 DI pulse,at 14 pulse's falling edge store CMD data, and

// Send 16 DI pulse,at 14 pulse's falling edge store CMD data, and
// at 16 pulse's falling edge convert to duty mode.
_di_pulse(16);
// TStop > 12us.

// TStop > 12us.
os_delay_us(12);
// ets_intr_unlock();

// ets_intr_unlock();

}

void my9291::_send() {

unsigned char i = 0;
unsigned char channel = 0;
unsigned char bit_length = 8;
unsigned int duty_current = 0;

// Color to show
unsigned int duty[4] = {0};
unsigned int duty[6] = {0};
if (_state) {
duty[0] = _color.red;
duty[1] = _color.green;
duty[2] = _color.blue;
duty[3] = _color.white;
if (_channels == 4) {
duty[0] = _color.red;
duty[1] = _color.green;
duty[2] = _color.blue;
duty[3] = _color.white;
duty[4] = 0;
duty[5] = 0;
} else {
duty[0] = _color.white;
duty[1] = _color.warm;
duty[2] = 0;
duty[3] = _color.green;
duty[4] = _color.red;
duty[5] = _color.blue;
}
}

unsigned char bit_length = 8;
switch (_command.bit_width) {

case MY9291_CMD_BIT_WIDTH_16:
bit_length = 16;
break;
Expand All @@ -140,48 +140,27 @@ void my9291::_send() {
}

// ets_intr_lock();
// TStop > 12us.

// TStop > 12us.
os_delay_us(12);

for (channel = 0; channel < 4; channel++) { //RGBW 4CH
// RGBW Channel
duty_current = duty[channel];
// Send 8bit/12bit/14bit/16bit Data
for (i = 0; i < bit_length / 2; i++) {
// DCK = 0;
digitalWrite(_pin_dcki, LOW);
if (duty_current & (0x01 << (bit_length - 1))) {
// DI = 1;
digitalWrite(_pin_di, HIGH);
} else {
// DI = 0;
digitalWrite(_pin_di, LOW);
}
// DCK = 1;
digitalWrite(_pin_dcki, HIGH);
duty_current = duty_current << 1;
if (duty_current & (0x01 << (bit_length - 1))) {
// DI = 1;
digitalWrite(_pin_di, HIGH);
} else {
// DI = 0;
digitalWrite(_pin_di, LOW);
}
//DCK = 0;
digitalWrite(_pin_dcki, LOW);
//DI = 0;
digitalWrite(_pin_di, LOW);
duty_current = duty_current << 1;
}
// Send color data
unsigned int length = (_channels == 4) ? 4 : 6;
for (unsigned char channel = 0; channel < length; channel++) {
_write(duty[channel], bit_length);
}

// TStart > 12us. Ready for send DI pulse.
os_delay_us(12);

// Send 8 DI pulse. After 8 pulse falling edge, store old data.
_di_pulse(8);

// TStop > 12us.
os_delay_us(12);

// ets_intr_unlock();

}

// -----------------------------------------------------------------------------
Expand All @@ -195,7 +174,8 @@ void my9291::setColor(my9291_color_t color) {
_color.green = color.green;
_color.blue = color.blue;
_color.white = color.white;
DEBUG_MSG_MY9291("[MY9291] setColor: %d, %d, %d, %d\n", _color.red, _color.green, _color.blue, _color.white);
_color.warm = color.warm;
DEBUG_MSG_MY9291("[MY9291] setColor: %d, %d, %d, %d, %d\n", _color.red, _color.green, _color.blue, _color.white, _color.warm);
if (_state) _send();
}

Expand All @@ -211,10 +191,12 @@ void my9291::setState(bool state) {

// -----------------------------------------------------------------------------

my9291::my9291(unsigned char di, unsigned char dcki, my9291_cmd_t command) {
my9291::my9291(unsigned char di, unsigned char dcki, my9291_cmd_t command, unsigned char channels) {

_pin_di = di;
_pin_dcki = dcki;
_command = command;
if (channels == 4 || channels == 5) _channels = channels;

pinMode(_pin_di, OUTPUT);
pinMode(_pin_dcki, OUTPUT);
Expand All @@ -223,7 +205,13 @@ my9291::my9291(unsigned char di, unsigned char dcki, my9291_cmd_t command) {
digitalWrite(_pin_dcki, LOW);

// Clear all duty register
_dcki_pulse(64 / 2);
if (_channels == 4) {
_dcki_pulse(32);
} else {
_dcki_pulse(64);
}

// Send init command
_set_cmd(command);

DEBUG_MSG_MY9291("[MY9291] Initialized\n");
Expand Down
11 changes: 7 additions & 4 deletions src/my9291.h
@@ -1,6 +1,6 @@
/*
MY9291 LED Driver Arduino library 0.1.0
MY9291 LED Driver Arduino library 2.0.0
Copyright (c) 2016 - 2026 MaiKe Labs
Copyright (C) 2017 - Xose Pérez
Expand Down Expand Up @@ -29,7 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#if ARDUINO_ARCH_ESP8266
#define DEBUG_MSG_MY9291(...) DEBUG_MY9291.printf( __VA_ARGS__ )
#elif ARDUINO_ARCH_AVR
#define DEBUG_MSG_MY9291(...) { char buffer[81]; snprintf(buffer, 80, __VA_ARGS__ ); DEBUG_MY9291.print(buffer); }
#define DEBUG_MSG_MY9291(...) { char buffer[80]; snprintf(buffer, sizeof(buffer), __VA_ARGS__ ); DEBUG_MY9291.print(buffer); }
#endif
#else
#define DEBUG_MSG_MY9291(...)
Expand Down Expand Up @@ -78,6 +78,7 @@ typedef struct {
unsigned int green;
unsigned int blue;
unsigned int white;
unsigned int warm;
} my9291_color_t;

#define MY9291_COMMAND_DEFAULT { \
Expand All @@ -93,7 +94,7 @@ class my9291 {

public:

my9291(unsigned char di, unsigned char dcki, my9291_cmd_t command);
my9291(unsigned char di, unsigned char dcki, my9291_cmd_t command, unsigned char channels = 4);
void setColor(my9291_color_t color);
my9291_color_t getColor();
void setState(bool state);
Expand All @@ -105,10 +106,12 @@ class my9291 {
void _dcki_pulse(unsigned int times);
void _set_cmd(my9291_cmd_t command);
void _send();
void _write(unsigned int data, unsigned char bit_length);

my9291_cmd_t _command;
unsigned char _channels = 4;
bool _state = false;
my9291_color_t _color = {0, 0, 0, 0};
my9291_color_t _color = {0, 0, 0, 0, 0};
unsigned char _pin_di;
unsigned char _pin_dcki;

Expand Down

0 comments on commit 3126ab2

Please sign in to comment.