Merge pull request #3 from paulchilton/master

Added an option for the M5TOUGH display
This commit is contained in:
martydingo
2023-04-17 12:28:38 +01:00
committed by GitHub
5 changed files with 263 additions and 8 deletions

View File

@@ -1,16 +1,24 @@
# ESPHome AXP192 Component
This custom component it to implement support for the AXP192 for both the M5Stick-C, and the M5Stack Core2, building on top of airy10's code.
Built on top of martydingo's version of the axp192 power management IC library for ESPHome, I have added support for the M5Tough, which requires a different register configuration for the M5Tough ILI9342C display. Other changes include a fix to stop the log being spammed with brightness values continually, these are only logged on change. Also the M5Tough needs resetting once the axp192 registers are set for the display to properly initialise so this version sets up the axp and then resets the ESP32 automatically.
## Installation
Copy the components to a custom_components directory next to your .yaml configuration file.
Copy the components to a custom_components directory next to your .yaml configuration file, or include directly from this repository.
## Configuration
Sample configurations can be found within `/sample-config`. Please note that I've not yet been able to correctly configure the M5Stick-C screen just yet, however the AXP192 component does initalise it, and the sample configuration currently demostrates a white screen, when it should present some text. I plan to fix this soon.
Sample configurations are found in the `/sample-config` folder.
This component adds a new model configuration to the AXP192 sensor, `model: M5CORE2` & `model: M5STICKC`, as so the right pins are initalized and voltages go to the right places:
This component adds a new model configuration to the AXP192 sensor which determines which registers are needed for each device. Available models are `model: M5CORE2`, `model: M5STICKC` and `model: M5TOUGH`.
### Include axp192 component
```yaml
external_components:
- source: github://paulchilton/esphome-axp192
components: [axp192]
```
### M5Stick-C
@@ -39,3 +47,30 @@ sensor:
name: "${upper_devicename} Battery Level"
id: "${devicename}_batterylevel"
```
### M5Tough
```yaml
sensor:
- platform: axp192
model: M5Tough
address: 0x34
i2c_id: bus_a
update_interval: 30s
battery_level:
name: "${upper_devicename} Battery Level"
id: "${devicename}_batterylevel"
```
The display component required for the M5Tough is as follows:
```yaml
display:
- platform: ili9341
# 320x240
model: M5STACK
cs_pin: GPIO5
dc_pin: GPIO15
lambda: |-
it.print(160, 0, id(title_font), id(color_white), TextAlign::TOP_CENTER, "Hello World");
```

View File

@@ -1,6 +1,7 @@
#include "axp192.h"
#include "esphome/core/log.h"
#include "esp_sleep.h"
#include <Esp.h>
namespace esphome {
namespace axp192 {
@@ -18,6 +19,19 @@ void AXP192Component::setup()
// disable LDO3 Vibration
begin(false, true, false, false, false);
}
case AXP192_M5TOUGH:
{
begin(false, false, false, false, false);
// If we're waking from a cold boot
if (GetStartupReason() == "ESP_RST_POWERON")
{
ESP_LOGD(TAG, "First power on, restarting ESP...");
// Reboot the ESP with the axp initialised
ESP.restart();
}
}
}
}
@@ -63,6 +77,13 @@ void AXP192Component::begin(bool disableLDO2, bool disableLDO3, bool disableRTC,
// Set LDO2 & LDO3(TFT_LED & TFT) 3.0V
Write1Byte(0x28, 0xcc);
}
case AXP192_M5TOUGH:
{
// Set DCDC3 (TFT_LED & TFT) 3.0V
Write1Byte(0x27, 0xcc);
// Set LDO2 & LDO3(TFT_LED & TFT) 3.0V
Write1Byte(0x28, 0xcc);
}
}
// Set ADC sample rate to 200hz
@@ -105,6 +126,7 @@ void AXP192Component::begin(bool disableLDO2, bool disableLDO3, bool disableRTC,
// Enable bat detection
Write1Byte(0x32, 0x46);
}
void AXP192Component::Write1Byte( uint8_t Addr , uint8_t Data )
@@ -183,11 +205,12 @@ void AXP192Component::ReadBuff( uint8_t Addr , uint8_t Size , uint8_t *Buff )
void AXP192Component::UpdateBrightness()
{
ESP_LOGD(TAG, "Brightness=%f (Curr: %f)", brightness_, curr_brightness_);
if (brightness_ == curr_brightness_)
{
return;
}
ESP_LOGD(TAG, "Brightness=%f (Curr: %f)", brightness_, curr_brightness_);
curr_brightness_ = brightness_;
const uint8_t c_min = 7;
@@ -207,13 +230,18 @@ void AXP192Component::UpdateBrightness()
case AXP192_M5CORE2:
{
uint8_t buf = Read8bit( 0x27 );
Write1Byte( 0x27 , ((buf & 0x80) | (ubri << 3)) );
Write1Byte( 0x27 , ((buf & 0x80) | (ubri << 3)) );
}
case AXP192_M5TOUGH:
{
uint8_t buf = Read8bit( 0x27 );
Write1Byte( 0x27 , ((buf & 0x80) | (ubri << 3)) );
}
}
}
bool AXP192Component::GetBatState()
{
{
if( Read8bit(0x01) | 0x20 )
return true;
else
@@ -541,7 +569,6 @@ void AXP192Component::SetLDO3(bool State)
Write1Byte( 0x12 , buf );
}
void AXP192Component::SetChargeCurrent(uint8_t current)
{
uint8_t buf = Read8bit(0x33);
@@ -558,6 +585,51 @@ void AXP192Component::SetAdcState(bool state)
{
Write1Byte(0x82, state ? 0xff : 0x00);
}
std::string AXP192Component::GetStartupReason() {
esp_reset_reason_t reset_reason = ::esp_reset_reason();
if (reset_reason == ESP_RST_DEEPSLEEP) {
esp_sleep_source_t wake_reason = esp_sleep_get_wakeup_cause();
if (wake_reason == ESP_SLEEP_WAKEUP_EXT0)
return "ESP_SLEEP_WAKEUP_EXT0";
if (wake_reason == ESP_SLEEP_WAKEUP_EXT0)
return "ESP_SLEEP_WAKEUP_EXT0";
if (wake_reason == ESP_SLEEP_WAKEUP_EXT1)
return "ESP_SLEEP_WAKEUP_EXT1";
if (wake_reason == ESP_SLEEP_WAKEUP_TIMER)
return "ESP_SLEEP_WAKEUP_TIMER";
if (wake_reason == ESP_SLEEP_WAKEUP_TOUCHPAD)
return "ESP_SLEEP_WAKEUP_TOUCHPAD";
if (wake_reason == ESP_SLEEP_WAKEUP_ULP)
return "ESP_SLEEP_WAKEUP_ULP";
if (wake_reason == ESP_SLEEP_WAKEUP_GPIO)
return "ESP_SLEEP_WAKEUP_GPIO";
if (wake_reason == ESP_SLEEP_WAKEUP_UART)
return "ESP_SLEEP_WAKEUP_UART";
return std::string{"WAKEUP_UNKNOWN_REASON"};
}
if (reset_reason == ESP_RST_UNKNOWN)
return "ESP_RST_UNKNOWN";
if (reset_reason == ESP_RST_POWERON)
return "ESP_RST_POWERON";
if (reset_reason == ESP_RST_SW)
return "ESP_RST_SW";
if (reset_reason == ESP_RST_PANIC)
return "ESP_RST_PANIC";
if (reset_reason == ESP_RST_INT_WDT)
return "ESP_RST_INT_WDT";
if (reset_reason == ESP_RST_TASK_WDT)
return "ESP_RST_TASK_WDT";
if (reset_reason == ESP_RST_WDT)
return "ESP_RST_WDT";
if (reset_reason == ESP_RST_BROWNOUT)
return "ESP_RST_BROWNOUT";
if (reset_reason == ESP_RST_SDIO)
return "ESP_RST_SDIO";
return std::string{"RESET_UNKNOWN_REASON"};
}
}
}

View File

@@ -11,6 +11,7 @@ namespace axp192 {
enum AXP192Model {
AXP192_M5STICKC = 0,
AXP192_M5CORE2,
AXP192_M5TOUGH,
};
#define SLEEP_MSEC(us) (((uint64_t)us) * 1000L)
@@ -40,6 +41,9 @@ public:
float get_setup_priority() const override;
void update() override;
private:
static std::string GetStartupReason();
protected:
sensor::Sensor *batterylevel_sensor_;
float brightness_{1.0f};

View File

@@ -13,6 +13,7 @@ AXP192Model = axp192_ns.enum("AXP192Model")
MODELS = {
"M5CORE2": AXP192Model.AXP192_M5CORE2,
"M5STICKC": AXP192Model.AXP192_M5STICKC,
"M5TOUGH": AXP192Model.AXP192_M5TOUGH,
}
AXP192_MODEL = cv.enum(MODELS, upper=True, space="_")

143
sample-config/m5tough.yaml Normal file
View File

@@ -0,0 +1,143 @@
esphome:
name: m5tough
esp32:
board: m5stack-core2
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
# Enable over the air programming
ota:
# Enable WiFi connection
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_pass
# Include the required components for this device
external_components:
- source: github://paulchilton/esphome-axp192
components: [axp192]
# SPI bus
spi:
clk_pin: GPIO18
mosi_pin: GPIO23
miso_pin: GPIO38
# I2C bus
i2c:
- id: bus_a
sda: GPIO21
scl: GPIO22
# Define sensors
sensor:
- platform: axp192
model: M5TOUGH
address: 0x34
i2c_id: bus_a
update_interval: 3s
brightness: 75%
- platform: uptime
name: "Uptime"
- platform: wifi_signal
name: "WiFi Signal"
update_interval: 60s
id: wifi_strength
text_sensor:
- platform: wifi_info
ip_address:
id: ip_address
# M5 Tough has a built in speaker which can be used by home assistant as a media player
media_player:
- platform: i2s_audio
name: M5TOUGH I2S Media Player
dac_type: external
i2s_lrclk_pin: GPIO0
i2s_dout_pin: GPIO2
i2s_bclk_pin: GPIO12
mode: stereo
# Setup a simple input that triggers when the screen is touched anywhere
binary_sensor:
- platform: gpio
id: touchscreen_pressed
name: Touch Screen Pressed
pin:
number: 39
on_press:
then:
- logger.log: "Screen was pressed"
# Also, send an event to home assistant api to indicate someone has pressed the screen.
- homeassistant.event:
event: esphome.screen_pressed
data:
message: Toughscreen was pressed
# Fonts used on the display
font:
- file: "gfonts://Roboto"
id: title_font
size: 38
- file: "gfonts://Roboto"
id: large_font
size: 42
- file: "gfonts://Roboto"
id: mid_font
size: 28
- file: "gfonts://Roboto"
id: small_font
size: 18
# Colours used on the display
color:
- id: color_white
red: 100%
green: 100%
blue: 100%
- id: color_grey
red: 30%
green: 30%
blue: 40%
- id: color_red
red: 100%
green: 3%
blue: 5%
# Display definition with a simple header and footer showing WiFi connection details
display:
- platform: ili9341
# 320x240
model: M5STACK
cs_pin: GPIO5
dc_pin: GPIO15
lambda: |-
// Header
it.print(160, 0, id(title_font), id(color_white), TextAlign::TOP_CENTER, "Hello World");
it.line(0, 50, it.get_width(), 50, id(color_grey));
// Footer
it.line(0, 215, it.get_width(), 215, id(color_grey));
if(isnan(id(wifi_strength).state) == 0){
it.printf(240, 220, id(small_font), id(color_white), TextAlign::TOP_LEFT, "%.1fdB", id(wifi_strength).state);
}
else
{
it.printf(160, 220, id(small_font), id(color_red), TextAlign::TOP_CENTER, "Disconnected");
}
it.printf(10, 220, id(small_font), id(color_white), TextAlign::TOP_LEFT, "%s", id(ip_address).state.c_str());