From 18535b811be94ebb8103dcef5bf2f07e9bd8ad8e Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 1 Jan 2020 15:32:00 +0100 Subject: update tv_light --- tv_light/.gitignore | 4 + tv_light/lib/readme.txt | 36 +++++ tv_light/platformio.ini | 26 ++++ tv_light/src/tv_light.ino | 339 +++++++++++++++++++++++++++++++++++++++++++++ tv_light/tv_light.ino | 340 ---------------------------------------------- 5 files changed, 405 insertions(+), 340 deletions(-) create mode 100644 tv_light/.gitignore create mode 100644 tv_light/lib/readme.txt create mode 100644 tv_light/platformio.ini create mode 100644 tv_light/src/tv_light.ino delete mode 100644 tv_light/tv_light.ino (limited to 'tv_light') diff --git a/tv_light/.gitignore b/tv_light/.gitignore new file mode 100644 index 0000000..e05273b --- /dev/null +++ b/tv_light/.gitignore @@ -0,0 +1,4 @@ +.pioenvs +.clang_complete +.gcc-flags.json +.piolibdeps \ No newline at end of file diff --git a/tv_light/lib/readme.txt b/tv_light/lib/readme.txt new file mode 100644 index 0000000..3f9e008 --- /dev/null +++ b/tv_light/lib/readme.txt @@ -0,0 +1,36 @@ + +This directory is intended for the project specific (private) libraries. +PlatformIO will compile them to static libraries and link to executable file. + +The source code of each library should be placed in separate directory, like +"lib/private_lib/[here are source files]". + +For example, see how can be organized `Foo` and `Bar` libraries: + +|--lib +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| |--Foo +| | |- Foo.c +| | |- Foo.h +| |- readme.txt --> THIS FILE +|- platformio.ini +|--src + |- main.c + +Then in `src/main.c` you should use: + +#include +#include + +// rest H/C/CPP code + +PlatformIO will find your libraries automatically, configure preprocessor's +include paths and build them. + +More information about PlatformIO Library Dependency Finder +- http://docs.platformio.org/en/stable/librarymanager/ldf.html diff --git a/tv_light/platformio.ini b/tv_light/platformio.ini new file mode 100644 index 0000000..6e0f132 --- /dev/null +++ b/tv_light/platformio.ini @@ -0,0 +1,26 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter, extra scripting +; Upload options: custom port, speed and extra flags +; Library options: dependencies, extra library storages +; +; Please visit documentation for the other options and examples +; http://docs.platformio.org/en/stable/projectconf.html + +[platformio] +env_default = pro8MHzatmega328 + +[env:miniatmega328] +platform=atmelavr +board=miniatmega328 +framework=arduino + +[env:pro8MHzatmega328] +platform=atmelavr +board=pro8MHzatmega328 +framework=arduino +; minicore/optirun uses 38400 for 8MHz +upload_speed=38400 + +[platformio] +lib_dir=/home/manuel/coding/Arduino/libraries diff --git a/tv_light/src/tv_light.ino b/tv_light/src/tv_light.ino new file mode 100644 index 0000000..492069d --- /dev/null +++ b/tv_light/src/tv_light.ino @@ -0,0 +1,339 @@ +/** + * The MySensors Arduino library handles the wireless radio link and protocol + * between your home built sensors/actuators and HA controller of choice. + * The sensors forms a self healing radio network with optional repeaters. Each + * repeater and gateway builds a routing tables in EEPROM which keeps track of the + * network topology allowing messages to be routed to nodes. + */ + +// Enable debug prints to serial monitor +//#define MY_DEBUG + +// configure radio +#define MY_RADIO_RFM69 + +/** @brief RFM69 frequency to use (RF69_433MHZ for 433MHz, RF69_868MHZ for 868MHz or RF69_915MHZ for 915MHz). */ +#define MY_RFM69_FREQUENCY RF69_868MHZ + +/** @brief Enable this if you're running the RFM69HW model. */ +#define MY_IS_RFM69HW + +/** @brief RFM69 Network ID. Use the same for all nodes that will talk to each other. */ +#define MY_RFM69_NETWORKID 1 + +/** @brief Node id defaults to AUTO (tries to fetch id from controller). */ +#define MY_NODE_ID 2 + +/** @brief If set, transport traffic is unmonitored and GW connection is optional */ +#define MY_TRANSPORT_DONT_CARE_MODE + +/** @brief Node parent defaults to AUTO (tries to find a parent automatically). */ +#define MY_PARENT_NODE_ID 0 + +/** @brief The user-defined AES key to use for EEPROM personalization */ +#include "aes_key.h" + +// Enable repeater functionality for this node +//#define MY_REPEATER_FEATURE + +/** @brief Enables RFM69 automatic transmit power control class. */ +//#define MY_RFM69_ATC + +#ifdef MY_AES_KEY +/** @brief enables RFM69 encryption */ +#define MY_RFM69_ENABLE_ENCRYPTION +#endif + +#include +#include +#include + +enum sensor_type : uint8_t +{ + SENSOR_RELAY = (1u << 0), + SENSOR_DIMMER = (1u << 1), + SENSOR_BUTTON = (1u << 2), +}; + +struct sensor_t +{ + uint8_t id; + uint8_t type; + struct + { + uint8_t pin; // relay pin + } relay; + struct + { + uint8_t pin; // dimmer pin + uint16_t level; // current dim level (0 to 100) + } dimmer; +}; + +struct sensor_t sensors[] = { + { + .id = 0, + .type = SENSOR_RELAY, + .relay = { .pin = 4 }, + }, + { + .id = 1, + .type = SENSOR_RELAY | SENSOR_DIMMER, + //.type = SENSOR_RELAY, + .relay = { .pin = 5 }, + .dimmer = { .pin = 6, .level = 100 }, + }, +}; + +//#define SAVE_RESTORE + +#define NUM(a) (sizeof(a) / sizeof(*a)) + +#define RELAY_ON 1 // GPIO value to write to turn on attached relay +#define RELAY_OFF 0 // GPIO value to write to turn off attached relay + +#define DIMMER_FADE_DELAY 40 // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim) + +#define TEMP_SENSOR_ID 254 +#define TEMP_READ_INTERVAL 1000L // read temp every 1 sec +#define TEMP_N_READS_MSG 60*60 // force temp message every n reads +#define TEMP_OFFSET 0 + +MyMessage msg(0, V_STATUS); + +inline void checkTemperature(void); +bool relayRead(struct sensor_t *sensor); +void relayWrite(struct sensor_t *sensor, bool state, bool send_update=false); +void flipRelay(struct sensor_t *sensor, bool send_update=false); +inline uint8_t pwmValue(uint8_t level); +void fadeDimmer(struct sensor_t *sensor, uint8_t level, bool send_update=false); + +void before() +{ + // set relay pins to output mode + restore to last known state + for (uint8_t i = 0; i < NUM(sensors); i++) + { + struct sensor_t *sensor = &sensors[i]; + if (sensor->type & SENSOR_RELAY) + { + pinMode(sensor->relay.pin, OUTPUT); +#ifdef SAVE_RESTORE + digitalWrite(sensor->relay.pin, loadState(sensor->id) ? RELAY_ON : RELAY_OFF); +#else + digitalWrite(sensor->relay.pin, RELAY_OFF); +#endif + } + + if (sensor->type & SENSOR_DIMMER) + { + pinMode(sensor->dimmer.pin, OUTPUT); +#ifdef SAVE_RESTORE + uint8_t level = loadState(NUM(sensors) + sensor->id; +#else + uint8_t level = sensor->dimmer.level; +#endif + if ((sensor->type & SENSOR_RELAY) && !relayRead(sensor)) + level = 0; + analogWrite(sensor->dimmer.pin, pwmValue(level)); + } + } + +#ifdef MY_AES_KEY + const uint8_t user_aes_key[16] = { MY_AES_KEY }; + uint8_t cur_aes_key[16]; + hwReadConfigBlock((void*)&cur_aes_key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, sizeof(cur_aes_key)); + if (memcmp(&user_aes_key, &cur_aes_key, 16) != 0) + { + hwWriteConfigBlock((void*)user_aes_key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, sizeof(user_aes_key)); + debug(PSTR("AES key written\n")); + } +#endif +} + +void setup() +{ +#ifdef MY_IS_RFM69HW + _radio.setHighPower(true); +#endif +#ifdef MY_RFM69_ATC + _radio.enableAutoPower(-70); + debug(PSTR("ATC enabled\n")); +#endif +} + +void presentation() +{ + sendSketchInfo("TVLight", "1.0"); + + // register all sensors to gw (they will be created as child devices) + for (uint8_t i = 0; i < NUM(sensors); i++) + { + struct sensor_t *sensor = &sensors[i]; + if (sensor->type & SENSOR_DIMMER) + present(sensor->id, S_DIMMER); + else if (sensor->type & SENSOR_RELAY || sensor->type & SENSOR_BUTTON) + present(sensor->id, S_BINARY); + } + +#if TEMP_SENSOR_ID >= 0 + present(TEMP_SENSOR_ID, S_TEMP); +#endif +} + +void loop() +{ + //TODO maybe call _radio.rcCalibration() all 1000x changes? +#if TEMP_SENSOR_ID >= 0 + checkTemperature(); +#endif +} + +inline void checkTemperature(void) +{ + static unsigned long lastTempUpdate = millis(); + static unsigned int numTempUpdates = 0; + static float lastTemp = 0; + static MyMessage msgTemp(TEMP_SENSOR_ID, V_TEMP); + + unsigned long now = millis(); + if (now - lastTempUpdate > TEMP_READ_INTERVAL) + { + float temp = _radio.readTemperature() + TEMP_OFFSET; + lastTempUpdate = now; + if (isnan(temp)) + Serial.println(F("Failed reading temperature")); + else if (abs(temp - lastTemp) >= 2 || numTempUpdates == TEMP_N_READS_MSG) + { + lastTemp = temp; + numTempUpdates = 0; + send(msgTemp.set(temp, 2)); +#ifdef MY_DEBUG + char str_temp[6]; + dtostrf(temp, 4, 2, str_temp); + debug(PSTR("Temperature: %s °C\n"), str_temp); +#endif + } + else + ++numTempUpdates; + } +} + +void receive(const MyMessage &message) +{ + if (message.type == V_STATUS || message.type == V_PERCENTAGE) + { + uint8_t sensor_id = message.sensor; + if (sensor_id >= NUM(sensors)) + { + Serial.print(F("Invalid sensor id:")); + Serial.println(sensor_id); + return; + } + + struct sensor_t *sensor = &sensors[sensor_id]; + if (message.type == V_STATUS && sensor->type & SENSOR_RELAY) + { + if (mGetCommand(message) == C_REQ) + send(msg.setType(V_STATUS).setSensor(sensor->id).set(relayRead(sensor))); + else if (mGetCommand(message) == C_SET) + relayWrite(sensor, message.getBool()); + } + else if (message.type == V_PERCENTAGE && sensor->type & SENSOR_DIMMER) + { + if (mGetCommand(message) == C_REQ) + send(msg.setType(V_PERCENTAGE).setSensor(sensor->id).set(sensor->dimmer.level)); + else if (mGetCommand(message) == C_SET) + { + uint16_t level = message.getUInt(); + fadeDimmer(sensor, (level > 100) ? 100 : level); + } + } + } +} + +bool relayRead(struct sensor_t *sensor) +{ + if (sensor->type & SENSOR_RELAY) + return digitalRead(sensor->relay.pin) == RELAY_ON; + return false; +} + +void relayWrite(struct sensor_t *sensor, bool state, bool send_update) +{ + if (!(sensor->type & SENSOR_RELAY)) + return; + + Serial.print(F("Incoming change for relay: ")); + Serial.print(sensor->relay.pin); + Serial.print(F(", New state: ")); + Serial.println(state); + + digitalWrite(sensor->relay.pin, state ? RELAY_ON : RELAY_OFF); + + if (sensor->type & SENSOR_DIMMER) + analogWrite(sensor->dimmer.pin, state ? pwmValue(sensor->dimmer.level) : 0); + +#ifdef SAVE_RESTORE + saveState(sensor->id, state ? RELAY_ON : RELAY_OFF); +#endif + + if (send_update) + send(msg.setType(V_STATUS).setSensor(sensor->id).set(state)); +} + +void flipRelay(struct sensor_t *sensor, bool send_update) +{ + relayWrite(sensor, relayRead(sensor) ? RELAY_OFF : RELAY_ON, send_update); +} + +inline uint8_t pwmValue(uint8_t level) +{ + static const uint8_t pwmtable[101] PROGMEM = { + 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, + 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, + 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, + 9, 10, 11, 11, 12, 12, 13, 14, 15, 16, + 16, 17, 18, 19, 20, 22, 23, 24, 25, 27, + 28, 30, 32, 33, 35, 37, 39, 42, 44, 47, + 49, 52, 55, 58, 61, 65, 68, 72, 76, 81, + 85, 90, 95, 100, 106, 112, 118, 125, 132, 139, + 147, 156, 164, 174, 183, 194, 205, 216, 228, 241, + 255 + }; + return (uint8_t)pgm_read_byte(&pwmtable[level]); +} + +void fadeDimmer(struct sensor_t *sensor, uint8_t level, bool send_update) +{ + if (!(sensor->type & SENSOR_DIMMER)) + return; + if (level > 100) + level = 100; + + Serial.print(F("Incoming change for dimmer: ")); + Serial.print(sensor->dimmer.pin); + Serial.print(F(", New level: ")); + Serial.println(level); + + if (level > 0 && sensor->type & SENSOR_RELAY && !relayRead(sensor)) + relayWrite(sensor, RELAY_ON); + + int delta = ((int8_t)(level - sensor->dimmer.level) < 0) ? -1 : 1; + while (sensor->dimmer.level != level) + { + sensor->dimmer.level += delta; + analogWrite(sensor->dimmer.pin, pwmValue(sensor->dimmer.level)); + delay(DIMMER_FADE_DELAY); + } + + if (level == 0 && sensor->type & SENSOR_RELAY && relayRead(sensor)) + relayWrite(sensor, RELAY_OFF); + +#ifdef SAVE_RESTORE + saveState(NUM(sensors) + sensor->id, level); +#endif + + if (send_update) + send(msg.setType(V_PERCENTAGE).setSensor(sensor->id).set(level)); +} diff --git a/tv_light/tv_light.ino b/tv_light/tv_light.ino deleted file mode 100644 index 0e82fe3..0000000 --- a/tv_light/tv_light.ino +++ /dev/null @@ -1,340 +0,0 @@ -/** - * The MySensors Arduino library handles the wireless radio link and protocol - * between your home built sensors/actuators and HA controller of choice. - * The sensors forms a self healing radio network with optional repeaters. Each - * repeater and gateway builds a routing tables in EEPROM which keeps track of the - * network topology allowing messages to be routed to nodes. - */ - -// Enable debug prints to serial monitor -//#define MY_DEBUG - -// configure radio -#define MY_RADIO_RFM69 - -/** @brief RFM69 frequency to use (RF69_433MHZ for 433MHz, RF69_868MHZ for 868MHz or RF69_915MHZ for 915MHz). */ -#define MY_RFM69_FREQUENCY RF69_868MHZ - -/** @brief Enable this if you're running the RFM69HW model. */ -#define MY_IS_RFM69HW - -/** @brief RFM69 Network ID. Use the same for all nodes that will talk to each other. */ -#define MY_RFM69_NETWORKID 1 - -/** @brief Node id defaults to AUTO (tries to fetch id from controller). */ -#define MY_NODE_ID 2 - -/** @brief If set, transport traffic is unmonitored and GW connection is optional */ -#define MY_TRANSPORT_DONT_CARE_MODE - -/** @brief Node parent defaults to AUTO (tries to find a parent automatically). */ -#define MY_PARENT_NODE_ID 0 - -/** @brief The user-defined AES key to use for EEPROM personalization */ -#include "aes_key.h" - -// Enable repeater functionality for this node -//#define MY_REPEATER_FEATURE - -/** @brief Enables RFM69 automatic transmit power control class. */ -//#define MY_RFM69_ATC - -#ifdef MY_AES_KEY -/** @brief enables RFM69 encryption */ -#define MY_RFM69_ENABLE_ENCRYPTION -#endif - -#include -#include -#include - -enum sensor_type : uint8_t -{ - SENSOR_RELAY = (1u << 0), - SENSOR_DIMMER = (1u << 1), - SENSOR_BUTTON = (1u << 2), -}; - -struct sensor_t -{ - uint8_t id; - uint8_t type; - struct - { - uint8_t pin; // relay pin - } relay; - struct - { - uint8_t pin; // dimmer pin - uint16_t level; // current dim level (0 to 100) - } dimmer; -}; - -struct sensor_t sensors[] = { - { - .id = 0, - .type = SENSOR_RELAY, - .relay = { .pin = 4 }, - }, - { - .id = 1, - .type = SENSOR_RELAY | SENSOR_DIMMER, - //.type = SENSOR_RELAY, - .relay = { .pin = 5 }, - .dimmer = { .pin = 6, .level = 100 }, - }, -}; - -//#define SAVE_RESTORE - -#define NUM(a) (sizeof(a) / sizeof(*a)) - -#define RELAY_ON 1 // GPIO value to write to turn on attached relay -#define RELAY_OFF 0 // GPIO value to write to turn off attached relay - -#define DIMMER_FADE_DELAY 40 // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim) - -#define TEMP_SENSOR_ID 254 -#define TEMP_READ_INTERVAL 1000L // read temp every 1 sec -#define TEMP_N_READS_MSG 60*60 // force temp message every n reads -#define TEMP_OFFSET 0 - -MyMessage msg(0, V_STATUS); - -inline void checkTemperature(void); -bool relayRead(struct sensor_t *sensor); -void relayWrite(struct sensor_t *sensor, bool state, bool send_update=false); -void flipRelay(struct sensor_t *sensor, bool send_update=false); -inline uint8_t pwmValue(uint8_t level); -void fadeDimmer(struct sensor_t *sensor, uint8_t level, bool send_update=false); - -void before() -{ - // set relay pins to output mode + restore to last known state - for (uint8_t i = 0; i < NUM(sensors); i++) - { - struct sensor_t *sensor = &sensors[i]; - if (sensor->type & SENSOR_RELAY) - { - pinMode(sensor->relay.pin, OUTPUT); -#ifdef SAVE_RESTORE - digitalWrite(sensor->relay.pin, loadState(sensor->id) ? RELAY_ON : RELAY_OFF); -#else - digitalWrite(sensor->relay.pin, RELAY_OFF); -#endif - } - - if (sensor->type & SENSOR_DIMMER) - { - pinMode(sensor->dimmer.pin, OUTPUT); -#ifdef SAVE_RESTORE - uint8_t level = loadState(NUM(sensors) + sensor->id; -#else - uint8_t level = sensor->dimmer.level; -#endif - if ((sensor->type & SENSOR_RELAY) && !relayRead(sensor)) - level = 0; - analogWrite(sensor->dimmer.pin, pwmValue(level)); - } - } - -#ifdef MY_AES_KEY - const uint8_t user_aes_key[16] = { MY_AES_KEY }; - uint8_t cur_aes_key[16]; - hwReadConfigBlock((void*)&cur_aes_key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, sizeof(cur_aes_key)); - if (memcmp(&user_aes_key, &cur_aes_key, 16) != 0) - { - hwWriteConfigBlock((void*)user_aes_key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, sizeof(user_aes_key)); - debug(PSTR("AES key written\n")); - } -#endif -} - -void setup() -{ -#ifdef MY_IS_RFM69HW - _radio.setHighPower(true); -#endif -#ifdef MY_RFM69_ATC - _radio.enableAutoPower(-70); - debug(PSTR("ATC enabled\n")); -#endif -} - -void presentation() -{ - sendSketchInfo("TVLight", "1.0"); - - // register all sensors to gw (they will be created as child devices) - for (uint8_t i = 0; i < NUM(sensors); i++) - { - struct sensor_t *sensor = &sensors[i]; - if (sensor->type & SENSOR_DIMMER) - present(sensor->id, S_DIMMER); - else if (sensor->type & SENSOR_RELAY || sensor->type & SENSOR_BUTTON) - present(sensor->id, S_BINARY); - } - -#if TEMP_SENSOR_ID >= 0 - present(TEMP_SENSOR_ID, S_TEMP); -#endif -} - -void loop() -{ - //TODO maybe call _radio.rcCalibration() all 1000x changes? -#if TEMP_SENSOR_ID >= 0 - checkTemperature(); -#endif -} - -inline void checkTemperature(void) -{ - static unsigned long lastTempUpdate = millis(); - static unsigned int numTempUpdates = 0; - static float lastTemp = 0; - static MyMessage msgTemp(TEMP_SENSOR_ID, V_TEMP); - - unsigned long now = millis(); - if (now - lastTempUpdate > TEMP_READ_INTERVAL) - { - float temp = _radio.readTemperature() + TEMP_OFFSET; - lastTempUpdate = now; - if (isnan(temp)) - Serial.println(F("Failed reading temperature")); - else if (abs(temp - lastTemp) >= 2 || numTempUpdates == TEMP_N_READS_MSG) - { - lastTemp = temp; - numTempUpdates = 0; - send(msgTemp.set(temp, 2)); -#ifdef MY_DEBUG - char str_temp[6]; - dtostrf(temp, 4, 2, str_temp); - debug(PSTR("Temperature: %s °C\n"), str_temp); -#endif - } - else - ++numTempUpdates; - } -} - -void receive(const MyMessage &message) -{ - if (message.type == V_STATUS || message.type == V_PERCENTAGE) - { - uint8_t sensor_id = message.sensor; - if (sensor_id >= NUM(sensors)) - { - Serial.print(F("Invalid sensor id:")); - Serial.println(sensor_id); - return; - } - - struct sensor_t *sensor = &sensors[sensor_id]; - if (message.type == V_STATUS && sensor->type & SENSOR_RELAY) - { - if (mGetCommand(message) == C_REQ) - send(msg.setType(V_STATUS).setSensor(sensor->id).set(relayRead(sensor))); - else if (mGetCommand(message) == C_SET) - relayWrite(sensor, message.getBool()); - } - else if (message.type == V_PERCENTAGE && sensor->type & SENSOR_DIMMER) - { - if (mGetCommand(message) == C_REQ) - send(msg.setType(V_PERCENTAGE).setSensor(sensor->id).set(sensor->dimmer.level)); - else if (mGetCommand(message) == C_SET) - { - uint16_t level = message.getUInt(); - fadeDimmer(sensor, (level > 100) ? 100 : level); - } - } - } -} - -bool relayRead(struct sensor_t *sensor) -{ - if (sensor->type & SENSOR_RELAY) - return digitalRead(sensor->relay.pin) == RELAY_ON; - return false; -} - -void relayWrite(struct sensor_t *sensor, bool state, bool send_update) -{ - if (!(sensor->type & SENSOR_RELAY)) - return; - - Serial.print(F("Incoming change for relay: ")); - Serial.print(sensor->relay.pin); - Serial.print(F(", New state: ")); - Serial.println(state); - - digitalWrite(sensor->relay.pin, state ? RELAY_ON : RELAY_OFF); - - if (sensor->type & SENSOR_DIMMER) - analogWrite(sensor->dimmer.pin, state ? pwmValue(sensor->dimmer.level) : 0); - -#ifdef SAVE_RESTORE - saveState(sensor->id, state ? RELAY_ON : RELAY_OFF); -#endif - - if (send_update) - send(msg.setType(V_STATUS).setSensor(sensor->id).set(state)); -} - -void flipRelay(struct sensor_t *sensor, bool send_update) -{ - relayWrite(sensor, relayRead(sensor) ? RELAY_OFF : RELAY_ON, send_update); -} - -inline uint8_t pwmValue(uint8_t level) -{ - static const uint8_t pwmtable[101] PROGMEM = { - 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, - 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, - 5, 6, 6, 6, 7, 7, 8, 8, 8, 9, - 9, 10, 11, 11, 12, 12, 13, 14, 15, 16, - 16, 17, 18, 19, 20, 22, 23, 24, 25, 27, - 28, 30, 32, 33, 35, 37, 39, 42, 44, 47, - 49, 52, 55, 58, 61, 65, 68, 72, 76, 81, - 85, 90, 95, 100, 106, 112, 118, 125, 132, 139, - 147, 156, 164, 174, 183, 194, 205, 216, 228, 241, - 255 - }; - return (uint8_t)pgm_read_byte(&pwmtable[level]); -} - -void fadeDimmer(struct sensor_t *sensor, uint8_t level, bool send_update) -{ - if (!(sensor->type & SENSOR_DIMMER)) - return; - if (level > 100) - level = 100; - - Serial.print(F("Incoming change for dimmer: ")); - Serial.print(sensor->dimmer.pin); - Serial.print(F(", New level: ")); - Serial.println(level); - - if (level > 0 && sensor->type & SENSOR_RELAY && !relayRead(sensor)) - relayWrite(sensor, RELAY_ON); - - int delta = ((int8_t)(level - sensor->dimmer.level) < 0) ? -1 : 1; - while (sensor->dimmer.level != level) - { - sensor->dimmer.level += delta; - analogWrite(sensor->dimmer.pin, pwmValue(sensor->dimmer.level)); - delay(DIMMER_FADE_DELAY); - } - - if (level == 0 && sensor->type & SENSOR_RELAY && relayRead(sensor)) - relayWrite(sensor, RELAY_OFF); - -#ifdef SAVE_RESTORE - saveState(NUM(sensors) + sensor->id, level); -#endif - - if (send_update) - send(msg.setType(V_PERCENTAGE).setSensor(sensor->id).set(level)); -} - -- cgit v1.2.3