14주차 스마트디바이스 (API) - jungjaeyeol/jyeol03 GitHub Wiki
API는 Application Programming Interface의 약자로,
응용 프로그램 간에 정보를 주고받거나 기능을 사용할 수 있도록 도와주는 인터페이스입니다.
📌 쉽게 말해, 서로 다른 프로그램끼리 소통할 수 있도록 돕는 "번역기" 역할을 합니다.
- 손님: 사용자
- 주방: 서버
- 웨이터: API
손님이 음식을 주문하면 웨이터(API)가 주방에 전달하고,
주방이 만든 요리를 다시 손님에게 전달합니다.
이처럼 API는 요청과 응답을 중개하는 역할을 합니다.
- Google Maps API: 웹사이트에 지도를 삽입할 수 있음
- 카카오 로그인 API: 외부 앱에서 카카오 계정으로 로그인 가능
- 날씨 API: 특정 지역의 실시간 날씨 정보를 받아올 수 있음
기능 | 설명 |
---|---|
데이터 요청 및 응답 | 외부 서버에서 필요한 정보를 받아옴 |
인증 처리 | 사용자 로그인/회원가입 등 |
제어 기능 | 외부에서 특정 기능을 실행 (예: 결제, 알림 전송 등) |
- API는 소프트웨어와 소프트웨어 사이의 연결 통로입니다.
- 복잡한 기능을 외부에서 간단히 사용할 수 있게 해주는 도구입니다.
- 현대의 웹, 앱, 서버 시스템이 협업하는 핵심 기술입니다.
- 보드 연결
- 코드
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "images.h" // 이미지 비트맵 배열 포함
#define SCREEN_WIDTH 128 // OLED 디스플레이의 너비 (픽셀 단위)
#define SCREEN_HEIGHT 32 // OLED 디스플레이의 높이 (픽셀 단위)
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Serial.begin(115200);
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
// 배경을 흰색으로 초기화
display.clearDisplay();
display.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, WHITE);
// 이미지 출력 (검정 이미지 on 흰 배경)
display.drawBitmap(0, 0, epd_bitmap_VeryGood, 32, 32, BLACK, WHITE);
display.drawBitmap(32, 0, epd_bitmap_Good, 32, 32, BLACK, WHITE);
display.drawBitmap(64, 0, epd_bitmap_Bad, 32, 32, BLACK, WHITE);
display.drawBitmap(96, 0, epd_bitmap_VeryBad, 32, 32, BLACK, WHITE);
display.display();
}
void loop() {
// 여기에 동작 반복 로직을 넣을 수 있습니다
}
- 실습 결과

- 실습 코드
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <WiFi.h>
#include <time.h>
#include "images.h" // 비트맵 이미지가 정의된 헤더
const char* ssid = "Your_SSID";
const char* password = "Your_Password";
const int httpPort = 80;
const char* apiKey = "일반 인증키";
const char* version = "&ver=1.3";
const char* server = "apis.data.go.kr";
const char* stationName = "측정소 위치";
const char* returnType = "xml";
const char* numOfRows = "1";
const char* pageNo = "1";
const char* dataTerm = "DAILY";
WiFiClient client;
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Serial.begin(115200);
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.display();
delay(2000);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("\nConnecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.println("\nWiFi is connected");
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.setTextColor(WHITE);
display.drawBitmap(0, 0, epd_bitmap_VeryGood, 32, 32, BLACK, WHITE); // 흰색 아이콘 출력
display.display();
}
void loop() {
String dateNtime, pm10Val, pm10Grade, tmp_str;
static int IntervalReq = 1800;
if (IntervalReq++ > 1800) {
IntervalReq = 0;
Requesthttp();
};
delay(50);
while (client.available()) {
String line = client.readStringUntil('\n');
Serial.println(line);
int i = line.indexOf("</dataTime>");
if (i > 0) {
tmp_str = "<dataTime>";
dateNtime = line.substring(line.indexOf(tmp_str) + tmp_str.length(), i);
}
i = line.indexOf("</pm10Value>");
if (i > 0) {
tmp_str = "<pm10Value>";
pm10Val = line.substring(line.indexOf(tmp_str) + tmp_str.length(), i);
}
i = line.indexOf("</pm10Grade>");
if (i > 0) {
tmp_str = "<pm10Grade>";
pm10Grade = line.substring(line.indexOf(tmp_str) + tmp_str.length(), i);
client.stop();
display.clearDisplay();
displayIcon(atoi(pm10Grade.c_str()));
displayString(dateNtime, pm10Val);
display.display();
break;
}
}
delay(1000);
}
void Requesthttp() {
if (client.connect(server, httpPort)) {
Serial.println("\nSuccessed connection, and request http protocol");
client.print(String("GET /B552584/ArpltnInforInqireSvc"));
client.print(String("/getMsrstnAcctoRltmMesureDnsty?serviceKey="));
client.print(apiKey);
client.print(String("&returnType=") + returnType);
client.print(String("&numOfRows=") + numOfRows);
client.print(String("&pageNo=") + pageNo);
client.print(String("&stationName=") + urlencode(stationName));
client.print(String("&dataTerm=") + dataTerm);
client.print(version);
client.print(" HTTP/1.1\r\n");
client.print("Host: " + String(server) + "\r\n");
client.print("Connection: close\r\n\r\n");
} else {
Serial.println("\nfailed connection");
}
}
void displayString(String dnt, String pmval) {
display.setCursor(50, 3);
display.println(dnt.substring(0, 10));
display.setCursor(50, 13);
display.println(dnt.substring(11));
display.setCursor(50, 23);
display.print(pmval);
display.println(" ug/m^3");
}
void displayIcon(int grade) {
switch (grade) {
case 1:
display.drawBitmap(0, 0, epd_bitmap_VeryGood, 32, 32, BLACK, WHITE);
break;
case 2:
display.drawBitmap(0, 0, epd_bitmap_Good, 32, 32, BLACK, WHITE);
break;
case 3:
display.drawBitmap(0, 0, epd_bitmap_Bad, 32, 32, BLACK, WHITE);
break;
case 4:
display.drawBitmap(0, 0, epd_bitmap_VeryBad, 32, 32, BLACK, WHITE);
break;
}
}
String urlencode(String str) {
String encodedString = "";
char c, code0, code1;
for (int i = 0; i < str.length(); i++) {
c = str.charAt(i);
if (c == ' ') {
encodedString += '+';
} else if (isalnum(c)) {
encodedString += c;
} else {
code1 = (c & 0xf) + '0';
if ((c & 0xf) > 9) code1 = (c & 0xf) - 10 + 'A';
c = (c >> 4) & 0xf;
code0 = c + '0';
if (c > 9) code0 = c - 10 + 'A';
encodedString += '%';
encodedString += code0;
encodedString += code1;
}
}
return encodedString;
}
-
실습 준비
-
- " https://www.data.go.kr/ " 공공데이터 포털에 접속한다
-
- "한국환경화_에어코리아_대기 오염정보"를 활용하여 신청을 진행한다
-
- serviceKey 를 무조건 복사해야한다. (복사해두지 않으면 실습 진행불가)
