πŸ’» Programming

There are two main programming methods supported and tested with the Smart Dashboard:
  • ESPHome

  • Arduino

In both scenarios, you will first need to enter the board into flashing mode. For that, press and hold the Flash pushbutton while you reset the board (pressing once the Reset pushbutton).

Note

For flashing new firmwares, if the OTA support is not available, you can use the USB-C or the serial port (3.3, GND, Tx, Rx).

Caution

If you decide to flash the board through the serial port, make sure to unplug the battery before (the 3.3V supply is shared).

ESPHome

ESPHome is a well known platform for programming ESP-based devices with a very little effort. It is configured via YAML files and supports a wide range of functionalities and sensors.

Note

At the moment, ESPHome only supports single-color E-Ink displays, so the 7-color display can not be used with ESPHome.

Important

For using ESPHome, and all its funcionalities, you need to have a Home Assistant (HA) instance running in the same network as your Smart Dashboard.

Tip

A very easy way to upload and copy files (code or even images) into your ESPHome folder hosted in your HA instance is with the help of the Visual Studio Code integration for HA. This way you can just drag and drop the files over the folder on the Home Assistant’s Visual Studio Code navigation panel on your left.

_images/captive_portal-ui.png

The Smart Dashboard already comes with an embeded version of ESPHome, that would only require an OTA update to get it ready to work in your network:

  1. Power the board, and let it run for 1-2 minutes. When the board cannot connect to a WiFi network, it will create a fallback hotspot.

  2. Use a smartphone or tablet and go to the WiFi settings, connect to the recently created Smart-Plant hotspot with the password smartplant.

  3. Access to the captive portal and open the browser if doesn’t pop up automatically.

  4. Enter your network setttings and press Save.

Now, your ESPHome device is ready to be found by Home Assistant in your network. Add it from the ESPHome section to add and edit a customized configuration file.

As an example of such configuration setup (and the one flashed on the factory settings of the Smart Dashboard) with all the dependencies:

esphome
β”œβ”€β”€ images
β”‚ └── Screenshot bw.png
β”œβ”€β”€ libraries
β”‚ └── MAX17048.h
└── smart-dashboard.yaml


In the folder structure above:

Screenshot bw.png

This is the background image to serve as an example of any background image you can add to your Smart Dashboard.

_images/Screenshot.png
MAX17048

This is the library to read the MAX17048 sensor (battery level):

 1#include "esphome.h"
 2
 3#define update_interval 3000 // 27000 makes a good rate
 4#define MAX17048_ADDRESS        0x36
 5#define MAX17048_VCELL          0x02 // voltage
 6#define MAX17048_SOC            0x04 // percentage
 7#define MAX17048_MODE           0x06
 8#define MAX17048_VERSION        0x08
 9#define MAX17048_CONFIG         0x0c
10#define MAX17048_COMMAND        0xfe
11
12class MAX17048Sensor : public PollingComponent, public Sensor {
13 public:
14  Sensor *voltage_sensor = new Sensor();
15  Sensor *percentage_sensor = new Sensor();
16
17  MAX17048Sensor() : PollingComponent(update_interval) {}
18
19  void setup() override {
20    // Initialize the device here. Usually Wire.begin() will be called in here,
21    // though that call is unnecessary if you have an 'i2c:' entry in your config
22    ESP_LOGD("custom", "Starting up MAX17048 sensor");
23
24    // Wire.begin();
25  }
26
27  uint16_t read16(uint8_t reg) {
28      uint16_t temp;
29      Wire.begin();
30      Wire.beginTransmission(MAX17048_ADDRESS);
31      Wire.write(reg);
32      Wire.endTransmission();
33      Wire.requestFrom(MAX17048_ADDRESS, 2);
34      temp = (uint16_t)Wire.read() << 8;
35      temp |= (uint16_t)Wire.read();
36      Wire.endTransmission();
37      return temp;
38  }
39
40  void update() override {
41    float voltage = (float)(read16(MAX17048_VCELL)) * 78.125 / 1000000;
42    voltage_sensor->publish_state(voltage);
43
44    uint16_t percentage_tmp = read16(MAX17048_SOC);
45    float percentage = (float)(percentage_tmp) / 256;
46    percentage_sensor->publish_state(percentage);
47  }
48};
smart-dashboard.yaml

This is the YAML configuration file, the most important file that configures your ESPHome-based Smart Dashboard:

  1substitutions:
  2  device_name: "smart-dashboard"
  3  friendly_name: "Smart Dashboard"
  4  project_name: "smart.dashboard"
  5  project_version: "1.0"
  6  ap_ssid: "Smart-Dashboard"
  7  ap_pwd: "smartdashboard"
  8
  9esphome:
 10  name: "${device_name}"
 11  name_add_mac_suffix: true
 12  includes:
 13    - libraries/MAX17048.h
 14  libraries:
 15    - "Wire"
 16    - "SPI"
 17  project:
 18    name: "${project_name}"
 19    version: "${project_version}"
 20  # Initialize the IIC bus immediatelly after the powering the sensors
 21  on_boot:
 22    priority: 600
 23    then:
 24     - lambda: |-
 25        Wire.begin();
 26        delay(100);
 27
 28     - script.execute: consider_deep_sleep
 29
 30esp32:
 31  board: esp32-s2-saola-1
 32  framework:
 33    type: arduino
 34
 35# Enable logging
 36logger:
 37
 38# Enable Home Assistant API
 39api:
 40
 41# Enable Over The Air updates
 42ota:
 43
 44
 45#Public location of this yaml file
 46dashboard_import:
 47  package_import_url: github://JGAguado/Smart_Dashboard/docs/source/files/configuration.yaml
 48  import_full_config: false
 49
 50# Enable fallback hotspot (captive portal) in case wifi connection fails
 51captive_portal:
 52
 53improv_serial:
 54
 55wifi:
 56  ssid: !secret wifi_ssid
 57  password: !secret wifi_password
 58
 59  ap:
 60    ssid: "${ap_ssid}"
 61    password: "${ap_pwd}"
 62
 63
 64i2c:
 65  scl: GPIO34
 66  sda: GPIO33
 67  scan: false
 68  id: bus_a
 69  frequency: 50kHz
 70
 71spi:
 72  clk_pin:  GPIO36
 73  miso_pin: GPIO35
 74
 75
 76font:
 77  - file: "gfonts://Audiowide"
 78    id: font_title
 79    size: 20
 80
 81switch:
 82  - platform: gpio
 83    pin: GPIO13
 84    id: exc
 85    name: "Excitation switch"
 86    icon: "mdi:power"
 87    restore_mode: ALWAYS_ON  
 88    
 89    
 90sensor:    
 91  # Battery level sensor  
 92  - platform: custom
 93    lambda: |-
 94      auto max17048_sensor = new MAX17048Sensor();
 95      App.register_component(max17048_sensor);
 96      return {max17048_sensor->voltage_sensor, max17048_sensor->percentage_sensor};
 97    sensors:
 98      - name: "Bat. voltage"
 99        unit_of_measurement: V
100        accuracy_decimals: 2
101        id: batvoltage
102
103      - name: "Battery"
104        id: battery
105        icon: "mdi:battery"
106        unit_of_measurement: '%'
107
108  # Temperature - Air pressure 
109  - platform: bmp280
110    temperature:
111      name: "Internal Temperature"
112      oversampling: 16x
113    pressure:
114      name: "Absolute Pressure"
115    address: 0x77
116    i2c_id: bus_a
117
118  # WiFi Signal     
119  - platform: wifi_signal
120    name: "WiFi Signal Sensor"
121    id: wifisignal
122    update_interval: 20s
123
124image:
125  - file: "images/Screenshot bw.png"
126    id: screenshot
127
128display:
129  - platform: waveshare_epaper
130    id: my_display
131    cs_pin: GPIO8
132    dc_pin: GPIO7
133    busy_pin: 
134      number: GPIO5
135      inverted: true
136    reset_pin: GPIO6
137    model: 7.50inV2alt
138    reset_duration: 2ms
139    update_interval: never
140    auto_clear_enabled: false
141    lambda: |-
142      it.image(0, 0, id(screenshot));
143
144deep_sleep:
145  id: deep_sleep_control
146  # run_duration: 5s
147  sleep_duration: 1h
148
149script:
150  - id: consider_deep_sleep
151    mode: queued
152    then:
153      - delay: 5s
154      - component.update: my_display   
155      - delay: 5s           
156      - if:
157          condition:
158            sensor.in_range:
159              id: batvoltage
160              above: 4.15
161          then:
162            - deep_sleep.prevent: deep_sleep_control 
163          else:
164            - deep_sleep.enter: deep_sleep_control 
165
166      - delay: 25s
167      - script.execute: consider_deep_sleep          

Arduino

If you are still interested in programming directly with the Arduino IDE, the procedure is no different than with any other ESP32 devices:

  1. Open the Arduino IDE and go to File -> Preferences option.

  2. Add to the Additional Boards Manager URSLs the url:

https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
  1. Close the preferences and open in the menu Tools -> Board -> Boards Manager.

  2. Search for esp32 and install it. This might take some time.

  3. Now you can select the board ESP32 Dev Module as the target board. Leave the rest of parameters by default.

  4. The right libraries from the e-paper displays can be found directly at Waveshare’s documentation website:

  1. Select the correct port and remember to enter the board into flashing mode before uploading the sketch.