diff --git a/.cproject b/.cproject index 2887129..47b073f 100644 --- a/.cproject +++ b/.cproject @@ -27,6 +27,8 @@ + + @@ -40,6 +42,8 @@ + + @@ -52,7 +56,8 @@ - + + @@ -73,4 +78,5 @@ + diff --git a/.settings/org.eclipse.cdt.core.prefs b/.settings/org.eclipse.cdt.core.prefs index a9033e0..a76e004 100644 --- a/.settings/org.eclipse.cdt.core.prefs +++ b/.settings/org.eclipse.cdt.core.prefs @@ -151,10 +151,10 @@ environment/project/it.baeyens.arduino.core.toolChain.release.723484165/A.EXTRA. environment/project/it.baeyens.arduino.core.toolChain.release.723484165/A.EXTRA.TIME.DTS/value=3600 environment/project/it.baeyens.arduino.core.toolChain.release.723484165/A.EXTRA.TIME.LOCAL/delimiter=\: environment/project/it.baeyens.arduino.core.toolChain.release.723484165/A.EXTRA.TIME.LOCAL/operation=replace -environment/project/it.baeyens.arduino.core.toolChain.release.723484165/A.EXTRA.TIME.LOCAL/value=1432722899 +environment/project/it.baeyens.arduino.core.toolChain.release.723484165/A.EXTRA.TIME.LOCAL/value=1433083040 environment/project/it.baeyens.arduino.core.toolChain.release.723484165/A.EXTRA.TIME.UTC/delimiter=\: environment/project/it.baeyens.arduino.core.toolChain.release.723484165/A.EXTRA.TIME.UTC/operation=replace -environment/project/it.baeyens.arduino.core.toolChain.release.723484165/A.EXTRA.TIME.UTC/value=1432715699 +environment/project/it.baeyens.arduino.core.toolChain.release.723484165/A.EXTRA.TIME.UTC/value=1433075840 environment/project/it.baeyens.arduino.core.toolChain.release.723484165/A.EXTRA.TIME.ZONE/delimiter=\: environment/project/it.baeyens.arduino.core.toolChain.release.723484165/A.EXTRA.TIME.ZONE/operation=replace environment/project/it.baeyens.arduino.core.toolChain.release.723484165/A.EXTRA.TIME.ZONE/value=3600 diff --git a/EEPROM/EEPROM.cpp b/EEPROM/EEPROM.cpp new file mode 100644 index 0000000..dfa1deb --- /dev/null +++ b/EEPROM/EEPROM.cpp @@ -0,0 +1,50 @@ +/* + EEPROM.cpp - EEPROM library + Copyright (c) 2006 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/****************************************************************************** + * Includes + ******************************************************************************/ + +#include +#include "Arduino.h" +#include "EEPROM.h" + +/****************************************************************************** + * Definitions + ******************************************************************************/ + +/****************************************************************************** + * Constructors + ******************************************************************************/ + +/****************************************************************************** + * User API + ******************************************************************************/ + +uint8_t EEPROMClass::read(int address) +{ + return eeprom_read_byte((unsigned char *) address); +} + +void EEPROMClass::write(int address, uint8_t value) +{ + eeprom_write_byte((unsigned char *) address, value); +} + +EEPROMClass EEPROM; diff --git a/EEPROM/EEPROM.h b/EEPROM/EEPROM.h new file mode 100644 index 0000000..aa2b577 --- /dev/null +++ b/EEPROM/EEPROM.h @@ -0,0 +1,35 @@ +/* + EEPROM.h - EEPROM library + Copyright (c) 2006 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef EEPROM_h +#define EEPROM_h + +#include + +class EEPROMClass +{ + public: + uint8_t read(int); + void write(int, uint8_t); +}; + +extern EEPROMClass EEPROM; + +#endif + diff --git a/RelayBox.cpp b/RelayBox.cpp index d948964..3fa50e4 100644 --- a/RelayBox.cpp +++ b/RelayBox.cpp @@ -7,6 +7,7 @@ #include #include #include +#include "config.h" @@ -64,18 +65,41 @@ void callback(char* topic, byte* payload, unsigned int length) { (indexStr != 0) && (*indexStr != 0) && (stateStr != 0) && (*stateStr != 0)) { String command = String(commandStr); - int index = atoi(indexStr); + int index = 99; + if (! strcmp(indexStr, "all")) { + index = -1; + } else { + index = atoi(indexStr); + } String state = String(stateStr); bool validCommand = command.equals("switch"); - bool validIndex = ! ((index < 0) || (index >= NUM_OF_LINES)); + bool validIndex = (! ((index < 0) || (index >= NUM_OF_LINES))) || (index == -1); if (validCommand && validIndex) { if (state.equalsIgnoreCase("on")) { - switches[index].on(); + if (index == -1) { + for (uint8_t i = 0; i < NUM_OF_LINES; i++) { + switches[i].on(); + } + } else { + switches[index].on(); + } } else if (state.equalsIgnoreCase("off")) { - switches[index].off(); + if (index == -1) { + for (uint8_t i = 0; i < NUM_OF_LINES; i++) { + switches[i].off(); + } + } else { + switches[index].off(); + } } else if (state.equalsIgnoreCase("toggle")) { - switches[index].toggle(); + if (index == -1) { + for (uint8_t i = 0; i < NUM_OF_LINES; i++) { + switches[i].toggle(); + } + } else { + switches[index].toggle(); + } } else { Serial << "Invalid state " << state << endl; } @@ -96,9 +120,11 @@ void callback(char* topic, byte* payload, unsigned int length) { void setup() { Serial.begin(9600); - + // delay(5000); Serial << "Starting ... " << endl; + configInit(); + Ethernet.begin(mac); Serial << "Got IP address: " << Ethernet.localIP() << endl; @@ -109,7 +135,7 @@ void setup() { for (uint8_t i = 0; i < NUM_OF_LINES; i++) { - switches[i].begin(FEEDBACK_PIN[i], BUTTON_PIN[i], RELAY_PIN[i], LED_PIN[i]); + switches[i].begin(FEEDBACK_PIN[i], BUTTON_PIN[i], RELAY_PIN[i], LED_PIN[i], i); } wdt_enable(WDTO_8S); @@ -171,7 +197,7 @@ void loop() { if (second.check() == 1) { uptime++; - Serial.println("tick"); + // Serial.println("tick"); if (disconnectState == 0) { String msg = String("{ \"metadata\": { \"device\": \"RelayBox\" }, \"data\": { \"uptime\": ") + uptime + String("}}"); @@ -191,6 +217,10 @@ void loop() { "\"state\": " << switches[i].getState() << ", " << "\"feedbackState\": " << switches[i].getFeedback() << ", " << "\"stateConflict\": " << switches[i].getStateConflict() << " }"; + if (switches[i].getStateConflict()) { + Serial << "State conflict on channel " << i << ", should be " << switches[i].getState() << + ", is " << switches[i].getFeedback() << endl; + } } buf << "], " << "\"uptime\": " << uptime << diff --git a/config.cpp b/config.cpp new file mode 100644 index 0000000..72976fb --- /dev/null +++ b/config.cpp @@ -0,0 +1,52 @@ +/* + * config.cpp + * + * Created on: 11.05.2015 + * Author: wn + */ + +#include +#include +#include "config.h" + +static bool __configIsValid = false; +const uint32_t CONFIG_MAGIC_TOKEN = 0xAffe0002; + + +void configInit() { + uint32_t magic; + configRead(CONFIG_MAGIC, 4, (char*)&magic); + __configIsValid = (magic != CONFIG_MAGIC_TOKEN); + + if (! __configIsValid) { + Serial << "Initialize config" << endl; + uint32_t setMagic = CONFIG_MAGIC_TOKEN; + configWrite(CONFIG_MAGIC, 4, (char*)&setMagic); + } else { + Serial << "Config valid" << endl; + } +} + +bool configIsValid() { + return __configIsValid; +} + +void configReset() { + Serial << "Reset config" << endl; + uint32_t setMagic = 0xa5a5a5a5; + configWrite(CONFIG_MAGIC, 4, (char*)&setMagic); +} + +void configRead(int addr, uint8_t len, char *buffer) { + for (uint8_t i = 0; i < len; i++) { + *(buffer + i) = EEPROM.read(addr + i); + // Serial << "Read " << _HEX(*(buffer + i)) << " from " << addr + i << endl; + } +} + +void configWrite(int addr, uint8_t len, char *buffer) { + for (uint8_t i = 0; i < len; i++) { + // Serial << "Write " << _HEX(*(buffer + i)) << " to " << addr + i << endl; + EEPROM.write(addr + i, *(buffer + i)); + } +} diff --git a/config.h b/config.h new file mode 100644 index 0000000..7579889 --- /dev/null +++ b/config.h @@ -0,0 +1,25 @@ +/* + * config.h + * + * Created on: 11.05.2015 + * Author: wn + */ + +#ifndef CONFIG_H_ +#define CONFIG_H_ + + +void configInit(); +bool configIsValid(); +void configReset(); + +void configRead(int addr, uint8_t len, char *buffer); +void configWrite(int addr, uint8_t len, char *buffer); + + + +#define CONFIG_MAGIC 0 // 4 +#define CONFIG_STATES_BEGIN 4 + + +#endif /* CONFIG_H_ */ diff --git a/hardware.cpp b/hardware.cpp index 8fb1c9c..b9d83e8 100644 --- a/hardware.cpp +++ b/hardware.cpp @@ -8,26 +8,41 @@ #include #include "hardware.h" #include +#include "config.h" Switch::Switch() : m_state(false), m_feedbackState(false), m_stateConflict(false), m_lastButtonState(false), m_buttonEngineState(0), m_buttonTimestamp(0), - m_ledEngineState(0), m_ledState(false), m_ledTimestamp(0) + m_ledEngineState(0), m_ledState(false), m_ledTimestamp(0), + m_index(0) { } -void Switch::begin(const uint8_t feedbackPin, const uint8_t buttonPin, const uint8_t relayPin, const uint8_t ledPin) { +void Switch::begin(const uint8_t feedbackPin, const uint8_t buttonPin, const uint8_t relayPin, const uint8_t ledPin, + uint8_t index) { m_feedbackPin = feedbackPin; m_buttonPin = buttonPin; m_relayPin = relayPin; m_ledPin = ledPin; + m_index = index; + + if (! configIsValid()) { + Serial << "Initializing config" << endl; + bool initValue = false; + configWrite(CONFIG_STATES_BEGIN + m_index, 1, (char*)&initValue); + } + pinMode(m_feedbackPin, INPUT_PULLUP); pinMode(m_buttonPin, INPUT_PULLUP); pinMode(m_relayPin, OUTPUT); + digitalWrite(m_relayPin, true); pinMode(m_ledPin, OUTPUT); + + configRead(CONFIG_STATES_BEGIN + m_index, 1, (char*)&m_state); + action(); } void Switch::toggle() { @@ -46,7 +61,8 @@ void Switch::off() { } void Switch::action() { - digitalWrite(m_relayPin, m_state); + configWrite(CONFIG_STATES_BEGIN + m_index, 1, (char*)&m_state); + digitalWrite(m_relayPin, ! m_state); } void Switch::exec() { diff --git a/hardware.h b/hardware.h index 3b57dcc..2082802 100644 --- a/hardware.h +++ b/hardware.h @@ -9,12 +9,12 @@ #define HARDWARE_H_ -const uint8_t NUM_OF_LINES = 4; +const uint8_t NUM_OF_LINES = 8; -const uint8_t FEEDBACK_PIN[NUM_OF_LINES] = { 22, 23, 24, 25 }; -const uint8_t BUTTON_PIN[NUM_OF_LINES] = { 30, 31, 32, 33 }; -const uint8_t RELAY_PIN[NUM_OF_LINES] = { 38, 39, 40, 41 }; -const uint8_t LED_PIN[NUM_OF_LINES] = { 46, 47, 48, 49 }; +const uint8_t FEEDBACK_PIN[NUM_OF_LINES] = { 22, 23, 24, 25, 26, 27, 28, 29 }; +const uint8_t BUTTON_PIN[NUM_OF_LINES] = { 30, 31, 32, 33, 34, 35, 36, 37 }; +const uint8_t RELAY_PIN[NUM_OF_LINES] = { 38, 39, 40, 42, 41, 44, 43, 45 }; +const uint8_t LED_PIN[NUM_OF_LINES] = { 46, 47, 48, 49, 50, 51, 52, 53 }; const uint32_t BUTTON_TIME = 1000; const uint32_t BUTTON_COOL_TIME = 5000; @@ -23,7 +23,7 @@ const uint32_t BLINK_TIME = 100; class Switch { public: Switch(); - void begin(const uint8_t feedbackPin, const uint8_t buttonPin, const uint8_t relayPin, const uint8_t ledPin); + void begin(const uint8_t feedbackPin, const uint8_t buttonPin, const uint8_t relayPin, const uint8_t ledPin, uint8_t index); void exec(); void toggle(); void on(); @@ -49,6 +49,8 @@ private: bool m_ledState; uint32_t m_ledTimestamp; + uint8_t m_index; +