W bibliotece TFT_eSPI należy prze edytować plik User_Setup.h w którym definiujemy jaki mamy wyświetlacz i z jakich GPIO skorzystaliśmy. U mnie wygląda to tak:
Code: Select all
#define ILI9341_DRIVER // Generic driver for common displays
// ###### EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR ESP8266 SETUP ######
// For NodeMCU - use pin numbers in the form PIN_Dx where Dx is the NodeMCU pin designation
#define TFT_MISO PIN_D6 // Automatically assigned with ESP8266 if not defined
#define TFT_MOSI PIN_D7 // Automatically assigned with ESP8266 if not defined
#define TFT_SCLK PIN_D5 // Automatically assigned with ESP8266 if not defined
#define TFT_CS PIN_D2 // Chip select control pin D8 bylo d2
#define TFT_DC PIN_D4 // Data Command control pin
#define TFT_RST PIN_D0 // Reset pin (could connect to NodeMCU RST, see next line)
//#define TFT_RST -1 // Set TFT_RST to -1 if the display RESET is connected to NodeMCU RST or 3.3V
//Piny miso, mosi i sclk równolegle - mostki z wyświetlaczem, tylko CS na osobnym GPIO
#define TOUCH_CS PIN_D3 // Chip select pin (T_CS) of touch screen
//Zakomentowałem część czcionek aby zaoszczędzić pamięci
//#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
//#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
//#define SMOOTH_FONT
//to było domyślnie
#define SPI_FREQUENCY 27000000
#define SPI_TOUCH_FREQUENCY 2500000
Code: Select all
#include <LittleFS.h>
#include <TFT_eSPI.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>
#include "grafika.h"
#define CALIBRATION_FILE "/TouchCalData1"
#define REPEAT_CAL false
TFT_eSPI tft = TFT_eSPI(); // Invoke library
char in_message[100];
// Wi-Fi settings
const char* ssid = "wifi";
const char* password = "wifi pass";
// MQTT broker settings
const char* mqttServer = "mqtt41.supla.org";
const int mqttPort = 8883; // MQTT over SSL/TLS default port
// MQTT authentication
const char* mqttUsername = "jusernejm z mqtt supli";
const char* mqttPassword = "pasłord z mqtt supli";
// Tematy MQTT z supli
String top1="supla/91----------------------------fd/devices/54x2/channels/11587/state/temperature";//Temperatura dom
String top2="supla/91----------------------------fd/devices/51x4/channels/10770/state/depth";//Poziom peletu
String top3="supla/91----------------------------fd/devices/51x4/channels/10765/state/temperature";//Temperatura kotla
String top4="supla/91----------------------------fd/devices/52x8/channels/11081/state/phases/1/power_active";//Moc kotła
String top5="supla/91----------------------------fd/devices/53x2/channels/11388/state/phases/1/voltage";//Napiecie sieci
String top6="supla/91----------------------------fd/devices/53x2/channels/11388/state/total_cost";//złotówki za kwh
// Create an instance of WiFiClientSecure
WiFiClientSecure wifiClient;
// Create an instance of PubSubClient
PubSubClient mqttClient(wifiClient);
//różne zmienne do kombinowania
unsigned long PrevMillis=0;
unsigned long PrevTouchTime=0;
bool fstRun=true;
volatile float r;
int his=0;
int Scr=0;
String tempDom;
String poziomPeletu, tmpPoziomPeletu;
String tempKotla;
String mocKotla;
String napiecie, napiecieTmp;
String koszty;
void setup()
{
Serial.begin(115200);
tft.begin(); // Initialise the display
tft.fillScreen(0x068a); // Screen fill
tft.setRotation(1); // landscape
tft.setSwapBytes(true);
// Calibrate the touch screen and retrieve the scaling factors
//touch_calibrate(); //przy pierwszym uruchomieniu
uint16_t calData[5] = { 361, 3521, 152, 3691, 7 }; //rotation 1
tft.setTouch(calData);
tft.pushImage(77, 77, supla2w, supla2h, supla2); //zielone logo na środku
tft.setTextColor(TFT_BLACK);
tft.setTextSize(1);
tft.drawString("Connecting ...", 230, 220, 2);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi!");
// Configure MQTT server and set SSL/TLS options
mqttClient.setServer(mqttServer, mqttPort);
mqttClient.setCallback(callback);
// Ustawnia niezabezpieczone połączenie
wifiClient.setInsecure();
// Connect to MQTT broker
connectToMqtt();
delay (1000);
}
void loop()
{
if (!mqttClient.connected()) {
// If MQTT connection is lost, try to reconnect
reconnect();
}
mqttClient.loop();
uint16_t x = 0, y = 0; // To store the touch coordinates
// Pressed will be set true is there is a valid touch on the screen
bool pressed = tft.getTouch(&x, &y);
// Draw a white spot at the detected coordinates
if (pressed and (millis()-PrevTouchTime>250)) {
Serial.print("Touch x,y = ");
Serial.print(x);
Serial.print(",");
Serial.print(y);
Serial.println("");
//wyznacza 80pix strefy dotyku
if (((x > 240) && (y > 1)) && ((x < 320) && (y < 240))) {
tft.fillCircle(x, y, 20, TFT_BROWN);
fstRun=true;// zeruje zmienną ustawijącą ekran
Scr++;
if (Scr>3)Scr=0;
}
if (((x > 1) && (y > 1)) && ((x < 80) && (y < 240))) {
tft.fillCircle(x, y, 20, TFT_BROWN);
fstRun=true;// zeruje zmienną ustawijącą ekran
Scr--;
if (Scr<0)Scr=3;
}
}//koniec pressed
//opóżnienie aby przy dotyku zbyt szybko nie przełączało ekranów
if (pressed){PrevTouchTime=millis();}
if(millis()-PrevMillis > 500){
PrevMillis=millis();
switch(Scr) {
case 0:
ScrZbiorczy1();
break;
case 1:
ScrPoziom();
break;
case 2:
ScrPiec();
break;
case 3:
ScrTxt();
break;
default:
ScrZbiorczy1();
}//koniec switch
}//koniec millis
}//koniec loop
//--------------------------------------------------------------
// E K R A N Y
//--------------------------------------------------------------
void ScrTxt(){
if (fstRun==true){
tft.fillScreen(0x068a); // Wyczyść ekran
tft.pushImage(250, 5, logow, logoh, logo);
tft.setTextColor(TFT_BLACK,0x068a);
fstRun=false;
}
tft.setTextSize(1);
tft.drawString("Moc piec: ", 10, 90, 4);
tft.drawString(moc()+" W ", 195, 90, 4);//dodatkowe spacje na końcu wymazują pozostałości przy dużej zmianie wartości...
tft.drawString("Napięcie sieci: ", 10, 130, 4);
tft.drawString(napiecieCnv()+" V ", 195, 130, 4);
tft.drawString("Koszty energii: ", 10, 170, 4);
tft.drawString(koszty+"zl ", 195, 170, 4);
}
//--------------------------------------------------------------
void ScrPiec (){
if (fstRun==true){
tft.fillScreen(TFT_WHITE);
tft.pushImage(32, 48, piecw, piech, piec);
fstRun=false;
}
tft.setTextSize(1);
tft.setTextColor(TFT_BLACK);
tft.drawString("Poziom pelletu % ", 10, 10, 4);
tft.setTextColor(TFT_RED,0xce79);//dla esp8266 sprait zjada za dużo RAMu
tft.drawString(poziom(), 195, 150, 7);
}
//--------------------------------------------------------------
void ScrPoziom(){
if (fstRun==true){
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.pushImage(250, 5, logow, logoh, logo, 0x068a);
fstRun=false;
}
tft.setTextSize(1);
tft.setTextColor(TFT_YELLOW);
tft.drawString("Poziom pelletu % ", 10, 10, 4);
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.setTextSize(2);
tft.drawString(poziom(), 90, 80, 7);
}
//--------------------------------------------------------------
void ScrZbiorczy1(){
if (fstRun==true){
tft.fillScreen(0x068a); // Wyczyść ekran
tft.pushImage(250, 5, logow, logoh, logo);
tft.setTextColor(TFT_BLACK);
tft.setTextSize(1);
tft.drawString("Temperatury:", 10, 50, 4);
tft.drawLine(200, 90, 200, 152, TFT_WHITE);
tft.drawString("Dom:", 10, 90, 4);
tft.drawLine(5, 118, tft.width() - 5, 118, TFT_WHITE);
tft.drawString("Piec:", 10, 125, 4);
tft.drawLine(5, 152, tft.width() - 5, 152, TFT_WHITE);
fstRun=false;
}
tft.setTextColor(TFT_BLACK, 0x068a);
r=atof(tempDom.c_str());
r=round(r*10)/10;
tempDom=String(r);
tempDom.remove(tempDom.length()-1);
tft.drawString(tempDom+"`C", 230, 90, 4);
r=atof(tempKotla.c_str());
r=round(r*10)/10;
tempKotla=String(r);
tempKotla.remove(tempKotla.length()-1);
tft.drawString(tempKotla+"`C", 230, 125, 4);
}
//--------------------------------------------------------------
String poziom(){
r=poziomPeletu.toFloat();
r=r*100;
//map(value, fromLow, fromHigh, toLow, toHigh)
int l= map(r, 10 , 110, 99, 0);//dwie liczby max
if (l >= 99) l=99;
tmpPoziomPeletu=String(l);
return tmpPoziomPeletu;
}
//--------------------------------------------------------------
String moc(){
r=atof(mocKotla.c_str());
mocKotla=String(r);
mocKotla.remove(mocKotla.length()-1);
return mocKotla;
}
//--------------------------------------------------------------
String napiecieCnv(){
napiecieTmp=napiecie;
napiecieTmp.remove(napiecieTmp.length()-3);
return napiecieTmp;
}
//--------------------------------------------------------------
void connectToMqtt() {
// Loop until connected to MQTT broker
while (!mqttClient.connected()) {
Serial.println("Connecting to MQTT server...");
if (mqttClient.connect("RaNd0Mbi", mqttUsername, mqttPassword)) {// !!!RaNd0Mbit -losowy ciąg 8 znakow
Serial.println("Connected to MQTT server!");
//subskrybuje tematy z mqtt
mqttClient.subscribe(top1.c_str());// Temperatura dom
mqttClient.subscribe(top2.c_str());// Poziom pelletu
mqttClient.subscribe(top3.c_str());// Temperatura kotła
mqttClient.subscribe(top4.c_str());// Moc kotła
mqttClient.subscribe(top5.c_str());// Napięcie
mqttClient.subscribe(top6.c_str());// Koszty
} else {
Serial.print("Failed to connect to MQTT server. Retrying in 5 seconds...");
delay(5000);
}
}
}
//--------------------------------------------------------------
void reconnect() {
// Disconnect if already connected
if (mqttClient.connected()) {
mqttClient.disconnect();
}
// Attempt to reconnect
connectToMqtt();
}
//--------------------------------------------------------------
void callback(char* topic, byte* payload, unsigned int length) {
// Handle MQTT subscription messages, if needed
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("]\n ");
if (strcmp(topic,top1.c_str())==0){
payload[length] = '\0';
tempDom=String((char*)payload);
}
if (strcmp(topic,top2.c_str())==0){
payload[length] = '\0';
poziomPeletu=String((char*)payload);
}
if (strcmp(topic,top3.c_str())==0){
payload[length] = '\0';
tempKotla=String((char*)payload);
}
if (strcmp(topic,top4.c_str())==0){
payload[length] = '\0';
mocKotla=String((char*)payload);
}
if (strcmp(topic,top5.c_str())==0){
payload[length] = '\0';
napiecie=String((char*)payload);
}
if (strcmp(topic,top6.c_str())==0){
payload[length] = '\0';
koszty=String((char*)payload);
}
}//koniec callback
void touch_calibrate()
{
uint16_t calData[5];
uint8_t calDataOK = 0;
// check file system exists
if (!LittleFS.begin()) {
Serial.println("Formating file system");
LittleFS.format();
LittleFS.begin();
}
// check if calibration file exists and size is correct
if (LittleFS.exists(CALIBRATION_FILE)) {
if (REPEAT_CAL)
{
// Delete if we want to re-calibrate
LittleFS.remove(CALIBRATION_FILE);
}
else
{
File f = LittleFS.open(CALIBRATION_FILE, "r");
if (f) {
if (f.readBytes((char *)calData, 14) == 14)
calDataOK = 1;
f.close();
}
}
}
if (calDataOK && !REPEAT_CAL) {
// calibration data valid
tft.setTouch(calData);
} else {
// data not valid so recalibrate
tft.fillScreen(TFT_BLACK);
tft.setCursor(20, 0);
tft.setTextFont(2);
tft.setTextSize(1);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.println("Touch corners as indicated");
tft.setTextFont(1);
tft.println();
if (REPEAT_CAL) {
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.println("Set REPEAT_CAL to false to stop this running again!");
}
tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15);
Serial.println(); Serial.println();
Serial.println("// Use this calibration code in setup():");
Serial.print(" uint16_t calData[5] = ");
Serial.print("{ ");
for (uint8_t i = 0; i < 5; i++)
{
Serial.print(calData[i]);
if (i < 4) Serial.print(", ");
}
Serial.println(" };");
Serial.print(" tft.setTouch(calData);");
Serial.println(); Serial.println();
tft.setTextColor(TFT_GREEN, TFT_BLACK);
tft.println("Calibration complete!");
// store data
File f = LittleFS.open(CALIBRATION_FILE, "w");
if (f) {
f.write((const unsigned char *)calData, 14);
f.close();
}
}
}//koniec calibracja dotyku
Jednak należy mieć na uwadzę że pamięć ESP8266 jest mało pojemna i nie można poszaleć. Samo połaczenie z MQTT zjada dużo zasobów i nie można poszaleć z sprite-ami...
Zdaje sobię sprawę że powyższe pozostawia wiele do życzenia ale może posłużyć jak baza to dalszej zabawy, zwłaszcza że MQTT daje dostęp do każdej zmiennej jaką widzimy w apce i można sobie to dowolnie układać na ekranie, obrabiać ico tam fantazja podpowie i RAM pozwoli. Mi najbardziej zależało na wyświetleniu poziomu pelletu w zasobniku, czujnik vl53l0x z innego użądzenia w supli pokazuje tylko odległość a tak mam ładną wizualizację która sobie pewnie jeszcze jakoś ubajeruję jak tylko coś fajnego mi wpadnie na myśl
Link do filmiu z działania, kolor na żywo są fajniejsze https://drive.google.com/file/d/1Fhr0Nv ... sp=sharing Wszytskie wyświetlone wartości zmieniają się dokładnie tak jak w apce choć na krótkim filmie tego może tak nie widać...