February 6, 2025

디바이스마트 미디어:

[66호] 원하는 색상으로 제어가 가능한 아두이노 IoT 스마트 무드등 키트 -

2021-06-25

★2021 ICT 융합 프로젝트 공모전 결과 발표! -

2021-05-12

디바이스마트 국내 온라인 유통사 유일 벨로다인 라이다 공급! -

2021-02-16

★총 상금 500만원 /2021 ICT 융합 프로젝트 공모전★ -

2021-01-18

디바이스마트 온라인 매거진 전자책(PDF)이 무료! -

2020-09-29

[61호]음성으로 제어하는 간접등 만들기 -

2020-08-26

디바이스마트 자체제작 코딩키트 ‘코딩 도담도담’ 출시 -

2020-08-10

GGM AC모터 대량등록! -

2020-07-10

[60호]초소형 레이더 MDR, 어떻게 제어하고 활용하나 -

2020-06-30

[60호]NANO 33 IoT보드를 활용한 블루투스 수평계 만들기 -

2020-06-30

라즈베리파이3가 드디어 출시!!! (Now Raspberry Pi 3 is Coming!!) -

2016-02-29

MoonWalker Actuator 판매개시!! -

2015-08-27

디바이스마트 레이저가공, 밀링, 선반, 라우터 등 커스텀서비스 견적요청 방법 설명동영상 입니다. -

2015-06-09

디바이스마트와 인텔®이 함께하는 IoT 경진대회! -

2015-05-19

드디어 adafruit도 디바이스마트에서 쉽고 저렴하게 !! -

2015-03-25

[29호] Intel Edison Review -

2015-03-10

Pololu 공식 Distributor 디바이스마트, Pololu 상품 판매 개시!! -

2015-03-09

[칩센]블루투스 전 제품 10%가격할인!! -

2015-02-02

[Arduino]Uno(R3) 구입시 37종 센서키트 할인이벤트!! -

2015-02-02

[M.A.I]Ahram_ISP_V1.5 60개 한정수량 할인이벤트!! -

2015-02-02

[61호]라즈베리파이4 최대 성능을 위한 일체형 수냉쿨러 소개

12737695_tmp_b564366ec6742f2a6f852240715a91c84503view

디바이스마트,오픈소스/코딩교육 > 라즈베리파이 > 아답터/방열판/OS/기타,ITM,라즈베리파이4 일체형 수냉쿨러 [설영-240G],여름철에도 라즈베리파이의 최대 성능을 이끌어 줄 수 있는 강력한 일체형 수냉 쿨러입니다.디바이스마트,오픈소스/코딩교육 > 라즈베리파이 > 아답터/방열판/OS/기타,ITM,라즈베리파이4 일체형 수냉쿨러 [설영-120G],여름철에도 라즈베리파이의 최대 성능을 이끌어 줄 수 있는 강력한 일체형 수냉 쿨러입니다.

ITM

라즈베리파이4 최대 성능을 위한 일체형 수냉쿨러 소개

라즈베리파이는 영국에서 기초 컴퓨터 과 학 교육용 프로젝트 목적으로 개발한 신용카 드 크기의 초소형/초저가 PC를 말한다. 키보 드, 마우스, 모니터만 연결하면 어디서든 PC 가 될 수 있으며 센서, 액추에이터 들을 연결 하여 다양한 기능을 구현할 수 있어 많은 주 목을 받고 있다. 원하는대로 기능을 확장하거나 용도를 변 경할 수 있기에 코딩교육이나 프로그래머들 이 나만의 컴퓨터로 취미나 창작 형태로 많이 사용하며 무더운 여름날 또는 호환 제품 사 용에 따라 많은 열을 방출하기에 본래의 성 능을 발휘할 수 있도록 도와줄 수 있는 제품 이 필요할 것이다. 라즈베리파이4 일체형 수냉쿨러는 혹서기 에도 23도로 무덥지 않은 영국에서 개발된 라즈베리파이가 혹서기 최고기온 30도가 넘 는 한국의 무더위에 영향을 덜 받고 최대 성 능을 이끄는 데 도움을 줄 수 있다. 고밀도의 방열판 폴딩 구조를 통해 최대한 의 표면적으로 냉각수를 효율적으로 식힐 수 있으며, 열전도율이 높은 구리 베이스로 접촉 면이 넓고 정밀하게 가공되어있어 다양한 장 치에 적용이 가능한 특징이 있다. 또한, 고분자 소재의 FDP를 사용한 튜브로 고온에서도 냉각수 증발을 억제하여 라즈베 리파이의 열을 효과적으로 낮춰준다. 현재 디바이스마트에서는 모터 1개, 2개 타 입을 선택하여 구매가 가능하며 가성비 높은 라즈베리파이 유지 장치를 고민하고 있다면 지금 당장 수냉쿨러 제품을 확인해보길 바란 다.

구성품

· 라디에에이터 펌프 본체 1개

· 서멀그리스 주사기 1개

· CPU용 브라켓 1세트

· Y형 쿨링팬 전원 분배 케이블 1개 (240G 해당)

· 블루라이트 팬모터 2개

· 양면테이프 1개

· 각종 패스너 1세트

 

일체형 수냉쿨러 바로 확인하기 

[61호]웨스트 시스템의 신기술로 개발한 G/Flex 에폭시

12551471_tmp_4388de774c8199f34c102a1be755117e9936large

WEST SYSTEM

웨스트 시스템의 신기술로 개발한 G/Flex 에폭시

웨스트시스템의 에폭시는 1969년에 개발되 어 전 세계 유수의 요트 및 보트 제조사, 전 문 빌더 뿐만 아니라 아마추어 빌더, 초보자 에게까지 애용되고 있는 대표적인 마린 및 다 목적 에폭시이다. 웨스트시스템은 회사 설립 이래 선박용 에 폭시의 성능 개발, 웨스트시스템 수지와 경화 제의 배합, 테스트, 개선을 지속적으로 수행 하여 전 세계에서 가장 신뢰할 수 있고 균형 잡힌 에폭시 시스템을 공급하고 있다. 웨스트시스템의 신기술로 개발한 G/Flex 는 내수성, 다양한 소재에의 접착력이 우수할 뿐 아니라 질기면서도 유연한 새로운 에폭시 이다. G/Flex 에폭시는 탄력성 있는 고인성 2액 형 에폭시로 금속, 플라스틱, 유리, 벽돌, 유리 섬유 및 젖은 목재와 접합하기 힘든 목재에도 탁월한 접합력을 갖도록 설계되었기 때문에 알루미늄 보트의 보수와 PE 또는 ABS 재질 의 카누와 카약 보수용으로도 효과적이다. 또한 응용성이 뛰어나 웨스트시스템의 필러 와 첨가제를 사용해 사용자가 원하는 특성을 부여할 수 있다. 질기고 유연한 특성을 기반으로 한 G/Flex 에폭시는 탄성 복원력과 내충격성이 우수한 편이며 사용하기 쉬운 1:1 혼합 비율은 46분 의 가용 시간, 실온에서 75분의 긴 실용 시간 을 제공한다. 현재 디바이스마트에서 G/Flex 에폭시의 더 자세한 사양을 확인할 수 있으며 각종 에폭 시, 유리섬유, 수리 키트, 작업 도구 또한 함 께 판매 중이다.

웨스트시스템 에폭시 바로 확인하기

[61호]세계 1위, 최고의 품질 수준의 슈퍼커패시터

12552689_tmp_162fb145047142fceb0fe2ad6249f3916610view

VINATech

세계 1위, 최고의 품질 수준의 슈퍼커패시터

비나텍은 2010년 세계 최초로 3볼트급 슈 퍼커패시터를 개발함과 동시에 국내뿐만 아 니라 글로벌 시장에서 기술력을 인정받고 있 는 업체이다. 빠르게 성장하고 있는 커패시터 시장에서 기술 경쟁력을 바탕으로 비나텍의 슈퍼커패 시터 Hybrid-cap은 1000F이하급 슈퍼커패 시터의 시장점유율 1위를 기록하고 있으며 UL과 IATF, ISO, RoHS 기준을 만족하는 등 글로벌 대표 브랜드로 자리매김했다. 비나텍의 주력 아이템인 슈퍼커패시터는 에너지를 저장한 뒤 필요한 순간에 전류를 공급할 수 있는 에너지 저장 장치다. 슈퍼커패시터의 적용 분야로는 보통 빠른 충전과 방전이 필요한 장치에 모두 들어간 다. 현재 비나텍의 슈퍼커패시터 대부분은 일 반 가정의 전기 사용량을 원격으로 자동 검 침할 수 있는 스마트미터기(AMR)에 이용되 고 있으며 전력 사용량 데이터를 원격 전송 하기 위해선 순간적으로 강한 출력이 필요한 데 이때 커패시터가 사용된다. 슈퍼커패시터 적용이 자동차 에어백 분야 로 확대됨에 따라 벤츠 자동차에도 사고 발 생 이후 에어백 작동 시 비나텍의 슈퍼커패 시터가 작동한다. 또한 전력 공급이 갑자기 중단됐을 때 데 이터를 백업할 수 있도록 잠시 동안 전력을 공급하는 SSD 백업 전원용으로도 활용 가능하다. 이 외에도 드론, 차량용 블랙박스, 안정적 인 전력 운용 수요가 높은 신재생에너지 및 친환경 솔루션 등으로 활용 범위가 넓어지고 있다. 최근 슈퍼커패시터 적용 분야 확장 및 수 요 증가와 맞물려 슈퍼커패시터를 앞세워 2 년 연속 퀀텀점프에 해당하는 실적을 올린 비나텍은 세계 슈퍼커패시터 시장의 성장으 로 꾸준한 매출 상승이 예상된다. 비나텍이 직접 연구 개발한 슈퍼커패시터 모두 디바이스마트에서 구매 가능하다.

슈퍼커패시터 바로 확인하기 

 

GGM AC모터 대량등록!

vvvv

 

디바이스마트에 GGM AC모터 상품이 대량 등록되어

 AC모터 상품도 이제 편리하게 구매가 가능합니다: )

GGM 브랜드는 1979년 설립되어 축적된 기술 노하우로

고효율, 고강도 품질의 AC,DC,기어드 모터제품을

전문 생산 유통하는 기어드 모터 선두주자입니다.

등록이 완료된 제품은 GGM 인덕션 , 리버시블 AC모터로

리드선 타입, 터미널타입 선택이 가능하며

샤프트 타입도 키타입, 기어타입, 디컷타입이 준비되어 있습니다: )

인덕션 모터 간략 스펙

단상, 삼상으로 전원이 분류되고,

모터 둘레:  60~90각

Output: 6W-200W

Voltage: 100V~440V 의 제품이 있습니다!

리버시블 모터 간략 스펙 

모터둘레: 60~90각

Output: 6W-180W

Voltage: 100V~240V 의 제품이 있습니다!

제품 분류 및 제품 확인 방법은

디바이스마트 블로그에 자세히 나와있으니

아래 링크를 통해 확인해보시기 바랍니다: )

블로그 포스팅 바로보기 

GGM AC모터 - 인덕션 모터 구매하러가기 

GGM AC모터- 리버시블 모터 바로가기

[60호]층간소음 측정 및 상쇄를 통한 이웃사랑 프로젝트

Cap 2020-09-07 14-49-36-584

Cap 2020-09-07 14-49-36-584

2019 ICT 융합 프로젝트 공모전 참가상

층간소음 측정 및 상쇄를 통한

이웃사랑 프로젝트

글 | 성균관대학교 김혁균, 고건우, 권동환, 정혜인, 최민수

 

1. 심사평
칩센 사회적 이슈로까지 번지고 있는 층간 소음에 대하여 고민을 한 것으로 보이지만, 제작한 결과물이 어떤 효과를 보이는지에 대한 확인이 어렵습니다. 또한 마이크로 입력된 소음 진동에 대하여 스피커를 통해 상쇄한다는 것도 실효성이 부족해 보입니다. 조금 더 구체적인 가설과 대안을 제시할 필요가 있어 보입니다.
뉴티씨 최근 많은 민원이 층간소음에서 발생하고, 실제로 이웃간의 분쟁도 많이 발생하고 있습니다. 이럴 때 이러한 장비를 고안하여 낸 것은 참 좋은 의미인 것 같습니다. FFT를 통한 주파수 확인 후 주요 주파수를 상쇄시키기 위해 스피커로 소리를 내서 층간소음을 줄이는 것은 제대로 구현된다면 참 도움이 될 것입니다. 다만, 작품의 결과가 어떻게 되었는지, 장치 전과 장치한 후의 결과 비교 또한 FFT주파수로 찾고 나서 반대파를 발생시킨 파형, 그리고 상쇄된 최종 파형 등이 함께 나와있다면 보다 좋은 작품이 되었을 것 같습니다. 20여년전에 전화박스를 외부소음으로부터 막아주기 위해 구현되었던 기능과 매우 유사합니다. 실제 생활에 도움이 되는 이러한 생각들은 평소에도 많이 해서, 삶이 변화되는 계기가 되면 좋겠습니다.
위드로봇 노이즈 캔슬링은 실시간 응답성이 매우 중요한데, 이 부분의 구현이 아쉽습니다,
펌테크 최근 들어 사회적 이슈가 되고 있는 층간 소음 문제를 반영한 아이디어와 실용성이 우수한 작품이라고 생각합니다. 작품에 적용된 기술이 단순히 층간 소음을 측정하여 수집하고 표시하는 것 외에도 층간 소음 발생 시 발생된 소음을 경감시키고자 하는 방안으로 FFT 노이즈 캔슬링 방식을 적용한 회로로 구성한 점은 참신한 기획이라고 생각합니다. 단 제출된 보고서 상에서는 구동되는 자세한 동작 영상을 확인할 수 없어 최종 완성이 되지는 않은 것으로 판단됩니다.

2. 작품 개요
2.1. 제작 배경 및 문제점
대한민국에서 ‘층간소음’의 문제점은 이미 사회적으로 큰 이슈가 되고 있다. 실제로 20대에게 ‘층간소음’ 설문조사를 한 결과 ‘층간소음을 겪어봤다’고 답한 응답자는 91.7%에 달했다. 또 10명 중 5명은 ‘소음 때문에 스트레스를 받고 있다’고 답했다. 국민일보 ‘층간소음, 윗집이 남기고 간 메모 때문에‘ ‘항의해 봤다’는 응답도 51.5%에 달했다. 그래서 층간소음 해결을 위하여 관리실에 민원을 넣거나 문자 메시지, 먹을 것을 주는 등 많은 방법을 사용한다. 하지만 해결이 안 될 경우 민원을 넣어도 현행법상 강제력이 없기 때문에 소음을 내는 집에서 협조하지 않게 되면 별다른 방도가 없다. 그로 인하여 직접 항의하거나 소음을 더 크게 내서 복수하는 행위가 나오게 되고, 이러한 과정에서 다툼이 일어나거나 심각한 경우 살인, 방화, 폭력 등 범죄 행위가 발생하는 상황이다.

Cap 2020-09-07 14-49-45-577

보통 항의를 하는 경우 구체적인 기준을 알아내기 어려운 경우가 많다. ‘시끄럽다‘의 기준은 주관적이기 때문이다. 물론 국토부와 환경부에서 상단 표와 같이 기준을 만들어 놓았지만, 윗집의 소음 정보를 아랫집에 제공하는 건 개인정보 보호법에 의하여 어렵다. 만약, 층간소음의 갈등이 심화 되어 법적인 절차로 넘어갈 경우, 개인적으로 녹음한 소음과 영상 등은 실효성을 입증하기 어렵다. 측정업체에 50~100만원의 비용을 소비해야 증거자료 사용할 수 있다.
또한, 자신이 내는 소음이 어느 정도로 주변에 영향을 미치는지 확실히 알 수 없는 경우가 많다.

2.2. 제작 목적 및 기대 효과
위의 나열한 문제점을 해결하기 위하여 층간소음 센서를 제작하였다. 애매한 ‘시끄럽다’ 기준을 확실히 하기 위하여 <표1>에 나와 있는 야간의 최고 소음도를 기준(실험환경이 미니어처 집이라서 망치로 내려치는 충격과 시끄러운 음악을 트는 것을 최고 소음도를 넘는다는 기준으로 설정하였다.)으로 일정 기준의 소음을 넘으면 LED 등에 ‘X’ 표시가 나오도록 코드를 작성하였다. 개인정보 보호법을 고려하여 소음을 받는 집에서 진동과 소음을 측정하고 기준을 넘으면 소음이 나는 집에 LED가 표시되도록 하였다.
또한, 주거 위치별 층간소음 피해는 위층의 소음으로 인해 아래층에서 불편을 호소하는 경우가 69.4%로 가장 많다는 설문조사를 바탕으로 윗집에서 아랫집으로 소음이 간다는 상황 설정으로 미니어처 집을 제작하였다. 그리고 우퍼(woofer·저음용 스피커) 설치로 보복 소음을 낸다는 것에서 아이디어를 얻어서 ‘음장상쇄 효과’를 적용해서 아랫집에서 소음을 실시간으로 인식하고, 아래층 천장에 부착된 스피커로 반대 위상을 가진 주파수를 내보내어 상쇄시키는 장치를 제작하였다.
이 센서를 사용할 경우 LED등이 소음이 나는 집에 경고를 주어 소음 제공자 스스로 소음을 억제하여 충돌을 방지하는 효과를 기대할 수 있고, 센서의 기록장치에 의해서 법적인 증거자료로 사용할 수 있다. 게다가, 아랫집에서 음장 상쇄 기능을 가진 스피커를 사용하게 되면, 윗집에서 나는 소음이 크더라도 소음이 감쇄된다. 그렇게 되면 층간소음 문제를 어느 정도 해결할 수 있을 것이다.

3. 작품 설명
3.1. 음장 상쇄
3.1.1. FFT(Fast Fourier Transform)
FFT(Fast Fourier Transform)이란 이산 푸리에 변환과 그 역변환을 빠르게 수행하는 효율적인 알고리즘을 의미한다. 보통 디지털 신호 처리 및 편미분 방정식의 풀이 등 여러 분야에서 사용된다.
푸리에 변환이란, 시간에 대한 함수를 주파수에 대한 함수로 변환하는 작업이다. 다시 말해, 푸리에 변환은 시간에 대한 함수를 분해하여 각 주파수 대역에 대한 성분으로 분해한다.

Cap 2020-09-07 14-49-57-793

위 그림에서 빨간 부분은 특정 신호를 시간에 대한 함수로 나타낸 것이다. 이러한 신호는 대개 여러 개의 사인파의 합성으로 이루어져 있는데, 이것을 주파수 대역에 대하여 분해하고 각 주파수 대역에 대한 진폭을 표시한 것이 파란 부분이다. 푸리에 변환을 이용하면 복잡한 신호를 간결하게 정리할 수 있으며, 특정 신호에서 지배적인 주파수 대역이 어떤 성분인지 확인할 수 있다. 이러한 푸리에 변환은 음성 구별, 다양한 소리 재생, 영상 노이즈 제거 등 여러 신호 처리 분야에서 활용되고 있다.

3.1.2. 아두이노를 이용한 FFT와 노이즈 캔슬링 알고리즘
아두이노를 이용한 FFT는 이미 많은 개발자들에 의해 오픈 소스 라이브러리가 제공되고 있다. 본 프로젝트에서는 이를 이용하여 노이즈 캔슬링 알고리즘을 구현한다. 먼저 아두이노의 아날로그 핀을 통해 현실 소리 데이터를 받고 이를 FFT 라이브러리를 이용하여 주파수 영역의 데이터로 전환한다. 그 후, 효율적인 캔슬링을 위해 가장 지배적인 주파수 대역을 선정하여 이에 해당하는 반대 진폭의 음파를 스피커를 통해 출력한다. 그림은 데이터 처리 과정 중, FFT를 이용하여 소리를 시각화한 것과 FFT를 통해 소리를 주파수 대역별로 분리한 후, 그것을 상대적인 진폭으로 나타낸 데이터이다.

Cap 2020-09-07 14-50-06-577 Cap 2020-09-07 14-50-16-711

3.1.3. 상수 및 변수 선언

 

const uint16_t samples = 128;
double signalFrequency = 1000;
double samplingFrequency = 5000;
uint8_t amplitude = 100;

sample의 크기와 FFT 변환에 필요한 신호 주파수를 정의하는 부분이다.

 

double vReal[samples];
double vImag[samples];

현실의 소리 샘플을 FFT 변환을 통해 주파수 대역으로 분리할 때 사용하는 Array를 선언한다. 아날로그 핀을 통해 얻은 소리 신호를 vReal에 저장하고, FFT 변환을 통해 얻은 주파수 영역 소리 신호를 vImag에 저장한다.

 

uint8_t mySensVals[samples];
float freq1;
float freq2;
float freq3;
uint8_t ampl1;
uint8_t ampl2;
uint8_t ampl3;
uint8_t i1;
uint8_t i2;
uint8_t i3;

FFT를 통해 분석한 소리 대역을 저장하는 mySensVals를 정의하고 그 중에서 진폭이 가장 큰 주파수 대역을 freq1, freq2, freq3에 저장한다. 그 후 각 주파수 대역에 대한 진폭을 ampl1, ampl2, ampl3에 저장한다. i1, i2, i3는 mySensVals에서 주파수가 큰 세 개의 인덱스를 의미한다,

3.1.4. 메인 loop 함수

for (uint8_t i = 0; i < samples; i++)

  {

    vReal[i] = analogRead(A0);

    delayMicroseconds(100);

    vImag[i] = 0;

  }

vReal에 마이크 센서를 이용해 아날로그 핀을 통해 실제 소리 데이터를 받는다, 그 후, vImag의 모든 데이터를 0으로 정리한다.

FFT.Windowing(vReal, samples, FFT_WIN_TYP_HAMMING, FFT_FORWARD);

  FFT.Compute(vReal, vImag, samples, FFT_FORWARD);

  FFT.ComplexToMagnitude(vReal, vImag, samples);

  PrintVector(vReal, (samples >> 1), SCL_FREQUENCY);

vReal에 있는 소리 데이터를 FFT를 이용하여 주파수 대역에 대하여 정리한 후, vImag에 저장한다. 해당 부분 코드는 FFT를 아두이노에 맞게 적용할 수 있는 arduinoFFT.h 오픈 소스 라이브러리를 이용하였다.

PrintVector(vImag, (samples >> 1), SCL_FREQUENCY);

vReal을 FFT를 통해 정리하여 주파수 영역의 소리 데이터를 mySensVals array에 저장한다.

i1 = 2;

  for (int k = 2;k < 64; k++){

    if(mySensVals[k]>mySensVals[i1]){

      i1 = k;

    }

  }

 

  i2 = 2;

  for (int k = 2;k < 64; k++){

    if((mySensVals[k]>mySensVals[i2]) && (k!=i1)){

      i2 = k;

    }

  }

 

  i3 = 2;

  for (int k = 2;k < 64; k++){

    if((mySensVals[k]>mySensVals[i3]) && (k!=i1) && (k!=i2)){

      i3 = k;

    }

  }

mySensVals의 데이터 중, 가장 진폭이 큰 데이터 3개를 추출하는 과정이다.

freq1 = scailing(i1);

freq2 = scailing(i2);

freq3 = scailing(i3);

freq 변수에 진폭이 가장 큰 주파수 대역에 인덱스를 주파수로 변환해 저장한다.

tone(speaker_pin1, freq1);

tone(speaker_pin2, freq2);

tone(speaker_pin3, freq3);

선택한 주파수 대역을 3개의 스피커를 통해 재생한다.

3.1.5. 기타 함수 설정

void PrintVector(double *vData, uint8_t bufferSize, uint8_t scaleType)

{

  for (uint16_t i = 2; i < bufferSize; i++)

  {

    uint8_t val_temp = map(vData[i],0,1000,0,255);

    mySensVals[i] = val_temp;

    /*Serial.print(bufferSize);

    Serial.print(” “);*/

  }

}

선택한 영역의 데이터를 글로벌 변수인 mySensVals에 저장하는 함수이다. 이 과정에서 진폭의 스케일을 0에서 255로 조정한다.

float scailing(int i){

  float ans = 200 + (1000-200)/(50-12)*(i-12);

  return ans;

}

소리 데이터의 인덱스를 주파수로 변환하는 함수이다.

3.2. 소음 및 진동 센서
3.2.1. 라이브러리

#include <FrequencyTimer2.h>

//도트 매트릭스 사용에 필요한 라이브러리를 가져옴.

//진동, 소음 센서의 경우 추가적인 라이브러리 불필요.

3.2.2. 도트매트릭스 설정

#define X  { \

    {1, 0, 0, 0, 0, 0, 0, 1}, \

    {0, 1, 0, 0, 0, 0, 1, 0}, \

    {0, 0, 1, 0, 0, 1, 0, 0}, \

    {0, 0, 0, 1, 1, 0, 0, 0}, \

    {0, 0, 0, 1, 1, 0, 0, 0}, \

    {0, 0, 1, 0, 0, 1, 0, 0}, \

    {0, 1, 0, 0, 0, 0, 1, 0}, \

    {1, 0, 0, 0, 0, 0, 0, 1}  \

 

#define D { \

    {0, 0, 0, 0, 0, 0, 0, 0},\

    {0, 0, 0, 0, 0, 0, 0, 0},\

    {0, 0, 0, 0, 0, 0, 0, 0},\

    {0, 0, 0, 0, 0, 0, 0, 0},\

    {0, 0, 0, 0, 0, 0, 0, 0},\

    {0, 0, 0, 0, 0, 0, 0, 0},\

    {0, 0, 0, 0, 0, 0, 0, 0},\

    {0, 0, 0, 0, 0, 0, 0, 0},\

}

//도트 매트릭스로 비춰줄 X 모양 상태와 불빛이 모두 꺼져있는 상태를 1과 0으로 지정해줌.

3.2.3. 상수 및 변수 선언

int SOUND_SENSOR = A5;

int threshold = 25;

//소음 센서를 A5로 받고, 감도조절 threshold를 25로 설정, Sensor_Value로 소음센서 정의함.

 

int tact = A5;      

//택트 스위치 A5에 연결

byte col = 0;       

//COL을 0으로 초기화

byte leds[8][8];    

//현재 출력해야 할 LED 모양 업로드하는 배열함.

 

//맨 처음 PINS[0]은 사용하지 않기때문에 -1로 설정. 1~16번까지의 핀을 PIN에 연결함.

int pins[17]= {-1, 5, 4, 3, 2, 14, 15, 16, 17, 13, 12, 11, 10, 9, 8, 7, 6};

 

//행 0~7번까지 핀 연결해 주기

int cols[8] = {pins[13], pins[3], pins[4], pins[10], pins[6], pins[11], pins[15], pins[16]};

 

//열 0~ 7번까지 핀 연결해 주기

int rows[8] = {pins[9], pins[14], pins[8], pins[12], pins[1], pins[7], pins[2], pins[5]};

 

const int numPatterns = 2;      

//총 사용할 패턴 수를 지정하기.

byte patterns[numPatterns][8][8] = { X, D };   

//위에서 정의한 led 모양을 patterns에 입력해 주기

int pattern = 0;

pattern의 초기값을 0으로 지정.

int Sensor_value;

 

void clearLeds() { 

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

    for (int j = 0; j < 8; j++) 

      leds[i][j] = 0;  }

//led를 다 초기화 시키는 clearLeds 정의.

void display() {

  digitalWrite(cols[col], HIGH);  

//이전 행들 다 꺼지게끔 해주기

  col++;

  if (col == 8) {

    col = 0;

  }

  for (int row = 0; row <= 7; row++) {

    if (leds[col][7 - row] == 1) {     // 위의 배열에서 1일때 해당되는 위치 불빛 켜주기

      digitalWrite(rows[row], HIGH);

    }

    else {                          // 위 배열에서 0일때 해당되는 위치 불빛 꺼줌.

      digitalWrite(rows[row], LOW);

    }

  }

  digitalWrite(cols[col], LOW);     

// 다음 패턴을 위해 led 다 꺼줌.

}

void setPattern(int pattern) {        // LED 배열에 PATTREN 입력하기

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

    for (int j = 0; j < 8; j++) 

      leds[i][j] = patterns[pattern][i][j];  

}

 

 

 

 

void setup() {

// 1~16번 까지의 핀을 출력으로 설정

  for (int i = 1; i <= 16; i++) {

    pinMode(pins[i], OUTPUT);

  }

 

// 행 0~7번까지를 high로 

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

    digitalWrite(cols[i], HIGH );

  }

// 열 0~7번 까지를 low로

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

    digitalWrite(rows[i], HIGH);

  }

 clearLeds();   // led 초기화

 

FrequencyTimer2::setOnOverflow(display);  

//leds를 보여주기 위해서 setOnOverFlow를 사용

 

  pinMode(tact, INPUT); 

//SW 를 설정, 아두이노 풀업저항 사용

  setPattern(pattern); 

 

Serial.begin(9600); 

// 시리얼모니터 출력

  pinMode(SOUND_SENSOR, INPUT);  

 

-메인 loop 함수

void loop() { 

  int val; 

 

 val=analogRead(4);

 

 Serial.print(val,DEC);

 

delay(100);  

//진동 센서 값을 아날로그 4핀으로 받고 val 로 정의한 뒤 delay 100의 지연시간으로 진동 센서 값을 시리얼 모니터에 표시함.

 

Sensor_value = analogRead(A5);   

 

  Serial.println(Sensor_value);   

 

  delay(100);

//소음 센서 값을 아날로그 5핀으로 받고 Sensor_value로 정의한 뒤 delay 100의 지연시간으로 소음 센서 값을 시리얼 모니터에 표시함.

 

int readTact = digitalRead(tact);

  if((Sensor_value>=300) || (val>=300)){

 // 소음센서 또는 진동센서의 값이 300을 넘는 값을 가질 때

    

    if(readTact == LOW){     

// 택트 스위치가 low일때 

      if(pattern == 2) pattern = 0;   

//패턴의 끝까지 다 출력하고 다시 처음을 출력

      else pattern++;                

// 다음 패턴 출력을 위해 pattern ++

     delay(300);                 

// 길게 눌러 패턴이 순식간에 넘어가지 않기 위해서 딜레이를 줌

    }    

       setPattern(pattern);           

// 패턴 출력 

  }

 

 

  else  

 clearLeds();

  Sensor_value = analogRead(A5);

//아닐 경우 다시 처음으로 돌아가 측정을 시작.

  }

3.3. 전체 시스템 구성

Cap 2020-09-07 14-50-31-077
본 시스템은 크게 주요한 두 가지 기능으로 나뉜다. 첫 번째는 두 개의 센서를 이용해 소음을 입력 값으로 받고, LED로 출력하는 과정이다. 이 과정은 층간소음의 진동과 소음을 각각 진동 감지 센서와 소음 감지 센서에서 인식한다. 이때, 진동과 소음의 정도가 일정 값을 넘게 되면 기준치와 비교해 LED에 표시를 해주게 된다.
두 번째는 마이크를 이용해 소음을 입력 받은 후 Fast Fourier Transform 변환 과정을 거쳐 일상의 소음을 사인파로 분석한다. 분석된 여러 주파수 중 가장 큰 주파수를 선택해 그에 반대되는 파장을 내보냄으로써 소음을 상쇄시킬 수 있다.
이때, 진동은 진동 감지 센서에서만 입력되고, 소음은 소음 감지 센서와 마이크 두 곳에서 입력을 받게 된다. 또한, 개인정보보호를 위해, 본 팀은 LED는 위층에 표시하고, 소음을 상쇄시키는 파장은 아래층에 있는 스피커에서 송출하도록 구성하였다. 따라서 위층은 자신의 소음을 인식할 수 있고, 아래층은 소음을 상쇄시킨 조용한 환경에서 지낼 수 있다.

3.4. 개발 환경
본 팀은 프로젝트의 목적하는 바를 구현하기 위해 Arduino Uno와 Arduino Due를 사용하였다. 소음센서, 진동센서의 값을 받아들여 LED와 스피커를 통제하기 위해 상호작용이 가능한 시스템을 만들어 내기 위해 아두이노 보드를 선택하였다. 또한, 임베디드 시스템 중의 하나로 장치의 제어를 쉽게 개발할 수 있다는 장점 때문에 우노 보드를 사용하였다.
아두이노의 IDE에서 소음 및 진동 값의 기준 비교와 음장 상쇄 등 프로젝트의 주된 기능들을 구현하였다. 기본적으로 내장된 라이브러리를 이용해 소음 및 진동센서 제어와 LED 출력을 프로그래밍 하였고, 음장상쇄 과정에서는 FFT관련한 오픈 소스 라이브러리를 사용하여 프로그래밍 하였다. 한편, 빠르게 연산 과정을 수행해야 하는 음장상쇄 기능에 있어서 아두이노 보드는 비교적 느린 사이클을 가지고 있었고, 소음의 발생보다 조금 늦게 반대파가 생성되는 것이 한계점이라 할 수 있다.

4. 단계별 제작 과정
4.1. 진동센서와 소음센서를 이용한 소음인식과 디스플레이 장치

Cap 2020-09-07 14-50-42-178
1. 진동센서. 소음센서와 LED디스플레이를 아두이노와 연결한다.
2. 진동센서의 진동 적정값과 소음센서의 소음 적정값을 구한다.
3. 아두이노가 진동과 소음을 동시에 느낄 때 디스플레이에 X표시가 뜨도록 코딩한다.

4.2. 마이크와 스피커를 이용한 음장상쇄 장치
1. 마이크와 스피커를 아두이노에 연결한다.
2. 마이크로 들어온 소리의 주파수를 분석해 역파장을 스피커로 출력하는 코딩한다.

Cap 2020-09-07 14-50-47-511

4.3. 층간소음 모형 및 실험
1. 아래층과 위층으로 나뉜 공간을 만든다.

Cap 2020-09-07 14-50-54-711

Cap 2020-09-07 14-50-59-310
2. 아래층의 천장 부분에 센서들과 스피커를 붙인다. 진동 및 소음 센서는 아래층의 소음이 감지되지 않고, 위층의 소음과 진동만 감지하도록 방음이 되는 재료로 둘러싸준다.
3. 위층에 충격과 소음을 일으켜 정상적으로 소음과 진동이 인식되어 디스플레이와 스피커가 반응하는지 확인한다.

Cap 2020-09-07 14-51-05-360

4.4. 소스코드

 

#include “arduinoFFT.h”
#define twoPi 6.28318531
#define fourPi 12.56637061
arduinoFFT::arduinoFFT(void)
{
/* Constructor */
}

arduinoFFT::~arduinoFFT(void)
{
/* Destructor */
}

uint8_t arduinoFFT::Revision(void)
{
return(FFT_LIB_REV);
}
void arduinoFFT::Compute(double *vReal, double *vImag, uint16_t samples, uint8_t dir)
{
Compute(vReal, vImag, samples, Exponent(samples), dir);
}

void arduinoFFT::Compute(double *vReal, double *vImag, uint16_t samples, uint8_t power, uint8_t dir)
{
/* Computes in-place complex-to-complex FFT */
/* Reverse bits */
uint16_t j = 0;
for (uint16_t i = 0; i < (samples – 1); i++) {
if (i < j) {
Swap(&vReal[i], &vReal[j]);
Swap(&vImag[i], &vImag[j]);
}
uint16_t k = (samples >> 1);
while (k <= j) {
j -= k;
k >>= 1;
}
j += k;
}
/* Compute the FFT */
double c1 = -1.0;
double c2 = 0.0;
uint8_t l2 = 1;
for (uint8_t l = 0; (l < power); l++) {
uint8_t l1 = l2;
l2 <<= 1;
double u1 = 1.0;
double u2 = 0.0;
for (j = 0; j < l1; j++) {
for (uint16_t i = j; i < samples; i += l2) {
uint16_t i1 = i + l1;
double t1 = u1 * vReal[i1] – u2 * vImag[i1];
double t2 = u1 * vImag[i1] + u2 * vReal[i1];
vReal[i1] = vReal[i] – t1;
vImag[i1] = vImag[i] – t2;
vReal[i] += t1;
vImag[i] += t2;
}
double z = ((u1 * c1) – (u2 * c2));
u2 = ((u1 * c2) + (u2 * c1));
u1 = z;
}
c2 = sqrt((1.0 – c1) / 2.0);
if (dir == FFT_FORWARD) {
c2 = -c2;
}
c1 = sqrt((1.0 + c1) / 2.0);
}
/* Scaling for reverse transform */
if (dir != FFT_FORWARD) {
for (uint16_t i = 0; i < samples; i++) {
vReal[i] /= samples;
vImag[i] /= samples;
}
}
}
void arduinoFFT::ComplexToMagnitude(double *vReal, double *vImag, uint16_t samples)
{
/* vM is half the size of vReal and vImag */
for (uint8_t i = 0; i < samples; i++) {
vReal[i] = sqrt(sq(vReal[i]) + sq(vImag[i]));
}
}

void arduinoFFT::Windowing(double *vData, uint16_t samples, uint8_t windowType, uint8_t dir)
{
/* Weighing factors are computed once before multiple use of FFT */
/* The weighing function is symetric; half the weighs are recorded */
double samplesMinusOne = (double(samples) – 1.0);
for (uint16_t i = 0; i < (samples >> 1); i++) {
double indexMinusOne = double(i);
double ratio = (indexMinusOne / samplesMinusOne);
double weighingFactor = 1.0;
/* Compute and record weighting factor */
switch (windowType) {
case FFT_WIN_TYP_RECTANGLE: /* rectangle (box car) */
weighingFactor = 1.0;
break;
case FFT_WIN_TYP_HAMMING: /* hamming */
weighingFactor = 0.54 – (0.46 * cos(twoPi * ratio));
break;
case FFT_WIN_TYP_HANN: /* hann */
weighingFactor = 0.54 * (1.0 – cos(twoPi * ratio));
break;
case FFT_WIN_TYP_TRIANGLE: /* triangle (Bartlett) */
weighingFactor = 1.0 – ((2.0 * abs(indexMinusOne – (samplesMinusOne / 2.0))) / samplesMinusOne);
break;
case FFT_WIN_TYP_BLACKMAN: /* blackmann */
weighingFactor = 0.42323 – (0.49755 * (cos(twoPi * ratio))) + (0.07922 * (cos(fourPi * ratio)));
break;
case FFT_WIN_TYP_FLT_TOP: /* flat top */
weighingFactor = 0.2810639 – (0.5208972 * cos(twoPi * ratio)) + (0.1980399 * cos(fourPi * ratio));
break;
case FFT_WIN_TYP_WELCH: /* welch */
weighingFactor = 1.0 – sq((indexMinusOne – samplesMinusOne / 2.0) / (samplesMinusOne / 2.0));
break;
}
if (dir == FFT_FORWARD) {
vData[i] *= weighingFactor;
vData[samples - (i + 1)] *= weighingFactor;
}
else {
vData[i] /= weighingFactor;
vData[samples - (i + 1)] /= weighingFactor;
}
}
}

double arduinoFFT::MajorPeak(double *vD, uint16_t samples, double samplingFrequency)
{
double maxY = 0;
uint16_t IndexOfMaxY = 0;
for (uint16_t i = 1; i < ((samples >> 1) – 1); i++) {
if ((vD[i-1] < vD[i]) && (vD[i] > vD[i+1])) {
if (vD[i] > maxY) {
maxY = vD[i];
IndexOfMaxY = i;
}
}
}
double delta = 0.5 * ((vD[IndexOfMaxY-1] – vD[IndexOfMaxY+1]) / (vD[IndexOfMaxY-1] – (2.0 * vD[IndexOfMaxY]) + vD[IndexOfMaxY+1]));
double interpolatedX = ((IndexOfMaxY + delta) * samplingFrequency) / (samples-1);
/* retuned value: interpolated frequency peak apex */
return(interpolatedX);
}

/* Private functions */

void arduinoFFT::Swap(double *x, double *y)
{
double temp = *x;
*x = *y;
*y = temp;
}

uint8_t arduinoFFT::Exponent(uint16_t value)
{
/* Computes the Exponent of a powered 2 value */
uint8_t result = 0;
while (((value >> result) & 1) != 1) result++;
return(result);
}

4.5. 참조
· 국민일보 ‘층간소음, 윗집이 남기고 간 메모 때문에’ : 
· 약한 진동까지 감지할 수 있는Piezo Disk Vibration Sensor(피에조 디스크 진동 센서) :
· [아두이노 강좌] 8 x8 도트 매트릭스 사용하기 :
· 아두이노 FFT 오픈소스 라이브러리 (arduinoFFT) :