How to make Geo-location Watch

2015. 10. 8. 14:542018년 이전 관심사/개발관련

반응형

How to make Geo-location watch

System Diagram

본 포스팅에서는 WizFi250과 WIZwiki-W7500을 이용하여 Geolocation Server에 접속해서 현재 내 위치를 알아 확인하고, NTP Server를 통해 시간을 가져오는 예제를 설명한다. 시스템 구성은 아래 그림과 같다.

20150626_171106

Materials

WIZwiki-W7500 ( MCU Platform)

wizwiki-w7500_main

WizFi250-EVB ( Wi-Fi Module )

ShopDtl_1203_20140918154919

Sensor Shield

TB2wSGHaFXXXXcLXXXXXXXXXXXX_!!33841454

SSD1306 OLED

  • Features
    • Resolution: 128 x 64 dot matrix panel
    • Power supply
      • VDD = 1.65V to 3.3V for IC logic
      • VCC = 7V to 15V for Panel driving
    • For matrix display
      • OLED driving output voltage, 15V maximum
      • Segment maximum source current: 100uA
      • Common maximum sink current: 15mA
      • 256 step contrast brightness current control
    • Embedded 128 x 64 bit SRAM display buffer
    • Pin selectable MCU Interfaces:
      • 8-bit 6800/8080-series parallel interface
      • 3 /4 wire Serial Peripheral Interface
      • I2C Interface
    • Screen saving continuous scrolling function in both horizontal and vertical direction
    • RAM write synchronization signal
    • Programmable Frame Rate and Multiplexing Ratio
    • Row Re-mapping and Column Re-mapping
  • On-Chip Oscillator
  • Chip layout for COG & COF
  • Wide range of operating temperature: -40°C to 85°C

Hardware Configuartion

WIZwiki-W7500 Board는 UART0 RX/TX/CTS/RTS 핀들로 WizFi250을 제어하고, I2C SDA/SCL 핀을 이용하여 SSD1306 OLED를 제어 한다.

20150626_204959

WizFi250-EVB Sensor Shield WIZwiki-W7500 SSD1306
RX-TX RXD TXD
TX-RX TXD RXD
CTS-RTS CTS D8
RTS-CTS RTS D7
WizFi250-RESET JP10-2 PA12
I2C SCL SCL PA9 SCL
I2C SDA SDA PA10 SDA
VCC VCC VCC
GND GND

Compile WizFi250 Geolocation_NTP Example

아래 주소에 접속하면 WizFi250 Geolocation_NTP Example를 이용할 수 있으며, Example에서 사용하는 라이브러리들은 아래와 같다.

WizFi250 Geolocation_NTP Example

SSD1306 Library

SSD1306 OLED를 사용하기 위해 Adarfruit GFX Library를 사용하였다. 이 라이브러리를 사용하는 중, Display() 함수에 약간의 버그가 있는 거 같아서 수정 후, 원작자에게 Pull Request를 보낸 상태이다. ( 원작자가 반영 해 줄 지는 모르겠다. )

Adafruit_GFX 수정
Adafruit GFX 원본

HTTP Client

HTTP Client Library는 이름에서도 알 수 있듯이, 외부에 있는 웹 서버에 Request와 Response를 송/수신 하기 위해 사용된다.
본 예제에서는 ip-api.com 서버에 접속해서 Geolocation(지리적 위치 코드)를 얻기 위해 사용되며, ip-api.com/csv 주소로 접속하면 csv 형태로 국가 이름, 주소, 위도(latitude), 경도(longitude), TimeZone 등의 정보를 얻을 수 있다.

아래 주소를 클릭하면 HTTP Client Library를 다운로드 할 수 있다.
HTTP Client

NTP Client

NTP Client Library는 UDP 통신을 이용하여 Network Time Server에서 UTC(협정 세계 시각)을 얻기 위해 사용된다. 본 예제에서는 한국의 NTP Server Domain인 kr.pool.ntp.org를 이용한다. NTP Server로 받은 정보는 UTC(협정 세계 시각)이므로, 9시간을 더해야 한국 시간을 알 수 있다.

NTP Client

Example Source Code

WizFi250-Geolocation_NTP

#include "mbed.h"
#include "Adafruit_SSD1306.h"
#include "WizFi250Interface.h"
#include "NTPClient.h"
#include "HTTPClient.h"


#define SECURE WizFi250::SEC_AUTO
#define SSID "wizohp"
#define PASS "wiznet218"


#if defined(TARGET_WIZwiki_W7500)
    #define SDA                  PA_10
    #define SCL                  PA_9
    WizFi250Interface wizfi250(D1,D0,D7,D8,PA_12,NC,115200);
    Serial pc(USBTX,USBRX);
#endif


// an SPI sub-class that provides a constructed default
class I2CPreInit : public I2C
{
public:
    I2CPreInit(PinName sda, PinName scl) : I2C(sda, scl)
    {
        frequency(100000);
        start();
    };
};

I2CPreInit gI2C(SDA,SCL);
Adafruit_SSD1306_I2c gOled(gI2C,NC,0x78,64,128);
NTPClient ntpClient;
HTTPClient httpClient;
void parse(char buffer[], int *j, char *string); //FUNCTION TO PARSE HTTP GET DATA
char httpGetData[200]; //BUFFER TO HOLD DATA FROM HTTP GET REQUEST


int main()
{
    time_t ctTime; //system time structure
    char success[10]={0};  //success first
    char countryFull[20]={0}; //Full Country Name
    char countryAbrv[5]={0}; //Abbreviated Country Name or country Code
    char stateAbrv[5]={0}; //Abbreviated State or region code
    char stateFull[15]={0}; //Full State Name
    char city[15]={0}; //City Name
    char zip[6]={0}; //ZIP CODE
    char latitude[10]={0}; //latitude
    char longitude[10]={0}; //longitude
    char timeZone[30]={0}; //timeZone
    int j=0, returnCode;

    pc.baud(115200);
    gOled.begin();
    gOled.clearDisplay();

    wizfi250.init();
    returnCode = wizfi250.connect(SECURE, SSID, PASS);

    if ( returnCode == 0 )
    {
        printf(" - WiFi Ready\r\n");
        printf("IP Address is %s\r\n", wizfi250.getIPAddress());
    }
    else
    {
        printf(" - Could not initialize WiFi - ending\r\n");
        return 0;
    }

    //HANDLES THE HTTP GET REQUEST THE WAY THE FUNCTION IS CALLED HERE IS THE FOLLOWING
    // get(DOMAIN_NAME,BUFFER,TIMEOUT_VAL)
    //DOMAIN_NAME= domain name that get request is sent to
    //BUFFER= buffer to store data returned from the server
    //TIMEOUT_VAL= Time before the request times out
    HTTPResult r = httpClient.get("http://ip-api.com/csv",httpGetData,128); //GET GEOLOCATION DATA (CSV)

    if (r==HTTP_OK) { //IF THE DATA WAS RECIEVED
        j=0;
        //parse and display each of the API's location information strings on the LCD
        parse(httpGetData, &j, success); 
        parse(httpGetData,&j,countryFull);
        parse(httpGetData,&j,countryAbrv);
        parse(httpGetData,&j,stateAbrv);
        parse(httpGetData,&j,stateFull);
        parse(httpGetData,&j,city);
        parse(httpGetData,&j,zip);
        parse(httpGetData,&j,latitude);
        parse(httpGetData,&j,longitude);
        parse(httpGetData,&j,timeZone);
        gOled.printf("HTTP Data Received\r\n");
        gOled.display();
    } 
    else { //HTTP GET REQUEST ERRORED
        gOled.printf("HTTP Error %d\r\n", r);
        gOled.display();
        return -1;
    }
    printf("Reading Time...\r\n");
    char* domainName="kr.pool.ntp.org"; //SET TO DOMAIN NAME OF SERVER GETTING TIME FROM
    //GETS THE TIME FROM THE SERVER
    //setTime(DOMAIN_NAME,PORT_NUMBER,TIME_OUT)
    //DOMAIN_NAME= domain name
    //PORT NUMBER=port number (123 for NTP)
    //TIME_OUT= timeout value for request
    ntpClient.setTime(domainName,123,0x00005000);
    printf("Time Set\r\n");
    //Delay for human time to read LCD display
    wait(3.0);

    char buffer[80]; //BUFFER TO HOLD FORMATTED TIME DATA
    gOled.printf("%s, %s %s, %s\r\n",city,stateAbrv,zip,countryAbrv); //PRINT CITY STATE AND ZIP INFORMATION AND COUNTRY
    gOled.printf("LAT:%s\r\nLONG:%s\r\n",latitude,longitude); //PRINT LATITUDE AND LONGITUDE 
    gOled.printf("Timezone:%s\r\n",timeZone); //PRINT TIMEZONE

    wizfi250.disconnect(); //DISCONNECT FROM THE NETWORK 
    while (1) {
        //ctTime = time(NULL)-(3600*4);  //TIME with offset for eastern time US
        ctTime = time(NULL)+(3600*9);  //TIME with offset for eastern time KR
        //FORMAT TIME FOR DISPLAY AND STORE FORMATTED RESULT IN BUFFER
        strftime(buffer,80,"%a %b %d\r\n%T %p %z\r\n %Z\r\n",localtime(&ctTime));
        gOled.printf("Univ Time Clock\r\n%s\r\n", buffer);
        gOled.display();
        gOled.setTextCursor(0,40);
        wait(1);
    }      
}

//SET FOR CSV FORMAT: NEEDS TO BE EDITED IF DIFFERENT FORMAT
void parse(char buffer[], int *j, char *string) {
//extracts next location string data item from buffer
    int i=0;
    for (i=0; i<=strlen(buffer); i++) {  //TOTAL SIZE OF RETURNED DATA
        if ((buffer[*j+i] == ',')||(buffer[*j+i] == '\0' )) { //IF comma or end of string
            //comma is the string field delimiter
            string[i]=0; //SETS END OF SRTRING TO 0
            *j=*j+i+1; //UPDATES to 1 after comma seperated value
            break;
        } else string[i]=buffer[*j+i]; //Keep adding to the string
    }
}

Demo Video


반응형