mirror of
https://github.com/randybb/esphome-configs.git
synced 2026-01-02 19:47:29 +01:00
have fun
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Gitignore settings for ESPHome
|
||||||
|
# This is an example and may include too much for your use-case.
|
||||||
|
# You can modify this file to suit your needs.
|
||||||
|
/.esphome/
|
||||||
|
/secrets.yaml
|
||||||
BIN
B612Mono-Regular.ttf
Normal file
BIN
B612Mono-Regular.ttf
Normal file
Binary file not shown.
BIN
BebasNeue-Regular.ttf
Normal file
BIN
BebasNeue-Regular.ttf
Normal file
Binary file not shown.
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024 Roman Priesol
|
||||||
|
|
||||||
|
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.
|
||||||
3
README.adoc
Normal file
3
README.adoc
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
= My ESPHome Configs
|
||||||
|
Roman Priesol <roman@priesol.net>
|
||||||
|
It is a mess, don't use it!
|
||||||
311
arduino_port_expander.h
Normal file
311
arduino_port_expander.h
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
// Must disable logging if using logging in main.cpp or in other custom components for the
|
||||||
|
// __c causes a section type conflict with __c thingy
|
||||||
|
// you can enable logging and use it if you enable this in logger:
|
||||||
|
/*
|
||||||
|
logger:
|
||||||
|
level: DEBUG
|
||||||
|
esp8266_store_log_strings_in_flash: False
|
||||||
|
*/
|
||||||
|
|
||||||
|
//#define APE_LOGGING
|
||||||
|
|
||||||
|
// take advantage of LOG_ defines to decide which code to include
|
||||||
|
#ifdef LOG_BINARY_OUTPUT
|
||||||
|
#define APE_BINARY_OUTPUT
|
||||||
|
#endif
|
||||||
|
#ifdef LOG_BINARY_SENSOR
|
||||||
|
#define APE_BINARY_SENSOR
|
||||||
|
#endif
|
||||||
|
#ifdef LOG_SENSOR
|
||||||
|
#define APE_SENSOR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const char *TAGape = "ape";
|
||||||
|
|
||||||
|
#define APE_CMD_DIGITAL_READ 0
|
||||||
|
#define APE_CMD_WRITE_ANALOG 2
|
||||||
|
#define APE_CMD_WRITE_DIGITAL_HIGH 3
|
||||||
|
#define APE_CMD_WRITE_DIGITAL_LOW 4
|
||||||
|
#define APE_CMD_SETUP_PIN_OUTPUT 5
|
||||||
|
#define APE_CMD_SETUP_PIN_INPUT_PULLUP 6
|
||||||
|
#define APE_CMD_SETUP_PIN_INPUT 7
|
||||||
|
// 8 analog registers.. A0 to A7
|
||||||
|
// A4 and A5 not supported due to I2C
|
||||||
|
#define CMD_ANALOG_READ_A0 0b1000 // 0x8
|
||||||
|
// ....
|
||||||
|
#define CMD_ANALOG_READ_A7 0b1111 // 0xF
|
||||||
|
|
||||||
|
#define CMD_SETUP_ANALOG_INTERNAL 0x10
|
||||||
|
#define CMD_SETUP_ANALOG_DEFAULT 0x11
|
||||||
|
|
||||||
|
#define get_ape(constructor) static_cast<ArduinoPortExpander *>(constructor.get_component(0))
|
||||||
|
|
||||||
|
#define ape_binary_output(ape, pin) get_ape(ape)->get_binary_output(pin)
|
||||||
|
#define ape_binary_sensor(ape, pin) get_ape(ape)->get_binary_sensor(pin)
|
||||||
|
#define ape_analog_input(ape, pin) get_ape(ape)->get_analog_input(pin)
|
||||||
|
|
||||||
|
class ArduinoPortExpander;
|
||||||
|
|
||||||
|
using namespace esphome;
|
||||||
|
|
||||||
|
#ifdef APE_BINARY_OUTPUT
|
||||||
|
class ApeBinaryOutput : public output::BinaryOutput
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ApeBinaryOutput(ArduinoPortExpander *parent, uint8_t pin)
|
||||||
|
{
|
||||||
|
this->parent_ = parent;
|
||||||
|
this->pin_ = pin;
|
||||||
|
}
|
||||||
|
void write_state(bool state) override;
|
||||||
|
uint8_t get_pin() { return this->pin_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ArduinoPortExpander *parent_;
|
||||||
|
uint8_t pin_;
|
||||||
|
// Pins are setup as output after the state is written, Arduino has no open drain outputs, after setting an output it will either sink or source thus activating outputs writen to false during a flick.
|
||||||
|
bool setup_{true};
|
||||||
|
bool state_{false};
|
||||||
|
|
||||||
|
friend class ArduinoPortExpander;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef APE_BINARY_SENSOR
|
||||||
|
class ApeBinarySensor : public binary_sensor::BinarySensor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ApeBinarySensor(ArduinoPortExpander *parent, uint8_t pin)
|
||||||
|
{
|
||||||
|
this->pin_ = pin;
|
||||||
|
}
|
||||||
|
uint8_t get_pin() { return this->pin_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint8_t pin_;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef APE_SENSOR
|
||||||
|
class ApeAnalogInput : public sensor::Sensor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ApeAnalogInput(ArduinoPortExpander *parent, uint8_t pin)
|
||||||
|
{
|
||||||
|
this->pin_ = pin;
|
||||||
|
}
|
||||||
|
uint8_t get_pin() { return this->pin_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint8_t pin_;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class ArduinoPortExpander : public Component, public I2CDevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ArduinoPortExpander(I2CBus *bus, uint8_t address, bool vref_default = false)
|
||||||
|
{
|
||||||
|
set_i2c_address(address);
|
||||||
|
set_i2c_bus(bus);
|
||||||
|
this->vref_default_ = vref_default;
|
||||||
|
}
|
||||||
|
void setup() override
|
||||||
|
{
|
||||||
|
#ifdef APE_LOGGING
|
||||||
|
ESP_LOGCONFIG(TAGape, "Setting up ArduinoPortExpander at %#02x ...", address_);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We cannot setup as usual as arduino boots later than esp8266
|
||||||
|
|
||||||
|
Poll i2c bus for our Arduino for a n seconds instead of failing fast,
|
||||||
|
also this is important as pin setup (INPUT_PULLUP, OUTPUT it's done once)
|
||||||
|
*/
|
||||||
|
this->configure_timeout_ = millis() + 5000;
|
||||||
|
}
|
||||||
|
void loop() override
|
||||||
|
{
|
||||||
|
if (millis() < this->configure_timeout_)
|
||||||
|
{
|
||||||
|
bool try_configure = millis() % 100 > 50;
|
||||||
|
if (try_configure == this->configure_)
|
||||||
|
return;
|
||||||
|
this->configure_ = try_configure;
|
||||||
|
|
||||||
|
if (ERROR_OK == this->read_register(APE_CMD_DIGITAL_READ, const_cast<uint8_t *>(this->read_buffer_), 3))
|
||||||
|
{
|
||||||
|
#ifdef APE_LOGGING
|
||||||
|
ESP_LOGCONFIG(TAGape, "ArduinoPortExpander found at %#02x", address_);
|
||||||
|
#endif
|
||||||
|
delay(10);
|
||||||
|
if (this->vref_default_)
|
||||||
|
{
|
||||||
|
this->write_register(CMD_SETUP_ANALOG_DEFAULT, nullptr, 0); // 0: unused
|
||||||
|
}
|
||||||
|
|
||||||
|
// Config success
|
||||||
|
this->configure_timeout_ = 0;
|
||||||
|
this->status_clear_error();
|
||||||
|
#ifdef APE_BINARY_SENSOR
|
||||||
|
for (ApeBinarySensor *pin : this->input_pins_)
|
||||||
|
{
|
||||||
|
App.feed_wdt();
|
||||||
|
uint8_t pinNo = pin->get_pin();
|
||||||
|
#ifdef APE_LOGGING
|
||||||
|
ESP_LOGCONFIG(TAGape, "Setup input pin %d", pinNo);
|
||||||
|
#endif
|
||||||
|
this->write_register(APE_CMD_SETUP_PIN_INPUT_PULLUP, &pinNo, 1);
|
||||||
|
delay(20);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef APE_BINARY_OUTPUT
|
||||||
|
for (ApeBinaryOutput *output : this->output_pins_)
|
||||||
|
{
|
||||||
|
if (!output->setup_)
|
||||||
|
{ // this output has a valid value already
|
||||||
|
this->write_state(output->pin_, output->state_, true);
|
||||||
|
App.feed_wdt();
|
||||||
|
delay(20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef APE_SENSOR
|
||||||
|
for (ApeAnalogInput *sensor : this->analog_pins_)
|
||||||
|
{
|
||||||
|
App.feed_wdt();
|
||||||
|
uint8_t pinNo = sensor->get_pin();
|
||||||
|
#ifdef APE_LOGGING
|
||||||
|
ESP_LOGCONFIG(TAGape, "Setup analog input pin %d", pinNo);
|
||||||
|
#endif
|
||||||
|
this->write_register(APE_CMD_SETUP_PIN_INPUT, &pinNo, 1);
|
||||||
|
delay(20);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Still not answering
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this->configure_timeout_ != 0 && millis() > this->configure_timeout_)
|
||||||
|
{
|
||||||
|
#ifdef APE_LOGGING
|
||||||
|
ESP_LOGE(TAGape, "ArduinoPortExpander NOT found at %#02x", address_);
|
||||||
|
#endif
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef APE_BINARY_SENSOR
|
||||||
|
if (ERROR_OK != this->read_register(APE_CMD_DIGITAL_READ, const_cast<uint8_t *>(this->read_buffer_), 3))
|
||||||
|
{
|
||||||
|
#ifdef APE_LOGGING
|
||||||
|
ESP_LOGE(TAGape, "Error reading. Reconfiguring pending.");
|
||||||
|
#endif
|
||||||
|
this->status_set_error();
|
||||||
|
this->configure_timeout_ = millis() + 5000;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (ApeBinarySensor *pin : this->input_pins_)
|
||||||
|
{
|
||||||
|
uint8_t pinNo = pin->get_pin();
|
||||||
|
|
||||||
|
uint8_t bit = pinNo % 8;
|
||||||
|
uint8_t value = pinNo < 8 ? this->read_buffer_[0] : pinNo < 16 ? this->read_buffer_[1] : this->read_buffer_[2];
|
||||||
|
bool ret = value & (1 << bit);
|
||||||
|
if (this->initial_state_)
|
||||||
|
pin->publish_initial_state(ret);
|
||||||
|
else
|
||||||
|
pin->publish_state(ret);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef APE_SENSOR
|
||||||
|
for (ApeAnalogInput *pin : this->analog_pins_)
|
||||||
|
{
|
||||||
|
uint8_t pinNo = pin->get_pin();
|
||||||
|
pin->publish_state(analogRead(pinNo));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
this->initial_state_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef APE_SENSOR
|
||||||
|
uint16_t analogRead(uint8_t pin)
|
||||||
|
{
|
||||||
|
bool ok = (ERROR_OK == this->read_register((uint8_t)(CMD_ANALOG_READ_A0 + pin), const_cast<uint8_t *>(this->read_buffer_), 2));
|
||||||
|
#ifdef APE_LOGGING
|
||||||
|
ESP_LOGVV(TAGape, "analog read pin: %d ok: %d byte0: %d byte1: %d", pin, ok, this->read_buffer_[0], this->read_buffer_[1]);
|
||||||
|
#endif
|
||||||
|
uint16_t value = this->read_buffer_[0] | ((uint16_t)this->read_buffer_[1] << 8);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef APE_BINARY_OUTPUT
|
||||||
|
output::BinaryOutput *get_binary_output(uint8_t pin)
|
||||||
|
{
|
||||||
|
ApeBinaryOutput *output = new ApeBinaryOutput(this, pin);
|
||||||
|
output_pins_.push_back(output);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef APE_BINARY_SENSOR
|
||||||
|
binary_sensor::BinarySensor *get_binary_sensor(uint8_t pin)
|
||||||
|
{
|
||||||
|
ApeBinarySensor *binarySensor = new ApeBinarySensor(this, pin);
|
||||||
|
input_pins_.push_back(binarySensor);
|
||||||
|
return binarySensor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef APE_SENSOR
|
||||||
|
sensor::Sensor *get_analog_input(uint8_t pin)
|
||||||
|
{
|
||||||
|
ApeAnalogInput *input = new ApeAnalogInput(this, pin);
|
||||||
|
analog_pins_.push_back(input);
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
void write_state(uint8_t pin, bool state, bool setup = false)
|
||||||
|
{
|
||||||
|
if (this->configure_timeout_ != 0)
|
||||||
|
return;
|
||||||
|
#ifdef APE_LOGGING
|
||||||
|
ESP_LOGD(TAGape, "Writing %d to pin %d", state, pin);
|
||||||
|
#endif
|
||||||
|
this->write_register(state ? APE_CMD_WRITE_DIGITAL_HIGH : APE_CMD_WRITE_DIGITAL_LOW, &pin, 1);
|
||||||
|
if (setup)
|
||||||
|
{
|
||||||
|
App.feed_wdt();
|
||||||
|
delay(20);
|
||||||
|
#ifdef APE_LOGGING
|
||||||
|
ESP_LOGI(TAGape, "Setup output pin %d", pin);
|
||||||
|
#endif
|
||||||
|
this->write_register(APE_CMD_SETUP_PIN_OUTPUT, &pin, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool configure_{true};
|
||||||
|
bool initial_state_{true};
|
||||||
|
uint8_t read_buffer_[3]{0, 0, 0};
|
||||||
|
unsigned long configure_timeout_{5000};
|
||||||
|
bool vref_default_{false};
|
||||||
|
|
||||||
|
#ifdef APE_BINARY_OUTPUT
|
||||||
|
std::vector<ApeBinaryOutput *> output_pins_;
|
||||||
|
#endif
|
||||||
|
#ifdef APE_BINARY_SENSOR
|
||||||
|
std::vector<ApeBinarySensor *> input_pins_;
|
||||||
|
#endif
|
||||||
|
#ifdef APE_SENSOR
|
||||||
|
std::vector<ApeAnalogInput *> analog_pins_;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef APE_BINARY_OUTPUT
|
||||||
|
void ApeBinaryOutput::write_state(bool state)
|
||||||
|
{
|
||||||
|
this->state_ = state;
|
||||||
|
this->parent_->write_state(this->pin_, state, this->setup_);
|
||||||
|
this->setup_ = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
BIN
blinky.gif
Normal file
BIN
blinky.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
1
common/.esphome/external_components/b7dc7eea
Submodule
1
common/.esphome/external_components/b7dc7eea
Submodule
Submodule common/.esphome/external_components/b7dc7eea added at 16571e8a90
4
common/api.yaml
Normal file
4
common/api.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
api:
|
||||||
|
encryption:
|
||||||
|
key: !secret api_key
|
||||||
|
reboot_timeout: 0s
|
||||||
3
common/binary_sensor/status.yaml
Normal file
3
common/binary_sensor/status.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
platform: status
|
||||||
|
name: "${name} Status"
|
||||||
3
common/button/factory_reset.yaml
Normal file
3
common/button/factory_reset.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
platform: factory_reset
|
||||||
|
name: ${name} Factory Defaults
|
||||||
3
common/button/restart.yaml
Normal file
3
common/button/restart.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
platform: restart
|
||||||
|
name: ${name} Restart
|
||||||
3
common/button/safe_mode.yaml
Normal file
3
common/button/safe_mode.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
platform: safe_mode
|
||||||
|
name: ${name} Restart (Safe Mode)
|
||||||
3
common/button/shutdown.yaml
Normal file
3
common/button/shutdown.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
platform: shutdown
|
||||||
|
name: ${name} Shutdown
|
||||||
22
common/common.yaml
Normal file
22
common/common.yaml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
<<: !include wifi.yaml
|
||||||
|
<<: !include api.yaml
|
||||||
|
<<: !include ota.yaml
|
||||||
|
<<: !include logger.yaml
|
||||||
|
|
||||||
|
binary_sensor:
|
||||||
|
- <<: !include binary_sensor/status.yaml
|
||||||
|
|
||||||
|
button:
|
||||||
|
- <<: !include button/factory_reset.yaml
|
||||||
|
- <<: !include button/restart.yaml
|
||||||
|
- <<: !include button/safe_mode.yaml
|
||||||
|
- <<: !include button/shutdown.yaml
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- <<: !include sensor/uptime.yaml
|
||||||
|
- <<: !include sensor/wifi_signal.yaml
|
||||||
|
|
||||||
|
text_sensor:
|
||||||
|
- <<: !include text_sensor/version.yaml
|
||||||
|
- <<: !include text_sensor/wifi_info.yaml
|
||||||
30
common/common_dev.yaml
Normal file
30
common/common_dev.yaml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
<<: !include wifi_dev.yaml
|
||||||
|
<<: !include api.yaml
|
||||||
|
<<: !include ota.yaml
|
||||||
|
#<<: !include logger.yaml
|
||||||
|
<<: !include logger_debug.yaml
|
||||||
|
|
||||||
|
binary_sensor:
|
||||||
|
- <<: !include binary_sensor/status.yaml
|
||||||
|
|
||||||
|
button:
|
||||||
|
- <<: !include button/factory_reset.yaml
|
||||||
|
- <<: !include button/restart.yaml
|
||||||
|
- <<: !include switch/safe_mode.yaml
|
||||||
|
- <<: !include switch/shutdown.yaml
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
# - <<: !include sensor/debug.yaml
|
||||||
|
- <<: !include sensor/uptime.yaml
|
||||||
|
- <<: !include sensor/wifi_signal.yaml
|
||||||
|
|
||||||
|
#switch:
|
||||||
|
# - <<: !include switch/restart.yaml
|
||||||
|
# - <<: !include switch/safe_mode.yaml
|
||||||
|
# - <<: !include switch/shutdown.yaml
|
||||||
|
|
||||||
|
text_sensor:
|
||||||
|
- <<: !include text_sensor/debug.yaml
|
||||||
|
- <<: !include text_sensor/version.yaml
|
||||||
|
- <<: !include text_sensor/wifi_info.yaml
|
||||||
27
common/common_eth.yaml
Normal file
27
common/common_eth.yaml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
<<: !include api.yaml
|
||||||
|
<<: !include ota.yaml
|
||||||
|
# <<: !include logger_debug.yaml
|
||||||
|
<<: !include ethernet.yaml
|
||||||
|
|
||||||
|
binary_sensor:
|
||||||
|
- <<: !include binary_sensor/status.yaml
|
||||||
|
|
||||||
|
button:
|
||||||
|
- <<: !include button/restart.yaml
|
||||||
|
- <<: !include switch/safe_mode.yaml
|
||||||
|
- <<: !include switch/shutdown.yaml
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- <<: !include sensor/uptime.yaml
|
||||||
|
# - <<: !include sensor/free_heap.yaml
|
||||||
|
|
||||||
|
#switch:
|
||||||
|
# - <<: !include switch/restart.yaml
|
||||||
|
# - <<: !include switch/safe_mode.yaml
|
||||||
|
# - <<: !include switch/shutdown.yaml
|
||||||
|
|
||||||
|
text_sensor:
|
||||||
|
# - <<: !include text_sensor/debug.yaml
|
||||||
|
# - <<: !include text_sensor/version.yaml
|
||||||
|
- <<: !include text_sensor/ethernet_info.yaml
|
||||||
21
common/common_min.yaml
Normal file
21
common/common_min.yaml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
<<: !include wifi.yaml
|
||||||
|
<<: !include api.yaml
|
||||||
|
<<: !include ota.yaml
|
||||||
|
<<: !include logger.yaml
|
||||||
|
|
||||||
|
#binary_sensor:
|
||||||
|
# - <<: !include binary_sensor/status.yaml
|
||||||
|
|
||||||
|
#button:
|
||||||
|
# - <<: !include button/restart.yaml
|
||||||
|
# - <<: !include switch/safe_mode.yaml
|
||||||
|
# - <<: !include switch/shutdown.yaml
|
||||||
|
|
||||||
|
#sensor:
|
||||||
|
# - <<: !include sensor/uptime.yaml
|
||||||
|
# - <<: !include sensor/wifi_signal.yaml
|
||||||
|
|
||||||
|
#text_sensor:
|
||||||
|
# - <<: !include text_sensor/version.yaml
|
||||||
|
# - <<: !include text_sensor/wifi_info.yaml
|
||||||
34
common/common_wo_debug.yaml
Normal file
34
common/common_wo_debug.yaml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
<<: !include wifi.yaml
|
||||||
|
<<: !include api.yaml
|
||||||
|
<<: !include ota.yaml
|
||||||
|
<<: !include logger.yaml
|
||||||
|
# <<: !include logger_debug.yaml
|
||||||
|
|
||||||
|
external_components:
|
||||||
|
- source: github://RoboMagus/esphome-gitref-sensor
|
||||||
|
|
||||||
|
binary_sensor:
|
||||||
|
- <<: !include binary_sensor/status.yaml
|
||||||
|
|
||||||
|
button:
|
||||||
|
- <<: !include button/factory_reset.yaml
|
||||||
|
- <<: !include button/restart.yaml
|
||||||
|
- <<: !include switch/safe_mode.yaml
|
||||||
|
- <<: !include switch/shutdown.yaml
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
# - <<: !include sensor/debug.yaml
|
||||||
|
- <<: !include sensor/uptime.yaml
|
||||||
|
- <<: !include sensor/wifi_signal.yaml
|
||||||
|
|
||||||
|
#switch:
|
||||||
|
# - <<: !include switch/restart.yaml
|
||||||
|
# - <<: !include switch/safe_mode.yaml
|
||||||
|
# - <<: !include switch/shutdown.yaml
|
||||||
|
|
||||||
|
text_sensor:
|
||||||
|
# - <<: !include text_sensor/debug.yaml
|
||||||
|
- <<: !include text_sensor/git_ref.yaml
|
||||||
|
- <<: !include text_sensor/version.yaml
|
||||||
|
- <<: !include text_sensor/wifi_info.yaml
|
||||||
8
common/ethernet.yaml
Normal file
8
common/ethernet.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
ethernet:
|
||||||
|
type: LAN8720
|
||||||
|
mdc_pin: 23
|
||||||
|
mdio_pin: 18
|
||||||
|
clk_mode: GPIO17_OUT
|
||||||
|
phy_addr: 0
|
||||||
|
power_pin: 12
|
||||||
3
common/logger.yaml
Normal file
3
common/logger.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
logger:
|
||||||
|
# level: DEBUG
|
||||||
5
common/logger_debug.yaml
Normal file
5
common/logger_debug.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
debug:
|
||||||
|
|
||||||
|
logger:
|
||||||
|
level: debug
|
||||||
4
common/ota.yaml
Normal file
4
common/ota.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
ota:
|
||||||
|
- platform: esphome
|
||||||
|
password: !secret ota_password
|
||||||
2
common/secrets.yaml
Normal file
2
common/secrets.yaml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
<<: !include ../secrets.yaml
|
||||||
10
common/sensor/debug.yaml
Normal file
10
common/sensor/debug.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
platform: debug
|
||||||
|
free:
|
||||||
|
name: "${name} Heap Free"
|
||||||
|
fragmentation:
|
||||||
|
name: "${name} Heap Fragmentation"
|
||||||
|
block:
|
||||||
|
name: "${name} Heap Max Block"
|
||||||
|
loop_time:
|
||||||
|
name: "${name} Loop Time"
|
||||||
9
common/sensor/free_heap.yaml
Normal file
9
common/sensor/free_heap.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
platform: template
|
||||||
|
name: ${name} Free heap
|
||||||
|
lambda: return heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||||
|
icon: "mdi:memory"
|
||||||
|
entity_category: diagnostic
|
||||||
|
state_class: measurement
|
||||||
|
unit_of_measurement: "b"
|
||||||
|
update_interval: 60s
|
||||||
9
common/sensor/uptime.yaml
Normal file
9
common/sensor/uptime.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
platform: uptime
|
||||||
|
name: ${name} Uptime
|
||||||
|
unit_of_measurement: "days"
|
||||||
|
accuracy_decimals: 2
|
||||||
|
update_interval: 60s
|
||||||
|
filters:
|
||||||
|
- lambda: return x / 86400;
|
||||||
|
|
||||||
4
common/sensor/wifi_signal.yaml
Normal file
4
common/sensor/wifi_signal.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
platform: wifi_signal
|
||||||
|
name: "${name} WiFi Signal"
|
||||||
|
update_interval: 60s
|
||||||
3
common/switch/restart.yaml
Normal file
3
common/switch/restart.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
platform: restart
|
||||||
|
name: ${name} Restart
|
||||||
3
common/switch/safe_mode.yaml
Normal file
3
common/switch/safe_mode.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
platform: safe_mode
|
||||||
|
name: ${name} Restart (Safe Mode)
|
||||||
3
common/switch/shutdown.yaml
Normal file
3
common/switch/shutdown.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
platform: shutdown
|
||||||
|
name: ${name} Shutdown
|
||||||
6
common/text_sensor/debug.yaml
Normal file
6
common/text_sensor/debug.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
platform: debug
|
||||||
|
device:
|
||||||
|
name: "${name} Device Info"
|
||||||
|
reset_reason:
|
||||||
|
name: "${name} Reset Reason"
|
||||||
4
common/text_sensor/ethernet_info.yaml
Normal file
4
common/text_sensor/ethernet_info.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
platform: ethernet_info
|
||||||
|
ip_address:
|
||||||
|
name: ${name} IP Address
|
||||||
7
common/text_sensor/git_ref.yaml
Normal file
7
common/text_sensor/git_ref.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
platform: git_ref
|
||||||
|
name: "${name} Git Ref"
|
||||||
|
long: true
|
||||||
|
all: true
|
||||||
|
abbrev: 16
|
||||||
|
dirty: "-dirty"
|
||||||
3
common/text_sensor/version.yaml
Normal file
3
common/text_sensor/version.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
platform: version
|
||||||
|
name: "${name} Version"
|
||||||
13
common/text_sensor/wifi_info.yaml
Normal file
13
common/text_sensor/wifi_info.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
platform: wifi_info
|
||||||
|
ip_address:
|
||||||
|
name: ${name} IP Address
|
||||||
|
icon: mdi:ip-network
|
||||||
|
#ssid:
|
||||||
|
# name: ${name} SSID
|
||||||
|
#bssid:
|
||||||
|
# name: ${name} BSSID
|
||||||
|
mac_address:
|
||||||
|
name: ${name} MAC
|
||||||
|
#scan_results:
|
||||||
|
# name: ${name} Latest Scan Results
|
||||||
4
common/time/homeassistant.yaml
Normal file
4
common/time/homeassistant.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
platform: homeassistant
|
||||||
|
id: ha_time
|
||||||
|
timezone: Europe/Bratislava
|
||||||
7
common/wifi.yaml
Normal file
7
common/wifi.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
wifi:
|
||||||
|
networks:
|
||||||
|
- ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
||||||
|
# enable_btm: true
|
||||||
|
# enable_rrm: true
|
||||||
10
common/wifi_dev.yaml
Normal file
10
common/wifi_dev.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
wifi:
|
||||||
|
networks:
|
||||||
|
- ssid: TEST
|
||||||
|
password: test'test
|
||||||
|
# enable_btm: true
|
||||||
|
# enable_rrm: true
|
||||||
|
ap:
|
||||||
|
ssid: TEST
|
||||||
|
password: testtest
|
||||||
12
compile_prod.sh
Executable file
12
compile_prod.sh
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export ESPHOME_IS_HA_ADDON=true
|
||||||
|
|
||||||
|
while IFS=, read -r device
|
||||||
|
do
|
||||||
|
esphome compile ${device}.yaml
|
||||||
|
# esphome upload ${device}.yaml --device ${device}.local
|
||||||
|
# esphome run ${device}.yaml
|
||||||
|
done < devices_dev.csv
|
||||||
|
# done < devices_prod.csv
|
||||||
|
#done < devices_nspanel.csv
|
||||||
24
components/bm8563/__init__.py
Normal file
24
components/bm8563/__init__.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import i2c
|
||||||
|
from esphome.const import CONF_ID, CONF_SLEEP_DURATION
|
||||||
|
|
||||||
|
DEPENDENCIES = ['i2c']
|
||||||
|
|
||||||
|
CONF_I2C_ADDR = 0x51
|
||||||
|
|
||||||
|
bm8563 = cg.esphome_ns.namespace('bm8563')
|
||||||
|
BM8563 = bm8563.class_('BM8563', cg.Component, i2c.I2CDevice)
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.Schema({
|
||||||
|
cv.GenerateID(): cv.declare_id(BM8563),
|
||||||
|
cv.Optional(CONF_SLEEP_DURATION): cv.positive_time_period_seconds,
|
||||||
|
}).extend(cv.COMPONENT_SCHEMA).extend(i2c.i2c_device_schema(CONF_I2C_ADDR))
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
if CONF_SLEEP_DURATION in config:
|
||||||
|
cg.add(var.set_sleep_duration(config[CONF_SLEEP_DURATION]))
|
||||||
|
yield cg.register_component(var, config)
|
||||||
|
yield i2c.register_i2c_device(var, config)
|
||||||
|
|
||||||
242
components/bm8563/bm8563.cpp
Normal file
242
components/bm8563/bm8563.cpp
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "esphome/components/i2c/i2c_bus.h"
|
||||||
|
#include "bm8563.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace bm8563 {
|
||||||
|
|
||||||
|
static const char *TAG = "bm8563.sensor";
|
||||||
|
|
||||||
|
void BM8563::setup(){
|
||||||
|
this->write_byte_16(0,0);
|
||||||
|
this->setupComplete = true;
|
||||||
|
if (this->sleep_duration_.has_value()) {
|
||||||
|
SetAlarmIRQ(*this->sleep_duration_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BM8563::loop(){
|
||||||
|
// if(!this->setupComplete){
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// BM8563_TimeTypeDef BM8563_TimeStruct;
|
||||||
|
// getTime(&BM8563_TimeStruct);
|
||||||
|
// this->publish_state(BM8563_TimeStruct.seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BM8563::dump_config(){
|
||||||
|
ESP_LOGCONFIG(TAG, "BM8563:");
|
||||||
|
ESP_LOGCONFIG(TAG, " Address: 0x%02X", this->address_);
|
||||||
|
ESP_LOGCONFIG(TAG, " setupComplete: %s", this->setupComplete ? "true" : "false");
|
||||||
|
if (this->sleep_duration_.has_value()) {
|
||||||
|
uint32_t duration = *this->sleep_duration_;
|
||||||
|
ESP_LOGCONFIG(TAG, " Sleep Duration: %u ms", duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BM8563::set_sleep_duration(uint32_t time_s) {
|
||||||
|
this->sleep_duration_ = uint64_t(time_s);
|
||||||
|
if (this->sleep_duration_.has_value()) {
|
||||||
|
SetAlarmIRQ(*this->sleep_duration_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BM8563::getVoltLow() {
|
||||||
|
uint8_t data = ReadReg(0x02);
|
||||||
|
return data & 0x80; // RTCC_VLSEC_MASK
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BM8563::bcd2ToByte(uint8_t value) {
|
||||||
|
uint8_t tmp = 0;
|
||||||
|
tmp = ((uint8_t)(value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10;
|
||||||
|
return (tmp + (value & (uint8_t)0x0F));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BM8563::byteToBcd2(uint8_t value) {
|
||||||
|
uint8_t bcdhigh = 0;
|
||||||
|
|
||||||
|
while (value >= 10) {
|
||||||
|
bcdhigh++;
|
||||||
|
value -= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((uint8_t)(bcdhigh << 4) | value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BM8563::getTime(BM8563_TimeTypeDef* BM8563_TimeStruct) {
|
||||||
|
uint8_t buf[3] = {0};
|
||||||
|
|
||||||
|
this->read_register(0x02, buf, 3);
|
||||||
|
|
||||||
|
BM8563_TimeStruct->seconds = bcd2ToByte(buf[0] & 0x7f);
|
||||||
|
BM8563_TimeStruct->minutes = bcd2ToByte(buf[1] & 0x7f);
|
||||||
|
BM8563_TimeStruct->hours = bcd2ToByte(buf[2] & 0x3f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BM8563::setTime(BM8563_TimeTypeDef* BM8563_TimeStruct) {
|
||||||
|
if (BM8563_TimeStruct == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint8_t buf[3] = {byteToBcd2(BM8563_TimeStruct->seconds), byteToBcd2(BM8563_TimeStruct->minutes), byteToBcd2(BM8563_TimeStruct->hours)};
|
||||||
|
|
||||||
|
this->write_register(0x02, buf, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BM8563::getDate(BM8563_DateTypeDef* BM8563_DateStruct) {
|
||||||
|
uint8_t buf[4] = {0};
|
||||||
|
this->read_register(0x05, buf, 4);
|
||||||
|
|
||||||
|
BM8563_DateStruct->date = bcd2ToByte(buf[0] & 0x3f);
|
||||||
|
BM8563_DateStruct->weekDay = bcd2ToByte(buf[1] & 0x07);
|
||||||
|
BM8563_DateStruct->month = bcd2ToByte(buf[2] & 0x1f);
|
||||||
|
|
||||||
|
if (buf[2] & 0x80) {
|
||||||
|
BM8563_DateStruct->year = 1900 + bcd2ToByte(buf[3] & 0xff);
|
||||||
|
} else {
|
||||||
|
BM8563_DateStruct->year = 2000 + bcd2ToByte(buf[3] & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BM8563::setDate(BM8563_DateTypeDef* BM8563_DateStruct) {
|
||||||
|
if (BM8563_DateStruct == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint8_t buf[4] = {byteToBcd2(BM8563_DateStruct->date), byteToBcd2(BM8563_DateStruct->weekDay), 0, byteToBcd2((uint8_t)(BM8563_DateStruct->year % 100))};
|
||||||
|
|
||||||
|
|
||||||
|
if (BM8563_DateStruct->year < 2000) {
|
||||||
|
buf[3] = byteToBcd2(BM8563_DateStruct->month) | 0x80;
|
||||||
|
} else {
|
||||||
|
buf[3] = byteToBcd2(BM8563_DateStruct->month) | 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->write_register(0x05, buf, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BM8563::WriteReg(uint8_t reg, uint8_t data) {
|
||||||
|
this->write_byte(reg, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BM8563::ReadReg(uint8_t reg) {
|
||||||
|
uint8_t data;
|
||||||
|
this->read_register(reg, &data, 1);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BM8563::SetAlarmIRQ(int afterSeconds) {
|
||||||
|
uint8_t reg_value = 0;
|
||||||
|
reg_value = ReadReg(0x01);
|
||||||
|
|
||||||
|
if (afterSeconds < 0) {
|
||||||
|
reg_value &= ~(1 << 0);
|
||||||
|
WriteReg(0x01, reg_value);
|
||||||
|
reg_value = 0x03;
|
||||||
|
WriteReg(0x0E, reg_value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t type_value = 2;
|
||||||
|
uint8_t div = 1;
|
||||||
|
if (afterSeconds > 255) {
|
||||||
|
div = 60;
|
||||||
|
type_value = 0x83;
|
||||||
|
} else {
|
||||||
|
type_value = 0x82;
|
||||||
|
}
|
||||||
|
|
||||||
|
afterSeconds = (afterSeconds / div) & 0xFF;
|
||||||
|
WriteReg(0x0F, afterSeconds);
|
||||||
|
WriteReg(0x0E, type_value);
|
||||||
|
|
||||||
|
reg_value |= (1 << 0);
|
||||||
|
reg_value &= ~(1 << 7);
|
||||||
|
WriteReg(0x01, reg_value);
|
||||||
|
return afterSeconds * div;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BM8563::SetAlarmIRQ(const BM8563_TimeTypeDef &BM8563_TimeStruct) {
|
||||||
|
uint8_t irq_enable = false;
|
||||||
|
uint8_t out_buf[4] = {0x80, 0x80, 0x80, 0x80};
|
||||||
|
|
||||||
|
if (BM8563_TimeStruct.minutes >= 0) {
|
||||||
|
irq_enable = true;
|
||||||
|
out_buf[0] = byteToBcd2(BM8563_TimeStruct.minutes) & 0x7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BM8563_TimeStruct.hours >= 0) {
|
||||||
|
irq_enable = true;
|
||||||
|
out_buf[1] = byteToBcd2(BM8563_TimeStruct.hours) & 0x3f;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_buf[2] = 0x00;
|
||||||
|
out_buf[3] = 0x00;
|
||||||
|
|
||||||
|
uint8_t reg_value = ReadReg(0x01);
|
||||||
|
|
||||||
|
if (irq_enable) {
|
||||||
|
reg_value |= (1 << 1);
|
||||||
|
} else {
|
||||||
|
reg_value &= ~(1 << 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
WriteReg(0x09 + i, out_buf[i]);
|
||||||
|
}
|
||||||
|
WriteReg(0x01, reg_value);
|
||||||
|
|
||||||
|
return irq_enable ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BM8563::SetAlarmIRQ(const BM8563_DateTypeDef &BM8563_DateStruct, const BM8563_TimeTypeDef &BM8563_TimeStruct) {
|
||||||
|
uint8_t irq_enable = false;
|
||||||
|
uint8_t out_buf[4] = {0x80, 0x80, 0x80, 0x80};
|
||||||
|
|
||||||
|
if (BM8563_TimeStruct.minutes >= 0) {
|
||||||
|
irq_enable = true;
|
||||||
|
out_buf[0] = byteToBcd2(BM8563_TimeStruct.minutes) & 0x7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BM8563_TimeStruct.hours >= 0) {
|
||||||
|
irq_enable = true;
|
||||||
|
out_buf[1] = byteToBcd2(BM8563_TimeStruct.hours) & 0x3f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BM8563_DateStruct.date >= 0) {
|
||||||
|
irq_enable = true;
|
||||||
|
out_buf[2] = byteToBcd2(BM8563_DateStruct.date) & 0x3f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BM8563_DateStruct.weekDay >= 0) {
|
||||||
|
irq_enable = true;
|
||||||
|
out_buf[3] = byteToBcd2(BM8563_DateStruct.weekDay) & 0x07;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t reg_value = ReadReg(0x01);
|
||||||
|
|
||||||
|
if (irq_enable) {
|
||||||
|
reg_value |= (1 << 1);
|
||||||
|
} else {
|
||||||
|
reg_value &= ~(1 << 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
WriteReg(0x09 + i, out_buf[i]);
|
||||||
|
}
|
||||||
|
WriteReg(0x01, reg_value);
|
||||||
|
|
||||||
|
return irq_enable ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BM8563::clearIRQ() {
|
||||||
|
uint8_t data = ReadReg(0x01);
|
||||||
|
WriteReg(0x01, data & 0xf3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BM8563::disableIRQ() {
|
||||||
|
clearIRQ();
|
||||||
|
uint8_t data = ReadReg(0x01);
|
||||||
|
WriteReg(0x01, data & 0xfC);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace bm8563
|
||||||
|
} // namespace esphome
|
||||||
62
components/bm8563/bm8563.h
Normal file
62
components/bm8563/bm8563.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/components/sensor/sensor.h"
|
||||||
|
#include "esphome/components/i2c/i2c.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace bm8563 {
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int8_t hours;
|
||||||
|
int8_t minutes;
|
||||||
|
int8_t seconds;
|
||||||
|
} BM8563_TimeTypeDef;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int8_t weekDay;
|
||||||
|
int8_t month;
|
||||||
|
int8_t date;
|
||||||
|
int16_t year;
|
||||||
|
} BM8563_DateTypeDef;
|
||||||
|
|
||||||
|
class BM8563 : public Component, public i2c::I2CDevice {
|
||||||
|
public:
|
||||||
|
void setup() override;
|
||||||
|
void loop() override;
|
||||||
|
void dump_config() override;
|
||||||
|
|
||||||
|
void set_sleep_duration(uint32_t time_ms);
|
||||||
|
|
||||||
|
bool getVoltLow();
|
||||||
|
|
||||||
|
void getTime(BM8563_TimeTypeDef* BM8563_TimeStruct);
|
||||||
|
void getDate(BM8563_DateTypeDef* BM8563_DateStruct);
|
||||||
|
|
||||||
|
void setTime(BM8563_TimeTypeDef* BM8563_TimeStruct);
|
||||||
|
void setDate(BM8563_DateTypeDef* BM8563_DateStruct);
|
||||||
|
|
||||||
|
int SetAlarmIRQ(int afterSeconds);
|
||||||
|
int SetAlarmIRQ(const BM8563_TimeTypeDef &BM8563_TimeStruct);
|
||||||
|
int SetAlarmIRQ(const BM8563_DateTypeDef &BM8563_DateStruct, const BM8563_TimeTypeDef &BM8563_TimeStruct);
|
||||||
|
|
||||||
|
void clearIRQ();
|
||||||
|
void disableIRQ();
|
||||||
|
|
||||||
|
void WriteReg(uint8_t reg, uint8_t data);
|
||||||
|
uint8_t ReadReg(uint8_t reg);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t bcd2ToByte(uint8_t value);
|
||||||
|
uint8_t byteToBcd2(uint8_t value);
|
||||||
|
|
||||||
|
uint8_t trdata[7];
|
||||||
|
optional<uint64_t> sleep_duration_;
|
||||||
|
bool setupComplete;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace bm8563
|
||||||
|
} // namespace esphome
|
||||||
30
components/m5stack_4relay/__init__.py
Normal file
30
components/m5stack_4relay/__init__.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import i2c
|
||||||
|
from esphome.const import CONF_ID
|
||||||
|
|
||||||
|
DEPENDENCIES = ["i2c"]
|
||||||
|
MULTI_CONF = True
|
||||||
|
AUTO_LOAD = ["switch"]
|
||||||
|
CODEOWNERS = ["@brotherdust"]
|
||||||
|
|
||||||
|
m5stack_4relay_ns = cg.esphome_ns.namespace("m5stack_4relay")
|
||||||
|
M5STACK4RELAYOutput = m5stack_4relay_ns.class_(
|
||||||
|
"M5STACK4RELAYSwitchComponent", cg.Component, i2c.I2CDevice
|
||||||
|
)
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = (
|
||||||
|
cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(M5STACK4RELAYOutput),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.extend(cv.COMPONENT_SCHEMA)
|
||||||
|
.extend(i2c.i2c_device_schema(0x26))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
yield cg.register_component(var, config)
|
||||||
|
yield i2c.register_i2c_device(var, config)
|
||||||
49
components/m5stack_4relay/m5stack_4relay.cpp
Normal file
49
components/m5stack_4relay/m5stack_4relay.cpp
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#include "m5stack_4relay.h"
|
||||||
|
#include <bitset>
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
namespace esphome {
|
||||||
|
namespace m5stack_4relay {
|
||||||
|
static const char *const TAG = "m5stack_4relay.switch";
|
||||||
|
|
||||||
|
void M5STACK4RELAYSwitchComponent::setup() {
|
||||||
|
ESP_LOGCONFIG(TAG, "Setting up M5STACK4RELAY (0x%02X)...", this->address_);
|
||||||
|
component_status = 0;
|
||||||
|
get_status(&component_status);
|
||||||
|
ESP_LOGD(TAG, "Setup Status 0x%02X", component_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
M5STACK4RELAYChannel *M5STACK4RELAYSwitchComponent::create_channel(uint8_t channel) {
|
||||||
|
return new M5STACK4RELAYChannel(this, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void M5STACK4RELAYSwitchComponent::get_status(uint8_t *state) { this->read_byte(RELAY_CONTROL_REG); }
|
||||||
|
|
||||||
|
bool M5STACK4RELAYSwitchComponent::set_channel_value_(uint8_t channel, bool state) {
|
||||||
|
get_status(&component_status);
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Current status 0x%02X", component_status);
|
||||||
|
ESP_LOGD(TAG, "Desired channel: %1u", channel);
|
||||||
|
ESP_LOGD(TAG, "Desired state: %1u", state);
|
||||||
|
|
||||||
|
channel = 3 - channel;
|
||||||
|
if (state) {
|
||||||
|
component_status |= (1u << channel);
|
||||||
|
} else {
|
||||||
|
component_status &= ~(1u << channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "New status 0x%02X", component_status);
|
||||||
|
|
||||||
|
return this->write_byte(this->address_, RELAY_CONTROL_REG, component_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void M5STACK4RELAYChannel::write_state(bool state) {
|
||||||
|
if (!this->set_channel_value_(this->channel_, state)) {
|
||||||
|
publish_state(false);
|
||||||
|
} else {
|
||||||
|
publish_state(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace m5stack_4relay
|
||||||
|
} // namespace esphome
|
||||||
49
components/m5stack_4relay/m5stack_4relay.h
Normal file
49
components/m5stack_4relay/m5stack_4relay.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/i2c/i2c.h"
|
||||||
|
#include "esphome/components/switch/switch.h"
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace m5stack_4relay {
|
||||||
|
|
||||||
|
class M5STACK4RELAYSwitchComponent;
|
||||||
|
class M5STACK4RELAYChannel : public switch_::Switch {
|
||||||
|
public:
|
||||||
|
M5STACK4RELAYChannel(M5STACK4RELAYSwitchComponent *parent, uint8_t channel) : parent_(parent), channel_(channel) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void write_state(bool state) override;
|
||||||
|
|
||||||
|
M5STACK4RELAYSwitchComponent *parent_;
|
||||||
|
uint8_t channel_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class M5STACK4RELAYSwitchComponent : public Component, public i2c::I2CDevice {
|
||||||
|
public:
|
||||||
|
const uint8_t MODE_CONTROL_REG = 0x10;
|
||||||
|
const uint8_t RELAY_CONTROL_REG = 0x11;
|
||||||
|
uint8_t component_status;
|
||||||
|
M5STACK4RELAYSwitchComponent() {}
|
||||||
|
M5STACK4RELAYChannel *create_channel(uint8_t channel);
|
||||||
|
|
||||||
|
void setup() override;
|
||||||
|
float get_setup_priority() const override { return setup_priority::HARDWARE; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend M5STACK4RELAYChannel;
|
||||||
|
|
||||||
|
void get_status(uint8_t *state);
|
||||||
|
|
||||||
|
bool set_channel_value_(uint8_t channel, bool state);
|
||||||
|
|
||||||
|
bool read_bytes_(uint8_t a_register, uint8_t *data, uint8_t len, uint32_t conversion) {
|
||||||
|
return this->raw_receive(this->address_, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
float value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace m5stack_4relay
|
||||||
|
} // namespace esphome
|
||||||
25
components/m5stack_4relay/switch.py
Normal file
25
components/m5stack_4relay/switch.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import esphome.config_validation as cv
|
||||||
|
import esphome.codegen as cg
|
||||||
|
from esphome.components import switch
|
||||||
|
from esphome.const import CONF_ID, CONF_CHANNEL
|
||||||
|
from . import M5STACK4RELAYOutput, m5stack_4relay_ns
|
||||||
|
|
||||||
|
DEPENDENCIES = ["m5stack_4relay"]
|
||||||
|
|
||||||
|
M5STACK4RELAYChannel = m5stack_4relay_ns.class_("M5STACK4RELAYChannel", switch.Switch)
|
||||||
|
CONF_M5STACK_4RELAY_ID = "m5stack_4relay_id"
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = switch.SWITCH_SCHEMA.extend(
|
||||||
|
{
|
||||||
|
cv.Required(CONF_ID): cv.declare_id(M5STACK4RELAYChannel),
|
||||||
|
cv.GenerateID(CONF_M5STACK_4RELAY_ID): cv.use_id(M5STACK4RELAYOutput),
|
||||||
|
cv.Required(CONF_CHANNEL): cv.int_range(min=0, max=3),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
paren = await cg.get_variable(config[CONF_M5STACK_4RELAY_ID])
|
||||||
|
rhs = paren.create_channel(config[CONF_CHANNEL])
|
||||||
|
var = cg.Pvariable(config[CONF_ID], rhs)
|
||||||
|
await switch.register_switch(var, config)
|
||||||
1
components/notes.txt
Normal file
1
components/notes.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
https://github.com/TomG736/esphome-BM8563
|
||||||
28
components/pca9536d/README.md
Normal file
28
components/pca9536d/README.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# PCA9536D i2c I/O expander
|
||||||
|
|
||||||
|
Requires a configured i2c bus
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```yaml
|
||||||
|
pca9536d:
|
||||||
|
- id: my_pca
|
||||||
|
|
||||||
|
switch:
|
||||||
|
- platform: gpio
|
||||||
|
pin:
|
||||||
|
pca9536d: my_pca
|
||||||
|
number: 0
|
||||||
|
id: relay
|
||||||
|
|
||||||
|
binary_sensor:
|
||||||
|
- platform: gpio
|
||||||
|
pin:
|
||||||
|
pca9536d: my_pca
|
||||||
|
number: 1
|
||||||
|
id: button
|
||||||
|
```
|
||||||
|
|
||||||
|
# Optional parameters
|
||||||
|
|
||||||
|
`address:` defaults to 0x41
|
||||||
|
|
||||||
69
components/pca9536d/__init__.py
Normal file
69
components/pca9536d/__init__.py
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome import pins
|
||||||
|
from esphome.components import i2c
|
||||||
|
from esphome.const import (
|
||||||
|
CONF_ID,
|
||||||
|
CONF_INPUT,
|
||||||
|
CONF_INVERTED,
|
||||||
|
CONF_NUMBER,
|
||||||
|
CONF_MODE,
|
||||||
|
CONF_OUTPUT,
|
||||||
|
)
|
||||||
|
|
||||||
|
DEPENDENCIES = ["i2c"]
|
||||||
|
MULTI_CONF = True
|
||||||
|
|
||||||
|
CONF_PCA9536D = "pca9536d"
|
||||||
|
|
||||||
|
pca9536d_ns = cg.esphome_ns.namespace("pca9536d")
|
||||||
|
PCA9536DGPIOMode = pca9536d_ns.enum("PCA9536DGPIOMode")
|
||||||
|
|
||||||
|
PCA9536D = pca9536d_ns.class_("PCA9536D", cg.Component, i2c.I2CDevice)
|
||||||
|
PCA9536DGPIOPin = pca9536d_ns.class_("PCA9536DGPIOPin", cg.GPIOPin)
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.COMPONENT_SCHEMA.extend(
|
||||||
|
{
|
||||||
|
cv.Required(CONF_ID): cv.declare_id(PCA9536D),
|
||||||
|
}
|
||||||
|
).extend(i2c.i2c_device_schema(0x41))
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
await cg.register_component(var, config)
|
||||||
|
await i2c.register_i2c_device(var, config)
|
||||||
|
|
||||||
|
def validate_mode(value):
|
||||||
|
if not (value[CONF_INPUT] or value[CONF_OUTPUT]):
|
||||||
|
raise cv.Invalid("Mode must be either input or output")
|
||||||
|
if value[CONF_INPUT] and value[CONF_OUTPUT]:
|
||||||
|
raise cv.Invalid("Mode must be either input or output")
|
||||||
|
return value
|
||||||
|
|
||||||
|
PCA9536D_PIN_SCHEMA = cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(PCA9536DGPIOPin),
|
||||||
|
cv.Required(CONF_PCA9536D): cv.use_id(PCA9536D),
|
||||||
|
cv.Required(CONF_NUMBER): cv.int_range(min=0, max=7),
|
||||||
|
cv.Optional(CONF_MODE, default={}): cv.All(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_INPUT, default=False): cv.boolean,
|
||||||
|
cv.Optional(CONF_OUTPUT, default=False): cv.boolean,
|
||||||
|
},
|
||||||
|
validate_mode,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
@pins.PIN_SCHEMA_REGISTRY.register(CONF_PCA9536D, PCA9536D_PIN_SCHEMA)
|
||||||
|
async def pca9536d_pin_to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
parent = await cg.get_variable(config[CONF_PCA9536D])
|
||||||
|
|
||||||
|
cg.add(var.set_parent(parent))
|
||||||
|
cg.add(var.set_pin(config[CONF_NUMBER]))
|
||||||
|
cg.add(var.set_inverted(config[CONF_INVERTED]))
|
||||||
|
cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE])))
|
||||||
|
return var
|
||||||
|
|
||||||
BIN
components/pca9536d/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
components/pca9536d/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
108
components/pca9536d/pca9536d.cpp
Normal file
108
components/pca9536d/pca9536d.cpp
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
#include "pca9536d.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace pca9536d {
|
||||||
|
|
||||||
|
static const char *TAG = "pca9536d";
|
||||||
|
|
||||||
|
void PCA9536D::setup() {
|
||||||
|
ESP_LOGCONFIG(TAG, "Setting up PCA9536D...");
|
||||||
|
if (!this->read_gpio_()) {
|
||||||
|
ESP_LOGE(TAG, "PCA9536D not available under 0x%02X", this->address_);
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->write_gpio_();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PCA9536D::dump_config() {
|
||||||
|
ESP_LOGCONFIG(TAG, "PCA9536D:");
|
||||||
|
LOG_I2C_DEVICE(this)
|
||||||
|
if (this->is_failed())
|
||||||
|
ESP_LOGE(TAG, "Communication with PCA9536D failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PCA9536D::digital_read(uint8_t pin) {
|
||||||
|
this->read_gpio_();
|
||||||
|
return this->inputs_ & (1 << pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PCA9536D::digital_write(uint8_t pin, bool value) {
|
||||||
|
if (value)
|
||||||
|
this->outputs_ |= (1 << pin);
|
||||||
|
else
|
||||||
|
this->outputs_ &= ~(1 << pin);
|
||||||
|
this->write_gpio_();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PCA9536D::set_pin_mode(uint8_t pin, uint8_t mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case gpio::FLAG_INPUT:
|
||||||
|
this->modes_ |= 1 << pin;
|
||||||
|
break;
|
||||||
|
case gpio::FLAG_OUTPUT:
|
||||||
|
this->modes_ &= ~(1 << pin);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this->set_modes_();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PCA9536D::read_gpio_() {
|
||||||
|
if (this->is_failed())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint8_t data;
|
||||||
|
if (!this->read_bytes(0, &data, 1)) {
|
||||||
|
this->status_set_warning();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->inputs_ = data;
|
||||||
|
this->status_clear_warning();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PCA9536D::write_gpio_() {
|
||||||
|
if (this->is_failed())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint8_t data = this->outputs_;
|
||||||
|
if (!this->write_bytes(1, &data, 1)) {
|
||||||
|
this->status_set_warning();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->status_clear_warning();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PCA9536D::set_modes_() {
|
||||||
|
if (this->is_failed())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint8_t data = this->modes_;
|
||||||
|
if (!this->write_bytes(3, &data, 1)) {
|
||||||
|
this->status_set_warning();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->status_clear_warning();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PCA9536DGPIOPin::setup() { this->pin_mode(this->flags_); }
|
||||||
|
|
||||||
|
bool PCA9536DGPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
|
||||||
|
|
||||||
|
void PCA9536DGPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
|
||||||
|
|
||||||
|
void PCA9536DGPIOPin::pin_mode(gpio::Flags flags) { this->parent_->set_pin_mode(this->pin_, flags); }
|
||||||
|
|
||||||
|
std::string PCA9536DGPIOPin::dump_summary() const {
|
||||||
|
return str_sprintf("%u via PCA9536D", pin_);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace pca9536d
|
||||||
|
} // namespace esphome
|
||||||
52
components/pca9536d/pca9536d.h
Normal file
52
components/pca9536d/pca9536d.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/core/hal.h"
|
||||||
|
#include "esphome/components/i2c/i2c.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace pca9536d {
|
||||||
|
|
||||||
|
class PCA9536D: public Component, public i2c::I2CDevice {
|
||||||
|
public:
|
||||||
|
void setup() override;
|
||||||
|
float get_setup_priority() const { return setup_priority::IO; }
|
||||||
|
void dump_config() override;
|
||||||
|
|
||||||
|
bool digital_read(uint8_t pin);
|
||||||
|
void digital_write(uint8_t pin, bool value);
|
||||||
|
void set_pin_mode(uint8_t pin, uint8_t mode);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool read_gpio_();
|
||||||
|
bool write_gpio_();
|
||||||
|
bool set_modes_();
|
||||||
|
|
||||||
|
// pin modes - 0 means output, 1 means input
|
||||||
|
uint8_t modes_{0xff};
|
||||||
|
uint8_t outputs_{0x00};
|
||||||
|
uint8_t inputs_{0x00};
|
||||||
|
};
|
||||||
|
|
||||||
|
class PCA9536DGPIOPin : public GPIOPin {
|
||||||
|
public:
|
||||||
|
void setup() override;
|
||||||
|
void pin_mode(gpio::Flags flags) override;
|
||||||
|
bool digital_read() override;
|
||||||
|
void digital_write(bool value) override;
|
||||||
|
std::string dump_summary() const override;
|
||||||
|
|
||||||
|
void set_parent(PCA9536D *parent) { parent_ = parent; }
|
||||||
|
void set_pin(uint8_t pin) { pin_ = pin; }
|
||||||
|
void set_inverted(bool inverted) { inverted_ = inverted; }
|
||||||
|
void set_flags(gpio::Flags flags) { flags_ = flags; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PCA9536D *parent_;
|
||||||
|
uint8_t pin_;
|
||||||
|
bool inverted_;
|
||||||
|
gpio::Flags flags_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace pca9536d
|
||||||
|
} // namespace esphome
|
||||||
57
components/pca9554_2/__init__.py
Normal file
57
components/pca9554_2/__init__.py
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome import pins
|
||||||
|
from esphome.components import i2c
|
||||||
|
from esphome.const import CONF_ID, CONF_NUMBER, CONF_MODE, CONF_INVERTED
|
||||||
|
|
||||||
|
DEPENDENCIES = ['i2c']
|
||||||
|
MULTI_CONF = True
|
||||||
|
|
||||||
|
pca9554_ns = cg.esphome_ns.namespace('pca9554')
|
||||||
|
PCA9554GPIOMode = pca9554_ns.enum('PCA9554GPIOMode')
|
||||||
|
PCF8674_GPIO_MODES = {
|
||||||
|
'INPUT': PCA9554GPIOMode.PCA9554_INPUT,
|
||||||
|
'OUTPUT': PCA9554GPIOMode.PCA9554_OUTPUT,
|
||||||
|
}
|
||||||
|
|
||||||
|
PCA9554Component = pca9554_ns.class_('PCA9554Component', cg.Component, i2c.I2CDevice)
|
||||||
|
PCA9554GPIOPin = pca9554_ns.class_('PCA9554GPIOPin', cg.GPIOPin)
|
||||||
|
|
||||||
|
CONF_PCA9554 = 'pca9554'
|
||||||
|
CONF_PCF8575 = 'pcf8575'
|
||||||
|
CONFIG_SCHEMA = cv.Schema({
|
||||||
|
cv.Required(CONF_ID): cv.declare_id(PCA9554Component),
|
||||||
|
cv.Optional(CONF_PCF8575, default=False): cv.boolean,
|
||||||
|
}).extend(cv.COMPONENT_SCHEMA).extend(i2c.i2c_device_schema(0x20))
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
yield cg.register_component(var, config)
|
||||||
|
yield i2c.register_i2c_device(var, config)
|
||||||
|
cg.add(var.set_pcf8575(config[CONF_PCF8575]))
|
||||||
|
|
||||||
|
|
||||||
|
def validate_pca9554_gpio_mode(value):
|
||||||
|
value = cv.string(value)
|
||||||
|
return cv.enum(PCF8674_GPIO_MODES, upper=True)(value)
|
||||||
|
|
||||||
|
|
||||||
|
PCA9554_OUTPUT_PIN_SCHEMA = cv.Schema({
|
||||||
|
cv.Required(CONF_PCA9554): cv.use_id(PCA9554Component),
|
||||||
|
cv.Required(CONF_NUMBER): cv.int_,
|
||||||
|
cv.Optional(CONF_MODE, default="OUTPUT"): validate_pca9554_gpio_mode,
|
||||||
|
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||||
|
})
|
||||||
|
PCA9554_INPUT_PIN_SCHEMA = cv.Schema({
|
||||||
|
cv.Required(CONF_PCA9554): cv.use_id(PCA9554Component),
|
||||||
|
cv.Required(CONF_NUMBER): cv.int_,
|
||||||
|
cv.Optional(CONF_MODE, default="INPUT"): validate_pca9554_gpio_mode,
|
||||||
|
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@pins.PIN_SCHEMA_REGISTRY.register('pca9554', (PCA9554_OUTPUT_PIN_SCHEMA, PCA9554_INPUT_PIN_SCHEMA))
|
||||||
|
def pca9554_pin_to_code(config):
|
||||||
|
parent = yield cg.get_variable(config[CONF_PCA9554])
|
||||||
|
yield PCA9554GPIOPin.new(parent, config[CONF_NUMBER], config[CONF_MODE], config[CONF_INVERTED])
|
||||||
96
components/pca9554_2/pca9554.cpp
Normal file
96
components/pca9554_2/pca9554.cpp
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
#include "pca9554.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace pca9554 {
|
||||||
|
|
||||||
|
static const char *TAG = "pca9554";
|
||||||
|
|
||||||
|
void PCA9554Component::setup() {
|
||||||
|
ESP_LOGCONFIG(TAG, "Setting up PCA9554...");
|
||||||
|
if (!this->read_gpio_()) {
|
||||||
|
ESP_LOGE(TAG, "PCA9554 not available under 0x%02X", this->address_);
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->write_gpio_();
|
||||||
|
this->read_gpio_();
|
||||||
|
}
|
||||||
|
void PCA9554Component::dump_config() {
|
||||||
|
ESP_LOGCONFIG(TAG, "PCA9554:");
|
||||||
|
LOG_I2C_DEVICE(this)
|
||||||
|
if (this->is_failed()) {
|
||||||
|
ESP_LOGE(TAG, "Communication with PCA9554 failed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool PCA9554Component::digital_read(uint8_t pin) {
|
||||||
|
this->read_gpio_();
|
||||||
|
return this->input_mask_ & (1 << pin);
|
||||||
|
}
|
||||||
|
void PCA9554Component::digital_write(uint8_t pin, bool value) {
|
||||||
|
if (value) {
|
||||||
|
this->output_mask_ |= (1 << pin);
|
||||||
|
} else {
|
||||||
|
this->output_mask_ &= ~(1 << pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->write_gpio_();
|
||||||
|
}
|
||||||
|
void PCA9554Component::pin_mode(uint8_t pin, uint8_t mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case PCA9554_OUTPUT:
|
||||||
|
// Clear mode mask bit
|
||||||
|
this->mode_mask_ &= ~(1 << pin);
|
||||||
|
// Write GPIO to enable input mode
|
||||||
|
this->write_gpio_();
|
||||||
|
break;
|
||||||
|
case PCA9554_INPUT:
|
||||||
|
// Set mode mask bit
|
||||||
|
this->mode_mask_ |= 1 << pin;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool PCA9554Component::read_gpio_() {
|
||||||
|
if (this->is_failed())
|
||||||
|
return false;
|
||||||
|
bool success;
|
||||||
|
uint8_t data[2];
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
this->status_set_warning();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this->status_clear_warning();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool PCA9554Component::write_gpio_() {
|
||||||
|
if (this->is_failed())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint16_t value = 0;
|
||||||
|
// Pins in OUTPUT mode and where pin is HIGH.
|
||||||
|
value |= this->mode_mask_ & this->output_mask_;
|
||||||
|
// Pins in INPUT mode must also be set here
|
||||||
|
value |= ~this->mode_mask_;
|
||||||
|
|
||||||
|
uint8_t data[2];
|
||||||
|
data[0] = value;
|
||||||
|
data[1] = value >> 8;
|
||||||
|
|
||||||
|
this->status_clear_warning();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
float PCA9554Component::get_setup_priority() const { return setup_priority::IO; }
|
||||||
|
|
||||||
|
void PCA9554GPIOPin::setup() { this->pin_mode(this->mode_); }
|
||||||
|
bool PCA9554GPIOPin::digital_read() { return this->parent_->digital_read(this->pin_) != this->inverted_; }
|
||||||
|
void PCA9554GPIOPin::digital_write(bool value) { this->parent_->digital_write(this->pin_, value != this->inverted_); }
|
||||||
|
void PCA9554GPIOPin::pin_mode(uint8_t mode) { this->parent_->pin_mode(this->pin_, mode); }
|
||||||
|
PCA9554GPIOPin::PCA9554GPIOPin(PCA9554Component *parent, uint8_t pin, uint8_t mode, bool inverted)
|
||||||
|
: GPIOPin(pin, mode, inverted), parent_(parent) {}
|
||||||
|
|
||||||
|
} // namespace pca9554
|
||||||
|
} // namespace esphome
|
||||||
61
components/pca9554_2/pca9554.h
Normal file
61
components/pca9554_2/pca9554.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/core/esphal.h"
|
||||||
|
#include "esphome/components/i2c/i2c.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace pca9554 {
|
||||||
|
|
||||||
|
/// Modes for PCA9554 pins
|
||||||
|
enum PCA9554GPIOMode : uint8_t {
|
||||||
|
PCA9554_INPUT = INPUT,
|
||||||
|
PCA9554_OUTPUT = OUTPUT,
|
||||||
|
};
|
||||||
|
|
||||||
|
class PCA9554Component : public Component, public i2c::I2CDevice {
|
||||||
|
public:
|
||||||
|
PCA9554Component() = default;
|
||||||
|
|
||||||
|
/// Check i2c availability and setup masks
|
||||||
|
void setup() override;
|
||||||
|
/// Helper function to read the value of a pin.
|
||||||
|
bool digital_read(uint8_t pin);
|
||||||
|
/// Helper function to write the value of a pin.
|
||||||
|
void digital_write(uint8_t pin, bool value);
|
||||||
|
/// Helper function to set the pin mode of a pin.
|
||||||
|
void pin_mode(uint8_t pin, uint8_t mode);
|
||||||
|
|
||||||
|
float get_setup_priority() const override;
|
||||||
|
|
||||||
|
void dump_config() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool read_gpio_();
|
||||||
|
|
||||||
|
bool write_gpio_();
|
||||||
|
|
||||||
|
/// Mask for the pin mode - 1 means input, 0 means output
|
||||||
|
uint16_t mode_mask_{0x00};
|
||||||
|
/// The mask to write as output state - 1 means HIGH, 0 means LOW
|
||||||
|
uint16_t output_mask_{0x00};
|
||||||
|
/// The state read in read_gpio_ - 1 means HIGH, 0 means LOW
|
||||||
|
uint16_t input_mask_{0x00};
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Helper class to expose a PCA9554 pin as an internal input GPIO pin.
|
||||||
|
class PCA9554GPIOPin : public GPIOPin {
|
||||||
|
public:
|
||||||
|
PCA9554GPIOPin(PCA9554Component *parent, uint8_t pin, uint8_t mode, bool inverted = false);
|
||||||
|
|
||||||
|
void setup() override;
|
||||||
|
void pin_mode(uint8_t mode) override;
|
||||||
|
bool digital_read() override;
|
||||||
|
void digital_write(bool value) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PCA9554Component *parent_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace pca9554
|
||||||
|
} // namespace esphome
|
||||||
1
components/sim7600
Submodule
1
components/sim7600
Submodule
Submodule components/sim7600 added at d754e306ad
3
components/st7735/__init__.py
Normal file
3
components/st7735/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
|
||||||
|
st7735_ns = cg.esphome_ns.namespace('st7735')
|
||||||
BIN
components/st7735/__pycache__/__init__.cpython-36.pyc
Normal file
BIN
components/st7735/__pycache__/__init__.cpython-36.pyc
Normal file
Binary file not shown.
BIN
components/st7735/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
components/st7735/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
components/st7735/__pycache__/display.cpython-36.pyc
Normal file
BIN
components/st7735/__pycache__/display.cpython-36.pyc
Normal file
Binary file not shown.
BIN
components/st7735/__pycache__/display.cpython-39.pyc
Normal file
BIN
components/st7735/__pycache__/display.cpython-39.pyc
Normal file
Binary file not shown.
41
components/st7735/display.py
Normal file
41
components/st7735/display.py
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome import pins
|
||||||
|
from esphome.components import display, spi
|
||||||
|
from esphome.const import CONF_ID, CONF_LAMBDA
|
||||||
|
from esphome.const import CONF_DC_PIN, CONF_CS_PIN, CONF_ID, CONF_LAMBDA, CONF_PAGES
|
||||||
|
from esphome.const import CONF_EXTERNAL_VCC, CONF_LAMBDA, CONF_MODEL, CONF_RESET_PIN, \
|
||||||
|
CONF_BRIGHTNESS
|
||||||
|
from . import st7735_ns
|
||||||
|
|
||||||
|
DEPENDENCIES = ['spi']
|
||||||
|
|
||||||
|
ST7735 = st7735_ns.class_('ST7735', cg.PollingComponent, spi.SPIDevice)
|
||||||
|
ST7735Ref = ST7735.operator('ref')
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = display.FULL_DISPLAY_SCHEMA.extend({
|
||||||
|
cv.GenerateID(): cv.declare_id(ST7735),
|
||||||
|
cv.Required(CONF_RESET_PIN): pins.gpio_output_pin_schema,
|
||||||
|
cv.Required(CONF_DC_PIN): pins.gpio_output_pin_schema,
|
||||||
|
cv.Required(CONF_CS_PIN): pins.gpio_output_pin_schema,
|
||||||
|
cv.Optional(CONF_BRIGHTNESS, default=1.0): cv.percentage,
|
||||||
|
}).extend(cv.polling_component_schema('1s')).extend(spi.spi_device_schema())
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
yield cg.register_component(var, config)
|
||||||
|
yield spi.register_spi_device(var, config)
|
||||||
|
|
||||||
|
dc = yield cg.gpio_pin_expression(config[CONF_DC_PIN])
|
||||||
|
cg.add(var.set_dc_pin(dc))
|
||||||
|
|
||||||
|
reset = yield cg.gpio_pin_expression(config[CONF_RESET_PIN])
|
||||||
|
cg.add(var.set_reset_pin(reset))
|
||||||
|
|
||||||
|
if CONF_LAMBDA in config:
|
||||||
|
lambda_ = yield cg.process_lambda(
|
||||||
|
config[CONF_LAMBDA], [(display.DisplayBufferRef, 'it')], return_type=cg.void)
|
||||||
|
cg.add(var.set_writer(lambda_))
|
||||||
|
|
||||||
|
yield display.register_display(var, config)
|
||||||
351
components/st7735/st7735.cpp
Normal file
351
components/st7735/st7735.cpp
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
#include "st7735.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "esphome/components/display/display_buffer.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace st7735 {
|
||||||
|
|
||||||
|
#define ST_CMD_DELAY 0x80 // special signifier for command lists
|
||||||
|
|
||||||
|
#define ST77XX_NOP 0x00
|
||||||
|
#define ST77XX_SWRESET 0x01
|
||||||
|
#define ST77XX_RDDID 0x04
|
||||||
|
#define ST77XX_RDDST 0x09
|
||||||
|
|
||||||
|
#define ST77XX_SLPIN 0x10
|
||||||
|
#define ST77XX_SLPOUT 0x11
|
||||||
|
#define ST77XX_PTLON 0x12
|
||||||
|
#define ST77XX_NORON 0x13
|
||||||
|
|
||||||
|
#define ST77XX_INVOFF 0x20
|
||||||
|
#define ST77XX_INVON 0x21
|
||||||
|
#define ST77XX_DISPOFF 0x28
|
||||||
|
#define ST77XX_DISPON 0x29
|
||||||
|
#define ST77XX_CASET 0x2A
|
||||||
|
#define ST77XX_RASET 0x2B
|
||||||
|
#define ST77XX_RAMWR 0x2C
|
||||||
|
#define ST77XX_RAMRD 0x2E
|
||||||
|
|
||||||
|
#define ST77XX_PTLAR 0x30
|
||||||
|
#define ST77XX_TEOFF 0x34
|
||||||
|
#define ST77XX_TEON 0x35
|
||||||
|
#define ST77XX_MADCTL 0x36
|
||||||
|
#define ST77XX_COLMOD 0x3A
|
||||||
|
|
||||||
|
#define ST77XX_MADCTL_MY 0x80
|
||||||
|
#define ST77XX_MADCTL_MX 0x40
|
||||||
|
#define ST77XX_MADCTL_MV 0x20
|
||||||
|
#define ST77XX_MADCTL_ML 0x10
|
||||||
|
#define ST77XX_MADCTL_RGB 0x00
|
||||||
|
|
||||||
|
#define ST77XX_RDID1 0xDA
|
||||||
|
#define ST77XX_RDID2 0xDB
|
||||||
|
#define ST77XX_RDID3 0xDC
|
||||||
|
#define ST77XX_RDID4 0xDD
|
||||||
|
|
||||||
|
|
||||||
|
// some flags for initR() :(
|
||||||
|
#define INITR_GREENTAB 0x00
|
||||||
|
#define INITR_REDTAB 0x01
|
||||||
|
#define INITR_BLACKTAB 0x02
|
||||||
|
#define INITR_18GREENTAB INITR_GREENTAB
|
||||||
|
#define INITR_18REDTAB INITR_REDTAB
|
||||||
|
#define INITR_18BLACKTAB INITR_BLACKTAB
|
||||||
|
#define INITR_144GREENTAB 0x01
|
||||||
|
#define INITR_MINI160x80 0x04
|
||||||
|
#define INITR_HALLOWING 0x05
|
||||||
|
|
||||||
|
// Some register settings
|
||||||
|
#define ST7735_MADCTL_BGR 0x08
|
||||||
|
#define ST7735_MADCTL_MH 0x04
|
||||||
|
|
||||||
|
#define ST7735_FRMCTR1 0xB1
|
||||||
|
#define ST7735_FRMCTR2 0xB2
|
||||||
|
#define ST7735_FRMCTR3 0xB3
|
||||||
|
#define ST7735_INVCTR 0xB4
|
||||||
|
#define ST7735_DISSET5 0xB6
|
||||||
|
|
||||||
|
#define ST7735_PWCTR1 0xC0
|
||||||
|
#define ST7735_PWCTR2 0xC1
|
||||||
|
#define ST7735_PWCTR3 0xC2
|
||||||
|
#define ST7735_PWCTR4 0xC3
|
||||||
|
#define ST7735_PWCTR5 0xC4
|
||||||
|
#define ST7735_VMCTR1 0xC5
|
||||||
|
|
||||||
|
#define ST7735_PWCTR6 0xFC
|
||||||
|
|
||||||
|
#define ST7735_GMCTRP1 0xE0
|
||||||
|
#define ST7735_GMCTRN1 0xE1
|
||||||
|
|
||||||
|
static const uint8_t PROGMEM
|
||||||
|
Rcmd1[] = { // 7735R init, part 1 (red or green tab)
|
||||||
|
15, // 15 commands in list:
|
||||||
|
ST77XX_SWRESET, ST_CMD_DELAY, // 1: Software reset, 0 args, w/delay
|
||||||
|
150, // 150 ms delay
|
||||||
|
ST77XX_SLPOUT, ST_CMD_DELAY, // 2: Out of sleep mode, 0 args, w/delay
|
||||||
|
255, // 500 ms delay
|
||||||
|
ST7735_FRMCTR1, 3, // 3: Framerate ctrl - normal mode, 3 arg:
|
||||||
|
0x01, 0x2C, 0x2D, // Rate = fosc/(1x2+40) * (LINE+2C+2D)
|
||||||
|
ST7735_FRMCTR2, 3, // 4: Framerate ctrl - idle mode, 3 args:
|
||||||
|
0x01, 0x2C, 0x2D, // Rate = fosc/(1x2+40) * (LINE+2C+2D)
|
||||||
|
ST7735_FRMCTR3, 6, // 5: Framerate - partial mode, 6 args:
|
||||||
|
0x01, 0x2C, 0x2D, // Dot inversion mode
|
||||||
|
0x01, 0x2C, 0x2D, // Line inversion mode
|
||||||
|
ST7735_INVCTR, 1, // 6: Display inversion ctrl, 1 arg:
|
||||||
|
0x07, // No inversion
|
||||||
|
ST7735_PWCTR1, 3, // 7: Power control, 3 args, no delay:
|
||||||
|
0xA2,
|
||||||
|
0x02, // -4.6V
|
||||||
|
0x84, // AUTO mode
|
||||||
|
ST7735_PWCTR2, 1, // 8: Power control, 1 arg, no delay:
|
||||||
|
0xC5, // VGH25=2.4C VGSEL=-10 VGH=3 * AVDD
|
||||||
|
ST7735_PWCTR3, 2, // 9: Power control, 2 args, no delay:
|
||||||
|
0x0A, // Opamp current small
|
||||||
|
0x00, // Boost frequency
|
||||||
|
ST7735_PWCTR4, 2, // 10: Power control, 2 args, no delay:
|
||||||
|
0x8A, // BCLK/2,
|
||||||
|
0x2A, // opamp current small & medium low
|
||||||
|
ST7735_PWCTR5, 2, // 11: Power control, 2 args, no delay:
|
||||||
|
0x8A, 0xEE,
|
||||||
|
ST7735_VMCTR1, 1, // 12: Power control, 1 arg, no delay:
|
||||||
|
0x0E,
|
||||||
|
ST77XX_INVOFF, 0, // 13: Don't invert display, no args
|
||||||
|
ST77XX_MADCTL, 1, // 14: Mem access ctl (directions), 1 arg:
|
||||||
|
0xC8, // row/col addr, bottom-top refresh
|
||||||
|
ST77XX_COLMOD, 1, // 15: set color mode, 1 arg, no delay:
|
||||||
|
0x05 }, // 16-bit color
|
||||||
|
|
||||||
|
Rcmd2green[] = { // 7735R init, part 2 (green tab only)
|
||||||
|
2, // 2 commands in list:
|
||||||
|
ST77XX_CASET, 4, // 1: Column addr set, 4 args, no delay:
|
||||||
|
0x00, 0x02, // XSTART = 0
|
||||||
|
0x00, 0x7F+0x02, // XEND = 127
|
||||||
|
ST77XX_RASET, 4, // 2: Row addr set, 4 args, no delay:
|
||||||
|
0x00, 0x01, // XSTART = 0
|
||||||
|
0x00, 0x9F+0x01 }, // XEND = 159
|
||||||
|
Rcmd2green144[] = { // 7735R init, part 2 (green 1.44 tab)
|
||||||
|
2, // 2 commands in list:
|
||||||
|
ST77XX_CASET, 4, // 1: Column addr set, 4 args, no delay:
|
||||||
|
0x00, 0x00, // XSTART = 0
|
||||||
|
0x00, 0x7F, // XEND = 127
|
||||||
|
ST77XX_RASET, 4, // 2: Row addr set, 4 args, no delay:
|
||||||
|
0x00, 0x00, // XSTART = 0
|
||||||
|
0x00, 0x7F }, // XEND = 127
|
||||||
|
Rcmd3[] = { // 7735R init, part 3 (red or green tab)
|
||||||
|
4, // 4 commands in list:
|
||||||
|
ST7735_GMCTRP1, 16 , // 1: Gamma Adjustments (pos. polarity), 16 args + delay:
|
||||||
|
0x02, 0x1c, 0x07, 0x12, // (Not entirely necessary, but provides
|
||||||
|
0x37, 0x32, 0x29, 0x2d, // accurate colors)
|
||||||
|
0x29, 0x25, 0x2B, 0x39,
|
||||||
|
0x00, 0x01, 0x03, 0x10,
|
||||||
|
ST7735_GMCTRN1, 16 , // 2: Gamma Adjustments (neg. polarity), 16 args + delay:
|
||||||
|
0x03, 0x1d, 0x07, 0x06, // (Not entirely necessary, but provides
|
||||||
|
0x2E, 0x2C, 0x29, 0x2D, // accurate colors)
|
||||||
|
0x2E, 0x2E, 0x37, 0x3F,
|
||||||
|
0x00, 0x00, 0x02, 0x10,
|
||||||
|
ST77XX_NORON, ST_CMD_DELAY, // 3: Normal display on, no args, w/delay
|
||||||
|
10, // 10 ms delay
|
||||||
|
ST77XX_DISPON, ST_CMD_DELAY, // 4: Main screen turn on, no args w/delay
|
||||||
|
100 }; // 100 ms delay
|
||||||
|
|
||||||
|
static const char *TAG = "st7735";
|
||||||
|
|
||||||
|
void ST7735::setup() {
|
||||||
|
ESP_LOGCONFIG(TAG, "Setting up SPI ST7735...");
|
||||||
|
this->spi_setup();
|
||||||
|
this->dc_pin_->setup(); // OUTPUT
|
||||||
|
|
||||||
|
this->init_reset_();
|
||||||
|
|
||||||
|
this->displayInit(Rcmd1);
|
||||||
|
this->displayInit(Rcmd2green);
|
||||||
|
this->displayInit(Rcmd3);
|
||||||
|
this->writecommand(ST7735_INVON);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//this->disable();
|
||||||
|
delay(120);
|
||||||
|
//this->enable();
|
||||||
|
|
||||||
|
this->writecommand(ST7735_DISPON); //Display on
|
||||||
|
delay(120);
|
||||||
|
|
||||||
|
this->init_internal_(this->get_buffer_length_());
|
||||||
|
memset(this->buffer_, 0x00, this->get_buffer_length_());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ST7735::write_display_data() {
|
||||||
|
|
||||||
|
uint16_t offsetx = 26;
|
||||||
|
uint16_t offsety = 1;
|
||||||
|
|
||||||
|
uint16_t x1 = offsetx;
|
||||||
|
uint16_t x2 = x1 + get_width_internal()-1;
|
||||||
|
uint16_t y1 = offsety;
|
||||||
|
uint16_t y2 = y1 + get_height_internal()-1;
|
||||||
|
|
||||||
|
this->enable();
|
||||||
|
|
||||||
|
// set column(x) address
|
||||||
|
this->dc_pin_->digital_write(false);
|
||||||
|
this->write_byte(ST77XX_CASET);
|
||||||
|
this->dc_pin_->digital_write(true);
|
||||||
|
this->spi_master_write_addr(x1, x2);
|
||||||
|
|
||||||
|
// set Page(y) address
|
||||||
|
this->dc_pin_->digital_write(false);
|
||||||
|
this->write_byte(ST77XX_RASET);
|
||||||
|
this->dc_pin_->digital_write(true);
|
||||||
|
this->spi_master_write_addr(y1, y2);
|
||||||
|
|
||||||
|
// Memory Write
|
||||||
|
this->dc_pin_->digital_write(false);
|
||||||
|
this->write_byte(ST77XX_RAMWR);
|
||||||
|
this->dc_pin_->digital_write(true);
|
||||||
|
|
||||||
|
this->write_array(this->buffer_, this->get_buffer_length_());
|
||||||
|
|
||||||
|
this->disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ST7735::spi_master_write_addr(uint16_t addr1, uint16_t addr2)
|
||||||
|
{
|
||||||
|
static uint8_t Byte[4];
|
||||||
|
Byte[0] = (addr1 >> 8) & 0xFF;
|
||||||
|
Byte[1] = addr1 & 0xFF;
|
||||||
|
Byte[2] = (addr2 >> 8) & 0xFF;
|
||||||
|
Byte[3] = addr2 & 0xFF;
|
||||||
|
|
||||||
|
|
||||||
|
this->dc_pin_->digital_write(true);
|
||||||
|
this->write_array(Byte, 4);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ST7735::spi_master_write_color(uint16_t color, uint16_t size)
|
||||||
|
{
|
||||||
|
static uint8_t Byte[1024];
|
||||||
|
int index = 0;
|
||||||
|
for(int i=0;i<size;i++) {
|
||||||
|
Byte[index++] = (color >> 8) & 0xFF;
|
||||||
|
Byte[index++] = color & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->dc_pin_->digital_write(true);
|
||||||
|
return write_array(Byte, size*2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ST7735::dump_config() {
|
||||||
|
LOG_DISPLAY("", "SPI ST7735", this);
|
||||||
|
LOG_PIN(" CS Pin: ", this->cs_);
|
||||||
|
LOG_PIN(" DC Pin: ", this->dc_pin_);
|
||||||
|
LOG_PIN(" Reset Pin: ", this->reset_pin_);
|
||||||
|
LOG_UPDATE_INTERVAL(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
float ST7735::get_setup_priority() const {
|
||||||
|
return setup_priority::PROCESSOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ST7735::update() {
|
||||||
|
this->do_update_();
|
||||||
|
this->write_display_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ST7735::loop() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int ST7735::get_width_internal() {
|
||||||
|
return 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ST7735::get_height_internal() {
|
||||||
|
return 160;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ST7735::get_buffer_length_() {
|
||||||
|
return size_t(this->get_width_internal()) * size_t(this->get_height_internal()) * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HOT ST7735::draw_absolute_pixel_internal(int x, int y, Color color) {
|
||||||
|
if (x >= this->get_width_internal() || x < 0 || y >= this->get_height_internal() || y < 0)
|
||||||
|
return;
|
||||||
|
const uint32_t color565 = color.to_rgb_565();
|
||||||
|
// where should the bits go in the big buffer array? math...
|
||||||
|
uint16_t pos = (x + y * this->get_width_internal()) * 2;
|
||||||
|
this->buffer_[pos++] = (color565 >> 8) & 0xff;
|
||||||
|
this->buffer_[pos] = color565 & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ST7735::displayInit(const uint8_t *addr) {
|
||||||
|
|
||||||
|
uint8_t numCommands, cmd, numArgs;
|
||||||
|
uint16_t ms;
|
||||||
|
|
||||||
|
numCommands = pgm_read_byte(addr++); // Number of commands to follow
|
||||||
|
while(numCommands--) { // For each command...
|
||||||
|
cmd = pgm_read_byte(addr++); // Read command
|
||||||
|
numArgs = pgm_read_byte(addr++); // Number of args to follow
|
||||||
|
ms = numArgs & ST_CMD_DELAY; // If hibit set, delay follows args
|
||||||
|
numArgs &= ~ST_CMD_DELAY; // Mask out delay bit
|
||||||
|
this->sendcommand(cmd, addr, numArgs);
|
||||||
|
addr += numArgs;
|
||||||
|
|
||||||
|
if(ms) {
|
||||||
|
ms = pgm_read_byte(addr++); // Read post-command delay time (ms)
|
||||||
|
if(ms == 255) ms = 500; // If 255, delay for 500 ms
|
||||||
|
delay(ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ST7735::init_reset_() {
|
||||||
|
if (this->reset_pin_ != nullptr) {
|
||||||
|
this->reset_pin_->setup();
|
||||||
|
this->reset_pin_->digital_write(true);
|
||||||
|
delay(1);
|
||||||
|
// Trigger Reset
|
||||||
|
this->reset_pin_->digital_write(false);
|
||||||
|
delay(10);
|
||||||
|
// Wake up
|
||||||
|
this->reset_pin_->digital_write(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ST7735::writecommand(uint8_t value) {
|
||||||
|
this->enable();
|
||||||
|
this->dc_pin_->digital_write(false);
|
||||||
|
this->write_byte(value);
|
||||||
|
this->dc_pin_->digital_write(true);
|
||||||
|
this->disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ST7735::writedata(uint8_t value) {
|
||||||
|
this->dc_pin_->digital_write(true);
|
||||||
|
this->enable();
|
||||||
|
this->write_byte(value);
|
||||||
|
this->disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ST7735::sendcommand(uint8_t cmd, const uint8_t* dataBytes, uint8_t numDataBytes) {
|
||||||
|
this->writecommand(cmd);
|
||||||
|
this->senddata(dataBytes,numDataBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ST7735::senddata(const uint8_t* dataBytes, uint8_t numDataBytes) {
|
||||||
|
this->dc_pin_->digital_write(true); //pull DC high to indicate data
|
||||||
|
this->cs_->digital_write(false);
|
||||||
|
this->enable();
|
||||||
|
for (uint8_t i=0; i<numDataBytes; i++) {
|
||||||
|
this->transfer_byte(pgm_read_byte(dataBytes++)); //write byte - SPI library
|
||||||
|
}
|
||||||
|
this->cs_->digital_write(true);
|
||||||
|
this->disable();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace st7735
|
||||||
|
} // namespace esphome
|
||||||
149
components/st7735/st7735.h
Normal file
149
components/st7735/st7735.h
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/components/spi/spi.h"
|
||||||
|
#include "esphome/components/display/display_buffer.h"
|
||||||
|
|
||||||
|
// ST7735 specific commands used in init
|
||||||
|
#define ST7735_NOP 0x00
|
||||||
|
#define ST7735_SWRESET 0x01
|
||||||
|
#define ST7735_RDDID 0x04
|
||||||
|
#define ST7735_RDDST 0x09
|
||||||
|
|
||||||
|
#define ST7735_RDDPM 0x0A // Read display power mode
|
||||||
|
#define ST7735_RDD_MADCTL 0x0B // Read display MADCTL
|
||||||
|
#define ST7735_RDD_COLMOD 0x0C // Read display pixel format
|
||||||
|
#define ST7735_RDDIM 0x0D // Read display image mode
|
||||||
|
#define ST7735_RDDSM 0x0E // Read display signal mode
|
||||||
|
#define ST7735_RDDSR 0x0F // Read display self-diagnostic result (ST7735)
|
||||||
|
|
||||||
|
#define ST7735_SLPIN 0x10
|
||||||
|
#define ST7735_SLPOUT 0x11
|
||||||
|
#define ST7735_PTLON 0x12
|
||||||
|
#define ST7735_NORON 0x13
|
||||||
|
|
||||||
|
#define ST7735_INVOFF 0x20
|
||||||
|
#define ST7735_INVON 0x21
|
||||||
|
#define ST7735_GAMSET 0x26 // Gamma set
|
||||||
|
#define ST7735_DISPOFF 0x28
|
||||||
|
#define ST7735_DISPON 0x29
|
||||||
|
#define ST7735_CASET 0x2A
|
||||||
|
#define ST7735_RASET 0x2B
|
||||||
|
#define ST7735_RAMWR 0x2C
|
||||||
|
#define ST7735_RGBSET 0x2D // Color setting for 4096, 64K and 262K colors
|
||||||
|
#define ST7735_RAMRD 0x2E
|
||||||
|
|
||||||
|
#define ST7735_PTLAR 0x30
|
||||||
|
#define ST7735_VSCRDEF 0x33 // Vertical scrolling definition (ST7735)
|
||||||
|
#define ST7735_TEOFF 0x34 // Tearing effect line off
|
||||||
|
#define ST7735_TEON 0x35 // Tearing effect line on
|
||||||
|
#define ST7735_MADCTL 0x36 // Memory data access control
|
||||||
|
#define ST7735_IDMOFF 0x38 // Idle mode off
|
||||||
|
#define ST7735_IDMON 0x39 // Idle mode on
|
||||||
|
#define ST7735_RAMWRC 0x3C // Memory write continue (ST7735)
|
||||||
|
#define ST7735_RAMRDC 0x3E // Memory read continue (ST7735)
|
||||||
|
#define ST7735_COLMOD 0x3A
|
||||||
|
|
||||||
|
#define ST7735_RAMCTRL 0xB0 // RAM control
|
||||||
|
#define ST7735_RGBCTRL 0xB1 // RGB control
|
||||||
|
#define ST7735_PORCTRL 0xB2 // Porch control
|
||||||
|
#define ST7735_FRCTRL1 0xB3 // Frame rate control
|
||||||
|
#define ST7735_PARCTRL 0xB5 // Partial mode control
|
||||||
|
#define ST7735_GCTRL 0xB7 // Gate control
|
||||||
|
#define ST7735_GTADJ 0xB8 // Gate on timing adjustment
|
||||||
|
#define ST7735_DGMEN 0xBA // Digital gamma enable
|
||||||
|
#define ST7735_VCOMS 0xBB // VCOMS setting
|
||||||
|
#define ST7735_LCMCTRL 0xC0 // LCM control
|
||||||
|
#define ST7735_IDSET 0xC1 // ID setting
|
||||||
|
#define ST7735_VDVVRHEN 0xC2 // VDV and VRH command enable
|
||||||
|
#define ST7735_VRHS 0xC3 // VRH set
|
||||||
|
#define ST7735_VDVSET 0xC4 // VDV setting
|
||||||
|
#define ST7735_VCMOFSET 0xC5 // VCOMS offset set
|
||||||
|
#define ST7735_FRCTR2 0xC6 // FR Control 2
|
||||||
|
#define ST7735_CABCCTRL 0xC7 // CABC control
|
||||||
|
#define ST7735_REGSEL1 0xC8 // Register value section 1
|
||||||
|
#define ST7735_REGSEL2 0xCA // Register value section 2
|
||||||
|
#define ST7735_PWMFRSEL 0xCC // PWM frequency selection
|
||||||
|
#define ST7735_PWCTRL1 0xD0 // Power control 1
|
||||||
|
#define ST7735_VAPVANEN 0xD2 // Enable VAP/VAN signal output
|
||||||
|
#define ST7735_CMD2EN 0xDF // Command 2 enable
|
||||||
|
#define ST7735_PVGAMCTRL 0xE0 // Positive voltage gamma control
|
||||||
|
#define ST7735_NVGAMCTRL 0xE1 // Negative voltage gamma control
|
||||||
|
#define ST7735_DGMLUTR 0xE2 // Digital gamma look-up table for red
|
||||||
|
#define ST7735_DGMLUTB 0xE3 // Digital gamma look-up table for blue
|
||||||
|
#define ST7735_GATECTRL 0xE4 // Gate control
|
||||||
|
#define ST7735_SPI2EN 0xE7 // SPI2 enable
|
||||||
|
#define ST7735_PWCTRL2 0xE8 // Power control 2
|
||||||
|
#define ST7735_EQCTRL 0xE9 // Equalize time control
|
||||||
|
#define ST7735_PROMCTRL 0xEC // Program control
|
||||||
|
#define ST7735_PROMEN 0xFA // Program mode enable
|
||||||
|
#define ST7735_NVMSET 0xFC // NVM setting
|
||||||
|
#define ST7735_PROMACT 0xFE // Program action
|
||||||
|
|
||||||
|
// Some ready-made 16-bit ('565') color settings:
|
||||||
|
#define ST77XX_BLACK 0x0000
|
||||||
|
#define ST77XX_WHITE 0xFFFF
|
||||||
|
#define ST77XX_RED 0xF800
|
||||||
|
#define ST77XX_GREEN 0x07E0
|
||||||
|
#define ST77XX_BLUE 0x001F
|
||||||
|
#define ST77XX_CYAN 0x07FF
|
||||||
|
#define ST77XX_MAGENTA 0xF81F
|
||||||
|
#define ST77XX_YELLOW 0xFFE0
|
||||||
|
#define ST77XX_ORANGE 0xFC00
|
||||||
|
|
||||||
|
// Some ready-made 16-bit ('565') color settings:
|
||||||
|
#define ST7735_BLACK ST77XX_BLACK
|
||||||
|
#define ST7735_WHITE ST77XX_WHITE
|
||||||
|
#define ST7735_RED ST77XX_RED
|
||||||
|
#define ST7735_GREEN ST77XX_GREEN
|
||||||
|
#define ST7735_BLUE ST77XX_BLUE
|
||||||
|
#define ST7735_CYAN ST77XX_CYAN
|
||||||
|
#define ST7735_MAGENTA ST77XX_MAGENTA
|
||||||
|
#define ST7735_YELLOW ST77XX_YELLOW
|
||||||
|
#define ST7735_ORANGE ST77XX_ORANGE
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace st7735 {
|
||||||
|
|
||||||
|
class ST7735 : public PollingComponent, public display::DisplayBuffer,
|
||||||
|
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_HIGH, spi::CLOCK_PHASE_TRAILING,
|
||||||
|
spi::DATA_RATE_8MHZ> {
|
||||||
|
public:
|
||||||
|
void set_dc_pin(GPIOPin *dc_pin) { this->dc_pin_ = dc_pin; }
|
||||||
|
void set_reset_pin(GPIOPin *reset_pin) { this->reset_pin_ = reset_pin; }
|
||||||
|
|
||||||
|
// ========== INTERNAL METHODS ==========
|
||||||
|
// (In most use cases you won't need these)
|
||||||
|
void setup() override;
|
||||||
|
void dump_config() override;
|
||||||
|
float get_setup_priority() const override;
|
||||||
|
void update() override;
|
||||||
|
void loop() override;
|
||||||
|
|
||||||
|
void write_display_data();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GPIOPin *dc_pin_;
|
||||||
|
GPIOPin *reset_pin_{nullptr};
|
||||||
|
|
||||||
|
void displayInit(const uint8_t *addr);
|
||||||
|
void sendcommand(uint8_t cmd, const uint8_t* dataBytes, uint8_t numDataBytes);
|
||||||
|
void senddata(const uint8_t* dataBytes, uint8_t numDataBytes);
|
||||||
|
|
||||||
|
void init_reset_();
|
||||||
|
void writecommand(uint8_t value);
|
||||||
|
void writedata(uint8_t value);
|
||||||
|
|
||||||
|
void spi_master_write_addr(uint16_t addr1, uint16_t addr2);
|
||||||
|
void spi_master_write_color(uint16_t color, uint16_t size);
|
||||||
|
|
||||||
|
void draw_absolute_pixel_internal(int x, int y, Color color) override;
|
||||||
|
|
||||||
|
int get_height_internal() override;
|
||||||
|
int get_width_internal() override;
|
||||||
|
size_t get_buffer_length_();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace st7735
|
||||||
|
} // namespace esphome
|
||||||
116
custom_components/AXP2101_component.h
Normal file
116
custom_components/AXP2101_component.h
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
#include "esphome.h"
|
||||||
|
|
||||||
|
#define XPOWERS_CHIP_AXP2101
|
||||||
|
#include "XPowersLib.h"
|
||||||
|
|
||||||
|
#ifdef I2C_SDA
|
||||||
|
#undef I2C_SDA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef I2C_SCL
|
||||||
|
#undef I2C_SCL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define I2C_SDA (7)
|
||||||
|
#define I2C_SCL (6)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class AXP2101Component : public Component {
|
||||||
|
public:
|
||||||
|
void setup() override {
|
||||||
|
// This will be called once to set up the component
|
||||||
|
// think of it as the setup() call in Arduino
|
||||||
|
ESP_LOGD("custom", "Custom component setup");
|
||||||
|
|
||||||
|
if (!PMU.begin(Wire, AXP2101_SLAVE_ADDRESS, I2C_SDA, I2C_SCL)) {
|
||||||
|
Serial.println("Failed to initialize power.....");
|
||||||
|
while (1) {
|
||||||
|
delay(5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set VSY off voltage as 2600mV , Adjustment range 2600mV ~ 3300mV
|
||||||
|
PMU.setSysPowerDownVoltage(2600);
|
||||||
|
|
||||||
|
//Turn off not use power channel
|
||||||
|
PMU.disableDC2();
|
||||||
|
PMU.disableDC3();
|
||||||
|
PMU.disableDC4();
|
||||||
|
PMU.disableDC5();
|
||||||
|
|
||||||
|
PMU.disableALDO1();
|
||||||
|
PMU.disableALDO2();
|
||||||
|
PMU.disableALDO3();
|
||||||
|
PMU.disableALDO4();
|
||||||
|
PMU.disableBLDO1();
|
||||||
|
PMU.disableBLDO2();
|
||||||
|
|
||||||
|
PMU.disableCPUSLDO();
|
||||||
|
PMU.disableDLDO1();
|
||||||
|
PMU.disableDLDO2();
|
||||||
|
// Board 5 Pin socket 3.3V power output control
|
||||||
|
PMU.setDC3Voltage(3100); //Extern 3100~ 3400V
|
||||||
|
PMU.enableDC3();
|
||||||
|
|
||||||
|
// Camera working voltage, please do not change
|
||||||
|
PMU.setALDO1Voltage(1500); // CAM DVDD
|
||||||
|
PMU.enableALDO1();
|
||||||
|
|
||||||
|
// Camera working voltage, please do not change
|
||||||
|
PMU.setALDO2Voltage(3000); // CAM DVDD
|
||||||
|
PMU.enableALDO2();
|
||||||
|
|
||||||
|
// Camera working voltage, please do not change
|
||||||
|
PMU.setALDO4Voltage(3000); // CAM AVDD
|
||||||
|
PMU.enableALDO4();
|
||||||
|
|
||||||
|
// Pyroelectric sensor working voltage, please do not change
|
||||||
|
PMU.setALDO3Voltage(3300); // PIR VDD
|
||||||
|
PMU.enableALDO3();
|
||||||
|
|
||||||
|
// Microphone working voltage, please do not change
|
||||||
|
PMU.setBLDO1Voltage(3300); // MIC VDD
|
||||||
|
PMU.enableBLDO1();
|
||||||
|
|
||||||
|
PMU.clearIrqStatus();
|
||||||
|
|
||||||
|
PMU.enableVbusVoltageMeasure();
|
||||||
|
PMU.enableBattVoltageMeasure();
|
||||||
|
PMU.enableSystemVoltageMeasure();
|
||||||
|
PMU.disableTemperatureMeasure();
|
||||||
|
|
||||||
|
// TS Pin detection must be disable, otherwise it cannot be charged
|
||||||
|
PMU.disableTSPinMeasure();
|
||||||
|
|
||||||
|
// Disable all interrupts
|
||||||
|
PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||||
|
// Clear all interrupt flags
|
||||||
|
PMU.clearIrqStatus();
|
||||||
|
// Enable the required interrupt function
|
||||||
|
PMU.enableIRQ(
|
||||||
|
XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | //BATTERY
|
||||||
|
XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | //VBUS
|
||||||
|
XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | //POWER KEY
|
||||||
|
XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ //CHARGE
|
||||||
|
// XPOWERS_PKEY_NEGATIVE_IRQ | XPOWERS_PKEY_POSITIVE_IRQ | //POWER KEY
|
||||||
|
);
|
||||||
|
|
||||||
|
// TS Pin detection must be disable, otherwise it cannot be charged
|
||||||
|
PMU.disableTSPinMeasure();
|
||||||
|
// Set the precharge charging current
|
||||||
|
PMU.setPrechargeCurr(XPOWERS_AXP2101_PRECHARGE_50MA);
|
||||||
|
// Set constant current charge current limit
|
||||||
|
PMU.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_300MA);
|
||||||
|
// Set stop charging termination current
|
||||||
|
PMU.setChargerTerminationCurr(XPOWERS_AXP2101_CHG_ITERM_25MA);
|
||||||
|
|
||||||
|
// Set charge cut-off voltage
|
||||||
|
PMU.setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V1);
|
||||||
|
|
||||||
|
// Set the time of pressing the button to turn off
|
||||||
|
PMU.setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
XPowersPMU PMU;
|
||||||
|
};
|
||||||
102
custom_components/AXP2101_component.yaml
Normal file
102
custom_components/AXP2101_component.yaml
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
esphome:
|
||||||
|
name: camera-2
|
||||||
|
platformio_options:
|
||||||
|
build_flags: "-DBOARD_HAS_PSRAM -UARDUINO_USB_CDC_ON_BOOT"
|
||||||
|
upload_speed: 921600
|
||||||
|
monitor_speed: 115200
|
||||||
|
friendly_name: "Camera 2"
|
||||||
|
libraries:
|
||||||
|
- XPowersLib=https://github.com/lewisxhe/XPowersLib.git
|
||||||
|
- "Wire"
|
||||||
|
includes:
|
||||||
|
- AXP2101_component.h
|
||||||
|
|
||||||
|
custom_component:
|
||||||
|
- lambda: |-
|
||||||
|
auto axp2101 = new AXP2101Component();
|
||||||
|
return {axp2101};
|
||||||
|
components:
|
||||||
|
- id: axp2101
|
||||||
|
|
||||||
|
esp32:
|
||||||
|
board: esp32s3box
|
||||||
|
framework:
|
||||||
|
type: arduino
|
||||||
|
|
||||||
|
# Enable Home Assistant API
|
||||||
|
api:
|
||||||
|
encryption:
|
||||||
|
key: "XXX" # Replace with your API encryption key
|
||||||
|
|
||||||
|
ota:
|
||||||
|
password: "XXX" # Replace with your OTA password
|
||||||
|
|
||||||
|
wifi:
|
||||||
|
ssid: !secret wifi_ssid # Replace with your Wi-Fi SSID stored in secrets.yaml
|
||||||
|
password: !secret wifi_password # Replace with your Wi-Fi password stored in secrets.yaml
|
||||||
|
|
||||||
|
# Enable fallback hotspot (captive portal) in case Wi-Fi connection fails
|
||||||
|
ap:
|
||||||
|
ssid: "Esp32-S3 Fallback Hotspot"
|
||||||
|
password: "XXX" # Replace with your fallback hotspot password
|
||||||
|
|
||||||
|
binary_sensor:
|
||||||
|
- platform: gpio
|
||||||
|
pin: GPIO17
|
||||||
|
name: "ttgocam2 PIR"
|
||||||
|
device_class: motion
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: wifi_signal
|
||||||
|
name: "ttgocam2 WiFi Signal"
|
||||||
|
update_interval: 60s
|
||||||
|
|
||||||
|
time:
|
||||||
|
- platform: homeassistant
|
||||||
|
id: homeassistant_time
|
||||||
|
|
||||||
|
font:
|
||||||
|
- file: "nanum.ttf"
|
||||||
|
id: tnr1
|
||||||
|
size: 17
|
||||||
|
|
||||||
|
web_server:
|
||||||
|
version: 2
|
||||||
|
|
||||||
|
i2c:
|
||||||
|
sda: GPIO07
|
||||||
|
scl: GPIO06
|
||||||
|
frequency: 200kHz
|
||||||
|
|
||||||
|
esp32_camera:
|
||||||
|
name: camera-2
|
||||||
|
external_clock:
|
||||||
|
pin: GPIO38
|
||||||
|
frequency: 20MHz
|
||||||
|
i2c_pins:
|
||||||
|
sda: GPIO05
|
||||||
|
scl: GPIO04
|
||||||
|
data_pins: [GPIO14, GPIO47, GPIO48, GPIO21, GPIO13, GPIO11, GPIO10, GPIO09]
|
||||||
|
vsync_pin: GPIO8
|
||||||
|
href_pin: GPIO18
|
||||||
|
pixel_clock_pin: GPIO12
|
||||||
|
vertical_flip: false
|
||||||
|
horizontal_mirror: false
|
||||||
|
resolution: 1024x768
|
||||||
|
|
||||||
|
esp32_camera_web_server:
|
||||||
|
- port: 8080
|
||||||
|
mode: stream
|
||||||
|
- port: 8081
|
||||||
|
mode: snapshot
|
||||||
|
|
||||||
|
display:
|
||||||
|
- platform: ssd1306_i2c
|
||||||
|
update_interval: 2s
|
||||||
|
model: "SSD1306 128x64"
|
||||||
|
address: 0x3C
|
||||||
|
rotation: 180
|
||||||
|
lambda: |-
|
||||||
|
// Display current date and time
|
||||||
|
it.strftime(64, 0, id(tnr1), TextAlign::TOP_CENTER, "%m-%d-%Y", id(homeassistant_time).now());
|
||||||
|
it.strftime(64, 44, id(tnr1), TextAlign::BASELINE_CENTER, "%I:%M:%S%p", id(homeassistant_time).now());
|
||||||
31
custom_components/ads1100/__init__.py
Normal file
31
custom_components/ads1100/__init__.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import i2c
|
||||||
|
from esphome.const import CONF_ID
|
||||||
|
|
||||||
|
DEPENDENCIES = ["i2c"]
|
||||||
|
AUTO_LOAD = ["sensor", "voltage_sampler"]
|
||||||
|
MULTI_CONF = True
|
||||||
|
|
||||||
|
ads1100_ns = cg.esphome_ns.namespace("ads1100")
|
||||||
|
ADS1100Component = ads1100_ns.class_("ADS1100Component", cg.Component, i2c.I2CDevice)
|
||||||
|
|
||||||
|
CONF_CONTINUOUS_MODE = "continuous_mode"
|
||||||
|
CONFIG_SCHEMA = (
|
||||||
|
cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(ADS1100Component),
|
||||||
|
cv.Optional(CONF_CONTINUOUS_MODE, default=False): cv.boolean,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.extend(cv.COMPONENT_SCHEMA)
|
||||||
|
.extend(i2c.i2c_device_schema(None))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
await cg.register_component(var, config)
|
||||||
|
await i2c.register_i2c_device(var, config)
|
||||||
|
|
||||||
|
cg.add(var.set_continuous_mode(config[CONF_CONTINUOUS_MODE]))
|
||||||
170
custom_components/ads1100/ads1100.cpp
Normal file
170
custom_components/ads1100/ads1100.cpp
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
#include "ads1100.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "esphome/core/hal.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace ads1100 {
|
||||||
|
|
||||||
|
static const char *const TAG = "ads1100";
|
||||||
|
static const uint8_t ADS1100_REGISTER_CONVERSION = 0x00;
|
||||||
|
static const uint8_t ADS1100_REGISTER_CONFIG = 0x01;
|
||||||
|
|
||||||
|
static const uint8_t ADS1100_DATA_RATE_860_SPS = 0b111;
|
||||||
|
|
||||||
|
void ADS1100Component::setup() {
|
||||||
|
ESP_LOGCONFIG(TAG, "Setting up ADS1100...");
|
||||||
|
uint16_t value;
|
||||||
|
if (!this->read_byte_16(ADS1100_REGISTER_CONVERSION, &value)) {
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint16_t config = 0;
|
||||||
|
// Clear single-shot bit
|
||||||
|
// 0b0xxxxxxxxxxxxxxx
|
||||||
|
config |= 0b0000000000000000;
|
||||||
|
// Setup multiplexer
|
||||||
|
// 0bx000xxxxxxxxxxxx
|
||||||
|
config |= ADS1100_MULTIPLEXER_8 << 12;
|
||||||
|
|
||||||
|
// Setup Gain
|
||||||
|
// 0bxxxx000xxxxxxxxx
|
||||||
|
config |= ADS1100_GAIN_6P144 << 9;
|
||||||
|
|
||||||
|
if (this->continuous_mode_) {
|
||||||
|
// Set continuous mode
|
||||||
|
// 0bxxxxxxx0xxxxxxxx
|
||||||
|
config |= 0b0000000000000000;
|
||||||
|
} else {
|
||||||
|
// Set singleshot mode
|
||||||
|
// 0bxxxxxxx1xxxxxxxx
|
||||||
|
config |= 0b0000000100000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set data rate - 860 samples per second (we're in singleshot mode)
|
||||||
|
// 0bxxxxxxxx100xxxxx
|
||||||
|
config |= ADS1100_DATA_RATE_860_SPS << 5;
|
||||||
|
|
||||||
|
// Set comparator mode - hysteresis
|
||||||
|
// 0bxxxxxxxxxxx0xxxx
|
||||||
|
config |= 0b0000000000000000;
|
||||||
|
|
||||||
|
// Set comparator polarity - active low
|
||||||
|
// 0bxxxxxxxxxxxx0xxx
|
||||||
|
config |= 0b0000000000000000;
|
||||||
|
|
||||||
|
// Set comparator latch enabled - false
|
||||||
|
// 0bxxxxxxxxxxxxx0xx
|
||||||
|
config |= 0b0000000000000000;
|
||||||
|
|
||||||
|
// Set comparator que mode - disabled
|
||||||
|
// 0bxxxxxxxxxxxxxx11
|
||||||
|
config |= 0b0000000000000011;
|
||||||
|
|
||||||
|
if (!this->write_byte_16(ADS1100_REGISTER_CONFIG, config)) {
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->prev_config_ = config;
|
||||||
|
}
|
||||||
|
void ADS1100Component::dump_config() {
|
||||||
|
ESP_LOGCONFIG(TAG, "Setting up ADS1100...");
|
||||||
|
LOG_I2C_DEVICE(this);
|
||||||
|
if (this->is_failed()) {
|
||||||
|
ESP_LOGE(TAG, "Communication with ADS1100 failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto *sensor : this->sensors_) {
|
||||||
|
LOG_SENSOR(" ", "Sensor", sensor);
|
||||||
|
ESP_LOGCONFIG(TAG, " Rate: %u", sensor->get_rate());
|
||||||
|
ESP_LOGCONFIG(TAG, " Gain: %u", sensor->get_gain());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float ADS1100Component::request_measurement(ADS1100Sensor *sensor) {
|
||||||
|
uint16_t config = this->prev_config_;
|
||||||
|
// Multiplexer
|
||||||
|
// 0bxBBBxxxxxxxxxxxx
|
||||||
|
config &= 0b1000111111111111;
|
||||||
|
config |= (sensor->get_multiplexer() & 0b111) << 12;
|
||||||
|
|
||||||
|
// Gain
|
||||||
|
// 0bxxxxBBBxxxxxxxxx
|
||||||
|
config &= 0b1111000111111111;
|
||||||
|
config |= (sensor->get_gain() & 0b111) << 9;
|
||||||
|
|
||||||
|
if (!this->continuous_mode_) {
|
||||||
|
// Start conversion
|
||||||
|
config |= 0b1000000000000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->continuous_mode_ || this->prev_config_ != config) {
|
||||||
|
if (!this->write_byte_16(ADS1100_REGISTER_CONFIG, config)) {
|
||||||
|
this->status_set_warning();
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
this->prev_config_ = config;
|
||||||
|
|
||||||
|
// about 1.2 ms with 860 samples per second
|
||||||
|
delay(2);
|
||||||
|
|
||||||
|
// in continuous mode, conversion will always be running, rely on the delay
|
||||||
|
// to ensure conversion is taking place with the correct settings
|
||||||
|
// can we use the rdy pin to trigger when a conversion is done?
|
||||||
|
if (!this->continuous_mode_) {
|
||||||
|
uint32_t start = millis();
|
||||||
|
while (this->read_byte_16(ADS1100_REGISTER_CONFIG, &config) && (config >> 15) == 0) {
|
||||||
|
if (millis() - start > 100) {
|
||||||
|
ESP_LOGW(TAG, "Reading ADS1100 timed out");
|
||||||
|
this->status_set_warning();
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t raw_conversion;
|
||||||
|
if (!this->read_byte_16(ADS1100_REGISTER_CONVERSION, &raw_conversion)) {
|
||||||
|
this->status_set_warning();
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
auto signed_conversion = static_cast<int16_t>(raw_conversion);
|
||||||
|
|
||||||
|
float millivolts;
|
||||||
|
switch (sensor->get_gain()) {
|
||||||
|
case ADS1100_GAIN_6P144:
|
||||||
|
millivolts = signed_conversion * 0.187500f;
|
||||||
|
break;
|
||||||
|
case ADS1100_GAIN_4P096:
|
||||||
|
millivolts = signed_conversion * 0.125000f;
|
||||||
|
break;
|
||||||
|
case ADS1100_GAIN_2P048:
|
||||||
|
millivolts = signed_conversion * 0.062500f;
|
||||||
|
break;
|
||||||
|
case ADS1100_GAIN_1P024:
|
||||||
|
millivolts = signed_conversion * 0.031250f;
|
||||||
|
break;
|
||||||
|
case ADS1100_GAIN_0P512:
|
||||||
|
millivolts = signed_conversion * 0.015625f;
|
||||||
|
break;
|
||||||
|
case ADS1100_GAIN_0P256:
|
||||||
|
millivolts = signed_conversion * 0.007813f;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
millivolts = NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->status_clear_warning();
|
||||||
|
return millivolts / 1e3f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ADS1100Sensor::sample() { return this->parent_->request_measurement(this); }
|
||||||
|
void ADS1100Sensor::update() {
|
||||||
|
float v = this->parent_->request_measurement(this);
|
||||||
|
if (!std::isnan(v)) {
|
||||||
|
ESP_LOGD(TAG, "'%s': Got Voltage=%fV", this->get_name().c_str(), v);
|
||||||
|
this->publish_state(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ads1100
|
||||||
|
} // namespace esphome
|
||||||
76
custom_components/ads1100/ads1100.h
Normal file
76
custom_components/ads1100/ads1100.h
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/components/sensor/sensor.h"
|
||||||
|
#include "esphome/components/i2c/i2c.h"
|
||||||
|
#include "esphome/components/voltage_sampler/voltage_sampler.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace ads1100 {
|
||||||
|
|
||||||
|
enum ADS1100OSMode {
|
||||||
|
ADS1100_OSMODE_SINGLE = 0x80,
|
||||||
|
ADS1100_OSMODE_BUSY = 0x00,
|
||||||
|
ADS1100_OSMODE_NOTBUSY = 0x80,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ADS1100Mode {
|
||||||
|
ADS1100_MODE_CONTINUOUS = 0x00,
|
||||||
|
ADS1100_MODE_SINGLE = 0x10,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ADS1100Rate {
|
||||||
|
ADS1100_RATE_128 = 0x00,
|
||||||
|
ADS1100_RATE_32 = 0x04,
|
||||||
|
ADS1100_RATE_16 = 0x08,
|
||||||
|
ADS1100_RATE_8 = 0x0c,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ADS1100Gain {
|
||||||
|
ADS1100_GAIN_1 = 0x01,
|
||||||
|
ADS1100_GAIN_2 = 0x02,
|
||||||
|
ADS1100_GAIN_4 = 0x03,
|
||||||
|
ADS1100_GAIN_8 = 0x04,
|
||||||
|
};
|
||||||
|
|
||||||
|
class ADS1100Sensor;
|
||||||
|
|
||||||
|
class ADS1100Component : public Component, public i2c::I2CDevice {
|
||||||
|
public:
|
||||||
|
void register_sensor(ADS1100Sensor *obj) { this->sensors_.push_back(obj); }
|
||||||
|
/// Set up the internal sensor array.
|
||||||
|
void setup() override;
|
||||||
|
void dump_config() override;
|
||||||
|
/// HARDWARE_LATE setup priority
|
||||||
|
float get_setup_priority() const override { return setup_priority::DATA; }
|
||||||
|
void set_continuous_mode(bool continuous_mode) { continuous_mode_ = continuous_mode; }
|
||||||
|
|
||||||
|
/// Helper method to request a measurement from a sensor.
|
||||||
|
float request_measurement(ADS1100Sensor *sensor);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<ADS1100Sensor *> sensors_;
|
||||||
|
uint16_t prev_config_{0};
|
||||||
|
bool continuous_mode_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Internal holder class that is in instance of Sensor so that the hub can create individual sensors.
|
||||||
|
class ADS1100Sensor : public sensor::Sensor, public PollingComponent, public voltage_sampler::VoltageSampler {
|
||||||
|
public:
|
||||||
|
ADS1100Sensor(ADS1100Component *parent) : parent_(parent) {}
|
||||||
|
void update() override;
|
||||||
|
void set_rate(ADS1100Rate rate) { rate_ = rate; }
|
||||||
|
void set_gain(ADS1100Gain gain) { gain_ = gain; }
|
||||||
|
|
||||||
|
float sample() override;
|
||||||
|
uint8_t get_rate() const { return rate_; }
|
||||||
|
uint8_t get_gain() const { return gain_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ADS1100Component *parent_;
|
||||||
|
ADS1100Rate rate_;
|
||||||
|
ADS1100Gain gain_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ads1100
|
||||||
|
} // namespace esphome
|
||||||
81
custom_components/ads1100/sensor.py
Normal file
81
custom_components/ads1100/sensor.py
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import sensor, voltage_sampler
|
||||||
|
from esphome.const import (
|
||||||
|
CONF_GAIN,
|
||||||
|
CONF_MULTIPLEXER,
|
||||||
|
DEVICE_CLASS_VOLTAGE,
|
||||||
|
STATE_CLASS_MEASUREMENT,
|
||||||
|
UNIT_VOLT,
|
||||||
|
CONF_ID,
|
||||||
|
)
|
||||||
|
from . import ads1100_ns, ADS1100Component
|
||||||
|
|
||||||
|
DEPENDENCIES = ["ads1100"]
|
||||||
|
|
||||||
|
ADS1100Multiplexer = ads1100_ns.enum("ADS1100Multiplexer")
|
||||||
|
MUX = {
|
||||||
|
"A0_A1": ADS1100Multiplexer.ADS1100_MULTIPLEXER_P0_N1,
|
||||||
|
"A0_A3": ADS1100Multiplexer.ADS1100_MULTIPLEXER_P0_N3,
|
||||||
|
"A1_A3": ADS1100Multiplexer.ADS1100_MULTIPLEXER_P1_N3,
|
||||||
|
"A2_A3": ADS1100Multiplexer.ADS1100_MULTIPLEXER_P2_N3,
|
||||||
|
"A0_GND": ADS1100Multiplexer.ADS1100_MULTIPLEXER_P0_NG,
|
||||||
|
"A1_GND": ADS1100Multiplexer.ADS1100_MULTIPLEXER_P1_NG,
|
||||||
|
"A2_GND": ADS1100Multiplexer.ADS1100_MULTIPLEXER_P2_NG,
|
||||||
|
"A3_GND": ADS1100Multiplexer.ADS1100_MULTIPLEXER_P3_NG,
|
||||||
|
}
|
||||||
|
|
||||||
|
ADS1100Gain = ads1100_ns.enum("ADS1100Gain")
|
||||||
|
GAIN = {
|
||||||
|
"6.144": ADS1100Gain.ADS1100_GAIN_6P144,
|
||||||
|
"4.096": ADS1100Gain.ADS1100_GAIN_4P096,
|
||||||
|
"2.048": ADS1100Gain.ADS1100_GAIN_2P048,
|
||||||
|
"1.024": ADS1100Gain.ADS1100_GAIN_1P024,
|
||||||
|
"0.512": ADS1100Gain.ADS1100_GAIN_0P512,
|
||||||
|
"0.256": ADS1100Gain.ADS1100_GAIN_0P256,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def validate_gain(value):
|
||||||
|
if isinstance(value, float):
|
||||||
|
value = f"{value:0.03f}"
|
||||||
|
elif not isinstance(value, str):
|
||||||
|
raise cv.Invalid(f'invalid gain "{value}"')
|
||||||
|
|
||||||
|
return cv.enum(GAIN)(value)
|
||||||
|
|
||||||
|
|
||||||
|
ADS1100Sensor = ads1100_ns.class_(
|
||||||
|
"ADS1100Sensor", sensor.Sensor, cg.PollingComponent, voltage_sampler.VoltageSampler
|
||||||
|
)
|
||||||
|
|
||||||
|
CONF_ADS1100_ID = "ads1100_id"
|
||||||
|
CONFIG_SCHEMA = (
|
||||||
|
sensor.sensor_schema(
|
||||||
|
unit_of_measurement=UNIT_VOLT,
|
||||||
|
accuracy_decimals=3,
|
||||||
|
device_class=DEVICE_CLASS_VOLTAGE,
|
||||||
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
|
)
|
||||||
|
.extend(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(ADS1100Sensor),
|
||||||
|
cv.GenerateID(CONF_ADS1100_ID): cv.use_id(ADS1100Component),
|
||||||
|
cv.Required(CONF_MULTIPLEXER): cv.enum(MUX, upper=True, space="_"),
|
||||||
|
cv.Required(CONF_GAIN): validate_gain,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.extend(cv.polling_component_schema("60s"))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
paren = await cg.get_variable(config[CONF_ADS1100_ID])
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID], paren)
|
||||||
|
await sensor.register_sensor(var, config)
|
||||||
|
await cg.register_component(var, config)
|
||||||
|
|
||||||
|
cg.add(var.set_multiplexer(config[CONF_MULTIPLEXER]))
|
||||||
|
cg.add(var.set_gain(config[CONF_GAIN]))
|
||||||
|
|
||||||
|
cg.add(paren.register_sensor(var))
|
||||||
0
custom_components/axp192_disable/__init__.py
Normal file
0
custom_components/axp192_disable/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
531
custom_components/axp192_disable/axp192.cpp
Normal file
531
custom_components/axp192_disable/axp192.cpp
Normal file
@@ -0,0 +1,531 @@
|
|||||||
|
#include "axp192.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace axp192 {
|
||||||
|
|
||||||
|
static const char *TAG = "axp192.sensor";
|
||||||
|
|
||||||
|
void AXP192Component::setup()
|
||||||
|
{
|
||||||
|
begin(false, false, false, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AXP192Component::dump_config() {
|
||||||
|
ESP_LOGCONFIG(TAG, "AXP192:");
|
||||||
|
LOG_I2C_DEVICE(this);
|
||||||
|
LOG_SENSOR(" ", "Battery Level", this->batterylevel_sensor_);
|
||||||
|
}
|
||||||
|
|
||||||
|
float AXP192Component::get_setup_priority() const { return setup_priority::DATA; }
|
||||||
|
|
||||||
|
void AXP192Component::update() {
|
||||||
|
|
||||||
|
if (this->batterylevel_sensor_ != nullptr) {
|
||||||
|
// To be fixed
|
||||||
|
// This is not giving the right value - mostly there to have some sample sensor...
|
||||||
|
float vbat = GetBatVoltage();
|
||||||
|
float batterylevel = 100.0 * ((vbat - 3.0) / (4.1 - 3.0));
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Got Battery Level=%f (%f)", batterylevel, vbat);
|
||||||
|
if (batterylevel > 100.) {
|
||||||
|
batterylevel = 100;
|
||||||
|
}
|
||||||
|
this->batterylevel_sensor_->publish_state(batterylevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateBrightness();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AXP192Component::begin(bool disableLDO2, bool disableLDO3, bool disableRTC, bool disableDCDC1, bool disableDCDC3)
|
||||||
|
{
|
||||||
|
// Set LDO2 & LDO3(TFT_LED & TFT) 3.0V
|
||||||
|
Write1Byte(0x28, 0xcc);
|
||||||
|
|
||||||
|
// Set ADC sample rate to 200hz
|
||||||
|
Write1Byte(0x84, 0b11110010);
|
||||||
|
|
||||||
|
// Set ADC to All Enable
|
||||||
|
Write1Byte(0x82, 0xff);
|
||||||
|
|
||||||
|
// Bat charge voltage to 4.2, Current 100MA
|
||||||
|
Write1Byte(0x33, 0xc0);
|
||||||
|
|
||||||
|
// Depending on configuration enable LDO2, LDO3, DCDC1, DCDC3.
|
||||||
|
byte buf = (Read8bit(0x12) & 0xef) | 0x4D;
|
||||||
|
if(disableLDO3) buf &= ~(1<<3);
|
||||||
|
if(disableLDO2) buf &= ~(1<<2);
|
||||||
|
if(disableDCDC3) buf &= ~(1<<1);
|
||||||
|
if(disableDCDC1) buf &= ~(1<<0);
|
||||||
|
Write1Byte(0x12, buf);
|
||||||
|
|
||||||
|
// 128ms power on, 4s power off
|
||||||
|
Write1Byte(0x36, 0x0C);
|
||||||
|
|
||||||
|
if(!disableRTC)
|
||||||
|
{
|
||||||
|
// Set RTC voltage to 3.3V
|
||||||
|
Write1Byte(0x91, 0xF0);
|
||||||
|
|
||||||
|
// Set GPIO0 to LDO
|
||||||
|
Write1Byte(0x90, 0x02);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable vbus hold limit
|
||||||
|
Write1Byte(0x30, 0x80);
|
||||||
|
|
||||||
|
// Set temperature protection
|
||||||
|
Write1Byte(0x39, 0xfc);
|
||||||
|
|
||||||
|
// Enable RTC BAT charge
|
||||||
|
Write1Byte(0x35, 0xa2 & (disableRTC ? 0x7F : 0xFF));
|
||||||
|
|
||||||
|
// Enable bat detection
|
||||||
|
Write1Byte(0x32, 0x46);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AXP192Component::Write1Byte( uint8_t Addr , uint8_t Data )
|
||||||
|
{
|
||||||
|
this->write_byte(Addr, Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t AXP192Component::Read8bit( uint8_t Addr )
|
||||||
|
{
|
||||||
|
uint8_t data;
|
||||||
|
this->read_byte(Addr, &data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t AXP192Component::Read12Bit( uint8_t Addr)
|
||||||
|
{
|
||||||
|
uint16_t Data = 0;
|
||||||
|
uint8_t buf[2];
|
||||||
|
ReadBuff(Addr,2,buf);
|
||||||
|
Data = ((buf[0] << 4) + buf[1]); //
|
||||||
|
return Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t AXP192Component::Read13Bit( uint8_t Addr)
|
||||||
|
{
|
||||||
|
uint16_t Data = 0;
|
||||||
|
uint8_t buf[2];
|
||||||
|
ReadBuff(Addr,2,buf);
|
||||||
|
Data = ((buf[0] << 5) + buf[1]); //
|
||||||
|
return Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t AXP192Component::Read16bit( uint8_t Addr )
|
||||||
|
{
|
||||||
|
uint32_t ReData = 0;
|
||||||
|
uint8_t Buff[2];
|
||||||
|
this->read_bytes(Addr, Buff, sizeof(Buff));
|
||||||
|
for( int i = 0 ; i < sizeof(Buff) ; i++ )
|
||||||
|
{
|
||||||
|
ReData <<= 8;
|
||||||
|
ReData |= Buff[i];
|
||||||
|
}
|
||||||
|
return ReData;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t AXP192Component::Read24bit( uint8_t Addr )
|
||||||
|
{
|
||||||
|
uint32_t ReData = 0;
|
||||||
|
uint8_t Buff[3];
|
||||||
|
this->read_bytes(Addr, Buff, sizeof(Buff));
|
||||||
|
for( int i = 0 ; i < sizeof(Buff) ; i++ )
|
||||||
|
{
|
||||||
|
ReData <<= 8;
|
||||||
|
ReData |= Buff[i];
|
||||||
|
}
|
||||||
|
return ReData;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t AXP192Component::Read32bit( uint8_t Addr )
|
||||||
|
{
|
||||||
|
uint32_t ReData = 0;
|
||||||
|
uint8_t Buff[4];
|
||||||
|
this->read_bytes(Addr, Buff, sizeof(Buff));
|
||||||
|
for( int i = 0 ; i < sizeof(Buff) ; i++ )
|
||||||
|
{
|
||||||
|
ReData <<= 8;
|
||||||
|
ReData |= Buff[i];
|
||||||
|
}
|
||||||
|
return ReData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AXP192Component::ReadBuff( uint8_t Addr , uint8_t Size , uint8_t *Buff )
|
||||||
|
{
|
||||||
|
this->read_bytes(Addr, Buff, Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AXP192Component::UpdateBrightness()
|
||||||
|
{
|
||||||
|
ESP_LOGD(TAG, "Brightness=%f (Curr: %f)", brightness_, curr_brightness_);
|
||||||
|
if (brightness_ == curr_brightness_)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
curr_brightness_ = brightness_;
|
||||||
|
|
||||||
|
const uint8_t c_min = 7;
|
||||||
|
const uint8_t c_max = 12;
|
||||||
|
auto ubri = c_min + static_cast<uint8_t>(brightness_ * (c_max - c_min));
|
||||||
|
|
||||||
|
if (ubri > c_max)
|
||||||
|
{
|
||||||
|
ubri = c_max;
|
||||||
|
}
|
||||||
|
uint8_t buf = Read8bit( 0x28 );
|
||||||
|
Write1Byte( 0x28 , ((buf & 0x0f) | (ubri << 4)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AXP192Component::GetBatState()
|
||||||
|
{
|
||||||
|
if( Read8bit(0x01) | 0x20 )
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t AXP192Component::GetBatData()
|
||||||
|
{
|
||||||
|
return Read8bit(0x75);
|
||||||
|
}
|
||||||
|
//---------coulombcounter_from_here---------
|
||||||
|
//enable: void EnableCoulombcounter(void);
|
||||||
|
//disable: void DisableCOulombcounter(void);
|
||||||
|
//stop: void StopCoulombcounter(void);
|
||||||
|
//clear: void ClearCoulombcounter(void);
|
||||||
|
//get charge data: uint32_t GetCoulombchargeData(void);
|
||||||
|
//get discharge data: uint32_t GetCoulombdischargeData(void);
|
||||||
|
//get coulomb val affter calculation: float GetCoulombData(void);
|
||||||
|
//------------------------------------------
|
||||||
|
void AXP192Component::EnableCoulombcounter(void)
|
||||||
|
{
|
||||||
|
Write1Byte( 0xB8 , 0x80 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AXP192Component::DisableCoulombcounter(void)
|
||||||
|
{
|
||||||
|
Write1Byte( 0xB8 , 0x00 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AXP192Component::StopCoulombcounter(void)
|
||||||
|
{
|
||||||
|
Write1Byte( 0xB8 , 0xC0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AXP192Component::ClearCoulombcounter(void)
|
||||||
|
{
|
||||||
|
Write1Byte( 0xB8 , 0xA0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t AXP192Component::GetCoulombchargeData(void)
|
||||||
|
{
|
||||||
|
return Read32bit(0xB0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t AXP192Component::GetCoulombdischargeData(void)
|
||||||
|
{
|
||||||
|
return Read32bit(0xB4);
|
||||||
|
}
|
||||||
|
|
||||||
|
float AXP192Component::GetCoulombData(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t coin = 0;
|
||||||
|
uint32_t coout = 0;
|
||||||
|
|
||||||
|
coin = GetCoulombchargeData();
|
||||||
|
coout = GetCoulombdischargeData();
|
||||||
|
|
||||||
|
//c = 65536 * current_LSB * (coin - coout) / 3600 / ADC rate
|
||||||
|
//Adc rate can be read from 84H ,change this variable if you change the ADC reate
|
||||||
|
float ccc = 65536 * 0.5 * (coin - coout) / 3600.0 / 25.0;
|
||||||
|
return ccc;
|
||||||
|
|
||||||
|
}
|
||||||
|
//----------coulomb_end_at_here----------
|
||||||
|
|
||||||
|
uint16_t AXP192Component::GetVbatData(void){
|
||||||
|
|
||||||
|
uint16_t vbat = 0;
|
||||||
|
uint8_t buf[2];
|
||||||
|
ReadBuff(0x78,2,buf);
|
||||||
|
vbat = ((buf[0] << 4) + buf[1]); // V
|
||||||
|
return vbat;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t AXP192Component::GetVinData(void)
|
||||||
|
{
|
||||||
|
uint16_t vin = 0;
|
||||||
|
uint8_t buf[2];
|
||||||
|
ReadBuff(0x56,2,buf);
|
||||||
|
vin = ((buf[0] << 4) + buf[1]); // V
|
||||||
|
return vin;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t AXP192Component::GetIinData(void)
|
||||||
|
{
|
||||||
|
uint16_t iin = 0;
|
||||||
|
uint8_t buf[2];
|
||||||
|
ReadBuff(0x58,2,buf);
|
||||||
|
iin = ((buf[0] << 4) + buf[1]);
|
||||||
|
return iin;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t AXP192Component::GetVusbinData(void)
|
||||||
|
{
|
||||||
|
uint16_t vin = 0;
|
||||||
|
uint8_t buf[2];
|
||||||
|
ReadBuff(0x5a,2,buf);
|
||||||
|
vin = ((buf[0] << 4) + buf[1]); // V
|
||||||
|
return vin;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t AXP192Component::GetIusbinData(void)
|
||||||
|
{
|
||||||
|
uint16_t iin = 0;
|
||||||
|
uint8_t buf[2];
|
||||||
|
ReadBuff(0x5C,2,buf);
|
||||||
|
iin = ((buf[0] << 4) + buf[1]);
|
||||||
|
return iin;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t AXP192Component::GetIchargeData(void)
|
||||||
|
{
|
||||||
|
uint16_t icharge = 0;
|
||||||
|
uint8_t buf[2];
|
||||||
|
ReadBuff(0x7A,2,buf);
|
||||||
|
icharge = ( buf[0] << 5 ) + buf[1] ;
|
||||||
|
return icharge;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t AXP192Component::GetIdischargeData(void)
|
||||||
|
{
|
||||||
|
uint16_t idischarge = 0;
|
||||||
|
uint8_t buf[2];
|
||||||
|
ReadBuff(0x7C,2,buf);
|
||||||
|
idischarge = ( buf[0] << 5 ) + buf[1] ;
|
||||||
|
return idischarge;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t AXP192Component::GetTempData(void)
|
||||||
|
{
|
||||||
|
uint16_t temp = 0;
|
||||||
|
uint8_t buf[2];
|
||||||
|
ReadBuff(0x5e,2,buf);
|
||||||
|
temp = ((buf[0] << 4) + buf[1]);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t AXP192Component::GetPowerbatData(void)
|
||||||
|
{
|
||||||
|
uint32_t power = 0;
|
||||||
|
uint8_t buf[3];
|
||||||
|
ReadBuff(0x70,2,buf);
|
||||||
|
power = (buf[0] << 16) + (buf[1] << 8) + buf[2];
|
||||||
|
return power;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t AXP192Component::GetVapsData(void)
|
||||||
|
{
|
||||||
|
uint16_t vaps = 0;
|
||||||
|
uint8_t buf[2];
|
||||||
|
ReadBuff(0x7e,2,buf);
|
||||||
|
vaps = ((buf[0] << 4) + buf[1]);
|
||||||
|
return vaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AXP192Component::SetSleep(void)
|
||||||
|
{
|
||||||
|
Write1Byte(0x31 , Read8bit(0x31) | ( 1 << 3)); // Power off voltag 3.0v
|
||||||
|
Write1Byte(0x90 , Read8bit(0x90) | 0x07); // GPIO1 floating
|
||||||
|
Write1Byte(0x82, 0x00); // Disable ADCs
|
||||||
|
Write1Byte(0x12, Read8bit(0x12) & 0xA1); // Disable all outputs but DCDC1
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- sleep
|
||||||
|
void AXP192Component::DeepSleep(uint64_t time_in_us)
|
||||||
|
{
|
||||||
|
SetSleep();
|
||||||
|
esp_sleep_enable_ext0_wakeup((gpio_num_t)37, LOW);
|
||||||
|
if (time_in_us > 0)
|
||||||
|
{
|
||||||
|
esp_sleep_enable_timer_wakeup(time_in_us);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
|
||||||
|
}
|
||||||
|
(time_in_us == 0) ? esp_deep_sleep_start() : esp_deep_sleep(time_in_us);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AXP192Component::LightSleep(uint64_t time_in_us)
|
||||||
|
{
|
||||||
|
if (time_in_us > 0)
|
||||||
|
{
|
||||||
|
esp_sleep_enable_timer_wakeup(time_in_us);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
|
||||||
|
}
|
||||||
|
esp_light_sleep_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0 not press, 0x01 long press, 0x02 press
|
||||||
|
uint8_t AXP192Component::GetBtnPress()
|
||||||
|
{
|
||||||
|
uint8_t state = Read8bit(0x46);
|
||||||
|
if(state)
|
||||||
|
{
|
||||||
|
Write1Byte( 0x46 , 0x03 );
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t AXP192Component::GetWarningLevel(void)
|
||||||
|
{
|
||||||
|
return Read8bit(0x47) & 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AXP192Component::GetBatVoltage()
|
||||||
|
{
|
||||||
|
float ADCLSB = 1.1 / 1000.0;
|
||||||
|
uint16_t ReData = Read12Bit( 0x78 );
|
||||||
|
return ReData * ADCLSB;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AXP192Component::GetBatCurrent()
|
||||||
|
{
|
||||||
|
float ADCLSB = 0.5;
|
||||||
|
uint16_t CurrentIn = Read13Bit( 0x7A );
|
||||||
|
uint16_t CurrentOut = Read13Bit( 0x7C );
|
||||||
|
return ( CurrentIn - CurrentOut ) * ADCLSB;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AXP192Component::GetVinVoltage()
|
||||||
|
{
|
||||||
|
float ADCLSB = 1.7 / 1000.0;
|
||||||
|
uint16_t ReData = Read12Bit( 0x56 );
|
||||||
|
return ReData * ADCLSB;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AXP192Component::GetVinCurrent()
|
||||||
|
{
|
||||||
|
float ADCLSB = 0.625;
|
||||||
|
uint16_t ReData = Read12Bit( 0x58 );
|
||||||
|
return ReData * ADCLSB;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AXP192Component::GetVBusVoltage()
|
||||||
|
{
|
||||||
|
float ADCLSB = 1.7 / 1000.0;
|
||||||
|
uint16_t ReData = Read12Bit( 0x5A );
|
||||||
|
return ReData * ADCLSB;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AXP192Component::GetVBusCurrent()
|
||||||
|
{
|
||||||
|
float ADCLSB = 0.375;
|
||||||
|
uint16_t ReData = Read12Bit( 0x5C );
|
||||||
|
return ReData * ADCLSB;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AXP192Component::GetTempInAXP192()
|
||||||
|
{
|
||||||
|
float ADCLSB = 0.1;
|
||||||
|
const float OFFSET_DEG_C = -144.7;
|
||||||
|
uint16_t ReData = Read12Bit( 0x5E );
|
||||||
|
return OFFSET_DEG_C + ReData * ADCLSB;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AXP192Component::GetBatPower()
|
||||||
|
{
|
||||||
|
float VoltageLSB = 1.1;
|
||||||
|
float CurrentLCS = 0.5;
|
||||||
|
uint32_t ReData = Read24bit( 0x70 );
|
||||||
|
return VoltageLSB * CurrentLCS * ReData/ 1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AXP192Component::GetBatChargeCurrent()
|
||||||
|
{
|
||||||
|
float ADCLSB = 0.5;
|
||||||
|
uint16_t ReData = Read13Bit( 0x7A );
|
||||||
|
return ReData * ADCLSB;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AXP192Component::GetAPSVoltage()
|
||||||
|
{
|
||||||
|
float ADCLSB = 1.4 / 1000.0;
|
||||||
|
uint16_t ReData = Read12Bit( 0x7E );
|
||||||
|
return ReData * ADCLSB;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AXP192Component::GetBatCoulombInput()
|
||||||
|
{
|
||||||
|
uint32_t ReData = Read32bit( 0xB0 );
|
||||||
|
return ReData * 65536 * 0.5 / 3600 /25.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AXP192Component::GetBatCoulombOut()
|
||||||
|
{
|
||||||
|
uint32_t ReData = Read32bit( 0xB4 );
|
||||||
|
return ReData * 65536 * 0.5 / 3600 /25.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AXP192Component::SetCoulombClear()
|
||||||
|
{
|
||||||
|
Write1Byte(0xB8,0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AXP192Component::SetLDO2( bool State )
|
||||||
|
{
|
||||||
|
uint8_t buf = Read8bit(0x12);
|
||||||
|
if( State == true )
|
||||||
|
{
|
||||||
|
buf = (1<<2) | buf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf = ~(1<<2) & buf;
|
||||||
|
}
|
||||||
|
Write1Byte( 0x12 , buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AXP192Component::SetLDO3(bool State)
|
||||||
|
{
|
||||||
|
uint8_t buf = Read8bit(0x12);
|
||||||
|
if( State == true )
|
||||||
|
{
|
||||||
|
buf = (1<<3) | buf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf = ~(1<<3) & buf;
|
||||||
|
}
|
||||||
|
Write1Byte( 0x12 , buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AXP192Component::SetChargeCurrent(uint8_t current)
|
||||||
|
{
|
||||||
|
uint8_t buf = Read8bit(0x33);
|
||||||
|
buf = (buf & 0xf0) | (current & 0x07);
|
||||||
|
Write1Byte(0x33, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AXP192Component::PowerOff()
|
||||||
|
{
|
||||||
|
Write1Byte(0x32, Read8bit(0x32) | 0x80);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AXP192Component::SetAdcState(bool state)
|
||||||
|
{
|
||||||
|
Write1Byte(0x82, state ? 0xff : 0x00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
116
custom_components/axp192_disable/axp192.h
Normal file
116
custom_components/axp192_disable/axp192.h
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
#ifndef __AXP192_H__
|
||||||
|
#define __AXP192_H__
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
#include "esphome/components/sensor/sensor.h"
|
||||||
|
#include "esphome/components/i2c/i2c.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace axp192 {
|
||||||
|
|
||||||
|
#define SLEEP_MSEC(us) (((uint64_t)us) * 1000L)
|
||||||
|
#define SLEEP_SEC(us) (((uint64_t)us) * 1000000L)
|
||||||
|
#define SLEEP_MIN(us) (((uint64_t)us) * 60L * 1000000L)
|
||||||
|
#define SLEEP_HR(us) (((uint64_t)us) * 60L * 60L * 1000000L)
|
||||||
|
|
||||||
|
#define CURRENT_100MA (0b0000)
|
||||||
|
#define CURRENT_190MA (0b0001)
|
||||||
|
#define CURRENT_280MA (0b0010)
|
||||||
|
#define CURRENT_360MA (0b0011)
|
||||||
|
#define CURRENT_450MA (0b0100)
|
||||||
|
#define CURRENT_550MA (0b0101)
|
||||||
|
#define CURRENT_630MA (0b0110)
|
||||||
|
#define CURRENT_700MA (0b0111)
|
||||||
|
|
||||||
|
class AXP192Component : public PollingComponent, public i2c::I2CDevice {
|
||||||
|
public:
|
||||||
|
void set_batterylevel_sensor(sensor::Sensor *batterylevel_sensor) { batterylevel_sensor_ = batterylevel_sensor; }
|
||||||
|
void set_brightness(float brightness) { brightness_ = brightness; }
|
||||||
|
|
||||||
|
// ========== INTERNAL METHODS ==========
|
||||||
|
// (In most use cases you won't need these)
|
||||||
|
void setup() override;
|
||||||
|
void dump_config() override;
|
||||||
|
float get_setup_priority() const override;
|
||||||
|
void update() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
sensor::Sensor *batterylevel_sensor_;
|
||||||
|
float brightness_{1.0f};
|
||||||
|
float curr_brightness_{-1.0f};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LDO2: Display backlight
|
||||||
|
* LDO3: Display Control
|
||||||
|
* RTC: Don't set GPIO1 as LDO
|
||||||
|
* DCDC1: Main rail. When not set the controller shuts down.
|
||||||
|
* DCDC3: Use unknown
|
||||||
|
*/
|
||||||
|
void begin(bool disableLDO2 = false, bool disableLDO3 = false, bool disableRTC = false, bool disableDCDC1 = false, bool disableDCDC3 = false);
|
||||||
|
void UpdateBrightness();
|
||||||
|
bool GetBatState();
|
||||||
|
uint8_t GetBatData();
|
||||||
|
|
||||||
|
void EnableCoulombcounter(void);
|
||||||
|
void DisableCoulombcounter(void);
|
||||||
|
void StopCoulombcounter(void);
|
||||||
|
void ClearCoulombcounter(void);
|
||||||
|
uint32_t GetCoulombchargeData(void);
|
||||||
|
uint32_t GetCoulombdischargeData(void);
|
||||||
|
float GetCoulombData(void);
|
||||||
|
|
||||||
|
uint16_t GetVbatData(void) __attribute__((deprecated));
|
||||||
|
uint16_t GetIchargeData(void) __attribute__((deprecated));
|
||||||
|
uint16_t GetIdischargeData(void) __attribute__((deprecated));
|
||||||
|
uint16_t GetTempData(void) __attribute__((deprecated));
|
||||||
|
uint32_t GetPowerbatData(void) __attribute__((deprecated));
|
||||||
|
uint16_t GetVinData(void) __attribute__((deprecated));
|
||||||
|
uint16_t GetIinData(void) __attribute__((deprecated));
|
||||||
|
uint16_t GetVusbinData(void) __attribute__((deprecated));
|
||||||
|
uint16_t GetIusbinData(void) __attribute__((deprecated));
|
||||||
|
uint16_t GetVapsData(void) __attribute__((deprecated));
|
||||||
|
uint8_t GetBtnPress(void);
|
||||||
|
|
||||||
|
// -- sleep
|
||||||
|
void SetSleep(void);
|
||||||
|
void DeepSleep(uint64_t time_in_us = 0);
|
||||||
|
void LightSleep(uint64_t time_in_us = 0);
|
||||||
|
|
||||||
|
// void SetChargeVoltage( uint8_t );
|
||||||
|
void SetChargeCurrent( uint8_t );
|
||||||
|
float GetBatVoltage();
|
||||||
|
float GetBatCurrent();
|
||||||
|
float GetVinVoltage();
|
||||||
|
float GetVinCurrent();
|
||||||
|
float GetVBusVoltage();
|
||||||
|
float GetVBusCurrent();
|
||||||
|
float GetTempInAXP192();
|
||||||
|
float GetBatPower();
|
||||||
|
float GetBatChargeCurrent();
|
||||||
|
float GetAPSVoltage();
|
||||||
|
float GetBatCoulombInput();
|
||||||
|
float GetBatCoulombOut();
|
||||||
|
uint8_t GetWarningLevel(void);
|
||||||
|
void SetCoulombClear();
|
||||||
|
void SetLDO2( bool State );
|
||||||
|
void SetLDO3( bool State );
|
||||||
|
void SetAdcState(bool State);
|
||||||
|
|
||||||
|
void PowerOff();
|
||||||
|
|
||||||
|
|
||||||
|
void Write1Byte( uint8_t Addr , uint8_t Data );
|
||||||
|
uint8_t Read8bit( uint8_t Addr );
|
||||||
|
uint16_t Read12Bit( uint8_t Addr);
|
||||||
|
uint16_t Read13Bit( uint8_t Addr);
|
||||||
|
uint16_t Read16bit( uint8_t Addr );
|
||||||
|
uint32_t Read24bit( uint8_t Addr );
|
||||||
|
uint32_t Read32bit( uint8_t Addr );
|
||||||
|
void ReadBuff( uint8_t Addr , uint8_t Size , uint8_t *Buff );
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
34
custom_components/axp192_disable/sensor.py
Normal file
34
custom_components/axp192_disable/sensor.py
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import i2c, sensor
|
||||||
|
from esphome.const import CONF_ID,\
|
||||||
|
CONF_BATTERY_LEVEL, CONF_BRIGHTNESS, UNIT_PERCENT, ICON_BATTERY
|
||||||
|
|
||||||
|
DEPENDENCIES = ['i2c']
|
||||||
|
|
||||||
|
axp192_ns = cg.esphome_ns.namespace('axp192')
|
||||||
|
|
||||||
|
AXP192Component = axp192_ns.class_('AXP192Component', cg.PollingComponent, i2c.I2CDevice)
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.Schema({
|
||||||
|
cv.GenerateID(): cv.declare_id(AXP192Component),
|
||||||
|
cv.Optional(CONF_BATTERY_LEVEL):
|
||||||
|
sensor.sensor_schema(UNIT_PERCENT, ICON_BATTERY, 1).extend({
|
||||||
|
}),
|
||||||
|
cv.Optional(CONF_BRIGHTNESS, default=1.0): cv.percentage,
|
||||||
|
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x77))
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
yield cg.register_component(var, config)
|
||||||
|
yield i2c.register_i2c_device(var, config)
|
||||||
|
|
||||||
|
if CONF_BATTERY_LEVEL in config:
|
||||||
|
conf = config[CONF_BATTERY_LEVEL]
|
||||||
|
sens = yield sensor.new_sensor(conf)
|
||||||
|
cg.add(var.set_batterylevel_sensor(sens))
|
||||||
|
|
||||||
|
if CONF_BRIGHTNESS in config:
|
||||||
|
conf = config[CONF_BRIGHTNESS]
|
||||||
|
cg.add(var.set_brightness(conf))
|
||||||
12
custom_components/heapmon/README.md
Normal file
12
custom_components/heapmon/README.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# heap space monitor
|
||||||
|
|
||||||
|
A sensor to show the available heap space.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```yaml
|
||||||
|
sensor:
|
||||||
|
- platform: heapmon
|
||||||
|
id: heapspace
|
||||||
|
name: "Free Space"
|
||||||
|
```
|
||||||
|
|
||||||
0
custom_components/heapmon/__init__.py
Normal file
0
custom_components/heapmon/__init__.py
Normal file
17
custom_components/heapmon/heapmon.cpp
Normal file
17
custom_components/heapmon/heapmon.cpp
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#include "heapmon.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace debug {
|
||||||
|
|
||||||
|
static const char *TAG = "heapmon";
|
||||||
|
|
||||||
|
void HeapMonitor::update() {
|
||||||
|
uint32_t free_heap = ESP.getFreeHeap();
|
||||||
|
ESP_LOGD(TAG, "Free Heap Size: %u bytes", free_heap);
|
||||||
|
this->publish_state(free_heap);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace debug
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
17
custom_components/heapmon/heapmon.h
Normal file
17
custom_components/heapmon/heapmon.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/components/sensor/sensor.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace debug {
|
||||||
|
|
||||||
|
class HeapMonitor : public sensor::Sensor, public PollingComponent {
|
||||||
|
public:
|
||||||
|
void update() override;
|
||||||
|
float get_setup_priority() const override { return setup_priority::LATE; };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace debug
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
18
custom_components/heapmon/sensor.py
Normal file
18
custom_components/heapmon/sensor.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import esphome.config_validation as cv
|
||||||
|
import esphome.codegen as cg
|
||||||
|
from esphome.components import sensor
|
||||||
|
from esphome.const import CONF_ID, ICON_GAUGE
|
||||||
|
|
||||||
|
UNIT_BYTE = "B"
|
||||||
|
|
||||||
|
debug_ns = cg.esphome_ns.namespace('debug')
|
||||||
|
HeapMonitor = debug_ns.class_('HeapMonitor', cg.PollingComponent)
|
||||||
|
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_BYTE, ICON_GAUGE, 0).extend({
|
||||||
|
cv.GenerateID(): cv.declare_id(HeapMonitor),
|
||||||
|
}).extend(cv.polling_component_schema('60s'))
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
yield cg.register_component(var, config)
|
||||||
|
yield sensor.register_sensor(var, config)
|
||||||
|
|
||||||
0
custom_components/ili9341_disable/__init__.py
Normal file
0
custom_components/ili9341_disable/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
61
custom_components/ili9341_disable/display.py
Normal file
61
custom_components/ili9341_disable/display.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome import pins
|
||||||
|
from esphome.components import display, spi
|
||||||
|
from esphome.const import CONF_DC_PIN, \
|
||||||
|
CONF_ID, CONF_LAMBDA, CONF_MODEL, CONF_PAGES, CONF_RESET_PIN
|
||||||
|
|
||||||
|
DEPENDENCIES = ['spi']
|
||||||
|
|
||||||
|
CONF_LED_PIN = 'led_pin'
|
||||||
|
|
||||||
|
ili9341_ns = cg.esphome_ns.namespace('ili9341')
|
||||||
|
ili9341 = ili9341_ns.class_('ILI9341Display', cg.PollingComponent, spi.SPIDevice,
|
||||||
|
display.DisplayBuffer)
|
||||||
|
ILI9341M5Stack = ili9341_ns.class_('ILI9341M5Stack', ili9341)
|
||||||
|
ILI9341TFT24 = ili9341_ns.class_('ILI9341TFT24', ili9341)
|
||||||
|
|
||||||
|
ILI9341Model = ili9341_ns.enum('ILI9341Model')
|
||||||
|
|
||||||
|
MODELS = {
|
||||||
|
'M5STACK': ILI9341Model.M5STACK,
|
||||||
|
'TFT_2.4': ILI9341Model.TFT_24,
|
||||||
|
}
|
||||||
|
|
||||||
|
ILI9341_MODEL = cv.enum(MODELS, upper=True, space="_")
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.All(display.FULL_DISPLAY_SCHEMA.extend({
|
||||||
|
cv.GenerateID(): cv.declare_id(ili9341),
|
||||||
|
cv.Required(CONF_MODEL): ILI9341_MODEL,
|
||||||
|
cv.Required(CONF_DC_PIN): pins.gpio_output_pin_schema,
|
||||||
|
cv.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema,
|
||||||
|
cv.Optional(CONF_LED_PIN): pins.gpio_output_pin_schema,
|
||||||
|
}).extend(cv.polling_component_schema('1s')).extend(spi.spi_device_schema()),
|
||||||
|
cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA))
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
if config[CONF_MODEL] == 'M5STACK':
|
||||||
|
lcd_type = ILI9341M5Stack
|
||||||
|
if config[CONF_MODEL] == 'TFT_2.4':
|
||||||
|
lcd_type = ILI9341TFT24
|
||||||
|
rhs = lcd_type.new()
|
||||||
|
var = cg.Pvariable(config[CONF_ID], rhs)
|
||||||
|
|
||||||
|
yield cg.register_component(var, config)
|
||||||
|
yield display.register_display(var, config)
|
||||||
|
yield spi.register_spi_device(var, config)
|
||||||
|
cg.add(var.set_model(config[CONF_MODEL]))
|
||||||
|
dc = yield cg.gpio_pin_expression(config[CONF_DC_PIN])
|
||||||
|
cg.add(var.set_dc_pin(dc))
|
||||||
|
|
||||||
|
if CONF_LAMBDA in config:
|
||||||
|
lambda_ = yield cg.process_lambda(config[CONF_LAMBDA], [(display.DisplayBufferRef, 'it')],
|
||||||
|
return_type=cg.void)
|
||||||
|
cg.add(var.set_writer(lambda_))
|
||||||
|
if CONF_RESET_PIN in config:
|
||||||
|
reset = yield cg.gpio_pin_expression(config[CONF_RESET_PIN])
|
||||||
|
cg.add(var.set_reset_pin(reset))
|
||||||
|
if CONF_LED_PIN in config:
|
||||||
|
led_pin = yield cg.gpio_pin_expression(config[CONF_LED_PIN])
|
||||||
|
cg.add(var.set_led_pin(led_pin))
|
||||||
83
custom_components/ili9341_disable/ili9341_defines.h
Normal file
83
custom_components/ili9341_disable/ili9341_defines.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace ili9341 {
|
||||||
|
|
||||||
|
// Color definitions
|
||||||
|
// clang-format off
|
||||||
|
static const uint8_t MADCTL_MY = 0x80; ///< Bit 7 Bottom to top
|
||||||
|
static const uint8_t MADCTL_MX = 0x40; ///< Bit 6 Right to left
|
||||||
|
static const uint8_t MADCTL_MV = 0x20; ///< Bit 5 Reverse Mode
|
||||||
|
static const uint8_t MADCTL_ML = 0x10; ///< Bit 4 LCD refresh Bottom to top
|
||||||
|
static const uint8_t MADCTL_RGB = 0x00; ///< Bit 3 Red-Green-Blue pixel order
|
||||||
|
static const uint8_t MADCTL_BGR = 0x08; ///< Bit 3 Blue-Green-Red pixel order
|
||||||
|
static const uint8_t MADCTL_MH = 0x04; ///< Bit 2 LCD refresh right to left
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
static const uint16_t ILI9341_TFTWIDTH = 320; ///< ILI9341 max TFT width
|
||||||
|
static const uint16_t ILI9341_TFTHEIGHT = 240; ///< ILI9341 max TFT height
|
||||||
|
|
||||||
|
// All ILI9341 specific commands some are used by init()
|
||||||
|
static const uint8_t ILI9341_NOP = 0x00;
|
||||||
|
static const uint8_t ILI9341_SWRESET = 0x01;
|
||||||
|
static const uint8_t ILI9341_RDDID = 0x04;
|
||||||
|
static const uint8_t ILI9341_RDDST = 0x09;
|
||||||
|
|
||||||
|
static const uint8_t ILI9341_SLPIN = 0x10;
|
||||||
|
static const uint8_t ILI9341_SLPOUT = 0x11;
|
||||||
|
static const uint8_t ILI9341_PTLON = 0x12;
|
||||||
|
static const uint8_t ILI9341_NORON = 0x13;
|
||||||
|
|
||||||
|
static const uint8_t ILI9341_RDMODE = 0x0A;
|
||||||
|
static const uint8_t ILI9341_RDMADCTL = 0x0B;
|
||||||
|
static const uint8_t ILI9341_RDPIXFMT = 0x0C;
|
||||||
|
static const uint8_t ILI9341_RDIMGFMT = 0x0A;
|
||||||
|
static const uint8_t ILI9341_RDSELFDIAG = 0x0F;
|
||||||
|
|
||||||
|
static const uint8_t ILI9341_INVOFF = 0x20;
|
||||||
|
static const uint8_t ILI9341_INVON = 0x21;
|
||||||
|
static const uint8_t ILI9341_GAMMASET = 0x26;
|
||||||
|
static const uint8_t ILI9341_DISPOFF = 0x28;
|
||||||
|
static const uint8_t ILI9341_DISPON = 0x29;
|
||||||
|
|
||||||
|
static const uint8_t ILI9341_CASET = 0x2A;
|
||||||
|
static const uint8_t ILI9341_PASET = 0x2B;
|
||||||
|
static const uint8_t ILI9341_RAMWR = 0x2C;
|
||||||
|
static const uint8_t ILI9341_RAMRD = 0x2E;
|
||||||
|
|
||||||
|
static const uint8_t ILI9341_PTLAR = 0x30;
|
||||||
|
static const uint8_t ILI9341_VSCRDEF = 0x33;
|
||||||
|
static const uint8_t ILI9341_MADCTL = 0x36;
|
||||||
|
static const uint8_t ILI9341_VSCRSADD = 0x37;
|
||||||
|
static const uint8_t ILI9341_PIXFMT = 0x3A;
|
||||||
|
|
||||||
|
static const uint8_t ILI9341_WRDISBV = 0x51;
|
||||||
|
static const uint8_t ILI9341_RDDISBV = 0x52;
|
||||||
|
static const uint8_t ILI9341_WRCTRLD = 0x53;
|
||||||
|
|
||||||
|
static const uint8_t ILI9341_FRMCTR1 = 0xB1;
|
||||||
|
static const uint8_t ILI9341_FRMCTR2 = 0xB2;
|
||||||
|
static const uint8_t ILI9341_FRMCTR3 = 0xB3;
|
||||||
|
static const uint8_t ILI9341_INVCTR = 0xB4;
|
||||||
|
static const uint8_t ILI9341_DFUNCTR = 0xB6;
|
||||||
|
|
||||||
|
static const uint8_t ILI9341_PWCTR1 = 0xC0;
|
||||||
|
static const uint8_t ILI9341_PWCTR2 = 0xC1;
|
||||||
|
static const uint8_t ILI9341_PWCTR3 = 0xC2;
|
||||||
|
static const uint8_t ILI9341_PWCTR4 = 0xC3;
|
||||||
|
static const uint8_t ILI9341_PWCTR5 = 0xC4;
|
||||||
|
static const uint8_t ILI9341_VMCTR1 = 0xC5;
|
||||||
|
static const uint8_t ILI9341_VMCTR2 = 0xC7;
|
||||||
|
|
||||||
|
static const uint8_t ILI9341_RDID4 = 0xD3;
|
||||||
|
static const uint8_t ILI9341_RDINDEX = 0xD9;
|
||||||
|
static const uint8_t ILI9341_RDID1 = 0xDA;
|
||||||
|
static const uint8_t ILI9341_RDID2 = 0xDB;
|
||||||
|
static const uint8_t ILI9341_RDID3 = 0xDC;
|
||||||
|
static const uint8_t ILI9341_RDIDX = 0xDD; // TBC
|
||||||
|
|
||||||
|
static const uint8_t ILI9341_GMCTRP1 = 0xE0;
|
||||||
|
static const uint8_t ILI9341_GMCTRN1 = 0xE1;
|
||||||
|
|
||||||
|
} // namespace ili9341
|
||||||
|
} // namespace esphome
|
||||||
240
custom_components/ili9341_disable/ili9341_display.cpp
Normal file
240
custom_components/ili9341_disable/ili9341_display.cpp
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
#include "ili9341_display.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "esphome/core/application.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace ili9341 {
|
||||||
|
|
||||||
|
static const char *TAG = "ili9341";
|
||||||
|
|
||||||
|
void ILI9341Display::setup_pins_() {
|
||||||
|
this->init_internal_(this->get_buffer_length_());
|
||||||
|
this->dc_pin_->setup(); // OUTPUT
|
||||||
|
this->dc_pin_->digital_write(false);
|
||||||
|
if (this->reset_pin_ != nullptr) {
|
||||||
|
this->reset_pin_->setup(); // OUTPUT
|
||||||
|
this->reset_pin_->digital_write(true);
|
||||||
|
}
|
||||||
|
if (this->led_pin_ != nullptr) {
|
||||||
|
this->led_pin_->setup();
|
||||||
|
this->led_pin_->digital_write(true);
|
||||||
|
}
|
||||||
|
this->spi_setup();
|
||||||
|
|
||||||
|
this->reset_();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ILI9341Display::dump_config() {
|
||||||
|
LOG_DISPLAY("", "ili9341", this);
|
||||||
|
ESP_LOGCONFIG(TAG, " Width: %d, Height: %d, Rotation: %d", this->width_, this->height_, this->rotation_);
|
||||||
|
LOG_PIN(" Reset Pin: ", this->reset_pin_);
|
||||||
|
LOG_PIN(" DC Pin: ", this->dc_pin_);
|
||||||
|
LOG_PIN(" Busy Pin: ", this->busy_pin_);
|
||||||
|
LOG_PIN(" Backlight Pin: ", this->led_pin_);
|
||||||
|
LOG_UPDATE_INTERVAL(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
float ILI9341Display::get_setup_priority() const { return setup_priority::PROCESSOR; }
|
||||||
|
void ILI9341Display::command(uint8_t value) {
|
||||||
|
this->start_command_();
|
||||||
|
this->write_byte(value);
|
||||||
|
this->end_command_();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ILI9341Display::reset_() {
|
||||||
|
if (this->reset_pin_ != nullptr) {
|
||||||
|
this->reset_pin_->digital_write(false);
|
||||||
|
delay(10);
|
||||||
|
this->reset_pin_->digital_write(true);
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ILI9341Display::data(uint8_t value) {
|
||||||
|
this->start_data_();
|
||||||
|
this->write_byte(value);
|
||||||
|
this->end_data_();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ILI9341Display::send_command(uint8_t command_byte, const uint8_t *data_bytes, uint8_t num_data_bytes) {
|
||||||
|
this->command(command_byte); // Send the command byte
|
||||||
|
this->start_data_();
|
||||||
|
this->write_array(data_bytes, num_data_bytes);
|
||||||
|
this->end_data_();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ILI9341Display::read_command(uint8_t command_byte, uint8_t index) {
|
||||||
|
uint8_t data = 0x10 + index;
|
||||||
|
this->send_command(0xD9, &data, 1); // Set Index Register
|
||||||
|
uint8_t result;
|
||||||
|
this->start_command_();
|
||||||
|
this->write_byte(command_byte);
|
||||||
|
this->start_data_();
|
||||||
|
do {
|
||||||
|
result = this->read_byte();
|
||||||
|
} while (index--);
|
||||||
|
this->end_data_();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ILI9341Display::update() {
|
||||||
|
this->do_update_();
|
||||||
|
this->display_();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ILI9341Display::display_() {
|
||||||
|
// we will only update the changed window to the display
|
||||||
|
int w = this->x_high_ - this->x_low_ + 1;
|
||||||
|
int h = this->y_high_ - this->y_low_ + 1;
|
||||||
|
|
||||||
|
set_addr_window_(this->x_low_, this->y_low_, w, h);
|
||||||
|
this->start_data_();
|
||||||
|
uint32_t start_pos = ((this->y_low_ * this->width_) + x_low_);
|
||||||
|
for (uint16_t row = 0; row < h; row++) {
|
||||||
|
for (uint16_t col = 0; col < w; col++) {
|
||||||
|
uint32_t pos = start_pos + (row * width_) + col;
|
||||||
|
|
||||||
|
uint16_t color = convert_to_16bit_color_(buffer_[pos]);
|
||||||
|
this->write_byte(color >> 8);
|
||||||
|
this->write_byte(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->end_data_();
|
||||||
|
|
||||||
|
// invalidate watermarks
|
||||||
|
this->x_low_ = this->width_;
|
||||||
|
this->y_low_ = this->height_;
|
||||||
|
this->x_high_ = 0;
|
||||||
|
this->y_high_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ILI9341Display::convert_to_16bit_color_(uint8_t color_8bit) {
|
||||||
|
int r = color_8bit >> 5;
|
||||||
|
int g = (color_8bit >> 2) & 0x07;
|
||||||
|
int b = color_8bit & 0x03;
|
||||||
|
uint16_t color = (r * 0x04) << 11;
|
||||||
|
color |= (g * 0x09) << 5;
|
||||||
|
color |= (b * 0x0A);
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ILI9341Display::convert_to_8bit_color_(uint16_t color_16bit) {
|
||||||
|
// convert 16bit color to 8 bit buffer
|
||||||
|
uint8_t r = color_16bit >> 11;
|
||||||
|
uint8_t g = (color_16bit >> 5) & 0x3F;
|
||||||
|
uint8_t b = color_16bit & 0x1F;
|
||||||
|
|
||||||
|
return ((b / 0x0A) | ((g / 0x09) << 2) | ((r / 0x04) << 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ILI9341Display::fill(Color color) {
|
||||||
|
auto color565 = color.to_rgb_565();
|
||||||
|
memset(this->buffer_, convert_to_8bit_color_(color565), this->get_buffer_length_());
|
||||||
|
this->x_low_ = 0;
|
||||||
|
this->y_low_ = 0;
|
||||||
|
this->x_high_ = this->get_width_internal() - 1;
|
||||||
|
this->y_high_ = this->get_height_internal() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ILI9341Display::fill_internal_(Color color) {
|
||||||
|
this->set_addr_window_(0, 0, this->get_width_internal(), this->get_height_internal());
|
||||||
|
this->start_data_();
|
||||||
|
|
||||||
|
auto color565 = color.to_rgb_565();
|
||||||
|
for (uint32_t i = 0; i < (this->get_width_internal()) * (this->get_height_internal()); i++) {
|
||||||
|
this->write_byte(color565 >> 8);
|
||||||
|
this->write_byte(color565);
|
||||||
|
buffer_[i] = 0;
|
||||||
|
}
|
||||||
|
this->end_data_();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HOT ILI9341Display::draw_absolute_pixel_internal(int x, int y, Color color) {
|
||||||
|
if (x >= this->get_width_internal() || x < 0 || y >= this->get_height_internal() || y < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// low and high watermark may speed up drawing from buffer
|
||||||
|
this->x_low_ = (x < this->x_low_) ? x : this->x_low_;
|
||||||
|
this->y_low_ = (y < this->y_low_) ? y : this->y_low_;
|
||||||
|
this->x_high_ = (x > this->x_high_) ? x : this->x_high_;
|
||||||
|
this->y_high_ = (y > this->y_high_) ? y : this->y_high_;
|
||||||
|
|
||||||
|
uint32_t pos = (y * width_) + x;
|
||||||
|
auto color565 = color.to_rgb_565();
|
||||||
|
buffer_[pos] = convert_to_8bit_color_(color565);
|
||||||
|
}
|
||||||
|
|
||||||
|
// should return the total size: return this->get_width_internal() * this->get_height_internal() * 2 // 16bit color
|
||||||
|
// values per bit is huge
|
||||||
|
uint32_t ILI9341Display::get_buffer_length_() { return this->get_width_internal() * this->get_height_internal(); }
|
||||||
|
|
||||||
|
void ILI9341Display::start_command_() {
|
||||||
|
this->dc_pin_->digital_write(false);
|
||||||
|
this->enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ILI9341Display::end_command_() { this->disable(); }
|
||||||
|
void ILI9341Display::start_data_() {
|
||||||
|
this->dc_pin_->digital_write(true);
|
||||||
|
this->enable();
|
||||||
|
}
|
||||||
|
void ILI9341Display::end_data_() { this->disable(); }
|
||||||
|
|
||||||
|
void ILI9341Display::init_lcd_(const uint8_t *init_cmd) {
|
||||||
|
uint8_t cmd, x, num_args;
|
||||||
|
const uint8_t *addr = init_cmd;
|
||||||
|
while ((cmd = pgm_read_byte(addr++)) > 0) {
|
||||||
|
x = pgm_read_byte(addr++);
|
||||||
|
num_args = x & 0x7F;
|
||||||
|
send_command(cmd, addr, num_args);
|
||||||
|
addr += num_args;
|
||||||
|
if (x & 0x80)
|
||||||
|
delay(150); // NOLINT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ILI9341Display::set_addr_window_(uint16_t x1, uint16_t y1, uint16_t w, uint16_t h) {
|
||||||
|
uint16_t x2 = (x1 + w - 1), y2 = (y1 + h - 1);
|
||||||
|
this->command(ILI9341_CASET); // Column address set
|
||||||
|
this->start_data_();
|
||||||
|
this->write_byte(x1 >> 8);
|
||||||
|
this->write_byte(x1);
|
||||||
|
this->write_byte(x2 >> 8);
|
||||||
|
this->write_byte(x2);
|
||||||
|
this->end_data_();
|
||||||
|
this->command(ILI9341_PASET); // Row address set
|
||||||
|
this->start_data_();
|
||||||
|
this->write_byte(y1 >> 8);
|
||||||
|
this->write_byte(y1);
|
||||||
|
this->write_byte(y2 >> 8);
|
||||||
|
this->write_byte(y2);
|
||||||
|
this->end_data_();
|
||||||
|
this->command(ILI9341_RAMWR); // Write to RAM
|
||||||
|
}
|
||||||
|
|
||||||
|
void ILI9341Display::invert_display_(bool invert) { this->command(invert ? ILI9341_INVON : ILI9341_INVOFF); }
|
||||||
|
|
||||||
|
int ILI9341Display::get_width_internal() { return this->width_; }
|
||||||
|
int ILI9341Display::get_height_internal() { return this->height_; }
|
||||||
|
|
||||||
|
// M5Stack display
|
||||||
|
void ILI9341M5Stack::initialize() {
|
||||||
|
this->init_lcd_(INITCMD_M5STACK);
|
||||||
|
this->width_ = 320;
|
||||||
|
this->height_ = 240;
|
||||||
|
this->invert_display_(true);
|
||||||
|
this->fill_internal_(COLOR_BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 24_TFT display
|
||||||
|
void ILI9341TFT24::initialize() {
|
||||||
|
this->init_lcd_(INITCMD_TFT);
|
||||||
|
this->width_ = 240;
|
||||||
|
this->height_ = 320;
|
||||||
|
this->fill_internal_(COLOR_BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ili9341
|
||||||
|
} // namespace esphome
|
||||||
92
custom_components/ili9341_disable/ili9341_display.h
Normal file
92
custom_components/ili9341_disable/ili9341_display.h
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/components/spi/spi.h"
|
||||||
|
#include "esphome/components/display/display_buffer.h"
|
||||||
|
#include "ili9341_defines.h"
|
||||||
|
#include "ili9341_init.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace ili9341 {
|
||||||
|
|
||||||
|
enum ILI9341Model {
|
||||||
|
M5STACK = 0,
|
||||||
|
TFT_24,
|
||||||
|
};
|
||||||
|
|
||||||
|
class ILI9341Display : public PollingComponent,
|
||||||
|
public display::DisplayBuffer,
|
||||||
|
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW,
|
||||||
|
spi::CLOCK_PHASE_LEADING, spi::DATA_RATE_40MHZ> {
|
||||||
|
public:
|
||||||
|
void set_dc_pin(GPIOPin *dc_pin) { dc_pin_ = dc_pin; }
|
||||||
|
float get_setup_priority() const override;
|
||||||
|
void set_reset_pin(GPIOPin *reset) { this->reset_pin_ = reset; }
|
||||||
|
void set_led_pin(GPIOPin *led) { this->led_pin_ = led; }
|
||||||
|
void set_model(ILI9341Model model) { this->model_ = model; }
|
||||||
|
|
||||||
|
void command(uint8_t value);
|
||||||
|
void data(uint8_t value);
|
||||||
|
void send_command(uint8_t command_byte, const uint8_t *data_bytes, uint8_t num_data_bytes);
|
||||||
|
uint8_t read_command(uint8_t command_byte, uint8_t index);
|
||||||
|
virtual void initialize() = 0;
|
||||||
|
|
||||||
|
void update() override;
|
||||||
|
|
||||||
|
void fill(Color color) override;
|
||||||
|
|
||||||
|
void dump_config() override;
|
||||||
|
void setup() override {
|
||||||
|
this->setup_pins_();
|
||||||
|
this->initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void draw_absolute_pixel_internal(int x, int y, Color color) override;
|
||||||
|
void setup_pins_();
|
||||||
|
|
||||||
|
void init_lcd_(const uint8_t *init_cmd);
|
||||||
|
void set_addr_window_(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||||||
|
void invert_display_(bool invert);
|
||||||
|
void reset_();
|
||||||
|
void fill_internal_(Color color);
|
||||||
|
void display_();
|
||||||
|
uint16_t convert_to_16bit_color_(uint8_t color_8bit);
|
||||||
|
uint8_t convert_to_8bit_color_(uint16_t color_16bit);
|
||||||
|
|
||||||
|
ILI9341Model model_;
|
||||||
|
int16_t width_{320}; ///< Display width as modified by current rotation
|
||||||
|
int16_t height_{240}; ///< Display height as modified by current rotation
|
||||||
|
uint16_t x_low_{0};
|
||||||
|
uint16_t y_low_{0};
|
||||||
|
uint16_t x_high_{0};
|
||||||
|
uint16_t y_high_{0};
|
||||||
|
|
||||||
|
uint32_t get_buffer_length_();
|
||||||
|
int get_width_internal() override;
|
||||||
|
int get_height_internal() override;
|
||||||
|
|
||||||
|
void start_command_();
|
||||||
|
void end_command_();
|
||||||
|
void start_data_();
|
||||||
|
void end_data_();
|
||||||
|
|
||||||
|
GPIOPin *reset_pin_{nullptr};
|
||||||
|
GPIOPin *led_pin_{nullptr};
|
||||||
|
GPIOPin *dc_pin_;
|
||||||
|
GPIOPin *busy_pin_{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------- M5Stack display --------------
|
||||||
|
class ILI9341M5Stack : public ILI9341Display {
|
||||||
|
public:
|
||||||
|
void initialize() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------- ILI9341_24_TFT display --------------
|
||||||
|
class ILI9341TFT24 : public ILI9341Display {
|
||||||
|
public:
|
||||||
|
void initialize() override;
|
||||||
|
};
|
||||||
|
} // namespace ili9341
|
||||||
|
} // namespace esphome
|
||||||
70
custom_components/ili9341_disable/ili9341_init.h
Normal file
70
custom_components/ili9341_disable/ili9341_init.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace ili9341 {
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
static const uint8_t PROGMEM INITCMD_M5STACK[] = {
|
||||||
|
0xEF, 3, 0x03, 0x80, 0x02,
|
||||||
|
0xCF, 3, 0x00, 0xC1, 0x30,
|
||||||
|
0xED, 4, 0x64, 0x03, 0x12, 0x81,
|
||||||
|
0xE8, 3, 0x85, 0x00, 0x78,
|
||||||
|
0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
|
||||||
|
0xF7, 1, 0x20,
|
||||||
|
0xEA, 2, 0x00, 0x00,
|
||||||
|
ILI9341_PWCTR1 , 1, 0x23, // Power control VRH[5:0]
|
||||||
|
ILI9341_PWCTR2 , 1, 0x10, // Power control SAP[2:0];BT[3:0]
|
||||||
|
ILI9341_VMCTR1 , 2, 0x3e, 0x28, // VCM control
|
||||||
|
ILI9341_VMCTR2 , 1, 0x86, // VCM control2
|
||||||
|
ILI9341_MADCTL , 1, MADCTL_BGR, // Memory Access Control
|
||||||
|
ILI9341_VSCRSADD, 1, 0x00, // Vertical scroll zero
|
||||||
|
ILI9341_PIXFMT , 1, 0x55,
|
||||||
|
ILI9341_FRMCTR1 , 2, 0x00, 0x13,
|
||||||
|
ILI9341_DFUNCTR , 3, 0x08, 0x82, 0x27, // Display Function Control
|
||||||
|
0xF2, 1, 0x00, // 3Gamma Function Disable
|
||||||
|
ILI9341_GAMMASET , 1, 0x01, // Gamma curve selected
|
||||||
|
ILI9341_GMCTRP1 , 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, // Set Gamma
|
||||||
|
0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03,
|
||||||
|
0x0E, 0x09, 0x00,
|
||||||
|
ILI9341_GMCTRN1 , 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, // Set Gamma
|
||||||
|
0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C,
|
||||||
|
0x31, 0x36, 0x0F,
|
||||||
|
ILI9341_SLPOUT , 0x80, // Exit Sleep
|
||||||
|
ILI9341_DISPON , 0x80, // Display on
|
||||||
|
0x00 // End of list
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t PROGMEM INITCMD_TFT[] = {
|
||||||
|
0xEF, 3, 0x03, 0x80, 0x02,
|
||||||
|
0xCF, 3, 0x00, 0xC1, 0x30,
|
||||||
|
0xED, 4, 0x64, 0x03, 0x12, 0x81,
|
||||||
|
0xE8, 3, 0x85, 0x00, 0x78,
|
||||||
|
0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
|
||||||
|
0xF7, 1, 0x20,
|
||||||
|
0xEA, 2, 0x00, 0x00,
|
||||||
|
ILI9341_PWCTR1 , 1, 0x23, // Power control VRH[5:0]
|
||||||
|
ILI9341_PWCTR2 , 1, 0x10, // Power control SAP[2:0];BT[3:0]
|
||||||
|
ILI9341_VMCTR1 , 2, 0x3e, 0x28, // VCM control
|
||||||
|
ILI9341_VMCTR2 , 1, 0x86, // VCM control2
|
||||||
|
ILI9341_MADCTL , 1, 0x48, // Memory Access Control
|
||||||
|
ILI9341_VSCRSADD, 1, 0x00, // Vertical scroll zero
|
||||||
|
ILI9341_PIXFMT , 1, 0x55,
|
||||||
|
ILI9341_FRMCTR1 , 2, 0x00, 0x18,
|
||||||
|
ILI9341_DFUNCTR , 3, 0x08, 0x82, 0x27, // Display Function Control
|
||||||
|
0xF2, 1, 0x00, // 3Gamma Function Disable
|
||||||
|
ILI9341_GAMMASET , 1, 0x01, // Gamma curve selected
|
||||||
|
ILI9341_GMCTRP1 , 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, // Set Gamma
|
||||||
|
0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03,
|
||||||
|
0x0E, 0x09, 0x00,
|
||||||
|
ILI9341_GMCTRN1 , 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, // Set Gamma
|
||||||
|
0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C,
|
||||||
|
0x31, 0x36, 0x0F,
|
||||||
|
ILI9341_SLPOUT , 0x80, // Exit Sleep
|
||||||
|
ILI9341_DISPON , 0x80, // Display on
|
||||||
|
0x00 // End of list
|
||||||
|
};
|
||||||
|
|
||||||
|
// clang-format on
|
||||||
|
} // namespace ili9341
|
||||||
|
} // namespace esphome
|
||||||
28
devices.csv
Normal file
28
devices.csv
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
m5stickc
|
||||||
|
mcu-basement
|
||||||
|
mcu-cam-1
|
||||||
|
mcu-clock-1
|
||||||
|
mcu-desk-lamp
|
||||||
|
mcu-dev-1
|
||||||
|
mcu-dev-2
|
||||||
|
mcu-dev-heating
|
||||||
|
mcu-dev-lora
|
||||||
|
mcu-dev-neo
|
||||||
|
mcu-dimmer
|
||||||
|
mcu-fireplace
|
||||||
|
mcu-gate
|
||||||
|
mcu-heating
|
||||||
|
mcu-irrigation-1
|
||||||
|
mcu-mini-01
|
||||||
|
mcu-mini-02
|
||||||
|
mcu-mini-03
|
||||||
|
mcu-mini-04
|
||||||
|
mcu-patio
|
||||||
|
mcu-rf433
|
||||||
|
mcu-socket-01
|
||||||
|
mcu-socket-02
|
||||||
|
mcu-socket-03
|
||||||
|
mcu-sw-office-r
|
||||||
|
mcu-tv-light
|
||||||
|
mcu-waterproof-socket
|
||||||
|
secrets
|
||||||
|
3
devices.sh
Executable file
3
devices.sh
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
ls -1 *.yaml | sed "s/.yaml//g" > devices.csv
|
||||||
4
devices_dev.csv
Normal file
4
devices_dev.csv
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
mcu-clock-1
|
||||||
|
mcu-nspanel-dev
|
||||||
|
mcu-gateway
|
||||||
|
mcu-atoms3
|
||||||
|
4
devices_dev_few.csv
Normal file
4
devices_dev_few.csv
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
nodemcu_cam_1
|
||||||
|
nodemcu_heating_dev
|
||||||
|
nodemcu_heating_dev_2
|
||||||
|
nodemcu_neo_0
|
||||||
|
7
devices_nspanel.csv
Normal file
7
devices_nspanel.csv
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
mcu-nspanel-bedroom
|
||||||
|
mcu-nspanel-dev
|
||||||
|
mcu-nspanel-ex
|
||||||
|
mcu-nspanel-office-j
|
||||||
|
mcu-nspanel-office-r
|
||||||
|
mcu-nspanel-patio
|
||||||
|
mcu-nspanel-fireplace
|
||||||
|
27
devices_prod.csv
Normal file
27
devices_prod.csv
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
mcu-basement
|
||||||
|
mcu-basement-2
|
||||||
|
mcu-clock-1
|
||||||
|
mcu-desk-lamp
|
||||||
|
mcu-dimmer
|
||||||
|
mcu-fireplace
|
||||||
|
mcu-echo
|
||||||
|
mcu-gate
|
||||||
|
mcu-heating
|
||||||
|
mcu-kitchen
|
||||||
|
mcu-office-r
|
||||||
|
mcu-mains-power
|
||||||
|
mcu-nspanel-bedroom
|
||||||
|
mcu-nspanel-office-j
|
||||||
|
mcu-nspanel-office-r
|
||||||
|
mcu-nspanel-patio
|
||||||
|
mcu-nspanel-fireplace
|
||||||
|
mcu-rf433
|
||||||
|
mcu-socket-01
|
||||||
|
mcu-socket-02
|
||||||
|
mcu-socket-03
|
||||||
|
mcu-patio
|
||||||
|
mcu-shed
|
||||||
|
mcu-staircase-light
|
||||||
|
mcu-tv-light
|
||||||
|
mcu-waterproof-socket
|
||||||
|
mcu-well
|
||||||
|
58
lora_sender.h
Normal file
58
lora_sender.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include "esphome.h"
|
||||||
|
#include "TinyLoRa.h"
|
||||||
|
#include "SPI.h"
|
||||||
|
|
||||||
|
using namespace esphome;
|
||||||
|
|
||||||
|
class lora_sender : public PollingComponent, public text_sensor::TextSensor {
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
lora_sender() : PollingComponent(15000) {}
|
||||||
|
|
||||||
|
// Network Session Key (MSB)
|
||||||
|
uint8_t NwkSkey[16] = { 0x31, 0x36, 0x41, 0x2E, 0xFE, 0x06, 0x84, 0x0B, 0x70, 0xB6, 0xCE, 0xBF, 0xBC, 0xAB, 0x06, 0x79 };
|
||||||
|
|
||||||
|
// Application Session Key (MSB)
|
||||||
|
uint8_t AppSkey[16] = { 0x93, 0x42, 0xD6, 0x50, 0xE4, 0xDE, 0x36, 0x11, 0x4E, 0x28, 0xEC, 0x31, 0xF5, 0x3A, 0xD7, 0x10 };
|
||||||
|
|
||||||
|
// Device Address (MSB)
|
||||||
|
uint8_t DevAddr[4] = { 0x26, 0x01, 0x17, 0xE0 };
|
||||||
|
// Data Packet to Send to TTN
|
||||||
|
//unsigned char loraData[11] = {"hello LoRa"};
|
||||||
|
char loraData[11];
|
||||||
|
|
||||||
|
// How many times data transfer should occur, in seconds
|
||||||
|
const unsigned int sendInterval = 30;
|
||||||
|
|
||||||
|
// Pinout for Adafruit Feather 32u4 LoRa
|
||||||
|
// TinyLoRa lora = TinyLoRa(irq, cs, rst);
|
||||||
|
TinyLoRa lora = TinyLoRa(18, 14, 26);
|
||||||
|
|
||||||
|
void setup() override {
|
||||||
|
//Serial.begin(115200);
|
||||||
|
Serial.begin(9600);
|
||||||
|
Serial.println("LoRa Sender");
|
||||||
|
//LoRa.setPins(18, 14, 26);
|
||||||
|
lora.setChannel(MULTI);
|
||||||
|
// set datarate
|
||||||
|
lora.setDatarate(SF7BW125);
|
||||||
|
if (!lora.begin()) {
|
||||||
|
Serial.println("Starting LoRa failed!");
|
||||||
|
while (1);
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
Serial.println("Sending data packet...");
|
||||||
|
}
|
||||||
|
|
||||||
|
void update() override {
|
||||||
|
// This will be called every "update_interval" milliseconds.
|
||||||
|
// Publish state
|
||||||
|
publish_state("Hello World");
|
||||||
|
Serial.println("Sending LoRa Data...");
|
||||||
|
strcpy(loraData,"Hello Lora");
|
||||||
|
lora.sendData((unsigned char *)loraData, sizeof(loraData), lora.frameCounter);
|
||||||
|
Serial.print("Frame Counter: ");Serial.println(lora.frameCounter);
|
||||||
|
lora.frameCounter++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user