벌써 5주차가 끝났습니다. 지난주 Qt강의를 듣고 금주 수요일까지는 Qt를 활용한 미니 프로젝트를 진행했습니다!!! 그리고 드디어 임베디드 수업이 시작되어쓰요 💗

빰빠빰~~~🎉

사실 데이터 입력, 수정, 삭제 등의 간단한 프로그램 구현을 목표로 시작했지만 하다보니 스케일이 점점 커졌다는 ...

동기들 중에는 게임을 만들기도 하고 주식 차트 확인 프로그램,간단한 은행 프로그램을 만든 팀들도 있었습니다.

그러나 벗! B.U.T .

저는 팀원과 함께 점심 식당 후기 공유 프로그램을 만들었습니다.
Velog에서 매주 점심 맛집 공유를 진행하면서 다른 사람들도 간단하게 맛있었던 식당이나 한식 뷔페 반찬 종류를 알려줬으면 좋겠다는 아이디어에서 출발했습니다!!!

간단하게 카카오맵 API를 긁어와서 대충 대충 끄적이면 될 줄 알았는데 그렇게 순탄치만은 않더라구요... ㅎㅎ

DB 설계

-- 사용자 (교육생)
CREATE TABLE User (
    user_id         INTEGER PRIMARY KEY AUTOINCREMENT,
    batch           INTEGER NOT NULL,        -- 회차 (: 23)
    name            TEXT NOT NULL,
    review_count    INTEGER DEFAULT 0,
    UNIQUE(batch, name)
);

-- 식당 (Kakao Map API에서 가져온 정보 + 카테고리 보강)
CREATE TABLE Restaurant (
    place_id        TEXT PRIMARY KEY,         -- Kakao place_id (고유)
    name            TEXT NOT NULL,
    category        TEXT,                    -- '한식', '양식', '카페' 등
    address         TEXT,
    road_address    TEXT,
    phone           TEXT,
    x               REAL,                    -- 경도
    y               REAL,                    -- 위도
    kakao_rating    REAL DEFAULT 0,          -- 카카오 기본 평점
    edu_rating      REAL DEFAULT 0,          -- 교육생 평균 평점
    review_total    INTEGER DEFAULT 0
);

-- 메뉴
CREATE TABLE Menu (
    menu_id         INTEGER PRIMARY KEY AUTOINCREMENT,
    place_id        TEXT NOT NULL,
    menu_name       TEXT NOT NULL,
    price           INTEGER,
    FOREIGN KEY(place_id) REFERENCES Restaurant(place_id) ON DELETE CASCADE,
    UNIQUE(place_id, menu_name)
);

-- 리뷰 (교육생 작성)
CREATE TABLE Review (
    review_id       INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id         INTEGER NOT NULL,
    place_id        TEXT NOT NULL,
    rating          REAL NOT NULL CHECK(rating >= 1 AND rating <= 5),
    review_text     TEXT,
    photo_path      TEXT,                    -- 로컬 저장 경로 (: ./photos/xxx.jpg)
    menu_name       TEXT,                    -- 추천 메뉴 (선택)
    created_at      DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY(user_id) REFERENCES User(user_id),
    FOREIGN KEY(place_id) REFERENCES Restaurant(place_id)
);

학생,식당,리뷰,메뉴 테이블을 구성하고 각 테이블 간의 관계를 설계했습니다. 여기까지는 갱장히 순탄했습니다.

  • 로그인 화면 및 Mainwindow 구성
  • 카카오맵 API 연결 및 DB 처리 function 작성
    으로 크게 역할을 분담하고 그 중 아래의 기능을 담당했습니다.

개발을 진행하며..

크고 작은 문제들이 많았지만 가장 문제가 되었던 것은 API의 제한적인 접근이었습니다.

Kakao Devleoper 에서 REST API키를 발급받아 현재 교육 장소 주변의 식당 검색이 가능했지만 호출 제한이 걸려있었습니다.

그래서 한번의 호출로 접근할 수 있던 식당은 45여개에 불과했습니다.‼️

시간을 두고 requset 요청을 하여 식당 정보를 받아올 수 있었지만 사용자 이용성 측면에서 답답하게 느껴질 것 같아 식당 DB정보를 제작하기로 결정했습니다.

https://data.seoul.go.kr/

위의 서울시 열린데이터 광장에서 강남구 일반음식점 인허가 정보 json 파일을 다운로드 받아 식당 DB를 구성했습니다.

각 식당 위치의 x,y좌표와 함께 도로명 및 지번 주소가 나오는데 실제 서비스 측면에서는 도보 거리 비교를 통해 범위를 설정해야하겠지만 임의로 적당히 걸어갈만한 거리의 식당을 정해 해당 x,y좌표와 교육 장소의 x,y 좌표의 차이를 이용해 거리를 구하고 해당 범위 이내의 영업 중인 식당을 추가했습니다.

여기서 예상치 못한 복병.

근처에 있는 KFC까지 범위로 하고 싶었는데 아무리 찾아도 안나오는게 아닌가...

알고 보니 서초구와 강남구 경계에 교육 장소가 있어 식당들이 대개 서초구에 있었다. 강남역에서 내려서 당연히 강남구만 있는 줄 -.-

그렇게 서초구 일반 음식점 인허가 정보도 다운로드 받아서 680여개의 식당 DB를 제작했다.

클래스 설계

사실 SQL DataBase를 처음 써봐서 이런 저런 애로사항이 많았다. 쿼리문 구현부터 DBManager class 구현까지.

model <-> view 

위의 관계를 통해 여러 dialog에서 재사용할 수 있는 model을 구현하고 싶었지만 하다보니 비슷한 기능이 중복되게 코드를 작성하였다.

#기능설명담당 클래스
1로그인이름 입력 → User 테이블에 삽입 (중복 방지)LoginDialog
2지도 기반 식당 로딩교육 장소 중심 1 km → Restaurant 테이블 저장/업데이트MapManager
3금주의 맛집 랭킹edu_rating → 상위 10개 리스트MainWindow, RestaurantModel
4교육생 리뷰 가점 반영리뷰 작성 시 edu_rating 재계산, review_count++DatabaseManager
5점메추 (점심 랜덤 추천)랜덤 1개 식당 팝업MainWindow
6카테고리별 순위 이동버튼 클릭 → CategoryRankDialog 열림MainWindow
7리뷰 등록평점(1~5), 사진(1장), 리뷰 텍스트, 메뉴 추천ReviewDialog
8랭킹 자동 갱신리뷰 등록 후 즉시 edu_rating 재계산 → UI 갱신DatabaseManager → RestaurantModel

각 기능에 맞는 클래스 구현을 통해서 프로그램을 완성했다.

기능 구현


로그인 화면메인 윈도우식당 검색
로그인메인 윈도우식당 검색
내가 쓴 리뷰 확인리뷰 작성식당 확인 및 이동
내가 쓴 리뷰 확인리뷰 작성식당 확인 및 이동

이렇게 간단하게 프로젝트를 마무리했다. 기능 구현이 바빠서 UI를 제대로 구현하지 못했지만 그래도 3일내에 Qt mini Project로는 재밌게 했다.

Feedback

식당 랭킹을 가져오기에 앞서 초기 랭킹은 카카오 평점을 기준으로 나타내려고 했다. 하지만 kakao map API로는 카카오 평점에 대한 접근이 불가능했다. 그래서 임의로 2~ 5.0으로 점수 배정을 하고 교육생 평점으로만 랭킹을 매기는 방식으로 바꿨다.
그리고 평점 표시에 있어 임의 점수와 교육생 점수를 색으로 구분해 실제 후기를 확인할 수 있게 했다.

객체 지향 프로그래밍에 있어 상속, 추상화, 캡슐화를 최대한 염두해 두며 코드를 작성하고 싶었지만 제한 시간 내에 해내려고 하다보니 많이 어려웠다. 이는 코드 리뷰를 통해서 구현 방식의 단점을 찾고 보완해나가겠다.

ARM Processor

본격적으로 ARM 프로세서 수업에 들어가기전에 임베디드 시스템의 구성요소를 배우며 컴퓨터 구조의 이론을 이해하는 시간을 가졌다.

STM32 , RaspBerry PI 4도 받았음. 드디어 임베디드 시작..
드과좌~~~

Architecture

core(@MCU) → 종류

  1. x86 i386

  2. x86 -64 i586 @ pc —> embedded

  3. ARM @mobile phone

    ⇒ Consumer Market [Home Appliance , mobile]

  4. PPC @pc —> @ embedded(network/aerospace & defense , industry, medical ,game

    ⇒ American/ Europe에서 주로 사용

  5. MIPS → Auto → ARM

  6. TriCore Pc→ Net → Phone

+SoC

ARM = 32bits (stm32F401re @Nucleo), 64bits(BCM7112 @ Raspberry pi)

+ROM

+RAM

  • Devices

기본적인 아키텍처를 배우며 startup.code의 동작 방식을 배웠다.

⭐⭐⭐ROM ⇒ Read Only memory

전역 변수는 data 영역에 저장 → 그러면 값이 변경 되었을 때 쓰기가 가능한가?  

no!!!

실행시 RAM으로 주소가 옮겨야 한다.  
LMA(load VIew) → VMA (virtual view)

그러면 주소를 누가 옮기나? 
Start-up Code [ startup.o] →linker가 알아서 붙여줌.

코드가 실행파일로 빌드 되며 생기는 ELF 파일의 section에 무엇이 저장되고 ROM에 저장된 ELF 명령어를 RAM으로 옮기고 실행하면서 startup.code의 역할이 무엇인지를 배웠다.

그리고 임베디드 프로그래밍에서 SoC를 새로 구성한다면 이러한 Startup code를 직접 재구성할 수 있다는 얘기를 들으며 머리가 뜨끈해지기도 했다..

😵‍💫😵‍💫😵‍💫😵‍💫😵‍💫

아직 나는 임베린이니까... 천천해 해보자.!

ELF section 구조

a.out (ELF) → section

  • .TEXT mov, adrp, bl 과 같은 실행 명령어가 들어간다. 대입의 - > move와 같은 시스템 아키텍처 명령어

  • .CONST(.rodata) : “hello word\n” 과 같은 문자열 리터럴이 들어감.

  • .DATA : 초기화된 전역 변수

  • .BSS : 초기화 되지 않은 전역 및 정적 변수.

💻gcc컴파일 단계 옵션 설명

명령어단계
$ gcc -E [소스 파일]전처리 (Preprocessing)
$ gcc -S [소스 파일]컴파일 (Compiling)
$ gcc -c [소스 파일]어셈블 (Assembling)
$ gcc -o [실행 파일 이름][입력 파일]출력 파일 지정 (Output)
$ gcc --save-temps [소스파일]중간 파일 저장 (Save Temps)

5주차 후기

번개 같이 지나간 한 주였다. 피곤이 몰려오지만 그래도 여전히 재미는 있다잉.

마무리로 늘 하던 식당 후기를 공유하며 끝내겠습니다.

돈카춘 뱅뱅사거리점

별점 ⭐️⭐️⭐️⭐️ (5점 만점)

푸짐한 더블 등심카츠와 눈치보이지만 리필가능한 장국과 밥
처음부터 조금 많이 주시면 서로 편할 것 같지만 어쩔 수 없다.

(아 소스는 테이블마다 구비되어 있습니다.)
https://naver.me/GoD7Jh8W

그러면 6주차 기록에서 SEE YOU SOON!!

profile
세상의 어려운 문제를 해결하자

0개의 댓글