#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
// Настройки Wi-Fi
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// URL для JSON API
const char* json_url = "https://www.cbr-xml-daily.ru/daily_json.js";
// Настройки OLED дисплея
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Настройки DHT11
#define DHTPIN 4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
// Переменные для отслеживания состояния и времени
enum DisplayState {
STATE_USD,
STATE_DHT
};
DisplayState currentState = STATE_USD;
unsigned long lastDisplayChange = 0;
const long displayDuration = 5000;
// Переменная для хранения курса доллара
float usdRate = 0.0;
bool usdRateUpdated = false;
unsigned long lastUsdUpdate = 0;
const long usdUpdateInterval = 60000; // Обновление курса раз в минуту
// Функция для получения курса доллара
void getUsdRate() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(json_url);
int httpCode = http.GET();
if (httpCode > 0) {
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
DynamicJsonDocument doc(512); // Уменьшил размер doc
DeserializationError error = deserializeJson(doc, payload);
if (!error) {
if (doc.containsKey("Valute") && doc["Valute"].containsKey("USD")) {
usdRate = doc["Valute"]["USD"]["Value"].as<float>();
usdRateUpdated = true;
} else {
Serial.println(F("Error: USD data not found")); // F() макрос
usdRateUpdated = false;
}
} else {
Serial.print(F("JSON parse failed: ")); // F() макрос
Serial.println(error.c_str());
usdRateUpdated = false;
}
} else {
Serial.printf(F("HTTP error: %d\n"), httpCode); // F() макрос
usdRateUpdated = false;
}
} else {
Serial.printf(F("HTTP req failed: %s\n"), http.errorToString(httpCode).c_str()); // F() макрос
usdRateUpdated = false;
}
http.end();
} else {
Serial.println(F("WiFi no connect")); // F() макрос
usdRateUpdated = false;
}
lastUsdUpdate = millis();
}
// Функция для отображения курса доллара на весь экран
void displayUsd() {
display.clearDisplay();
display.setTextSize(1);
String usdString = usdRateUpdated ? "$" + String(usdRate, 2) : "USD error";
int16_t tbx, tby;
uint16_t tbw, tbh;
int fontSize = 1;
while (true) {
display.setTextSize(fontSize);
display.getTextBounds(usdString, 0, 0, &tbx, &tby, &tbw, &tbh);
if (tbw < SCREEN_WIDTH - 5 && tbh < SCREEN_HEIGHT - 5) {
fontSize++;
if (fontSize > 6) break;
} else {
fontSize--;
display.setTextSize(fontSize);
display.getTextBounds(usdString, 0, 0, &tbx, &tby, &tbw, &tbh);
break;
}
}
int16_t x = (SCREEN_WIDTH - tbw) / 2;
int16_t y = (SCREEN_HEIGHT - tbh) / 2;
display.setCursor(x, y);
display.print(usdString);
display.display();
}
// Функция для отображения данных с DHT22 по центру экрана
void displayDht() {
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
display.clearDisplay();
display.setTextSize(3);
if (isnan(temperature) || isnan(humidity)) {
display.setCursor(0, 20);
display.println(F("DHT error")); // F() макрос
} else {
char tempStr[8]; // char array для температуры
dtostrf(temperature, 0, 0, tempStr);
int16_t tbx, tby;
uint16_t tbw, tbh;
display.getTextBounds(tempStr, 0, 0, &tbx, &tby, &tbw, &tbh);
display.setCursor((SCREEN_WIDTH - tbw - 10) / 2, 10);
display.print(tempStr);
display.cp437(true);
display.write(248);
char humStr[8]; // char array для влажности
dtostrf(humidity, 0, 0, humStr);
display.getTextBounds(humStr, 0, 0, &tbx, &tby, &tbw, &tbh);
display.setCursor((SCREEN_WIDTH - tbw - 10) / 2, 40);
display.print(humStr);
display.print(F("%")); // F() макрос
}
display.display();
}
void setup() {
Serial.begin(115200);
Serial.println(F("DHT22 & USD on OLED")); // Сократил немного
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
Serial.println(F("OLED init error")); // Сократил
for (;;);
}
display.display();
delay(1000);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.cp437(true);
dht.begin();
Serial.print(F("Connect to ")); // Сократил
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(F("."));
}
Serial.println(); // Убрал F() - экономия
Serial.println(F("WiFi OK")); // Сократил
getUsdRate();
}
void loop() {
unsigned long currentTime = millis();
if (currentTime - lastDisplayChange >= displayDuration) {
lastDisplayChange = currentTime;
currentState = (currentState == STATE_USD) ? STATE_DHT : STATE_USD;
}
if (currentTime - lastUsdUpdate >= usdUpdateInterval) {
getUsdRate();
}
if (currentState == STATE_USD) {
displayUsd();
} else {
displayDht();
}
delay(100);
}