Added effect 'rainbow'.

This commit is contained in:
Fabian Schlenz 2021-01-19 19:52:40 +00:00
parent d9708d9159
commit 8949041812
6 changed files with 46 additions and 13 deletions

View File

@ -26,6 +26,7 @@ class Node {
Node(uint16_t number, Coords c, uint8_t direction);
Node* create_neighbour(uint8_t edge);
Coords coords_at_direction(uint8_t edge);
uint16_t distance_from_start = 0;
void blend_to(CRGB color, uint16_t effect_id=0, uint8_t effect_speed=0);
void set_color(CRGB color);

View File

@ -24,7 +24,8 @@ enum AnimationMode {
AM_OFF,
AM_ERROR,
AM_NONE,
AM_STATIC
AM_STATIC,
AM_RAINBOW
};
extern std::map<AnimationMode, const char*> animation_mode_names;

View File

@ -35,6 +35,7 @@ void setup_layout() {
LOGln("Setting up layout...");
uint8_t layout[] = LAYOUT;
Node* current_node = new Node(0, {0, 0}, 0);
current_node->distance_from_start = 1;
nodes.push_back(current_node);
for(uint16_t i=0; i<NODE_COUNT-1; i++) {
@ -47,7 +48,7 @@ void setup_layout() {
if (verbose) LOGln("Looking for neighbours of node #%d @ %d,%d", n1->_number, n1->coords.x, n1->coords.y);
for(int edge=0; edge<CORNERS_PER_PART; edge++) {
Coords c = n1->coords_at_direction(edge);
if (verbose) LOGln(" Chcking edge %d @ %d,%d...", edge, c.x, c.y);
if (verbose) LOGln(" Checking edge %d @ %d,%d...", edge, c.x, c.y);
Node* found = nullptr;
for(Node* n2 : nodes) {
@ -82,8 +83,25 @@ void setup_layout() {
}
}
bool checked_all = false;
while (!checked_all) {
checked_all = true;
for(Node* n : nodes) {
if (n->distance_from_start == 0) {
checked_all = false;
} else {
for(int i=0; i<CORNERS_PER_PART; i++) {
if (n->neighbours[i] != nullptr && (n->neighbours[i]->distance_from_start==0 || n->neighbours[i]->distance_from_start > n->distance_from_start)) {
n->neighbours[i]->distance_from_start = n->distance_from_start+1;
}
}
}
}
}
for (Node* node : nodes) {
LOGln("Node #%d:", node->_number);
LOGln(" Distance from start: %d", node->distance_from_start);
for(Corner* corner : node->_corners) {
LOGln(" Corner #%d,%d:", node->_number, corner->number);
for (auto c: corner->_long_neighbours) {
@ -95,7 +113,7 @@ void setup_layout() {
}
for (int i=0; i<CORNERS_PER_PART; i++) {
if (node->neighbours[i]==nullptr) {
LOGln(" Neighbour %d: NULL", i);
LOGln(" Neighbour %d: -", i);
} else {
LOGln(" Neighbour %d: #%d", i, node->neighbours[i]->_number);
}
@ -276,6 +294,13 @@ void loop() {
for(Node* node : nodes) {
node->set_color(active_mode == AM_OFF ? CRGB::Black : color);
}
} else if (active_mode == AM_RAINBOW) {
const uint8_t speed = 5; // seconds (approx.) for full color sweep
const uint8_t diff_per_node = 5;
uint8_t base_hue = (millis() * 256 / speed) / 1000;
for(Node* node : nodes) {
node->set_color(CHSV(base_hue + diff_per_node * node->distance_from_start, 255, 255));
}
} else { // This includes AM_ERROR
for(Node* node : nodes) {
node->set_color(CRGB::Black);

View File

@ -11,7 +11,7 @@ LOGln("Connecting to MQTT broker...");
char buffer[40];
snprintf(buffer, 40, "online %s", wifi.localIP().toString().c_str());
mqtt.publish(MQTT_TOPIC "available_long", buffer, true);
mqtt.subscribe(MQTT_TOPIC"cmnd");
mqtt.subscribe(MQTT_TOPIC "cmnd");
String discovery_msg = "{"
"\"~\":\"" MQTT_TOPIC "\",\"avty_t\":\"~available\",\"cmd_t\":\"~cmnd\",\"stat_t\":\"~state\","
"\"name\":\"ESPleaf\",\"schema\":\"json\","
@ -68,6 +68,7 @@ void mqtt_setup() {
void mqtt_loop() {
if (!mqtt.connected()) {
LOGln("MQTT disconnected. Reason: %d", mqtt.state());
connect();
}
mqtt.loop();

View File

@ -9,5 +9,6 @@ std::map<AnimationMode, const char*> animation_mode_names {
{AM_OFF, "off"},
{AM_ERROR, "error"},
{AM_NONE, "NONE"},
{AM_STATIC, "static"}
{AM_STATIC, "static"},
{AM_RAINBOW, "rainbow"}
};

View File

@ -27,14 +27,18 @@ void State::parse_state(String state) {
}
void State::parse_mode(String mode) {
if (mode.equals("nodes")) { set_mode(AM_NODES); }
else if (mode.equals("first_node")) { set_mode(AM_FIRST_NODE); }
else if (mode.equals("corners")) { set_mode(AM_CORNERS); }
else if (mode.equals("first_corner")) { set_mode(AM_FIRST_CORNER); }
else if (mode.equals("off")) { set_mode(AM_OFF); }
else if (mode.equals("flash")) { set_mode(AM_FLASH); }
else if (mode.equals("static")) { set_mode(AM_STATIC); }
else { LOGln("parse_mode: Unknown mode '%s'.", mode.c_str()); }
AnimationMode m = AM_NONE;
for (std::pair<AnimationMode, const char*> pair : animation_mode_names) {
if (mode.equals(pair.second)) {
m = pair.first;
break;
}
}
if (m == AM_NONE) {
LOGln("parse_mode: Unknown mode '%s'.", mode.c_str());
} else {
set_mode(m);
}
}
void State::set_mode(AnimationMode m) {