최종프로젝트에서 뭘 했는지 시간이 지나 까먹기 전에, 기록 차원에서 글을 남겨 본다.

 

0. 기술 스택 변경 

도저히 진도가 나가지 않는 Node Js 기반의 서버 활용을 그만두고, JSP/Servlet 기반으로 돌아가기로 했다.

간단한 기능 구현 조차도 자꾸 막히고, 시간은 촉박하게 다가오는지라 만장일치로 변경하게 되었다.

일단 전반적인 숙련도가 너무 부족해서 기능 구현을 위해선 끊임없이 배워야 하는데, 하나 해결하면 막히고 하나 해결하면 막히고...정말 미칠 뻔 했다.

 

1. 개발환경 재 셋팅

앞서 사용했던 라즈베리파이를 DB Server로 사용하고 있기에 그에 맞춰 JDBC 드라이버를 변경해서 사용했다.

드라이버로는 mariadb-java-client-2.7.4 사용, 프로젝트 내 WEB-INF/lib 폴더에 복사하여 사용.

 

연결코드는 다음과 같이 변하게 되었다.

ERD 다이어그램, device_seq로 기본 키가 잡혀있는데...이걸 신경 못 쓰고 넘어가 막판에 후회 진짜 많이 했다.

 

2. 센서별 테스트 

초기에는 ESP32 개발보드를 사용하기로 했었다.

다만 주력으로 사용하는 MQ 계열 센서, ZE08-CH2O 센서와의 라이브러리 호환성이 맞지 않고, 

Node MCU ESP-32S 보드의 경우, 보드 리버전에 따라 버그가 있는 경우가 있는데 하필 또 해당되는 보드라

업로드 할 때마다 버튼을 눌러 업로드 모드로 전환시켜줘야 코드가 들어간다고 한다.

 

그래서 결국 돌고 돌아 메가로 도착...

도착한 센서들을 같이 구매했던 도서, 구글 검색결과로 나오는 자료들과 함께 개별 테스트를 먼저 진행했다.

 

포름알데히드 센서의 경우 ZE08-CH2O라는 센서를 사용했는데

연결 방법엔 세가지가 있다..DAC, UART, DFRobot등등..

DAC 방식이 간단해서 그 방법으로 했는데, 멀쩡한 환경인데 자꾸만 Bad가 나와 UART 방식으로 선회,

또다른 문제 봉착으로 인해(코드 통합 시 측정이 진행되지 않음) 결국 DFRobot 방식 썼음.

 

3. MQTT 통신 접목

 

자꾸만 멘토분이 이야기하는 방향과 기술이 멀어저가던 중, 팀장 형이 MQTT에 대해 공부해보더니 이걸 써보자고 했다.

그래서 ESP 8266에서 돌아가게 할려고...꼬박 하루를 고생하던 중 펌웨어 업데이트를 다음과 같이 진행했더니 써먹을 수 있게 되었다.

 

https://mie96.tistory.com/entry/%EA%B4%91%EC%A3%BC%EB%B9%85%EB%8D%B0%EC%9D%B4%ED%84%B0%ED%95%99%EC%9B%90-ESP-8266-%EB%AA%A8%EB%93%88%EC%9D%84-%EC%89%BD%EA%B2%8C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-%EC%9C%84%ED%95%9C-%EA%B0%80%EC%9D%B4%EB%93%9C

 

(광주빅데이터학원) ESP-8266 모듈을 쉽게 사용하기 위한 가이드

2차 프로젝트에서 기존 1차에서 쓰던 방식 (AT 커맨드를 통해 ESP-8266 모듈을 직접 제어하고, GET 방식으로 센서 값 전송) 을 그대로 쓸려다 MQTT 통신을 써 볼려니 문제가 생겼다. ESP8266과 ESP 01 어댑

mie96.tistory.com

PubSubClient 라이브러리에서도 통신기능을 위해 와이파이 라이브러리를 가져다 쓰니 작업이 필수였다. 

 

MQTT 통신의 경우 다음과 같은 도식도를 따른다.

 

우리 시스템의 경우

아두이노에서 각종 환경센서에 대한 정보를 Sensor/total라는 topic으로 publish 하면, 

중간에 라즈베리파이가 이를 중계해주고, 웹 서버에서 topic를 구독해서 값을 받아오게끔 했다.

타 팀이 하고 있던 통합 모니터링 시스템에서는 이러한 topic를 구독만 해 오면 값을 받아올 수 있게 되는 것이다.

 

반대로 각 센서별로 제어하기 위해 마일스 함수를 사용하고, 센서별로 토픽을 각각 만들어 publish 했고, 반대로 웹에선 이러한 내용을 구독한 후, 토픽을 실어 (측정 주기) 보내면 적용되게끔 했다.

 

4. Broker Server 구축 및 통신 테스트 

 

다음과 같은 명령어를 차례대로 입력해 설치를 했다. 

$ wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key
$ sudo apt-key add mosquitto-repo.gpg.key 
$ cd /etc/apt/sources.list.d/
$ sudo wget http://repo.mosquitto.org/debian/mosquitto-bullseye.list
$ sudo apt-get update
$ sudo apt-get install mosquitto mosquitto-clients

+로컬 네트워크 환경이면 별다른 설정 필요 없으나 외부에서 접속 시 설정파일 수정이 필수다!

 

mosquitto_sub -t sensor/#

#의 경우 해당 토픽 아래의 모든 내용을 가져오는 명령이다.

 

원래는 센서별로 토픽을 지정했으나, 분류하는 과정이 복잡하고, 오류가 자꾸 발생해서 JSON 형식으로 토픽을 보내도록 했다. 

 

mid는 원래 +"mid_1" 식으로 붙혔는데, 자바에서 파싱할 때는 괜찮았으나 통합모니터링시스템의 Node Js 환경에선

문제가 발생해 "\"mid_1\"" 식으로 수정했다.

 

 

5. 외형 조립 및 발표 준비 

 

조립이야 어렵진 않았다. 플라스틱 케이스에 폼 양면테이프 사용.

 

하지만 발표 준비가 진짜 어려웠는데, 6인의 팀원이 절반 절반 나눠 3인은 프론트엔드 (PC/모바일 웹), 3인은 IoT 파트를 담당해서 진행하다보니 프론트엔드 팀은 IoT를 아예 모르고, IoT 팀은 프론트엔드 파트에 약점이 생겨버릴 수 밖에 없었다.

 발표자가 프론트엔드 팀이였는데, 할 말이 너무 많아 IoT 팀원들이 같이 붙어서 원고 봐주고 설명해줬는데도

말을 줄이자니 이해하기 어려울 것 같고, 그렇다고 넣자니 발표자가 대본 암기하기 어려울 것 같고...

그래서 대본을 들고 올라갔는데 불이 꺼지는 바람에 대본도 보기 힘들었다고 한다. 발표자가 진짜 고생이 많았지..

 

 

6. 대망의 발표 당일

 

02:11:04 부터 보면 된다. 팀원 소개 시간 때 내 역활에 대해서 잘 써 놨는데 너무 떨린 나머지 얼버무리고 말았다. 어휴..

 

 

 

7. 후기

 

 그냥...일주일만 더 빨리 Node Js 포기하고 JSP/Servlet으로 선회할껄 그랬다. 개발 범위 설정과 시간 분배에 성공해서 

남들 프로젝트할 때 미리 끝내고 다른 조 도와주고, 발표준비했던 1차 프로젝트와는 달리, 개발 범위 설정과 시간 분배에

실패했던 것 같다. 멘토의 방향을 잘못 이해하다보니 MQTT 도입도 늦어졌고, 기능 구현도 쉽지는 않았다.

일단 예제도 없고, 심화로 갈려니 정말...머리 터지는 줄 알았다. 

사실 만든 것도 버그 투성이다. ESP8266을 쓴 건 좋은데 너무 불안정하고, 웹서버에서 넘어오는 토픽도 받아질 때도 있고 자기 맘대로 동작한다. 이것저것 코드를 다 집어넣어놔 분리시켜 라이브러리화 시키면 좋은데 C++과 자바의 클래스 구조에는 차이도 있고, 분리해보려는 데 시간이 너무 촉박했다. 

 사실 DB도 1차처럼 내가 좀 봐줬어야 하는데 (기기번호(자동증가 컬럼)으로 식별하기 보단 기기 SN로 구별하는 게 좋은데, 신경 못 쓴 사이에 기기번호로 식별하도록 모든 VO, DAO가 짜여져서 그 부분이 좀 아쉬웠음) 그러질 못했다.

 

운이 좋아 최우수상까지 수상했지만 시간관리 측면에서 참 생각이 많아진 프로젝트였다. 

 

 

 

 

기업 연계프로젝트 참여와 팀 내 아이디어를 기반으로 하여 프로젝트를 진행할 수 있었는데,

개인적으론 반대했지만, 팀원들의 뜻에 따르기로 하고, 기업 연계 프로젝트에 참여하게 되었다.

(마음고생도 되게 많이 했다..)

 

 

 

 

요구되는 기술 스택들에 대해 별 안내 없이 들어서 더 거부감이 컸던것도 있다. (이걸 다 써야 하는거야?)

 

같은 과정을 듣는 다른 분반 팀들과 협업 형식으로 진행이 되는데,

 

크게는 대립이

 

"각자 전체 서비스를 소형화 시켜 구현하는 것이다. vs 센서 수집 시스탬과 전체 관제 시스템을 두 팀이 나눠 진행한다."

"프로젝트 발표를 한 팀이 전담하는 것은 부당하다. vs 굳이 두 팀 각자 같은 주제로 발표할 필요가 있나?"

 

라는 내용에서 발생했지만

 

"센서 수집 시스템은 A분반 팀이 진행하고, 통합 관제 시스템 및 비콘 출입관리 시스템은 B분반 팀이 진행한다."

"발표는 각자가 개발한 기능에 초점을 맞춰 진행하고, 기타 문서는 통합이 가능하면 통합하는 순으로 한다."

 

로 Fix가 되어 얼마 전 부품 선정을 마치고, 학습에 필요한 도서도 주문 완료 했다.

 

그래서....내가 맡은 웹서버 구현 및 데이터베이스 구축, 라즈베리파이 셋팅 및 환경 백업의 과정을 요약해보고자 한다.

 

 

0. 라즈베리파이 원격 접속 설정

 

자주 쓰게 될 SSH와 VNC를 활성화 해주었다. VNC가 연결되었을 때의 해상도도 별도로 설정함.

 

1. mariaDB 설정 및 node.js 최신버전 설치

 

//mariadb 설치
sudo apt-get install mariadb-server

//mariadb 보안 설정, 입력 한 후 내용 읽어보며 진행하기.
sudo mysql_secure_installation

//관리자 계정으로 접속, 모든 ip에 대한 허용 진행
sudo mysql -u root -p 설정했던 비밀번호

//계정 생성 및 비밀번호 설정
create user'사용자명'@'호스트명' identified by '패스워드';

//모든 데이터베이스에 대한 접근권한을 특정 사용자에게 부여하는 명령
GRANT ALL PRIVILEGES ON *.* TO '사용자명'@'호스트명' IDENTIFIED BY '패스워드';
//호스트 명을 *.*로 해두면 모든 IP에서 접속이 가능하다. 다만 보안설정은 필수!

flush privileges;

// mariadb 서비스 종료, 시작, 재시작
sudo service mysql stop
sudo service mysql start
sudo service mysql restart

 

다음 경로의 파일을 열어준다.

sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf

 

bind-address 가 기본 값으론 127.0.0.1로 되어있는데, 이를 *로 바꾸어 준다.

Ctrl +x로 나가면서 y 입력하고 빠져나간 후 서비스를 다시 시작해준다.

 

기존 개발환경과 일치시키기 위해 nodejs의 버전을 업데이트 시켜준다. 현재 기준 최신 LTS 버전은 

16.13.1이지만, 라즈베리파이에는 이보다 이전의 버전이 설치되어 있을 것이다.

 

//설치된 nodejs의 버전 확인
node -v

//구버전 node.js 삭제
sudo apt-get remove nodejs
sudo apr-get autoremove -y

//패키지 저장소와 버전 비교
apt list | grep nodejs

//nodejs 패키지 저장소 최신화
sudo curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -

//갱신 여부 확인
apt list | grep nodejs

//최신버전 nodejs 설치
sudo apt-get install nodejs -y

 

2. vsCode 설치 및 ufw(리눅스 방화벽) 설치, DB 및 자주 쓰는 포트 열기

//vsCode 설치 
sudo apt-get install code -y

//방화벽 설치
sudo apt-get install ufw -y

일단 확실하게 열어야 할 포트는 SSH 사용을 위한 22번 포트, VNC Viewer를 위한 5900포트, mysql에서 사용되는

3306 포트가 되겠다. (필요한 포트가 있다면 포트번호만 바꾸는 방식으로 열어줄 수 있으니 걱정 마시라..!)

기본 정책상으론 들어오는 포트는 모두 닫혀있기에 필요한 포트만 열어주는 식으로 작업했다.

//방화벽 활성화
sudo ufw enable

//방화벽 끄기
sudo ufw disable

//포트 허용
sudo ufw allow '포트번호'

//포트 차단
sudo ufw deny '포트번호'

모든 작업이 되었다면 한번 방화벽을 껐다가 다시 켜 주자.

 

테스트 해 본 결과이다. 

 

 

번외 :: 라즈베리파이 환경 백업하기

저장장치로 마이크로 SD카드가 아닌 외장 SSD를 사용중에 있는데, 스냅샷 겸 현재 상태를 이미지 화 시키고 싶었다.

Win32diskimger32의 경우 모든 섹터를 저장하니 저장장치 크기만큼 점유한다는 문제가 있어 알아보던중...

Acronis True Image를 이용하기로 했다. 마침 학원 PC의 SSD가 WD 제품인지라..for Western Digital 버전을 다운로드, 

백업을 진행하고 테스트를 해 봤는데...정상동작한다!

 

ex)단, 사양차이가 나는 라즈베리파이의 모델 간 작업 시에는 오류가 발생할 가능이 높다.

특히 상위 모델에서 백업한 이미지를 구형 모델에 복원 시킬 경우 오류 발생하는 빈도가 높았다.(직접 당함)

라즈베리파이 3/3+에서 백업한 자료를 라즈베리파이 4에 작업 할 경우 - 정상 동작

라즈베리파이 4 4기가 모델에서 백업한 자료를 라즈베리파이 4 2기가 모델에 작업할 경우 - 오류 발생

하지만 동일 기기의 백업 목적으로는 사용하기가 좋다. 

 

 

 

 

일정

 

2021.10.11~2021.10.16

아이디어 브래인스토밍 및 멘토링 기획서 작성, 아이디어 선정, 필요 부품 주문

 

2021.10.18~2021.10.25

요구사항 정의서, DB 설계, 기획서 작성 및 DB 설계 확정

 

2021.10.26~2021.10.30

GitHub 사용법 학습 및 레퍼지토리 생성, 칸반보드 작성 시작.

아두이노 - 웹서버 간 통신 테스트. 기초 감지 로직 작성.

각 기능을 위한 DAO / VO 설계 및 SQL 쿼리문 작성, 테스트

웹페이지 레이아웃, 페이지 배치 및 배경화면 변경, 

 

2021.11.01~2021.11.04

일산화탄소 농도에 따른 기기 동작 코드 작성

발표 자료 제작 및 최종 검수

시제품 제작 및 동작영상 촬영, 질의응답 대비

담당 Part

데이터베이스 설계 및 시퀸스 생성.

GetSensor 서블릿 작성 및 DAO 설계

SQL 쿼리문 작성 및 테스트

아두이노 센서, 네트워크 통신테스트, 주 로직 설계, 시제품 제작.

기타 프로젝트간 팀원들 파트 막히는 부분 AS 및 조율 - DB, SQL, 서블릿, 아두이노

 

1주차(2021.10.11~2021.10.16) 진행 과정

0. 아이디어 도출 (브래인스토밍 진행) & 아이디어 멘토링

내부에서 아이디어를 선정해서 멘토링을 받기 보단 다 모아서 가자는 생각으로 아이디어를 모아 다음과 같이 작성했다.

브래인스토밍 과정

브래인스토밍으로 도출한 아이디어를 가지고 멘토링을 받았다.

내가 제안했던 유해가스 감지기 및 경보기만 살아남아 보충할 점에 대해 의견을 들었다. 

알림까진 좋으나 신고 기능에 대해 보강할 점이 필요해 해당 부분은 진행하면서 생각하기로 의견을 종합했다.

 

1.부품 주문

아이디어에 필요한 부품들을 주문하는 절차를 가졌다. 장바구니에서 바로 엑셀을 뽑을 수 있다는 장점, 

대학교때 잘 썼던 디바이스마트에서 주문을 했으나...그게 나중에 대참사가 될 줄은 몰랐다.

부품 선정 및 주문서 작성.

 

2주차(2021.10.18~2021.10.25) 진행 과정

1. 데이터베이스 테이블 명세서, 테이블 정의서 작성

여기서 생각보다 시간이 많이 걸렸다. 나머지 문서야 팀원들이 분담해서 작성하고, 내가 봐주면서 보강해주면 되는 것이라 어렵진 않았지만...몇번을 갈아 엎은지를 모르겠다. 멘토링 받으며 해결.

 

데이터베이스 요구사항 정의서
관리자 회원정보 테이블

 

3주차 (2021.10.26~2021.10.30) 진행 과정

0. 아두이노 네트워크 통신 테스트

값이 넘어올 JSP 파일을 만들어 통신 테스트를 진행.

아두이노 코드를 작성했다.

ESP8266 모듈과 메가보드를 사용하기에 소프트웨어시리얼을 사용하지 않았다.

아두이노 코드 링크 >> https://github.com/SkyBlaze96/Toyproject/blob/main/MQ_9_WebServerChange.ino

정상적으로 넘어가는 것을 확인한 뒤 서블릿 설계에 들어갔다.

 

1. GetSensor & DAO 메서드 생성

파일명 확장자를 안 붙힌 체 서블릿 파일명을 지정하면 바로 프로젝트 내의 자바 리소스에 접근할 수 있게 된다.

DAO는 미리 생성해놨기에 GetSensor 서블릿을 만들고, DAO로 넘어가 메서드를 만들었다.

GetSensor 서블릿

 

DAO 내 InsertSensor 메서드

아두이노에 RTC 모듈을 달지 않아 일단 시간은 네트워크에 전송이 되었을 때 그 때 서버 시간을 넣어줄 수 있도록 

SimpleDateFormat를 사용했다. 

그리고 쿼리문이 진짜 긴데...목적을 설명하면 다음과 같다.

 통합 정보 테이블의 모든 컬럼에

 1) 관리 번호는 자동 부여 (시퀸스)

 2) 관리자 번호는 사용자 정보 테이블에 들어있는 기기 아이디와 입력받은 기기 아이디와 일치하는 관리자 번호

 3) 사용자 번호는 사용자 정보 테이블에 들어있는 기기 아이디와 입력받은 기기 아이디와 일치하는 사용자 번호

 4) 입력받은 기기 아이디 

 5) 입력받은 가스 농도

 6) SimpleDateFormat의 시간정보

이런 걸 넣고자 하는 쿼리문이다.

 

3. 기초 로직 설계 및 동작설계

설정한 평균농도에 따라 가스벨브를 잠그고 (솔레노이드벨브) 환풍기를 동작시키며 경고 알람을 동작시키고, 

해당 상황이 되었을 때 외부 웹서버로 이를 전송하도록 큰 틀을 잡았다.

 

단순히 아두이노 코드 내의 void loop() 내에 작성하면 무조건 보내기만 하니 

조건문을 걸어 평균농도가 일정 수치가 넘고, 60회(테스트 편의를 위해 10회로 조정함)할 때만 

값을 보내도록 하고, 카운트 변수를 초기화하도록 설정했다.

값이 정상화되면 모든 외부 릴레이, 부저 동작을 멈추게끔 하고 싶어 조건문 내에 중지하는 함수를 호출하게 했더니

멈추거나 아니면 값이 안 넘어가는 경우가 생겼다.

 

그냥 외부 릴레이 함수를 평균 계산하고 타이머 누적하는 함수에서 호출하도록 변경했다.

 

4. Github 칸반보드 작성

지금이야 모두 마무리되서 Done에 가 있지만

크게 해야 할 일을 To Do에 작성, 그날 그날 진행중인걸 In progress에 넣는 식으로 작성을 했다.

 

3주차 (2021.11.01~2021.11.04) 진행 과정

 

0. 프로토타입 조립 및 시연 영상 촬영

포맥스 3T로 외형을 만들고, 글루건과 록타이드 본드를 사용했다. 

배선의 문제인지 역전류의 문제, 전류량 문제인지는 모르겠으나 아두이노와 솔레노이드 벨브를 12V 어댑터 전원을

사용하도록 연결하니 릴레이가 동작하는 시점(즉, 솔레노이드 벨브에 전원이 인가되는 순간)에 보드가 리부팅 되는

문제가 있었다.

일단 동작 영상은 찍어야 하니 여분의 릴레이로 교체하고, 아두이노 전원인가는 USB 포트로 하도록 했다.

1.아두이노 내부 로직 완성

영상 촬영 및 테스트를 위해 수치를 낮게 설정했었는데 (평균농도 20ppm, 카운트 5회)

수치를 현실적인 경고기준으로 변경했다. (250ppm 이상이 3분 정도 지속되면)

2. 최종 발표 준비 및 문서 작업

시스템 동작 흐름도를 작성하고, 발표를 맡은 팀원과, 발표자료 제작 팀원 간 계속 확인해가며 발표준비를 진행했다.

+ Recent posts