2022-04-22 13:57:14 +08:00
# define SCREEN_WIDTH 128
# define SCREEN_HEIGHT 128
# define SCREEN_ROTATION 0
2022-04-05 20:00:26 +08:00
# define DOWNLOADED_IMG " / download.jpg"
2022-04-22 13:57:14 +08:00
// #define FULL_FONT 1
// #define CHINESE_FONT 1
2022-04-05 20:00:26 +08:00
2022-04-07 16:01:31 +08:00
# define BLK_PIN 19
# define BTN_PIN 0
2022-04-05 22:08:37 +08:00
# include <WiFiManager.h>
2022-04-05 20:00:26 +08:00
# include <EspMQTTClient.h>
2022-04-07 16:01:31 +08:00
# include <ArduinoJson.h>
# include <Effortless_SPIFFS.h>
2022-04-05 20:00:26 +08:00
2022-04-05 22:08:37 +08:00
WiFiManager wm ;
WiFiManagerParameter mqtt_host_field ;
WiFiManagerParameter mqtt_port_field ;
WiFiManagerParameter mqtt_topic_field ;
WiFiManagerParameter mqtt_client_field ;
WiFiManagerParameter mqtt_user_field ;
WiFiManagerParameter mqtt_password_field ;
String mqtt_host_value = " " ;
short mqtt_port_value = 1883 ;
String mqtt_client_postfix = " " ;
String mqtt_topic_value = " " ;
String mqtt_user_value = " " ;
String mqtt_client_value = " " ;
String mqtt_password_value = " " ;
//EspMQTTClient mclient(
// WIFI_SSID,
// WIFI_PASSWORD,
// MQTT_IP,
// MQTT_USER,
// MQTT_PASSWORD,
// MQTT_CLIENT_NAME,
// MQTT_PORT
//);
EspMQTTClient mclient ;
2022-04-05 20:00:26 +08:00
2022-04-22 13:57:14 +08:00
# ifdef CHINESE_FONT
# ifdef FULL_FONT
# define AA_FONT_CUBIC "Cubic1112"
# else
# include "cubic_12.h"
# endif
# endif
2022-04-22 01:54:15 +08:00
2022-04-07 18:15:52 +08:00
2022-04-05 20:00:26 +08:00
// #include "SPI.h"
# include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI ( ) ;
2022-04-07 16:01:31 +08:00
# include <NTPClient.h>
2022-04-05 20:00:26 +08:00
# ifdef ESP8266
# include <ESP8266HTTPClient.h>
# define BEEP_PIN D8
# define IMG_SCALE 2
# define TXT_SCALE 2
# else
# include "SPIFFS.h" // Required for ESP32 only
# define IMG_SCALE 2
# define TXT_SCALE 2
# define BEEP_PIN 22
# include <HTTPClient.h>
# endif
# include <TJpg_Decoder.h>
2022-04-07 18:15:52 +08:00
# include <EasyButton.h>
EasyButton clearbtn ( BTN_PIN ) ;
2022-04-05 20:00:26 +08:00
2022-04-07 16:01:31 +08:00
# include <WiFiUdp.h>
WiFiUDP ntpUDP ;
NTPClient timeClient ( ntpUDP , " ntp1.aliyun.com " , 60 * 60 * 8 , 60000 ) ;
//flag for saving data
bool shouldSaveConfig = false ;
//callback notifying us of the need to save config
void saveConfigCallback ( ) {
Serial . println ( " Should save config " ) ;
shouldSaveConfig = true ;
}
DynamicJsonDocument jsonDocument ( 1024 ) ;
2022-04-05 20:00:26 +08:00
void setup ( ) {
Serial . begin ( 115200 ) ;
mclient . enableDebuggingMessages ( ) ;
2022-04-07 18:15:52 +08:00
clearbtn . begin ( ) ;
clearbtn . onPressed ( clear_config ) ;
2022-04-05 20:00:26 +08:00
tft . begin ( ) ;
2022-04-07 16:01:31 +08:00
pinMode ( BLK_PIN , OUTPUT ) ;
digitalWrite ( BLK_PIN , HIGH ) ;
2022-04-07 18:15:52 +08:00
// tft.setRotation(2); // 屏幕方向
2022-04-05 20:00:26 +08:00
tft . fillScreen ( TFT_BLACK ) ;
tft . setTextColor ( 0xFFFF , 0x0000 ) ; tft . setCursor ( 0 , 0 , 1 ) ; tft . setTextSize ( TXT_SCALE ) ; tft . println ( " Init ... " ) ;
Serial . println ( " tft init " ) ;
if ( ! SPIFFS . begin ( ) ) {
Serial . println ( " SPIFFS initialisation failed! " ) ;
while ( 1 ) yield ( ) ; // Stay here twiddling thumbs waiting
}
Serial . println ( " SPIFFS init " ) ;
2022-04-07 16:01:31 +08:00
eSPIFFS fileSystem ;
// Check Flash Size - Always try to incorrperate a check when not debugging to know if you have set the SPIFFS correctly
if ( ! fileSystem . checkFlashConfig ( ) ) {
Serial . println ( " Flash size was not correct! Please check your SPIFFS config and try again " ) ;
delay ( 100000 ) ;
ESP . restart ( ) ;
}
2022-04-05 20:00:26 +08:00
TJpgDec . setJpgScale ( IMG_SCALE ) ;
TJpgDec . setSwapBytes ( true ) ;
TJpgDec . setCallback ( tft_output ) ;
Serial . println ( " TJpgDec init " ) ;
2022-04-05 22:08:37 +08:00
2022-04-07 16:01:31 +08:00
// 检测本地配置文件
if ( SPIFFS . exists ( " /config.json " ) )
{
2022-04-22 13:57:14 +08:00
Serial . println ( " config.json exist " ) ;
2022-04-07 16:01:31 +08:00
fileSystem . openFromFile ( " /config.json " , jsonDocument ) ;
Serial . print ( " JSON Document is: " ) ;
serializeJson ( jsonDocument , Serial ) ;
Serial . println ( ) ;
Serial . println ( jsonDocument [ " wifi_ssid " ] . as < String > ( ) ) ;
Serial . println ( jsonDocument [ " wifi_password " ] . as < String > ( ) ) ;
// 链接wifi
WiFi . begin ( jsonDocument [ " wifi_ssid " ] . as < const char * > ( ) , jsonDocument [ " wifi_password " ] . as < const char * > ( ) ) ;
mqtt_host_value = jsonDocument [ " mqtt_host " ] . as < String > ( ) ;
mqtt_port_value = jsonDocument [ " mqtt_port " ] . as < short > ( ) ;
mqtt_user_value = jsonDocument [ " mqtt_user " ] . as < String > ( ) ;
mqtt_password_value = jsonDocument [ " mqtt_password " ] . as < String > ( ) ;
mqtt_topic_value = jsonDocument [ " mqtt_topic " ] . as < String > ( ) ;
mqtt_client_value = jsonDocument [ " mqtt_client " ] . as < String > ( ) ;
} else
{
2022-04-22 13:57:14 +08:00
Serial . println ( " config.json not exist " ) ;
2022-04-07 16:01:31 +08:00
tft . fillScreen ( TFT_BLACK ) ;
tft . setCursor ( 0 , 0 , 1 ) ;
tft . println ( " Connect to DeerEspWiFi, go 192.168.4.1 " ) ;
2022-04-05 22:08:37 +08:00
2022-04-07 16:01:31 +08:00
WiFi . mode ( WIFI_STA ) ;
wm . resetSettings ( ) ;
2022-04-05 22:08:37 +08:00
2022-04-07 16:01:31 +08:00
// add a custom input field
int customFieldLength = 40 ;
new ( & mqtt_host_field ) WiFiManagerParameter ( " mqtt_host " , " MQTT IP " , " broker.emqx.io " , customFieldLength , " placeholder= \" MQTT server IP \" " ) ;
new ( & mqtt_port_field ) WiFiManagerParameter ( " mqtt_port " , " MQTT Port " , " 1883 " , customFieldLength , " placeholder= \" MQTT server port, 1883 as default \" " ) ;
new ( & mqtt_topic_field ) WiFiManagerParameter ( " mqtt_topic " , " MQTT Topic " , " LB2312 " , customFieldLength , " placeholder= \" MQTT base topic \" " ) ;
new ( & mqtt_client_field ) WiFiManagerParameter ( " mqtt_client " , " MQTT Client ID " , " DeerESP0001 " , customFieldLength , " placeholder= \" MQTT client id, can be empty \" " ) ;
new ( & mqtt_user_field ) WiFiManagerParameter ( " mqtt_user " , " MQTT User " , " " , customFieldLength , " placeholder= \" MQTT user, can be empty \" " ) ;
new ( & mqtt_password_field ) WiFiManagerParameter ( " mqtt_password " , " MQTT Password " , " " , customFieldLength , " placeholder= \" MQTT password, can be empty \" " ) ;
wm . addParameter ( & mqtt_host_field ) ;
wm . addParameter ( & mqtt_port_field ) ;
wm . addParameter ( & mqtt_topic_field ) ;
wm . addParameter ( & mqtt_client_field ) ;
wm . addParameter ( & mqtt_user_field ) ;
wm . addParameter ( & mqtt_password_field ) ;
wm . setSaveParamsCallback ( saveParamCallback ) ;
wm . setSaveConfigCallback ( saveConfigCallback ) ;
bool res ;
res = wm . autoConnect ( " DeerEspWiFi " ) ; // anonymous ap
2022-04-05 22:08:37 +08:00
2022-04-07 16:01:31 +08:00
if ( ! res ) {
Serial . println ( " Failed to connect " ) ;
ESP . restart ( ) ;
}
else {
//if you get here you have connected to the WiFi
Serial . println ( " connected...yeey :) " ) ;
}
2022-04-05 22:08:37 +08:00
2022-04-07 16:01:31 +08:00
}
2022-04-05 22:08:37 +08:00
2022-04-07 16:01:31 +08:00
2022-04-05 22:08:37 +08:00
mclient . enableDebuggingMessages ( true ) ;
mclient . setMqttClientName ( mqtt_client_value . c_str ( ) ) ;
mclient . setMqttServer ( mqtt_host_value . c_str ( ) , mqtt_user_value . c_str ( ) , mqtt_password_value . c_str ( ) , mqtt_port_value ) ;
2022-04-07 16:01:31 +08:00
if ( shouldSaveConfig )
{
jsonDocument [ " mqtt_host " ] = mqtt_host_value ;
jsonDocument [ " mqtt_port " ] = mqtt_port_value ;
jsonDocument [ " mqtt_user " ] = mqtt_user_value ;
jsonDocument [ " mqtt_password " ] = mqtt_password_value ;
jsonDocument [ " mqtt_topic " ] = mqtt_topic_value ;
jsonDocument [ " mqtt_client " ] = mqtt_client_value ;
jsonDocument [ " wifi_ssid " ] = WiFi . SSID ( ) ;
jsonDocument [ " wifi_password " ] = WiFi . psk ( ) ;
fileSystem . saveToFile ( " /config.json " , jsonDocument ) ;
Serial . print ( " JSON Document is: " ) ;
serializeJson ( jsonDocument , Serial ) ;
Serial . println ( ) ;
2022-04-22 13:57:14 +08:00
if ( SPIFFS . exists ( " /config.json " ) ) Serial . print ( " config.json exists " ) ;
else Serial . print ( " config.json not exists " ) ;
// File root = SPIFFS.open("/","r");
2022-04-07 16:01:31 +08:00
//
// File file = root.openNextFile();
//
// while(file){
//
// Serial.print("FILE: ");
// Serial.println(file.name());
//
// file = root.openNextFile();
// }
}
2022-04-05 22:08:37 +08:00
2022-04-05 20:00:26 +08:00
}
2022-04-05 22:08:37 +08:00
String getParam ( String name ) {
//read parameter from server, for customhmtl input
String value ;
if ( wm . server - > hasArg ( name ) ) {
value = wm . server - > arg ( name ) ;
}
return value ;
}
void saveParamCallback ( ) {
mqtt_host_value = getParam ( " mqtt_host " ) ;
mqtt_user_value = getParam ( " mqtt_user " ) ;
mqtt_password_value = getParam ( " mqtt_password " ) ;
mqtt_topic_value = getParam ( " mqtt_topic " ) ;
mqtt_client_value = getParam ( " mqtt_client " ) ;
mqtt_port_value = getParam ( " mqtt_port " ) . toInt ( ) ;
Serial . println ( String ( mqtt_port_value ) ) ;
if ( mqtt_port_value < 1 ) mqtt_port_value = 1883 ;
Serial . println ( " [CALLBACK] saveParamCallback fired " ) ;
}
2022-04-05 20:00:26 +08:00
void onConnectionEstablished ( )
{
Serial . println ( " connected " ) ;
2022-04-22 13:57:14 +08:00
tft . fillScreen ( TFT_BLACK ) ; tft . setTextColor ( 0xFFFF , 0x0000 ) ; tft . setCursor ( 0 , 0 , 1 ) ; tft . println ( " Waiting for messages at " + mqtt_topic_value + " ... " ) ;
2022-04-05 20:00:26 +08:00
2022-04-05 22:08:37 +08:00
mclient . subscribe ( mqtt_topic_value + " _text " , [ ] ( const String & payload )
2022-04-05 20:00:26 +08:00
{
Serial . println ( payload ) ;
if ( SPIFFS . exists ( DOWNLOADED_IMG ) = = true ) TJpgDec . drawFsJpg ( 0 , 0 , DOWNLOADED_IMG ) ;
else tft . fillScreen ( TFT_BLACK ) ;
2022-04-22 13:57:14 +08:00
# ifdef CHINESE_FONT
# ifdef FULL_FONT
tft . loadFont ( AA_FONT_CUBIC ) ;
# else
tft . loadFont ( cubic_11 ) ;
# endif
2022-04-07 18:15:52 +08:00
# endif
2022-04-05 20:00:26 +08:00
if ( payload . length ( ) > 80 ) tft . setTextSize ( TXT_SCALE / 2 ) ;
else tft . setTextSize ( TXT_SCALE ) ;
char * found ;
short line = 0 ;
int base = 5 ;
int now_base = 0 ;
char * payloads = const_cast < char * > ( payload . c_str ( ) ) ;
while ( ( found = strsep ( & payloads , " \n " ) ) ! = NULL )
{
now_base = base + line * 14 ;
tft . setTextColor ( 0x0000 ) ; tft . setCursor ( base + 1 , now_base + 1 ) ; tft . println ( found ) ;
tft . setTextColor ( 0xFFFF ) ; tft . setCursor ( base , now_base ) ; tft . println ( found ) ;
line + + ;
}
2022-04-22 13:57:14 +08:00
# ifdef CHINESE_FONT
tft . unloadFont ( ) ;
# endif
2022-04-05 20:00:26 +08:00
2022-04-07 16:01:31 +08:00
show_time ( true ) ;
2022-04-05 20:00:26 +08:00
# ifdef BEEP_PIN
if ( payload . indexOf ( " ♪ " ) > = 0 ) tone ( BEEP_PIN , 1000 , 100 ) ;
# endif
} ) ;
2022-04-05 22:08:37 +08:00
mclient . subscribe ( mqtt_topic_value + " _bg_url " , [ ] ( const String & payload )
2022-04-05 20:00:26 +08:00
{
Serial . println ( payload ) ;
bool ret = file_put_contents ( payload , DOWNLOADED_IMG ) ;
if ( SPIFFS . exists ( DOWNLOADED_IMG ) = = true ) {
TJpgDec . drawFsJpg ( 0 , 0 , DOWNLOADED_IMG ) ;
2022-04-07 16:01:31 +08:00
show_time ( true ) ;
2022-04-05 20:00:26 +08:00
}
} ) ;
}
2022-04-07 16:01:31 +08:00
String lastTime = " 2020 " ;
String newTime = " " ;
2022-04-05 20:00:26 +08:00
void loop ( ) {
mclient . loop ( ) ;
2022-04-07 16:01:31 +08:00
show_time ( false ) ;
2022-04-07 18:15:52 +08:00
clearbtn . read ( ) ;
}
void clear_config ( )
{
2022-04-07 16:01:31 +08:00
SPIFFS . remove ( " /config.json " ) ;
2022-04-07 18:15:52 +08:00
tone ( BEEP_PIN , 1000 , 100 ) ;
2022-04-07 16:01:31 +08:00
}
void show_time ( bool force )
{
timeClient . update ( ) ;
2022-04-07 23:41:53 +08:00
String hourStr = timeClient . getHours ( ) < 10 ? " 0 " + String ( timeClient . getHours ( ) ) : String ( timeClient . getHours ( ) ) ;
String minStr = timeClient . getMinutes ( ) < 10 ? " 0 " + String ( timeClient . getMinutes ( ) ) : String ( timeClient . getMinutes ( ) ) ;
newTime = hourStr + " : " + minStr ;
2022-04-07 16:01:31 +08:00
if ( lastTime ! = newTime )
{
echo_time ( newTime ) ;
lastTime = newTime ;
}
else
{
if ( force ) echo_time ( newTime ) ;
}
}
void echo_time ( String thetime )
{
2022-04-22 13:57:14 +08:00
if ( SCREEN_WIDTH = = 128 )
{
tft . setCursor ( 96 , 120 , 1 ) ;
tft . setTextSize ( 1 ) ;
}
if ( SCREEN_WIDTH = = 240 )
{
tft . setCursor ( 180 , 210 , 1 ) ;
tft . setTextSize ( 2 ) ;
}
2022-04-07 16:01:31 +08:00
tft . setTextColor ( TFT_WHITE , TFT_BLACK ) ;
tft . println ( thetime ) ;
tft . setTextSize ( TXT_SCALE ) ;
2022-04-05 20:00:26 +08:00
}
bool file_put_contents ( String url , String filename ) {
Serial . println ( " Downloading " + filename + " from " + url ) ;
// Check WiFi connection
if ( WiFi . status ( ) = = WL_CONNECTED ) {
Serial . print ( " [HTTP] begin... \n " ) ;
WiFiClient client ;
HTTPClient http ;
http . setFollowRedirects ( HTTPC_STRICT_FOLLOW_REDIRECTS ) ;
http . begin ( client , url ) ;
Serial . print ( " [HTTP] GET... \n " ) ;
int httpCode = http . GET ( ) ;
if ( httpCode > 0 ) {
fs : : File f = SPIFFS . open ( filename , " w+ " ) ;
if ( ! f ) {
Serial . println ( " file open failed " ) ;
return 0 ;
}
Serial . printf ( " [HTTP] GET... code: %d \n " , httpCode ) ;
if ( httpCode = = HTTP_CODE_OK ) {
int total = http . getSize ( ) ;
int len = total ;
uint8_t buff [ 128 ] = { 0 } ;
WiFiClient * stream = http . getStreamPtr ( ) ;
while ( http . connected ( ) & & ( len > 0 | | len = = - 1 ) ) {
size_t size = stream - > available ( ) ;
if ( size ) {
int c = stream - > readBytes ( buff , ( ( size > sizeof ( buff ) ) ? sizeof ( buff ) : size ) ) ;
f . write ( buff , c ) ;
if ( len > 0 ) {
len - = c ;
}
}
yield ( ) ;
}
Serial . println ( ) ;
Serial . print ( " [HTTP] connection closed or file end. \n " ) ;
}
f . close ( ) ;
}
else {
Serial . printf ( " [HTTP] GET... failed, error: %s \n " , http . errorToString ( httpCode ) . c_str ( ) ) ;
Serial . print ( httpCode ) ;
}
http . end ( ) ;
}
return 1 ;
}
bool tft_output ( int16_t x , int16_t y , uint16_t w , uint16_t h , uint16_t * bitmap )
{
if ( y > = tft . height ( ) ) return 0 ;
tft . pushImage ( x , y , w , h , bitmap ) ;
return 1 ;
}
# ifdef ESP32
void tone ( byte pin , int freq , int timeout ) {
ledcSetup ( 0 , 2000 , 8 ) ; // setup beeper
ledcAttachPin ( pin , 0 ) ; // attach beeper
ledcWriteTone ( 0 , freq ) ; // play tone
delay ( timeout ) ;
ledcWriteTone ( 0 , 0 ) ;
}
# endif