From f0ecb4d38fff522c72905a8551355ca925381fa3 Mon Sep 17 00:00:00 2001 From: manuel Date: Tue, 17 Mar 2020 12:00:59 +0100 Subject: platform io cleanup --- lr_switch/src/main.cpp | 197 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 lr_switch/src/main.cpp (limited to 'lr_switch/src/main.cpp') diff --git a/lr_switch/src/main.cpp b/lr_switch/src/main.cpp new file mode 100644 index 0000000..673eb3a --- /dev/null +++ b/lr_switch/src/main.cpp @@ -0,0 +1,197 @@ +/** + * 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 3 + +/** @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 + +enum sensor_type : uint8_t +{ + SENSOR_RELAY = (1u << 0), + SENSOR_DIMMER = (1u << 1), + SENSOR_BUTTON = (1u << 2), + SENSOR_SCENE = (1u << 3), +}; + +struct sensor_t +{ + uint8_t id; + uint8_t type; + struct + { + uint8_t pin; // push button pin + } button; +}; + +struct sensor_t sensors[] = { + { + .id = 0, + .type = SENSOR_BUTTON | SENSOR_SCENE, + .button = { .pin = 3 }, + }, +}; + +#define NUM(a) (sizeof(a) / sizeof(*a)) + +#define TEMP_SENSOR_ID -1 +#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_SCENE_ON); + +inline void checkTemperature(void); +void wakeUp(void); + +void before() +{ +#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 + //_radio.setPowerLevel(10); +#ifdef MY_RFM69_ATC + _radio.enableAutoPower(-70); + debug(PSTR("ATC enabled\n")); +#endif + + for (uint8_t i = 0; i < NUM(sensors); i++) + { + struct sensor_t *sensor = &sensors[i]; + if (sensor->type & SENSOR_BUTTON) + pinMode(sensor->button.pin, INPUT_PULLUP); + } +} + +void presentation() +{ + sendSketchInfo("LRSwitch", "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_SCENE) + present(sensor->id, S_SCENE_CONTROLLER); + } + +#if TEMP_SENSOR_ID >= 0 + present(TEMP_SENSOR_ID, S_TEMP); +#endif +} + +void loop() +{ + //TODO maybe call _radio.rcCalibration() all 1000x changes? + + struct sensor_t *sensor = &sensors[0]; + uint8_t pin = sensor->button.pin; + + // delay() instead of sleep() + // sleep() will for whatever reason trigger the external interrupt?! + delay(1000); + + Serial.println("r"); + Serial.flush(); + uint8_t state_before = digitalRead(pin); + int8_t intr = sleep(digitalPinToInterrupt(pin), CHANGE, 0); + if (intr == digitalPinToInterrupt(pin)) + { + uint8_t state_now = digitalRead(pin); + if (state_before != state_now) + { + Serial.println("m"); + send(msg.setType(V_SCENE_ON).setSensor(sensor->id).set(1)); + } + } + +#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; + } +} + -- cgit v1.2.3