Nano 33 IoT 보드를 사용하여 원하는 도시의 온도와 습도 정보를 보여줍니다. 날씨 정보를 뽑아오는 상세한 설명은 참고 자료의 사이트를 참고합니다. 세계 어떤 지역의 날씨를 보여줄 수 있습니다. 아래 첨부한 잘 돌아가는 코드를 참고하세요.
보완할 점
1. 장소를 옮길 때마다 매번 인터넷 WiFi 변경을 바꿔주고 펌웨어를 업로드해야 한다. 블루투스로 연결하여 설정을 바꿔주면 좋겠다. 설정 정보는 wifi 접속 정보, 국가, 도시, 보여줄 정보 - 온도, 습도, 압력, 바람 등-를 사용자가 선택하게.
2. 예쁜 기상 정보 아이콘은 Weather Icons란 사이트를 참고한다.
3. display 화면이 현재는 ssd1306 oled인데 너무 작고 정보가 적으므로 큰 디스플레이 화면으로 변경
아래 잘 돌아가는 코드를 참고합니다.
WiFi 환경을 잡아주는 arduino_secret.h 파일을 인터넷 환경에 맞도록 수정한다.
#define SECRET_SSID "FO****RCM"
#define SECRET_PASS "166******10350"
API 키를 받아와 OpenweatherMap 사이트에서 정보를 불러와 OLED에 나타내는 코드입니다. 25라인 보면 발급받은 API 키를 이용해 도시 설정을 바꾸어 주면 됩니다. 예제에서는 그린란드의 qaanaaq 란 도시의 온도와 습도를 보여줍니다. 결과 화면을 아래에 첨부합니다.
/*
* Rui Santos
* Complete Project Details http://randomnerdtutorials.com
* Based on the Arduino Ethernet Web Client Example
* and on the sketch "Sample Arduino Json Web Client" of the Arduino JSON library by Benoit Blanchon (bblanchon.github.io/ArduinoJson)
*/
#include <ArduinoJson.h>
#include <SPI.h>
#include <WiFiNINA.h>
#include <Adafruit_GFX.h> // include Adafruit graphics library
#include <Adafruit_SSD1306.h> // include Adafruit SSD1306 OLED display driver
#define OLED_RESET 4 // define display reset pin
Adafruit_SSD1306 display(OLED_RESET);
//EthernetClient client;
WiFiClient client;
// Name address for Open Weather Map API
const char* server = "api.openweathermap.org";
// Replace with your unique URL resource
//const char* resource = "/data/2.5/weather?q=seoul,KR&APPID=34b3527445f4bb5a2b~~~~~~~~~~~~~~";
//const char* resource = "/data/2.5/weather?q=busan,KR&APPID=34b3527445f4bb5a2b~~~~~~~~~~~~~~";
const char* resource = "/data/2.5/weather?q=qaanaaq&APPID=34b3527445f4bb5a2b8be~~~~~~~~~~~~~~";
// How your resource variable should look like, but with your own COUNTRY CODE, CITY and API KEY (that API KEY below is just an example):
//const char* resource = "/data/2.5/weather?q=Porto,pt&appid=bd939aa3d23ff33d3c8f5dd1";
const unsigned long HTTP_TIMEOUT = 10000; // max respone time from server
const size_t MAX_CONTENT_SIZE = 512; // max size of the HTTP response
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS;
// The type of data that we want to extract from the page
struct clientData {
char temp[8];
char humidity[8];
};
// ARDUINO entry point #1: runs once when you press reset or power the board
void setup() {
Serial.begin(9600);
//while (!Serial) { ; } //wait for serial port to initialize
initial_oled();
Serial.println("Serial ready");
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to wifi");
printWifiStatus();
}
// ARDUINO entry point #2: runs over and over again forever
void loop() {
if(connect(server)) {
if(sendRequest(server, resource) && skipResponseHeaders()) {
clientData clientData;
if(readReponseContent(&clientData)) {
printclientDatatoserial(&clientData);
printclientDatatooled(&clientData);
}
}
}
disconnect();
wait();
}
// Open connection to the HTTP server
bool connect(const char* hostName) {
Serial.print("Connect to ");
Serial.println(hostName);
bool ok = client.connect(hostName, 80);
Serial.println(ok ? "Connected" : "Connection Failed!");
return ok;
}
// Send the HTTP GET request to the server
bool sendRequest(const char* host, const char* resource) {
Serial.print("GET ");
Serial.println(resource);
client.print("GET ");
client.print(resource);
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(host);
client.println("Connection: close");
client.println();
return true;
}
// Skip HTTP headers so that we are at the beginning of the response's body
bool skipResponseHeaders() {
// HTTP headers end with an empty line
char endOfHeaders[] = "\r\n\r\n";
client.setTimeout(HTTP_TIMEOUT);
bool ok = client.find(endOfHeaders);
if (!ok) {
Serial.println("No response or invalid response!");
}
return ok;
}
// Parse the JSON from the input string and extract the interesting values
// Here is the JSON we need to parse
/*{
"coord": {
"lon": -8.61,
"lat": 41.15
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
],
"base": "stations",
"main": {
"temp": 296.15,
"pressure": 1020,
"humidity": 69,
"temp_min": 296.15,
"temp_max": 296.15
},
"visibility": 10000,
"wind": {
"speed": 4.6,
"deg": 320
},
"clouds": {
"all": 0
},
"dt": 1499869800,
"sys": {
"type": 1,
"id": 5959,
"message": 0.0022,
"country": "PT",
"sunrise": 1499836380,
"sunset": 1499890019
},
"id": 2735943,
"name": "Porto",
"cod": 200
}*/
bool readReponseContent(struct clientData* clientData) {
// Compute optimal size of the JSON buffer according to what we need to parse.
// See https://bblanchon.github.io/ArduinoJson/assistant/
const size_t bufferSize = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) +
2*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) +
JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(12) + 390;
DynamicJsonBuffer jsonBuffer(bufferSize);
JsonObject& root = jsonBuffer.parseObject(client);
if (!root.success()) {
Serial.println("JSON parsing failed!");
return false;
}
// Here were copy the strings we're interested in using to your struct data
strcpy(clientData->temp, root["main"]["temp"]);
strcpy(clientData->humidity, root["main"]["humidity"]);
// It's not mandatory to make a copy, you could just use the pointers
// Since, they are pointing inside the "content" buffer, so you need to make
// sure it's still in memory when you read the string
return true;
}
// Print the data extracted from the JSON
void printclientDatatoserial(const struct clientData* clientData) {
Serial.println(clientData->temp);
Serial.println(clientData->humidity);
Serial.print("Temp = ");
String receivedTemp = clientData->temp;
Serial.print(receivedTemp.toFloat()-273.15);
Serial.println(" ℃");
Serial.print("Humidity = ");
Serial.print(clientData->humidity);
Serial.println(" %");
}
char _readydatatoOled[8];
void printclientDatatooled(const struct clientData* clientData) {
String receivedTemp = clientData->temp;
float tCelsius = receivedTemp.toFloat()-273.15;
display.setCursor(23, 10);
display.print(String(tCelsius) + " C");
display.setCursor(23, 30);
display.print(String(clientData->humidity) + " /");
display.drawCircle(76, 12, 2, WHITE);
display.drawCircle(60, 32, 2, WHITE);
display.drawCircle(70, 42, 2, WHITE);
display.display();
}
// Close the connection with the HTTP server
void disconnect() {
Serial.println("Disconnect");
client.stop();
}
// Pause for a 1 minute
void wait() {
Serial.println("Wait 60 seconds");
delay(60000);
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
void initial_oled()
{
//initialize the SSD1306 OLED display with I2C address = 0x3D
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
// clear the display buffer.
display.clearDisplay();
display.setTextSize(1); // text size = 1
display.setTextColor(WHITE, BLACK); // set text color to white and black background
display.setCursor(15, 0); // move cursor to position (15, 0) pixel
display.print("Seoul Weather");
display.display(); // update the display
display.setTextSize(2); // text size = 2
}
결과 사진
참고사이트
OpenWeatherMap을 이용한 날씨 API를 사용해보자
222 Weather Themed Icons and CSS
'개발자 > Arduino' 카테고리의 다른 글
HTTP를 통해 Arduino Nano 33 IoT와 Ubidots 연결 1 (0) | 2020.10.30 |
---|---|
Arduino IDE – 설정 및 시작 가이드 (0) | 2020.10.28 |
nano 33 IoT에서 타이머 인터럽트 구현 참고 2 (0) | 2020.10.25 |
nano 33 IoT에서 타이머 인터럽트 구현 참고 1 (0) | 2020.10.25 |
Nano 33 IoT 보드에서 아날로그 적외선 거리센서 (GP2Y0A21YK) (0) | 2020.10.20 |
nano 33 iot 보드 타이머 인터럽트 예제 (0) | 2020.10.20 |
스마트 팩토리 연결도와 소스코드 20201018 (0) | 2020.10.18 |
Nano 33 IoT 데이터 서버 전송 Get 방식 (0) | 2020.10.13 |
더욱 좋은 정보를 제공하겠습니다.~ ^^