top of page
블로그: Blog2

코인 Ticker 만들기 #17.전체소스 설명

최종 수정일: 2019년 2월 18일

이번 강좌에서는 그동안 배원던 정보를 기초로 코인 Ticker 소스를 설명드리는 시간을 갖도록 하겠습니다.


소스의 전체 흐름은 아래와 같습니다.


1. 프로그램 내에서 필요한 변수 및 객체 선언

2. setup()

2.1 환경설정

2.2 Wifi mode 확인

2.3 Wifi mode에 따른 분기

2.3.1 AP 모드 처리

2.3.2 STATION 모드 처리

2.3.2.1 고정IP 방식 처리

2.3.2.2 유동IP 방식 처리

3. loop()

3.1 AP 모드 처리

3.2 STATION 모드 처리

3.2.1 코인 정보 처리

4. 웹서버 index 페이지 메서드

5. 환경설정 정보 저장 메서드

6. 코인 API 관련 메서드


소스를 단계별로 설명드리도록 하겠습니다.


1. 프로그램 내에서 필요한 변수 및 객체 선언

- 이 단계는 프로그램에서 사용되는 변수 및 객체에 대해서 선언하는 부분입니다.

#include <ESP8266WiFi.h>

#include <ESP8266WebServer.h>

#include <WiFiClientSecure.h>

#include <EEPROM.h>

#include <Timer.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#include <ArduinoJson.h>


- 이 부분은 코인 Ticker 프로그램과 관련된 헤더정보를 참조하는 부분입니다.


#define OLED_RESET 0 // GPIO0


- OLED 관련된 상수로 OLED 관련 객체를 최초 생성할때 OLED를 RESET 해주기위한 상수입니다.


#define debug Serial


- Serial 모니퍼에 대해서 debug 라는 상수이름으로 사용합니다.


#define ip_dhcp 0

#define ip_static 1


- Station 모드에서 고정IP 와 유동IP 를 구분하기위한 상수입니다.


#define LED0 D4 //LED_BUILTIN

#define FN_SW D5 //function key (주의.D3나 D4는 RX, TX 포트이므로 사용금지)


- LED 는 내장 LED를 사용하며, AP모드 전환을 위한 FN_SW 로 D5를 사용한다는 상수입니다.


#define station 1

#define ap 0

#define ap_set 2


-- AP 모드와 AP_SET 모드, STATION 모드를 구분짓기 위한 상수입니다.


#define addr_mode 0

#define addr_iptype 10

#define addr_init 20


#define addr_ssid 100

#define addr_pwd 200

#define addr_ssid_length 150

#define addr_pwd_length 250


#define addr_ser_ip1 300

#define addr_ser_ip2 310

#define addr_ser_ip3 320

#define addr_ser_ip4 330

#define addr_dev_ip1 340

#define addr_dev_ip2 350

#define addr_dev_ip3 360

#define addr_dev_ip4 370


- EEPROM 에서 데이터를 읽을 위치정보를 갖고 있는 상수입니다.


byte mac[6];

byte serverIP[4];

byte deviceIP[4];


- Wemos D1 mini 의 맥어드레스와 서버IP주소, 장치IP 주소를 기억할 byte 배열 입니다.


bool init_false=false;


- STATION 모드가 아님을 확인하는 변수입니다.


long timer_period=1000;


- 타이머를 주기를 관리하는 변수입니다.


bool ap_set_led=false;


- AP_SET 모드의 경우 LED를 깜빡이기 위한 변수입니다.


char* ssid;

char* pwd;


- Wifi 의 SSID 와 PASSWORD 를 관리하기 위한 변수입니다.


int cur_mode;


- 현재 모드를 기억하고 있는 변수입니다.


String header = "<!DOCTYPE html><html><title>coinMon Ticker Setting</title><head></head><body><BR>";

String footer = "</body></html>";


- 웹 index 페이지의 header 와 footer 입니다.

기본적으로 html 형식을 따릅니다.

unsigned long prev_time = 0; // Access Token 갱신용

String accessToken = "";


- 코인 API 의 ACCESS TOKEN 을 관리하기 위한 변수입니다.

현재 버전에서는 사용하지 않으며 차후 사용 예정입니다.

ESP8266WiFiClass Wifi8266;


- Wifi 와 관련된 작업을 처리하기 위한 객체입니다.


ESP8266WebServer Web(80);


- Wemos D1 mini 의 웹서버 포트를 80으로 설정합니다.


Adafruit_SSD1306 display(OLED_RESET);


- Adafruit 라이브러리를 이용하여 OLED 를 RESET 합니다.


EspClass esp;


- ESP8266 과 같은 ESP 계열의 IC 를 제어하기 위한 객체입니다.

이번 소스에서는 재부팅용으로 사용합니다.

IPAddress gateway={192,168,0,1};

IPAddress subnet={255,255,255,0};


- IP주소와 관련된 환경설정 변수입니다.

GATEWAY 와 SUBNET MASK 정보를 갖고 있습니다.

Timer t;


- 타이버 객체입니다.


2. setup()

2.1 환경설정

display.begin();

display.clearDisplay();

- OLED를 시작하고 화면의 내용을 지웁니다.


display.setTextWrap(false);

display.setTextSize(1);

display.setTextColor(WHITE);

display.setCursor(0,0);

- OLED의 글꼴 설정과 좌표를 설정합니다.


display.print("coinMon. ");

display.println("v.0.5");

display.display();

- 코인 Ticker 의 버전정보를 OLED에 표시합니다.


EEPROM.begin(4096); // 4M

- EEPROM을 4096 byte 로 설정합니다.

debug.begin(115200);

- 시리얼 통신 속도를 115200 으로 설정합니다.


pinMode(LED0, OUTPUT);

pinMode(FN_SW, INPUT);

- 입출력 핀을 설정합니다.

digitalWrite(LED0, LOW);

- 내장 LED 에 LOW 전압을 인가하여 LED 를 ON 합니다.

2.2 Wifi mode 확인


cur_mode = EEPROM.read(addr_mode);

- 현재 모드를 EEPROM 의 0번째 주소에서 읽어옵니다.

최초 아무것도 없습니다.(default nothing)

if (!digitalRead(FN_SW)||(cur_mode!=station)) //ap mode button

cur_mode = ap_set;

- FN_SW 입력이 GND 인경우, 현재 모드가 STATION 이 아닌경우 현재 모드를 ap_set으로 설정합니다.


if(EEPROM.read(addr_init)!=init_false){

cur_mode=station;

EEPROM.write(addr_init,init_false);

EEPROM.commit();

}

- EEPROM 의 0번째 주소값이 true(STATION 모드) 인경우

현재모드를 station 모드로 전환하고

EEPROM 의 0번째 주소에 false 를 저장합니다.

(AP 모드의 재진입을 위한 설정값 저장)

2.3 Wifi mode에 따른 분기

if (cur_mode != station) //if ap mode

- 현재 에 따라 분기합니다.


2.3.1 AP 모드 처리

Wifi8266.mode(WIFI_AP);

- Wifi 모드를 AP 모드로 설정합니다.


String macID = Wifi8266.softAPmacAddress();


- 맥어드레스를 확인합니다.

macID.toUpperCase();

- 맥어드레스를 대문자로 변환합니다.


String AP_NameString = "coinMon_" + macID;

char AP_NameChar[AP_NameString.length() + 1];

memset(AP_NameChar, 0, AP_NameString.length() + 1);


for (int i = 0; i < AP_NameString.length(); i++) {

AP_NameChar[i] = AP_NameString.charAt(i);

}


- AP 모드인경우 PC나 스마트폰으로 Wifi 검색을 하게 되는데

Wemos D1 mini 의 SSID 이름을 coinMon_맥어드레스 와 같이 명명하여

사용자가 확인할 수 있도록 합니다.

const char* AP_PwdChar = "20090609";


- AP 모드의 Wemos D1 mini 에 접속시 사용하는 비밀번호입니다.


Wifi8266.softAP(AP_NameChar, AP_PwdChar);


- Wemod D1 mini 를 AP 모드로 최종 설정합니다.


display.clearDisplay();

display.setCursor(0,0);

display.println("1. Connect WiFi : ");

display.println(AP_NameString);

display.println("2. Open WebPage : ");

display.println(Wifi8266.softAPIP());

display.display();

- AP 모드인경우 사용자에게 안내하는 정보를 OLED에 표시합니다.


Web.on("/", indexpage);

Web.on("/save", savepage);

Web.begin();

- 웹서버를 기동합니다.


t.every(timer_period, notconnect); //1sec timer init


- timer_period 주기(1초)마다 타이머 이벤트를 발생하여 notconnect 메서드를 수행합니다.

2.3.2 STATION 모드 처리

Wifi8266.mode(WIFI_STA);

- Wifi 모드를 STATION 모드로 설정합니다.


String macaddr = Wifi8266.macAddress();


- Wemod D1 mini 의 맥어드레스 를 받아옵니다.


String temp = "";

for (int i = 0; i < 6; i++) {

for (int j = 0; j < 2; j++) {

temp += macaddr[(2 * i) + j + i];

}

const char *tt = temp.c_str();

mac[i] = strtol(tt, NULL, 16);

}

- 맥어드레스 주소를 기억해 놓습니다.

이번 소스에서는 특별히 사용하는일은 없습니다.

int ssid_length = EEPROM.read(addr_ssid_length);

int pw_length = EEPROM.read(addr_pwd_length);

- EEPROM에 미리 저장된 공유기의 SSID와 PASSWORD 길이정보를 읽어옵니다.


for (int i = 0; i < ssid_length; i++)

str_ssid += (char)(EEPROM.read(addr_ssid + i));


- 공유기의 SSID 명을 EEPROM 에서 읽어서 str_ssid 변수에 담아놓습니다.


display.setTextColor(WHITE);

display.print("SSID:");

display.println(str_ssid);

- OLED 에 공유기 SSID 정보를 표시합니다.


for (int i = 0; i < pw_length; i++)

str_pwd += (char)(EEPROM.read(addr_pwd + i));


- 공유기 SSID 비밀번호 정보를 EEPROM 에서 읽어서 str_pwd 변수에 담아놓숩니다.

serverIP[0]=EEPROM.read(addr_ser_ip1);

serverIP[1]=EEPROM.read(addr_ser_ip2);

serverIP[2]=EEPROM.read(addr_ser_ip3);

serverIP[3]=EEPROM.read(addr_ser_ip4);

- 미리 저장된 server IP 정보를 EEPROM에서 읽어서 serverIP 배열에 담아놓습니다.


for(int i=0;i<4;i++){

debug.print(serverIP[i]);

if(i<3)

debug.print(".");

else

debug.println("");

}

- 공유기 SSID 에 접속되는 상태를 .으로 표시합니다.

2.3.2.1 고정IP 방식 처리

if(EEPROM.read(addr_iptype)==ip_static){//static

- 고정IP 방식에 대해서 처리합니다.



deviceIP[0]=EEPROM.read(addr_dev_ip1);

deviceIP[1]=EEPROM.read(addr_dev_ip2);

deviceIP[2]=EEPROM.read(addr_dev_ip3);

deviceIP[3]=EEPROM.read(addr_dev_ip4);

gateway[0]=EEPROM.read(addr_dev_ip1);

gateway[1]=EEPROM.read(addr_dev_ip2);

gateway[2]=EEPROM.read(addr_dev_ip3);

- 고정IP 정보를 EEPROM 에서 읽어옵니다.



for(int i=0;i<4;i++){

debug.print(deviceIP[i]);

if(i<3)

debug.print(".");

else

debug.println("");

}

- 고정IP로 접속되는 상태를 .으로 표시합니다.

Wifi8266.begin(ssid, pwd); //ans

Wifi8266.config(deviceIP,gateway,subnet);

Wifi8266.begin(ssid, pwd); //ans

- 고정IP로 접속합니다.


while (int state=Wifi8266.status() != WL_CONNECTED) {

Wifi8266.begin(ssid, pwd); //ans

delay(5000);

}


- 접속될때까지 5초마다 반복합니다.


display.clearDisplay();

display.setCursor(0,0);

display.println("static ip connection ok");

display.display();


- 접속 성공시 OLED에 접속정보를 표시합니다.


2.3.2.2 유동IP 방식 처리

}else{//dhcp

- 고정IP 방식이 아닌경우 유동IP 방식에 대해서 처리합니다.


Wifi8266.begin(ssid, pwd); //ans

- 공유기의 SSID 에 접속을 시도합니다.


while (Wifi8266.status() != WL_CONNECTED) {

- 접속이 성공할때까지 반복합니다.


waiting_timer++;

if(waiting_timer>20)

esp.restart();

}

- 20회까지 접속 성공을 못하면 Wemos D1 mini 를 재기동 합니다.

3. loop()


void loop() {


- 반복구를 실행합니다.


3.1 AP 모드 처리


if (cur_mode == ap_set) { //if ap mode

Web.handleClient();

t.update();

//timer update

}

- 현재 모드가 ap_set 인경우 웹서버를 기동하고 타이머를 update 합니다.


3.2 STATION 모드 처리

} else if (cur_mode == station) {


- 현재 모드가 station 인경우 처리를 합니다.


3.2.1 코인 정보 처리


const char* host = "api.korbit.co.kr"; // API를 호출하기위한 접속주소

String line = "";

unsigned long current_time = millis();

String refreshToken = "";


- 코인 API 주소정보와 현재시간, 토큰 재설정정보를 변수처리 합니다.


// 호스트 접속 여부 체크

WiFiClientSecure client = getConnection(host);


- 호스트로 접속 후 접속정보를 받아옵니다.


// KORBIT(시장 현황 상세정보)

// API 호출하여 결과 json 받기

line = getKorbitV1TickerDetailed(host, client);


- 코인 API 로부터 코인정보를 json 데이터로 받아옵니다.


// KORBIT(시장 현황 상세정보) 표시

//jSon Data Parsing

dispKorbitV1TickerDetailed(line);


- 받아온 코인정보 json 데이터를 OLED에 표시합니다.


digitalWrite(LED0, LOW);

delay(50);

digitalWrite(LED0, HIGH);

delay(50);

digitalWrite(LED0, LOW);

delay(50);

digitalWrite(LED0, HIGH);


- 내장 LED 를 깜빡입니다.


4. 웹서버 index 페이지 메서드


void indexpage() {

String ssid;

int netcount = WiFi.scanNetworks();

String s = header;

s += "<form method='post' action='save'>SSID: <select name='ssid'>";

for (int i = 0; i < netcount; ++i) {

ssid=WiFi.SSID(i);

s += "<option name=ssid>";

s += ssid;

s += "</option>";

}

s += "</select><br>Password: <input type='password' name='pw'>";

s += "<br><input type='submit' value='Save'></form>";

s += footer;

Web.send(200, "text/html", s);


}


- wemos D1 mini 웹서버의 index 페이지 구성을 합니다.

공유기의 Wifi SSID 목록을 콤보로 설정합니다.

비밀번호를 입력할 수 있는 입력상자를 하나 둡니다.

저장할 수 있는 저장버튼을 둡니다.


5. 환경설정 정보 저장 메서드


Web.send(200, "text/html", "<p>Your AP information is saved success!!<p></br>");


- 저장 성공시의 메시지를 웹서버에 보냅니다.


String rcvSSID=Web.arg("ssid");

String rcvPW=Web.arg("pw");

int lengthSSID=rcvSSID.length();

int lengthPW=rcvPW.length();


- EEPROM 에 저장하기 위해 SSID, PASSWORD, SSID 문자길이,PASSWORD 문자길이 를 변수화 합니다.


EEPROM.write(addr_mode,station);

- EEPROM 의 0번째 주소에 설정이후 모드는 station 모드임을 저장합니다.

현재는 ap_set 모드입니다.

이후 접속 시 station 모드로 기동됩니다.

for(int i=0;i<lengthSSID;i++){

EEPROM.write(addr_ssid+i,sid[i]);

debug.print(sid[i]);

}

- EEPROM 에 Wifi 의 SSID 정보를 저장합니다.


for(int i=0;i<lengthPW;i++){

EEPROM.write(addr_pwd+i,pid[i]);

debug.print(pid[i]);

}

- EEPROM 에 Wifi 의 PASSWORD 정보를 저장합니다.


EEPROM.write(addr_ssid_length,lengthSSID);

EEPROM.write(addr_pwd_length,lengthPW);

EEPROM.commit();

- EEPROM 에 SSID 문자길이, PASSWORD 문자길이를 저장합니다.


EspClass esp;

esp.restart();

- Wemos D1 mini 를 재기동합니다.


코인 API 부분은 API 마다 호출하는 방식이 다르기 때문에


따로 설명드리진 않습니다.


현재 코인 API 는 GET 방식으로 처리하고 있으며


GET 방식의 API 인경우 소스를 참조하여 사용하시면 됩니다.


이상으로 전체 소스에 대해서 설명드렸습니다.


감사합니다.


전체소스 파일은 아래 링크에 있습니다.

http://wix.to/00D5AKQ

 
 
 

コメント


Join our mailing list

Never miss an update

뉴스레터 구독하기

최신 업데이트를 받아보세요!

대한민국 경기도 수원시 장안구 연무동 21 유천프라자 가동 508호

  • facebook
  • twitter
  • linkedin

©2018 by 윈드마켓. Proudly created with Wix.com

bottom of page