반응형
ESP32보드를 활용하여 날씨 정보를 알려주는 웨더스테이션을 만들어보겠습니다.
1. 준비물
- ESP32
- ILI9341
- 미니 브래드보드
- 온습도 센서(DHT11)
2. ESP32 시작하기
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json
그림과 같이 입력하고 "확인"을 클릭 합니다
- 툴-보드메니저 선택
- "esp32"를 입력하고 설치
- ESP32 Dev Module선택
3. ESP32 와 ILI9341 연결하여 기상정보 표시하기
#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include "WiFi.h"
#ifndef STASSID
#define STASSID "your-ssid" //와이파이 검색했을때 뜨는 이름
#define STAPSK "your-password" //패스워드
#endif
#define TFT_DC 2
#define TFT_CS 5
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
const char* ssid = STASSID;
const char* password = STAPSK;
//http://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=1159068000
const char* host = "www.kma.go.kr";
const int httpsPort = 80;
void setup() {
Serial.begin(115200);
tft.begin();
tft.setRotation(3);
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(4);
tft.setCursor(0, 0);
Serial.println();
Serial.print("connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// Use WiFiClientSecure class to create TLS connection
WiFiClient client;
Serial.print("connecting to ");
Serial.println(host);
//클라이언트와 서버와 커넥트
if (!client.connect(host, httpsPort)) {
Serial.println("connection failed");
return;
}
String url = "/wid/queryDFSRSS.jsp?zone=1159068000";
Serial.print("requesting URL: ");
Serial.println(url);
//사물인터넷보드에서 RSS서버로 보내는 요청!
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
//서버로부터 응답이 있을때까지 대기하겠다..
//언제까지 기다려야하나요..?
//timeout!
unsigned long t = millis(); //생존시간
while(1){
if(client.available()) break;
if(millis() - t > 10000) break;
}
/*
*
시간 <hour>
기온 <temp>
날씨 <wfEn>
강수확률 <pop>
풍속 <ws>
풍향 <wdEn>
습도 <reh>
*/
//응답이 날라오는 부분!
Serial.println("request sent");
int count = 1;
while(client.available()){
String data = client.readStringUntil('\n'); //readline();
if(count > 7) return;
String temp = "<hour>";
int s = data.indexOf(temp) + temp.length();
int e = data.indexOf("</hour>");
if(s != -1 && e != -1){
String output = data.substring(s,e);
Serial.println("시간=" + output);
tft.println("HOUR=" + output);
count++;
}
temp = "<temp>";
s = data.indexOf(temp) + temp.length();
e = data.indexOf("</temp>");
if(s != -1 && e != -1){
String output = data.substring(s,e);
Serial.println("온도=" + output);
tft.println("TEMP=" + output);
count++;
}
temp = "<wfEn>";
s = data.indexOf(temp) + temp.length();
e = data.indexOf("</wfEn>");
if(s != -1 && e != -1){
String output = data.substring(s,e);
Serial.println("날씨=" + output);
tft.println("WFEN=" + output);
count++;
}
temp = "<pop>";
s = data.indexOf(temp) + temp.length();
e = data.indexOf("</pop>");
if(s != -1 && e != -1){
String output = data.substring(s,e);
Serial.println("강수확률=" + output);
tft.println("POP=" + output);
count++;
}
temp = "<ws>";
s = data.indexOf(temp) + temp.length();
e = data.indexOf("</ws>");
if(s != -1 && e != -1){
String output = data.substring(s,e);
Serial.println("풍속=" + output);
tft.println("WS=" + output);
count++;
}
temp = "<wdEn>";
s = data.indexOf(temp) + temp.length();
e = data.indexOf("</wdEn>");
if(s != -1 && e != -1){
String output = data.substring(s,e);
Serial.println("풍향=" + output);
tft.println("WDEN=" + output);
count++;
}
temp = "<reh>";
s = data.indexOf(temp) + temp.length();
e = data.indexOf("</reh>");
if(s != -1 && e != -1){
String output = data.substring(s,e);
Serial.println("습도=" + output);
tft.println("REH=" + output);
count++;
}
}
Serial.println("DONE");
}
void loop() {
}
-결과
(2) DHT11를 이용하여 실내 온도습도 표시하기
- 참고 : https://www.youtube.com/watch?v=mYH8ADLHVwo
- 회로도
- 소스코드
https://github.com/Philc333/ESP32_ILI9341_DHT11
- 라이브러리 설치
툴메뉴-> 라이브러리 관리에서 'Arduino_GFX_Library' 검색
- 소스코드
/*
This program uses the DHT11 Temperature and Humidity Sensor, whos values are displayed
on A ILI9341 TFT screen, via the ESP32. The analogue meter(Humidity) was originally designed by Bodmer,
I believe, and can be found in the TFT_eSPI example folder. I have re-codeed the meter using
the Arduino_GFX_Library, and the Temperature meter was designed by me, and also uses the
Arduino_GFX_Library. Feel free to use and alter the code as needed!!
*/
#include "SPI.h"
#include <Arduino_GFX_Library.h>
#include "DHT.h"
#define DHTPIN 33 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT11 // DHT 11
#define TFT_DC 2 //9
#define TFT_CS 15 //10
#define TFT_RST 4 //8
#define TFT_SCK 18
#define TFT_MOSI 23
#define TFT_MISO 19
//Define Chip Select Pins, and Rotation
#define TS_CS 21 //7
#define SD_CS 5
#define ROTATION 0
uint32_t setUPTime = 0; // time for next update
int my_Ntemp = 0;
int my_Otemp = 0;
int oBlock_H = 50;
int mH = 0, mH2 = 0;
// Assign human-readable names to some common 16-bit color values:
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define DARK_GREY 0x4A89
#define MEDIUM_GREY 0x8492
#define LIGHT_GREY 0xD6BA
#define LIGHT_GREEN 0x970E
DHT dht(DHTPIN, DHTTYPE);
int redNeedle = 220, greyNeedle = 220,checkNeedle = 220;//Values set to 220,which equal 0 on meter.
Arduino_ESP32SPI bus = Arduino_ESP32SPI(TFT_DC, TFT_CS, TFT_SCK, TFT_MOSI, TFT_MISO);
Arduino_ILI9341 tft = Arduino_ILI9341(&bus, TFT_RST);
void setup() {
Serial.begin(115200);
//*****Deselect all SPI Devices*****
pinMode(TFT_CS, OUTPUT);
digitalWrite(TFT_CS, HIGH);
pinMode(21, OUTPUT); //was 7
digitalWrite(21, HIGH); //was 7
pinMode(SD_CS, OUTPUT);
digitalWrite(SD_CS, HIGH);
//2 Lines below can be ignored, they're part of a bigger project
pinMode(17, OUTPUT);
digitalWrite(17, LOW);
//tft.setRotation(uint8_t 1);
tft.begin();
tft.setRotation(ROTATION);
dht.begin();
myHumiditySetup();
myTemperatureSetup();
setUPTime = millis(); // Next update time
Serial.print("Setup Time: ");Serial.println(setUPTime);
}
//*********************************Loop Function Code**********************************
unsigned long lastFrame = millis();
void loop() {
while((millis() - lastFrame) < 2000);
lastFrame = millis();
Serial.print("Loop lastFrame Time(millis()): "); Serial.println(lastFrame);
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float f = dht.readTemperature(true);
Serial.print("Temperature(Celsius and Fahrenheit): ");Serial.print((int) t);Serial.print(" "); Serial.println((int) f);
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
mH2 = mH;
mH = (int) h;
tft.setTextSize(2);
tft.setTextColor(WHITE);
tft.setCursor(20, 90);
tft.print(mH2);
tft.setTextSize(2);
tft.setTextColor(BLACK);
tft.setCursor(20, 90);
tft.print(mH);
temp_Update((int)t);
myMeter(mH + 220);
}
//*****************************Temperature Setup Function Code***************************
void myTemperatureSetup(){
//**********Title Bar with Temperature Code********
tft.setTextSize(2);
tft.setTextColor(BLACK);
tft.setCursor(25, 130);
tft.print("Temperature ");
tft.setCursor(170, 130);
tft.print(my_Ntemp);
tft.print((char)247);
tft.print("C");
//*********Temperature Gauge Code*********
tft.fillRoundRect(tft.width()-135, tft.height()-170, 30, 150,20, BLACK);
tft.fillRoundRect(tft.width()-132, tft.height()-167, 24, 150,20, WHITE);
tft.fillCircle(tft.width()-120, tft.height()-30, 20, BLACK);
tft.fillCircle(tft.width()-120, tft.height()-30, 17, WHITE);
tft.fillRect(tft.width()-132, tft.height()-50, 24, 30,WHITE);
tft.fillCircle(tft.width()-120, tft.height()-30, 12, RED);
tft.fillRect(tft.width()-123, tft.height()-50, 6, 20,RED);
//*********Temperature Gauge Lines Code**********
int Line_Height = 270;
for(int a = 0; a < 5; a++ ){
tft.drawFastHLine(tft.width()-105,Line_Height,10,BLACK);
Line_Height = Line_Height - 25;
}
int sLine_Height = 270;
for(int b = 0; b < 20; b++ ){
tft.drawFastHLine(tft.width()-105,sLine_Height,5,BLACK);
sLine_Height = sLine_Height - 5;
}
//**********Temperature Gauge Numbers Code**********
tft.setTextSize(1);
tft.setTextColor(BLACK);
int number_Height = 267; //was 147
int gNum = 0;
for(int c = 0; c < 5; c++ ){
tft.setCursor(tft.width()-92, number_Height); //was 225
tft.print(gNum);
tft.print((char)247);
tft.print("C");
number_Height = number_Height - 25;
gNum = gNum + 25;
}
}
//***********************Dial Gauge(Humidity) Setup Function Code************************
void myHumiditySetup(){
tft.fillScreen(YELLOW);
tft.fillRect(0, 0, 240, 126, DARK_GREY);
tft.fillRect(5, 3, 230, 119, WHITE);
tft.setTextSize(2);
tft.setTextColor(BLACK);
tft.setCursor(200, 90);
tft.print("H%");
tft.setCursor(20, 90);
tft.print(mH);
tft.drawArc(120, 140, 115, 99, 220, 320, BLACK);
tft.fillArc(120, 140, 115, 100, 295, 319, YELLOW);
tft.fillArc(120, 140, 115, 100, 270, 295, GREEN);
tft.fillArc(120, 140, 115, 100, 220, 270, WHITE);
tft.setTextSize(1);
tft.setTextColor(BLACK);
tft.setCursor(25, 57);
tft.print("0");
tft.setCursor(206, 56);
tft.print("100");
tft.setCursor(65, 25);
tft.print("25");
tft.setCursor(165, 25);
tft.print("75");
tft.setCursor(115, 15);
tft.print("50");
for (int a = 220; a < 320; a = a + 25){
tft.fillArc(120, 140, 115, 100, a, a, BLACK);
}
for (int b = 225; b <= 315; b = b + 5){
tft.fillArc(120, 140, 110, 100, b, b, BLACK);
}
}
//***************************Dial Gauge Pointer Update Code***************************
void myMeter(int hNeedle){
//int redNeedle = 220, greyNeedle = 220,checkNeedle = 220, hNeedle = 220;
checkNeedle = redNeedle;
if(hNeedle > redNeedle){
redNeedle = hNeedle;
for(int uRN = checkNeedle; uRN <= redNeedle; uRN++){
tft.fillArc(120, 140, 95, 20, uRN - 1, uRN - 1, WHITE);
tft.fillArc(120, 140, 95, 20, uRN, uRN, RED);
tft.fillRect(95, 122, 48, 4, DARK_GREY);
tft.fillRect(99, 126, 42, 3, YELLOW);
delay(10);
}
}else if(hNeedle < redNeedle){
redNeedle = hNeedle;
for(int dRN = checkNeedle; dRN >= redNeedle; dRN--){
tft.fillArc(120, 140, 95, 20, dRN + 1, dRN + 1, WHITE);
tft.fillArc(120, 140, 95, 20, dRN, dRN, RED);
tft.fillRect(95, 122, 48, 4, DARK_GREY);
tft.fillRect(99, 126, 42, 3, YELLOW);
delay(10);
}
}else{};
}
// ***************************Temperature Update Function Start***********************
//int oBlock_H = 50;
void temp_Update(int my_Ntemp){
int nBlock_H;
if(my_Ntemp != my_Otemp){
tft.setTextSize(2);
tft.setTextColor(YELLOW);
tft.setCursor(170, 130);
tft.print(my_Otemp);
tft.print((char)247);
tft.print("C");
my_Otemp = my_Ntemp;
tft.setTextSize(2);
tft.setTextColor(BLACK);
tft.setCursor(170, 130);
tft.print(my_Ntemp);
tft.print((char)247);
tft.print("C");
nBlock_H = map(my_Ntemp, 0, 100, 50, 150);
Serial.print("nBlock: ");Serial.print(nBlock_H);Serial.print(" my_Ntemp: ");Serial.println(my_Ntemp);
tft.fillRect(tft.width()-123, tft.height()- oBlock_H, 6, oBlock_H - 50,WHITE);
tft.fillRect(tft.width()-123, tft.height()- nBlock_H, 6, nBlock_H - 50,RED);
oBlock_H = nBlock_H;
//To be commented out, or deleted
Serial.print("Height: ");
Serial.print(nBlock_H);
Serial.print(" Temperature: ");
Serial.print(my_Ntemp);
}
}
-결과
==>> DHT22를 사용할 경우 위의 회로대로 연결하고 소스코드에서 DHT11 을 DHT22로 수정하면 됩니다.
반응형
'피지컬컴퓨팅 > 아두이노' 카테고리의 다른 글
ESP32 연결 시 포트 인식 못할 때 해결방법 (0) | 2024.08.18 |
---|---|
ESP32 사용 기초(WIFI, LCD연결) (0) | 2024.08.13 |
#인공지능 AI 활용 - Mediapipe를 이용한 로봇 손 제어하기 (0) | 2024.07.17 |
심장박동 센서 활용하기 (0) | 2024.06.25 |
ESP32 와 ESP8266 차이점 비교 (0) | 2024.05.23 |