Kod: Zaznacz cały
#include <ESP8266WiFi.h>
#include <Ticker.h>
#include <JsonListener.h>
#include "SSD1306Wire.h"
#include "OLEDDisplayUi.h"
#include "Wire.h"
#include "WundergroundClient.h"
#include "WeatherStationFonts.h"
#include "WeatherStationImages.h"
#include "TimeClient.h"
#include "ThingspeakClient.h"
/***************************
* Begin Settings
**************************/
// WIFI
const char* WIFI_SSID = "";
const char* WIFI_PWD = "";
// Setup
const int UPDATE_INTERVAL_SECS = 10 * 60; // Update every 10 minutes
// Display Settings
const int I2C_DISPLAY_ADDRESS = 0x3c;
const int SDA_PIN = D6;
const int SDC_PIN = D5;
// TimeClient settings
const float UTC_OFFSET = 2;
// Wunderground Settings
const boolean IS_METRIC = true;
const String WUNDERGRROUND_API_KEY = "";
const String WUNDERGRROUND_LANGUAGE = "PL";
const String WUNDERGROUND_COUNTRY = "PL";
const String WUNDERGROUND_CITY = "Bilgoraj";
//Thingspeak Settings
const String THINGSPEAK_CHANNEL_ID = "271134";
const String THINGSPEAK_API_READ_KEY = "";
// Initialize the oled display for address 0x3c
// sda-pin=14 and sdc-pin=12
SSD1306Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN);
OLEDDisplayUi ui( &display );
/***************************
* End Settings
**************************/
TimeClient timeClient(UTC_OFFSET);
// Set to false, if you prefere imperial/inches, Fahrenheit
WundergroundClient wunderground(IS_METRIC);
ThingspeakClient thingspeak;
// flag changed in the ticker function every 10 minutes
bool readyForWeatherUpdate = false;
String lastUpdate = "--";
Ticker ticker;
//declaring prototypes
void drawProgress(OLEDDisplay *display, int percentage, String label);
void updateData(OLEDDisplay *display);
void drawDateTime(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
void drawCurrentWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
void drawForecast(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
void drawThingspeak(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex);
void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state);
void setReadyForWeatherUpdate();
// Add frames
// this array keeps function pointers to all frames
// frames are the single views that slide from right to left
FrameCallback frames[] = { drawDateTime, drawCurrentWeather, drawForecast, drawThingspeak };
int numberOfFrames = 4;
OverlayCallback overlays[] = { drawHeaderOverlay };
int numberOfOverlays = 1;
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println();
// initialize dispaly
display.init();
display.clear();
display.display();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.setContrast(255);
WiFi.begin(WIFI_SSID, WIFI_PWD);
int counter = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
display.clear();
display.drawString(64, 10, "Connecting to WiFi");
display.drawXbm(46, 30, 8, 8, counter % 3 == 0 ? activeSymbole : inactiveSymbole);
display.drawXbm(60, 30, 8, 8, counter % 3 == 1 ? activeSymbole : inactiveSymbole);
display.drawXbm(74, 30, 8, 8, counter % 3 == 2 ? activeSymbole : inactiveSymbole);
display.display();
counter++;
}
ui.setTargetFPS(30);
ui.setActiveSymbol(activeSymbole);
ui.setInactiveSymbol(inactiveSymbole);
// You can change this to
// TOP, LEFT, BOTTOM, RIGHT
ui.setIndicatorPosition(BOTTOM);
// Defines where the first frame is located in the bar.
ui.setIndicatorDirection(LEFT_RIGHT);
// You can change the transition that is used
// SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN
ui.setFrameAnimation(SLIDE_LEFT);
ui.setFrames(frames, numberOfFrames);
ui.setOverlays(overlays, numberOfOverlays);
// Inital UI takes care of initalising the display too.
ui.init();
Serial.println("");
display.flipScreenVertically();
updateData(&display);
display.flipScreenVertically();
ticker.attach(UPDATE_INTERVAL_SECS, setReadyForWeatherUpdate);
}
void loop() {
display.flipScreenVertically();
if (readyForWeatherUpdate && ui.getUiState()->frameState == FIXED) {
updateData(&display);
}
int remainingTimeBudget = ui.update();
if (remainingTimeBudget > 0) {
// You can do some work here
// Don't do stuff if you are below your
// time budget.
delay(remainingTimeBudget);
}
}
void drawProgress(OLEDDisplay *display, int percentage, String label) {
display->clear();
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(ArialMT_Plain_10);
display->drawString(64, 10, label);
display->drawProgressBar(2, 28, 124, 10, percentage);
display->display();
}
void updateData(OLEDDisplay *display) {
drawProgress(display, 10, "Updating time...");
timeClient.updateTime();
drawProgress(display, 30, "Updating conditions...");
wunderground.updateConditions(WUNDERGRROUND_API_KEY, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY);
drawProgress(display, 50, "Updating forecasts...");
wunderground.updateForecast(WUNDERGRROUND_API_KEY, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY);
drawProgress(display, 80, "Updating thingspeak...");
thingspeak.getLastChannelItem(THINGSPEAK_CHANNEL_ID, THINGSPEAK_API_READ_KEY);
lastUpdate = timeClient.getFormattedTime();
readyForWeatherUpdate = false;
drawProgress(display, 100, "Done...");
delay(1000);
}
void drawDateTime(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(ArialMT_Plain_10);
String date = wunderground.getDate();
int textWidth = display->getStringWidth(date);
display->drawString(64 + x, 5 + y, date);
display->setFont(ArialMT_Plain_24);
String time = timeClient.getFormattedTime();
textWidth = display->getStringWidth(time);
display->drawString(64 + x, 15 + y, time);
display->setTextAlignment(TEXT_ALIGN_LEFT);
Serial.println(time);
}
void drawCurrentWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
display->setFont(ArialMT_Plain_10);
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->drawString(40 + x, 5 + y, wunderground.getWeatherText());
display->setFont(ArialMT_Plain_24);
String temp = wunderground.getCurrentTemp() + "°C";
display->drawString(50 + x, 15 + y, temp);
int tempWidth = display->getStringWidth(temp);
display->setFont(Meteocons_Plain_42);
String weatherIcon = wunderground.getTodayIcon();
int weatherIconWidth = display->getStringWidth(weatherIcon);
display->drawString(22 + x - weatherIconWidth / 2, 05 + y, weatherIcon);
}
void drawForecast(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
drawForecastDetails(display, x, y, 0);
drawForecastDetails(display, x + 44, y, 2);
drawForecastDetails(display, x + 88, y, 4);
}
void drawThingspeak(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(ArialMT_Plain_10);
display->drawString(64 + x, 0 + y, "Thingspeak");
display->setFont(ArialMT_Plain_10);
display->drawString(20 + x, 30 + y, thingspeak.getFieldValue(0) + "°C");
display->drawString(20 + x, 15 + y, thingspeak.getFieldValue(3));
display->drawString(32 + x, 15 + y, "V");
display->drawString(90 + x, 15 + y, thingspeak.getFieldValue(1) + "%");
display->drawString(90 + x, 30 + y, thingspeak.getFieldValue(2) + "hPa");
Serial.print(" TEMP-");
Serial.print(thingspeak.getFieldValue(0));
Serial.print(" NAP-");
Serial.print(thingspeak.getFieldValue(3));
Serial.print(" RH-");
Serial.print(thingspeak.getFieldValue(1));
Serial.print(" PRESS-");
Serial.println(thingspeak.getFieldValue(2));
}
void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex) {
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(ArialMT_Plain_10);
String day = wunderground.getForecastTitle(dayIndex).substring(0, 3);
day.toUpperCase();
display->drawString(x + 20, y, day);
display->setFont(Meteocons_Plain_21);
display->drawString(x + 20, y + 12, wunderground.getForecastIcon(dayIndex));
Serial.print(wunderground.getForecastIcon(dayIndex));
Serial.print(",");
Serial.println(day);
display->setFont(ArialMT_Plain_10);
display->drawString(x + 20, y + 34, wunderground.getForecastLowTemp(dayIndex) + "|" + wunderground.getForecastHighTemp(dayIndex));
display->setTextAlignment(TEXT_ALIGN_LEFT);
}
void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {
display->setColor(WHITE);
display->setFont(ArialMT_Plain_10);
String time = timeClient.getFormattedTime().substring(0, 5);
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->drawString(0, 54, time);
display->setTextAlignment(TEXT_ALIGN_RIGHT);
String temp = wunderground.getCurrentTemp() + "°C";
display->drawString(128, 54, temp);
display->drawHorizontalLine(0, 52, 128);
}
void setReadyForWeatherUpdate() {
Serial.println("Setting readyForUpdate to true");
readyForWeatherUpdate = true;
}
Chciałbym aby dane wysyłane były tylko raz po wywołaniu konkretnej ramki. Teraz dane są wysyłane non stop przez cały czas trwania ramki, powoduje to niezły bajzel przy odczycie.
Pewnie bym sobie z tym poradził gdybym potrafił wysyłane wartości zapisać do zmiennych, wtedy porównanie nowego odczytu do starego, jeśli się różnią to wysyłam jeśli brak różnicy to nie wysyłam.