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:
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
|
||||
Reference in New Issue
Block a user