diff --git a/lib/Multi_Channel_Relay_Arduino_Library/.gitlab-ci.yml b/lib/Multi_Channel_Relay_Arduino_Library/.gitlab-ci.yml new file mode 100644 index 000000000..5e2b6aa0c --- /dev/null +++ b/lib/Multi_Channel_Relay_Arduino_Library/.gitlab-ci.yml @@ -0,0 +1,8 @@ +build: + tags: + - nas + script: + - wget -c https://files.seeedstudio.com/arduino/seeed-arduino-ci.sh + - chmod +x seeed-arduino-ci.sh + - bash $PWD/seeed-arduino-ci.sh test + diff --git a/lib/Multi_Channel_Relay_Arduino_Library/.travis.yml b/lib/Multi_Channel_Relay_Arduino_Library/.travis.yml new file mode 100644 index 000000000..202d2e079 --- /dev/null +++ b/lib/Multi_Channel_Relay_Arduino_Library/.travis.yml @@ -0,0 +1,21 @@ + +language: generic +dist: bionic +sudo: false +cache: + directories: + - ~/arduino_ide + - ~/.arduino15/packages/ + +before_install: + - wget -c https://files.seeedstudio.com/arduino/seeed-arduino-ci.sh + +script: + - chmod +x seeed-arduino-ci.sh + - cat $PWD/seeed-arduino-ci.sh + - bash $PWD/seeed-arduino-ci.sh test + +notifications: + email: + on_success: change + on_failure: change diff --git a/lib/Multi_Channel_Relay_Arduino_Library/LICENSE b/lib/Multi_Channel_Relay_Arduino_Library/LICENSE new file mode 100644 index 000000000..c78cc0bf3 --- /dev/null +++ b/lib/Multi_Channel_Relay_Arduino_Library/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Seeed Studio + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/lib/Multi_Channel_Relay_Arduino_Library/README.md b/lib/Multi_Channel_Relay_Arduino_Library/README.md new file mode 100644 index 000000000..f04230ae9 --- /dev/null +++ b/lib/Multi_Channel_Relay_Arduino_Library/README.md @@ -0,0 +1,84 @@ +# Multi_Channel_Relay_Arduino_Library [![Build Status](https://travis-ci.com/Seeed-Studio/Multi_Channel_Relay_Arduino_Library.svg?branch=master)](https://travis-ci.com/Seeed-Studio/Multi_Channel_Relay_Arduino_Library) +This is the Arduino library for Seeed multi channel relay. + + + + + + + +### How to use this library +you can download from Arduino Library Manager or directlly download from this repository. +Connect the 8-channel Solid state relay v1.0 to Arduino board's I2C port, compile and upload four_channel_relay_control.ino. Open the serial monitor the relay should go as expected some massage should show as below: + +``` +Channel 1 on +Channel 2 on +Channel 3 on +Channel 4 on +Turn all channels on, State: 1111 +Turn 1 3 channels on, State: 101 +Turn 2 4 channels on, State: 1010 +Turn off all channels, State: 0 +``` + +- Upload eight_channel_relay_control.ino, open the serial monitor and show the below logs: + +``` +Channel 1 on +Channel 2 on +Channel 3 on +Channel 4 on +Channel 5 on +Channel 6 on +Channel 7 on +Channel 8 on +Turn all channels on, State: 11111111 +Turn 1 3 5 7 channels on, State: 1010101 +Turn 2 4 6 8 channels on, State: 10101010 +Turn off all channels, State: 0 + +``` + +- This module can be set I2C address by software, open change_i2c_address.ino modify new_i2c_address as you want; compile and upload the sketch, open the serial monitor and show the below logs: + +``` +Scanning... +I2C device found at address 0x11 ! +Found 1 devices +Address 0x21 has been saved to flash. +``` + +- Read firmware version of the module by example read_firmware_version.ino. Serial logs as below: + +``` +firmware version: 0x1 +``` + +### Functionalities +- The relay board is an I2C device, device address is changeable, refer to **changeI2CAddress(uint8_t new_addr, uint8_t old_addr)** . +- Use **getChannelState()** to know the state of every channel. +- Use **getFirmwareVersion()** to recognize firmware burn in the on board MCU. +- Use **channelCtrl(uint8_t state)** to change all channel immediately, the **state** parameter represents channel 1 to 8. +- Use **turn_on_channel(uint8_t channel)** to turn on single channel. +- Use **turn_off_channel(uint8_t channel)** to turn off single channel. +- External functionality **scanI2CDevice()**, use for scan device address. + + + + +---- +This software is written by lambor for seeed studio and is licensed under The MIT License.
+ +Contributing to this software is warmly welcomed. You can do this basically by
+[forking](https://help.github.com/articles/fork-a-repo), committing modifications and then [pulling requests](https://help.github.com/articles/using-pull-requests) (follow the links above
+for operating guide). Adding change log and your contact into file header is encouraged.
+Thanks for your contribution. + +Seeed is a hardware innovation platform for makers to grow inspirations into differentiating products. By working closely with technology providers of all scale, Seeed provides accessible technologies with quality, speed and supply chain knowledge. When prototypes are ready to iterate, Seeed helps productize 1 to 1,000 pcs using in-house engineering, supply chain management and agile manufacture forces. Seeed also team up with incubators, Chinese tech ecosystem, investors and distribution channels to portal Maker startups beyond. + + +[1]:http://wiki.seeedstudio.com/Grove-OLED_Display_0.96inch/ + + + diff --git a/lib/Multi_Channel_Relay_Arduino_Library/examples/change_i2c_address/change_i2c_address.ino b/lib/Multi_Channel_Relay_Arduino_Library/examples/change_i2c_address/change_i2c_address.ino new file mode 100644 index 000000000..8c41134ca --- /dev/null +++ b/lib/Multi_Channel_Relay_Arduino_Library/examples/change_i2c_address/change_i2c_address.ino @@ -0,0 +1,45 @@ +/** + When running this sketch please make sure there is only one + Multi Channel Relay module connected to your board, otherwise + it may not work to change module address, or cause other + unpredictable issue. + + +*/ + +#include + + +int new_i2c_address = 0x21; + +Multi_Channel_Relay relay; + +void setup() { + uint8_t old_address = 0; + uint8_t retry = 0; + + DEBUG_PRINT.begin(9600); + while (!DEBUG_PRINT); + + // // Set I2C address by default and start relay + relay.begin(); + + /* Scan I2C device detect device address */ + while ((retry++ < 10) && (old_address == 0x00)) { + old_address = relay.scanI2CDevice(); + delay(100); + } + + if ((0x00 == old_address) || (0xff == old_address)) { + while (1); + } + + relay.changeI2CAddress(old_address, new_i2c_address); /* Set I2C address and save to Flash */ + DEBUG_PRINT.print("Address 0x"); + DEBUG_PRINT.print(new_i2c_address, HEX); + DEBUG_PRINT.println(" has been saved to flash."); +} + +void loop() { + +} diff --git a/lib/Multi_Channel_Relay_Arduino_Library/examples/eight_channel_relay_control/eight_channel_relay_control.ino b/lib/Multi_Channel_Relay_Arduino_Library/examples/eight_channel_relay_control/eight_channel_relay_control.ino new file mode 100644 index 000000000..d7f91ab5c --- /dev/null +++ b/lib/Multi_Channel_Relay_Arduino_Library/examples/eight_channel_relay_control/eight_channel_relay_control.ino @@ -0,0 +1,95 @@ +#include + +/** + channle: 8 7 6 5 4 3 2 1 + state: 0b00000000 -> 0x00 (all off) + state: 0b11111111 -> 0xff (all on) +*/ + +Multi_Channel_Relay relay; + +void setup() { + + DEBUG_PRINT.begin(9600); + while (!DEBUG_PRINT); + + // Set I2C address and start relay + relay.begin(0x11); + + /* Begin Controlling Relay */ + DEBUG_PRINT.println("Channel 1 on"); + relay.turn_on_channel(1); + delay(500); + DEBUG_PRINT.println("Channel 2 on"); + relay.turn_off_channel(1); + relay.turn_on_channel(2); + delay(500); + DEBUG_PRINT.println("Channel 3 on"); + relay.turn_off_channel(2); + relay.turn_on_channel(3); + delay(500); + DEBUG_PRINT.println("Channel 4 on"); + relay.turn_off_channel(3); + relay.turn_on_channel(4); + delay(500); + DEBUG_PRINT.println("Channel 5 on"); + relay.turn_off_channel(4); + relay.turn_on_channel(5); + delay(500); + DEBUG_PRINT.println("Channel 6 on"); + relay.turn_off_channel(5); + relay.turn_on_channel(6); + delay(500); + DEBUG_PRINT.println("Channel 7 on"); + relay.turn_off_channel(6); + relay.turn_on_channel(7); + delay(500); + DEBUG_PRINT.println("Channel 8 on"); + relay.turn_off_channel(7); + relay.turn_on_channel(8); + delay(500); + relay.turn_off_channel(8); + + relay.channelCtrl(CHANNLE1_BIT | + CHANNLE2_BIT | + CHANNLE3_BIT | + CHANNLE4_BIT | + CHANNLE5_BIT | + CHANNLE6_BIT | + CHANNLE7_BIT | + CHANNLE8_BIT); + DEBUG_PRINT.print("Turn all channels on, State: "); + DEBUG_PRINT.println(relay.getChannelState(), BIN); + + delay(2000); + + relay.channelCtrl(CHANNLE1_BIT | + CHANNLE3_BIT | + CHANNLE5_BIT | + CHANNLE7_BIT); + DEBUG_PRINT.print("Turn 1 3 5 7 channels on, State: "); + DEBUG_PRINT.println(relay.getChannelState(), BIN); + + delay(2000); + + relay.channelCtrl(CHANNLE2_BIT | + CHANNLE4_BIT | + CHANNLE6_BIT | + CHANNLE8_BIT); + DEBUG_PRINT.print("Turn 2 4 6 8 channels on, State: "); + DEBUG_PRINT.println(relay.getChannelState(), BIN); + + delay(2000); + + + relay.channelCtrl(0); + DEBUG_PRINT.print("Turn off all channels, State: "); + DEBUG_PRINT.println(relay.getChannelState(), BIN); + + delay(2000); +} + +void loop() { + + +} diff --git a/lib/Multi_Channel_Relay_Arduino_Library/examples/four_channel_relay_control/four_channel_relay_control.ino b/lib/Multi_Channel_Relay_Arduino_Library/examples/four_channel_relay_control/four_channel_relay_control.ino new file mode 100644 index 000000000..7c6b5c052 --- /dev/null +++ b/lib/Multi_Channel_Relay_Arduino_Library/examples/four_channel_relay_control/four_channel_relay_control.ino @@ -0,0 +1,70 @@ +#include + +/** + channle: 4 3 2 1 + state: 0b0000 -> 0x00 (all off) + state: 0b1111 -> 0x0f (all on) +*/ + +Multi_Channel_Relay relay; + +void setup() { + DEBUG_PRINT.begin(9600); + while (!DEBUG_PRINT); + + // Set I2C address and start relay + relay.begin(0x11); + + /* Begin Controlling Relay */ + DEBUG_PRINT.println("Channel 1 on"); + relay.turn_on_channel(1); + delay(500); + DEBUG_PRINT.println("Channel 2 on"); + relay.turn_off_channel(1); + relay.turn_on_channel(2); + delay(500); + DEBUG_PRINT.println("Channel 3 on"); + relay.turn_off_channel(2); + relay.turn_on_channel(3); + delay(500); + DEBUG_PRINT.println("Channel 4 on"); + relay.turn_off_channel(3); + relay.turn_on_channel(4); + delay(500); + relay.turn_off_channel(4); + + relay.channelCtrl(CHANNLE1_BIT | + CHANNLE2_BIT | + CHANNLE3_BIT | + CHANNLE4_BIT); + DEBUG_PRINT.print("Turn all channels on, State: "); + DEBUG_PRINT.println(relay.getChannelState(), BIN); + + delay(2000); + + relay.channelCtrl(CHANNLE1_BIT | + CHANNLE3_BIT); + DEBUG_PRINT.print("Turn 1 3 channels on, State: "); + DEBUG_PRINT.println(relay.getChannelState(), BIN); + + delay(2000); + + relay.channelCtrl(CHANNLE2_BIT | + CHANNLE4_BIT); + DEBUG_PRINT.print("Turn 2 4 channels on, State: "); + DEBUG_PRINT.println(relay.getChannelState(), BIN); + + delay(2000); + + + relay.channelCtrl(0); + DEBUG_PRINT.print("Turn off all channels, State: "); + DEBUG_PRINT.println(relay.getChannelState(), BIN); + + delay(2000); +} + +void loop() { + + +} diff --git a/lib/Multi_Channel_Relay_Arduino_Library/examples/read_firmware_version/read_firmware_version.ino b/lib/Multi_Channel_Relay_Arduino_Library/examples/read_firmware_version/read_firmware_version.ino new file mode 100644 index 000000000..b1fd29610 --- /dev/null +++ b/lib/Multi_Channel_Relay_Arduino_Library/examples/read_firmware_version/read_firmware_version.ino @@ -0,0 +1,23 @@ +#include + +#define USE_8_CHANNELS (1) + +Multi_Channel_Relay relay; + +void setup() { + DEBUG_PRINT.begin(9600); + while (!DEBUG_PRINT); + + // Set I2C address and start relay + relay.begin(0x11); + + /* Read firmware version */ + DEBUG_PRINT.print("firmware version: "); + DEBUG_PRINT.print("0x"); + DEBUG_PRINT.print(relay.getFirmwareVersion(), HEX); + DEBUG_PRINT.println(); +} + +void loop() { + +} diff --git a/lib/Multi_Channel_Relay_Arduino_Library/keywords.txt b/lib/Multi_Channel_Relay_Arduino_Library/keywords.txt new file mode 100644 index 000000000..16526100b --- /dev/null +++ b/lib/Multi_Channel_Relay_Arduino_Library/keywords.txt @@ -0,0 +1,6 @@ +changeI2CAddress KEYWORD2 +getChannelState KEYWORD2 +getFirmwareVersion KEYWORD2 +channelCtrl KEYWORD2 +turn_on_channel KEYWORD2 +turn_off_channel KEYWORD2 diff --git a/lib/Multi_Channel_Relay_Arduino_Library/library.properties b/lib/Multi_Channel_Relay_Arduino_Library/library.properties new file mode 100644 index 000000000..d8ab6cb97 --- /dev/null +++ b/lib/Multi_Channel_Relay_Arduino_Library/library.properties @@ -0,0 +1,9 @@ +name=Multi Channel Relay Arduino Library +version=1.1.0 +author=Seeed Studio +maintainer=Seeed Studio +sentence=Arduino library to control Multi Channel Rely. +paragraph=Arduino library to control Multi Channel Rely. +category=Device Control +url=https://github.com/Seeed-Studio/Multi_Channel_Relay_Arduino_Library +architectures=* \ No newline at end of file diff --git a/lib/Multi_Channel_Relay_Arduino_Library/multi_channel_relay.cpp b/lib/Multi_Channel_Relay_Arduino_Library/multi_channel_relay.cpp new file mode 100644 index 000000000..ecf5950e4 --- /dev/null +++ b/lib/Multi_Channel_Relay_Arduino_Library/multi_channel_relay.cpp @@ -0,0 +1,134 @@ +/* + multi_channel_relay.h + Seeed multi channel relay Arduino library + + Copyright (c) 2018 Seeed Technology Co., Ltd. + Author : lambor + Create Time : June 2018 + Change Log : + + 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 +*/ + +#include + +Multi_Channel_Relay::Multi_Channel_Relay() { + +} + +void Multi_Channel_Relay::begin(int address) { + // Wire.begin(); Handled by ESPEasy already + channel_state = 0; + _i2cAddr = address; + +} + +uint8_t Multi_Channel_Relay::getFirmwareVersion(void) { + Wire.beginTransmission(_i2cAddr); + Wire.write(CMD_READ_FIRMWARE_VER); + Wire.endTransmission(); + + Wire.requestFrom(_i2cAddr, 1); + //while(!Wire.available()); + return Wire.read(); +} + +void Multi_Channel_Relay::changeI2CAddress(uint8_t old_addr, uint8_t new_addr) { + Wire.beginTransmission(old_addr); + Wire.write(CMD_SAVE_I2C_ADDR); + Wire.write(new_addr); + Wire.endTransmission(); + + _i2cAddr = new_addr; +} + +uint8_t Multi_Channel_Relay::getChannelState(void) { + return channel_state; +} + +void Multi_Channel_Relay::channelCtrl(uint8_t state) { + channel_state = state; + + Wire.beginTransmission(_i2cAddr); + Wire.write(CMD_CHANNEL_CTRL); + Wire.write(channel_state); + Wire.endTransmission(); +} + +void Multi_Channel_Relay::turn_on_channel(uint8_t channel) { + channel_state |= (1 << (channel - 1)); + + Wire.beginTransmission(_i2cAddr); + Wire.write(CMD_CHANNEL_CTRL); + Wire.write(channel_state); + Wire.endTransmission(); +} + +void Multi_Channel_Relay::turn_off_channel(uint8_t channel) { + channel_state &= ~(1 << (channel - 1)); + + Wire.beginTransmission(_i2cAddr); + Wire.write(CMD_CHANNEL_CTRL); + Wire.write(channel_state); + Wire.endTransmission(); +} + +// uint8_t Multi_Channel_Relay::scanI2CDevice(void) { + // byte error = 0, address = 0, result = 0; + // int nDevices; + + // DEBUG_PRINT.println("Scanning..."); + + // nDevices = 0; + // for (address = 1; address <= 127; address++) { + // // The i2c_scanner uses the return value of + // // the Write.endTransmisstion to see if + // // a device did acknowledge to the address. + // Wire.beginTransmission(address); + // error = Wire.endTransmission(); + + // if (error == 0) { + // result = address; + // DEBUG_PRINT.print("I2C device found at address 0x"); + // if (address < 16) { + // DEBUG_PRINT.print("0"); + // } + // DEBUG_PRINT.print(address, HEX); + // DEBUG_PRINT.println(" !"); + + // nDevices++; + // } else if (error == 4) { + // DEBUG_PRINT.print("Unknown error at address 0x"); + // if (address < 16) { + // DEBUG_PRINT.print("0"); + // } + // DEBUG_PRINT.println(address, HEX); + // } + // } + // if (nDevices == 0) { + // DEBUG_PRINT.println("No I2C devices found\n"); + // result = 0x00; + // } else { + // DEBUG_PRINT.print("Found "); + // DEBUG_PRINT.print(nDevices); + // DEBUG_PRINT.print(" devices\n"); + // if (nDevices != 1) { + // result = 0x00; + // } + // } + + // return result; +// return 0; +// } diff --git a/lib/Multi_Channel_Relay_Arduino_Library/multi_channel_relay.h b/lib/Multi_Channel_Relay_Arduino_Library/multi_channel_relay.h new file mode 100644 index 000000000..df27d602b --- /dev/null +++ b/lib/Multi_Channel_Relay_Arduino_Library/multi_channel_relay.h @@ -0,0 +1,129 @@ +/* + multi_channel_relay.cpp + Seeed multi channel relay Arduino library + + Copyright (c) 2018 Seeed Technology Co., Ltd. + Author : lambor + Create Time : June 2018 + Change Log : + + 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 +*/ + +#pragma once + +#ifndef MULTI_CHANNEL_RELAY_H +#define MULTI_CHANNEL_RELAY_H + +// Architecture specific include +// #if defined(ARDUINO_ARCH_AVR) +// #define DEBUG_PRINT Serial +// #elif defined(ARDUINO_ARCH_SAM) +// #define DEBUG_PRINT SerialUSB +// #elif defined(ARDUINO_ARCH_SAMD) +// #define DEBUG_PRINT SerialUSB +// #elif defined(ARDUINO_ARCH_STM32F4) +// #define DEBUG_PRINT SerialUSB +// #else +// #pragma message("Not match any architecture.") +// #define DEBUG_PRINT Serial +// #endif + +#include +#include + + +#define CHANNLE1_BIT 0x01 +#define CHANNLE2_BIT 0x02 +#define CHANNLE3_BIT 0x04 +#define CHANNLE4_BIT 0x08 +#define CHANNLE5_BIT 0x10 +#define CHANNLE6_BIT 0x20 +#define CHANNLE7_BIT 0x40 +#define CHANNLE8_BIT 0x80 + +#define CMD_CHANNEL_CTRL 0x10 +#define CMD_SAVE_I2C_ADDR 0x11 +#define CMD_READ_I2C_ADDR 0x12 +#define CMD_READ_FIRMWARE_VER 0x13 + +class Multi_Channel_Relay { + public: + Multi_Channel_Relay(); + + /** + Begin Multi Channel Relay by a I2C address. + @param address can be changed by changeI2CAddress. Please refer to example change_i2c_address + */ + void begin(int address = 0x11); + + /** + @brief Change device address from old_addr to new_addr. + @param new_addr, the address to use. + old_addr, the original address + @return None + */ + void changeI2CAddress(uint8_t new_addr, uint8_t old_addr); + + /** + /brief Get channel state + /return One byte value to indicate channel state + the bits range from 0 to 7 represents channel 1 to 8 + */ + uint8_t getChannelState(void); + + /** + @brief Read firmware version from on board MCU + @param + @return Firmware version in byte + */ + uint8_t getFirmwareVersion(void); + + /** + @brief Control relay channels + @param state, use one Byte to represent 8 channel + @return None + */ + void channelCtrl(uint8_t state); + + /** + @brief Turn on one of 8 channels + @param channel, channel to control with (range form 1 to 8) + @return None + */ + void turn_on_channel(uint8_t channel); + + /** + @brief Turn off on of 8 channels + @param channel, channel to control with (range form 1 to 8) + @return None + */ + void turn_off_channel(uint8_t channel); + + // /** + // @brief Scan I2C device, return the address if there is only one i2c device + // @param + // @return device address + // */ + // uint8_t scanI2CDevice(void); + + private: + int _i2cAddr; // This is the I2C address you want to use + int channel_state; // Value to save channel state +}; + + + +#endif \ No newline at end of file diff --git a/platformio_esp32_envs.ini b/platformio_esp32_envs.ini index 727f5d22b..5be3ef720 100644 --- a/platformio_esp32_envs.ini +++ b/platformio_esp32_envs.ini @@ -10,7 +10,7 @@ lib_ignore = ESP8266WiFi, ESP8266Ping, ESP8266WebServer, ESP8266H [esp32_common] extends = common, core_esp32_3_3_0 -lib_deps = td-er/ESPeasySerial @ 2.0.7, adafruit/Adafruit ILI9341 @ ^1.5.6, Adafruit GFX Library, LOLIN_EPD, Adafruit BusIO, VL53L0X @ 1.3.0, SparkFun VL53L1X 4m Laser Distance Sensor @ 1.2.9, td-er/SparkFun MAX1704x Fuel Gauge Arduino Library @ ^1.0.1, ArduinoOTA, ESP32HTTPUpdateServer +lib_deps = td-er/ESPeasySerial @ 2.0.7, adafruit/Adafruit ILI9341 @ ^1.5.6, Adafruit GFX Library, LOLIN_EPD, Adafruit BusIO, VL53L0X @ 1.3.0, SparkFun VL53L1X 4m Laser Distance Sensor @ 1.2.9, td-er/SparkFun MAX1704x Fuel Gauge Arduino Library @ ^1.0.1, ArduinoOTA, ESP32HTTPUpdateServer, Multi Channel Relay Arduino Library lib_ignore = ${esp32_always.lib_ignore}, ESP32_ping, IRremoteESP8266, HeatpumpIR board_build.f_flash = 80000000L board_build.flash_mode = dout diff --git a/platformio_esp82xx_base.ini b/platformio_esp82xx_base.ini index 71d65746c..ef13b0397 100644 --- a/platformio_esp82xx_base.ini +++ b/platformio_esp82xx_base.ini @@ -52,7 +52,7 @@ extends = common board_build.f_cpu = 80000000L build_flags = ${debug_flags.build_flags} ${mqtt_flags.build_flags} -DHTTPCLIENT_1_1_COMPATIBLE=0 build_unflags = -DDEBUG_ESP_PORT -lib_deps = td-er/ESPeasySerial @ 2.0.7, adafruit/Adafruit ILI9341 @ ^1.5.6, Adafruit GFX Library, LOLIN_EPD, Adafruit BusIO, bblanchon/ArduinoJson @ ^6.17.2, VL53L0X @ 1.3.0, SparkFun VL53L1X 4m Laser Distance Sensor @ 1.2.9, td-er/RABurton ESP8266 Mutex @ ^1.0.2, td-er/SparkFun MAX1704x Fuel Gauge Arduino Library @ ^1.0.1, ESP8266HTTPUpdateServer +lib_deps = td-er/ESPeasySerial @ 2.0.7, adafruit/Adafruit ILI9341 @ ^1.5.6, Adafruit GFX Library, LOLIN_EPD, Adafruit BusIO, bblanchon/ArduinoJson @ ^6.17.2, VL53L0X @ 1.3.0, SparkFun VL53L1X 4m Laser Distance Sensor @ 1.2.9, td-er/RABurton ESP8266 Mutex @ ^1.0.2, td-er/SparkFun MAX1704x Fuel Gauge Arduino Library @ ^1.0.1, ESP8266HTTPUpdateServer, Multi Channel Relay Arduino Library lib_ignore = ${esp82xx_defaults.lib_ignore}, IRremoteESP8266, HeatpumpIR, LittleFS(esp8266), ServoESP32, TinyWireM board = esp12e monitor_filters = esp8266_exception_decoder diff --git a/src/_P124_MultiRelay.ino b/src/_P124_MultiRelay.ino new file mode 100644 index 000000000..30b9faa28 --- /dev/null +++ b/src/_P124_MultiRelay.ino @@ -0,0 +1,231 @@ +#include "_Plugin_Helper.h" + +#ifdef USES_P124 + +// ####################################################################################################### +// ########################### Plugin 124 I2C Multi Relay module ############################### +// ####################################################################################################### + +/** Changelog: + * 2021-11-18 tonhuisman: Implement settings, + * Implement write commands: + * multirelay,on, (channel 1..8, max. accepted as configured) + * multirelay,off, + * multirelay,set, (value in decimal, 0xnn hex or 0bnnnnnnnn binary) + * Add binary state to Devices screen, when plugin enabled. + * 2021-11-17 tonhuisman: Initial plugin development. + */ + +# define PLUGIN_124 +# define PLUGIN_ID_124 124 +# define PLUGIN_NAME_124 "Output - I2C Multi Relay [TESTING]" +# define PLUGIN_VALUENAME1_124 "State" + +# include "./src/PluginStructs/P124_data_struct.h" + + +boolean Plugin_124(uint8_t function, struct EventStruct *event, String& string) +{ + boolean success = false; + + switch (function) + { + case PLUGIN_DEVICE_ADD: + { + Device[++deviceCount].Number = PLUGIN_ID_124; + Device[deviceCount].Type = DEVICE_TYPE_I2C; + Device[deviceCount].VType = Sensor_VType::SENSOR_TYPE_SINGLE; + Device[deviceCount].Ports = 0; + Device[deviceCount].PullUpOption = false; + Device[deviceCount].InverseLogicOption = false; + Device[deviceCount].FormulaOption = true; + Device[deviceCount].ValueCount = 1; + Device[deviceCount].SendDataOption = true; + Device[deviceCount].TimerOption = true; + Device[deviceCount].TimerOptional = true; + + break; + } + + case PLUGIN_GET_DEVICENAME: + { + string = F(PLUGIN_NAME_124); + break; + } + + case PLUGIN_GET_DEVICEVALUENAMES: + { + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_124)); + break; + } + + case PLUGIN_I2C_HAS_ADDRESS: + { + success = (event->Par1 == 0x11); + break; + } + + case PLUGIN_SET_DEFAULTS: + { + ExtraTaskSettings.TaskDeviceValueDecimals[0] = 0; // No decimals needed + break; + } + + case PLUGIN_WEBFORM_LOAD: + { + const __FlashStringHelper *optionsMode2[] = { + F("2 relays"), + F("4 relays"), + F("8 relays") }; + int optionValuesMode2[] { 2, 4, 8 }; + addFormSelector(F("Number of relays"), F("plugin_124_relays"), 3, optionsMode2, optionValuesMode2, P124_CONFIG_RELAY_COUNT, true); + + const __FlashStringHelper *yesNoOptions[] = { + F("No"), + F("Yes") + }; + int yesNoValues[] = { 0, 1 }; + addFormSelector(F("Initialize relays on startup"), + getPluginCustomArgName(P124_FLAGS_INIT_RELAYS), 2, yesNoOptions, yesNoValues, + bitRead(P124_CONFIG_FLAGS, P124_FLAGS_INIT_RELAYS) ? 1 : 0, true); + String label; + + if (bitRead(P124_CONFIG_FLAGS, P124_FLAGS_INIT_RELAYS)) { + for (int i = 0; i < P124_CONFIG_RELAY_COUNT; i++) { + label = F("Relay "); + label += i + 1; + label += F(" initial state (on/off)"); + addFormCheckBox(label, getPluginCustomArgName(i), bitRead(P124_CONFIG_FLAGS, i)); + } + } + success = true; + break; + } + + case PLUGIN_WEBFORM_SAVE: + { + P124_CONFIG_RELAY_COUNT = getFormItemInt(F("plugin_124_relays")); + uint32_t lSettings = 0u; + bitWrite(lSettings, P124_FLAGS_INIT_RELAYS, getFormItemInt(getPluginCustomArgName(P124_FLAGS_INIT_RELAYS)) == 1); + + if (lSettings != 0) { + for (int i = 0; i < P124_CONFIG_RELAY_COUNT; i++) { + bitWrite(lSettings, i, isFormItemChecked(getPluginCustomArgName(i))); + } + } + P124_CONFIG_FLAGS = lSettings; + + success = true; + break; + } + + case PLUGIN_INIT: + { + initPluginTaskData(event->TaskIndex, new (std::nothrow) P124_data_struct(PCONFIG(0))); + P124_data_struct *P124_data = static_cast(getPluginTaskData(event->TaskIndex)); + + if (nullptr == P124_data) { + return success; + } + + if (P124_data->isInitialized()) { + String log; + log.reserve(46); + log = F("MultiRelay: Initialized, firmware version: "); + log += P124_data->getFirmwareVersion(); + addLog(LOG_LEVEL_INFO, log); + + if (bitRead(P124_CONFIG_FLAGS, P124_FLAGS_INIT_RELAYS)) { + P124_data->channelCtrl(P124_CONFIG_FLAGS & 0xFF); // Set relays state + UserVar[event->BaseVarIndex] = P124_data->getChannelState(); // Get relays state + } + success = true; + } else { + addLog(LOG_LEVEL_ERROR, F("MultiRelay: Initialization error!")); + } + + break; + } + + case PLUGIN_READ: + { + P124_data_struct *P124_data = static_cast(getPluginTaskData(event->TaskIndex)); + + if (nullptr == P124_data) { + return success; + } + + if (P124_data->isInitialized()) { + UserVar[event->BaseVarIndex] = P124_data->getChannelState(); // Get relays state + success = true; + } + break; + } + + case PLUGIN_WEBFORM_SHOW_VALUES: + { + P124_data_struct *P124_data = static_cast(getPluginTaskData(event->TaskIndex)); + + if ((nullptr != P124_data) && P124_data->isInitialized()) { + uint8_t varNr = 1; // VARS_PER_TASK; + String label = F("Relay state "); + label += P124_CONFIG_RELAY_COUNT; + label += F(".."); + label += 1; + String state = F("0b "); + uint32_t val = UserVar[event->BaseVarIndex]; + val &= 0xff; + val |= (0x1 << P124_CONFIG_RELAY_COUNT); + state += ull2String(val, 2); + state.remove(3, 1); // Delete leading 1 we added + pluginWebformShowValue(event->TaskIndex, varNr++, label, state, true); + + // success = true; + } + break; + } + + case PLUGIN_WRITE: + { + P124_data_struct *P124_data = static_cast(getPluginTaskData(event->TaskIndex)); + + if (nullptr == P124_data) { + return success; + } + + # ifdef P124_DEBUG_LOG + addLog(LOG_LEVEL_INFO, string); + String log = F("Par1..3:"); + log += event->Par1; + log += ','; + log += event->Par2; + log += ','; + log += event->Par3; + addLog(LOG_LEVEL_INFO, log); + # endif // ifdef P124_DEBUG_LOG + + String command = parseString(string, 1); + + if (P124_data->isInitialized() && + command.equals(F("multirelay"))) { + String subcommand = parseString(string, 2); + + if (subcommand.equals(F("on"))) { + success = P124_data->turn_on_channel(event->Par2); + } else if (subcommand.equals(F("off"))) { + success = P124_data->turn_off_channel(event->Par2); + } else if (subcommand.equals(F("set"))) { + success = P124_data->channelCtrl(event->Par2); + } + + if (success) { + UserVar[event->BaseVarIndex] = P124_data->getChannelState(); // Get relays state + } + } + break; + } + } + return success; +} + +#endif // ifdef USES_P124 diff --git a/src/src/PluginStructs/P124_data_struct.cpp b/src/src/PluginStructs/P124_data_struct.cpp new file mode 100644 index 000000000..6ea0cace0 --- /dev/null +++ b/src/src/PluginStructs/P124_data_struct.cpp @@ -0,0 +1,61 @@ +#include "../PluginStructs/P124_data_struct.h" + +#ifdef USES_P124 + +// **************************************************************************/ +// Constructor +// **************************************************************************/ +P124_data_struct::P124_data_struct(uint8_t relayCount) + : _relayCount(relayCount) { + relay = new (std::nothrow) Multi_Channel_Relay(); // Use default address +} + +// **************************************************************************/ +// Destructor +// **************************************************************************/ +P124_data_struct::~P124_data_struct() { + if (isInitialized()) { + delete relay; + relay = nullptr; + } +} + +uint8_t P124_data_struct::getChannelState() { + if (isInitialized()) { + return relay->getChannelState(); + } + return 0u; +} + +uint8_t P124_data_struct::getFirmwareVersion() { + if (isInitialized()) { + return relay->getFirmwareVersion(); + } + return 0u; +} + +bool P124_data_struct::channelCtrl(uint8_t state) { + if (isInitialized()) { + relay->channelCtrl(state); + return true; + } + return false; +} + +bool P124_data_struct::turn_on_channel(uint8_t channel) { + if (isInitialized() && (validChannel(channel))) { + relay->turn_on_channel(channel); + return true; + } + return false; +} + +bool P124_data_struct::turn_off_channel(uint8_t channel) { + if (isInitialized() && (validChannel(channel))) { + relay->turn_off_channel(channel); + return true; + } + return false; +} + +#endif // ifdef USES_P124 diff --git a/src/src/PluginStructs/P124_data_struct.h b/src/src/PluginStructs/P124_data_struct.h new file mode 100644 index 000000000..61a41a3b1 --- /dev/null +++ b/src/src/PluginStructs/P124_data_struct.h @@ -0,0 +1,45 @@ +#ifndef PLUGINSTRUCTS_P124_DATA_STRUCT_H +#define PLUGINSTRUCTS_P124_DATA_STRUCT_H + +#include "../../_Plugin_Helper.h" +#ifdef USES_P124 + +# include + +// # define P124_DEBUG_LOG // Enable for some (extra) logging + +# define P124_CONFIG_RELAY_COUNT PCONFIG(0) +# define P124_CONFIG_FLAGS PCONFIG_LONG(0) + +# define P124_FLAGS_INIT_RELAYS 8 // 0..7 hold the on/off state of each relay + +struct P124_data_struct : public PluginTaskData_base { +public: + + P124_data_struct(uint8_t relayCount); + + P124_data_struct() = delete; + ~P124_data_struct(); + + bool isInitialized() { + return relay != nullptr; + } + + uint8_t getChannelState(); + uint8_t getFirmwareVersion(); + bool channelCtrl(uint8_t state); + bool turn_on_channel(uint8_t channel); + bool turn_off_channel(uint8_t channel); + +private: + + bool validChannel(uint channel) { + return channel > 0 && channel <= _relayCount; + } + + Multi_Channel_Relay *relay = nullptr; + + uint8_t _relayCount; +}; +#endif // ifdef USES_P124 +#endif // ifndef PLUGINSTRUCTS_P124_DATA_STRUCT_H diff --git a/src/src/WebServer/I2C_Scanner.cpp b/src/src/WebServer/I2C_Scanner.cpp index a687f8746..6e89b4f9f 100644 --- a/src/src/WebServer/I2C_Scanner.cpp +++ b/src/src/WebServer/I2C_Scanner.cpp @@ -176,6 +176,9 @@ String getKnownI2Cdevice(uint8_t address) { switch (address) { + case 0x11: + result += F("I2C_MultiRelay"); + break; case 0x20: case 0x21: case 0x22: