Merge branch '0.1.0-dev' of https://github.com/fvanroie/hasp-lvgl into 0.1.0-dev

This commit is contained in:
fvanroie 2020-05-23 11:52:28 +02:00
commit c072e87f7e
54 changed files with 2574 additions and 1845 deletions

2
.gitignore vendored
View File

@ -5,8 +5,10 @@
.git .git
.pio .pio
data/* data/*
src/user_setups/active/*
src/user_config_override.h src/user_config_override.h
platformio_override.ini platformio_override.ini
user_setups/active/*
## Visual Studio Code specific ###### ## Visual Studio Code specific ######
.vscode .vscode

View File

@ -1,4 +1,10 @@
# HASP - Open Hardware edition # HASP - Open Hardware edition
[![GitHub release](https://img.shields.io/github/release/fvanroie/hasp-lvgl.svg)](https://github.com/fvanroie/hasp-lvgl/releases)
[![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/fvanroie/hasp-lvgl/blob/master/LICENSE)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing)
[![GitHub issues](https://img.shields.io/github/issues/fvanroie/hasp-lvgl.svg)](http://github.com/fvanroie/hasp-lvgl/issues)
This project is a re-implementation of the popular HASwitchPlate sketch created by aderusha. This project is a re-implementation of the popular HASwitchPlate sketch created by aderusha.
The [original HASwitchPlate][1] project uses a Wemos D1 mini and requires a Nextion/TJC HMI display. The [original HASwitchPlate][1] project uses a Wemos D1 mini and requires a Nextion/TJC HMI display.
This rewrite removes the Nextion/TJC requirement by using the [Littlev Graphics Library][2] on the MCU to drive a cheap commodity display. This rewrite removes the Nextion/TJC requirement by using the [Littlev Graphics Library][2] on the MCU to drive a cheap commodity display.
@ -19,14 +25,14 @@ This version also adds ESP32 and STM32 support to take advantage of the addition
| SPI display | :white_check_mark: yes | :white_check_mark: yes | :white_check_mark: yes | SPI display | :white_check_mark: yes | :white_check_mark: yes | :white_check_mark: yes
| Parallel display | :x: no | :white_check_mark: yes | :white_check_mark: yes | Parallel display | :x: no | :white_check_mark: yes | :white_check_mark: yes
| PWM Screen dimming | :white_check_mark: yes | :white_check_mark: yes | :white_check_mark: yes | PWM Screen dimming | :white_check_mark: yes | :white_check_mark: yes | :white_check_mark: yes
| Maximum Page Count | 4 | 12 | | Maximum Page Count | 4 | 12 | 12
| Object Types / Widgets | 14 | 15 | 15 | Object Types / Widgets | 14 | 15 | 15
| Dynamic Objects | :white_check_mark: yes | :white_check_mark: yes | :white_check_mark: yes | Dynamic Objects | :white_check_mark: yes | :white_check_mark: yes | :white_check_mark: yes
| [Lvgl Theme Support][3] | basic only | all themes | tbd | [Lvgl Theme Support][3] | basic only | all themes | tbd
| [Custom .zi V5 font][4] | :white_check_mark: yes (latin1) | :white_check_mark: yes (latin1) | no | [Custom .zi V5 font][4] | :white_check_mark: yes (latin1) | :white_check_mark: yes (latin1) | no
| [FontAwesome Icons][5] | :white_check_mark: 1300+ | :white_check_mark: 1300+ | no | [FontAwesome Icons][5] | :white_check_mark: 1300+ | :white_check_mark: 1300+ | no
| PNG images | :x: no | :grey_question: tbd | :grey_question: tbd | PNG images | :x: no | :grey_question: tbd | :grey_question: tbd
| Network | :white_check_mark: Wifi | :white_check_mark: Wifi | :grey_question: tbd | Network | :white_check_mark: Wifi | :white_check_mark: Wifi | :white_check_mark: Ethernet
## Cloning ## Cloning

View File

@ -7,43 +7,88 @@
#define HASP_USE_APP 1 #define HASP_USE_APP 1
/* Network */ /* Network Services */
#define HASP_HAS_NETWORK (ARDUINO_ARCH_ESP32>0 || ARDUINO_ARCH_ESP8266>0) #define HASP_HAS_NETWORK (ARDUINO_ARCH_ESP32 > 0 || ARDUINO_ARCH_ESP8266 > 0)
#ifndef HASP_USE_OTA
#define HASP_USE_OTA (HASP_HAS_NETWORK) #define HASP_USE_OTA (HASP_HAS_NETWORK)
#define HASP_USE_WIFI (HASP_HAS_NETWORK)
#define HASP_USE_MQTT (HASP_HAS_NETWORK)
#define HASP_USE_HTTP (HASP_HAS_NETWORK)
#define HASP_USE_MDNS (HASP_HAS_NETWORK)
#define HASP_USE_SYSLOG (HASP_HAS_NETWORK)
#define HASP_USE_TELNET (HASP_HAS_NETWORK)
/* Filesystem */
#define HASP_HAS_FILESYSTEM (ARDUINO_ARCH_ESP32>0 || ARDUINO_ARCH_ESP8266>0)
#define HASP_USE_SPIFFS (HASP_HAS_FILESYSTEM)
#define HASP_USE_EEPROM (HASP_HAS_FILESYSTEM)
#define HASP_USE_SDCARD 0
#define HASP_USE_BUTTON 1
#define HASP_USE_QRCODE 1
#define HASP_USE_PNGDECODE 0
#define HASP_NUM_INPUTS 3 // Buttons
#define HASP_NUM_OUTPUTS 3
#if defined(ARDUINO_ARCH_ESP32)
#define HASP_NUM_PAGES 12
#else
#define HASP_NUM_PAGES 4
#endif #endif
#ifndef HASP_USE_WIFI
#define HASP_USE_WIFI (HASP_HAS_NETWORK)
#endif
#if HASP_USE_SPIFFS>0 #ifndef HASP_USE_ETHERNET
#define HASP_USE_ETHERNET 0
#endif
#ifndef HASP_USE_MQTT
#define HASP_USE_MQTT 1
#endif
#ifndef HASP_USE_HTTP
#define HASP_USE_HTTP 1
#endif
#ifndef HASP_USE_MDNS
#define HASP_USE_MDNS (HASP_HAS_NETWORK)
#endif
#ifndef HASP_USE_SYSLOG
#define HASP_USE_SYSLOG 0
#endif
#ifndef HASP_USE_TELNET
#define HASP_USE_TELNET 0
#endif
/* Filesystem */
#define HASP_HAS_FILESYSTEM (ARDUINO_ARCH_ESP32 > 0 || ARDUINO_ARCH_ESP8266 > 0)
#ifndef HASP_USE_SPIFFS
#define HASP_USE_SPIFFS (HASP_HAS_FILESYSTEM)
#endif
#ifndef HASP_USE_EEPROM
#define HASP_USE_EEPROM 1
#endif
#ifndef HASP_USE_SDCARD
#define HASP_USE_SDCARD 0
#endif
#ifndef HASP_USE_GPIO
#define HASP_USE_GPIO 1
#endif
#ifndef HASP_USE_QRCODE
#define HASP_USE_QRCODE 1
#endif
#ifndef HASP_USE_PNGDECODE
#define HASP_USE_PNGDECODE 0
#endif
#ifndef HASP_NUM_INPUTS
#define HASP_NUM_INPUTS 3 // Buttons
#endif
#ifndef HASP_NUM_OUTPUTS
#define HASP_NUM_OUTPUTS 3
#endif
#ifndef HASP_NUM_PAGES
#if defined(ARDUINO_ARCH_ESP8266)
#define HASP_NUM_PAGES 4
#else
#define HASP_NUM_PAGES 12
#endif
#endif
/* Includes */
#if HASP_USE_SPIFFS > 0
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h" #include "SPIFFS.h"
#include "hasp_eeprom.h"
#endif #endif
#include <FS.h> // Include the SPIFFS library #include <FS.h> // Include the SPIFFS library
#include "hasp_spiffs.h" #include "hasp_spiffs.h"
@ -51,42 +96,70 @@
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
//#include "lv_zifont.h" //#include "lv_zifont.h"
#endif #endif
#endif #endif // SPIFFS
#if HASP_USE_EEPROM>0 #if HASP_USE_EEPROM > 0
#include "hasp_eeprom.h" #include "hasp_eeprom.h"
#endif #endif
#if HASP_USE_WIFI>0 #if HASP_USE_WIFI > 0
#include "hasp_wifi.h" #include "hasp_wifi.h"
#endif #endif
#if HASP_USE_MQTT>0 #if HASP_USE_ETHERNET > 0
#if USE_BUILTIN_ETHERNET > 0
#include <LwIP.h>
#include <STM32Ethernet.h>
#warning Use built-in STM32 Ethernet
#elif USE_UIP_ETHERNET
#include <UIPEthernet.h>
#include <utility/logging.h>
#warning Use ENC28J60 Ethernet shield
#else
#include "Ethernet.h"
#warning Use W5x00 Ethernet shield
#endif
#include "hasp_ethernet.h"
#endif
#if HASP_USE_MQTT > 0
#include "hasp_mqtt.h" #include "hasp_mqtt.h"
#endif #endif
#if HASP_USE_HTTP>0 #if HASP_USE_HTTP > 0
#include "hasp_http.h" #include "hasp_http.h"
#endif #endif
#if HASP_USE_TELNET>0 #if HASP_USE_TELNET > 0
#include "hasp_telnet.h" #include "hasp_telnet.h"
#endif #endif
#if HASP_USE_MDNS>0 #if HASP_USE_MDNS > 0
#include "hasp_mdns.h" #include "hasp_mdns.h"
#endif #endif
#if HASP_USE_BUTTON>0 #if HASP_USE_BUTTON > 0
#include "hasp_button.h" #include "hasp_button.h"
#endif #endif
#if HASP_USE_OTA>0 #if HASP_USE_OTA > 0
#include "hasp_ota.h" #include "hasp_ota.h"
#endif #endif
#if HASP_USE_TASMOTA_SLAVE > 0
#include "hasp_slave.h"
#endif
#if HASP_USE_ETHERNET > 0
#include "hasp_ethernet.h"
#endif #endif
#ifndef FPSTR #ifndef FPSTR
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer)) #define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
#endif #endif
#ifndef PGM_P
#define PGM_P const char *
#endif
#endif // HASP_CONF_H

View File

@ -80,7 +80,7 @@ typedef int16_t lv_coord_t;
# define LV_MEM_SIZE (12 * 1024U) // 12KB # define LV_MEM_SIZE (12 * 1024U) // 12KB
#endif #endif
#ifndef LV_MEM_SIZE #ifndef LV_MEM_SIZE
# define LV_MEM_SIZE (64 * 1024U) // 48KB # define LV_MEM_SIZE (20 * 1024U) // 48KB
#endif #endif
/* Complier prefix for a big array declaration */ /* Complier prefix for a big array declaration */

View File

@ -0,0 +1,16 @@
/* Include the normal default core configuration */
#include "stm32f4xx_hal_conf_default.h"
#if USE_BUILTIN_ETHERNET
/* Remove the default PHY address */
#ifdef LAN8742A_PHY_ADDRESS
#undef LAN8742A_PHY_ADDRESS
#endif
/* Section 2: PHY configuration section */
/* Redefine LAN8742A PHY Address*/
#ifndef LAN8742A_PHY_ADDRESS
#define LAN8742A_PHY_ADDRESS 0x01U //HASP_PHY_ADDRESS
#endif
#endif

View File

@ -8,7 +8,7 @@ lolin24 =
-D ILI9341_DRIVER=1 -D ILI9341_DRIVER=1
-D TFT_WIDTH=240 -D TFT_WIDTH=240
-D TFT_HEIGHT=320 -D TFT_HEIGHT=320
-D TFT_ROTATION=0 ; 0=0, 1=90, 2=180 or 3=270 degree -D TFT_ROTATION=2 ; 0=0, 1=90, 2=180 or 3=270 degree
-D SPI_FREQUENCY=40000000 -D SPI_FREQUENCY=40000000
-D SPI_TOUCH_FREQUENCY=2500000 -D SPI_TOUCH_FREQUENCY=2500000
-D SPI_READ_FREQUENCY=20000000 -D SPI_READ_FREQUENCY=20000000

View File

@ -129,7 +129,6 @@ void Logging::print(Print * logOutput, const char * format, va_list args)
++format; ++format;
printFormat(logOutput, *format, (va_list *)&args); printFormat(logOutput, *format, (va_list *)&args);
} else { } else {
//_logOutput->print(*format);
logOutput->print(*format); logOutput->print(*format);
} }
} }

View File

@ -285,19 +285,15 @@ class Logging {
if(_logOutput[i] == NULL || level>_level[i]) continue; if(_logOutput[i] == NULL || level>_level[i]) continue;
if(_prefix != NULL) { if(_prefix != NULL) {
// _prefix(level, _logOutput[i]); _prefix(level, _logOutput[i]);
} }
va_list args; va_list args;
va_start(args, msg); va_start(args, msg);
#ifdef STM32_CORE_VERSION_MAJOR print(_logOutput[i], msg, args);
print(_logOutput[i], msg, args);
Serial.println();
#else
print(_logOutput[i], msg, args);
#endif
if(_suffix != NULL) { if(_suffix != NULL) {
// _suffix(level, _logOutput[i]); _suffix(level, _logOutput[i]);
} }
} }

View File

@ -150,7 +150,7 @@ static lv_fs_res_t fs_open(lv_fs_drv_t * drv, void * file_p, const char * path,
Log.verbose(F("LVFS: %d"), __LINE__); Log.verbose(F("LVFS: %d"), __LINE__);
lv_spiffs_file_t * fp = (lv_spiffs_file_t *)file_p; /*Just avoid the confusing casings*/ lv_spiffs_file_t * fp = (lv_spiffs_file_t *)file_p; /*Just avoid the confusing casings*/
// Log.verbose(F("LVFS: Copying %s"), f.name()); // Log.verbose(F("LVFS: Copying %s"), f.name());
Log.verbose(F("LVFS: %d"), __LINE__); Log.verbose(F("LVFS: %d - %x - %d"), __LINE__, fp, sizeof(lv_spiffs_file_t));
if (fp != NULL) (*fp) = file; if (fp != NULL) (*fp) = file;
// memcpy(fp,&file,sizeof(lv_spiffs_file_t)); // memcpy(fp,&file,sizeof(lv_spiffs_file_t));
Log.verbose(F("LVFS: %d"), __LINE__); Log.verbose(F("LVFS: %d"), __LINE__);

@ -1 +1 @@
Subproject commit 8b663bdc39b8a745cee39334b2f6c065babd5fd9 Subproject commit ecd0d4fb0907d73e07788283c16e5a4ab1e829b6

View File

@ -18,6 +18,9 @@ extra_configs =
pin_config.ini pin_config.ini
; -- Add customizations to this file only: ; -- Add customizations to this file only:
platformio_override.ini platformio_override.ini
; -- Put active [env] files in this dir to be included in the build menu
user_setups/active/*.ini
user_setups/*/*.ini
default_envs = default_envs =
; Uncomment the needed environments in platformio_override.ini ; Uncomment the needed environments in platformio_override.ini
@ -47,11 +50,13 @@ lib_deps =
;TFT_eSPI@^1.4.20 ; Tft SPI drivers ;TFT_eSPI@^1.4.20 ; Tft SPI drivers
PubSubClient@^2.7.0 ; MQTT client PubSubClient@^2.7.0 ; MQTT client
ArduinoJson@^6.15.1,>6.15.0 ; needs at least 6.15.0 ArduinoJson@^6.15.1,>6.15.0 ; needs at least 6.15.0
StreamUtils@^1.4.0
Syslog@^2.0.0 Syslog@^2.0.0
AceButton@^1.4.0 AceButton@^1.4.0
;AsyncTCP ;AsyncTCP
;https://github.com/me-no-dev/ESPAsyncWebServer/archive/master.zip ;https://github.com/me-no-dev/ESPAsyncWebServer/archive/master.zip
;https://github.com/me-no-dev/ESPAsyncTCP/archive/master.zip ;https://github.com/me-no-dev/ESPAsyncTCP/archive/master.zip
https://github.com/andrethomas/TasmotaSlave.git
lib_ignore = lib_ignore =
https://github.com/littlevgl/lvgl.git https://github.com/littlevgl/lvgl.git
@ -67,6 +72,7 @@ build_flags =
-D SPIFFS_TEMPORAL_FD_CACHE ; speedup opening recent files -D SPIFFS_TEMPORAL_FD_CACHE ; speedup opening recent files
-D ARDUINOJSON_DECODE_UNICODE=1 ; for utf-8 symbols -D ARDUINOJSON_DECODE_UNICODE=1 ; for utf-8 symbols
-D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments -D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments
-D STREAMUTILS_ENABLE_EEPROM=1 ; for STM32, it also supports EEPROM
;-D DISABLE_LOGGING ;-D DISABLE_LOGGING
-I include ; include lv_conf.h and hasp_conf.h -I include ; include lv_conf.h and hasp_conf.h
${override.build_flags} ${override.build_flags}
@ -88,6 +94,9 @@ esp32_flags=
stm32_flags= stm32_flags=
${env.build_flags} ${env.build_flags}
-D IRAM_ATTR= ; No IRAM_ATTR available on STM32 -D IRAM_ATTR= ; No IRAM_ATTR available on STM32
-D STM32
-D STREAMUTILS_USE_EEPROM_UPDATE=1 ; update cell only when changed
-D MQTT_MAX_PACKET_SIZE=2048 ; longer PubSubClient messages
; -- By default there are no ${override.build_flags} set ; -- By default there are no ${override.build_flags} set
; -- to use it, copy platformio_override.ini from the template ; -- to use it, copy platformio_override.ini from the template
@ -120,210 +129,6 @@ hspi32 =
; 7 - mirror content, and rotate 90 deg anti-clockwise ; 7 - mirror content, and rotate 90 deg anti-clockwise
;***************************************************
; STM32F4 build
;***************************************************
[env:black_f407vg]
platform = ststm32
board = diymore_f407vgt
board_build.mcu = stm32f407vgt6
upload_protocol = dfu
monitor_port = COM7 ; To change the port, use platform_override.ini
build_flags =
${env.build_flags}
${flags.stm32_flags}
-I include/stm32f4
; -- TFT_eSPI build options ------------------------
${lcd.lolin24}
;-D TFT_MISO=PB4 ;Default
;-D TFT_MOSI=PB5 ;Default
;-D TFT_SCLK=PB3 ;Default
-D TFT_CS=PB11 ;D8
-D TFT_DC=PC5 ;D3
-D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4)
-D TOUCH_CS=PC4 ;NC
-D TFT_RST=-1 ;D4
-D STM32
lib_deps =
${env.lib_deps}
Ticker@^3.1.5
STM32duino LwIP@^2.1.2
STM32duino STM32Ethernet@^1.0.5
src_filter = +<*> -<.git/> -<.svn/> -<example/> -<examples/> -<test/> -<tests/> -<lv_lib_zifont/> +<stm32f4/>
;***************************************************
; Generic ESP32 build
;***************************************************
[env:esp32dev-mrb3511]
platform = espressif32
board = esp32dev
upload_port = COM1 ; To change the port, use platform_override.ini
monitor_port = COM1 ; To change the port, use platform_override.ini
debug_tool = esp-prog
debug_init_break = tbreak setup
build_flags =
${flags.esp32_flags}
; -- TFT_eSPI build options ------------------------
${lcd.mrb3511}
-D TFT_BCKL=5 ;None, configurable via web UI (e.g. 2 for D4)
-D TFT_CS=33 ; Chip select control pin
-D TFT_DC=15 ; =RS; Data Command control pin - must use a pin in the range 0-31
-D TFT_RST=32 ; Reset pin
-D TFT_WR=4 ; Write strobe control pin - must use a pin in the range 0-31
-D TFT_RD=2
-D TFT_D0=12 ; Must use pins in the range 0-31 for the data bus
-D TFT_D1=13 ; so a single register write sets/clears all bits
-D TFT_D2=26
-D TFT_D3=25
-D TFT_D4=17
-D TFT_D5=16
-D TFT_D6=27
-D TFT_D7=14
-D TOUCH_SDA=21
-D TOUCH_SCL=22
-D TOUCH_IRQ=34 ; use 34-39 as these are input only pins
-D TOUCH_RST=-1 ; not used, connected to 3.3V
; -- Debugging options -----------------------------
; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
; -- Library options -------------------------------
lib_deps =
${env.lib_deps}
https://github.com/netwizeBE/arduino-goodix.git ; GT911 touch screen driver
src_filter = +<*> +<../drivers/stm32f429_disco>
;***************************************************
; Generic ESP32 build with ILI9488 SPI 4-WIRE
;***************************************************
[env:esp32dev-ili9488]
platform = espressif32
board = esp32dev
upload_port = COM2 ; To change the port, use platform_override.ini
monitor_port = COM2 ; To change the port, use platform_override.ini
; upload_protocol = espota ; Use ArduinoOTA after flashing over serial
; upload_port = 10.4.0.171 ; IP of the ESP
; upload_flags =
; --port=3232
debug_tool = esp-prog
debug_init_break = tbreak setup
build_flags =
${flags.esp32_flags}
; -- TFT_eSPI build options ------------------------
-D USER_SETUP_LOADED=1
-D ILI9488_DRIVER=1
-D TFT_ROTATION=0 ; 0=0, 1=90, 2=180 or 3=270 degree
-D TFT_WIDTH=320
-D TFT_HEIGHT=480
-D TFT_MISO=19 ;// (leave TFT SDO disconnected if other SPI devices share MISO)
-D TFT_MOSI=23
-D TFT_SCLK=18
-D TFT_CS=15 ;// Chip select control pin
-D TFT_DC=2 ;// Data Command control pin
-D TFT_RST=4 ;// Reset pin (could connect to RST pin)
-D TFT_BCKL=5 ;None, configurable via web UI (e.g. 2 for D4)
-D SUPPORT_TRANSACTIONS
-D TOUCH_CS=22
-D TOUCH_DRIVER=0 ; XPT2606 Resistive touch panel driver
-D SPI_FREQUENCY=27000000
-D SPI_TOUCH_FREQUENCY=2500000
-D SPI_READ_FREQUENCY=16000000
; -- Debugging options -----------------------------
; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
; -- Library options -------------------------------
lib_deps =
${env.lib_deps}
src_filter = +<*> +<../drivers/stm32f429_disco>
;***************************************************
; NodeMCU32S with MHS-4" RPI Display-B
;***************************************************
[env:nodemcu32s-raspi]
platform = espressif32
board = nodemcu-32s
upload_port = COM3 ; To change the port, use platform_override.ini
monitor_port = COM3 ; To change the port, use platform_override.ini
debug_tool = esp-prog
debug_init_break = tbreak setup
build_flags =
${flags.esp32_flags}
; -- TFT_eSPI build options ------------------------
${lcd.raspberrypi}
${pins.vspi32}
-D TFT_CS=15
-D TFT_DC=4
-D TFT_RST=32
-D TOUCH_CS=22
; -- Debugging options -----------------------------
; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
; -- Library options -------------------------------
lib_deps =
${env.lib_deps}
;***************************************************
; ESP32 build
;***************************************************
[env:d132-unoshield]
platform = espressif32
board = esp32dev
upload_port = COM4 ; To change the port, use platform_override.ini
monitor_port = COM4 ; To change the port, use platform_override.ini
build_flags =
${flags.esp32_flags}
; -- TFT_eSPI build options ------------------------
-D USER_SETUP_LOADED=1
;-D ST7796_DRIVER=1 ;3.95inch Arduino Display-UNO
-D ILI9486_DRIVER=1 ;3.5inch Arduino Display-UNO
-D ESP32_PARALLEL=1
-D TFT_ROTATION=${lcd.TFT_ROTATION}
-D TFT_WIDTH=320
-D TFT_HEIGHT=480
${pins.vspi32}
-D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4)
-D TFT_CS=33 ; Chip select control pin
-D TFT_DC=15 ; Data Command control pin - must use a pin in the range 0-31
-D TFT_RST=32 ; Reset pin
-D TFT_WR=4 ; Write strobe control pin - must use a pin in the range 0-31
-D TFT_RD=2
-D TFT_D0=12 ; Must use pins in the range 0-31 for the data bus
-D TFT_D1=13 ; so a single register write sets/clears all bits
-D TFT_D2=26
-D TFT_D3=25
-D TFT_D4=17
-D TFT_D5=16
-D TFT_D6=27
-D TFT_D7=14
-D SD_CS=5
-D SPI_FREQUENCY=40000000
;-D SPI_TOUCH_FREQUENCY=2500000 ; Uses ADC instead
-D SPI_READ_FREQUENCY=20000000
; -- Debugging options -----------------------------
; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
; -- Library options -------------------------------
lib_deps =
${env.lib_deps}
src_filter = +<*> +<../drivers/stm32f429_disco>
;*************************************************** ;***************************************************
; D1 Mini ESP32 with Lolin TFT 2.4" ; D1 Mini ESP32 with Lolin TFT 2.4"
;*************************************************** ;***************************************************
@ -393,42 +198,6 @@ build_flags =
-D TFT_RST=-1 ;RST -D TFT_RST=-1 ;RST
;***************************************************
; ESP-12 build
;***************************************************
[env:esp12e-st7735]
platform = espressif8266@^2.4.0 ;@2.3.2
board = esp12e
upload_port = COM8 ; To change the port, use platform_override.ini
monitor_port = COM8 ; To change the port, use platform_override.ini
board_build.f_flash = 40000000L
board_build.flash_mode = dout
board_build.ldscript = eagle.flash.4m2m.ld ; 2Mb Spiffs
board_build.f_cpu = 160000000L ; set frequency to 160MHz
build_flags =
${flags.esp8266_flags}
; -- TFT_eSPI build options ------------------------
-D USER_SETUP_LOADED=1
-D ST7735_DRIVER=1
-D ST7735_BLACKTAB=1
-D TFT_ROTATION=${lcd.TFT_ROTATION}
-D TFT_WIDTH=128
-D TFT_HEIGHT=160
-D TFT_MISO=-1 ;NC
-D TFT_MOSI=13 ;D7
-D TFT_SCLK=14 ;D5
-D TFT_CS=15 ;D8
-D TFT_DC=0 ;D3
-D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4)
-D TOUCH_CS=-1 ;NC
-D TFT_RST=2 ;D4
-D SPI_FREQUENCY=27000000
; -- Library options -------------------------------
lib_deps =
${env.lib_deps}
;Ethernet@<2.0.0
;*************************************************** ;***************************************************
; Native build ; Native build
;*************************************************** ;***************************************************

View File

@ -1,7 +1,7 @@
; Copy this file and rename it to platform_override.ini ; Copy this file and rename it to platformio_override.ini
; ONLY edit platform_override.ini to make local changes to the parameters ; ONLY edit platformio_override.ini to make local changes to the parameters
; ;
; The platform_override.ini file is not overwritten or monitored by git ; The platformio_override.ini file is not overwritten or monitored by git
[override] [override]

View File

@ -3,8 +3,9 @@
*********************/ *********************/
#include "hasp_conf.h" #include "hasp_conf.h"
#include <Arduino.h> #include <Arduino.h>
#include "ArduinoJson.h"
#include "ArduinoLog.h" #include "ArduinoLog.h"
#include "ArduinoJson.h"
#include "StreamUtils.h"
#include "lvgl.h" #include "lvgl.h"
#include "lv_conf.h" #include "lv_conf.h"
@ -24,6 +25,8 @@
#include "hasp_attribute.h" #include "hasp_attribute.h"
#include "hasp.h" #include "hasp.h"
#include "EEPROM.h"
//#if LV_USE_HASP //#if LV_USE_HASP
/********************* /*********************
@ -665,7 +668,7 @@ void haspClearPage(uint16_t pageid)
Log.warning(F("HASP: Cannot clear a layer")); Log.warning(F("HASP: Cannot clear a layer"));
} else { } else {
Log.notice(F("HASP: Clearing page %u"), pageid); Log.notice(F("HASP: Clearing page %u"), pageid);
lv_page_clean(pages[pageid]); lv_obj_clean(pages[pageid]);
} }
} }
@ -955,6 +958,15 @@ void haspLoadPage(const char * pages)
file.close(); file.close();
Log.notice(F("HASP: File %s loaded"), pages); Log.notice(F("HASP: File %s loaded"), pages);
#else
#if HASP_USE_EEPROM > 0
Log.notice(F("HASP: Loading jsonl from EEPROM..."));
EepromStream eepromStream(4096, 1024);
dispatchJsonl(eepromStream);
Log.notice(F("HASP: Loaded jsonl from EEPROM"));
#endif
#endif #endif
} }

View File

@ -19,7 +19,7 @@ extern "C" {
* INCLUDES * INCLUDES
*********************/ *********************/
#if HASP_USE_APP #if HASP_USE_APP>0
/********************* /*********************
* DEFINES * DEFINES
@ -81,8 +81,6 @@ void hasp_send_obj_attribute_int(lv_obj_t * obj, const char * attribute, int32_t
void hasp_send_obj_attribute_color(lv_obj_t * obj, const char * attribute, lv_color_t color); void hasp_send_obj_attribute_color(lv_obj_t * obj, const char * attribute, lv_color_t color);
void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char * attr, const char * payload); void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char * attr, const char * payload);
void haspSendCmd(String nextionCmd);
void haspParseJson(String & strPayload);
void haspNewObject(const JsonObject & config, uint8_t & saved_page_id); void haspNewObject(const JsonObject & config, uint8_t & saved_page_id);
void haspReconnect(void); void haspReconnect(void);
@ -101,10 +99,10 @@ void IRAM_ATTR toggle_event_handler(lv_obj_t * obj, lv_event_t event);
* MACROS * MACROS
**********************/ **********************/
#endif /*LV_USE_DEMO*/ #endif /*HASP_USE_APP*/
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif #endif
#endif /*DEMO_H*/ #endif /*HASP_H*/

View File

@ -84,13 +84,6 @@ static lv_color_t haspPayloadToColor(const char * payload)
case 7: case 7:
if(!strcmp_P(payload, PSTR("magenta"))) return haspLogColor(LV_COLOR_MAGENTA); if(!strcmp_P(payload, PSTR("magenta"))) return haspLogColor(LV_COLOR_MAGENTA);
/* HEX format #rrggbb or #rrggbbaa */
int r, g, b, a;
if(*payload == '#' && sscanf(payload + 1, "%2x%2x%2x%2x", &r, &g, &b, &a) == 4) {
return haspLogColor(LV_COLOR_MAKE(r, g, b));
} else if(*payload == '#' && sscanf(payload + 1, "%2x%2x%2x", &r, &g, &b) == 3) {
return haspLogColor(LV_COLOR_MAKE(r, g, b));
}
default: default:
// if(!strcmp_P(payload, PSTR("darkblue"))) return haspLogColor(LV_COLOR_MAKE(0, 51, 102)); // if(!strcmp_P(payload, PSTR("darkblue"))) return haspLogColor(LV_COLOR_MAKE(0, 51, 102));
// if(!strcmp_P(payload, PSTR("lightblue"))) return haspLogColor(LV_COLOR_MAKE(46, 203, // if(!strcmp_P(payload, PSTR("lightblue"))) return haspLogColor(LV_COLOR_MAKE(46, 203,
@ -98,6 +91,14 @@ static lv_color_t haspPayloadToColor(const char * payload)
break; break;
} }
/* HEX format #rrggbb or #rrggbbaa */
int r, g, b, a;
if(*payload == '#' && sscanf(payload + 1, "%2x%2x%2x%2x", &r, &g, &b, &a) == 4) {
return haspLogColor(LV_COLOR_MAKE(r, g, b));
} else if(*payload == '#' && sscanf(payload + 1, "%2x%2x%2x", &r, &g, &b) == 3) {
return haspLogColor(LV_COLOR_MAKE(r, g, b));
}
/* 16-bit RGB565 Color Scheme*/ /* 16-bit RGB565 Color Scheme*/
if(only_digits(payload)) { if(only_digits(payload)) {
uint16_t c = atoi(payload); uint16_t c = atoi(payload);
@ -582,23 +583,19 @@ static void hasp_process_obj_attribute_val(lv_obj_t * obj, const char * attr, co
lv_dropdown_set_selected(obj, val); lv_dropdown_set_selected(obj, val);
return; return;
} else if(check_obj_type(objtype, LV_HASP_LMETER)) { } else if(check_obj_type(objtype, LV_HASP_LMETER)) {
lv_linemeter_set_value(obj, intval); return update ? lv_linemeter_set_value(obj, intval) : hasp_out_int(obj, attr, lv_linemeter_get_value(obj));
return;
} else if(check_obj_type(objtype, LV_HASP_SLIDER)) { } else if(check_obj_type(objtype, LV_HASP_SLIDER)) {
lv_slider_set_value(obj, intval, LV_ANIM_ON); return update ? lv_slider_set_value(obj, intval, LV_ANIM_ON)
return; : hasp_out_int(obj, attr, lv_slider_get_value(obj));
} else if(check_obj_type(objtype, LV_HASP_LED)) { } else if(check_obj_type(objtype, LV_HASP_LED)) {
lv_led_set_bright(obj, (uint8_t)val); return update ? lv_led_set_bright(obj, (uint8_t)val) : hasp_out_int(obj, attr, lv_led_get_bright(obj));
return;
} else if(check_obj_type(objtype, LV_HASP_GAUGE)) { } else if(check_obj_type(objtype, LV_HASP_GAUGE)) {
lv_gauge_set_value(obj, 0, intval); return update ? lv_gauge_set_value(obj, 0, intval) : hasp_out_int(obj, attr, lv_gauge_get_value(obj, 0));
return;
} else if(check_obj_type(objtype, LV_HASP_ROLLER)) { } else if(check_obj_type(objtype, LV_HASP_ROLLER)) {
lv_roller_set_selected(obj, val, LV_ANIM_ON); lv_roller_set_selected(obj, val, LV_ANIM_ON);
return; return;
} else if(check_obj_type(objtype, LV_HASP_BAR)) { } else if(check_obj_type(objtype, LV_HASP_BAR)) {
lv_bar_set_value(obj, intval, LV_ANIM_OFF); return update ? lv_bar_set_value(obj, intval, LV_ANIM_ON) : hasp_out_int(obj, attr, lv_bar_get_value(obj));
return;
} else if(check_obj_type(objtype, LV_HASP_CPICKER)) { } else if(check_obj_type(objtype, LV_HASP_CPICKER)) {
return update ? (void)lv_cpicker_set_color(obj, haspPayloadToColor(payload)) return update ? (void)lv_cpicker_set_color(obj, haspPayloadToColor(payload))
: hasp_out_color(obj, attr, lv_cpicker_get_color(obj)); : hasp_out_color(obj, attr, lv_cpicker_get_color(obj));
@ -794,9 +791,10 @@ void hasp_process_obj_attribute(lv_obj_t * obj, const char * attr_p, const char
* **************************/ * **************************/
static inline bool is_true(const char * s) static inline bool is_true(const char * s)
{ {
return (!strcmp_P(s, PSTR("true")) || !strcmp_P(s, PSTR("TRUE")) || !strcmp_P(s, PSTR("1")) || return (!strcmp_P(s, PSTR("true")) || !strcmp_P(s, PSTR("TRUE")) || !strcmp_P(s, PSTR("True")) ||
!strcmp_P(s, PSTR("on")) || !strcmp_P(s, PSTR("ON")) || !strcmp_P(s, PSTR("On")) || !strcmp_P(s, PSTR("on")) || !strcmp_P(s, PSTR("ON")) || !strcmp_P(s, PSTR("On")) ||
!strcmp_P(s, PSTR("yes")) || !strcmp_P(s, PSTR("YES")) || !strcmp_P(s, PSTR("Yes"))); !strcmp_P(s, PSTR("yes")) || !strcmp_P(s, PSTR("YES")) || !strcmp_P(s, PSTR("Yes")) ||
!strcmp_P(s, PSTR("1")));
} }
static inline bool only_digits(const char * s) static inline bool only_digits(const char * s)
@ -808,17 +806,17 @@ static inline bool only_digits(const char * s)
return strlen(s) == digits; return strlen(s) == digits;
} }
void hasp_out_int(lv_obj_t * obj, const char * attr, uint32_t val) void inline hasp_out_int(lv_obj_t * obj, const char * attr, uint32_t val)
{ {
hasp_send_obj_attribute_int(obj, attr, val); hasp_send_obj_attribute_int(obj, attr, val);
} }
void hasp_out_str(lv_obj_t * obj, const char * attr, const char * data) void inline hasp_out_str(lv_obj_t * obj, const char * attr, const char * data)
{ {
hasp_send_obj_attribute_str(obj, attr, data); hasp_send_obj_attribute_str(obj, attr, data);
} }
void hasp_out_color(lv_obj_t * obj, const char * attr, lv_color_t color) void inline hasp_out_color(lv_obj_t * obj, const char * attr, lv_color_t color)
{ {
hasp_send_obj_attribute_color(obj, attr, color); hasp_send_obj_attribute_color(obj, attr, color);
} }

View File

@ -1,75 +0,0 @@
#include "Arduino.h"
#include "ArduinoLog.h"
#include "AceButton.h"
#include "hasp_conf.h"
#include "lv_conf.h"
#include "hasp_mqtt.h" // testing memory consumption
#include "hasp_button.h"
#include "hasp_dispatch.h"
using namespace ace_button;
static AceButton * button[HASP_NUM_INPUTS]; // Connect your button between pin 2 and GND
static void button_event_cb(AceButton * button, uint8_t eventType, uint8_t buttonState)
{
char buffer[8];
switch(eventType) {
case 0: // AceButton::kEventPressed:
memcpy_P(buffer, PSTR("DOWN"), sizeof(buffer));
break;
case 2: // AceButton::kEventClicked:
memcpy_P(buffer, PSTR("SHORT"), sizeof(buffer));
break;
// case AceButton::kEventDoubleClicked:
// memcpy_P(buffer, PSTR("DOUBLE"), sizeof(buffer));
// break;
case 4: // AceButton::kEventLongPressed:
memcpy_P(buffer, PSTR("LONG"), sizeof(buffer));
break;
case 5: // AceButton::kEventRepeatPressed:
return; // Fix needed for switches
memcpy_P(buffer, PSTR("HOLD"), sizeof(buffer));
break;
case 1: // AceButton::kEventReleased:
memcpy_P(buffer, PSTR("UP"), sizeof(buffer));
break;
}
dispatch_button(button->getId(), buffer);
}
void buttonSetup(void)
{
// button[0] = new Button(2);
button[1] = new AceButton(3, HIGH, 1);
button[2] = new AceButton(4, HIGH, 2);
Log.verbose(F("BTNS: setup(): ready"));
ButtonConfig * buttonConfig = ButtonConfig::getSystemButtonConfig();
buttonConfig->setEventHandler(button_event_cb);
// Features
buttonConfig->setFeature(ButtonConfig::kFeatureClick);
buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
buttonConfig->setFeature(ButtonConfig::kFeatureRepeatPress);
// buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick);
// buttonConfig->setFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick);
// Delays
buttonConfig->setClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
buttonConfig->setDoubleClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
buttonConfig->setLongPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
buttonConfig->setRepeatPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
buttonConfig->setRepeatPressInterval(LV_INDEV_DEF_LONG_PRESS_REP_TIME);
}
void IRAM_ATTR buttonLoop(void)
{
// Should be called every 4-5ms or faster, for the default debouncing time
// of ~20ms.
for(uint8_t i = 0; i < HASP_NUM_INPUTS; i++) {
if(button[i]) button[i]->check();
}
}

View File

@ -1,10 +0,0 @@
#if HASP_USE_BUTTON
#ifndef HASP_BUTTON_H
#define HASP_BUTTON_H
void buttonSetup(void);
void IRAM_ATTR buttonLoop(void);
#endif
#endif

View File

@ -1,6 +1,7 @@
#include "Arduino.h" #include "Arduino.h"
#include "ArduinoJson.h"
#include "ArduinoLog.h" #include "ArduinoLog.h"
#include "ArduinoJson.h"
#include "StreamUtils.h"
#include "hasp_config.h" #include "hasp_config.h"
#include "hasp_debug.h" #include "hasp_debug.h"
@ -13,21 +14,16 @@
#include "hasp_conf.h" #include "hasp_conf.h"
#if HASP_USE_SPIFFS>0 #if HASP_USE_SPIFFS > 0
#include <FS.h> // Include the SPIFFS library #include <FS.h> // Include the SPIFFS library
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h" #include "SPIFFS.h"
#endif #endif
#endif #endif
#if HASP_USE_EEPROM>0 #if HASP_USE_EEPROM > 0
#include "EEPROM.h" #include "EEPROM.h"
#endif #endif
#ifndef FPSTR
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
#endif
void confDebugSet(const char * name) void confDebugSet(const char * name)
{ {
/*char buffer[128]; /*char buffer[128];
@ -77,13 +73,17 @@ void configStartDebug(bool setupdebug, String & configFile)
{ {
if(setupdebug) { if(setupdebug) {
debugStart(); // Debug started, now we can use it; HASP header sent debugStart(); // Debug started, now we can use it; HASP header sent
#if HASP_USE_SPIFFS > 0
Log.notice(F("FILE: [SUCCESS] SPI flash FS mounted")); Log.notice(F("FILE: [SUCCESS] SPI flash FS mounted"));
#if HASP_USE_SPIFFS>0
spiffsInfo(); spiffsInfo();
spiffsList(); spiffsList();
#endif #endif
} }
#if HASP_USE_SPIFFS > 0
Log.notice(F("CONF: Loading %s"), configFile.c_str()); Log.notice(F("CONF: Loading %s"), configFile.c_str());
#else
Log.notice(F("CONF: reading EEPROM"));
#endif
} }
void configGetConfig(JsonDocument & settings, bool setupdebug = false) void configGetConfig(JsonDocument & settings, bool setupdebug = false)
@ -91,9 +91,10 @@ void configGetConfig(JsonDocument & settings, bool setupdebug = false)
String configFile((char *)0); String configFile((char *)0);
configFile.reserve(128); configFile.reserve(128);
configFile = String(FPSTR(HASP_CONFIG_FILE)); configFile = String(FPSTR(HASP_CONFIG_FILE));
DeserializationError error;
#if HASP_USE_SPIFFS>0 #if HASP_USE_SPIFFS > 0
File file = SPIFFS.open(configFile, "r"); File file = SPIFFS.open(configFile, "r");
if(file) { if(file) {
size_t size = file.size(); size_t size = file.size();
@ -102,7 +103,7 @@ void configGetConfig(JsonDocument & settings, bool setupdebug = false)
return; return;
} }
DeserializationError error = deserializeJson(settings, file); error = deserializeJson(settings, file);
if(!error) { if(!error) {
file.close(); file.close();
@ -126,17 +127,26 @@ void configGetConfig(JsonDocument & settings, bool setupdebug = false)
return; return;
} }
} }
#else
#if HASP_USE_EEPROM > 0
EepromStream eepromStream(0, 1024);
error = deserializeJson(settings, eepromStream);
#endif
#endif #endif
// File does not exist or error reading file // File does not exist or error reading file
if(setupdebug) { if(setupdebug) {
debugPreSetup(settings[F("debug")]); debugPreSetup(settings[F("debug")]);
} }
configStartDebug(setupdebug, configFile); configStartDebug(setupdebug, configFile);
Log.error(F("CONF: Failed to load %s"), configFile.c_str());
}
#if HASP_USE_SPIFFS > 0
Log.error(F("CONF: Failed to load %s"), configFile.c_str());
#endif
}
/*
void configBackupToEeprom() void configBackupToEeprom()
{ {
#if HASP_USE_SPIFFS>0 #if HASP_USE_SPIFFS>0
@ -165,10 +175,9 @@ void configBackupToEeprom()
} }
#endif #endif
} }
*/
void configWriteConfig() void configWriteConfig()
{ {
#if HASP_USE_SPIFFS>0
String configFile((char *)0); String configFile((char *)0);
configFile.reserve(128); configFile.reserve(128);
configFile = String(FPSTR(HASP_CONFIG_FILE)); configFile = String(FPSTR(HASP_CONFIG_FILE));
@ -190,14 +199,15 @@ void configWriteConfig()
bool writefile = false; bool writefile = false;
bool changed = false; bool changed = false;
#if HASP_USE_WIFI #if HASP_USE_WIFI>0
if(settings[F("wifi")].as<JsonObject>().isNull()) settings.createNestedObject(F("wifi")); if(settings[F("wifi")].as<JsonObject>().isNull()) settings.createNestedObject(F("wifi"));
changed = wifiGetConfig(settings[F("wifi")]); changed = wifiGetConfig(settings[F("wifi")]);
if(changed) { if(changed) {
Log.verbose(F("WIFI: Settings changed")); Log.verbose(F("WIFI: Settings changed"));
writefile = true; writefile = true;
} }
#if HASP_USE_MQTT #endif
#if HASP_USE_MQTT>0
if(settings[F("mqtt")].as<JsonObject>().isNull()) settings.createNestedObject(F("mqtt")); if(settings[F("mqtt")].as<JsonObject>().isNull()) settings.createNestedObject(F("mqtt"));
changed = mqttGetConfig(settings[F("mqtt")]); changed = mqttGetConfig(settings[F("mqtt")]);
if(changed) { if(changed) {
@ -206,7 +216,7 @@ void configWriteConfig()
writefile = true; writefile = true;
} }
#endif #endif
#if HASP_USE_TELNET #if HASP_USE_TELNET>0
if(settings[F("telnet")].as<JsonObject>().isNull()) settings.createNestedObject(F("telnet")); if(settings[F("telnet")].as<JsonObject>().isNull()) settings.createNestedObject(F("telnet"));
changed = telnetGetConfig(settings[F("telnet")]); changed = telnetGetConfig(settings[F("telnet")]);
if(changed) { if(changed) {
@ -215,7 +225,7 @@ void configWriteConfig()
writefile = true; writefile = true;
} }
#endif #endif
#if HASP_USE_MDNS #if HASP_USE_MDNS>0
if(settings[F("mdns")].as<JsonObject>().isNull()) settings.createNestedObject(F("mdns")); if(settings[F("mdns")].as<JsonObject>().isNull()) settings.createNestedObject(F("mdns"));
changed = mdnsGetConfig(settings[F("mdns")]); changed = mdnsGetConfig(settings[F("mdns")]);
if(changed) { if(changed) {
@ -223,7 +233,7 @@ void configWriteConfig()
writefile = true; writefile = true;
} }
#endif #endif
#if HASP_USE_HTTP #if HASP_USE_HTTP>0
if(settings[F("http")].as<JsonObject>().isNull()) settings.createNestedObject(F("http")); if(settings[F("http")].as<JsonObject>().isNull()) settings.createNestedObject(F("http"));
changed = httpGetConfig(settings[F("http")]); changed = httpGetConfig(settings[F("http")]);
if(changed) { if(changed) {
@ -231,7 +241,6 @@ void configWriteConfig()
configOutput(settings[F("http")]); configOutput(settings[F("http")]);
writefile = true; writefile = true;
} }
#endif
#endif #endif
if(settings[F("debug")].as<JsonObject>().isNull()) settings.createNestedObject(F("debug")); if(settings[F("debug")].as<JsonObject>().isNull()) settings.createNestedObject(F("debug"));
@ -258,6 +267,7 @@ void configWriteConfig()
// changed |= otaGetConfig(settings[F("ota")].as<JsonObject>()); // changed |= otaGetConfig(settings[F("ota")].as<JsonObject>());
if(writefile) { if(writefile) {
#if HASP_USE_SPIFFS > 0
File file = SPIFFS.open(configFile, "w"); File file = SPIFFS.open(configFile, "w");
if(file) { if(file) {
Log.notice(F("CONF: Writing %s"), configFile.c_str()); Log.notice(F("CONF: Writing %s"), configFile.c_str());
@ -265,36 +275,71 @@ void configWriteConfig()
file.close(); file.close();
if(size > 0) { if(size > 0) {
Log.verbose(F("CONF: [SUCCESS] Saved %s"), configFile.c_str()); Log.verbose(F("CONF: [SUCCESS] Saved %s"), configFile.c_str());
configBackupToEeprom(); // configBackupToEeprom();
return; } else {
Log.error(F("CONF: Failed to write %s"), configFile.c_str());
} }
} else {
Log.error(F("CONF: Failed to write %s"), configFile.c_str());
} }
#endif
Log.error(F("CONF: Failed to write %s"), configFile.c_str()); // Method 1
// Log.verbose(F("CONF: Writing to EEPROM"));
// EepromStream eepromStream(0, 1024);
// WriteBufferingStream bufferedWifiClient{eepromStream, 512};
// serializeJson(doc, bufferedWifiClient);
// bufferedWifiClient.flush(); // <- OPTIONAL
// eepromStream.flush(); // (for ESP)
#if defined(STM32F4xx)
// Method 2
Log.verbose(F("CONF: Writing to EEPROM"));
char buffer[1024 + 128];
size_t size = serializeJson(doc, buffer, sizeof(buffer));
if(size > 0) {
uint16_t i;
for(i = 0; i < size; i++) eeprom_buffered_write_byte(i, buffer[i]);
eeprom_buffered_write_byte(i, 0);
eeprom_buffer_flush();
Log.verbose(F("CONF: [SUCCESS] Saved EEPROM"));
} else {
Log.error(F("CONF: Failed to save config to EEPROM"));
}
#endif
} else { } else {
Log.notice(F("CONF: Configuration was not changed")); Log.notice(F("CONF: Configuration did not change"));
} }
#endif configOutput(settings);
} }
void configSetup() void configSetup()
{ {
#if HASP_USE_SPIFFS>0 DynamicJsonDocument settings(1024 + 128);
if(!SPIFFS.begin()) {
#endif
#if HASP_USE_SPIFFS>0
} else {
#endif
DynamicJsonDocument settings(1024 + 128);
Serial.print(__FILE__);
Serial.println(__LINE__);
configGetConfig(settings, true); for(uint8_t i = 0; i < 2; i++) {
Serial.print(__FILE__);
Serial.println(__LINE__);
Log.error(F("FILE: SPI flash init failed. Unable to mount FS: Using default settings...")); if(i == 0) {
#if HASP_USE_SPIFFS>0 #if HASP_USE_SPIFFS > 0
EepromStream eepromStream(0, 2048);
DeserializationError error = deserializeJson(settings, eepromStream);
#else
continue;
#endif
} else {
#if HASP_USE_SPIFFS > 0
if(!SPIFFS.begin()) {
Log.error(F("FILE: SPI flash init failed. Unable to mount FS: Using default settings..."));
return;
}
#endif
configGetConfig(settings, true);
}
//#if HASP_USE_SPIFFS > 0
Log.verbose(F("Loading debug settings")); Log.verbose(F("Loading debug settings"));
debugSetConfig(settings[F("debug")]); debugSetConfig(settings[F("debug")]);
Log.verbose(F("Loading GUI settings")); Log.verbose(F("Loading GUI settings"));
@ -303,29 +348,30 @@ void configSetup()
haspSetConfig(settings[F("hasp")]); haspSetConfig(settings[F("hasp")]);
// otaGetConfig(settings[F("ota")]); // otaGetConfig(settings[F("ota")]);
#if HASP_USE_WIFI #if HASP_USE_WIFI>0
Log.verbose(F("Loading WiFi settings")); Log.verbose(F("Loading WiFi settings"));
wifiSetConfig(settings[F("wifi")]); wifiSetConfig(settings[F("wifi")]);
#if HASP_USE_MQTT #endif
#if HASP_USE_MQTT>0
Log.verbose(F("Loading MQTT settings")); Log.verbose(F("Loading MQTT settings"));
mqttSetConfig(settings[F("mqtt")]); mqttSetConfig(settings[F("mqtt")]);
#endif #endif
#if HASP_USE_TELNET #if HASP_USE_TELNET>0
Log.verbose(F("Loading Telnet settings")); Log.verbose(F("Loading Telnet settings"));
telnetSetConfig(settings[F("telnet")]); telnetSetConfig(settings[F("telnet")]);
#endif #endif
#if HASP_USE_MDNS #if HASP_USE_MDNS>0
Log.verbose(F("Loading MDNS settings")); Log.verbose(F("Loading MDNS settings"));
mdnsSetConfig(settings[F("mdns")]); mdnsSetConfig(settings[F("mdns")]);
#endif #endif
#if HASP_USE_HTTP #if HASP_USE_HTTP>0
Log.verbose(F("Loading HTTP settings")); Log.verbose(F("Loading HTTP settings"));
httpSetConfig(settings[F("http")]); httpSetConfig(settings[F("http")]);
#endif #endif
#endif // }
Log.notice(F("User configuration loaded"));
} }
Log.notice(F("User configuration loaded")); //#endif
#endif
} }
void configOutput(const JsonObject & settings) void configOutput(const JsonObject & settings)

View File

@ -15,7 +15,7 @@
#endif #endif
#include "hasp_hal.h" #include "hasp_hal.h"
#if HASP_USE_MQTT>0 #if HASP_USE_MQTT > 0
#include "hasp_mqtt.h" #include "hasp_mqtt.h"
#endif #endif
@ -31,11 +31,11 @@
#define SERIAL_SPEED 115200 #define SERIAL_SPEED 115200
#endif #endif
#if HASP_USE_TELNET != 0 #if HASP_USE_TELNET > 0
#include "hasp_telnet.h" #include "hasp_telnet.h"
#endif #endif
#if HASP_USE_SYSLOG != 0 #if HASP_USE_SYSLOG > 0
#include "Syslog.h" #include "Syslog.h"
#ifndef SYSLOG_SERVER #ifndef SYSLOG_SERVER
@ -71,9 +71,11 @@ Syslog * syslog;
#endif // USE_SYSLOG #endif // USE_SYSLOG
// Serial Settings // Serial Settings
uint8_t serialInputIndex = 0; // Empty buffer
char serialInputBuffer[1024];
uint16_t debugSerialBaud = SERIAL_SPEED / 10; // Multiplied by 10 uint16_t debugSerialBaud = SERIAL_SPEED / 10; // Multiplied by 10
bool debugSerialStarted = false; bool debugSerialStarted = false;
bool debugAnsiCodes = true; bool debugAnsiCodes = true;
//#define TERM_COLOR_Black "\u001b[30m" //#define TERM_COLOR_Black "\u001b[30m"
#define TERM_COLOR_GRAY "\e[37m" #define TERM_COLOR_GRAY "\e[37m"
@ -94,11 +96,12 @@ String debugHaspHeader()
{ {
String header((char *)0); String header((char *)0);
header.reserve(256); header.reserve(256);
header = F(" _____ _____ _____ _____\r\n" if(debugAnsiCodes) header += TERM_COLOR_YELLOW;
" | | | _ | __| _ |\r\n" header += F(" _____ _____ _____ _____\r\n"
" | | |__ | __|\r\n" " | | | _ | __| _ |\r\n"
" |__|__|__|__|_____|__|\r\n" " | | |__ | __|\r\n"
" Home Automation Switch Plate\r\n"); " |__|__|__|__|_____|__|\r\n"
" Home Automation Switch Plate\r\n");
char buffer[128]; char buffer[128];
snprintf(buffer, sizeof(buffer), PSTR(" Open Hardware edition v%u.%u.%u\r\n"), HASP_VERSION_MAJOR, snprintf(buffer, sizeof(buffer), PSTR(" Open Hardware edition v%u.%u.%u\r\n"), HASP_VERSION_MAJOR,
HASP_VERSION_MINOR, HASP_VERSION_REVISION); HASP_VERSION_MINOR, HASP_VERSION_REVISION);
@ -119,7 +122,7 @@ void debugStart()
// log/logf method) // log/logf method)
} }
#if HASP_USE_SYSLOG != 0 #if HASP_USE_SYSLOG > 0
void syslogSend(uint8_t priority, const char * debugText) void syslogSend(uint8_t priority, const char * debugText)
{ {
if(strlen(debugSyslogHost) != 0 && WiFi.isConnected()) { if(strlen(debugSyslogHost) != 0 && WiFi.isConnected()) {
@ -130,7 +133,7 @@ void syslogSend(uint8_t priority, const char * debugText)
void debugSetup() void debugSetup()
{ {
#if HASP_USE_SYSLOG != 0 #if HASP_USE_SYSLOG > 0
syslog = new Syslog(syslogClient, debugSyslogProtocol == 0 ? SYSLOG_PROTO_IETF : SYSLOG_PROTO_BSD); syslog = new Syslog(syslogClient, debugSyslogProtocol == 0 ? SYSLOG_PROTO_IETF : SYSLOG_PROTO_BSD);
syslog->server(debugSyslogHost, debugSyslogPort); syslog->server(debugSyslogHost, debugSyslogPort);
syslog->deviceHostname(mqttNodeName); syslog->deviceHostname(mqttNodeName);
@ -155,7 +158,7 @@ bool debugGetConfig(const JsonObject & settings)
if(debugTelePeriod != settings[FPSTR(F_DEBUG_TELEPERIOD)].as<uint16_t>()) changed = true; if(debugTelePeriod != settings[FPSTR(F_DEBUG_TELEPERIOD)].as<uint16_t>()) changed = true;
settings[FPSTR(F_DEBUG_TELEPERIOD)] = debugTelePeriod; settings[FPSTR(F_DEBUG_TELEPERIOD)] = debugTelePeriod;
#if HASP_USE_SYSLOG != 0 #if HASP_USE_SYSLOG > 0
if(strcmp(debugSyslogHost, settings[FPSTR(F_CONFIG_HOST)].as<String>().c_str()) != 0) changed = true; if(strcmp(debugSyslogHost, settings[FPSTR(F_CONFIG_HOST)].as<String>().c_str()) != 0) changed = true;
settings[FPSTR(F_CONFIG_HOST)] = debugSyslogHost; settings[FPSTR(F_CONFIG_HOST)] = debugSyslogHost;
@ -193,7 +196,7 @@ bool debugSetConfig(const JsonObject & settings)
changed |= configSet(debugTelePeriod, settings[FPSTR(F_DEBUG_TELEPERIOD)], PSTR("debugTelePeriod")); changed |= configSet(debugTelePeriod, settings[FPSTR(F_DEBUG_TELEPERIOD)], PSTR("debugTelePeriod"));
/* Syslog Settings*/ /* Syslog Settings*/
#if HASP_USE_SYSLOG != 0 #if HASP_USE_SYSLOG > 0
if(!settings[FPSTR(F_CONFIG_HOST)].isNull()) { if(!settings[FPSTR(F_CONFIG_HOST)].isNull()) {
changed |= strcmp(debugSyslogHost, settings[FPSTR(F_CONFIG_HOST)]) != 0; changed |= strcmp(debugSyslogHost, settings[FPSTR(F_CONFIG_HOST)]) != 0;
strncpy(debugSyslogHost, settings[FPSTR(F_CONFIG_HOST)], sizeof(debugSyslogHost)); strncpy(debugSyslogHost, settings[FPSTR(F_CONFIG_HOST)], sizeof(debugSyslogHost));
@ -216,21 +219,23 @@ static void debugPrintTimestamp(int level, Print * _logOutput)
time_t rawtime; time_t rawtime;
struct tm * timeinfo; struct tm * timeinfo;
//time(&rawtime); // time(&rawtime);
//timeinfo = localtime(&rawtime); // timeinfo = localtime(&rawtime);
// strftime(buffer, sizeof(buffer), "%b %d %H:%M:%S.", timeinfo); // strftime(buffer, sizeof(buffer), "%b %d %H:%M:%S.", timeinfo);
// Serial.println(buffer); // Serial.println(buffer);
debugSendAnsiCode(F(TERM_COLOR_CYAN), _logOutput); debugSendAnsiCode(F(TERM_COLOR_CYAN), _logOutput);
/* if(timeinfo->tm_year >= 120) { /* if(timeinfo->tm_year >= 120) {
char buffer[64]; char buffer[64];
strftime(buffer, sizeof(buffer), "[%b %d %H:%M:%S.", timeinfo); // Literal String strftime(buffer, sizeof(buffer), "[%b %d %H:%M:%S.", timeinfo); // Literal String
_logOutput->print(buffer); _logOutput->print(buffer);
_logOutput->printf(PSTR("%03lu]"), millis() % 1000); _logOutput->printf(PSTR("%03lu]"), millis() % 1000);
} else */ { } else */
_logOutput->printf(PSTR("[%20.3f]"), (float)millis() / 1000); {
uint32_t msecs = millis();
_logOutput->printf(PSTR("[%16d.%03d]"), msecs / 1000, msecs % 1000);
} }
} }
@ -328,15 +333,17 @@ void debugPreSetup(JsonObject settings)
uint32_t baudrate = settings[FPSTR(F_CONFIG_BAUD)].as<uint32_t>() * 10; uint32_t baudrate = settings[FPSTR(F_CONFIG_BAUD)].as<uint32_t>() * 10;
if(baudrate == 0) baudrate = SERIAL_SPEED; if(baudrate == 0) baudrate = SERIAL_SPEED;
if(baudrate >= 9600u) { /* the baudrates are stored divided by 10 */ if(baudrate >= 9600u) { /* the baudrates are stored divided by 10 */
#ifdef STM32_CORE_VERSION_MAJOR #if defined(STM32F4xx)
Serial.setRx(PA3); // User Serial2 #ifndef STM32_SERIAL1 // Define what Serial port to use for log output
Serial.setTx(PA2); Serial.setRx(PA3); // User Serial2
Serial.setTx(PA2);
#endif
#endif #endif
Serial.begin(baudrate); /* prepare for possible serial debug */ Serial.begin(baudrate); /* prepare for possible serial debug */
delay(10); delay(10);
Log.registerOutput(0, &Serial, LOG_LEVEL_VERBOSE, true); Log.registerOutput(0, &Serial, LOG_LEVEL_VERBOSE, true);
debugSerialStarted = true; debugSerialStarted = true;
Serial.println(); Serial.println();
Log.trace(("Serial started at %u baud"), baudrate); Log.trace(("Serial started at %u baud"), baudrate);
@ -373,7 +380,26 @@ void debugLvgl(lv_log_level_t level, const char * file, uint32_t line, const cha
#endif #endif
void debugLoop() void debugLoop()
{} {
while(Serial.available()) {
char ch = Serial.read();
Serial.print(ch);
if(ch == 13 || ch == 10) {
serialInputBuffer[serialInputIndex] = 0;
if(serialInputIndex > 0) dispatchCommand(serialInputBuffer);
serialInputIndex = 0;
} else {
if(serialInputIndex < sizeof(serialInputBuffer) - 1) {
serialInputBuffer[serialInputIndex++] = ch;
}
serialInputBuffer[serialInputIndex] = 0;
if(strcmp(serialInputBuffer, "jsonl=") == 0) {
dispatchJsonl(Serial);
serialInputIndex = 0;
}
}
}
}
/*void printLocalTime() /*void printLocalTime()
{ {

View File

@ -38,7 +38,7 @@ void dispatchLoop()
void dispatchStatusUpdate() void dispatchStatusUpdate()
{ {
#if HASP_USE_MQTT #if HASP_USE_MQTT>0
mqtt_send_statusupdate(); mqtt_send_statusupdate();
#endif #endif
} }
@ -48,11 +48,15 @@ void dispatchOutput(int output, bool state)
int pin = 0; int pin = 0;
if(pin >= 0) { if(pin >= 0) {
Log.notice(F("PIN OUTPUT STATE %d"),state);
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
ledcWrite(99, state ? 1023 : 0); // ledChannel and value ledcWrite(99, state ? 1023 : 0); // ledChannel and value
#elif defined(STM32F4xx)
digitalWrite(HASP_OUTPUT_PIN, state);
#else #else
analogWrite(pin, state ? 1023 : 0); digitalWrite(D1, state);
// analogWrite(pin, state ? 1023 : 0);
#endif #endif
} }
} }
@ -95,11 +99,6 @@ void dispatchAttribute(String strTopic, const char * payload)
{ {
if(strTopic.startsWith("p[")) { if(strTopic.startsWith("p[")) {
dispatchButtonAttribute(strTopic, payload); dispatchButtonAttribute(strTopic, payload);
} else if(strTopic.startsWith(F("output"))) {
#if defined(ARDUINO_ARCH_ESP8266)
uint8_t state = isON(payload) ? HIGH : LOW;
digitalWrite(D1, state);
#endif
} else if(strTopic == F("page")) { } else if(strTopic == F("page")) {
dispatchPage(payload); dispatchPage(payload);
@ -138,9 +137,12 @@ void dispatchPage(String strPageid)
String strPage((char *)0); String strPage((char *)0);
strPage.reserve(128); strPage.reserve(128);
strPage = haspGetPage(); strPage = haspGetPage();
#if HASP_USE_MQTT #if HASP_USE_MQTT > 0
mqtt_send_state(F("page"), strPage.c_str()); mqtt_send_state(F("page"), strPage.c_str());
#endif #endif
#if HASP_USE_TASMOTA_SLAVE > 0
slave_send_state(F("page"), strPage.c_str());
#endif
} }
void dispatchClearPage(String strPageid) void dispatchClearPage(String strPageid)
@ -159,12 +161,16 @@ void dispatchDim(String strDimLevel)
// Set the current state // Set the current state
if(strDimLevel.length() != 0) guiSetDim(strDimLevel.toInt()); if(strDimLevel.length() != 0) guiSetDim(strDimLevel.toInt());
dispatchPrintln(F("DIM"), strDimLevel); dispatchPrintln(F("DIM"), strDimLevel);
#if HASP_USE_MQTT
char buffer[8]; char buffer[8];
#if defined(HASP_USE_MQTT) || defined(HASP_USE_TASMOTA_SLAVE)
itoa(guiGetDim(), buffer, DEC); itoa(guiGetDim(), buffer, DEC);
#if HASP_USE_MQTT > 0
mqtt_send_state(F("dim"), buffer); mqtt_send_state(F("dim"), buffer);
#endif #endif
#if HASP_USE_TASMOTA_SLAVE > 0
slave_send_state(F("dim"), buffer);
#endif
#endif
} }
void dispatchBacklight(String strPayload) void dispatchBacklight(String strPayload)
@ -177,14 +183,18 @@ void dispatchBacklight(String strPayload)
// Return the current state // Return the current state
strPayload = getOnOff(guiGetBacklight()); strPayload = getOnOff(guiGetBacklight());
#if HASP_USE_MQTT #if HASP_USE_MQTT > 0
mqtt_send_state(F("light"), strPayload.c_str()); mqtt_send_state(F("light"), strPayload.c_str());
#endif #endif
#if HASP_USE_TASMOTA_SLAVE > 0
slave_send_state(F("light"), strPayload.c_str());
#endif
} }
void dispatchCommand(String cmnd) void dispatchCommand(String cmnd)
{ {
// dispatchPrintln(F("CMND"), cmnd); dispatchPrintln(F("CMND"), cmnd);
if(cmnd.startsWith(F("page "))) { if(cmnd.startsWith(F("page "))) {
cmnd = cmnd.substring(5, cmnd.length()); cmnd = cmnd.substring(5, cmnd.length());
@ -266,34 +276,46 @@ void dispatchJsonl(char * payload)
void dispatchIdle(const char * state) void dispatchIdle(const char * state)
{ {
#if HASP_USE_MQTT>0 #if !defined(HASP_USE_MQTT) && !defined(HASP_USE_TASMOTA_SLAVE)
mqtt_send_state(F("idle"), state);
#else
Log.notice(F("OUT: idle = %s"), state); Log.notice(F("OUT: idle = %s"), state);
#else
#if HASP_USE_MQTT > 0
mqtt_send_state(F("idle"), state);
#endif
#if HASP_USE_TASMOTA_SLAVE > 0
slave_send_state(F("idle"), state);
#endif
#endif #endif
} }
void dispatchReboot(bool saveConfig) void dispatchReboot(bool saveConfig)
{ {
if(saveConfig) configWriteConfig(); if(saveConfig) configWriteConfig();
#if HASP_USE_MQTT>0 #if HASP_USE_MQTT > 0
mqttStop(); // Stop the MQTT Client first mqttStop(); // Stop the MQTT Client first
#endif #endif
debugStop(); debugStop();
#if HASP_USE_WIFI>0 #if HASP_USE_WIFI > 0
wifiStop(); wifiStop();
#endif #endif
Log.verbose(F("-------------------------------------")); Log.verbose(F("-------------------------------------"));
Log.notice(F("STOP: Properly Rebooting the MCU now!")); Log.notice(F("STOP: Properly Rebooting the MCU now!"));
Serial.flush(); Serial.flush();
//halRestart(); halRestart();
} }
void dispatch_button(uint8_t id, const char * event) void dispatch_button(uint8_t id, const char * event)
{ {
#if !defined(HASP_USE_MQTT) && !defined(HASP_USE_TASMOTA_SLAVE)
Log.notice(F("OUT: input%d = %s"), id, event);
#else
#if HASP_USE_MQTT > 0 #if HASP_USE_MQTT > 0
mqtt_send_input(id, event); mqtt_send_input(id, event);
#endif #endif
#if HASP_USE_TASMOTA_SLAVE>0
slave_send_input(id, event);
#endif
#endif
} }
void dispatchWebUpdate(const char * espOtaUrl) void dispatchWebUpdate(const char * espOtaUrl)
@ -306,10 +328,15 @@ void dispatchWebUpdate(const char * espOtaUrl)
void IRAM_ATTR dispatch_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute, const char * data) void IRAM_ATTR dispatch_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute, const char * data)
{ {
#if !defined(HASP_USE_MQTT) && !defined(HASP_USE_TASMOTA_SLAVE)
Log.notice(F("OUT: json = {\"p[%u].b[%u].%s\":\"%s\"}"), pageid, btnid, attribute, data);
#else
#if HASP_USE_MQTT > 0 #if HASP_USE_MQTT > 0
mqtt_send_obj_attribute_str(pageid, btnid, attribute, data); mqtt_send_obj_attribute_str(pageid, btnid, attribute, data);
#else #endif
Log.notice(F("OUT: json = {\"p[%u].b[%u].%s\":\"%s\"}"), pageid, btnid, attribute, data); #if HASP_USE_TASMOTA_SLAVE > 0
slave_send_obj_attribute_str(pageid, btnid, attribute, data);
#endif
#endif #endif
} }
@ -356,14 +383,14 @@ void dispatchConfig(const char * topic, const char * payload)
haspGetConfig(settings); haspGetConfig(settings);
} }
#if HASP_USE_WIFI #if HASP_USE_WIFI > 0
else if(strcmp_P(topic, PSTR("wifi")) == 0) { else if(strcmp_P(topic, PSTR("wifi")) == 0) {
if(update) if(update)
wifiSetConfig(settings); wifiSetConfig(settings);
else else
wifiGetConfig(settings); wifiGetConfig(settings);
} }
#if HASP_USE_MQTT #if HASP_USE_MQTT > 0
else if(strcmp_P(topic, PSTR("mqtt")) == 0) { else if(strcmp_P(topic, PSTR("mqtt")) == 0) {
if(update) if(update)
mqttSetConfig(settings); mqttSetConfig(settings);
@ -371,11 +398,11 @@ void dispatchConfig(const char * topic, const char * payload)
mqttGetConfig(settings); mqttGetConfig(settings);
} }
#endif #endif
#if HASP_USE_TELNET #if HASP_USE_TELNET > 0
// else if(strcmp_P(topic, PSTR("telnet")) == 0) // else if(strcmp_P(topic, PSTR("telnet")) == 0)
// telnetGetConfig(settings[F("telnet")]); // telnetGetConfig(settings[F("telnet")]);
#endif #endif
#if HASP_USE_MDNS #if HASP_USE_MDNS > 0
else if(strcmp_P(topic, PSTR("mdns")) == 0) { else if(strcmp_P(topic, PSTR("mdns")) == 0) {
if(update) if(update)
mdnsSetConfig(settings); mdnsSetConfig(settings);
@ -383,7 +410,7 @@ void dispatchConfig(const char * topic, const char * payload)
mdnsGetConfig(settings); mdnsGetConfig(settings);
} }
#endif #endif
#if HASP_USE_HTTP #if HASP_USE_HTTP > 0
else if(strcmp_P(topic, PSTR("http")) == 0) { else if(strcmp_P(topic, PSTR("http")) == 0) {
if(update) if(update)
httpSetConfig(settings); httpSetConfig(settings);
@ -397,10 +424,15 @@ void dispatchConfig(const char * topic, const char * payload)
if(!update) { if(!update) {
settings.remove(F("pass")); // hide password in output settings.remove(F("pass")); // hide password in output
size_t size = serializeJson(doc, buffer, sizeof(buffer)); size_t size = serializeJson(doc, buffer, sizeof(buffer));
#if HASP_USE_MQTT #if !defined(HASP_USE_MQTT) && !defined(HASP_USE_TASMOTA_SLAVE)
mqtt_send_state(F("config"), buffer);
#else
Log.notice(F("OUT: config %s = %s"),topic,buffer); Log.notice(F("OUT: config %s = %s"),topic,buffer);
#else
#if HASP_USE_MQTT > 0
mqtt_send_state(F("config"), buffer);
#endif
#if HASP_USE_TASMOTA > 0
slave_send_state(F("config"), buffer);
#endif
#endif #endif
} }
} }

View File

@ -1,49 +1,23 @@
#include <Arduino.h> #include <Arduino.h>
#include "EEPROM.h" #include "EEPROM.h"
#include "hasp_debug.h"
void eepromWrite(char addr, std::string & data);
std::string eepromRead(char addr);
void eepromSetup() void eepromSetup()
{ {
#if defined(STM32Fxx)
eeprom_buffer_fill();
char buffer[] = "{\"objid\":10,\"id\":1,\"page\":0,\"x\":10,\"y\":45,\"w\":220,\"h\":55,\"toggle\":\"TRUE\",\"txt\":\"Toggle Me\"}";
uint size = strlen(buffer);
uint16_t i;
for(i = 0; i < size; i++) eeprom_buffered_write_byte(i+4096, buffer[i]);
eeprom_buffered_write_byte(i+4096, 0);
// eeprom_buffer_flush();
#endif
// ESP8266 // Don't start at boot, only at write
// EEPROM.begin(1024); // EEPROM.begin(1024);
// debugPrintln("EEPROM: Started Eeprom"); // debugPrintln("EEPROM: Started Eeprom");
} }
void eepromLoop() void eepromLoop()
{} {}
void eepromUpdate(uint16_t addr, char ch)
{
if(EEPROM.read(addr) != ch) {
EEPROM.write(addr, ch);
}
}
void eepromWrite(uint16_t addr, std::string & data)
{
int count = data.length();
for(int i = 0; i < count; i++) {
eepromUpdate(addr + i, data[i]);
}
eepromUpdate(addr + count, '\0');
// EEPROM.commit();
}
std::string eepromRead(uint16_t addr)
{
char data[1024]; // Max 1024 Bytes
int len = 0;
unsigned char k;
k = EEPROM.read(addr);
while(k != '\0' && len < 1023) // Read until null character
{
k = EEPROM.read(addr + len);
if((uint8_t(k) < 32) || (uint8_t(k) > 127)) break; // check for printable ascii, includes '\0'
data[len] = k;
len++;
}
return std::string(data);
}

96
src/hasp_ethernet.cpp Normal file
View File

@ -0,0 +1,96 @@
#include <Arduino.h>
#include "ArduinoJson.h"
#include "ArduinoLog.h"
#include "hasp_conf.h"
#include "hasp_hal.h"
#if HASP_USE_ETHERNET > 0
EthernetClient EthClient;
IPAddress ip;
void ethernetSetup()
{
#if USE_BUILTIN_ETHERNET > 0
// start Ethernet and UDP
Log.notice(F("ETH: Begin Ethernet LAN8720"));
if(Ethernet.begin() == 0) {
Log.notice(F("ETH: Failed to configure Ethernet using DHCP"));
} else {
ip = Ethernet.localIP();
Log.notice(F("ETH: DHCP Success got IP %d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
}
Log.notice(F("ETH: MAC Address %s"), halGetMacAddress(0, ":"));
#else
byte mac[6];
uint32_t baseUID = (uint32_t)UID_BASE;
mac[0] = 0x00;
mac[1] = 0x80;
mac[2] = 0xE1;
mac[3] = (baseUID & 0x00FF0000) >> 16;
mac[4] = (baseUID & 0x0000FF00) >> 8;
mac[5] = (baseUID & 0x000000FF);
char ethHostname[12];
memset(ethHostname, 0 ,sizeof(ethHostname));
snprintf(ethHostname, sizeof(ethHostname), PSTR("HASP-%02x%02x%02x"), mac[3], mac[4], mac[5]);
Ethernet.setCsPin(W5500_CS);
Ethernet.setRstPin(W5500_RST);
Ethernet.setHostname(ethHostname);
Log.notice(F("ETH: Begin Ethernet W5500"));
if(Ethernet.begin(mac) == 0) {
Log.notice(F("ETH: Failed to configure Ethernet using DHCP"));
} else {
ip = Ethernet.localIP();
Log.notice(F("ETH: DHCP Success got IP %d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
}
#endif
}
void ethernetLoop(void)
{
switch(Ethernet.maintain()) {
case 1:
// renewed fail
Log.notice(F("ETH: Error: renewed fail"));
break;
case 2:
// renewed success
ip = Ethernet.localIP();
Log.notice(F("ETH: DHCP Renew Success got IP=%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
break;
case 3:
// rebind fail
Log.notice(F("Error: rebind fail"));
break;
case 4:
// rebind success
ip = Ethernet.localIP();
Log.notice(F("ETH: DHCP Rebind Success got IP=%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
break;
default:
// nothing happened
break;
}
}
bool ethernetEvery5Seconds()
{
bool state;
#if USE_BUILTIN_ETHERNET > 0
state = Ethernet.linkStatus() == LinkON;
#else
state = Ethernet.link() == 1;
#endif
Log.warning(F("ETH: %s"), state ? F("ONLINE") : F("OFFLINE"));
return state;
}
#endif

8
src/hasp_ethernet.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef HASP_ETHERNET_H
#define HASP_ETHERNET_H
void ethernetSetup();
void ethernetLoop(void);
bool ethernetEvery5Seconds();
#endif

View File

@ -1,10 +1,254 @@
#include <Arduino.h> #include "Arduino.h"
#include "ArduinoJson.h" #include "ArduinoLog.h"
#include "AceButton.h"
#include "lv_conf.h" // For timing defines
#include "hasp_conf.h"
#include "hasp_gpio.h"
#include "hasp_dispatch.h"
#define HASP_NUM_GPIO_CONFIG 5
uint8_t gpioUsedInputCount = 0;
uint16_t gpioConfig[HASP_NUM_GPIO_CONFIG];
using namespace ace_button;
static AceButton * button[HASP_NUM_INPUTS];
struct hasp_gpio_config_t {
const uint8_t pin;
const uint8_t group;
const uint8_t io_mode;
bool default_state;
};
// An array of button pins, led pins, and the led states. Cannot be const
// because ledState is mutable.
hasp_gpio_config_t gpioConfig2[HASP_NUM_GPIO_CONFIG] = {
{2, 8, INPUT, LOW},
{3, 9, OUTPUT, LOW},
{4, 10, INPUT, HIGH},
{5, 11, OUTPUT, LOW},
{6, 12, INPUT, LOW},
};
#if defined(ARDUINO_ARCH_ESP32)
class TouchConfig : public ButtonConfig {
public:
TouchConfig();
protected:
// Number of iterations to sample the capacitive switch. Higher number
// provides better smoothing but increases the time taken for a single read.
static const uint8_t kSamples = 10;
// The threshold value which is considered to be a "touch" on the switch.
static const long kTouchThreshold = 70;
int readButton(uint8_t pin) override
{
// long total = mSensor.capacitiveSensor(kSamples);
return (touchRead(pin) > kTouchThreshold) ? LOW : HIGH;
}
};
TouchConfig touchConfig();
#endif
static void gpio_event_cb(AceButton * button, uint8_t eventType, uint8_t buttonState)
{
char buffer[16];
switch(eventType) {
case 0: // AceButton::kEventPressed:
memcpy_P(buffer, PSTR("DOWN"), sizeof(buffer));
break;
case 2: // AceButton::kEventClicked:
memcpy_P(buffer, PSTR("SHORT"), sizeof(buffer));
break;
case AceButton::kEventDoubleClicked:
memcpy_P(buffer, PSTR("DOUBLE"), sizeof(buffer));
break;
case 4: // AceButton::kEventLongPressed:
memcpy_P(buffer, PSTR("LONG"), sizeof(buffer));
break;
case 5: // AceButton::kEventRepeatPressed:
// return; // Fix needed for switches
memcpy_P(buffer, PSTR("HOLD"), sizeof(buffer));
break;
case 1: // AceButton::kEventReleased:
memcpy_P(buffer, PSTR("UP"), sizeof(buffer));
break;
default:
memcpy_P(buffer, PSTR("UNKNOWN"), sizeof(buffer));
}
dispatch_button(button->getId(), buffer);
}
void aceButtonSetup(void)
{
ButtonConfig * buttonConfig = ButtonConfig::getSystemButtonConfig();
buttonConfig->setEventHandler(gpio_event_cb);
// Features
buttonConfig->setFeature(ButtonConfig::kFeatureClick);
buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
buttonConfig->setFeature(ButtonConfig::kFeatureRepeatPress);
// buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick);
// buttonConfig->setFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick);
// Delays
buttonConfig->setClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
buttonConfig->setDoubleClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
buttonConfig->setLongPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
buttonConfig->setRepeatPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME);
buttonConfig->setRepeatPressInterval(LV_INDEV_DEF_LONG_PRESS_REP_TIME);
}
void IRAM_ATTR gpioLoop(void)
{
// Should be called every 4-5ms or faster, for the default debouncing time of ~20ms.
for(uint8_t i = 0; i < gpioUsedInputCount; i++) {
if(button[i]) button[i]->check();
}
}
void gpioAddButton( uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t channel)
{
uint8_t i;
for(i = 0; i < HASP_NUM_INPUTS; i++) {
if(!button[i]) {
button[i] = new AceButton(pin, default_state, channel);
// button[i]->init(pin, default_state, channel);
if(button[i]) {
pinMode(pin, input_mode);
ButtonConfig * buttonConfig = button[i]->getButtonConfig();
buttonConfig->setEventHandler(gpio_event_cb);
buttonConfig->setFeature(ButtonConfig::kFeatureClick);
buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick);
buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress);
buttonConfig->clearFeature(
ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses
Log.verbose(F("GPIO: Button%d created on pin %d (channel %d) mode %d default %d"), i, pin, channel,
input_mode, default_state);
gpioUsedInputCount = i + 1;
return;
}
}
}
Log.error(F("GPIO: Failed to create Button%d pin %d (channel %d). All %d slots available are in use!"), i, pin,
channel, HASP_NUM_INPUTS);
}
void gpioAddTouchButton( uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t channel)
{
uint8_t i;
for(i = 0; i < HASP_NUM_INPUTS; i++) {
if(!button[i]) {
button[i] = new AceButton();
if(button[i]) {
pinMode(pin, input_mode);
ButtonConfig * buttonConfig = button[i]->getButtonConfig();
buttonConfig->setEventHandler(gpio_event_cb);
buttonConfig->setFeature(ButtonConfig::kFeatureClick);
buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick);
buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress);
buttonConfig->clearFeature(
ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses
Log.verbose(F("GPIO: Button%d created on pin %d (channel %d) mode %d default %d"), i, pin, channel,
input_mode, default_state);
gpioUsedInputCount = i + 1;
return;
}
}
}
Log.error(F("GPIO: Failed to create Button%d pin %d (channel %d). All %d slots available are in use!"), i, pin,
channel, HASP_NUM_INPUTS);
}
void gpioSetup() void gpioSetup()
{ {
aceButtonSetup();
// gpioConfig[0] = PD15 * 256 + 5 + (INPUT << 3);
#if defined(ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
gpioAddButton( D2, INPUT_PULLUP, HIGH, 1);
pinMode(D1, OUTPUT); pinMode(D1, OUTPUT);
pinMode(D2, INPUT_PULLUP);
#endif #endif
#if defined(ARDUINO_ARCH_ESP32)
gpioAddButton( D2, INPUT, HIGH, 1);
pinMode(D1, OUTPUT);
#endif
for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
uint8_t pin = (gpioConfig[i] >> 8) & 0xFF;
uint8_t channel = gpioConfig[i] & 0b111; // 3bit
uint8_t input_mode = (gpioConfig[i] >> 3) & 0b11; // 2bit gpio mode
//uint8_t input_mode = gpioConfig[i].io_mode
uint8_t gpiotype = (gpioConfig[i] >> 5) & 0b111; // 3bit
uint8_t default_state = gpioConfig[i] & 0b1; // 1bit: 0=LOW, 1=HIGH
switch(input_mode) {
case 1:
input_mode = OUTPUT;
break;
case 2:
input_mode = INPUT_PULLUP;
break;
#ifndef ARDUINO_ARCH_ESP8266
case 3:
input_mode = INPUT_PULLDOWN;
break;
#endif
default:
input_mode = INPUT;
}
switch(gpiotype) {
case HASP_GPIO_SWITCH:
case HASP_GPIO_BUTTON:
// gpioAddButton(gpioConfig[i].io_mode.pin, input_mode, gpioConfig[i].default_state, gpioConfig[i].group);
break;
case HASP_GPIO_RELAY:
pinMode(pin, OUTPUT);
break;
// case HASP_GPIO_LED:
case HASP_GPIO_PWM:
case HASP_GPIO_BACKLIGHT:
pinMode(pin, OUTPUT);
#if defined(ARDUINO_ARCH_ESP32)
// configure LED PWM functionalitites
ledcSetup(channel, 20000, 10);
// attach the channel to the GPIO to be controlled
ledcAttachPin(pin, channel);
#endif
break;
}
}
/*
#if defined(ARDUINO_ARCH_ESP8266)
pinMode(D1, OUTPUT);
pinMode(D2, INPUT_PULLUP);
#endif
#if defined(STM32F4xx)
pinMode(HASP_OUTPUT_PIN, OUTPUT);
pinMode(HASP_INPUT_PIN, INPUT);
#endif
*/
} }

View File

@ -1,3 +1,25 @@
#ifndef HASP_GPIO_H
#define HASP_GPIO_H
#include "ArduinoJson.h" #include "ArduinoJson.h"
void gpioSetup(); #ifdef __cplusplus
extern "C" {
#endif
void gpioSetup(void);
void IRAM_ATTR gpioLoop(void);
enum lv_hasp_gpio_type_t {
HASP_GPIO_SWITCH = 0,
HASP_GPIO_BUTTON = 1,
HASP_GPIO_RELAY = 2,
HASP_GPIO_PWM = 3,
HASP_GPIO_BACKLIGHT = 4,
};
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View File

@ -18,7 +18,7 @@
//#include "lv_ex_conf.h" //#include "lv_ex_conf.h"
//#include "tpcal.h" //#include "tpcal.h"
#if HASP_USE_PNGDECODE #if HASP_USE_PNGDECODE > 0
#include "png_decoder.h" #include "png_decoder.h"
#endif #endif
@ -26,7 +26,7 @@
#define TOUCH_DRIVER 0 #define TOUCH_DRIVER 0
#endif #endif
#if HASP_USE_SPIFFS #if HASP_USE_SPIFFS > 0
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h" #include "SPIFFS.h"
#endif #endif
@ -41,6 +41,11 @@ File pFileOut;
#endif #endif
uint8_t guiSnapshot = 0; uint8_t guiSnapshot = 0;
#if defined(STM32F4xx)
//#include <EthernetWebServer_STM32.h>
// EthernetWebServer * webClient(0);
#endif
#if defined(ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WebServer.h> #include <ESP8266WebServer.h>
ESP8266WebServer * webClient; // for snatshot ESP8266WebServer * webClient; // for snatshot
@ -75,10 +80,7 @@ static uint8_t guiRotation = TFT_ROTATION;
#if ESP32 > 0 || ESP8266 > 0 #if ESP32 > 0 || ESP8266 > 0
static Ticker tick; /* timer for interrupt handler */ static Ticker tick; /* timer for interrupt handler */
#else #else
static Ticker tick(lv_tick_handler,guiTickPeriod); static Ticker tick(lv_tick_handler, guiTickPeriod);
uint8_t serialInputIndex = 0; // Empty buffer
char serialInputBuffer[1024];
#endif #endif
static TFT_eSPI tft; // = TFT_eSPI(); /* TFT instance */ static TFT_eSPI tft; // = TFT_eSPI(); /* TFT instance */
static uint16_t calData[5] = {0, 65535, 0, 65535, 0}; static uint16_t calData[5] = {0, 65535, 0, 65535, 0};
@ -174,14 +176,15 @@ static bool guiCheckSleep()
/* Flush VDB bytes to a stream */ /* Flush VDB bytes to a stream */
static void gui_take_screenshot(uint8_t * data_p, size_t len) static void gui_take_screenshot(uint8_t * data_p, size_t len)
{ {
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
size_t res = 0; size_t res = 0;
switch(guiSnapshot) { switch(guiSnapshot) {
#if HASP_USE_SPIFFS > 0
case 1: case 1:
res = pFileOut.write(data_p, len); res = pFileOut.write(data_p, len);
break; break;
#endif
case 2: case 2:
res = webClient->client().write(data_p, len); res = httpClientWrite(data_p, len);
break; break;
default: default:
res = 0; // nothing to do res = 0; // nothing to do
@ -189,7 +192,6 @@ static void gui_take_screenshot(uint8_t * data_p, size_t len)
if(res != len) { if(res != len) {
Log.warning(F("GUI: Pixelbuffer not completely sent")); Log.warning(F("GUI: Pixelbuffer not completely sent"));
} }
#endif
} }
/* Experimetnal Display flushing */ /* Experimetnal Display flushing */
@ -200,7 +202,6 @@ static void IRAM_ATTR tft_espi_flush(lv_disp_drv_t * disp, const lv_area_t * are
/* Update TFT */ /* Update TFT */
tft.startWrite(); /* Start new TFT transaction */ tft.startWrite(); /* Start new TFT transaction */
tft.setWindow(area->x1, area->y1, area->x2, area->y2); /* set the working window */ tft.setWindow(area->x1, area->y1, area->x2, area->y2); /* set the working window */
tft.setSwapBytes(true); /* set endianess */
tft.pushPixels((uint16_t *)color_p, len); /* Write words at once */ tft.pushPixels((uint16_t *)color_p, len); /* Write words at once */
tft.endWrite(); /* terminate TFT transaction */ tft.endWrite(); /* terminate TFT transaction */
@ -306,14 +307,6 @@ static void IRAM_ATTR lv_tick_handler(void)
lv_tick_inc(guiTickPeriod); lv_tick_inc(guiTickPeriod);
} }
#ifdef STM32_CORE_VERSION
void Update_IT_callback(void)
{
Serial.print("?");
lv_tick_inc(guiTickPeriod);
}
#endif
/* Reading input device (simulated encoder here) */ /* Reading input device (simulated encoder here) */
/*bool read_encoder(lv_indev_drv_t * indev, lv_indev_data_t * data) /*bool read_encoder(lv_indev_drv_t * indev, lv_indev_data_t * data)
{ {
@ -628,6 +621,14 @@ void guiSetup()
{ {
/* TFT init */ /* TFT init */
tft.begin(); tft.begin();
tft.setSwapBytes(true); /* set endianess */
#ifdef USE_DMA_TO_TFT
// DMA - should work with STM32F2xx/F4xx/F7xx processors
// NOTE: >>>>>> DMA IS FOR SPI DISPLAYS ONLY <<<<<<
tft.initDMA(); // Initialise the DMA engine (tested with STM32F446 and STM32F767)
#endif
tft.setRotation(guiRotation); /* 1/3=Landscape or 0/2=Portrait orientation */ tft.setRotation(guiRotation); /* 1/3=Landscape or 0/2=Portrait orientation */
#if TOUCH_DRIVER == 0 #if TOUCH_DRIVER == 0
tft.setTouch(calData); tft.setTouch(calData);
@ -656,14 +657,14 @@ void guiSetup()
#else #else
static lv_disp_buf_t disp_buf; static lv_disp_buf_t disp_buf;
static lv_color_t guiVdbBuffer1[16 * 512u]; // 16 KBytes static lv_color_t guiVdbBuffer1[16 * 512u]; // 16 KBytes
static lv_color_t guiVdbBuffer2[16 * 512u]; // 16 KBytes // static lv_color_t guiVdbBuffer2[16 * 512u]; // 16 KBytes
guiVDBsize = sizeof(guiVdbBuffer1) / sizeof(guiVdbBuffer1[0]); guiVDBsize = sizeof(guiVdbBuffer1) / sizeof(guiVdbBuffer1[0]);
lv_disp_buf_init(&disp_buf, guiVdbBuffer1, guiVdbBuffer2, guiVDBsize); // lv_disp_buf_init(&disp_buf, guiVdbBuffer1, guiVdbBuffer2, guiVDBsize);
//lv_disp_buf_init(&disp_buf, guiVdbBuffer1, NULL, guiVDBsize); lv_disp_buf_init(&disp_buf, guiVdbBuffer1, NULL, guiVDBsize);
#endif #endif
/* Initialize PNG decoder */ /* Initialize PNG decoder */
#if HASP_USE_PNGDECODE != 0 #if HASP_USE_PNGDECODE > 0
png_decoder_init(); png_decoder_init();
#endif #endif
@ -673,8 +674,13 @@ void guiSetup()
lv_fs_if_init(); // auxilary file system drivers lv_fs_if_init(); // auxilary file system drivers
#endif #endif
/* Dump TFT Cofiguration */ /* Dump TFT Configuration */
tftSetup(tft); tftSetup(tft);
#ifdef USE_DMA_TO_TFT
Log.verbose(F("TFT: DMA : ENABELD"));
#else
Log.verbose(F("TFT: DMA : DISABELD"));
#endif
/* Load User Settings */ /* Load User Settings */
// guiSetConfig(settings); // guiSetConfig(settings);
@ -780,27 +786,27 @@ void guiSetup()
tick.attach_ms(guiTickPeriod, lv_tick_handler); tick.attach_ms(guiTickPeriod, lv_tick_handler);
#else #else
/* /*
#if defined(TIM1) #if defined(TIM1)
TIM_TypeDef * Instance = TIM1; TIM_TypeDef * Instance = TIM1;
#else #else
TIM_TypeDef * Instance = TIM2; TIM_TypeDef * Instance = TIM2;
#endif #endif
*/ */
// Instantiate HardwareTimer object. Thanks to 'new' instanciation, HardwareTimer is not destructed when setup() // Instantiate HardwareTimer object. Thanks to 'new' instanciation, HardwareTimer is not destructed when setup()
// function is finished. // function is finished.
/* static HardwareTimer * MyTim = new HardwareTimer(Instance); /* static HardwareTimer * MyTim = new HardwareTimer(Instance);
MyTim->pause(); MyTim->pause();
MyTim->setPrescaleFactor(1); MyTim->setPrescaleFactor(1);
MyTim->setMode(0, TIMER_OUTPUT_COMPARE, NC); MyTim->setMode(0, TIMER_OUTPUT_COMPARE, NC);
MyTim->setOverflow(1000 * guiTickPeriod, MICROSEC_FORMAT); // MicroSec MyTim->setOverflow(1000 * guiTickPeriod, MICROSEC_FORMAT); // MicroSec
MyTim->setCount(0,MICROSEC_FORMAT); MyTim->setCount(0,MICROSEC_FORMAT);
MyTim->refresh(); MyTim->refresh();
MyTim->detachInterrupt(); MyTim->detachInterrupt();
MyTim->attachInterrupt((void (*)(HardwareTimer *))lv_tick_handler); MyTim->attachInterrupt((void (*)(HardwareTimer *))lv_tick_handler);
MyTim->detachInterrupt(0); MyTim->detachInterrupt(0);
MyTim->attachInterrupt(0,(void (*)(HardwareTimer *))lv_tick_handler); MyTim->attachInterrupt(0,(void (*)(HardwareTimer *))lv_tick_handler);
MyTim->resume();*/ MyTim->resume();*/
tick.start(); tick.start();
#endif #endif
@ -811,36 +817,17 @@ void guiSetup()
void IRAM_ATTR guiLoop() void IRAM_ATTR guiLoop()
{ {
#ifdef STM32_CORE_VERSION_MAJOR #if defined(STM32F4xx)
tick.update(); tick.update();
while(Serial.available()) {
char ch = Serial.read();
Serial.print(ch);
if (ch == 13 ||ch == 10) {
serialInputBuffer[serialInputIndex] = 0;
if (serialInputIndex>0) dispatchCommand(serialInputBuffer);
serialInputIndex=0;
}else{
if(serialInputIndex < sizeof(serialInputBuffer) - 1) {
serialInputBuffer[serialInputIndex++] = ch;
}
serialInputBuffer[serialInputIndex] = 0;
if (strcmp(serialInputBuffer,"jsonl=")==0){
dispatchJsonl(Serial);
serialInputIndex=0;
}
}
}
#endif #endif
//lv_tick_handler();
// lv_tick_handler();
lv_task_handler(); /* let the GUI do its work */ lv_task_handler(); /* let the GUI do its work */
guiCheckSleep(); guiCheckSleep();
#if TOUCH_DRIVER == 1 #if TOUCH_DRIVER == 1
touch.loop(); touch.loop();
#endif #endif
} }
void guiStop() void guiStop()
@ -925,6 +912,7 @@ bool guiGetConfig(const JsonObject & settings)
v.set(calData[i]); v.set(calData[i]);
} else { } else {
changed = true; changed = true;
tft.setTouch(calData);
} }
i++; i++;
} }
@ -935,6 +923,8 @@ bool guiGetConfig(const JsonObject & settings)
for(uint8_t i = 0; i < 5; i++) { for(uint8_t i = 0; i < 5; i++) {
array.add(calData[i]); array.add(calData[i]);
} }
changed = true;
tft.setTouch(calData);
} }
if(changed) configOutput(settings); if(changed) configOutput(settings);
@ -991,6 +981,7 @@ bool guiSetConfig(const JsonObject & settings)
oobeSetAutoCalibrate(true); oobeSetAutoCalibrate(true);
} }
if(status) tft.setTouch(calData);
changed |= status; changed |= status;
} }
@ -1005,23 +996,15 @@ static void guiSetBmpHeader(uint8_t * buffer_p, int32_t data)
*buffer_p++ = (data >> 24) & 0xFF; *buffer_p++ = (data >> 24) & 0xFF;
} }
#if defined(ARDUINO_ARCH_ESP8266)
static void guiSendBmpHeader(); static void guiSendBmpHeader();
void guiTakeScreenshot(ESP8266WebServer & client) void guiTakeScreenshot()
#endif
#if defined(ARDUINO_ARCH_ESP32)
static void guiSendBmpHeader();
void guiTakeScreenshot(WebServer & client)
#endif // ESP32{
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
{ {
webClient = &client; // webClient = &client;
lv_disp_t * disp = lv_disp_get_default(); // lv_disp_t * disp = lv_disp_get_default();
webClient->setContentLength(122 + disp->driver.hor_res * disp->driver.ver_res * sizeof(lv_color_t)); // webClient->setContentLength(122 + disp->driver.hor_res * disp->driver.ver_res * sizeof(lv_color_t));
webClient->send(200, PSTR("image/bmp"), ""); // webClient->send(200, PSTR("image/bmp"), "");
guiSnapshot = 2; guiSnapshot = 2;
guiSendBmpHeader(); guiSendBmpHeader();
@ -1082,15 +1065,17 @@ static void guiSendBmpHeader()
buffer[70 + 0] = 0x20; buffer[70 + 0] = 0x20;
if(guiSnapshot == 1) { if(guiSnapshot == 1) {
#if HASP_USE_SPIFFS > 0
size_t len = pFileOut.write(buffer, 122); size_t len = pFileOut.write(buffer, 122);
if(len != sizeof(buffer)) { if(len != sizeof(buffer)) {
Log.warning(F("GUI: Data written does not match header size")); Log.warning(F("GUI: Data written does not match header size"));
} else { } else {
Log.verbose(F("GUI: Bitmap header written")); Log.verbose(F("GUI: Bitmap header written"));
} }
#endif
} else if(guiSnapshot == 2) { } else if(guiSnapshot == 2) {
if(webClient->client().write(buffer, 122) != 122) { if(httpClientWrite(buffer, 122) != 122) {
Log.warning(F("GUI: Data sent does not match header size")); Log.warning(F("GUI: Data sent does not match header size"));
} else { } else {
Log.verbose(F("GUI: Bitmap header sent")); Log.verbose(F("GUI: Bitmap header sent"));
@ -1107,6 +1092,7 @@ static void guiSendBmpHeader()
* @param[in] pFileName Output binary file name. * @param[in] pFileName Output binary file name.
* *
**/ **/
#if HASP_USE_SPIFFS > 0
void guiTakeScreenshot(const char * pFileName) void guiTakeScreenshot(const char * pFileName)
{ {
pFileOut = SPIFFS.open(pFileName, "w"); pFileOut = SPIFFS.open(pFileName, "w");

View File

@ -6,15 +6,17 @@
#include "lvgl.h" #include "lvgl.h"
#if defined(ARDUINO_ARCH_ESP8266) // #if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WebServer.h> // #include <ESP8266WebServer.h>
void guiTakeScreenshot(ESP8266WebServer & client); // void guiTakeScreenshot(ESP8266WebServer & client);
#endif // #endif
#if defined(ARDUINO_ARCH_ESP32) // #if defined(ARDUINO_ARCH_ESP32)
#include <WebServer.h> // #include <WebServer.h>
void guiTakeScreenshot(WebServer & client); // void guiTakeScreenshot(WebServer & client);
#endif // ESP32 // #endif // ESP32
void guiTakeScreenshot();
void guiSetup(); void guiSetup();
void guiLoop(void); void guiLoop(void);

View File

@ -1,25 +1,20 @@
#if defined(ESP32) || defined(ESP8266) #include "hasp_hal.h"
#include "hasp_conf.h"
#if defined(ESP8266)
#include <ESP.h> #include <ESP.h>
#include <ESP8266WiFi.h>
#endif #endif
#include "hasp_hal.h" #if defined(ESP32)
#include <ESP.h>
#if ESP32 #include <Wifi.h>
#include "esp_system.h" #include "esp_system.h"
#endif #endif
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include <rom/rtc.h> // needed to get the ResetInfo #include <rom/rtc.h> // needed to get the ResetInfo
void halRestart(void)
{
#if defined(ESP32) || defined(ESP8266)
ESP.restart();
#else
NVIC_SystemReset();
#endif
}
// Compatibility function for ESP8266 getRestInfo // Compatibility function for ESP8266 getRestInfo
String esp32ResetReason(uint8_t cpuid) String esp32ResetReason(uint8_t cpuid)
{ {
@ -90,6 +85,15 @@ String esp32ResetReason(uint8_t cpuid)
} }
#endif #endif
void halRestart(void)
{
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
ESP.restart();
#else
NVIC_SystemReset();
#endif
}
String halGetResetInfo() String halGetResetInfo()
{ {
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
@ -105,57 +109,6 @@ String halGetResetInfo()
#else #else
return ""; return "";
#endif #endif
}
#ifdef __arm__
// should use uinstd.h to define sbrk but Due causes a conflict
extern "C" char* sbrk(int incr);
#else // __ARM__
extern char *__brkval;
#endif // __arm__
int freeMemory() {
char top;
#ifdef __arm__
return &top - reinterpret_cast<char*>(sbrk(0));
#elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151)
return &top - __brkval;
#else // __arm__
return __brkval ? &top - __brkval : &top - __malloc_heap_start;
#endif // __arm__
}
uint8_t halGetHeapFragmentation()
{
#if defined(ARDUINO_ARCH_ESP32)
return (int8_t)(100.00f - (float)ESP.getMaxAllocHeap() * 100.00f / (float)ESP.getFreeHeap());
#elif defined(ARDUINO_ARCH_ESP8266)
return ESP.getHeapFragmentation();
#else
return 255;
#endif
}
size_t halGetMaxFreeBlock()
{
#if defined(ARDUINO_ARCH_ESP32)
return ESP.getMaxAllocHeap();
#elif defined(ARDUINO_ARCH_ESP8266)
return ESP.getMaxFreeBlockSize();
#else
return freeMemory();
#endif
}
size_t halGetFreeHeap(void)
{
#if defined(ARDUINO_ARCH_ESP32)
return ESP.getFreeHeap();
#elif defined(ARDUINO_ARCH_ESP8266)
return ESP.getFreeHeap();
#else
return 1;
#endif
} }
String halGetCoreVersion() String halGetCoreVersion()
@ -193,8 +146,8 @@ String halGetChipModel()
case CHIP_ESP32S2: case CHIP_ESP32S2:
model += F("ESP32-S2"); model += F("ESP32-S2");
break; break;
#endif #endif
default: default:
model = F("Unknown ESP"); model = F("Unknown ESP");
} }
model += F(" rev"); model += F(" rev");
@ -202,4 +155,146 @@ String halGetChipModel()
#endif // ESP32 #endif // ESP32
return model; return model;
}
/*******************************/
/* Memory Management Functions */
#if defined(STM32F4xx)
#include <malloc.h> // for mallinfo()
#include <unistd.h> // for sbrk()
int freeHighMemory()
{
char top;
#ifdef __arm__
return &top - reinterpret_cast<char *>(sbrk(0));
#elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151)
return &top - __brkval;
#else // __arm__
return __brkval ? &top - __brkval : &top - __malloc_heap_start;
#endif // __arm__
}
#endif
/*
extern char *fake_heap_end; // current heap start
extern char *fake_heap_start; // current heap end
char* getHeapStart() {
return fake_heap_start;
}
char* getHeapEnd() {
return (char*)sbrk(0);
}
char* getHeapLimit() {
return fake_heap_end;
}
int getMemUsed() { // returns the amount of used memory in bytes
struct mallinfo mi = mallinfo();
return mi.uordblks;
}
int getMemFree() { // returns the amount of free memory in bytes
struct mallinfo mi = mallinfo();
return mi.fordblks + freeHighMemory();
} */
size_t halGetMaxFreeBlock()
{
#if defined(ARDUINO_ARCH_ESP32)
return ESP.getMaxAllocHeap();
#elif defined(ARDUINO_ARCH_ESP8266)
return ESP.getMaxFreeBlockSize();
#else
return freeHighMemory();
#endif
}
size_t halGetFreeHeap(void)
{
#if defined(ARDUINO_ARCH_ESP32)
return ESP.getFreeHeap();
#elif defined(ARDUINO_ARCH_ESP8266)
return ESP.getFreeHeap();
#else
struct mallinfo chuncks = mallinfo();
// fordblks
// This is the total size of memory occupied by free (not in use) chunks.
return chuncks.fordblks + freeHighMemory();
#endif
}
uint8_t halGetHeapFragmentation()
{
#if defined(ARDUINO_ARCH_ESP32)
return (int8_t)(100.00f - (float)ESP.getMaxAllocHeap() * 100.00f / (float)ESP.getFreeHeap());
#elif defined(ARDUINO_ARCH_ESP8266)
return ESP.getHeapFragmentation();
#else
return (int8_t)(100.00f - (float)freeHighMemory() * 100.00f / (float)halGetFreeHeap());
#endif
}
String halGetMacAddress(int start, const char * seperator)
{
byte mac[6];
#if defined(STM32F4xx)
uint8_t * mac_p = nullptr;
#if USE_BUILTIN_ETHERNET > 0
mac_p = Ethernet.MACAddress();
for(uint8_t i = 0; i < 6; i++) mac[i] = *(mac_p + i);
#else
Ethernet.macAddress(mac);
#endif
#else
WiFi.macAddress(mac);
#endif
String cMac((char *)0);
cMac.reserve(32);
for(int i = start; i < 6; ++i) {
if(mac[i] < 0x10) cMac += "0";
cMac += String(mac[i], HEX);
if(i < 5) cMac += seperator;
}
cMac.toUpperCase();
return cMac;
}
uint16_t halGetCpuFreqMHz()
{
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_32)
return ESP.getCpuFreqMHz();
#else
return (F_CPU / 1000 / 1000);
#endif
}
String halFormatBytes(size_t bytes)
{
String output((char *)0);
output.reserve(128);
if(bytes < 1024) {
output += bytes;
} else if(bytes < (1024 * 1024)) {
output += bytes / 1024.0;
output += "K";
} else if(bytes < (1024 * 1024 * 1024)) {
output += bytes / 1024.0 / 1024.0;
output += "M";
} else {
output += bytes / 1024.0 / 1024.0 / 1024.0;
output += "G";
}
output += "B";
return output;
} }

View File

@ -3,12 +3,15 @@
#include <Arduino.h> #include <Arduino.h>
void halRestart(void);
uint8_t halGetHeapFragmentation(void); uint8_t halGetHeapFragmentation(void);
String halGetResetInfo(void); String halGetResetInfo(void);
size_t halGetMaxFreeBlock(void); size_t halGetMaxFreeBlock(void);
size_t halGetFreeHeap(void); size_t halGetFreeHeap(void);
String halGetCoreVersion(void); String halGetCoreVersion(void);
String halGetChipModel(); String halGetChipModel();
void halRestart(void); String halGetMacAddress(int start, const char * seperator);
uint16_t halGetCpuFreqMHz(void);
String halFormatBytes(size_t bytes);
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,8 @@ void httpLoop(void);
void httpEvery5Seconds(void); void httpEvery5Seconds(void);
void httpReconnect(void); void httpReconnect(void);
size_t httpClientWrite(const uint8_t *buf, size_t size); // Screenshot Write Data
bool httpGetConfig(const JsonObject & settings); bool httpGetConfig(const JsonObject & settings);
bool httpSetConfig(const JsonObject & settings); bool httpSetConfig(const JsonObject & settings);

View File

@ -13,10 +13,10 @@
#include "hasp_config.h" #include "hasp_config.h"
#include "hasp_conf.h" #include "hasp_conf.h"
#if HASP_USE_MQTT #if HASP_USE_MQTT>0
#include "hasp_mqtt.h" #include "hasp_mqtt.h"
#endif #endif
#if HASP_USE_MDNS #if HASP_USE_MDNS>0
#include "hasp_mdns.h" #include "hasp_mdns.h"
#endif #endif

View File

@ -1,5 +1,5 @@
#include "hasp_conf.h" #include "hasp_conf.h"
#if HASP_USE_MQTT #if HASP_USE_MQTT>0
#include <Arduino.h> #include <Arduino.h>
#include "ArduinoJson.h" #include "ArduinoJson.h"
@ -11,10 +11,22 @@
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include <Wifi.h> #include <Wifi.h>
#else WiFiClient mqttNetworkClient;
#elif defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <EEPROM.h> #include <EEPROM.h>
#include <ESP.h> #include <ESP.h>
WiFiClient mqttNetworkClient;
#else
#if defined(W5500_MOSI) && defined(W5500_MISO) && defined(W5500_SCLK)
#define W5500_LAN
#include <Ethernet.h>
#else
#include <STM32Ethernet.h>
#endif
EthernetClient mqttNetworkClient;
#endif #endif
#include "hasp_hal.h" #include "hasp_hal.h"
@ -97,8 +109,7 @@ const String mqttLightSubscription = "hasp/" + String(haspGetNodename())
const String mqttLightBrightSubscription = "hasp/" + String(haspGetNodename()) + "/brightness/#"; const String mqttLightBrightSubscription = "hasp/" + String(haspGetNodename()) + "/brightness/#";
*/ */
WiFiClient mqttWifiClient; PubSubClient mqttClient(mqttNetworkClient);
PubSubClient mqttClient(mqttWifiClient);
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Send changed values OUT // Send changed values OUT
@ -179,11 +190,13 @@ void mqtt_send_statusupdate()
snprintf_P(data, sizeof(data), PSTR("{\"status\":\"available\",\"version\":\"%s\",\"uptime\":%lu,"), snprintf_P(data, sizeof(data), PSTR("{\"status\":\"available\",\"version\":\"%s\",\"uptime\":%lu,"),
haspGetVersion().c_str(), long(millis() / 1000)); haspGetVersion().c_str(), long(millis() / 1000));
strcat(buffer, data); strcat(buffer, data);
#if HASP_USE_WIFI>0
snprintf_P(buffer, sizeof(buffer), PSTR("\"ssid\":\"%s\",\"rssi\":%i,\"ip\":\"%s\","), WiFi.SSID().c_str(), snprintf_P(buffer, sizeof(buffer), PSTR("\"ssid\":\"%s\",\"rssi\":%i,\"ip\":\"%s\","), WiFi.SSID().c_str(),
WiFi.RSSI(), WiFi.localIP().toString().c_str()); WiFi.RSSI(), WiFi.localIP().toString().c_str());
strcat(data, buffer); strcat(data, buffer);
#endif
snprintf_P(buffer, sizeof(buffer), PSTR("\"heapFree\":%u,\"heapFrag\":%u,\"espCore\":\"%s\","), snprintf_P(buffer, sizeof(buffer), PSTR("\"heapFree\":%u,\"heapFrag\":%u,\"espCore\":\"%s\","),
ESP.getFreeHeap(), halGetHeapFragmentation(), halGetCoreVersion().c_str()); halGetFreeHeap(), halGetHeapFragmentation(), halGetCoreVersion().c_str());
strcat(data, buffer); strcat(data, buffer);
snprintf_P(buffer, sizeof(buffer), PSTR("\"espCanUpdate\":\"false\",\"page\":%u,\"numPages\":%u,"), snprintf_P(buffer, sizeof(buffer), PSTR("\"espCanUpdate\":\"false\",\"page\":%u,\"numPages\":%u,"),
haspGetPage(), (HASP_NUM_PAGES)); haspGetPage(), (HASP_NUM_PAGES));
@ -339,9 +352,11 @@ void mqttReconnect()
bool mqttFirstConnect = true; bool mqttFirstConnect = true;
{ {
byte mac[6]; String mac = halGetMacAddress(3, "");
WiFi.macAddress(mac); mac.toLowerCase();
snprintf_P(mqttClientId, sizeof(mqttClientId), PSTR("%s-%2x%2x%2x"), mqttNodeName, mac[3], mac[4], mac[5]); memset(mqttClientId, 0 ,sizeof(mqttClientId));
snprintf_P(mqttClientId, sizeof(mqttClientId), PSTR("plate_%s"), mac.c_str());
Log.verbose(mqttClientId);
} }
// Attempt to connect and set LWT and Clean Session // Attempt to connect and set LWT and Clean Session
@ -537,7 +552,7 @@ bool mqttSetConfig(const JsonObject & settings)
} }
// Prefill node name // Prefill node name
if(strlen(mqttNodeName) == 0) { if(strlen(mqttNodeName) == 0) {
String mac = wifiGetMacAddress(3, ""); String mac = halGetMacAddress(3, "");
mac.toLowerCase(); mac.toLowerCase();
snprintf_P(mqttNodeName, sizeof(mqttNodeName), PSTR("plate_%s"), mac.c_str()); snprintf_P(mqttNodeName, sizeof(mqttNodeName), PSTR("plate_%s"), mac.c_str());
changed = true; changed = true;

View File

@ -14,7 +14,7 @@
#include "hasp_config.h" #include "hasp_config.h"
#include "hasp_dispatch.h" #include "hasp_dispatch.h"
#if HASP_USE_QRCODE != 0 #if HASP_USE_QRCODE > 0
#include "lv_qrcode.h" #include "lv_qrcode.h"
#endif #endif
@ -128,7 +128,7 @@ static void oobeSetupQR(const char * ssid, const char * pass)
lv_obj_set_style_local_bg_opa(container, LV_ARC_PART_BG, LV_STATE_DEFAULT, 0); lv_obj_set_style_local_bg_opa(container, LV_ARC_PART_BG, LV_STATE_DEFAULT, 0);
lv_obj_set_style_local_border_opa(container, LV_ARC_PART_BG, LV_STATE_DEFAULT, 0); lv_obj_set_style_local_border_opa(container, LV_ARC_PART_BG, LV_STATE_DEFAULT, 0);
#if HASP_USE_QRCODE != 0 #if HASP_USE_QRCODE > 0
snprintf_P(buffer, sizeof(buffer), PSTR("WIFI:S:%s;T:WPA;P:%s;;"), ssid, pass); snprintf_P(buffer, sizeof(buffer), PSTR("WIFI:S:%s;T:WPA;P:%s;;"), ssid, pass);
lv_obj_t * qr = lv_qrcode_create(oobepage[0], 120, LV_COLOR_BLACK, LV_COLOR_WHITE); lv_obj_t * qr = lv_qrcode_create(oobepage[0], 120, LV_COLOR_BLACK, LV_COLOR_WHITE);

View File

@ -10,11 +10,11 @@
#include "hasp_conf.h" #include "hasp_conf.h"
#if HASP_USE_MQTT #if HASP_USE_MQTT>0
#include "hasp_mqtt.h" #include "hasp_mqtt.h"
#endif #endif
#if HASP_USE_MDNS #if HASP_USE_MDNS>0
#include "hasp_mdns.h" #include "hasp_mdns.h"
#endif #endif

165
src/hasp_slave.cpp Normal file
View File

@ -0,0 +1,165 @@
/*********************
* INCLUDES
*********************/
#if HASP_USE_TASMOTA_SLAVE>0
#include "hasp_slave.h"
#include <Arduino.h>
#include "ArduinoJson.h"
#include "ArduinoLog.h"
#include "hasp_dispatch.h"
#include "hasp_gui.h"
#include "hasp_hal.h"
#include "hasp_tft.h"
#include "hasp_config.h"
#include "hasp.h"
#include "tasmotaSlave.h"
// set RX and TX pins
HardwareSerial Serial2(PD6, PD5);
TasmotaSlave slave(&Serial2);
#define slaveNodeTopic "hasp/"
unsigned long updateLedTimer = 0; // timer in msec for tele mqtt send
unsigned long updatLedPeriod = 1000; // timer in msec for tele mqtt send
bool ledstate = false;
void IRAM_ATTR slave_send_state(const __FlashStringHelper * subtopic, const char * payload)
{
// page = 0
// p[0].b[0].attr = abc
// dim = 100
// idle = 0/1
// light = 0/1
// brightness = 100
char cBuffer[strlen(payload) + 64];
memset(cBuffer, 0 ,sizeof(cBuffer));
snprintf(cBuffer, sizeof(cBuffer), PSTR("publish %sstate/%s %s"), slaveNodeTopic ,subtopic, payload);
slave.ExecuteCommand((char*)cBuffer);
// Log after char buffers are cleared
Log.notice(F("TAS PUB: %sstate/%S = %s"), slaveNodeTopic, subtopic, payload);
}
void IRAM_ATTR slave_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute, const char * data)
{
char cBuffer[192];
memset(cBuffer, 0 ,sizeof(cBuffer));
snprintf_P(cBuffer, sizeof(cBuffer), PSTR("publish %sstate/json {\"p[%u].b[%u].%s\":\"%s\"}"), slaveNodeTopic, pageid, btnid, attribute, data);
slave.ExecuteCommand((char*)cBuffer);
// Log after char buffers are cleared
Log.notice(F("TAS PUB: %sstate/json = {\"p[%u].b[%u].%s\":\"%s\"}"), slaveNodeTopic, pageid, btnid, attribute, data);
}
void slave_send_input(uint8_t id, const char * payload)
{
// Log.trace(F("MQTT TST: %sstate/input%u = %s"), mqttNodeTopic, id, payload); // to be removed
char cBuffer[strlen(payload) + 64];
memset(cBuffer, 0 ,sizeof(cBuffer));
snprintf_P(cBuffer, sizeof(cBuffer), PSTR("publish %sstate/input%u %s"), slaveNodeTopic, id, payload);
slave.ExecuteCommand((char*)cBuffer);
// Log after char buffers are cleared
Log.notice(F("TAS PUB: %sstate/input%u = %s"), slaveNodeTopic, id, payload);
}
void TASMO_TELE_JSON()
{ // Periodically publish a JSON string indicating system status
char data[3 * 128];
{
char buffer[128];
snprintf_P(data, sizeof(data), PSTR("{\"status\":\"available\",\"version\":\"%s\",\"uptime\":%lu,"),
haspGetVersion().c_str(), long(millis() / 1000));
strcat(buffer, data);
snprintf_P(buffer, sizeof(buffer), PSTR("\"espCanUpdate\":\"false\",\"page\":%u,\"numPages\":%u,"),
haspGetPage(), (HASP_NUM_PAGES));
strcat(data, buffer);
snprintf_P(buffer, sizeof(buffer), PSTR("\"tftDriver\":\"%s\",\"tftWidth\":%u,\"tftHeight\":%u}"),
tftDriverName().c_str(), (TFT_WIDTH), (TFT_HEIGHT));
strcat(data, buffer);
}
slave.sendJSON((char*)data);
// slave_send_state(F("statusupdate"), data);
// debugLastMillis = millis();
}
void TASMO_DATA_RECEIVE(char *data)
{
Log.verbose(F("TAS: Slave IN [%s]"), data);
char dataType[3];
memset(dataType, 0 ,sizeof(dataType));
snprintf_P(dataType, sizeof(dataType), data);
Log.verbose(F("TAS: dataType [%s]"), dataType);
if (!strcmp(dataType, "p[")){ //
dispatchCommand(data);
} else if (!strcmp(dataType, "[\"")) {
dispatchJson(data);
} else {
char slvCmd[20],slvVal[60];
memset(slvCmd, 0 ,sizeof(slvCmd));
memset(slvVal, 0 ,sizeof(slvVal));
sscanf(data,"%[^=] =%s", slvCmd, slvVal);
Log.verbose(F("TAS: Cmd[%s] Val[%s]"), slvCmd, slvVal);
if (!strcmp(slvCmd, "calData")){
if (strlen(slvVal) != 0) {
char cBuffer[strlen(slvVal) + 24];
memset(cBuffer, 0 ,sizeof(cBuffer));
snprintf_P(cBuffer, sizeof(cBuffer), PSTR("{'calibration':[%s]}"), slvVal);
dispatchConfig("gui",cBuffer);
} else {
dispatchConfig("gui","");
}
} else if (!strcmp(slvCmd, "jsonl")) {
dispatchJsonl(slvVal);
} else if (!strcmp(slvCmd, "clearpage")) {
dispatchClearPage(slvVal);
} else {
dispatchCommand(data);
}
}
}
void TASMO_EVERY_SECOND(void)
{
if (ledstate) {
ledstate = false;
//digitalWrite(HASP_OUTPUT_PIN, 1);
// Log.verbose(F("LED OFF"));
} else {
ledstate = true;
//digitalWrite(HASP_OUTPUT_PIN, 0);
// Log.verbose(F("LED ON"));
}
}
void slaveSetup()
{
Serial2.begin(HASP_SLAVE_SPEED);
// slave.attach_FUNC_EVERY_SECOND(TASMO_EVERY_SECOND);
slave.attach_FUNC_JSON(TASMO_TELE_JSON);
slave.attach_FUNC_COMMAND_SEND(TASMO_DATA_RECEIVE);
Log.notice(F("TAS: HASP SLAVE LOADED"));
}
void slaveLoop(void)
{
slave.loop();
// demo code to run the led without tasmota
// if ((millis() - updateLedTimer) >= updatLedPeriod) {
// updateLedTimer = millis();
// TASMO_EVERY_SECOND();
// }
}
#endif

20
src/hasp_slave.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef HASP_SLAVE_H
#define HASP_SLAVE_H
#include "ArduinoJson.h"
#define HASP_SLAVE_SPEED 57600
void TASMO_EVERY_SECOND(void);
void TASMO_DATA_RECEIVE(char *data);
void IRAM_ATTR slave_send_state(const __FlashStringHelper * subtopic, const char * payload);
void IRAM_ATTR slave_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute, const char * data);
void slave_send_input(uint8_t id, const char * payload);
void slave_send_statusupdate();
void slaveSetup();
void slaveLoop(void);
#endif

View File

@ -5,7 +5,7 @@
#include "hasp_conf.h" #include "hasp_conf.h"
#include "hasp_spiffs.h" #include "hasp_spiffs.h"
#if HASP_USE_SPIFFS #if HASP_USE_SPIFFS>0
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h" #include "SPIFFS.h"
#endif #endif
@ -14,7 +14,7 @@
void spiffsInfo() void spiffsInfo()
{ // Get all information of your SPIFFS { // Get all information of your SPIFFS
#if defined(ARDUINO_ARCH_ESP8266) #if 0
FSInfo fs_info; FSInfo fs_info;
SPIFFS.info(fs_info); SPIFFS.info(fs_info);
@ -91,7 +91,7 @@ void spiffsSetup()
{ {
// no SPIFFS settings, as settings depend on SPIFFS // no SPIFFS settings, as settings depend on SPIFFS
#if HASP_USE_SPIFFS #if HASP_USE_SPIFFS>0
#if defined(ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
if(!SPIFFS.begin()) { if(!SPIFFS.begin()) {
#else #else
@ -102,25 +102,4 @@ void spiffsSetup()
Log.verbose(F("FILE: SPI Flash FS mounted")); Log.verbose(F("FILE: SPI Flash FS mounted"));
} }
#endif #endif
}
String spiffsFormatBytes(size_t bytes)
{
String output((char *)0);
output.reserve(128);
if(bytes < 1024) {
output += bytes;
} else if(bytes < (1024 * 1024)) {
output += bytes / 1024.0;
output += "K";
} else if(bytes < (1024 * 1024 * 1024)) {
output += bytes / 1024.0 / 1024.0;
output += "M";
} else {
output += bytes / 1024.0 / 1024.0 / 1024.0;
output += "G";
}
output += "B";
return output;
} }

View File

@ -7,6 +7,5 @@ void spiffsSetup(void);
void spiffsList(); void spiffsList();
void spiffsInfo(); void spiffsInfo();
String spiffsFormatBytes(size_t bytes);
#endif #endif

View File

@ -9,11 +9,20 @@
#include "hasp_config.h" #include "hasp_config.h"
#include "hasp_dispatch.h" #include "hasp_dispatch.h"
#include "hasp_telnet.h" #include "hasp_telnet.h"
#include "hasp_conf.h"
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include <Wifi.h> #include <Wifi.h>
#else WiFiClient telnetClient;
static WiFiServer * telnetServer;
#elif defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
WiFiClient telnetClient;
static WiFiServer * telnetServer;
#else
//#include <STM32Ethernet.h>
EthernetClient telnetClient;
static EthernetServer telnetServer(23);
#endif #endif
#define TELNET_UNAUTHENTICATED 0 #define TELNET_UNAUTHENTICATED 0
@ -21,12 +30,14 @@
#define TELNET_USERNAME_NOK 99 #define TELNET_USERNAME_NOK 99
#define TELNET_AUTHENTICATED 255 #define TELNET_AUTHENTICATED 255
#if HASP_USE_HTTP > 0
extern char httpUser[32]; extern char httpUser[32];
extern char httpPassword[32]; extern char httpPassword[32];
#endif
uint8_t telnetLoginState = TELNET_UNAUTHENTICATED; uint8_t telnetLoginState = TELNET_UNAUTHENTICATED;
WiFiClient telnetClient; // WiFiClient telnetClient;
static WiFiServer * telnetServer; // static WiFiServer * telnetServer;
uint16_t telnetPort = 23; uint16_t telnetPort = 23;
bool telnetInCommandMode = false; bool telnetInCommandMode = false;
uint8_t telnetEnabled = true; // Enable telnet debug output uint8_t telnetEnabled = true; // Enable telnet debug output
@ -36,7 +47,7 @@ char telnetInputBuffer[128];
void telnetClientDisconnect() void telnetClientDisconnect()
{ {
Log.notice(F("Closing session from %s"), telnetClient.remoteIP().toString().c_str()); // Log.notice(F("Closing session from %s"), telnetClient.remoteIP().toString().c_str());
telnetClient.stop(); telnetClient.stop();
Log.unregisterOutput(1); // telnetClient Log.unregisterOutput(1); // telnetClient
telnetLoginState = TELNET_UNAUTHENTICATED; telnetLoginState = TELNET_UNAUTHENTICATED;
@ -51,7 +62,7 @@ void telnetClientLogon()
telnetLoginState = TELNET_AUTHENTICATED; // User and Pass are correct telnetLoginState = TELNET_AUTHENTICATED; // User and Pass are correct
telnetLoginAttempt = 0; // Reset attempt counter telnetLoginAttempt = 0; // Reset attempt counter
Log.registerOutput(1, &telnetClient, LOG_LEVEL_VERBOSE, true); Log.registerOutput(1, &telnetClient, LOG_LEVEL_VERBOSE, true);
Log.notice(F("Client login from %s"), telnetClient.remoteIP().toString().c_str()); // Log.notice(F("Client login from %s"), telnetClient.remoteIP().toString().c_str());
telnetClient.flush(); telnetClient.flush();
/* Echo locally as separate string */ /* Echo locally as separate string */
// telnetClient.print(F("TELNET: Client login from ")); // telnetClient.print(F("TELNET: Client login from "));
@ -66,17 +77,25 @@ void telnetAcceptClient()
telnetClient.stop(); // client disconnected telnetClient.stop(); // client disconnected
Log.unregisterOutput(1); // telnetClient Log.unregisterOutput(1); // telnetClient
} }
telnetClient = telnetServer->available(); // ready for new client telnetClient = telnetServer.available(); // ready for new client
Log.notice(F("Client connected from %s"), telnetClient.remoteIP().toString().c_str()); // Log.notice(F("Client connected from %s"), telnetClient.remoteIP().toString().c_str());
if(!telnetClient) {
Log.notice(F("Client NOT connected"));
return;
}
Log.notice(F("Client connected"));
/* Avoid a buffer here */ /* Avoid a buffer here */
telnetClient.print(0xFF); // DO TERMINAL-TYPE telnetClient.print(0xFF); // DO TERMINAL-TYPE
telnetClient.print(0xFD); telnetClient.print(0xFD);
telnetClient.print(0x1B); telnetClient.print(0x1B);
#if HASP_USE_HTTP > 0
if(strlen(httpUser) != 0 || strlen(httpPassword) != 0) { if(strlen(httpUser) != 0 || strlen(httpPassword) != 0) {
telnetClient.print(F("\r\nUsername: ")); telnetClient.print(F("\r\nUsername: "));
telnetLoginState = TELNET_UNAUTHENTICATED; telnetLoginState = TELNET_UNAUTHENTICATED;
} else { } else
#endif
{
telnetClientLogon(); telnetClientLogon();
} }
telnetInputIndex = 0; // reset input buffer index telnetInputIndex = 0; // reset input buffer index
@ -100,6 +119,7 @@ static void telnetProcessLine()
switch(telnetLoginState) { switch(telnetLoginState) {
case TELNET_UNAUTHENTICATED: { case TELNET_UNAUTHENTICATED: {
telnetClient.printf(PSTR("Password: %c%c%c"), 0xFF, 0xFB, 0x01); // Hide characters telnetClient.printf(PSTR("Password: %c%c%c"), 0xFF, 0xFB, 0x01); // Hide characters
#if HASP_USE_HTTP > 0
telnetLoginState = strcmp(telnetInputBuffer, httpUser) == 0 ? TELNET_USERNAME_OK : TELNET_USERNAME_NOK; telnetLoginState = strcmp(telnetInputBuffer, httpUser) == 0 ? TELNET_USERNAME_OK : TELNET_USERNAME_NOK;
break; break;
} }
@ -112,13 +132,16 @@ static void telnetProcessLine()
telnetLoginState = TELNET_UNAUTHENTICATED; telnetLoginState = TELNET_UNAUTHENTICATED;
telnetLoginAttempt++; // Subsequent attempt telnetLoginAttempt++; // Subsequent attempt
telnetClient.println(F("Authorization failed!\r\n")); telnetClient.println(F("Authorization failed!\r\n"));
Log.warning(F("Incorrect login attempt from %s"), telnetClient.remoteIP().toString().c_str()); // Log.warning(F("Incorrect login attempt from %s"), telnetClient.remoteIP().toString().c_str());
if(telnetLoginAttempt >= 3) { if(telnetLoginAttempt >= 3) {
telnetClientDisconnect(); telnetClientDisconnect();
} else { } else {
telnetClient.print(F("Username: ")); telnetClient.print(F("Username: "));
} }
} }
#else
telnetClientLogon();
#endif
break; break;
} }
default: default:
@ -173,6 +196,15 @@ void telnetSetup()
// telnetSetConfig(settings); // telnetSetConfig(settings);
if(telnetEnabled) { // Setup telnet server for remote debug output if(telnetEnabled) { // Setup telnet server for remote debug output
#if defined(STM32F4xx)
// if(!telnetServer) telnetServer = new EthernetServer(telnetPort);
// if(telnetServer) {
telnetServer.begin();
Log.notice(F("Debug telnet console started"));
// } else {
// Log.error(F("Failed to start telnet server"));
//}
#else
if(!telnetServer) telnetServer = new WiFiServer(telnetPort); if(!telnetServer) telnetServer = new WiFiServer(telnetPort);
if(telnetServer) { if(telnetServer) {
telnetServer->setNoDelay(true); telnetServer->setNoDelay(true);
@ -189,12 +221,41 @@ void telnetSetup()
} else { } else {
Log.error(F("Failed to start telnet server")); Log.error(F("Failed to start telnet server"));
} }
#endif
} }
} }
void IRAM_ATTR telnetLoop() void IRAM_ATTR telnetLoop()
{ // Basic telnet client handling code from: https://gist.github.com/tablatronix/4793677ca748f5f584c95ec4a2b10303 { // Basic telnet client handling code from: https://gist.github.com/tablatronix/4793677ca748f5f584c95ec4a2b10303
#if defined(STM32F4xx)
Ethernet.schedule();
// if(telnetServer)
{ // client is connected
EthernetClient client = telnetServer.available();
if(client) {
if(!telnetClient || !telnetClient.connected()) {
//telnetAcceptClient(client);
telnetClient = client; // ready for new client
// Log.notice(F("Client connected from %s"), telnetClient.remoteIP().toString().c_str());
if(!telnetClient) {
Log.notice(F("Client NOT connected"));
return;
}
Log.notice(F("Client connected"));
/* Avoid a buffer here */
// telnetClient.print(0xFF); // DO TERMINAL-TYPE
// telnetClient.print(0xFD);
// telnetClient.print(0x1B);
} else {
//client.stop(); // have client, block new connections
}
}
}
#else
if(telnetServer && telnetServer->hasClient()) { // client is connected if(telnetServer && telnetServer->hasClient()) { // client is connected
if(!telnetClient || !telnetClient.connected()) { if(!telnetClient || !telnetClient.connected()) {
telnetAcceptClient(); telnetAcceptClient();
@ -209,6 +270,7 @@ void IRAM_ATTR telnetLoop()
telnetProcessCharacter(telnetClient.read()); // client input processing telnetProcessCharacter(telnetClient.read()); // client input processing
} }
} }
#endif
} }
bool telnetGetConfig(const JsonObject & settings) bool telnetGetConfig(const JsonObject & settings)

View File

@ -3,6 +3,7 @@
#include "TFT_eSPI.h" #include "TFT_eSPI.h"
#include "hasp_tft.h" #include "hasp_tft.h"
#include "hasp_hal.h"
#if defined(ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
ADC_MODE(ADC_VCC); // tftShowConfig measures the voltage on the pin ADC_MODE(ADC_VCC); // tftShowConfig measures the voltage on the pin
@ -84,11 +85,10 @@ void tftShowConfig(TFT_eSPI & tft)
Log.verbose(F("TFT: TFT_eSPI : v%s"), tftSetup.version.c_str()); Log.verbose(F("TFT: TFT_eSPI : v%s"), tftSetup.version.c_str());
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_32) #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_32)
Log.verbose(F("TFT: Processor : ESP%x"), tftSetup.esp); Log.verbose(F("TFT: Processor : ESP%x"), tftSetup.esp);
Log.verbose(F("TFT: CPU freq. : %i MHz"), ESP.getCpuFreqMHz());
#else #else
Log.verbose(F("TFT: Processor : STM%x"), tftSetup.esp); Log.verbose(F("TFT: Processor : STM%x"), tftSetup.esp);
Log.verbose(F("TFT: CPU freq. : %i MHz"), F_CPU/1000/1000);
#endif #endif
Log.verbose(F("TFT: CPU freq. : %i MHz"), halGetCpuFreqMHz());
#if defined(ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
Log.verbose(F("TFT: Voltage : %2.2f V"), ESP.getVcc() / 918.0); // 918 empirically determined Log.verbose(F("TFT: Voltage : %2.2f V"), ESP.getVcc() / 918.0); // 918 empirically determined
@ -98,6 +98,7 @@ void tftShowConfig(TFT_eSPI & tft)
#if defined(ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
Log.verbose(F("TFT: SPI overlap : %s"), (tftSetup.overlap == 1) ? PSTR("Yes") : PSTR("No")); Log.verbose(F("TFT: SPI overlap : %s"), (tftSetup.overlap == 1) ? PSTR("Yes") : PSTR("No"));
#endif #endif
if(tftSetup.tft_driver != 0xE9D) // For ePaper displays the size is defined in the sketch if(tftSetup.tft_driver != 0xE9D) // For ePaper displays the size is defined in the sketch
{ {
Log.verbose(F("TFT: Driver : %s"), tftDriverName().c_str()); // tftSetup.tft_driver); Log.verbose(F("TFT: Driver : %s"), tftDriverName().c_str()); // tftSetup.tft_driver);
@ -155,14 +156,10 @@ void tftShowConfig(TFT_eSPI & tft)
tftPinInfo(F("TFT_D7"), tftSetup.pin_tft_d7); tftPinInfo(F("TFT_D7"), tftSetup.pin_tft_d7);
if(tftSetup.serial == 1) { if(tftSetup.serial == 1) {
char buffer[8]; Log.verbose(F("TFT: Display SPI freq. : %d.%d MHz"), tftSetup.tft_spi_freq / 10, tftSetup.tft_spi_freq % 10);
snprintf_P(buffer, sizeof(buffer), "%4.2f", (float)tftSetup.tft_spi_freq / 10.0f);
Log.verbose(F("TFT: Display SPI freq. : %s MHz"), buffer);
} }
if(tftSetup.pin_tch_cs != -1) { if(tftSetup.pin_tch_cs != -1) {
char buffer[8]; Log.verbose(F("TFT: Touch SPI freq. : %d.%d MHz"), tftSetup.tch_spi_freq / 10, tftSetup.tch_spi_freq % 10);
snprintf_P(buffer, sizeof(buffer), "%4.2f", (float)tftSetup.tch_spi_freq / 10.0f);
Log.verbose(F("TFT: Touch SPI freq. : %s MHz"), buffer);
} }
} }

View File

@ -41,22 +41,6 @@ uint8_t wifiReconnectCounter = 0;
// const byte DNS_PORT = 53; // const byte DNS_PORT = 53;
// DNSServer dnsServer; // DNSServer dnsServer;
String wifiGetMacAddress(int start, const char * seperator)
{
byte mac[6];
WiFi.macAddress(mac);
String cMac((char *)0);
cMac.reserve(32);
for(int i = start; i < 6; ++i) {
if(mac[i] < 0x10) cMac += "0";
cMac += String(mac[i], HEX);
if(i < 5) cMac += seperator;
}
cMac.toUpperCase();
return cMac;
}
void wifiConnected(IPAddress ipaddress) void wifiConnected(IPAddress ipaddress)
{ {
Log.notice(F("WIFI: Received IP address %s"), ipaddress.toString().c_str()); Log.notice(F("WIFI: Received IP address %s"), ipaddress.toString().c_str());

View File

@ -13,6 +13,4 @@ bool wifiTestConnection();
bool wifiGetConfig(const JsonObject & settings); bool wifiGetConfig(const JsonObject & settings);
bool wifiSetConfig(const JsonObject & settings); bool wifiSetConfig(const JsonObject & settings);
String wifiGetMacAddress(int start, const char * seperator);
#endif #endif

View File

@ -1,12 +1,11 @@
#include "hasp_conf.h" // load first #include "hasp_conf.h" // load first
#include <Arduino.h> #include <Arduino.h>
#include "hasp_conf.h"
#include "hasp_debug.h" #include "hasp_debug.h"
#include "hasp_spiffs.h"
#include "hasp_config.h" #include "hasp_config.h"
#include "hasp_gui.h" #include "hasp_gui.h"
#include "hasp.h" #include "hasp.h"
#include "hasp_conf.h"
#include "hasp_oobe.h" #include "hasp_oobe.h"
#include "hasp_gpio.h" #include "hasp_gpio.h"
@ -22,15 +21,15 @@ void setup()
***************************/ ***************************/
/* Init Storage */ /* Init Storage */
#if HASP_USE_EEPROM #if HASP_USE_EEPROM>0
// eepromSetup(); // Don't start at boot, only at write eepromSetup(); // Don't start at boot, only at write
#endif #endif
#if HASP_USE_SPIFFS #if HASP_USE_SPIFFS>0
spiffsSetup(); spiffsSetup();
#endif #endif
#if HASP_USE_SDCARD #if HASP_USE_SDCARD>0
sdcardSetup(); sdcardSetup();
#endif #endif
@ -43,41 +42,45 @@ void setup()
* Apply User Configuration * Apply User Configuration
***************************/ ***************************/
debugSetup(); debugSetup();
gpioSetup();
guiSetup();
#if HASP_USE_WIFI #if HASP_USE_GPIO>0
gpioSetup();
#endif
#if HASP_USE_WIFI>0
wifiSetup(); wifiSetup();
#endif #endif
guiSetup();
oobeSetup(); oobeSetup();
haspSetup(); haspSetup();
#if HASP_USE_WIFI #if HASP_USE_MDNS>0
#if HASP_USE_HTTP
httpSetup();
#endif
#if HASP_USE_MQTT
mqttSetup();
#endif
#if HASP_USE_TELNET
telnetSetup();
#endif
#if HASP_USE_MDNS
mdnsSetup(); mdnsSetup();
#endif #endif
#if HASP_USE_OTA #if HASP_USE_OTA>0
otaSetup(); otaSetup();
#endif #endif
#endif // WIFI #if HASP_USE_ETHERNET > 0
ethernetSetup();
#endif
#if HASP_USE_BUTTON #if HASP_USE_MQTT>0
buttonSetup(); mqttSetup();
#endif
#if HASP_USE_HTTP>0
httpSetup();
#endif
#if HASP_USE_TELNET > 0
telnetSetup();
#endif
#if HASP_USE_TASMOTA_SLAVE>0
slaveSetup();
#endif #endif
mainLastLoopTime = millis() - 1000; // reset loop counter mainLastLoopTime = millis() - 1000; // reset loop counter
@ -86,82 +89,98 @@ void setup()
void loop() void loop()
{ {
/* Storage Loops */ /* Storage Loops */
#if HASP_USE_EEPROM /*
eepromLoop(); #if HASP_USE_EEPROM>0
#endif // eepromLoop(); // Not used
// spiffsLoop(); #endif
#if HASP_USE_SDCARD
// sdcardLoop();
#endif
// configLoop(); #if HASP_USE_SPIFFS>0
// spiffsLoop(); // Not used
#endif
#if HASP_USE_SDCARD>0
// sdcardLoop(); // Not used
#endif
// configLoop(); // Not used
*/
/* Graphics Loops */ /* Graphics Loops */
// tftLoop(); // tftLoop();
guiLoop(); guiLoop();
/* Application Loops */ /* Application Loops */
// haspLoop(); // haspLoop();
debugLoop();
#if HASP_USE_GPIO>0
gpioLoop();
#endif
/* Network Services Loops */ /* Network Services Loops */
#if HASP_USE_WIFI #if HASP_USE_ETHERNET > 0
ethernetLoop();
#endif
#if HASP_USE_MQTT #if HASP_USE_MQTT>0
mqttLoop(); mqttLoop();
#endif // MQTT #endif // MQTT
#if HASP_USE_HTTP #if HASP_USE_HTTP>0
httpLoop(); httpLoop();
#endif // HTTP #endif // HTTP
#if HASP_USE_TELNET #if HASP_USE_MDNS>0
telnetLoop();
#endif // TELNET
#if HASP_USE_MDNS
mdnsLoop(); mdnsLoop();
#endif // MDNS #endif // MDNS
#if HASP_USE_BUTTON #if HASP_USE_OTA>0
buttonLoop();
#endif // BUTTON
#if HASP_USE_OTA
otaLoop(); otaLoop();
#endif // OTA #endif // OTA
#endif // WIFI #if HASP_USE_TELNET > 0
telnetLoop();
#endif // TELNET
// Every Second Loop #if HASP_USE_TASMOTA_SLAVE>0
slaveLoop();
#endif // TASMOTASLAVE
// digitalWrite(HASP_OUTPUT_PIN, digitalRead(HASP_INPUT_PIN)); // sets the LED to the button's value
/* Timer Loop */
if(millis() - mainLastLoopTime >= 1000) { if(millis() - mainLastLoopTime >= 1000) {
/* Run Every Second */ /* Run Every Second */
#if HASP_USE_OTA #if HASP_USE_OTA>0
otaEverySecond(); otaEverySecond();
#endif #endif
debugEverySecond(); debugEverySecond();
/* Run Every 5 Seconds */ /* Run Every 5 Seconds */
if(mainLoopCounter == 0 || mainLoopCounter == 4) { if(mainLoopCounter == 0 || mainLoopCounter == 5) {
#if HASP_USE_HTTP #if HASP_USE_WIFI > 0
isConnected = wifiEvery5Seconds();
#endif
#if HASP_USE_ETHERNET > 0
isConnected = ethernetEvery5Seconds();
#endif
#if HASP_USE_HTTP > 0
httpEvery5Seconds(); httpEvery5Seconds();
#endif #endif
#if HASP_USE_WIFI #if HASP_USE_MQTT > 0
isConnected = wifiEvery5Seconds();
#if HASP_USE_MQTT
mqttEvery5Seconds(isConnected); mqttEvery5Seconds(isConnected);
#endif
#endif #endif
} }
/* Update counters */ /* Reset loop counter every 10 seconds */
if(mainLoopCounter >= 9) {
mainLoopCounter = 0;
} else {
mainLoopCounter++;
}
mainLastLoopTime += 1000; mainLastLoopTime += 1000;
mainLoopCounter++;
if(mainLoopCounter >= 10) {
mainLoopCounter = 0;
}
} }
delay(3); delay(3);

View File

@ -0,0 +1,23 @@
;***************************************************;
; D1 Mini ESP32 with Lolin TFT 2.4" ;
; - D1-mini-esp32 board ;
; - ili9341 TFT ;
; - xpt2606 touch controller ;
;***************************************************;
[env:d1mini32-lolintft24]
platform = espressif32@^1.12.0
board = wemos_d1_mini32
upload_port = COM5 ; To change the port, use platform_override.ini
monitor_port = COM5 ; To change the port, use platform_override.ini
board_build.partitions = default.csv
build_flags =
${flags.esp32_flags}
; -- TFT_eSPI build options ------------------------
${lcd.lolin24}
${pins.vspi32}
-D TFT_DC=5
-D TFT_CS=26
-D TFT_RST=-1 ; RST
-D TFT_BCKL=-1 ; None, configurable via web UI (e.g. 21)
-D TOUCH_CS=17 ; (can also be 22 or 16)

View File

@ -0,0 +1,49 @@
;***************************************************;
; ESP32 build with ;
; - Wemos "TTGo" D1 R32 board ;
; - ili9486 TFT ;
;***************************************************;
[env:d132-unoshield]
platform = espressif32
board = esp32dev
upload_port = COM4 ; To change the port, use platform_override.ini
monitor_port = COM4 ; To change the port, use platform_override.ini
build_flags =
${flags.esp32_flags}
; -- TFT_eSPI build options ------------------------
-D USER_SETUP_LOADED=1
;-D ST7796_DRIVER=1 ;3.95inch Arduino Display-UNO
-D ILI9486_DRIVER=1 ;3.5inch Arduino Display-UNO
-D ESP32_PARALLEL=1
-D TFT_ROTATION=${lcd.TFT_ROTATION}
-D TFT_WIDTH=320
-D TFT_HEIGHT=480
${pins.vspi32}
-D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4)
-D TFT_CS=33 ; Chip select control pin
-D TFT_DC=15 ; Data Command control pin - must use a pin in the range 0-31
-D TFT_RST=32 ; Reset pin
-D TFT_WR=4 ; Write strobe control pin - must use a pin in the range 0-31
-D TFT_RD=2
-D TFT_D0=12 ; Must use pins in the range 0-31 for the data bus
-D TFT_D1=13 ; so a single register write sets/clears all bits
-D TFT_D2=26
-D TFT_D3=25
-D TFT_D4=17
-D TFT_D5=16
-D TFT_D6=27
-D TFT_D7=14
-D SD_CS=5
-D SPI_FREQUENCY=40000000
;-D SPI_TOUCH_FREQUENCY=2500000 ; Uses ADC instead
-D SPI_READ_FREQUENCY=20000000
; -- Debugging options -----------------------------
; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
; -- Library options -------------------------------
lib_deps =
${env.lib_deps}
src_filter = +<*> +<../drivers/stm32f429_disco>

View File

@ -0,0 +1,48 @@
;***************************************************;
; Generic ESP32 build with ;
; - ili9488 TFT SPI 4-WIRE ;
; - xpt2606 touch controller ;
;***************************************************;
[env:esp32dev-ili9488]
platform = espressif32
board = esp32dev
upload_port = COM2 ; To change the port, use platform_override.ini
monitor_port = COM2 ; To change the port, use platform_override.ini
; upload_protocol = espota ; Use ArduinoOTA after flashing over serial
; upload_port = 10.4.0.171 ; IP of the ESP
; upload_flags =
; --port=3232
debug_tool = esp-prog
debug_init_break = tbreak setup
build_flags =
${flags.esp32_flags}
; -- TFT_eSPI build options ------------------------
-D USER_SETUP_LOADED=1
-D ILI9488_DRIVER=1
-D TFT_ROTATION=0 ; 0=0, 1=90, 2=180 or 3=270 degree
-D TFT_WIDTH=320
-D TFT_HEIGHT=480
-D TFT_MISO=19 ;// (leave TFT SDO disconnected if other SPI devices share MISO)
-D TFT_MOSI=23
-D TFT_SCLK=18
-D TFT_CS=15 ;// Chip select control pin
-D TFT_DC=2 ;// Data Command control pin
-D TFT_RST=4 ;// Reset pin (could connect to RST pin)
-D TFT_BCKL=5 ;None, configurable via web UI (e.g. 2 for D4)
-D SUPPORT_TRANSACTIONS
-D TOUCH_CS=22
-D TOUCH_DRIVER=0 ; XPT2606 Resistive touch panel driver
-D SPI_FREQUENCY=27000000
-D SPI_TOUCH_FREQUENCY=2500000
-D SPI_READ_FREQUENCY=16000000
; -- Debugging options -----------------------------
; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
; -- Library options -------------------------------
lib_deps =
${env.lib_deps}
src_filter = +<*> +<../drivers/stm32f429_disco>

View File

@ -0,0 +1,46 @@
;***************************************************;
; Generic ESP32 build with ;
; - ESP32dev board ;
; - ili9488 TFT ;
; - GT911 touch controller ;
;***************************************************;
[env:esp32dev-mrb3511]
platform = espressif32
board = esp32dev
upload_port = COM1 ; To change the port, use platform_override.ini
monitor_port = COM1 ; To change the port, use platform_override.ini
debug_tool = esp-prog
debug_init_break = tbreak setup
build_flags =
${flags.esp32_flags}
; -- TFT_eSPI build options ------------------------
${lcd.mrb3511}
-D TFT_BCKL=5 ;None, configurable via web UI (e.g. 2 for D4)
-D TFT_CS=33 ; Chip select control pin
-D TFT_DC=15 ; =RS; Data Command control pin - must use a pin in the range 0-31
-D TFT_RST=32 ; Reset pin
-D TFT_WR=4 ; Write strobe control pin - must use a pin in the range 0-31
-D TFT_RD=2
-D TFT_D0=12 ; Must use pins in the range 0-31 for the data bus
-D TFT_D1=13 ; so a single register write sets/clears all bits
-D TFT_D2=26
-D TFT_D3=25
-D TFT_D4=17
-D TFT_D5=16
-D TFT_D6=27
-D TFT_D7=14
-D TOUCH_SDA=21
-D TOUCH_SCL=22
-D TOUCH_IRQ=34 ; use 34-39 as these are input only pins
-D TOUCH_RST=-1 ; not used, connected to 3.3V
; -- Debugging options -----------------------------
; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
; -- Library options -------------------------------
lib_deps =
${env.lib_deps}
https://github.com/netwizeBE/arduino-goodix.git ; GT911 touch screen driver
src_filter = +<*> +<../drivers/stm32f429_disco>

View File

@ -0,0 +1,41 @@
;***************************************************;
; ESP32 build with ;
; - ESP32Cam board ;
; - st7796 TFT ;
; - xpt2606 touch controller ;
;***************************************************;
[env:esp32cam-st7796]
platform = espressif32
board = esp32cam
; upload_port = COM18 ; To change the port, use platform_override.ini
; monitor_port = COM18 ; To change the port, use platform_override.ini
; upload_protocol = espota ; Use ArduinoOTA after flashing over serial
; upload_port = x.x.x.x; IP of the ESP
; upload_flags =
; --port=3232
debug_tool = esp-prog
debug_init_break = tbreak setup
;board_build.partitions = min_spiffs.csv
board_build.partitions = default.csv
;ESP32 CAM PINS
build_flags =
${flags.esp32_flags}
; -- TFT_eSPI build options ------------------------
${lcd.raspberrypi}
-D USE_HSPI_PORT
${pins.hspi32}
-D TFT_CS=15
-D TFT_DC=2
-D TFT_RST=-1 ; 3.3v
-D TOUCH_CS=0 ; 3 ; RX
-D TFT_BCKL=-1
; -- Debugging options -----------------------------
; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
; -- Library options -------------------------------
lib_deps =
${env.lib_deps}

View File

@ -0,0 +1,31 @@
;***************************************************;
; NodeMCU32S with build with ;
; - st7796 TFT ;
; - MHS-4" RPI Display-B ;
; - xpt2606 touch controller ;
;***************************************************;
[env:nodemcu32s-raspi]
platform = espressif32
board = nodemcu-32s
upload_port = COM3 ; To change the port, use platform_override.ini
monitor_port = COM3 ; To change the port, use platform_override.ini
debug_tool = esp-prog
debug_init_break = tbreak setup
build_flags =
${flags.esp32_flags}
; -- TFT_eSPI build options ------------------------
${lcd.raspberrypi}
${pins.vspi32}
-D TFT_CS=15
-D TFT_DC=4
-D TFT_RST=32
-D TOUCH_CS=22
; -- Debugging options -----------------------------
; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
; -- Library options -------------------------------
lib_deps =
${env.lib_deps}

View File

@ -0,0 +1,28 @@
;***************************************************;
; D1 Mini ESP8266 with Lolin TFT 2.4" ;
; - D1-mini board ;
; - ili9341 TFT ;
; - xpt2606 touch controller ;
;***************************************************;
[env:d1mini-lolintft24]
platform = espressif8266@^2.4.0 ;@2.3.2
board = d1_mini
upload_port = COM7 ; To change the port, use platform_override.ini
monitor_port = COM7 ; To change the port, use platform_override.ini
board_build.f_flash = 40000000L
board_build.flash_mode = dout
board_build.ldscript = eagle.flash.4m2m.ld ; 2Mb Spiffs
board_build.f_cpu = 160000000L ; set frequency to 160MHz
build_flags =
${flags.esp8266_flags}
; -- TFT_eSPI build options ------------------------
${lcd.lolin24}
;-D TFT_MISO=12 ;D6 Use default HSPI
;-D TFT_MOSI=13 ;D7 Use default HSPI
;-D TFT_SCLK=14 ;D5 Use default HSPI
-D TFT_DC=15 ;D8
-D TFT_CS=16 ;D0
-D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4)
-D TOUCH_CS=0 ;D3 (can also be D1 or D2)
-D TFT_RST=-1 ;RST

View File

@ -0,0 +1,38 @@
;***************************************************;
; ESP8266 build with ;
; - ESP-12 board ;
; - st7735 TFT ;
;***************************************************;
[env:esp12e-st7735]
platform = espressif8266@^2.4.0 ;@2.3.2
board = esp12e
upload_port = COM8 ; To change the port, use platform_override.ini
monitor_port = COM8 ; To change the port, use platform_override.ini
board_build.f_flash = 40000000L
board_build.flash_mode = dout
board_build.ldscript = eagle.flash.4m2m.ld ; 2Mb Spiffs
board_build.f_cpu = 160000000L ; set frequency to 160MHz
build_flags =
${flags.esp8266_flags}
; -- TFT_eSPI build options ------------------------
-D USER_SETUP_LOADED=1
-D ST7735_DRIVER=1
-D ST7735_BLACKTAB=1
-D TFT_ROTATION=${lcd.TFT_ROTATION}
-D TFT_WIDTH=128
-D TFT_HEIGHT=160
-D TFT_MISO=-1 ;NC
-D TFT_MOSI=13 ;D7
-D TFT_SCLK=14 ;D5
-D TFT_CS=15 ;D8
-D TFT_DC=0 ;D3
-D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4)
-D TOUCH_CS=-1 ;NC
-D TFT_RST=2 ;D4
-D SPI_FREQUENCY=27000000
; -- Library options -------------------------------
lib_deps =
${env.lib_deps}
;Ethernet@<2.0.0

View File

@ -0,0 +1,53 @@
;***************************************************;
; STM32F4 build with ;
; - DIY_more board ;
; - ili9341 TFT ;
; - xpt2046 touch controller ;
;***************************************************;
[env:black_f407vg]
platform = ststm32
board = diymore_f407vgt
board_build.mcu = stm32f407vgt6
upload_protocol = dfu
monitor_port = COM7 ; To change the port, use platform_override.ini
build_flags =
${env.build_flags}
${flags.stm32_flags}
-I include/stm32f4
; -- TFT_eSPI build options ------------------------
${lcd.lolin24}
;-D TFT_MISO=PB4 ;Default
;-D TFT_MOSI=PB5 ;Default
;-D TFT_SCLK=PB3 ;Default
-D TFT_CS=PE13 ;D8
-D TFT_DC=PE14 ;D3
-D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4)
-D TOUCH_CS=PA6 ;NC
-D TFT_RST=-1 ;D4
-D HASP_OUTPUT_PIN=PE0 ; User LED D2 on DevEBox board
-D HASP_INPUT_PIN=PD15 ; User Button K1 on DevEBox board
-D STM32_SERIAL1 ; Set this option to use Serial1 as default sersial port, leave out if using Serial2
;-D HAL_ETH_MODULE_ENABLED=1 ; enable ethernet support
;-D LAN8742A_PHY_ADDRESS=0x01U ; set LAN8720 PHY address
-D HASP_USE_TASMOTA_SLAVE=1
-D HASP_USE_ETHERNET=1
-D W5500_MOSI=PB15 ;SPI2 MOSI
-D W5500_MISO=PB14 ;SPI2 MISO
-D W5500_SCLK=PB13 ;SPI2 SCLK
-D W5500_CS=PB6 ;SPI2 CS
-D W5500_RST=PD1 ;SPI2 CS
lib_deps =
${env.lib_deps}
Ticker@^3.1.5
;Ethernet
; STM32duino LwIP@^2.1.2
; STM32duino STM32Ethernet@^1.0.5
https://github.com/stm32duino/LwIP.git
https://github.com/netwizeBE/Ethernet3.git
https://github.com/khoih-prog/EthernetWebServer_STM32
src_filter = +<*> -<.git/> -<.svn/> -<example/> -<examples/> -<test/> -<tests/> -<lv_lib_zifont/> +<stm32f4/>
;***************************************************

View File

@ -0,0 +1,52 @@
;***************************************************;
; STM32F4xx build with ;
; - DevEBox board ;
; - ili9341 TFT ;
; - xpt2046 touch controller ;
;***************************************************;
[env:DevEBox_STM32F4xx]
platform = ststm32
board = black_f407zg
board_build.mcu = stm32f407vgt6
; upload_protocol = dfu
upload_protocol = stlink
debug_tool = stlink
monitor_port = COM19 ; To change the port, use platform_override.ini
build_flags =
${env.build_flags}
${flags.stm32_flags}
-I include/stm32f4
; -- TFT_eSPI build options ------------------------
${lcd.lolin24}
;-D TFT_MISO=PB4 ;Default
;-D TFT_MOSI=PB5 ;Default
;-D TFT_SCLK=PB3 ;Default
-D TFT_CS=PE13 ;D8
-D TFT_DC=PE14 ;D3
-D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4)
-D TOUCH_CS=PA6 ;NC
-D TFT_RST=-1 ;D4
-D STM32
-D TFT_SPI3
-D USE_DMA_TO_TFT
-D HASP_USE_TASMOTA_SLAVE=1
-D HASP_OUTPUT_PIN=PA1 ; User LED D2 on DevEBox board
-D HASP_INPUT_PIN=PA0 ; User Button K1 on DevEBox board
-D STM32_SERIAL1 ; Set this option to use Serial1 as default sersial port, leave out if using Serial2
-D HASP_USE_ETHERNET=1
-D USE_BUILTIN_ETHERNET=1
-D HAL_ETH_MODULE_ENABLED=1
; -D LAN8742A_PHY_ADDRESS=0x01U ; moved to include\stm32f4\hal_conf_custom.h
; -D DP83848_PHY_ADDRESS=0x01U
lib_deps =
${env.lib_deps}
Ticker@^3.1.5
; STM32duino LwIP@^2.1.2
; STM32duino STM32Ethernet@^1.0.5
https://github.com/stm32duino/LwIP.git
https://github.com/stm32duino/STM32Ethernet.git
https://github.com/khoih-prog/EthernetWebServer_STM32
src_filter = +<*> -<.git/> -<.svn/> -<example/> -<examples/> -<test/> -<tests/> -<lv_lib_zifont/> +<stm32f4/>