Compare commits

..
97 Commits
Author SHA1 Message Date
randy eea872b930 mcu-stackchan: spectrum analyzer, head touch gestures, status bar
- Winamp style spectrum analyzer instead of the face while music plays,
  using audio_spectrum from randybb/esphome-components
- head touch: tap starts the assistant, stroking shows an in-love face;
  SI12T sensitivity raised so the pads actually trigger
- battery (AXP2101) and wifi indicators, ear icon while listening
2026-09-27 15:19:07 +02:00
randy 39e744900d mcu-stackchan: add M5Stack StackChan config
Voice assistant satellite with animated face on the CoreS3 display:
- power rails, IO expander resets and servo power as in the M5 BSP
- mic and speaker share one I2S bus, so the mic is released before playback
- AW88298 volume limited to the audible range (0.5-1.0)
- partial display redraws, status screen until Home Assistant connects
- battery and wifi indicators, listening icon
- camera converted to JPEG on demand, no periodic frames
2026-09-27 14:02:40 +02:00
randy 6348e6bbb6 mcu-nspanel-*: migrate to native nspanel_lovelace component
CI / ESPHome config validation (push) Failing after 14s
CI / YAML lint (push) Failing after 32s
Switch all NSPanels from the MQTT + AppDaemon based
esphome-nspanel-lovelace-ui to the native component
(randybb/esphome-nspanel-lovelace-native, ref: devices).
Cards and screensaver are now configured directly in ESPHome,
removing the dependency on MQTT and AppDaemon.
2026-09-26 19:31:16 +02:00
randy 6a40e65a4b mcu-nspanel: drop local sk.json, use built-in sk translation from fork 2026-09-26 18:05:23 +02:00
randy a6605fe5e4 Add CLAUDE.md: no Claude attribution in commits/PRs 2026-09-25 23:14:35 +02:00
randyandClaude Sonnet 5 0daecc2fb9 mcu-lvgl-trainer, mcu-lvgl-eworkbench: migrate display to mipi_spi
CI / ESPHome config validation (push) Failing after 8s
CI / YAML lint (push) Failing after 52s
qspi_dbi is deprecated in favor of mipi_spi. Also fixes
mcu-lvgl-trainer's LVGL rotation (must be set on the lvgl component,
not the display, when LVGL is in use) and its deprecated
publish_initial_state -> trigger_on_initial_state. brightness is
dropped since mipi_spi only supports it for AMOLED panels and both
devices already control backlight separately.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 22:56:01 +02:00
randyandClaude Sonnet 5 c9358e7bd6 Rename deprecated light rgb_order to channel_colors
ESPHome renamed the esp32_rmt_led_strip platform's rgb_order option to
channel_colors; update the remaining devices using it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 22:16:30 +02:00
randyandClaude Sonnet 5 173514f73e mcu-echo-1: migrate to speaker-based media_player with mixer
The i2s_audio media_player platform was removed; rebuild the audio
pipeline like mcu-echo.yaml with an i2s_audio speaker feeding a
mixer, so media playback, TTS announcements, and rtttl beeps all
share the one physical DAC output without conflicting. Also uses
format: NONE instead of the deprecated codec_support_enabled.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 22:16:11 +02:00
randyandClaude Sonnet 5 b818b5291b mcu-gate: split OGI detection into steady-state and blink sensors
The single on_multi_click FSM mixed an unbounded "at least 1500ms"
pattern with two bounded blink patterns, which made Open detection
unreliable. Split into two binary_sensor entries sharing the same
pin: a filter-based one for steady Open/Closed, and a dedicated
on_multi_click for the Opening/Closing blink patterns.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 22:09:06 +02:00
randyandClaude Sonnet 5 ab08e9a0af mcu-gateway: migrate modbus_controller off deprecated register_count
register_count is derived from value_type now; drop the now-redundant
register_count: 1 on the temp/humidity sensors, and replace the
Solar Pressure sensor's register_count: 2 (its device always returns
2 registers per read) with a hidden padding sensor on the next
register using reuse_previous_range: true, per the new
modbus_controller range-grouping mechanism.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 21:52:03 +02:00
randyandClaude Sonnet 5 5f966ffba6 mcu-tft: migrate display from deprecated ili9xxx to mipi_spi
ili9xxx is being phased out in favor of the unified mipi_spi driver;
model TFT 2.4 maps to the ILI9341 chip it was already using.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 21:43:14 +02:00
randyandClaude Sonnet 5 cd78449995 mcu-tft: comment out pinned esp-idf/platform version
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 21:39:02 +02:00
randyandClaude Sonnet 5 aaa6418edc mcu-well: add Modbus support for n4dig08 relay module
Adds a UART-based Modbus link plus scripts to toggle channel 1 on the
n4dig08 relay module, and calls relay_module.setup() before each
irrigation switch action.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 21:35:44 +02:00
randyandClaude Sonnet 5 a36dd4447d mcu-well: enable sram1_as_iram to use bootloader's extra 40KB IRAM
Fixes bootloader warning:
[W][app:198]: Bootloader supports SRAM1 as IRAM (+40KB). Set sram1_as_iram: true under esp32 > framework > advanced

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 21:35:38 +02:00
randyandClaude Sonnet 5 f9656a8e4c mcu-well: rename deprecated api services/service to actions/action
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 21:35:14 +02:00
randyandClaude Sonnet 5 c0309c5418 mcu-apollo-dev: explicitly set esp-idf toolchain
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 21:25:38 +02:00
randyandClaude Sonnet 5 c895c821ea mcu-rf: rework RF pin wiring and unify transmit/receive frequency
Move rx/tx off the shared gdo0 pin (21) onto dedicated pins, drop the
now-unneeded allow_other_uses/gdo0_pin workarounds, and align tx/rx
frequency to 433.92MHz.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 21:25:32 +02:00
randyandClaude Sonnet 5 13a5bf04cc mcu-basement: rename sewage treatment blower to aerator pump
Reflects what the device actually controls; renames the entity/id
(blower_auto -> aerator_auto) and display names accordingly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 21:25:22 +02:00
randyandClaude Sonnet 5 176b875bef Rename deprecated light rgb_order to channel_colors
ESPHome renamed the esp32_rmt_led_strip platform's rgb_order option to
channel_colors; update all devices using it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 21:24:58 +02:00
randyandClaude Sonnet 5 56db2c2087 Rename deprecated api services/service to actions/action
ESPHome renamed the api component's services/service keys to
actions/action; update all devices using the old names.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 21:24:36 +02:00
randyandClaude Sonnet 5 468e813958 Stop tracking .device-builder.json state file
It's generated/local state from ESPHome Device Builder that changes
constantly and doesn't belong in version control.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 21:22:20 +02:00
randy 083d603777 Add .device-builder.json to gitignore
CI / YAML lint (push) Failing after 15s
CI / ESPHome config validation (push) Failing after 17s
2026-06-17 12:12:38 +02:00
ESPHome Device Builder 213b092029 Edit mcu-apollo-dev.yaml 2026-06-17 12:00:07 +02:00
ESPHome Device Builder 6791ecd849 Edit mcu-apollo-dev.yaml 2026-06-17 11:59:49 +02:00
ESPHome Device Builder ef51ad3f0e Edit mcu-apollo-dev.yaml 2026-06-17 11:55:38 +02:00
ESPHome Device Builder 1b55751c7d Edit mcu-apollo-dev.yaml 2026-06-17 11:55:30 +02:00
ESPHome Device Builder ad6fa5bfc8 Edit mcu-apollo-dev.yaml 2026-06-10 19:44:07 +02:00
ESPHome Device Builder 7764995c14 Edit mcu-apollo-dev.yaml 2026-06-10 19:42:59 +02:00
ESPHome Device Builder 3d1318956e Edit mcu-apollo-dev.yaml 2026-06-10 19:39:42 +02:00
ESPHome Device Builder 2954489bb9 Edit mcu-apollo-dev.yaml 2026-06-10 19:15:11 +02:00
ESPHome Device Builder d3cd52ac49 Edit mcu-apollo-dev.yaml 2026-06-10 19:12:21 +02:00
ESPHome Device Builder 85af3e7ece Edit mcu-apollo-dev.yaml 2026-06-10 19:07:22 +02:00
ESPHome Device Builder 83def722f5 Edit mcu-apollo-dev.yaml 2026-06-10 18:57:10 +02:00
ESPHome Device Builder 2229e5006e Edit mcu-apollo-dev.yaml 2026-06-10 18:56:59 +02:00
ESPHome Device Builder 4b9a9763a9 Create mcu-apollo-dev.yaml 2026-06-10 18:55:05 +02:00
randy fc37633d53 Comment out broken PR for LLDP
CI / YAML lint (push) Has been cancelled
CI / ESPHome config validation (push) Has been cancelled
2026-05-14 19:21:26 +02:00
randy eb85d84880 Switch from platformio to native esp-idf toolchain for ESP32* devices 2026-05-14 18:14:07 +02:00
randy 85c2caa9eb Fix media-player on mcu-echo
CI / YAML lint (push) Has been cancelled
CI / ESPHome config validation (push) Has been cancelled
2026-05-12 23:21:17 +02:00
randy 259d269af5 Add new RF Bridge
CI / YAML lint (push) Has been cancelled
CI / ESPHome config validation (push) Has been cancelled
2026-05-11 21:47:10 +02:00
randy 252c4c3f22 Add VSCode settings for YAML file association with ESPHome
CI / YAML lint (push) Has been cancelled
CI / ESPHome config validation (push) Has been cancelled
2026-05-10 21:17:30 +02:00
randy 4237c7c4ce Remove area from comments, and add, if missing 2026-05-10 21:17:13 +02:00
randy 34c4c475ea Update ESP32 configuration to use numeric minimum_chip_revision and enable sram1_as_iram
CI / YAML lint (push) Has been cancelled
CI / ESPHome config validation (push) Has been cancelled
2026-05-09 11:06:02 +02:00
randy bfcf9005d6 Add allow_partition_access to OTA configuration for esp32 devices
CI / YAML lint (push) Has been cancelled
CI / ESPHome config validation (push) Has been cancelled
2026-05-08 22:30:05 +02:00
randy 3a23b88823 Cleanup
CI / YAML lint (push) Has been cancelled
CI / ESPHome config validation (push) Has been cancelled
2026-05-07 12:06:00 +02:00
randy e4c8c72c20 Custom scripts and related device lists are no longer needed
CI / YAML lint (push) Has been cancelled
CI / ESPHome config validation (push) Has been cancelled
2026-05-07 00:31:06 +02:00
randy bd087dc511 Update .gitignore to include .device-builder.yaml and .claude 2026-05-06 22:25:39 +02:00
randy 184a40ddf7 Add local fonts 2026-05-06 22:24:36 +02:00
randy 0f68e1379f switch to specific OTA for esp32 devices with ethernet 2026-05-06 22:24:08 +02:00
randy a76df9405b Add id's to all common components 2026-05-06 22:20:29 +02:00
randy 51f7537244 Separate OTA for esp32 which supports partition table update via OTA 2026-05-06 22:18:49 +02:00
randy bab7ffafe6 Force WPA2 for esp8266 devices 2026-05-06 22:17:59 +02:00
randy e00040e7ee Add A3 to morning irrigation cycle 2026-05-06 22:17:25 +02:00
randy 39929e46a7 Reboot mcu-kitchen when API is stuck due weak wifi 2026-05-06 22:16:09 +02:00
randy ca6f175a58 Add minimum chip revision to mcu-gateway
CI / YAML lint (push) Has been cancelled
CI / ESPHome config validation (push) Has been cancelled
2026-04-26 12:31:11 +02:00
randy 945b60c168 New file for device-builder 2026-04-26 12:22:54 +02:00
randy 4a95ebbc79 Fix for esphome-desktop 2026-04-26 12:22:19 +02:00
randy fb9822a5be pcf8574 pin numbering has been changed 2026-04-26 12:21:46 +02:00
randy 06f125e851 Simplify status led
CI / YAML lint (push) Has been cancelled
CI / ESPHome config validation (push) Has been cancelled
2026-04-06 14:36:37 +02:00
randy a35b003284 Allow async and disable reboot for MQTT on all NSPanels 2026-04-06 14:35:01 +02:00
randy 1badaaf232 NSPanels no longer need an explicit esp_http_client - fixed in the ext component
CI / YAML lint (push) Has been cancelled
CI / ESPHome config validation (push) Has been cancelled
2026-02-26 19:16:29 +01:00
randy 5600203e6b Add --- to make valid yaml's and fix all commented indentations 2026-02-24 08:53:20 +01:00
randy 1b5ef340e4 Remove empty line
CI / YAML lint (push) Has been cancelled
CI / ESPHome config validation (push) Has been cancelled
2026-02-21 10:14:58 +01:00
randy 082286ba87 Remove version/platform from can devices 2026-02-21 09:56:32 +01:00
randy baad6eda7c Real data for LLDP 2026-02-21 09:55:04 +01:00
randy 9eeeef6a57 NSPanel's need esp_http_client 2026-02-21 09:54:27 +01:00
randy a966f6adb4 Templated gate beacon on_press and on_release
CI / YAML lint (push) Has been cancelled
CI / ESPHome config validation (push) Has been cancelled
2026-02-19 14:23:27 +01:00
randy 2ef5945c9f Add indent-sequences: whatever to support more compact indent 2026-02-19 12:21:00 +01:00
randy 3ca7b2390d Use image files from assets directory 2026-02-19 12:10:33 +01:00
randy 38791e3313 Move fonts (not being used for now) and images to assets directory. Remove obsolete .h files. 2026-02-19 12:07:56 +01:00
randy d03d889e81 Remove unused local components directory 2026-02-19 11:54:26 +01:00
randyandClaude Sonnet 4.6 4ee29295ac Remove debug ota.h and its include from mcu-lvgl
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 11:36:52 +01:00
randyandClaude Sonnet 4.6 dd033f69bb Refactor vehicle beacon configs and clean up gate
Extract shared M5ATOM vehicle code (esp32, on_loop, LED effects) into
common/vehicle_base.yaml, reducing each vehicle file from ~136 to 20
lines. Remove dead commented-out code from on_loop lambda.

Gate: fix on_multi_click and select indentation, change
esp32_ble_tracker id from ${name} to ${device} (lowercase),
remove unused commented-out gate_flash GPIO sensor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 11:32:23 +01:00
randyandClaude Sonnet 4.6 7c9aae0a7d Fix trailing spaces and missing newlines in all mcu-*.yaml files
Bulk cleanup: remove trailing whitespace and ensure files end with a
newline. Structural issues (indentation, bracket spacing) left for
per-file fixes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 11:22:12 +01:00
randyandClaude Sonnet 4.6 c88ccfbdb8 Use ESPHome dev branch in CI to match production
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 11:18:38 +01:00
randyandClaude Sonnet 4.6 b18ce4a2da Fix yamllint errors in POW configs, update CI and lint config
- Fix UART list indentation (yamllint error)
- Remove trailing spaces in display lambda
- Add missing newline at end of file
- Add ON/OFF to yamllint truthy allowed values
- Fix invalid comments rule option in .yamllint.yml
- Lint only changed files in CI (avoids blocking PRs with pre-existing issues)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 11:14:51 +01:00
randyandClaude Sonnet 4.6 d4967c6411 Add CI: ESPHome config validation and YAML lint
- yamllint on all YAML files with ESPHome-friendly rules
  (allows True/False, long lines for lambdas, no forced document-start)
- ESPHome config validation on changed mcu-*.yaml files per push/PR

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 11:05:09 +01:00
randyandClaude Sonnet 4.6 a8b71d99dd Fix and improve POW dishwasher and washer configs
- Remove redundant interval block overriding status_led behavior
- Add UART id and reference it explicitly in cse7766
- Replace manual power factor template with native cse7766 power_factor sensor
- Remove redundant switch_led control from bi-stable relay actions
- Fix stray quote in energy sensor name (dishwasher)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 10:56:34 +01:00
randy 1c8c319406 Some changes to common files 2026-02-11 23:07:57 +01:00
randy 8693d810b4 Remove custom_components 2026-02-11 23:06:57 +01:00
randy d3e3175d39 Remove custom_components 2026-02-11 23:06:27 +01:00
randy c3a5291927 Migrate heating to friendly name and sub devices and rename it to heater 2026-02-11 23:05:21 +01:00
randy d24866b5a2 Migrate mains-power to friendly name and sub devices 2026-02-11 23:04:39 +01:00
randy 9812f5ed03 New POW devices - dishwasher and washer 2026-02-11 23:03:12 +01:00
randy 86051c9f1a Usual cleanup + irrigation changes 2026-02-11 23:02:24 +01:00
randy c2d1d16cbd New rfid-reader 2026-02-11 23:01:58 +01:00
randy 239f4c3ce5 Migrate from Boards to Variant, remove hardcoded versions, remove customn directories and some cleanup 2026-02-11 23:01:41 +01:00
randy badcad9c5a Remove config switches from common configs and add version text_sensor to eth 2025-05-18 17:41:01 +02:00
randy ba1aea9132 Add archive to git ignore 2025-05-09 21:08:36 +02:00
randy 918b54e5ed Delete old files 2025-05-09 21:08:22 +02:00
randy a55314dff8 Merge pull request #1 from randybb/friendly_name
Add friendly_name to make HA folks happy
2025-05-09 21:06:16 +02:00
randy 9cc69d7ad2 Add friendly_name to make HA folks happy 2025-05-09 21:01:58 +02:00
randy f552ea0f97 Start playing with CANopen 2025-05-02 20:34:53 +02:00
randy e0b76fb95f Fix ethernet 2025-05-02 20:29:19 +02:00
randy f8ef9d261d Remove API and WIFI from vehicle beacons 2025-05-02 20:24:55 +02:00
randy f86cb569b0 Switch to pioarduino 2025-05-02 20:23:18 +02:00
randy e77ab50d02 Slovak translation for esphome-nspanel-lovelace-native 2025-03-16 15:44:40 +01:00
randy 5b913cecf0 Add area, switch to idf 5.3.1, replacing climate.heating with a new setup 2025-03-16 15:43:49 +01:00
171 changed files with 5241 additions and 6771 deletions

No files matched your search

+53
View File
@@ -0,0 +1,53 @@
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
yamllint:
name: YAML lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get changed YAML files
id: changed
uses: tj-actions/changed-files@v46
with:
files: "**/*.yaml"
- uses: ibiqlik/action-yamllint@v3
if: steps.changed.outputs.any_changed == 'true'
with:
config_file: .yamllint.yml
file_or_dir: ${{ steps.changed.outputs.all_changed_files }}
validate:
name: ESPHome config validation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get changed device configs
id: changed
uses: tj-actions/changed-files@v46
with:
files: "mcu-*.yaml"
- name: Install ESPHome (dev)
if: steps.changed.outputs.any_changed == 'true'
run: pip install git+https://github.com/esphome/esphome.git@dev
- name: Prepare secrets
if: steps.changed.outputs.any_changed == 'true'
run: cp secrets.yaml.default secrets.yaml
- name: Validate changed configs
if: steps.changed.outputs.any_changed == 'true'
run: |
for f in ${{ steps.changed.outputs.all_changed_files }}; do
echo "Validating $f..."
esphome config "$f"
done
+3
View File
@@ -1,6 +1,9 @@
# 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.
/.claude/
/.esphome/
/secrets.yaml
/archive/
/trash/
.device-builder.json
+5
View File
@@ -0,0 +1,5 @@
{
"files.associations": {
"*.yaml": "esphome"
}
}
+27
View File
@@ -0,0 +1,27 @@
extends: default
rules:
# ESPHome uses True/False (Python style) and yes/no
truthy:
allowed-values: ["true", "false", "True", "False", "yes", "no", "on", "off", "ON", "OFF"]
check-keys: false
# Lambdas and long substitutions can exceed 80 chars
line-length:
max: 200
level: warning
# Not all files use --- document start marker
document-start: disable
# ESPHome uses both indented and non-indented sequences
indentation:
spaces: 2
indent-sequences: whatever
check-multi-line-strings: false
# Some files have trailing spaces; warn only
trailing-spaces: enable
comments:
require-starting-space: false
+8
View File
@@ -0,0 +1,8 @@
# Git commit attribution
Do not add any Claude/Anthropic attribution to git commits or pull requests in
this repository — no `Co-Authored-By: Claude ...` line, no mention of Claude
anywhere in the commit message or PR description. Commits should look like
they were written entirely by the human author.
This overrides any default Claude Code attribution instructions.
-311
View File
@@ -1,311 +0,0 @@
// 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
File renamed without changes.
File renamed without changes.
Binary file not shown.
File renamed without changes.
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1194" height="240" fill="none" viewBox="0 0 1194 240"><g clip-path="url(#clip0_2_63)"><path fill="#18BCF2" d="M240 219C240 227.24 233.24 234 225 234H15C6.76 234 0 227.24 0 219V129C0 120.76 4.78 109.22 10.6 103.4L109.4 4.61999C115.24 -1.22001 124.78 -1.22001 130.62 4.61999L229.4 103.4C235.24 109.24 240 120.76 240 129V219Z"/><path fill="#F2F4F9" d="M160 78.66H80C76.68 78.66 74 81.34 74 84.66V234H86V90.66H154V102.66H104C100.68 102.66 98 105.34 98 108.66V132.66C98 135.98 100.68 138.66 104 138.66H154V150.66H104C100.68 150.66 98 153.34 98 156.66V180.66C98 183.98 100.68 186.66 104 186.66H154V198.66H104C100.68 198.66 98 201.34 98 204.66C98 207.98 100.68 210.66 104 210.66H160C163.32 210.66 166 207.98 166 204.66V180.66C166 177.34 163.32 174.66 160 174.66H110V162.66H160C163.32 162.66 166 159.98 166 156.66V132.66C166 129.34 163.32 126.66 160 126.66H110V114.66H160C163.32 114.66 166 111.98 166 108.66V84.66C166 81.34 163.32 78.66 160 78.66Z"/><path fill="#F2F4F9" d="M423 167.61V190.11H336V49.95H423V72.63H359.82V108.91H416.26V130.01H359.82V167.61H423Z"/><path fill="#F2F4F9" d="M491.08 47.41C503.9 47.41 514.54 50.53 523.04 56.79C531.54 63.03 536.76 71.39 538.7 81.83L516.3 87.93C515.04 81.93 512.12 77.31 507.54 74.05C502.94 70.81 497.28 69.17 490.52 69.17C483.26 69.17 477.52 70.91 473.28 74.37C469.02 77.83 466.9 82.45 466.9 88.19C466.9 97.25 472.52 103.13 483.78 105.81L506.66 111.53C518.48 114.59 527.32 119.45 533.2 126.11C539.08 132.77 542.02 140.97 542.02 150.71C542.02 163.21 537.48 173.31 528.42 181.03C519.36 188.75 507.24 192.61 492.04 192.61C478.36 192.61 466.78 189.39 457.36 182.95C448.04 176.27 442.54 167.45 440.86 156.51L463.26 150.69C464.08 156.87 467.16 161.73 472.5 165.23C477.84 168.73 484.64 170.47 492.9 170.47C501.16 170.47 507.08 168.79 511.6 165.45C516.14 162.11 518.4 157.57 518.4 151.81C518.4 142.81 512.78 136.87 501.52 133.99L478.64 128.45C466.88 125.77 458.06 120.99 452.16 114.15C446.26 107.31 443.3 98.95 443.3 89.07C443.3 76.69 447.7 66.65 456.48 58.93C465.26 51.21 476.8 47.35 491.12 47.35L491.08 47.41Z"/><path fill="#F2F4F9" d="M666.1 95.61C666.1 109.37 661.92 120.49 653.58 128.99C645.24 137.49 634 141.75 619.88 141.75H588.38V190.13H564.56V49.95H620.06C634.3 49.95 645.54 54.07 653.76 62.27C661.98 70.49 666.08 81.59 666.08 95.59L666.1 95.61ZM641.16 95.05C641.16 87.99 638.96 82.25 634.56 77.85C630.16 73.45 623.92 71.25 615.86 71.25H588.4V120.85H615.5C623.74 120.85 630.1 118.51 634.54 113.81C638.98 109.13 641.2 102.87 641.2 95.05H641.16Z"/><path fill="#F2F4F9" d="M687.38 49.95H711.2V108.55L772.98 108.73V49.95H796.98V190.11H772.98V129.83L711.2 129.65V190.11H687.38V49.95Z"/><path fill="#F2F4F9" d="M868.6 92.79C883.1 92.79 894.92 97.45 904.04 106.75C913.16 116.07 917.72 128.03 917.72 142.65C917.72 157.27 913.16 169.15 904.04 178.47C894.92 187.79 883.1 192.43 868.6 192.43C854.1 192.43 842.1 187.77 832.98 178.47C823.86 169.15 819.3 157.23 819.3 142.65C819.3 128.07 823.86 115.97 832.98 106.69C842.1 97.41 853.98 92.77 868.6 92.77V92.79ZM868.6 172.01C876.34 172.01 882.64 169.27 887.5 163.81C892.34 158.35 894.76 151.23 894.76 142.49C894.76 133.75 892.34 126.67 887.5 121.25C882.66 115.85 876.36 113.15 868.6 113.15C860.84 113.15 854.26 115.85 849.38 121.25C844.5 126.65 842.06 133.73 842.06 142.49C842.06 151.25 844.5 158.35 849.38 163.81C854.26 169.27 860.66 172.01 868.6 172.01Z"/><path fill="#F2F4F9" d="M1081.6 129.83V190.11H1059.56V133.29C1059.56 126.73 1057.88 121.61 1054.5 117.91C1051.12 114.23 1046.54 112.37 1040.72 112.37C1034.54 112.37 1029.6 114.39 1025.9 118.41C1022.22 122.45 1020.36 128.09 1020.36 135.33V190.09H998.04V133.27C998.04 126.71 996.4 121.59 993.12 117.89C989.84 114.21 985.3 112.35 979.48 112.35C973.3 112.35 968.32 114.37 964.58 118.39C960.84 122.41 958.96 128.07 958.96 135.31V190.07H936.28V95.39H957.38L958.14 104.49C963.64 96.43 972.6 92.39 985.04 92.39C992.28 92.39 998.58 93.89 1003.88 96.89C1009.2 99.89 1013.22 104.27 1015.98 110.01C1018.3 104.51 1022.12 100.19 1027.46 97.07C1032.8 93.95 1039.16 92.39 1046.54 92.39C1057.28 92.39 1065.82 95.71 1072.14 102.33C1078.46 108.95 1081.6 118.11 1081.6 129.79V129.83Z"/><path fill="#F2F4F9" d="M1193.54 151.11H1120.98C1121.74 158.23 1124.42 163.67 1129.04 167.43C1133.66 171.19 1139.54 173.05 1146.66 173.05C1158.22 173.05 1166.32 168.23 1170.94 158.61L1189.88 166.11C1186.32 174.43 1180.7 180.93 1173.06 185.61C1165.4 190.29 1156.6 192.65 1146.66 192.65C1132.66 192.65 1121.3 188.07 1112.58 178.91C1103.86 169.75 1099.5 157.73 1099.5 142.87C1099.5 128.01 1103.9 115.91 1112.68 106.59C1121.46 97.27 1132.94 92.63 1147.14 92.63C1161.34 92.63 1172.3 97.23 1180.8 106.41C1189.3 115.59 1193.56 127.69 1193.56 142.69V151.13L1193.54 151.11ZM1121.36 135.17H1170.48C1170.04 127.49 1167.72 121.63 1163.5 117.59C1159.28 113.55 1153.6 111.55 1146.48 111.55C1139.36 111.55 1133.66 113.59 1129.24 117.69C1124.8 121.79 1122.18 127.61 1121.36 135.17Z"/></g><defs><clipPath id="clip0_2_63"><rect width="1193.56" height="240" fill="#fff"/></cliLine truncated

After

Width:  |  Height:  |  Size: 4.9 KiB

File renamed without changes.
+2 -1
View File
@@ -1,3 +1,4 @@
---
platform: status
name: "${name} Status"
name: Status
id: status_sensor
+2 -1
View File
@@ -1,3 +1,4 @@
---
platform: factory_reset
name: ${name} Factory Defaults
name: Factory Defaults
id: factory_reset_button
+2 -1
View File
@@ -1,3 +1,4 @@
---
platform: restart
name: ${name} Restart
name: Restart
id: restart_button
+2 -1
View File
@@ -1,3 +1,4 @@
---
platform: safe_mode
name: ${name} Restart (Safe Mode)
name: Restart (Safe Mode)
id: restart_safe_mode_button
+2 -1
View File
@@ -1,3 +1,4 @@
---
platform: shutdown
name: ${name} Shutdown
name: Shutdown
id: shutdown_button
+4 -1
View File
@@ -1,7 +1,7 @@
---
<<: !include wifi.yaml
<<: !include api.yaml
<<: !include ota.yaml
<<: !include ota_esp32.yaml
# <<: !include logger.yaml
<<: !include logger_debug.yaml
@@ -24,5 +24,8 @@ text_sensor:
# - <<: !include text_sensor/uptime.yaml
- <<: !include text_sensor/wifi_info.yaml
# time:
#. - <<: !include time/homeassistant.yaml
network:
enable_ipv6: true
-5
View File
@@ -19,11 +19,6 @@ sensor:
- <<: !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
+2 -7
View File
@@ -1,6 +1,6 @@
---
<<: !include api.yaml
<<: !include ota.yaml
<<: !include ota_esp32.yaml
<<: !include logger_debug.yaml
<<: !include ethernet.yaml
@@ -16,14 +16,9 @@ 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/version.yaml
- <<: !include text_sensor/ethernet_info.yaml
network:
-5
View File
@@ -22,11 +22,6 @@ sensor:
- <<: !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
+3 -1
View File
@@ -3,6 +3,8 @@ ethernet:
type: LAN8720
mdc_pin: 23
mdio_pin: 18
clk_mode: GPIO17_OUT
clk:
pin: 17
mode: CLK_OUT
phy_addr: 0
power_pin: 12
+9
View File
@@ -0,0 +1,9 @@
- if:
condition:
and:
- switch.is_on: ${enable_id}
- switch.is_on: auto_close
- lambda: 'return id(beacon_count) == 1;'
then:
- button.press: gate_close
- lambda: 'id(beacon_count) -= 1;'
+9
View File
@@ -0,0 +1,9 @@
- lambda: 'id(beacon_count) += 1;'
- if:
condition:
and:
- switch.is_on: ${enable_id}
- switch.is_on: auto_open
- lambda: 'return id(beacon_count) == 1;'
then:
- button.press: gate_open
+5
View File
@@ -0,0 +1,5 @@
---
ota:
- platform: esphome
password: !secret ota_password
allow_partition_access: true
+8 -4
View File
@@ -1,10 +1,14 @@
---
platform: debug
free:
name: "${name} Heap Free"
name: Heap Free
id: heap_free_sensor
fragmentation:
name: "${name} Heap Fragmentation"
name: Heap Fragmentation
id: heap_fragmentation_sensor
block:
name: "${name} Heap Max Block"
name: Heap Max Block
id: heap_max_block_sensor
loop_time:
name: "${name} Loop Time"
name: Loop Time
id: loop_time_sensor
+1 -1
View File
@@ -1,6 +1,6 @@
---
platform: template
name: ${name} Free heap
name: Free heap
lambda: return heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
icon: "mdi:memory"
entity_category: diagnostic
+2 -1
View File
@@ -1,6 +1,7 @@
---
platform: uptime
name: ${name} Uptime
name: Uptime
id: uptime_sensor
unit_of_measurement: "days"
accuracy_decimals: 2
update_interval: 60s
+2 -1
View File
@@ -1,4 +1,5 @@
---
platform: wifi_signal
name: "${name} WiFi Signal"
name: WiFi Signal
id: wifi_signal_sensor
update_interval: 60s
+2 -1
View File
@@ -1,3 +1,4 @@
---
platform: restart
name: ${name} Restart
name: Restart
id: restart_switch
+2 -1
View File
@@ -1,3 +1,4 @@
---
platform: safe_mode
name: ${name} Restart (Safe Mode)
name: Restart (Safe Mode)
id: restart_safe_mode_switch
+2 -1
View File
@@ -1,3 +1,4 @@
---
platform: shutdown
name: ${name} Shutdown
name: Shutdown
id: shutdown_switch
+4 -2
View File
@@ -1,6 +1,8 @@
---
platform: debug
device:
name: "${name} Device Info"
name: Device Info
id: device_info_sensor
reset_reason:
name: "${name} Reset Reason"
name: Reset Reason
id: reset_reason_sensor
+6 -3
View File
@@ -1,8 +1,11 @@
---
platform: ethernet_info
ip_address:
name: ${name} IP Address
name: IP Address
id: ip_address_sensor
address_1:
name: ${name} IP Address 1
name: IP Address 1
id: ip_address_1_sensor
address_2:
name: ${name} IP Address 2
name: IP Address 2
id: ip_address_2_sensor
+2 -1
View File
@@ -1,6 +1,7 @@
---
platform: git_ref
name: "${name} Git Ref"
name: Git Ref
id: git_ref_sensor
long: true
all: true
abbrev: 16
+2 -1
View File
@@ -1,3 +1,4 @@
---
platform: uptime
name: ${name} Uptime
name: Uptime
id: uptime_sensor
+2 -1
View File
@@ -1,3 +1,4 @@
---
platform: version
name: "${name} Version"
name: Version
id: version_sensor
+30 -7
View File
@@ -1,17 +1,40 @@
---
platform: wifi_info
ip_address:
name: ${name} IP Address
name: IP Address
id: ip_address_sensor
icon: mdi:ip-network
# address_0:
# name: IP Address 0
# icon: mdi:ip-network
address_1:
name: ${name} IP Address 1
name: IP Address 1
id: ip_address_1_sensor
icon: mdi:ip-network
address_2:
name: ${name} IP Address 2
name: IP Address 2
id: ip_address_2_sensor
icon: mdi:ip-network
# address_3:
# name: IP Address 3
# id: ip_address_3_sensor
# icon: mdi:ip-network
# address_4:
# name: IP Address 4
# id: ip_address_4_sensor
# icon: mdi:ip-network
#ssid:
# name: ${name} SSID
# name: SSID
# id: ssid_sensor
#bssid:
# name: ${name} BSSID
# name: BSSID
# id: bssid_sensor
mac_address:
name: ${name} MAC
name: MAC
id: mac_address_sensor
#scan_results:
# name: ${name} Latest Scan Results
# name: Latest Scan Results
# id: scan_results_sensor
power_save_mode:
name: WiFi Power Save Mode
id: wifi_power_save_mode_sensor
+106
View File
@@ -0,0 +1,106 @@
esp32:
variant: esp32
toolchain: esp-idf
framework:
type: esp-idf
external_components:
- source: components
# PINOUTS: M5ATOM
# IR G12
# NEO G27
# BUTTON G39
# I2C0 SDA G26
# I2C0 SCL G32
# I2C1 SDA G25
# I2C1 SCL G21
# UART0 RX G3
# UART0 TX G1
# UART1 RX G23
# UART1 TX G33
# 1-WIRE G22
# NC G19
esphome:
on_loop:
then:
lambda: |-
static uint32_t last_state = 0;
auto state = App.get_app_state();
if (state != last_state) {
if (state & STATUS_LED_ERROR) {
auto call = id(led).turn_on();
call.set_effect("ERROR");
call.perform();
} else if (state & STATUS_LED_WARNING) {
auto call = id(led).turn_on();
call.set_effect("BOOT");
call.perform();
} else {
auto call = id(led).turn_on();
call.set_effect("BEACON");
call.perform();
}
last_state = state;
}
light:
- platform: esp32_rmt_led_strip
name: LED
id: led
rgb_order: GRB
pin: 27
num_leds: 1
chipset: ws2812
restore_mode: ALWAYS_OFF
effects:
- strobe:
name: "BEACON"
colors:
- state: true
red: 0%
green: 0%
blue: 50%
duration: 200ms
- state: false
duration: 200ms
- state: true
red: 0%
green: 0%
blue: 50%
duration: 200ms
- state: false
duration: 10s
- lambda:
name: "ERROR"
update_interval: 0.5s
lambda: |-
static bool state = false;
auto call = id(led).turn_on();
call.set_transition_length(500);
call.set_rgb(1, 0, 0);
if (!state) {
call.set_brightness(1);
} else {
// If using 0, it freaks Home Assistant UI.
call.set_brightness(0.01);
}
call.perform();
state = !state;
- lambda:
name: "BOOT"
update_interval: 0.5s
lambda: |-
static bool state = false;
auto call = id(led).turn_on();
call.set_transition_length(500);
call.set_rgb(0, 1, 0);
if (!state) {
call.set_brightness(1);
} else {
// If using 0, it freaks Home Assistant UI.
call.set_brightness(0.01);
}
call.perform();
state = !state;
+1
View File
@@ -6,3 +6,4 @@ wifi:
password: !secret wifi_password
enable_btm: true
enable_rrm: true
min_auth_mode: WPA3
+1
View File
@@ -6,3 +6,4 @@ wifi:
password: !secret wifi_password
# enable_btm: true
# enable_rrm: true
min_auth_mode: WPA2
-12
View File
@@ -1,12 +0,0 @@
#!/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
View File
@@ -1,24 +0,0 @@
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
View File
@@ -1,242 +0,0 @@
#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
View File
@@ -1,62 +0,0 @@
#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
View File
@@ -1,30 +0,0 @@
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)
@@ -1,49 +0,0 @@
#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
@@ -1,49 +0,0 @@
#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
View File
@@ -1,25 +0,0 @@
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
View File
@@ -1 +0,0 @@
https://github.com/TomG736/esphome-BM8563
-28
View File
@@ -1,28 +0,0 @@
# 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
View File
@@ -1,69 +0,0 @@
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
-108
View File
@@ -1,108 +0,0 @@
#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
View File
@@ -1,52 +0,0 @@
#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
View File
@@ -1,57 +0,0 @@
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
View File
@@ -1,96 +0,0 @@
#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
View File
@@ -1,61 +0,0 @@
#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
Submodule components/sim7600 deleted from d754e306ad.
-3
View File
@@ -1,3 +0,0 @@
import esphome.codegen as cg
st7735_ns = cg.esphome_ns.namespace('st7735')
Binary file not shown.
Binary file not shown.
-41
View File
@@ -1,41 +0,0 @@
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
View File
@@ -1,351 +0,0 @@
#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
View File
@@ -1,149 +0,0 @@
#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
View File
@@ -1,116 +0,0 @@
#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
View File
@@ -1,102 +0,0 @@
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
View File
@@ -1,31 +0,0 @@
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
View File
@@ -1,170 +0,0 @@
#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
View File
@@ -1,76 +0,0 @@
#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
View File
@@ -1,81 +0,0 @@
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))
Whitespace-only changes.
-531
View File
@@ -1,531 +0,0 @@
#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
View File
@@ -1,116 +0,0 @@
#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
@@ -1,34 +0,0 @@
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
View File
@@ -1,12 +0,0 @@
# heap space monitor
A sensor to show the available heap space.
Example:
```yaml
sensor:
- platform: heapmon
id: heapspace
name: "Free Space"
```
Whitespace-only changes.
-17
View File
@@ -1,17 +0,0 @@
#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
View File
@@ -1,17 +0,0 @@
#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
View File
@@ -1,18 +0,0 @@
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)
Whitespace-only changes.
@@ -1,61 +0,0 @@
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))
@@ -1,83 +0,0 @@
#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
@@ -1,240 +0,0 @@
#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
@@ -1,92 +0,0 @@
#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
@@ -1,70 +0,0 @@
#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
Loaded 100 of 171 files, more files were not shown because too many files have changed in this diff. Show more