14주차 스마트디바이스 (API) - jungjaeyeol/jyeol03 GitHub Wiki

📘 API란?

APIApplication Programming Interface의 약자로,
응용 프로그램 간에 정보를 주고받거나 기능을 사용할 수 있도록 도와주는 인터페이스입니다.

📌 쉽게 말해, 서로 다른 프로그램끼리 소통할 수 있도록 돕는 "번역기" 역할을 합니다.


🍽️ 비유로 이해하기 – 레스토랑 예시

  • 손님: 사용자
  • 주방: 서버
  • 웨이터: API

손님이 음식을 주문하면 웨이터(API)가 주방에 전달하고,
주방이 만든 요리를 다시 손님에게 전달합니다.
이처럼 API는 요청과 응답을 중개하는 역할을 합니다.


🌐 API의 실제 예

  • Google Maps API: 웹사이트에 지도를 삽입할 수 있음
  • 카카오 로그인 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() {
  // 여기에 동작 반복 로직을 넣을 수 있습니다
}
  • 실습 결과

🤓 실습2 (한국 시간 표기)

  • 실습 코드
#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;
}
  • 실습 준비

    1. " https://www.data.go.kr/ " 공공데이터 포털에 접속한다
    1. "한국환경화_에어코리아_대기 오염정보"를 활용하여 신청을 진행한다
    1. serviceKey 를 무조건 복사해야한다. (복사해두지 않으면 실습 진행불가)

실습 결과

⚠️ **GitHub.com Fallback** ⚠️