Quantcast
Channel: Hard Copy Arduino
Viewing all 99 articles
Browse latest View live

파이프 가구 DIY – 1편. 코너 탁자

$
0
0

 

troopie 님이 하드카피월드에 게시한 “파이프 가구 DIY” 시리즈 입니다.

 

 

파이프 가구 DIY – 1편. 코너 탁자

 

파이프로 만든 가구는 오래 전부터 있어왔습니다. 뭔진 모르지만 한번씩은 들어봤을 바우하우스란 곳에서도 파이프로 디자인한 가구가 많이 있었으며, 최근까지 각종 쇼핑몰에서 판매하는 의자의 상당부분이 파이프로 디자인한, 흔히 말하는 인터네셔널 스타일의 디자인 입니다. 하지만 직접 만드는 파이프가구는 그 재질이나 디자인이 기존의 인터네셔널한 디자인과는 상당히 다른 빈티지한 느낌을 줍니다. 최근에 파이프로 뭘 만들고 싶다는 생각이 많이 들어 저도 한번 만들어 보기로 했습니다. 인터넷에 인더스트리얼 디지인이라 검색하면 유사한 작품이 다수 있으니 참고하시기 바랍니다.

1.01

지금까지 제가 직접 만들어 본 것이 전무합니다. 가구는 고사하고 생활소품도 만들어 본 적이 없기에 일단 쉬운 것부터 만들어 보기로 했습니다. 그 중에 눈에 들어온 것이 아래 사진 코너에 들어갈 탁자입니다. 리모콘이나 핸드폰, 컵 등을 올려놓고 사용할 만한 간단한 구조의 가구입니다. 10년 전에 산 타워형 선풍기가 자리잡은 위치를 방해하지 않는 코너탁자. DIY가 좋은 점이 이런 것이네요. 내 마음대로 모양을 바꿀 수 있다는 점.

1.02

하지만 쉽지만은 않네요. 처음 다루는 자재이다 보니 많은 시행착오를 겪었고 돈낭비도 조금 있었습니다. 어쩌겠습니까 초보의 운명이죠. 그래도 의도한대로 만들어져 기쁘네요. 지금까지의 경험을 공유하고 혹시나 관심 있으신 분이 계실까 싶어 저 같은 초보자도 쉽게 만들 수 있도록 제 능력껏 설명해보도록 하겠습니다.

 

– 설계

다룰 줄 아는 디자인 관련 툴이 없어서 그냥 손으로 그렸습니다. 다이소에서 1000원짜리 줄자 하나 사서 길이 재본 후 대충 그렸습니다. 상상한 이미지랑 그려본 이미지랑 많이 다르더군요. 처음엔 정사각형 모양의 ㄴ자 모양을 생각했었는데, 옆에 깔아놓은 대방석의 크기와 조화가 안되는 것 같아 한쪽을 100mm줄여서 전체 크기가 900/800mm가 되는 ㄴ자 모양을 만들기로 했습니다. 구석에 선풍기 들어갈 자리를 만들어서 ㄴ자 모양이 된다는 점만 빼면 그냥 단순한 사각형에 다리만 만든 구조입니다.

1.03

전체적인 사이즈를 정하고 나니 탁자 높이를 얼마로 해야 할까 고민이 되더군요. 보통 거실에는 소파가 있으니 소파 높이에 따라 정하면 되겠지만 전 대방석을 깔고 드러눕기 좋게 해놓았기에 다과상 높이정도가 적당해 보였습니다. 그래서 또 다이소 줄자를 들고 다과상의 높이를 재 보았습니다. 정확히 250mm네요. 다리에 레듀서랑 사이드 아웃렛 엘보가 결구되니 늘어나는 높이를 감안해서 200mm로 파이프 길이를 정했습니다. 결구 시 늘어나는 길이는 ‘자재’부분에서 설명하겠습니다.

손으로 대충 그린 설계도에 구체적인 파이프 치수를 정하고 연결나사를 하나씩 그리고 머릿속으로 작업과정을 시뮬레이션 해보던 중 갑자기 큰 난관에 빠졌습니다. 나사에 파이프를 시계방향으로 돌리면서 결구해보니 사각형의 마지막 부분이 연결이 안 되는 겁니다. 한 파이프의 양쪽을 시계방향으로 돌릴 수는 없으니까요. 이거 용접을 해야 하나? 어떻게 해야 하지? 이렇게 간단한 탁자하나 만들기가 이렇게 어려워서야 원. 별 잡생각과 짜증이 동반되어 작업을 한동안 쉬었습니다. 주위에 배관관련 일을 하시는 분도 없고, 인터넷에 검색해도 사각형 구조의 파이프가구는 없더군요. 그래도 설마 이런 간단한 구조를 연결할 나사가 없을리가 없다는 생각에 열심히 뒤져본 결과 ‘드레샤 엘보’라는 연결나사를 알게 되었습니다. 안에 고무바킹과 링이 있어 끼워서 조우는 형식의 나사더군요. 다시 빛이 비쳤습니다. DIY 포기하지 않아도 되겠네요.

1.04

 

-자재

  • 파이프, 사이드아웃렛 엘보4, 드레샤 엘보2, 레듀서4

제가 코너탁자를 만들면서 사용한 자재입니다. 자재는 인터넷에서 쉽게 주문할 수 있습니다. 전 명인코리아라는 사이트를 이용했습니다. 가장 저렴한지는 모르겠지만 자재를 이미지로 잘 정리해 놓아서 뭐가 뭔지 모르는 저에게 참고가 많이 되는 사이트였습니다.

http://myoung119.com/shop/main/index.php

여기 뿐만 아니라 일반 쇼핑몰에서도 구할 수 있으니 싼 곳 검색해서 구하시면 됩니다. 자재를 구매할 때 유의할 점을 하나 하나 설명하면서 제가 했던 삽질을 토대로 여러분들의 돈낭비를 줄일 수 있도록 하겠습니다.

우선 파이프입니다. 파이프에는 종류가 여러가지 있는데 전 15A 흑관을 사용했습니다. 백관, 동관, 스텐레스관 등등등 중에서 제일 저렴했거든요. 이것 저것 만들어 보겠다고 20m 주문했습니다. 결론부터 말씀드리면 20m중에서 19.7m가 창고에 기름냄새 풍기며 쳐박혀 있습니다.

DIY 니 나사도 내가 직접 내고 싶다고 생각하여 바인더(파이프를 고정시켜 주는 공구), 다이스(파이프에 숫나사산을 내는 공구), 다이스 핸들(파이프에 다이스를 물려 잡고 돌릴 수 있는 공구)까지 사서 돌려보니 나사가 안나더군요. 내가 초보라 그렇겠지 생각하여 폭염주의보 하에서도 열심히 돌렸습니다. 그래도 안나더군요. 아니 내가 들인 돈이 얼만데. 파이프랑 공구랑 다 합치면 15만원인데. 이대로 둘 수 없다 싶어 파이프 앞 대가리를 그라인더로 갈았습니다. 파이프에 다이스가 물리는 면적을 더 늘릴려구요. 성공하였습니다. 너무 기뻐 내가 아는 모든 이들에게 사진을 찍어 카톡을 날렸습죠. 거기까지 였습니다. 파이프 2개에 나사산을 만들었고, 그마저도 하나는 각이 틀어져 연결이 어려울 정도였습니다. 이후로는 다이스 날이 상했는지 나사산이 잘 안나지더군요.

1.05

직접 나사를 내는 것은 포기하고 나사산이 나있는 파이프를 주문하였습니다. 흑관 1m가 2000원 정도라면 나사산 나있는 흑관 1m가 4000원 정도로 배로 비싸긴 합니다. 하지만 각도 안비틀어지고, 특히 인테리어용 나사산은 훨씬 깔끔하게 결구가 가능하기에 전 나사산 나있는 파이프를 주문하시라고 말씀드리고 싶습니다. 아니 주문 해야합니다.^^

다음은 사이드 아웃렛 엘보 입니다. 꺽이는 부분을 연결할 때 사용하는 연결나사가 엘보우입니다. 그리고 엘보에 연결구멍이 하나 더 있어 3방향으로 연결이 가능한 엘보가 사이드 아웃렛 엘보입니다. 꺽이는 각은 90도, 45도가 있는데 다른 각도 있는 지는 모르겠습니다. 엘보에 파이프를 연결하면 1cm정도 겹치며 연결됩니다. 그리고 실제 엘보 크기가 있기 때문에 연결 시 파이프의 길이는 교차하는 파이프의 중심선까지 약 15mm 늘어나고 외경까지 포함하면 약 35mm 늘어납니다. 글로 설명하려니 잘 안되네요. 사진 참고하세요.

1.06

드레샤 엘보는 나사를 돌려 결구하는게 아니라 고무바킹에 끼워 연결하기에 치수조정이 약간 가능합니다. 중심선까지 늘어나는 길이는 15~35mm, 외경까지는 35~50mm 정도입니다.

1.07

레듀서는 원래 사이즈가 다른 파이프끼리 연결하는 나사이지만 전 상다리로 사용했습니다. 프렌지란 연결나사도 다리로 사용하기에 좋지만 비싸고 주로 벽에 고정할 때 많이 사용하는 듯 합니다. 제가 사용한 사이즈는 15A/25A입니다. 연결하고나면 길이가 35mm 늘어납니다.

1.08

  • 레듀셔 35
  • 티,사이드아웃렛티 20/35
  • 엘보,사이드아웃렛엘보 15/35
  • 드레샤 엘보15~30/35~50

1.09

1.10

제가 사용해본 연결나사의 설계상 늘어나는 길이를 정리한 것입니다. 다른 작업 하시는 분들 참고하시라고 올려드립니다.

 

-세척

물건이 배송되면 가장 먼저 해야할 일이 세척입니다. 녹방지를 위해서인지 검은 기름이 잔뜩 뭍어 있습니다. 걸레로 닦고 쓰기에는 너무 더럽습니다. 이 기름때를 뭘로 없애야하나 생각하다 주방세제로 닦아 봤습니다. 기름 분해하는데엔 주방세제가 좋더군요. 설거지하듯 부드러운 쑤세미로 세제 한가득 풀어서 2번 닦아줬습니다. 그래도 약간의 기름때가 남더군요. 그래서 마른 걸레로 물기를 흡수하며 닦아줬습니다.

 

-가조립

자재가 건축용이다보니 사이즈의 오차가 조금 있습니다. 파이프에 나있는 나사도 자동 오스터 기계로 수평 잡아서 나사산을 냈다 해도 각도가 틀어지는 부분이 있습니다. 이런 미세한 차이를 조정하기 위해 일단 가조립부터 해보기로 했습니다. 코너탁자의 경우 구조가 간단하고 결구되는 파이프의 길이도 짧아서인지 별 문제가 없네요. 굿~

혹시 각이 안맞거나 길이가 안맞는 부분이 있다면 다른 부품으로 바꿔가면서 맞춰보세요. 맞는 경우가 있더라구요. 가조립 할때는 너무 세게 결구시키지 마세요. 풀 때 손 아파요.

 

-도장

파이프는 쇠로 만들어져 있어서 녹이 잘 납니다. 파이프 세척할 때 물기 말리는 순간 나사 부분에 빨갛게 녹이 나는걸 볼 수 있을 정도로 습기에 약합니다. 그래서 색칠을 해줘야 합니다. 저도 모르는 전문적인 방법이야 많겠지만, 집에서 간단히 할 수 있는 페인트칠로 녹방지를 해주기로 했습니다. 집 근처 페인트 집 가면 투명락카를 1500에 구입할 수 있습니다. 집 밖에 신문지나 박스를 깔아주고 파이프를 일렬로 세운 후 뿌려줍니다. 락카 1통이면 가구 1개 정도 칠할 수 있다고 보시면 됩니다.

 

-조립 및 마무리

칠도 다 했겠다 짱짱하게 조립해야죠. 나사를 돌리다가 잘 안돌아간다 싶으면 긴 파이프 하나를 연결해서 지렛대원리를 이용하면 안돌아가던 나사도 꽉 조이면서 들어갑니다. 도저히 안돌아간다 싶으면 테프론을 감아서 조금 덜 돌리도라도 빡빡하게 결구시키면 됩니다.

우리집은 마루라 바닥이 잘 긁힙니다. 바닥에 닿는 나사가 무엇이든 간에 긁힘방지 스티커를 붙여줘야 안전합니다. 다이소에 가면 동그란 스티커가 있는데 레듀서 크기(25a)와 똑같습니다. 다른 닿는 부분이 있으면 잘라 쓰는 것도 있으니 크기에 맞게 붙여줍니다. 이정도 하면 우리가 할 수 있는 일은 다 된 듯 합니다.

1.11

1.12

1.13

상판만 올리면 코너탁자는 완성되는데 아직 뭐로 할지 결정이 안됐습니다. 처음에는 마끈을 감아서 하려 했으나 너무 약하더군요. 그래서 타공판을 주문하여 잘라 쓸까 하다 주문할 곳이 마땅찮아 포기했죠. 철망도 고려해 봤지만 영~. 아직 고민 중입니다. 좋은 아이디어 있음 좀 주세요.

 

이만 코너탁자 만들기 DIY를 마치겠습니다.

 

============================================================

troopie 님이 하드카피월드에 게시한 “파이프 가구 DIY” 시리즈 입니다.

 


파이프 가구 DIY – 2편. 책상

$
0
0

 

troopie 님이 하드카피월드에 게시한 “파이프 가구 DIY” 시리즈 입니다.

 

 

파이프가구 DIY 2 – 책상

코너 탁자를 한번 만들어 보니 이게 되는구나 라는 걸 느꼈습니다. 별거 아닌 가구지만 내가 원하는 대로 모양을 만들고 나니 자신감이 조금 붙더군요. 게다가 많은 삽질을 통해 내가 할 수 있는 부분과 할 수 없는 부분에 대한 구분이 확실해 졌다고 할까요? 요령이 붙었다고 표현하는게 더 좋을 것 같네요. 내친김에 좀 더 모양이 복잡하고 고려해야 할 것이 많은 책상만들기에 도전해 봅니다.

 

-설계

일단 제가 스케치한 설계부터 보여드릴게요.

2.1

인더스트리얼 디자인으로 검색해 보면 상판을 나무로 만들고 다리와 가로대를 파이프와 파이프 프렌지로 연결한 작품들이 꽤나 있습니다. 상판이 나무면 구조적으로 매우 안정적이지만 파이프가 많이 가려져 특유의 금속느낌과 빈티지함이 죽는 것 같아서 과감하게 전체를 파이프로 만들고 강화유리 상판을 올려 파이프의 골계미(?)를 살리기로 했습니다. 거기에 구조적 안정성을 더하기 위해 긴 파이프를 짧은 파이프로 연결하는 구조를 생각했습니다.

한가지 더 생각한 부분이 있다면 파이프 가구의 경우 너무 직선적이어서 변화의 재미가 안느껴진다는 점입니다. 직선과 직사각형만 보이니 공장의 느낌이 나긴 하지만 요즘 공장은 더욱 복잡미묘한 감성이 있잖아요. 그래서 한 쪽 면에 요철 형태의 길이 변화를 주었습니다. 스케치 상으로 길게 잘못 그려진 보조책상도 얹어 주었구요.

2.2

스케치를 대충 봐도 사각형 구조가 많고 연결나사가 많아 길이계산 하는 게 빡세 보입니다. 예. 실제로 엄청 복잡합니다. 특히 짧은 연결 파이프까지 직선배치가 아닌 다단배치를 해버려서 가로대 계산하는데 엄청 애먹었어요. 저번 코너탁자 만들기에서 각 연결나사의 중심과 외경까지 늘어나는 길이를 정리한 표가 사실 책상의 파이프 길이 계산하면서 정리한 것입니다. 코너탁자의 경우 대충 끼워 맞추면 안 맞아도 알아서 자리 잡지만 책상의 경우 구조적으로 너무 부실해져 버리거든요. 책상으로 쓰기 힘들 정도로. 파이프가 쇠라고 무조건 튼튼한 건 아니더라구요.

책상의 사이즈는 대충 방에 맞게 정했습니다. 전 책상에서 어떤 작업을 하든 좀 늘어놓고 하는 편이라 큰 책상을 선호합니다. 그래서 세로를 좀 크게 700mm정도로 하고 가로를 1500mm정도로 했습니다. 보조책상의 경우 한쪽 벽면이 베란다이기에 베란다 창이 없는 벽의 길이에 맞게 500mm정도로 정했습니다. 책상 높이의 경우 쇼핑몰에 나온 책상의 높이를 그대로 따라했어요. 우리 집에 있는 책상은 저한테 너무 높아서 어깨가 많이 아프고 불편하더라구요. 이런건 가구에 관한 데이터가 많이 쌓여 설계된 시중품을 따라하는게 최고더라구요. 720mm가 나오도록 했습니다.

 

-자재

  • 파이프, 레듀서9, 엘보3, 드레샤 엘보6, 티11, 크로스티2

2.3

자재가 꽤 많이 들어가죠! 자재 관련 설명은 코너탁자에서 대부분 설명했으니 생략하고 중요한 결구 시 늘어나는 길이만 다시 한번 설명할게요.

  • 레듀셔 35
  • 티, 사이드아웃렛티 20/35
  • 크로스티 20
  • 엘보,사이드아웃렛엘보 15/35
  • 드레샤 엘보15~30/35~50

예를 들면 책상 제일 윗 가로대가 1000이고 짧은 파이프로 두 개의 파이프가 연결된 두 번째 가로대에 연결됩니다. 그렇다면 두 번째 파이프의 총 길이도 1000이 되어야 하기에 200, 800으로 나눠진 두 빠이프에 티 연결나사가 들어가는 길이를 빼줘야 하는 겁니다. 티의 경우 중심까지 20이 늘어나므로 양쪽 합하여 40을 빼줘야 하는 겁니다. 즉 200+800-40으로 계산해야 1000짜리 가로대의 끝선에 두 번째 가로대의 끝선이 일치하게 되는 겁니다. 걍 글만 읽으면 잘 머리에 안들어오니 만들고 싶은 것 있으시면 한번 설계해 보시고 고민해 보시면 제 글이 와 닿으실 겁니다. 인생 뭐 있나요. 안 맞으면 다시 주문해서 다시 끼우고 돈 좀 더 쓰면 되는 거죠.

 

-세척

도착하자마자 기름때부터 벗겨야죠. 기름이니까 아세톤 같은 걸로 닦아주면 녹도 안슬고 좋을 것 같지만 없으니 또 세제로 열심히 닦아줍니다. 다른 좋은 방법 있으면 공유해요. 세제로 하는 건 아무리 열심히 닦아도 조립할 때 보면 기름이 뭍더라구요.

2.4

 

-도장

전에는 가조립부터 하고 도색을 했는데 이번 건 구조도 복잡하고 연결할 것도 많고 하니 일단 락카부터 뿌리고 하렵니다. 한여름 땡볕에 박스 깔고 쇳덩이 늘어놓고 락카칠하니 락카도 녹고 나도 녹고 쇠도 녹는 것 같네요. 햇볕에 잘 구워진 쇠파이프는 사람손을 융합시킬 듯이 뜨겁더군요. 장갑 꼭 끼세요.

-조립

책상의 경우 네 부분을 구성되어 있습니다. 조립도 부분별로 해서 한꺼번에 연결해줘야 편합니다. 일단 다리부터 만들고, 가로대 연결하고, 남은 다리 연결하면 끝. 참 말로는 쉽네요. 그리고 말처럼 안되는 게 DIY죠. 열심히 연결해보니 3번째 가로대의 길이가 안맞는 겁니다. 50mm 길더군요. 한 가로대에 티가 4개나 연결되고 거기에 드레샤엘보까지 연결되다보니 계산대로 안된 부분이 생겼습니다. 특히 제일 오른쪽 티에 드레샤가 연결되다보니 길이를 조정할 여유가 안생겨 가운데를 줄여야 하는 경우가 생겼습니다. 길이 계산 잘하셔야 합니다. 제가 정리해드린 늘어나는 길이가 다 이런 삽질을 통해 정리된 것입니다.ㅜ.ㅜ

2.5

근데 문제는 이 뿐만이 아니었습니다. 설계상으로 책상 왼쪽 다리는 다리끼리 연결하는 파이프가 없는데, 없어도 충분히 튼튼할 줄 알았습니다. 사실 요철 모양으로 만들어놔서 연결하려면 삼각함수로 길이 계산을 해야 하는데, 또 그게 말처럼 쉬운게 아니잖아요. 설계대로 모양 나온다는 보장도 없는데. 근데 너무 흔들거리는 겁니다. 책상으로 쓰기 힘들정도로. 할 수 없이 나무에 구멍을 뚫어 꽂아넣기로 했습니다.

2.6

사이 간격을 실측해서 넣었죠. 여기서 또 실수를 했습니다. 사이즈 줄인다고 파이프를 빼놨는데 제대로 결구도 안된 가로대에 다리 간격을 실측해 버려서 연결하고 나니 다리 사이가 오므라 들더군요. 구멍을 다시 뚫었습니다.(ㅜ.ㅜ) 참고로 나무는 집 앞에 버려진 방부 데크를 주워왔고, 구멍은 조각도로 팠습니다. 어쩜 이리 열악한지.(ㅜ.ㅜ)

2.7

 

– 마무리

여러 삽질을 거쳐 조립이 완성되었기에 바로 다이소로 달려가서 긁힘방지 스티커를 사와 붙이고, 상판으로 올릴 강화유리를 실측하여 주문하였습니다. 유리가 너무 커서 택배배송이 안된다하여 제 경차 같은 소형차에 어거지로 실어왔습니다.

2.8

상판올리고 나니 기분 좋네요. 아 유리는 깨지는 게 걱정되서 8mm짜리 강화유리로 했어요. 근데 어째 상판올리고 나니 공장 같은 느낌보다 세련된 느낌이 더 드는지 원. 의도치 않게 예뻐진 거 같아요.

2.9

 

===============================================================

troopie 님이 하드카피월드에 게시한 “파이프 가구 DIY” 시리즈 입니다.

 

파이프 가구 DIY – 3편. 거실 탁자

$
0
0

troopie 님이 하드카피월드에 게시한 “파이프 가구 DIY” 시리즈 입니다.

 

 

파이프 가구 DIY 3 – 거실 탁자

파이프로 간단하게 코너탁자도 만들어 봤고, 복잡한 모양의 책상도 만들어 봤습니다. 다시 생각해도 파이프로 만든 책상은 꽤나 힘든 작업물이었습니다. 누가 만들어 달라 그러면 가격 세게 불러야 겠어요.^^

사실 파이프로 가장 만들고 싶었던 가구는 책장이었습니다. 이리 저리 구부러져 연결된 책장. 제가 서재에 대한 로망이 조금 있거든요. 파이프 이리 저리 꼬아서 프렌지 연결하고, 칼블럭으로 벽에 구멍 뚫어 고정시키자니 깨끗하게 도배된 벽이 너무 아까운 겁니다. 뭐 어쩔 수 없죠. 내 집이 아니니 집 망가뜨리는 건 훗날로 미루고 다른 걸 만들어 보기로 했습니다. 좀 더 재밌는 것으로다가. 그러다 눈에 들어온 것이 거실탁자 입니다. 지금 집에 식탁이 없고 다과상만 있어서 밥 먹을 때 허리를 90도로 접어야 했기에 많이 불편했거든요. 그래서 밥상 겸용으로 쓸 탁자를 만들기로 했습니다.

 

– 설계

앞의 두 작업물은 온전히 저의 생각대로 만들었다기 보다는 파이프가 가진 물성을 잘 표현하고자 하는 의도의 디자인이었습니다. 이번엔 좀 파격적으로 쇠파이프가 가진 직선적 이미지를 가지고 곡선적 이미지를 만들고 싶었습니다. 직선으로 곡선 만들기. 이게 뭔 헛소린지 참…

파이프가 가진 직선이라는 물성을 가지고 곡선을 만들려면 어떻게 해야 할까요? 이거 리만 기하학인가 하는 알 수 없는 수학에서나 가능한 것 아닌가 싶습니다. 직선이지만 곡선인…뭐 꼭 이런 이상한 생각이라기 보다는 파이프가 가진 그 직선의 이미지, 합리적 이미지를 깨고 싶었던 겁니다. 바우하우스에서도 파이프를 쓴 이유가 합리성이었다죠. 건물도 직선으로 네모 반듯하게 짓고. 사실 요즘의 디자인도 별반 다를 것 없다고 생각하거든요. 산업디자인이라는 자본주의에 포섭된 디자인의 흐름. 그 합리성이 맘에 안 들어 다른 다양함을 보여 주고 싶었습니다. 겁나게 비실용적이며 비효율적이지만 보는 이로 하여금 충격을 줄만한 그 어떤 것.

들뢰즈라는 철학자가 말하는 탈주의 속성을 지닌 탁자. 합리성이라는 중심이 빠져 다양하게 뻗어나가는, 새로운 배치로 기관 없는 신체 같은 탁자. 그런 형태를 표현하고 싶었습니다.

3.01

제멋대로 꺾이고 연결되어 요상한 모양의 스케치가 나왔습니다. 기본적인 전체 사이즈와 높이만 정해놓고 이리 꼬고 저리 꼬아서 눈이 어지러운 디자인이죠. 탁자의 중심이라고 할 만한 점도 없고, 다리 역할을 할 만한 네 개의 부분이 서로 합리적으로 연결되는 공통성도 없습니다. 마냥 자유롭게 어디까지 연결될 지 모를 만큼.

 

-자재

  • 파이프, 레듀서7, 엘보31, 사이드아웃렛 엘보4, 크로스 티1, 마개2

하도 이리 저리 많이 꼬고 꺾어서 엘보만 30개가 넘게 들었습니다. 파이프의 길이도 짧은 게 많이 들어가다 보니 가랑비에 옷 젖듯이 돈이 들어가네요. 이번 탁자의 경우 모양은 복잡해 보여도 구조 자체는 간단합니다. 서로 치수를 맞춰서 연결하는 부분이 없다 보니 단순히 연결만 하면 됩니다. 그래서 300mm이하의 짧은 파이프가 많이 들어가네요. 작업하다 맘에 안들면 즉흥적으로 디자인을 바꿔도 상관이 없을만큼 간단한 구조여요. 재료비로 8만원 조금 넘게 들었습니다. 은근 비싸죠?

 

-세척

이번이 세 번째 파이프 세척인데 계속 주방세제로 닦고 있네요. 앞으로 파이프로 무언가를 더 만들지 모르겠지만 깨끗하게 세척할 방법을 찾아야겠어요. 주방세제는 간단하게 구해서 쓸 수 있지만 아무리 잘 닦아도 기름때가 많이 남더라고요.

 

-도장

폭염주의보 하에서 락카 뿌리는 건 참 힘드네요. 락카 뿌리는 시간은 10분 정도인데 온 몸이 땀에 푹 절어버리는 군요. 건강 조심하세요.

 

-조립

꼬이는 부분 각을 잘 맞춰주면서 연결하다 보면 간단히 조립이 끝납니다. 조립하다 맘에 안 든다거나 다른 파이프에 걸려서 조립이 안되면 바로 디자인을 바꿔서 처음 설계랑 다르게 조립해도 무방합니다. 전 파이프 1개와 연결나사 1개를 다른데 놔두고 못 찾아서 설계 바꿔서 조립했다가 뒤늦게 찾는 바람에 다시 조립했습니다. 아래 두 사진에 숨은 그림 찾기 하듯이 찾으면 보일거에요.

3.02

3.03

 

– 상판 올리기 및 마무리

일단 긁힘방지 스티커 다 붙여주었습니다. 그리고 상판의 사이즈를 실측했죠. 애초에 900x900으로 사이즈를 잡았는데 상판은 좀 더 커야 하더군요. 그래서 8mm짜리 강화유리를 1000x1000으로 주문했습니다.

3.04

검은색 강화유리라 시선이 파이프보다는 강화유리에 많이 뺐기네요. 상판이 없을 때엔 어지럽고 난잡한 느낌이 많았는데, 상판 올리니 깔끔해져 버렸습니다. 괜히 검은색으로 했나봐요. 내 의도는 이게 아니었는데…투명색 강화유리로 그 구조가 훤히 보이게 했어야 했는데. 쩝. 저를 제외한 다른 사람들은 모두 예뻐졌다고 좋아했지만 많이 아쉽네요.

3.05

3.06

 

이만 파이프 DIY를 마치겠습니다. 혹시 궁금한 게 있으시면 글 남겨주세요. 제가 아는 선에서 최대한 도움을 드릴게요.

 

===============================================================================

troopie 님이 하드카피월드에 게시한 “파이프 가구 DIY” 시리즈 입니다.

 

EL Wire 컨트롤 모듈 (EL Escudo Dos 실드)

$
0
0

 

EL Wire

 

EL-Wire 는 네온사인 효과를 내는 조명장치의 일종입니다. 보통 차량 튜닝을 할 때 멋을 내기 위한 용도로 많이 사용되곤 하는데, 저전력으로도 구동이 가능하기 때문에 의류나 물체의 형태를 강조하는 용도로도 사용되곤 합니다. EL-Wire 는 이름처럼 긴 선 형태로 판매되는게 일반적인데 사각형 또는 기타 모양 형태로(EL Panel, EL Tape) 판매되기도 합니다.

99ebb87f123bd77e46dbaab6997f

어쨌든 EL-Wire를 이용하면 네온사인처럼 독특한 효과를 낼 수 있습니다. 소모 전류가 낮은 대신 밝기가 상당히 약하기 때문에 주광에서는 거의 효과가 없지만 야간에는 시선을 끌기에 충분합니다.

el-wire-21

 

EL 와이어는 일반적인 LED 처럼 동작하지 않습니다. 그보다는 커패시터(capacitor)에 가깝다고 합니다. 따라서 아두이노에서 PWM 핀을 이용해서 밝기를 제어 할 수 없습니다. 그리고 AC 전원을 사용하는 특징이 있습니다. (100V, 1000Hz)

흔히 차량의 12V(시거잭) 또는 건전지(3V)로 EL-Wire 를 밝히는데, 실제로는 인버터를 이용해서 AC 전원으로 변환해서 밝히는 겁니다. 인버터는 보통 3V, 12V 인버터를 사용합니다. 3V는 건전지를 이용해 휴대용으로 만드는데 좋고, 12V는 어댑터를 이용해 더 긴 길이, 더 밝은 EL-Wire를 원할 때 적당합니다.

10201-03a_i_ma 3V 인버터

10469-06_i_ma 12V 인버터

 

 

EL Escudo Dos

 

EL Wire 는 AC 전원으로 동작하기 때문에 아두이노와 같은 마이크로 컨트롤러로 ON/OFF 제어를 하기 까다롭습니다. 그래서 전용 컨트롤러 모듈이 필요합니다. 이를 쉽게 할 수 있도록 도와주는 모듈이 바로 EL Escudo Dos 실드입니다.

-font-b-EL-b-font-Escudo-Dos-font-b-shield-b-font-for-Arduino

아두이노에 끼워서 쓸 수 있기 때문에 사용이 간편할 뿐 아니라 총 8개의 EL-Wire(또는 Panel, Tape) 를 제어할 수 있습니다. 아두이노 보드에 9~12V 어댑터를 연결하면 자동으로  EL Escudo Dos 실드에도 전원이 공급됩니다.

그런데 EL Escudo Dos 실드에는 인버터가 포함되어 있지 않습니다. 그래서 일단 인버터는 별도로 구매해서 연결해줘야 합니다. 3V, 12V 인버터 모두를 사용할 수 있으며 연결할 때는 아래 순서로 연결하면 됩니다.

Escudo2

  • DC to Inverter (실드의 DC 전원을 인버터로 공급)
    실드의 (+) ==> 인버터의 + 입력 (빨간색 선)
    실드의 (-) ==> 인버터의 – 입력 (검은색 선)
  • AC from Inverter (인버터의 AC 전원을 실드로 공급)
    인버터의 두 라인을 순서에 관계없이 2개의 (~) 포트에 연결

여기서는 아두이노에 9V 또는 12V 어댑터를 연결해서 아두이노와 EL-Wire에 DC 전원을 공급하는 것으로 가정하고 있습니다.  만약 별도의 외부 어댑터나 건전지 전원을 사용해서 EL-Wire에 전원을 공급하고 싶다면 DC to Inverter (+), (-) 포트를 실드에 연결하지않아도 됩니다. 인버터에 직접 DC 전원을 넣어주고 AC 전원만 실드에 연결하면 됩니다.

여기서 한가지 주의할 점이 있습니다. EL Escudo Dos 실드에 연결한 인버터의 종류와 공급되는 DC 전압에 따라 EL Escudo Dos 실드의 점퍼 설정을 해줘야 합니다.

3V inverter 12V inverter
3.7V Lipo battery           close SJ1 won’t work
5V supply no changes needed close SJ1, very dim
9V supply no changes needed close SJ1, dim
12V supply no changes needed, but will run warm close SJ1, bright!
> 13.5V supply no changes needed, but will run warm replace regulator resistors A and B for 12V output,

see schematic and LM317 datasheet

위 표에서 [close SJ1] 에 해당하는 경우 실드의 SJ1 점퍼를 납땜해서 연결되도록 만들어줘야 합니다.

 

이정도만 설정해주면 EL-Wire를 아두이노에서 제어할 준비는 끝납니다. 이제 EL Escudo Dos 실드를 아두이노에 결합하고 EL-Wire를 연결한 뒤, 간단한 스케치만 작성해주면 됩니다.

주의!!! 반드시 EL-Wire를 하나 이상 연결하고 EL Escudo Dos 실드에 전원을 넣으세요. 실드가 원활히 동작하기 위해서는 적절한 부하가 필요하기 때문입니다.

 

 

소스코드 (스케치)

 

EL Escudo Dos 실드는 8개의 EL-Wire 연결 포트를 제공합니다. 순서대로 A~H 까지 보드에 표기되어 있습니다.

A~H 까지의 포트는 아두이노의 2~8번 핀으로 제어할 수 있도록 되어 있습니다. 따라서 아두이노 2~8번 핀을 digitalWrite() 함수로 제어하면 EL-Wire를 원하는대로 on/off 시킬 수 있습니다.

void setup() {                
  pinMode(2, OUTPUT);  // channel A  
  pinMode(3, OUTPUT);  // channel B   
  pinMode(4, OUTPUT);  // channel C
  pinMode(5, OUTPUT);  // channel D    
  pinMode(6, OUTPUT);  // channel E
  pinMode(7, OUTPUT);  // channel F
  pinMode(8, OUTPUT);  // channel G
  pinMode(9, OUTPUT);  // channel H
}

void loop() 
{
  // turn on
  for (int x=2; x<=9; x++)
  {
    digitalWrite(x, HIGH);   // turn the EL channel on
  }

  // turn off
  // turn on
  for (int x=2; x<=9; x++)
  {
    digitalWrite(x, LOW);   // turn the EL channel off
  }
}

 

참고로 실드는 LED를 하나 포함하고 있는데 아두이노 10번 핀과 연결되어 있습니다. 10번 핀을 이용해서 LED를 제어할 수 있습니다.

 

EL-Sequencer를 사용하면 더 편리하게 EL-wire를 제어하고, 휴대용으로 만들 수 있습니다. 이미 아두이노 칩을 보드에 포함하고 있기 때문에 외부 전원(LiPo 배터리 혹은 건전지 등), 인버터, EL-Wire만 연결하면 됩니다. 제어 방법은 EL Escudo Dos 실드와 거의 유사합니다.

5664802419_74b8e8928d

 

참고자료

 

개인용 기상관측 센서 (SEN0186)

$
0
0

 

개인용 기상대를 만들때 유용한 기상관측 센서(모듈)입니다. 온습도, 풍속, 강우량, 기압을 한번에 측정해주기 때문에 센서 여러개를 사서 조합할 필요없이 한번에 해결이 가능합니다! 대신 모듈 가격이 좀 비쌉니다;;;

기상관측 모듈에는 아래 부품들이 포함되어 있습니다.

02

대부분은 기구부 부품들이고 센서 회로 자체는 작습니다. (그림에서 우측 하단) 센서는 아래 정보들을 수집해서 출력해줍니다.

•    온도 (C)
•    습도 (%)
•    바람 방향
•    1분간 측정한 평균 풍속 (m/s)
•    5분간 측정한 평균 풍속 (m/s)
•    시간당 강우량 (mm)
•    하루 강우량 (mm)
•    기압 (hPa)

 

 

연결방법

 

기상관측 모듈은 시리얼 통신으로 데이터를 전송해줍니다. 따라서 아래 방법대로 4개 선만 연결해주면 됩니다.

  • 기상관측 모듈 –> 아두이노
  • 5V –> 5V
  • GND –> GND
  • TX –> RX
  • RX –> TX

500px-sen0186_connection_diagram

여기서는 아두이노의 하드웨어 시리얼(D0, D1) 핀을 이용하는데, 스케치 업로드 할 때 모듈이 연결되어 있으면 업로드가 되지 않습니다. 따라서 일단 TX, RX 연결은 해제한 상태에서 스케치 업로드를 해야합니다. 스케치 업로드가 끝나면 TX, RX 를 연결해서 쓰면 됩니다.

하지만 보통은 하드웨어 시리얼을 PC와 양방향 통신을 하는데 사용하므로 SoftwareSerial을 이용해서 제어하는 편이 좋아보입니다. 이때는 D0, D1 핀을 제외한 나머지 핀 중 2개를 사용하면 됩니다.

 

 

예제 코드 (스케치)

 

하드웨어 시리얼을 이용해서 제어하는 경우(D0, D1 핀 이용) 아래 코드를 이용하면 됩니다.

char                 databuffer[35];
double               temp;

void getBuffer()  //Get weather status data
{
  int index;
  for (index = 0;index < 35;index ++)
  {
    if(Serial.available())
    {
      databuffer[index] = Serial.read();
      if (databuffer[0] != 'c')
      {
        index = -1;
      }
    }
    else
    {
      index --;
    }
  }
}

int transCharToInt(char *_buffer,int _start,int _stop)  //char to int
{
  int _index;
  int result = 0;
  int num = _stop - _start + 1;
  int _temp[num];
  for (_index = _start;_index <= _stop;_index ++)
  {
    _temp[_index - _start] = _buffer[_index] - '0';
    result = 10*result + _temp[_index - _start];
  }
  return result;
}

int WindDirection()  //Wind Direction
{
  return transCharToInt(databuffer,1,3);
}

float WindSpeedAverage()  //air Speed (1 minute)
{
  temp = 0.44704 * transCharToInt(databuffer,5,7);
  return temp;
}

float WindSpeedMax()  //Max air speed (5 minutes)
{
  temp = 0.44704 * transCharToInt(databuffer,9,11);
  return temp;
}

float Temperature()  //Temperature ("C")
{
  temp = (transCharToInt(databuffer,13,15) - 32.00) * 5.00 / 9.00;
  return temp;
}

float RainfallOneHour()  //Rainfall (1 hour)
{
  temp = transCharToInt(databuffer,17,19) * 25.40 * 0.01;
  return temp;
}

float RainfallOneDay()  //Rainfall (24 hours)
{
  temp = transCharToInt(databuffer,21,23) * 25.40 * 0.01;
  return temp;
}

int Humidity()  //Humidity
{
  return transCharToInt(databuffer,25,26);
}

float BarPressure()  //Barometric Pressure
{
  temp = transCharToInt(databuffer,28,32);
  return temp / 10.00;
}

void setup()
{
  Serial.begin(9600);
}
void loop()
{ 
  getBuffer();  //Begin!
  Serial.print("Wind Direction: ");
  Serial.print(WindDirection());
  Serial.println("  ");
  Serial.print("Average Wind Speed (One Minute): ");
  Serial.print(WindSpeedAverage());
  Serial.println("m/s  ");
  Serial.print("Max Wind Speed (Five Minutes): ");
  Serial.print(WindSpeedMax());
  Serial.println("m/s");
  Serial.print("Rain Fall (One Hour): ");
  Serial.print(RainfallOneHour());
  Serial.println("mm  ");
  Serial.print("Rain Fall (24 Hour): ");
  Serial.print(RainfallOneDay());
  Serial.println("mm");
  Serial.print("Temperature: ");
  Serial.print(Temperature());
  Serial.println("C  ");
  Serial.print("Humidity: ");
  Serial.print(Humidity());
  Serial.println("%  ");
  Serial.print("Barometric Pressure: ");
  Serial.print(BarPressure());
  Serial.println("hPa");
  Serial.println("");
   Serial.println("");
}

약간의 꼼수가 들어가 있습니다. 하드웨어 시리얼 D0(RX) 핀을 이용해서 기상관측 모듈이 전달해주는 데이터를 받습니다. 그리고 D1(TX) 핀은 PC에도 연결되어 있기 때문에 D1 핀으로 수집한 정보를 PC에 출력합니다. 두 개의 시리얼을 한번에 사용하는 셈입니다.

(따라서 기상관측 센서의 RX 핀은 연결하지 않아도 될 것입니다.)

SoftwareSerial을 사용하는 경우 아래처럼 코드들을 수정해줘야 합니다. (기상관측 모듈의 TX, RX 핀이 각각 D2, D3에 연결되었다고 가정)

// 추가되는 부분
#include <SoftwareSerial.h>

SoftwareSerial softSerial(2, 3); // module's TX, RX

void getBuffer()  //Get weather status data
{
  int index;
  for (index = 0;index < 35;index ++)
  {
    if(softSerial.available())
    {
      databuffer[index] = softSerial.read();
      if (databuffer[0] != 'c')
      {
        index = -1;
      }
    }
    else
    {
      index --;
    }
  }
}

void setup()
{
  Serial.begin(9600);
  softSerial.begin(9600);
}

 

참고자료

 

반응형 네온사인 조명 만들기

$
0
0

 

EL wire는 네온사인 조명과 유사한 느낌을 내는 조명장치 입니다. “반응형 네온사인 조명 만들기”는 EL wire와 센서를 이용해서 사람이나 주변 밝기에 반응하는 조명을 직접 만들어 보는 프로젝트입니다. 집에서 장식용으로 사용하거나 상가 혹은 공공 장소의 안내용 조명 장치로 활용할 수 있습니다.

“반응형 네온사인 조명 만들기”“2016 서울 상상력 발전소 – 세운상가 그리고 메이커스” 행사의 일환으로 기획되고 워크샵을 진행하였습니다. 행사에 사용되었던 기술자료는 대부분 이 문서에 포함되어 있으므로 워크샵에 참가하지 못하신 분들은 본 문서를 활용하시면 됩니다.

 

 

 

준비물

 

제작을 위해서는 아래 부품들이 필요합니다.

  • 아두이노 우노 보드
  • EL wire : 1~8 줄 까지 사용하고 싶은 만큼
  • EL Escudo Dos 실드
  • 3V 또는 12V DC->AC 인버터
  • 아두이노용 12V 어댑터
  • 모션 센서 또는 광센서
  • 저항, 점퍼선, 글루건, 납땜 도구 및 외형 제작을 위한 도구 일체

EL wire는 AC(교류) 100~115V 정도의 고전압에서 빛을 발산하는 조명 장치입니다. 보통은 선(wire) 형태로 된 EL wire를 많이 사용하지만 면(EL panel), 테이프(EL tape) 등의 제품도 있습니다. 어떤 형태이든 사용법은 모두 같습니다.

%ea%b7%b8%eb%a6%bc5 99ebb87f123bd77e46dbaab6997f 447-00

EL wire를 밝히기 위해서는 고압의 교류 전기가 필요한데(반면 소모 전류는 낮음) 반해 일반적으로 우리가 사용하는 전원은 DC(직류) 전원입니다. 그래서 직류를 교류로 변환해주는 컨버터가 필요합니다. 대부분 3V 인버터, 12V 인버터를 사용합니다. 3V는 건전지를 이용해서 휴대용으로 만들 때, 12V는 어댑터를 이용하는 대신 더 많은 EL wire를 더 밝게 사용하고 싶을 때 사용합니다.

10201-03a_i_ma 3V 인버터  10469-06_i_ma 12V 인버터

 

그럼 EL wire를 밝힐 전원은 공급이 됩니다. 이제 센서로 측정한 조건에 따라 EL wire를 on/off 시켜야 합니다. 그런데 고압의 AC 전원을 on/off 하기 위해서는 특별한 제어장치가 필요합니다. 이런 역할을 해주는 대표적인 모듈이 EL Escudo Dos 실드입니다.

-font-b-EL-b-font-Escudo-Dos-font-b-shield-b-font-for-Arduino

EL Escudo Dos 실드는 아두이노 위에 끼워서 사용할 수 있는 실드 형태로 제작되어 있습니다. 아두이노에 끼우기만 하면 디지털 2번~9번 핀을 이용해서 8개의 EL Wire(A~H포트)를 제어할 수 있습니다. EL Escudo Dos 실드에는 DC->AC 인버터는 내장되어 있지 않기 때문에 별도로 구매해서 달아줘야 합니다.

EL Escudo Dos 실드와 인버터가 준비되면 조명 제어를 위한 준비는 끝납니다. 이제 주변의 밝기나 사람의 동작을 인식할 수 있는 센서가 필요합니다. 여기서는 가장 다루기 쉬운 센서인 광센서(조도센서)와 적외선 모션센서 중 하나를 사용하도록 하겠습니다.

%ea%b7%b8%eb%a6%bc21 광센서  pirsensor_t 모션센서

 

이상의 준비물에 아두이노만 추가하면 네온사인 조명을 만들 준비는 끝납니다.

 

 

제작 방법

 

먼저 아두이노에 센서를 연결해서 동작을 테스트 해봐야 합니다.

적외선 모션센서를 사용해서 사람의 움직임에 반응하도록 하는 경우는 아래처럼 모션센서를 아두이노에 연결합니다. (모션센서를 뒤에서 봤을때 기준으로 연결)

  • 아두이노 5V ==> 센서 (+)
  • 아두이노 GND ==> 센서 (-)
  • 아두이노 D2 ==> 센서 Out 핀

proximity_pirardbb

그리고 아래 스케치를 올려 테스트 하면 됩니다. 모션 센서로 모션이 감지되었을 때 아두이노에 내장된 (디지털 13번에 연결되어 있는) LED가 켜져야 합니다.

/*
 * PIR sensor tester
 */
 
int ledPin = 13;                // choose the pin for the LED
int inputPin = 2;               // choose the input pin (for PIR sensor)
int val = 0;                    // variable for reading the pin status
 
void setup() {
  pinMode(ledPin, OUTPUT);      // declare LED as output
  pinMode(inputPin, INPUT);     // declare sensor as input
}
 
void loop(){
  val = digitalRead(inputPin);  // read input value
  if (val == HIGH) {            // check if the input is HIGH
    digitalWrite(ledPin, HIGH);  // turn LED ON
  } else {
    digitalWrite(ledPin, LOW); // turn LED OFF
  }
}

자세한 모션 센서 사용법은 다음 링크를 참고하세요.

 

 

광센서(조도센서)를 이용해 주변 밝기를 측정해서 동작하게 하고 싶다면 광센서를 아래처럼 연결하면 됩니다.

%ea%b7%b8%eb%a6%bc1

모션센서를 사용할 때는 모션 인식 여부를 디지털 핀으로 입력 받습니다. 반면, 광센서를 사용할 때는 주변의 밝기 값을 아날로그 핀으로 측정합니다.(밝기에 따라 광센서의 저항이 변하고 출력되는 전압이 변하기 때문) 그래서 A0 아날로그 핀을 사용했습니다.

아래 스케치로 밝기에 따라 아날로그 핀으로 입력되는 값의 변화를 살펴보면 됩니다.

void setup(void) {
  // We'll send debugging information via the Serial monitor
  Serial.begin(9600);   
}
 
void loop(void) {
  int photocellReading = analogRead(photocellPin);  
 
  Serial.print("Analog reading = ");
  Serial.println(photocellReading);     // the raw analog reading
 
  delay(100);
}

주변 밝기 에 따라 값이 어떻게 변하는지 PC에서 아두이노 개발환경 – 시리얼 모니터를 실행해 확인하면 됩니다. 아날로그 핀으로 읽는 값은 0~1023 범위에서 밝기에 따라 변합니다.

적절한 밝기 값을 정한 뒤 EL wire가 켜질 기준값으로 사용하면 됩니다.

 

 

EL wire 제어

 

이제 본격적으로 EL wire 조명장치를 만들 차례입니다.

먼저 테스트에 사용되었던 센서들을 아두이노에서 제거하세요. 그리고 EL Escudo Dos 실드와 아두이노를 결합합니다. 아두이노 위에 실드를 그대로 끼우기만 하면 됩니다.

그리고 EL Escudo Dos 실드에 3V 또는 12V 인버터를 연결합니다. EL Escudo Dos 실드를 보면 인버터 연결을 위한 (1)DC TO INVERTER, (2)AC FROM INVERTER 포트가 있습니다. 인버터의 빨간색+검은색 선을 (1)번 포트에, 2줄의 검은색 선을 (2)번 포트에 연결하면 됩니다.

Escudo2 %ec%ba%a1%ec%b2%98

여기서는 아두이노에 12V 어댑터를 연결해서 전원을 공급할 예정입니다. 아두이노에 12V 전원을 넣으면 아두이노 자체가 동작하는데 필요한 전원도 공급되고 EL Escudo Dos 실드가 조명을 켜는데 필요한 전원도 공급됩니다.(인버터로 공급되어 변환된 전원을 사용)

이때 사용하는 어댑터의 전압에 따라 점퍼 설정이 필요할 수 있습니다. 아래 표를 참고해서 SJ1 점퍼를 설정해주세요.

3V inverter 12V inverter
3.7V Lipo battery           close SJ1 won’t work
5V supply no changes needed close SJ1, very dim
9V supply no changes needed close SJ1, dim
12V supply no changes needed, but will run warm close SJ1, bright!
> 13.5V supply no changes needed, but will run warm replace regulator resistors A and B for 12V output,

see schematic and LM317 datasheet

[close SJ1] 에 해당하는 경우 아래 이미지에 보이는 점퍼를 납땜해서 연결되도록 해주세요. 본 예제에서는 12V 어댑터와 12V 인버터를 사용하기 때문에 SJ1 점퍼를 납땜해서 닫았습니다.

el_escudo_dos_sj1

 

그리고 EL wire를 원하는 만큼 EL Escudo Dos 실드에 연결합니다. A~H까지 8개의 포트를 사용할 수 있습니다.

%ec%ba%a1%ec%b2%982

자세한 EL Escudo Dos 실드 사용법은 아래 링크를 참고하세요.

 

 

이제 EL wire를 제어하기 위한 준비는 완료되었습니다. 이제 분리해둔 센서를 EL Escudo Dos 실드위에 다시 연결해 줘야 합니다.

주의!!! 모션 센서를 사용하는 경우 테스트 할 때 디지털 2번 핀을 사용했습니다. 하지만 EL Escudo Dos 실드에서 디지털 2~9번 핀을 점유하고 있기 때문에 디지털 11번 핀으로 바꿔줘야 합니다. 즉, 아래처럼 연결해줘야 합니다.

  • 아두이노 5V ==> 센서 (+)
  • 아두이노 GND ==> 센서 (-)
  • 아두이노 D11 ==> 센서 Out 핀

광센서를 사용하는 경우 테스트 할 때와 똑같이 연결해주면 됩니다.

 

이제 센서를 이용해서 EL wire가 점등되는지 테스트 해볼 스케치를 작성하고 업로드 해보겠습니다. 모션 센서를 사용하는 경우는 아래 스케치를 사용하세요.

void setup() {
  pinMode(2, OUTPUT);  // channel A  
  pinMode(3, OUTPUT);  // channel B   
  pinMode(4, OUTPUT);  // channel C
  pinMode(11, INPUT);  // PIR motion sensor
}

void loop() 
{
  int status;
  status = digitalRead(11);   // Read from PIR motion sensor

  digitalWrite(2, status);   // turn the EL channel on
  digitalWrite(3, status);
  digitalWrite(4, status);
  delay(100);
}

아두이노 디지털 11번 핀으로 모션센서의 측정값을 읽습니다. 그리고 디지털 2, 3, 4번 핀으로 3개의 EL wire를 on/off 시킵니다. EL wire를 추가로 사용하는 경우라면 5, 6, 7, 8, 9 번 핀을 추가로 제어해주면 됩니다.

스케치를 아두이노에 업로드하고 12V 어댑터를 아두이노에 연결해주세요. 그럼 12V 어댑터를 통해 아두이노용 전원도 공급되고 EL Escudo Dos 실드에도 전원이 공급됩니다.

센서가 모션을 감지하면 EL wire가 켜지는지 확인하세요.

주의!!! EL wire 에는 소량의 전류이긴 하지만 고압의 AC 전원이 공급됩니다. 따라서 전원이 들어간 상태에서 절대 EL ESCUDO DOS 실드 혹은 EL wire의 포트 연결 부위를 만지면 안됩니다!! 물, 전도성 물체가 아두이노 및 실드에 닿지 않도록 주의해야 하며, 모든 작업은 반드시 전원 공급이 차단된 상태에서 해야 합니다.

 

광센서를 사용하는 경우에는 아래 스케치를 이용해서 테스트 해보세요.

void setup() {
  pinMode(2, OUTPUT);  // channel A  
  pinMode(3, OUTPUT);  // channel B   
  pinMode(4, OUTPUT);  // channel C
  pinMode(11, INPUT);  // PIR motion sensor
}

void loop() 
{
   int onoff = LOW;
   int status = analogRead(A0);   // read light sensor
   if(status > 512)  onoff = HIGH;
   else onoff = LOW;

  digitalWrite(2, onoff);   // turn the EL channel on
  digitalWrite(3, onoff);
  digitalWrite(4, onoff);
  delay(100);
}

아날로그 핀으로 광센서의 값을 읽고 일정 기준(512) 이상일 경우 EL wire 가 켜지도록 만든 스케치입니다. 기준값 512 를 원하는 값으로 변경해보세요.

 

테스트가 성공적이라면 아래처럼 센서에 의해 EL wire가 제어될 겁니다.

%ea%b7%b8%eb%a6%bc1

 

 

외형 제작

 

이제 조명 기기답게 외형을 제작하면 됩니다.

%ea%b7%b8%eb%a6%bc3

14650611_1140726625993271_8423995794704649343_n

 

상상력을 발휘해서 본인만의 멋진 네온사인 조명을 만들어 보시길!!

 

 

휴대용 블루투스 포토 프린터 만들기

$
0
0

 

보통 영수증을 출력할 때 사용하는 프린터는 열전사 프린터입니다. 아래 이미지처럼 생긴건데, 열(heat)에 감응하는 용지에 열로 글자, 이미지 등을 그려내는 방식이라 보면 됩니다.

a6

DIY 용으로도 쉽게 구매해서 사용해 볼 수 있는 프린터라서 이전에 이 프린터를 활용하는 방법에 대한 글을 올린 적이 있습니다. 보통 아두이노 또는 라즈베리 파이에 연결해서 사용합니다.

http://www.hardcopyworld.com/gnuboard5/bbs/board.php?bo_table=tech_etc&wr_id=9

 

그런데 요즘 aliexpress.com 을 검색해보니 굉장한 열전사 프린터들을 비교적 싼 가격에 판매하는게 눈에 들어오더군요.

ali_bt_printer_resized

동작 방식은 위에서 소개한 프린터와 같지만 더욱 빠르고 충전 가능한 배터리가 있어서 휴대용으로 쓸 수도 있고 블루투스, USB 연결까지 지원해 줍니다. (WiFi, IR 연결은 모델에 따라 옵션) 가격도 30$ ~ 35$ 선에서 구매가 가능합니다. 잉크값 들어갈 일이 없으니 저렴한 전용 용지만 구해두면 맘껏 프린트 할 수 있습니다. (프린터 헤더 수명이 100Km 라고…)

이 제품 보니 딱 휴대용 포토 프린터 용이다 싶어서 직접 만들어 봤습니다.

 

 

하드웨어 (프린터)

 

aliexpress.com 에서 [bluetooth printer] 로 검색하면 유사한 제품들이 주르륵 나옵니다. 제가 사용한 프린터는 아래 스펙을 가지고 있습니다.

  • 프로토콜 : ESC/POS
  • 용지 가로 폭 : 58mm (80mm 프린터도 있음)
  • 용지 롤 직경 : 4cm 이하 사용
  • 열전사 프린터 (Thermal paper 사용)
  • 블루투스 4.0, 3.0 지원
  • 가로 해상도 : 384 dop / line (노멀 사이즈 폰트 사용시 영문 32자 출력)
  • 배터리 : 7.4V, 1500mAh

bt_printer_sample

DIY 라곤 하지만 제품만 구입하면 끝.  58mm 용 감열지 (직경 4Cm 이하) 50롤 구매에 15,000원도 안하니 대량구매.

  • 주의!!  영수증 용지의 환경 호르몬 문제가 제기된 적이 있습니다. 반드시 BPA free 표시된 제품을 사용하시길 권장합니다.

이제 안드로이드 앱을 만들어 요걸 휴대용 포토 프린터로 써먹어 보겠습니다.  :)

 

 

이미지 프린트

 

구글 검색을 해보면 프린터 제작사에서 만들어서 배포하는 안드로이드/iOS 용 앱이 있습니다. 그런데 성능이 너무 떨어져서 그대로 쓸 수가 없는 지경이라 안드로이드 전용 앱 Printer Lab 을 새로 만들었습니다.

PrinterLab_title_small

블루투스  연결 관리는 이전에 작성해 둔게 있어서 쉽게 구현. 블루투스로 프린터 페어링 할 때 PIN 번호를 물어봅니다. 제가 가진 프린터는 PIN 번호가 0000 으로 설정되어 있던데 1234 로 설정된 경우도 있을겁니다. 테스트를 해보니 빠릿빠릿하게 연결되고 배터리로 구동되는 상태에서도 잘 됩니다.

가장 먼저 이미지 출력 기능을 구현했습니다.

app_image_ss

그리고 아들 사진 골라서 출력!!

bw_print_sample1

그런데 흑백으로만 나옵니다. 아들 사진 출력했는데 이래서는 뉘집 아들인지 알 수가…

 

열전사 프린터는 특성상 1픽셀을 흰색/검은색으로만 표현하기 때문에 명암(grayscale)을 표현할 수 없습니다. 그래서 컬러 이미지를 흑백(grayscale) 이미지로 변환한 뒤, 이미지 전체 grayscale 평균 값을 계산합니다. 그리고 픽셀의 밝기가 평균보다 크면 검은색, 값이 작으면 흰색으로 표현해 버립니다.

그래서 몇 가지 꼼수를 써서 5단계 명암 표현이 가능하도록 수정해 봤습니다. 아래는 수정 후 출력한 결과입니다.

bw_print_sample2

bw_print_sample3

bw_print_sample4

bw_print_sample5

이미지가 한결 보기 좋아졌습니다. 이제 아들이 아들같아 보입니다… 이 방식이 모든 이미지에 최선은 아니라서, 컨트라스트가 강하고 사물과 배경의 경계가 명확한 경우 품질이 좀 떨어져 보이기도 합니다. 하지만 대부분의 이미지에서는 더 좋은 결과를 내줍니다.

bw_print_sample6

bw_print_sample7

위에 적용한 방법은 Ordered dithering 으로 5단계 명암을 표현했습니다. 이번에는 좀 더 진화한(?) Error diffusion dithering을 적용해 보겠습니다. 사진이 좀 더 근사하게 나옵니다.

dithered_1

dithered_2

 

결과를 보면 시중에 판매되는 전용 포토 프린터에 비할바가 아니지만 이게 어딥니까. 값비싼 잉크나 포토 프린터 용지를 사지 않고도 싼 값으로 마음껏 프린트해서 놀 수 있으니까요. 핸드폰 카메라로 사진을 찍어서 바로 출력도 가능합니다.

print_sample_all

이정도 출력해도 3cm 1롤을 다 못쓸 정도로 경제적입니다. 그리고 열전사 프린터의 진정한 가치는 다음에 소개할 다양한 부가 기능에 있습니다.

 

 

다양한 부가 기능

 

사실 열전사 프린터는 이미지가 아니라 문자 출력용이죠. 그래서 기본 영문 폰트에 몇 가지 효과를 먹여서 출력할 수 있습니다.

char_print_sample

영문 출력을 테스트 해보니 속도도 빠르고 깔끔하게 프린트 됩니다. 문제는 한글… 프린터 스펙에 다국어 지원이라 적혀있긴 한데, 중국산이라 그런지 한자(간체, 번체)는 되지만 한글은 출력이 되질 않습니다. 매뉴얼을 뒤져서 한글 code page 설정법은 찾았는데 프린터에 폰트가 탑재되지 않았는지 사용불가.

이래저래 고민을 거듭하다 내린 결론은… 한글도 이미지로 출력해 버리자;;;  아래는 문자열을 이미지로 그려서 출력한 결과입니다.

print_korean_lang

영문 폰트처럼 깔끔하게 출력되는건 아니지만 상당히 괜찮게 나옵니다. 어쨌든 문제는 해결 됐으니 이걸로 다양한 부가 기능들을 구현해 봤습니다.

 

# 간단한 메모, 텍스트 출력

메모를 적어서 바로 출력 가능하도록 만들었습니다. 그리고 외부 앱, 예를 들어 카카오 톡이나 일정 관리 앱에서 텍스트(메시지)를 Printer Lab 앱으로 전달해서 출력할 수 있습니다. (외부 앱에서 이미지를 전달받아 출력도 가능)

app_text_ss

 

# QR  코드, 바코드 출력

QR 코드로 만들 텍스트를 넣으면 QR 코드를 프린트 해줍니다. 즉석에서 원하는 만큼 뽑아서 사람들에게 나눠줄 수 있습니다. 바코드 출력 기능도 구현을 해두긴 했는데… 전 쓸 일이 없어서…

app_test2

 

# RSS 뉴스 출력

뉴스를 받아와서 출력할 수 있도록 RSS 기능을 넣었습니다. RSS 주소를 등록하면 RSS 피드를 주기적으로 가져옵니다. 수집된 RSS 피드는 타임라인 탭에 쌓입니다.

app_extensions2

RSS 주소 등록이 귀찮아서 주요 RSS URL을 모아두었습니다.  아래 링크를 참고하세요. Printer Lab 내부에서 제공하는 브라우저로 원하는 RSS 주소로 들어간 뒤 버튼을 눌러 바로 등록이 가능합니다.

http://www.hardcopyworld.com/gnuboard5/bbs/board.php?bo_table=freeboard&wr_id=1387

RSS 업데이트 주기를 설정해두면 자동으로 피드를 업데이트 해줍니다. 요건 [타임라인(Timeline)] 탭에서 확인 후 한꺼번에 출력 가능합니다.

RSS 피드는 제목만 출력합니다. (본문은 출력하기엔 너무 깁니다)  RSS 피드는 최대 10개만 가져옵니다. (너무 많으면 프린터 출력에 부담, 설정에서 변경 가능)

 

# 일정 출력

구글 캘린더에서 일정을 가져와 출력할 수 있습니다. 먼저 일정 가져오기 버튼을 누르면 원하는 구글 계정을 선택하도록 창이 뜹니다. 계정을 선택하면 지금부터 24시간 이내의 일정을 가져와 타임라인에 등록해줍니다.

 

# 타임라인

업데이트 된 RSS 피드, 일정 데이터를 모아서 보여주고 한꺼번에 출력할 수 있습니다. 한번 프린트 한건 다시 출력되지 않으며 24시간이 지난 데이터는 자동으로 지워집니다.

app_extensions

 

# 기타 

  • 앱 실행시 프린터 자동 연결 기능 – 요건 PIN 코드를 미리 입력해둬야 합니다.
  • 자동 프린트 – 일정 간격으로 타임라인 탭에 쌓인 데이터를 자동 출력합니다. 프린터 자동 연결이 설정되어 있어야 합니다.

 

 

PortablePhotoPrinter_small

처음에는 열전사 프린터로 포토 프린터를 만들어보자는 취지로 시작했는데 앱을 만들다보니 점점 일이 커져서… 이런저런 기능들을 추가하게 되었네요. 여기 있는 기능외에 더 좋은 아이디어 있으면 제게도 알려주세요.

열전사 프린터 구매해서 활용해 보고 싶으시다면 Printer Lab 앱을 다운받아 꼭 써보세요. But… 안드로이드 v5.0 이상만 지원합니다.

 

 

 

참고자료

 

Printer Lab 앱 다운로드 (안드로이드 v5.0 이상만 지원)

블루투스 열전사 프린터 판매 제품 목록

전용 용지

안드로이드 ESC/POS 프린팅 How-To

 

 

 

 

[사물 인터넷 네트워크와 서비스 구축 강좌] #5-2 메신저 연동 IoT 서비스

$
0
0

 

강좌 목차 보기

  • 현재 강좌 ==> [사물 인터넷 네트워크와 서비스 구축 강좌] #5-2 메신저 연동 IoT 서비스

 

 

이번 파트에서 다루는 주제는 꽤나 흥미롭습니다. 바로 메신저를 연동한 IoT 서비스 구축입니다.

 

사물인터넷 서비스를 구성함에 있어 가장 신경써야 할 부분 중 하나가 사용자와의 접점입니다. 서버에 아무리 고급 데이터가 모이더라도 이걸 사용자에게 효과적으로 보여줄 수 있는 다양한 방법이 필요합니다. 맥/윈도우/리눅스용 어플리케이션, iOS/안드로이드 같은 모바일 앱, 웹 등등 사용자는 다양한 플랫폼을 사용하기 때문에, 이런 플랫폼에서 우리가 만든 서비스를 이용할 수 있는 방법들을 고안해야 합니다. 그리고 우리 서비스를 사용하도록 마케팅을 해야하고 유지보수도 꾸준히 해줘야 합니다.

특히나 이 강좌가 목표로 하는 개인/소규모 팀 단위에서 프로토타이핑을 하는 경우라면, 사용자와의 접점이 되는 다양한 플랫폼을 지원하기 위해 시간과 노력을 들이기란 너무 부담스럽습니다. 이런 경우는 SNS 서비스가 효과적인 대안이 될 수 있습니다. 예를 들어, 보안상 중요하지 않은 데이터를 수신받고 싶을 때 트위터와 연동시키면 여러 플랫폼용 어플리케이션을 개발하지 않아도 트위터 서비스를 UI 로 이용할 수 있습니다. 페이스 북이나 여타 SNS 서비스도 (꽤나 제약이 있긴 하지만) 마찬가지입니다.

여기서는 그 중 텔레그램(Telegram)을 이용하는 방법을 소개하려 합니다. 텔레그램은 챗 봇이라는 대단히 실험적이고 재밌는 서비스를 제공하기 때문에 우리가 만드는 사물인터넷 서버와 궁합이 잘 맞습니다. 특히 텔레그램의 챗 봇은 상용 서비스보다는 Tech DIY 용도 또는 제한된 그룹의 인원들만을 대상으로 서버의 상태를 리포트 하는 경우 대단히 유용합니다.

 

앞선 파트 [5-1 Node.js 서버 연동] 에서 센서장치가 보내준 데이터를 [nodejs폴더/data/data.txt] 파일에 저장했습니다. 이 파일은 센서장치가 새로운 값을 보내줄 때마다 업데이트 되지요. 이번 파트에서 실습할 내용은 텔레그램 챗 봇을 이용해 data.txt 에 담긴 센서장치 데이터를 텔레그램으로 보여주도록 하겠습니다.

 

 

텔레그램과 봇 파더

 

챗 봇은 텔레그램이 제공하는 기능 중 하나입니다. 카xx톡 같은 서비스를 사용하다보면 ‘이런 기능이 있었으면 좋겠다’ 라고 생각하신 적 많을 겁니다. 그런걸 개인이 직접 구현할 수 있도록 제공해주는 기능이 챗 봇입니다.

텔레그램 내에서 챗 봇을 생성하면 Bot 기능이 들어간 채팅창이 하나 생깁니다. 그리고 라즈베리파이에서 챗 봇과 연동되는 프로그램을 작성하면, 내가 생성한 채팅창에 메시지를 뿌릴 수 있습니다. 이 채팅창에는 다수의 사람들이 참여할 수 있고, 참가자들이 봇에게 명령어를 전달할 수도 있습니다. 물론 라즈베리파이는 이 명령어를 처리하고 결과를 뿌려줄 코드가 들어가 있어야겠죠.

텔레그램 봇을 이용하기 위해서는 봇을 생성하고 Bot API 를 사용하기 위한 키를 제공 받아야 합니다. 텔레그램에서는 이러한 설정을 편하게 하기 위한 BotFather  채널을 운영하고 있습니다.

 

BotFather 채널 추가하기

안드로이드 폰의 경우 우측 상단에 있는 돋보기 아이콘을 클릭하고, 아이폰의 경우 Chat 탭에서 리스트를 아래로 스크롤 해 검색창을 열고 @BotFather를 검색해서 추가합니다.

 

챗 봇 생성

BotFather 채팅창에서 ‘시작’버튼을 누른 후, 새로운 봇을 생성하기 위해 채팅창에 ‘/newbot’이라고 타이핑 하거나 채팅창의 ‘/’ 아이콘을 클릭해 ‘/newbot’을 선택합니다.

 

봇의 이름과 봇의 ID를 생성합니다. 봇의 이름은 이후 봇 사용시 상단에 보이는 이름이며, 봇 ID는 BotFather 검색해서 연결할 때와 마찬가지로 봇에 접속 또는 검색하기 위해 사용되는 유일한 값입니다.

/newbot 이후 첫 질문이 ‘이름을 뭘로 하겠는가?’, 두 번째 질문이 ‘아이디를 뭘로 하겠는가?’ 입니다. (ID는 반드시 공백없이 Bot 또는 bot 으로 끝나야합니다.) 각각에 대한 답을 채팅창에 적어 보내면 BotFather 가 알아서 처리해줍니다.

 

봇 ID 까지 생성 완료하면 다음과 같이 API 토큰값이 전달됩니다. 이 키값은 라즈베리파이에서 봇을 제어하기위해 사용됩니다.

 

이제 채팅창 리스트로 가보면 내가 만든 챗 봇이 내가 설정한 이름으로 보일 것입니다.

 

 

봇 명령어 처리

 

이제 라즈베리파이에서 텔레그램 봇을 통해 들어오는 요청을 처리하는 텔레그램 봇 서버 코드를 구현해야 합니다. 파이썬으로 텔레그램 봇 서버를 구현하기 위해 파이썬 모듈 중 ‘telepot’을 이용할 예정입니다.

PIP를 통해 telepot을 다운 받습니다.

  • sudo pip3 install telepot

 

telepot을 다운로드 받은 후, 파이썬으로 특정 텍스트(status)를 수신했을 때 센서장치 데이터(data.txt)를 채팅창에 전송하도록 구현하겠습니다.

#-*- coding: utf-8 -*-
import time
import telepot
from telepot.loop import MessageLoop

def handle(msg):
    content_type, chat_type, chat_id = telepot.glance(msg)

    if content_type == 'text':
        if msg['text'].upper() == 'STATUS':
            f = open("./simple_server_test/data/data.txt", 'r')
            data = f.read()
            bot.sendMessage(chat_id, data)
        elif msg['text'] == '/start':
            pass
        else:
            bot.sendMessage(chat_id, '지원하지 않는 기능입니다')


TOKEN = 'your_telegram_token_here'    # 텔레그램으로부터 받은 Bot API 토큰

bot = telepot.Bot(TOKEN)
MessageLoop(bot, handle).run_as_thread()
print ('Listening ...')

# Keep the program running.
while True:
    time.sleep(1000)

 

파이썬 파일을 라즈베리파이 원하는 위치에 올려두세요. 대신 소스코드에서 data.txt 파일을 읽어올 수 있도록 경로는 자신의 환경에 맞게 수정해야 합니다.

f = open("./simple_server_test/data/data.txt", 'r')

 

그리고 앞서 챗 봇을 생성할 때 발급받은 API 토큰 값을 넣어주세요.

TOKEN = 'your_telegram_token_here'    # 텔레그램으로부터 받은 Bot API 토큰

 

챗 봇 제어부는 아래와 같습니다.

if content_type == 'text':
        if msg['text'].upper() == 'STATUS':
            f = open("./simple_server_test/data/data.txt", 'r')
            data = f.read()
            bot.sendMessage(chat_id, data)
        elif msg['text'] == '/start':
            pass
        else:
            bot.sendMessage(chat_id, '지원하지 않는 기능입니다')

 

status‘ 라는 텍스트를 누군가 입력하면 센서값이 저장된 data.txt 파일을 열고 데이터를 읽어서 채팅창에 전송해주는 코드입니다.

텔레그램 앱을 실행해서 앞서 생성한 봇 창에 status 를 입력해보세요. 결과가 아래처럼 보일것입니다. 센서장치의 데이터가 사용자에게까지 효율적으로 전달되었지요!

 

이건 가장 간단한 구현 예일 뿐입니다. 챗 창에 이미지나 파일을 전송할 수도 있고, 더 복잡한 명령어를 받아 센서들을 제어할 수도 있습니다. 심지어는 챗 봇으로 즐기는 게임을 만들 수도 있고 결제를 할 수도 있습니다.

 

 

활용

 

텔레그램이나 SNS를 내가 기획하는 사물인터넷 서비스와 연동하면 다양한 플랫폼에 대응하는 사용자 UI 앱을 직접 만들지 않아도 된다는 점에서 무척 편리합니다. 비록 상용 서비스를 기획한다면 이 방법은 고려대상이 되기 힘들지만, 소규모-개인 프로젝트라면 이런 방식이 어울리겠지요.

특히 공장이나 센서 값의 이상 유무를 즉시 관련된 사용자 그룹에 알려줘야 하는 서비스의 경우, 이런 챗 어플을 사용한 서비스의 강점이 십분 발휘됩니다.

 

 

참고자료

 

 

주의!!! [사물 인터넷 네트워크와 서비스 구축 강좌] 시리즈 관련 문서들은 무단으로 내용의 일부 또는 전체를 게시하여서는 안됩니다. 계속 내용이 업데이트 되는 문서이며, 문서에 인용된 자료의 경우 원작자의 라이센스 문제가 있을 수 있습니다.

 

강좌 목차 보기

  • 현재 강좌 ==> [사물 인터넷 네트워크와 서비스 구축 강좌] #5-2 메신저 연동 IoT 서비스

 

 


[사물 인터넷 네트워크와 서비스 구축 강좌] #5-3 MQTT 연동 IoT 서비스

$
0
0

 

강좌 목차 보기

  • 현재 강좌 ==> [사물 인터넷 네트워크와 서비스 구축 강좌] #5-3 MQTT 연동 IoT 서비스

 

 

사람들이 채팅 서비스에 모여 채팅방을 만들어 그룹화하고 메시지를 주고 받듯이, MQTT는 인터넷 네트워크에 참여한 다양한 장치들을 그룹화해서 서로 메시지를 주고 받을 수 있도록 해주는 프로토콜입니다.

이번 파트에서는 사물인터넷 구축할 때 사용할 수 있는 강력한 툴 중 하나인 MQTT 를 사용해보겠습니다. 그리고 MQTT 를 이용해서 센서장치, 서버, 모바일이 함께 동작하도록 만들어 보겠습니다. 그 전에, MQTT 의 동작 구조와 몇 가지 특징들을 기억해야 합니다.

 

 

MQTT 소개

 

MQTT (MQ Telemetry Transport)는 센서장치나 라즈베리파이 같은 임베디드 장치, 모바일 장치 사이의 통신을 위한 가벼운 메시징 프로토콜입니다. TCP/IP 기반으로 대역폭이 작은 네트워크에서 동작할 수 있도록 설계된 프로토콜입니다. 쉽게 얘기해서 임베디드 장치들을 위한 트위터라고 볼 수 있습니다.

MQTT 자체는 메시지를 어떻게 보낼 것인지를 정의하는 규약일 뿐입니다. 따라서 실제 “MQTT 트위터”를 동작시키기 위해서는 서버 역할을 해주는 장치와 프로그램이 필요한데 이를 MQTT 브로커(Broker)라고 합니다. MQTT 브로커는 각종 장치들(MQTT Client)이 보내주는 메시지를 수집하고 이걸 다시 필요한 장치들에게 전송해주는 중계서버 역할을 합니다.

 

MQTT 클라이언트는 브로커에게 메시지를 전달하거나 필요한 메시지를 받기만 하면 되고, MQTT 프로토콜의 구조도 간단하기 때문에 처리능력이 낮은 임베디드 장치에 잘 어울립니다. 메시지는 트위터처럼 140자 제한이 없으므로 긴 메시지나 JSON 포맷 또는 파일도 전송이 가능합니다. 이런 특징들 때문에 MQTT 프로토콜은 센서 네트웍을 구성하는데 유용한 도구로 관심을 받고 있습니다.

 

MQTT 동작 구조

트위터 서비스의 동작구조를 떠올려보세요. 트위터에서 사용자는 다른 사용자를 follow 할 수 있습니다. 그럼 다른 사용자가 생성하는 메시지(트윗)를 받아볼 수 있죠. 그리고 스스로 메시지를 생성할 수도 있습니다. 그럼 자신을 follow하는 사용자에게 메시지가 전달되죠.

MQTT도 거의 유사한 동작구조를 갖습니다. MQTT 시스템에 참여하는 MQTT 클라이언트는 메시지 발행(publish, 트윗에 해당), 메시지 구독(subscribe, follow에 해당) 두 가지 동작을 할 수 있습니다. MQTT 클라이언트가 메시지를 특정 채널(Topic, 토픽)에 발행하면 이 채널을 구독한 모든 클라이언트에게 메시지가 전달되는 겁니다. 중간에서 메시지를 수집, 재분해 하는 작업은 MQTT 브로커가 담당합니다.

 

토픽 (Topic)

메시지를 발행/구독(pub/sub) 하는 행위는 채널 단위로 일어납니다. 이를 MQTT에서는 토픽(Topic)이라고 합니다. 토픽은 슬래시(/)로 구분된 계층구조를 갖습니다.

topic_basics

메시지를 구독/발행 할 때 여러개의 토픽을 한번에 지정할 수 있도록 wild card 문자를 지원합니다. [+] 문자는 단 1개의(1 레벨) 토픽을 임의의 토픽으로 대체하는 와일드카드 문자입니다.

topic_wildcard_plus

반면 [#] 문자는 여러 레벨의 토픽을 대체할 수 있습니다. [myhome/#] 처럼 사용하면 myhome 의 하위 토픽들 모두를 지칭하게 됩니다. [#] 문자는 토픽 문자열 끝에만 사용할 수 있으며 하위 토픽 모두를 지칭합니다. (2단계 이상 하위 토픽도 포함)

topic_wildcard_hash

[$] 문자로 시작하는 토픽은 시스템에 의해 사용되는 특수한 토픽을 의미합니다. 이 토픽들은 [#] 문자열로 지정해도 포함되지 않는 토픽이 됩니다. 주로 [$SYS/] 로 시작하는 토픽들이 브로커의 내부 메시지를 위해 사용됩니다. (이에 대한 명확한 표준은 없는 상태인듯)

토픽 구조를 구성할 때 몇 가지 주의할 점이 있습니다.

  • 최상위 토픽이 [/] 문자로 시작하지 않도록 합니다. [/home/sensor/humid] 이렇게 사용할 수는 있지만 최상위 토픽이 이름이 없는 토픽이 되므로 사용하지 않는 것을 권장합니다.
  • 토픽 이름에 공백을 사용하지 않습니다.
  • 토픽 이름은 ASCII 문자만 사용합니다. (임베디드 장치와의 호환성을 위해 주의)
  • [#] 를 이용해서 토픽 전체를 구독하지 않도록 합니다. 오버헤드가 심할 경우 브로커/클라이언트 프로세스가 중단될 수 있습니다.

 

QoS (Quality of Service)

MQTT는 시스템에 참여하는 장치들의 처리 능력, 네트워크 대역폭, 메시지 오버헤드 등 주변상황에 맞게 시스템이 동작할 수 있도록 3단계 QoS(Quality of Service) 를 제공합니다.

  • 0 : 메시지는 한번만 전달하며, 전달여부를 확인하지 않는다. Fire and Forget 타입이다.
  • 1 : 메시지는 반드시 한번 이상 전달된다. 하지만 메시지의 핸드셰이킹 과정을 엄밀하게 추적하지 않기 때문에, 중복전송될 수도 있다.
  • 2 : 메시지는 한번만 전달된다. 메시지의 핸드셰이킹 과정을 추적한다. 높은 품질을 보장하지만 성능의 희생이 따른다.

 

0에 가까울수록 메시지 처리에 대한 부하가 적은 대신 메시지 손실 위험이 높아집니다. 2에 가까울수록 메시지 손실 위험은 줄어들지만 메시지 처리 부하가 급격히 늘어납니다.

(보통 0~1 정도의 QoS를 사용하면서 메시지 손실등의 위험은 상위 어플리케이션 차원에서 관리하도록 하는듯 합니다.)

 

 

MQTT 브로커 설치

 

MQTT 브로커는 시스템의 핵심 서버 역할을 하며,  여기에 메시지가 수집되고 다시 재분배 됩니다. 다양한 MQTT 브로커 프로그램들이 개발되어 있는데 ActiveMQ, Apollo, IBM Message SightJoramMQMosquittoRabbitMQSolace Message Routers 등이 자주 사용됩니다. 아래 링크에 MQTT 브로커의 특징을 비교한 자료가 있습니다.

 

여기서는 Mosquitto 브로커를 사용할 것입니다. Mosquitto는 MQTT의 기본 기능을 충실히 지원하는 가벼운 MQTT 브로커 프로그램입니다. Mosquitto 클라이언트 프로그램도 있으므로 여러대의 PC를 이용해서 테스트를 할 수 있습니다.

MQTT 동작 테스트를 위해 라즈베리파이에 Mosquitto MQTT 브로커를 설치하고 PC 및 모바일 폰에는 MQTT 클라이언트를 설치 할 것입니다.

라즈베리파이에 Mosquitto 브로커를 설치하는 작업부터 시작합니다. Mosquitto 는 apt-get 명령어를 통해 간단히 설치할 수도 있지만 업데이트가 되지 않는 문제점이 보고되고 있습니다. 아래 순서로 설치하길 권장합니다. (최신 소스코드를 다운로드 받아 설치하실땐 링크를 참고하세요.)

  • 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-wheezy.list
  • sudo apt-get install mosquitto

 

설치가 완료되면 브로커는 1883 포트를 사용하게 됩니다.

 

이제 PC와 모바일 폰에 MQTT 클라이언트를 설치해서 연동을 해보겠습니다. PC(Windows, Linux, OS X)에서는 MQTT.fx 클라이언트를 설치하면 됩니다. 아래 링크에서 프로그램을 받을 수 있습니다.

 

MQTT.fx 클라이언트는 윈도우 64비트만 지원합니다. 이 문제 때문에 설치가 안된다면 크롬 브라우저의 확장 앱으로 설치해서 사용하는 방법도 있습니다. 크롬 브라우저에서 아래 링크를 통해 설치할 수 있습니다.

 

모바일 폰에서는 앱 스토어에서 MQTT로 검색하시면 됩니다. 다양한 클라이언트가 등록되어 있는데 대부분 비슷하므로 아무거나 사용하셔도 됩니다. 유명한 MQTT 클라이언트들은 링크에서 확인하실 수 있습니다.

 

설정 방법은 간단합니다. 일단 MQTT 브로커 연결을 위해 아래 항목들만 정확히 설정해 주면 됩니다.

  • MQTT 브로커 URL : MQTT 브로커를 설치한 서버의 URL 입니다.
    • 같은 공유기에 PC, 모바일 폰, 라즈베리파이가 같이 물려있다면 라즈베리파이의 내부 IP 주소(192.168.x.x)를 사용하면 됩니다.
  • Port : 앞서 설치한 Mosquitto 브로커는 기본 1883 포트를 사용합니다.
  • Username / Password : 지금은 설정하지 않아도 됩니다.

 

그리고 우리가 메시지를 받을 Topic 을 지정해주면 이후 해당 Topic 으로 들어오는 메시지를 볼 수 있습니다. MQTT 클라이언트에서 subscribe 버튼을 누르고 토픽에 messagebox를 입력합니다. 그럼 messagebox 토픽이 생성되고 구독이 됩니다. PC, 모바일 등 모든 장치에서 같은 작업을 해줍니다.

이제 PC, 모바일에서 publish 를 합니다. 이때 토픽은 messagebox로 선택합니다. 그럼 입력한 메시지가 브로커로 전달되고 messagebox 토픽을 구독하는 다른 장치들에도 전달되어야 합니다. 제대로 동작하는지 확인해보세요.

 

MQTT 브로커를 설치한 라즈베리파이에 MQTT 클라이언트를 설치해서 확인할 수도 있습니다.

  • apt-get install mosquitto-clients

 

아래 명령으로 메시지 발행(pub)을 할 수 있습니다. 다른 기기에도 메시지가 보여야겠죠.

  • mosquitto_pub -d -t messagebox -m “sent from RPi server”

 

특정 토픽을 구독(sub) 할 수 있습니다. 이 경우 특정 토픽에 메시지가 도착 할 때마다 표시됩니다. Ctrl+c 를 눌러 멈추기 전까지는 메시지 표시하는 상태로 유지됩니다.

  • mosquitto_sub -d -t messagebox

 

 

센서장치와 MQTT

 

이제 센서장치에 MQTT client 기능을 넣어서 데이터를 뿌리면 PC – 서버 – 모바일 폰 등 다양한 장치들이 메시지를 수신할 수 있겠죠?

센서장치에 MQTT 기능을 넣기 위해서는 라이브러리 설치가 필요합니다. 아두이노 개발환경을 실행해서 [메뉴 – 스케치 – 라이브러리 포함하기 – 라이브러리 관리] 를 순서대로 실행합니다. 그리고 PubSubClient 로 검색하세요. 발견된 라이브러리 중 PubSubClient 라이브러리를 설치하면 됩니다.

 

ESP32 모듈이 MQTT 를 이용해 데이터를 송신, 수신할 수 있도록 코드를 올려보겠습니다. 아래 스케치를 받아 ESP32에 올려주세요.

 

소스코드에서 아래 부분들을 수정해줘야 합니다.

const char* ssid = "your_ssid";
const char* password =  "your_pass";
const char* mqttServer = "192.168.1.9";
const int mqttPort = 1883;
const char* mqttUser = "yourMQTTuser";
const char* mqttPassword = "yourMQTTpassword";
const char* topic_pub = "messagebox";
const char* topic_sub = "messagebox2";

ssid, password 는 자신의 공유기 환경에 맞게 수정하세요. mqttServer 는 MQTT 브로커가 설치된 라즈베리파이 주소입니다. 같은 공유기 안에 있다면 내부 IP 주소를 넣어주면 됩니다. mqttUser, mqttPassword 는 사용하지 않습니다. topic_pub 가 메시지를 전송할 토픽 이름입니다. topic_sub 는 센서장치로 들어오는 메시지 수신을 위해 새로 만든 토픽입니다. (별도로 토픽을 만드는 작업은 필요 없습니다. 다른 장치에서 해당 토픽으로 보내기만 하면 됩니다.)

 

이제 스케치를 업로드하고, 시리얼 모니터를 켜세요. 그리고 PC, 모바일 폰 등에 설치된 MQTT client를 유심히 보세요.

messagebox 토픽으로 센서장치가 생성하는 랜덤한 숫자가 5초 간격으로 보일겁니다. 그리고 MQTT client 에서 messagebox2 토픽으로 메시지를 보내면, ESP32 가 받아서 시리얼 모니터에 표시해 줄겁니다.

 

이처럼 MQTT 를 활용하면 큰 힘 들이지 않고도 장치들을 자유자재로 연결할 수 있습니다.

 

ESP32 에 올린 소스코드를 보겠습니다. 초기화 함수인 setup() 함수부터 보죠.

void setup() {
  ......
  mqttClient.setServer(mqttServer, mqttPort);
  mqttClient.setCallback(callback);
 
  while (!mqttClient.connected()) {
    Serial.println("Connecting to MQTT...");
    
    if (mqttClient.connect("ESP32Client", mqttUser, mqttPassword )) {
      Serial.println("connected");
    } else {
      Serial.print("failed with state ");
      Serial.print(mqttClient.state());
      delay(2000);
    }
  }

  mqttClient.subscribe(topic_sub);
  mqttClient.publish(topic_pub, "ESP32 logged in");
  prevUpdateTime = millis();
}

 

공유기에 연결된 이후로 mqttClient.setServer() 함수를 호출해서 MQTT 서버 연결 정보를 등록합니다. 그리고 mqttClient.setCallback() 을 호출해서 subscribe 한 토픽에서 메시지를 받았을 때 호출될 함수를 지정해줍니다.  콜백함수에는 호출될 때 받은 메시지를 출력하는 코드만 넣어뒀습니다.

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived in topic: ");
  Serial.println(topic_sub);
 
  Serial.print("Message: ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
 
  Serial.println();
  Serial.println("-----------------------");
}

 

이제 mqttClient.connect() 함수를 이용해 MQTT 브로커에 연결을 시도합니다. 연결이 완료되면 subscribe()  함수를 이용해 메시지 구독할 토픽을 지정해줍니다. public() 함수를 이용하면 특정 토픽에 메시지를 전송할 수 있습니다.

loop() 함수에서는 주기적으로 랜덤한 숫자를 생성해 messagebox 토픽으로 전송합니다.

void loop() {
  mqttClient.loop();

  unsigned long currentTime = millis();
  if(currentTime > prevUpdateTime + UPDATE_INTERVAL) {
    int i = random(100);
    std::stringstream st;
    st<<i;
    mqttClient.publish(topic_pub, st.str().c_str());
    prevUpdateTime = currentTime;
  }
}

 

 

서버에서 MQTT 처리하기

 

우리가 서버로 사용하는 라즈베리파이 홈 서버에는 MQTT 브로커가 설치되어 있습니다. 하지만 MQTT 브로커는 메시지를 중계할 뿐, 메시지를 받아 특정한 작업을 처리하지는 않습니다.

라즈베리파이 서버도 MQTT 메시지를 받으면 특정한 작업을 처리하도록 파이썬으로 코드를 만들어 보겠습니다. 먼저 python 에서 MQTT client 모듈을 쓸 수 있도록 설치작업을 해야합니다.

  • sudo pip3 install paho-mqtt

 

이제 아래에서 소스코드를 받아 라즈베리파이 적당한 곳에 올려두세요.

 

코드는 굉장히 간단합니다.

import paho.mqtt.client as mqtt
import time

mqttc = mqtt.Client('RaspberryPI')
mqttc.connect('test.mostquitto.org', 1883)
while mqttc.loop() == 0:
     mqttc.publish('rfd', 'Publish')
     time.sleep(10)

 

여기서 mqttc.connet() 함수 호출할 때 넘기는 파라미터를 수정해주세요. 라즈베리파이 자신에 MQTT 브로커가 설치되어 있으니 자신의 IP를 넣어주면 됩니다. 그리고 mqttc.publish() 함수를 이용해 메시지를 전송할 때 사용하는 topic 이 ‘messagebox’ 로 되어있는지 확인하세요.

 

수정이 끝났으면 이 파이썬 코드를 실행해보죠.

  • python3 mqtt-publish.py

 

실행시키면 터미널 창에는 아무 반응이 없을겁니다. 하지만 주기적으로 MQTT 로 메시지를 보내도록 되어 있습니다. PC/모바일 폰에서 MQTT client 로 확인해보세요. 아래처럼 “Message from RPi” 가 주기적으로 찍히면 정상입니다.

 

이번에는 반대로 MQTT 메시지를 받는 코드를 만들어 보겠습니다.

 

마찬가지로 소스를 받은 후 몇 가지 수정해줘야합니다.

import socket
import fcntl
import struct
import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe("hello/world")

def on_message(client, userdata, msg):
    print( msg.topic+" "+str(msg.payload))

def get_ipaddress(network):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915,  # SIOCGIFADDR
        struct.pack('256s', network[:15].encode('utf-8'))
    )[20:24])


port = 1883

client = mqtt.Client('RaspberryPI')
client.on_connect = on_connect
client.on_message = on_message

client.connect(get_ipaddress('eth0'), port, 60)
client.loop_forever()

 

MQTT 브로커에 연결되면 호출되는 콜백함수가 on_connect() 입니다. 여기서 client.subscribe() 함수를 이용해 특정 토픽을 구독하도록 짜여져있습니다. 따라서 구독할 topic 이름을 센서장치가 메시지를 보내주는 messagebox 로 수정해줘야 합니다.

def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe("hello/world")

 

나머지 코드는 수정할 부분이 없습니다. 왜냐면 라즈베리파이 자신이 IP 주소를 가져와서 사용하도록 코드가 짜여져 있거든요.

코드 중 on_message 함수는 구독한 채널로 메시지가 들어올 때 호출되는 콜백함수입니다. 센서장치의 데이터를 수신했을 때 호출되겠지요. 수신된 데이터를 출력만 합니다.

def on_message(client, userdata, msg):
    print( msg.topic+" "+str(msg.payload))

 

파일을 실행했을 때 진행되는 코드는 아래와 같습니다.

port = 1883

client = mqtt.Client('RaspberryPI')
client.on_connect = on_connect
client.on_message = on_message

client.connect(get_ipaddress('eth0'), port, 60)
client.loop_forever()

 

MQTT 브로커에 연결되었을 때, 구독한 topic 으로 메시지가 들어왔을 때 실행할 콜백 함수를 등록해 줬습니다. 그리고 client.connect() 함수를 이용해 MQTT 브로커에 연결했습니다. client_loop_forever() 함수를 호출하면 MQTT 관련 작업이 백그라운드에서 계속 실행됩니다. 그리고 코드 진행은 여기서 멈춥니다. (사용자가 Ctrl+C 를 눌러 강제로 멈추기 전까지는요.)

 

이상의 mqtt.py 파일을 실행하면 아래와 같이 센서장치의 데이터를 받아 출력해 줄겁니다.

  • python3 mqtt.py

 

이 코드에서 살을 붙여나가면 서버에서 각종 MQTT 메시지를 받아 처리할 수 있겠죠!! 물론 MQTT 메시지는 파이썬 외에 Node.js 등 다른 플랫폼에서도 라이브러리를 통해 같은 방식의 제어가 가능합니다.

 

 

모바일에서 MQTT 처리하기

 

안드로이드나 iOS 같은 모바일 장치에 MQTT client 를 설치했다면 센서장치가 전송하는 메시지를 수실할 수 있을겁니다. 모바일 폰에 이런 기능을 직접 구현하고 싶다면 Paho 라이브러리를 사용하길 추천합니다. Paho 프로젝트는 Java 뿐 아니라 C/C++, JavaScript, Android, Python, Go, Rust, C# 등 다양한 언어에서 MQTT client 를 구현할 수 있도록 라이브러리를 제공하는 프로젝트입니다.

 

Paho 홈페이지에서 안드로이드 라이브러리를 이용하면 MQTT client 를 안드로이드 앱 안에 넣을 수 있습니다.

 

다만 페이지 업데이트가 느리고 라이브러리 코드가 약간 복잡해서 사용이 어려울 수도 있을겁니다. 안드로이드용 라이브러리를 이용한 안드로이드 앱 샘플을 제작해서 올려뒀으니 아래 코드를 다운로드 받아 분석하고 실행해보세요.

 

앱을 다운로드 받은 후 직접 빌드하고, APK 파일을 안드로이드 폰에 올려 설치해 보시기 바랍니다.

 

MQTT를 응용해서 음성으로 센서장치 제어가 가능하도록 만든 안드로이드 앱도 코드를 공유하고 있습니다. 아래 링크를 참고하세요.

 

안드로이드는 코드 양이 많고 라이브러리 사용법이 꽤 복잡해서 여기서 다루지는 않습니다. 하지만 MQTT 의 동작구조를 숙지하고, Java 언어와 Android 플랫폼에 대한 이해가 있다면 직접 분석하실 수 있을겁니다.

 

 

활용

 

사물인터넷에 참가하는 센서나 PC, 모바일 폰 등… node에 해당하는 장치와 사용자가 많을수록, 서버에 전달된 메시지를 적재적소에 직접 분배하기는 어려워집니다. MQTT 를 사용하면 Topic 기반한 채널 관리로 이런 수고를 상당 부분 줄일 수 있습니다. 실제 페이스북이나 우아한 형제들에서도 MQTT 를 서비스에 활용하는 것으로 알려져 있습니다.

당장 사용하지는 않더라도 MQTT 의 존재와 활용 가능성은 염두에 두세요. 구현하는 서비스의 규모가 점점 커질수록 MQTT 에 대한 향수가 점점 커질지도 모릅니다.

 

 

참고자료

 

 

주의!!! [사물 인터넷 네트워크와 서비스 구축 강좌] 시리즈 관련 문서들은 무단으로 내용의 일부 또는 전체를 게시하여서는 안됩니다. 계속 내용이 업데이트 되는 문서이며, 문서에 인용된 자료의 경우 원작자의 라이센스 문제가 있을 수 있습니다.

 

강좌 목차 보기

  • 현재 강좌 ==> [사물 인터넷 네트워크와 서비스 구축 강좌] #5-3 MQTT 연동 IoT 서비스

 

 

[라즈베리파이] 홈 오토메이션 서버 예제 실행을 위한 준비

$
0
0

 

 

본격적으로 홈 오토메이션 서버를 구축하기 위해 기본적인 설정을 해보겠습니다.

 

우선, 서버에서 사용할 데이터베이스를 생성해야 합니다.

라즈베리파이에서는 MySQL 호환 DBMS 인 MariaDB를 사용합니다. apt-get 을 통해 MariaDB를 설치합니다.

sudo apt-get install mariadb-server mariadb-client

 

설치 도중 root 비밀번호를 설정하는 팝업이 뜨는 경우, 비밀번호를 설정해 줍니다.

팝업이 뜨지 않는 경우, 설치 완료 후 다음과 같이 입력하여 root 비밀번호를 설정해 줍니다.

sudo mysql_secure_installation

패스워드 반드시 지정해주시고, 나머지 다 Y 로 대답하면 됩니다.

 

데이터베이스 생성을 위해 MariaDB를 실행합니다.

sudo mariadb -u root -p

 

비밀번호를 입력하면 MariaDB가 실행됩니다.

홈 오토메이션 서버에서 사용하는 데이터베이스를 생성합니다.

CREATE DATABASE sensor_db;

 

다음, 방금 생성한 데이터베이스에 연결해 채널 테이블과 데이터 테이블을 생성합니다.

connect sensor_db

CREATE TABLE `channel_table` (
  `channel` int(11) NOT NULL AUTO_INCREMENT,
  `channel_info` varchar(20) DEFAULT NULL,
  `auth_code` char(6) DEFAULT NULL,
  `status` char(1) DEFAULT '1',
  PRIMARY KEY (`channel`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

CREATE TABLE `data_table` (
  `_id` int(11) NOT NULL AUTO_INCREMENT,
  `channel` int(11) DEFAULT '0',
  `data` int(11) DEFAULT '0',
  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`_id`)
) ENGINE=InnoDB AUTO_INCREMENT=746 DEFAULT CHARSET=utf8;

 

데이터베이스 생성이 완료되면 Node.js용 패키지 폴더를 생성해 패키지 초기화를 실행합니다.

mkdir sensor_nodejs
cd sensor_nodejs
npm init

 

Node.js로 구현된 홈 오토메이션 예제를 다운 받으세요.

 

다운받은 파일들을 새로 생성한 패키지 폴더에 복사하고 다음의 모듈들을 설치해 줍니다.

npm install body-parser mysql mqtt express chart.js pug

 

다음의 모듈들은 홈 오토메이션 예제에서 사용되는 UI framework 인 부트스트랩-  CoreUI 를 사용하기 위해 설치하는 모듈들입니다.

이 모듈들은 CoreUI 모듈을 설치하기 전에 설치해야 정상설치가 됩니다.

npm install jquery perfect-scrollbar popper.js bootstrap chalk pace-progress

 

마지막으로 CoreUI 모듈을 설치합니다.

npm install @coreui/coreui @coreui/coreui-plugin-chartjs-custom-tooltips

 

package.json 파일을 열어 main 필드를 예제 파일의 app_sensor.js로 변경해 줍니다.

{
  "name": "sensor_nodejs",
  "version": "1.0.0",
  "description": "",
  "main": "app_sensor.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@coreui/coreui": "^2.0.4",
    "@coreui/coreui-plugin-chartjs-custom-tooltips": "^1.2.0",
    "@coreui/coreui-plugin-npm-postinstall": "^1.0.2",
    "body-parser": "^1.18.3",
    "bootstrap": "^4.1.3",
    "chalk": "^2.4.1",
    "chart.js": "^2.7.2",
    "express": "^4.16.3",
    "jquery": "^3.3.1",
    "mqtt": "^2.18.3",
    "mysql": "^2.16.0",
    "pace-progress": "^1.0.2",
    "perfect-scrollbar": "^1.4.0",
    "popper.js": "^1.14.4",
    "pug": "^2.0.3"
  }
}

 

다음 app_sensor.js 파일을 열어 데이터베이스 연결과 관련된 설정을 변경해 줍니다.

const sqlConn = sql.createConnection({
  host: 'localhost',
  user: 'root',
  password: '사용자 비밀번호',
  database: 'sensor_db',
})

앞서 database 이름을 sensor_db 로 했으니 여기서도 똑같이 맞춰줘야 합니다.

 

Node.js에서 데이터베이스에 접근할 수 있게 하기 위해 MariaDB root 계정에 권한을 부여해야 합니다.

쉘에 다음과 같이 입력하여 MariaDB 접근에 대한 root 권한을 얻어옵니다.

sudo mysqld_safe --skip-grant-tables

 

그 후 MariaDB를 실행합니다.

sudo mariadb -u root -p

 

MariaDB에서 다음과 같이 입력하여 root 계정에 모든 권한을 부여한다

use mysql;
GRANT ALL PRIVILEGES on *.* to 'root'@'localhost' IDENTIFIED BY '사용자비밀번호';
FLUSH PRIVILEGES;

 

이것으로 홈 오토메이션 서버 구동 준비가 끝났습니다.

아래 명령어로 서버를 실행하세요.

  • sudo node app_sensor.js

 

아래 주소로 접속해서 채널 선택 화면이 뜨는지 확인해보세요.

  • http://RPi_IP_Address:3010/login

 

 

 

 

 

[사물 인터넷 네트워크와 서비스 구축 강좌] #7-1 홈 오토메이션 서비스 기획

$
0
0

 

강좌 목차 보기

  • 현재 강좌 ==> [사물 인터넷 네트워크와 서비스 구축 강좌] #7-1 홈 오토메이션 서비스 기획

 

 

이번 장에서는 1~6 장에서 다룬 통신 방법과 제어코드를 활용해서 사물인터넷  서비스 하나를 만들어 보겠습니다. 이런 예제 서비스를 만들 때 가장 먼저 생각나는건 홈 오토메이션이죠. 여기서도 홈 오토메이션을 주제로 한 서비스를 구현해 볼 예정입니다.

 

 

홈 오토메이션 서비스 기획

 

Tech DIY 등을 하다보면 가장 흔하게 선택하는 주제가 생활 주변의 가전들, 그리고 실내에서 가지고 노는 장난감들 입니다. 그래서 이런 DIY  작품들을 업그레이드 하다보면 자연스레 홈 오토메이션과 연결되기 마련입니다.

예를 들어, 요즘 화두가 되곤하는 미세먼지에 착안해서 미세먼지 측정기를 만들고, 공기청정기가 미세먼지 센서에 연동해서 돌아갈 수 있도록 만들었다고 가정해보죠. 그럼 자연스럽게 공기청정기를 사물인터넷 서비스에 연결하고 싶어집니다. 미세먼지 센서의 값은 서버에 저장해서 언제 어디서든 핸드폰으로 확인할 수 있도록 만들고, 핸드폰에서 공기청정기의 동작을 제어하도록 만들고 싶어지겠죠.

하지만 이런 서버 구현이 어려운 사람들을 위해 범용 사물인터넷 서비스들이 생겨났습니다. 대표적인 것이 ThingSpeak 입니다.

ThingSpeak 서비스에 가입하면 채널(channel)을 생성할 수 있습니다. 이 채널이 데이터 저장소 역할을 합니다. 우리가 만든 미세먼지센서-공기청정기가 있다면, 미세먼지 센서의 값을 이 채널로 보내면 됩니다. 그러면 핸드폰이나 PC의 브라우저에서 생성한 채널의 URL 로 접속해서 누적된 값으로 그려진 그래프를 볼 수 있습니다. 또한 채널이 제공하는 API 를 호출해서 데이터를 가져와 원하는대로 가공해서 쓸 수도 있습니다.

즉, ThingSpeak 서비스는 Tech DIY 나 사물인터넷 데모 버전을 만들다보면 가장 흔히 겪는 목마름을 해소해주는 도구입니다. 그래서 이번 장에서 만들 홈 오토메이션 예제도 ThingSpeak 와 유사하게 동작하는 예제로 잡았습니다.

 

우선 예제 서비스가 동작할 대강의 구조를 잡아보겠습니다.

 

센서 장치가 수집하는 데이터는 서버로 전달되어 저장되고, 서버의 데이터는 다양한 사용자 장치에서 볼 수 있습니다. 반대로, 사용자 장치에서 명령어를 서버로 전송하면 서버는 다시 명령어를 센서 장치로 전송해 줍니다.

 

이제 ThinkSpeak 서비스를 참고해서, 좀 더 상세한 동작 시나리오를 그려 보겠습니다.

  • 웹 페이지를 통해 채널(channel) 생성
  • 채널이 생성되면 인증 코드를 발급
  • 각 채널은 1개의 센서 데이터를 저장
  • 각 채널에 센서 데이터 입력을 위해 외부에서 호출가능한 data input API 제공
  • 센서장치는 data input API 를 호출해서 데이터 입력 가능 (인증코드와 데이터를 함께 전송)
  • 서버는 각 채널로 입력되는 데이터를 DB에 저장
  • 각 채널의 데이터를 그래프로 표시해주는 웹 페이지 제공
  • 그래프 페이지에서 버튼을 눌러 명령어를 센서장치로 전송 가능
  • 외부 장치에서 각 채널 데이터를 검색 할 수 있는 query API 제공

 

동작 시니라오대로 작동하기 위해서는 홈 오토메이션 서비스가 아래와 같은 웹 화면들을 제공해야겠지요.

[채널 선택, 등록 화면]

 

[등록(생성) – 채널 이름 설정]

 

[채널 등록 후 인증 코드 발급]

 

 

[채널 선택 – 그래프 확인 화면]

 

자, 대강의 서버 구현 계획은 세워졌습니다. 그럼 실제 서비스가 동작하기 위해 필요한 기술적인 요소들을 선택하고, 상호 데이터를 주고 받을 때 사용할 데이터 형식을 정해 보겠습니다.

 

 

홈 오토메이션 예제의 상세 구현 계획

 

서버

예제 구현을 위해 가장 중요한 역할을 하는 것은 서버입니다. 서버는 센서장치에 data input API 를 제공해서 데이터를 수집 저장하고, 다양한 플랫폼을 사용하는 사용자에게 데이터를 보여줄 수 있는 방법을 제공해줘야 합니다.

우리는 사용자에게 웹 페이지 형식으로 데이터를 보여줄 겁니다. 웹 페이지 형식을 사용하면 사용자가 어떤 플랫폼을 쓰든 브라우저를 통해 서비스를 사용할 수 있는 장점이 있습니다. 대신 웹 서버를 구축해야겠죠.

또한, 서버는 모바일 앱이나 기타 다른 어플리케이션을 위해 웹이 아닌 API 형식으로 데이터를 추출할 수 있도록 해줄겁니다. 그래야 단순히 현재 데이터를 확인하는 것을 넘어 더 다양한 처리를 해서 사용자에게 보여줄 수 있으니까요.

이런 요구사항들을 감암하면 서버는 라즈베리파이에 node.js 를 이용해서 구현하는 것이 편리합니다. node.js 를 사용하면 웹 서버 구축 뿐 아니라 센서장치와 사용자 앱이 사용할 API 만들기도 쉽습니다. 널리 사용되는 서버 플랫폼이라 관련된 모듈, 자료 구하기도 쉽구요.

 

센서장치

센서장치가 서버로 데이터를 전달하기 위해 WiFi 모듈을 사용할겁니다. 우리가 만드는 센서장치는 대부분 사용자의 위치와는 무관하게 스스로 계속 데이터를 수집하면서 동작해야 합니다. 따라서 블루투스는 이런 환경에서 사용하기가 힘듭니다.

센서장치는 서버로 데이터를 보낼 때 HTTP POST 를 사용하도록 하겠습니다. 이때 HTTP body 안에 JSON 형식으로(application/json) 데이터를 담아 보내겠습니다.

{
  "channel": 채널넘버,
  "auth_code": "채널인증코드",
  "data": 숫자데이터
}

사용자가 웹 페이지를 통해 채널을 생성하면 채널 번호와 채널 인증코드가 발급됩니다. 이 값을 사용해서 센서가 업데이트 할 채널을 지정하고, 숫자로 된 데이터를 함께 담아 보내도록 만들겠습니다.

 

그런데 여기에 문제가 하나 있습니다. 사용자가 커맨드를 서버로 전송하면, 서버는 다시 센서장치에게 커맨드를 보내줘야 합니다. 센서장치가 이 커맨드를 받으려면 어떻게 해야할까요? 현재 센서장치에 들어온 커맨드가 있는지 HTTP request 를 빠르게 계속 서버로 보내서 체크해야 할까요? 이런 polling 방식은 굉장히 비효율적입니다. 언제 그리고 얼마나 자주 커맨드가 들어올지 모르는데 계속 서버에 HTTP request 를 보낸다면, 센서장치가 증가할수록 부하가 급증합니다. 따라서 서버 push 방식의 해결책이 필요합니다.

이 때 생각해 볼 수 있는 (그리고 우리가 다뤘던), push 가 가능한 통신 방법은 웹 소켓과 MQTT 입니다. 여기서는 많은 수의 센서장치를 효율적으로 관리하기 위해 MQTT를 사용하도록 하겠습니다. 센서장치는 MQTT 브로커에 접속하고, [채널넘버/status] 토픽을 구독(subscribe)해서 0(off) 또는 1(on) 제어신호를 받도록 하겠습니다.

 

모바일 폰

센서장치와 서버가 동작하면, 데이터는 서버에 차곡차곡 쌓일겁니다. 사용자는 웹 브라우저만 있으면 서버에 접속해서 데이터를 확인할 수 있고, 명령어를 보낼 수도 있습니다.

따라서 홈 오토메이션 서버의 주소만 북마크 해두고 사용하면 간단하게 사용자 UI 가 해결됩니다. 이걸 좀 더 세련되고 만들고 싶으면, 안드로이드나 iOS 전용 앱을 만들면 됩니다. 전용 앱은 WebView 를 사용해서 서버의 웹 페이지를 보여주기도 하고, 채널과 인증코드를 이용해서 서버 API 에서 데이터를 읽어와 그래프로 그려줄 수 있죠. 또한 명령어는 MQTT를 이용해 직접 보낼 수도 있습니다. 이걸 조합하면 폰이 특정 상태일 때 센서장치의 동작을 제어하도록 자동화 할 수도 있죠. (물론 서버에서 이 작업을 해도 되고, 그 편이 더 효율적이지만…)

단, 모바일 폰에서 MQTT 를 사용할 때는 주의할 점이 하나 있습니다. 모바일 폰은 특성상 사용자 입력 없이 오래 대기하면 power save 모드로 진입합니다. 그리고 이 때는 framework 에서 강제로 HTTP 통신을 끊는 등 background 로 동작하는 작업에 지장이 생기는 경우가 많습니다. MQTT 는 socket 통신을 사용하기 때문에 두 장치가 계속 연결되어 있는 상태를 가정합니다. 모바일 폰의 framework 에서 여기에 제한을 걸면 앱에서 백그라운드로 MQTT 작업을 할 수 없는 경우가 생깁니다.

 

 

이제 어떻게 홈 오토메이션 서비스를 구현할지 계획이 모두 세워졌습니다. 요약하자면 아래와 같은 구조로 되겠지요.

 

다음 파트부터 하나씩 차근차근 구현해 보겠습니다.

 

참고자료

 

 

주의!!! [사물 인터넷 네트워크와 서비스 구축 강좌] 시리즈 관련 문서들은 무단으로 내용의 일부 또는 전체를 게시하여서는 안됩니다. 계속 내용이 업데이트 되는 문서이며, 문서에 인용된 자료의 경우 원작자의 라이센스 문제가 있을 수 있습니다.

 

강좌 목차 보기

  • 현재 강좌 ==> [사물 인터넷 네트워크와 서비스 구축 강좌] #7-1 홈 오토메이션 서비스 기획

 

 

[사물 인터넷 네트워크와 서비스 구축 강좌] #7-2 홈 오토메이션 –센서장치 만들기

$
0
0

 

강좌 목차 보기

  • 현재 강좌 ==> [사물 인터넷 네트워크와 서비스 구축 강좌] #7-2 홈 오토메이션 – 센서장치 만들기

 

 

홈 오토메이션 서비스 기획대로 센서장치를 추가해 보겠습니다.

ESP32 모듈을 센서장치로 사용하고, 온도센서(DHT-11)를 달아서 측정값을 서버에 보내도록 하겠습니다. 서버에서 커맨드 (0- off, 1-on)를 받으면 측정값 전송을 멈추도록 만들겠습니다.

 

 

ESP32 를 이용한 센서장치 제작

 

우선 ESP32 보드에 온습도 센서 DHT-11 을 연결하고 동작을 확인해야 합니다. ESP32 보드에서 DHT-11 (또는 DHT-22) 온습도 센서 테스트 하는 방법은 아래에 자세한 설명이 있습니다.

 

연결은 아래와 같이 하면 됩니다.

만약 사용하는 온습도 센서가 interface board 위에 붙어있다면 3개의 핀만 아래와 같이 연결하면 됩니다.

  • ESP32 –> DHT11
  • 5V –> VCC (+)
  • GND –> GND
  • D16 –> Signal

 

DHT-11 센서를 ESP32 에서 사용하기 위해서는 라이브러리를 설치해줘야 합니다. 아래 두 라이브러리를 다운로드 받아 설치해주면 됩니다. (같은 이름의 라이브러리가 이미 존재하는 경우 기존 라이브러리를 백업 후 삭제하세요.)

 

스케치를 아래에서 다운로드 받아주세요.

 

소스코드에서 수정해줘야 할 부분이 많습니다. 상단의 전역 변수들을 바꿔줘야 합니다.

// Uncomment one of the lines below for whatever DHT sensor type you're using!
#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
//#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

// DHT Sensor
const int DHTPin = 16;

// Initialize DHT sensor.
DHT dht(DHTPin, DHTTYPE);

// Network settings
const char* ssid = "your_ssid";
const char* password =  "your_pass";

// Server info
#define SERVER_POST_URL "http://your_server:port_num/data"
#define SERVER_CHANNEL 3
#define SERVER_AUTHCODE "authcode"
#define HTTP_POST_INTERVAL 10000L

// MQTT info
const char* mqttServer = "your_server"; // do not use "http://"
const int mqttPort = 1883;
const char* mqttUser = "";
const char* mqttPassword = "";
const char* topic_sub = "3/status";   // 3 is channel number.

 

DHT-11 센서를 사용하기 위해 아래 #define 구문을 사용했습니다. 만약 정확도 향상을 위해 DHT-22 센서를 사용한다면 DHT22 define 구문을 활성화해주면 됩니다.

#define DHTTYPE DHT11

 

공유기 연결을 위해 ssid, password 값을 설정해주세요.

const char* ssid = "your_ssid";
const char* password =  "your_pass";

 

아직 서버 구축을 하진 않았지만, 서버에 HTTP request 를 보내기 위해 필요한 정보를 미리 설정해줍니다. 추후에 서버 설치를 마치고, 채널을 생성하고 나면 이 부분을 다시 수정해서 사용하면 됩니다. 인증 코드와 채널 넘버는 채널을 생성하면 서버에서 알려줍니다.

#define SERVER_POST_URL "http://your_server:port_num/data"
#define SERVER_CHANNEL 3
#define SERVER_AUTHCODE "authcode"

 

MQTT 관련된 설정을 변경해줍니다. MQTT 서버 주소와 포트, 토픽을 입력해주면 됩니다. 이것도 추후 채널을 생성하고 수정해주면 됩니다.

const char* mqttServer = "your_server"; // do not use "http://"
const int mqttPort = 1883;
const char* mqttUser = "";
const char* mqttPassword = "";
const char* topic_sub = "3/status";   // 3 is channel number.

 

이제 코드를 ESP32 에 업로드 해주세요. 일단은 공유기에 연결되어 동작하는 상태까지만 확인하면 됩니다. 서버 설정을 마치고 채널을 생성한 다음, 이 포스트로 돌아와서 채널 넘버/인증 코드를 넣고 업로드하면 정상 동작합니다.

 

 

코드 분석

 

이미 HTTP POST 전송 방법과 MQTT 사용 방법을 실습했었습니다.

 

따라서 여기서는 주요 코드만 살펴보겠습니다.

void connectMqtt() {
  ......
  mqttClient.subscribe(topic_sub);
  mqttClient.publish(topic_sub, "ESP32 logged in");
}

void setup() {
  ......
  mqttClient.setServer(mqttServer, mqttPort);
  mqttClient.setCallback(mqttCallback);

  connectMqtt();
}

 

setup() 초기화 함수가 실행되면서 WiFi 연결을 하고 MQTT 서버 설정과 연결을 합니다. 이때 [채널 넘버/status] 토픽을 구독하고, 메시지를 받으면 mqttCallBack 함수가 호출되도록 설정했습니다. mqttCallback() 함수는 아래와 같습니다.

void mqttCallback(char* topic, byte* payload, unsigned int length) {
  ......
  for (int i = 0; i < length; i++) {
    if(payload[i] == 0x30) {          // Char '0'
      sensorPower = false;
      ......
    }
    else if(payload[i] == 0x31) {     // Char '1'
      sensorPower = true;
      ......
    } else {
      Serial.print("0x");
      Serial.print(payload[i], HEX);
      Serial.print(", ");
    }
  }
  ......
}

 

[채널 넘버/status] 토픽을 구독한 이유는 여기로 들어오는 명령어를 받기 위함입니다. 여기로 ASCII 문자 0(0x30) 또는 1(0x31) 값이 들어옵니다. 해당 값에 따라 sensor 값 전송을 on/off 하도록 처리했습니다.

 

loop() 함수안에서 이루어지는 메인 작업을 살펴보겠습니다.

void loop() {
  if(WiFi.status() == WL_CONNECTED) {   //Check WiFi connection status
    mqttClient.loop();

    unsigned long currentTime = millis();
    
    if(sensorPower && currentTime > prevPostTime + HTTP_POST_INTERVAL) {
      // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
      float h = dht.readHumidity();
      // Read temperature as Celsius (the default)
      float t = dht.readTemperature();
      // Read temperature as Fahrenheit (isFahrenheit = true)
      float f = dht.readTemperature(true);
      
      // Check if any reads failed and exit early (to try again).
      if(isnan(h) || isnan(t) || isnan(f)) {
        Serial.println("Failed to read from DHT sensor!");
      } else {
        Serial.println("HTTP start --------------------------------");
        HTTPClient http;
     
        http.begin(SERVER_POST_URL);  //Specify destination for HTTP request
        http.addHeader("Content-Type", "application/json");             //Specify content-type header
  
        // Make JSON string
        std::stringstream ss;
        ss << "{\"channel\":" << SERVER_CHANNEL << ",\"auth_code\":\"" << SERVER_AUTHCODE << "\",\"data\":" << t << "}";
  
        // send HTTP POST request
        Serial.println(ss.str().c_str());
        int httpResponseCode = http.POST(ss.str().c_str());   //Send the actual POST request
  
        if(httpResponseCode > 0){
          String response = http.getString();                       //Get the response to the request
          Serial.println(httpResponseCode);   //Print return code
          Serial.println(response);           //Print request answer
        } else {
          Serial.print("Error on sending POST: ");
          Serial.println(httpResponseCode);
        }
        http.end();  //Free resources
        Serial.println("HTTP end --------------------------------");
      }
      prevPostTime = currentTime;
    }  // End of if(sensorPower)
 
  } else {
    Serial.println("Error in WiFi connection... Try to reconnect WiFi and MQTT.");   
    connectWiFi();
    connectMqtt();
  }
}

 

상단에 mqttClient.loop() 함수를 호출해주는 부분이 있습니다. 이 함수는 반드시 loop() 반복 함수 안에서 계속 호출해줘야 합니다. 그렇지 않으면 MQTT 로 들어오는 메시지를 받지 못하는 문제가 발생합니다.

loop() 함수는 HTTP_POST_INTERVAL 간격으로 센서값을 읽고 서버로 전송을 시도합니다. 이 때 전송할 JSON string 을 직접 만드는 루틴은 아래와 같습니다.

// Make JSON string
        std::stringstream ss;
        ss << "{\"channel\":" << SERVER_CHANNEL << ",\"auth_code\":\"" << SERVER_AUTHCODE << "\",\"data\":" << t << "}";
  
        // send HTTP POST request
        Serial.println(ss.str().c_str());
        int httpResponseCode = http.POST(ss.str().c_str());   //Send the actual POST request

 

직접 string을 만드는 방식을 사용했는데, JSON 라이브러리가 제공하는 방법을 사용해도 됩니다. 우리가 사용하는 JSON 데이터가 간단하기 때문에 그냥 string을 조합해서 만든겁니다. JSON string 에는 서버 채널 번호, 인증 코드, 온도 데이터 값이 들어있습니다.

그리고 HTTP POST request 를 서버로 보냅니다. 이 request 가 성공하면 서버에 데이터가 저장됩니다.

 

 

 

참고자료

 

 

주의!!! [사물 인터넷 네트워크와 서비스 구축 강좌] 시리즈 관련 문서들은 무단으로 내용의 일부 또는 전체를 게시하여서는 안됩니다. 계속 내용이 업데이트 되는 문서이며, 문서에 인용된 자료의 경우 원작자의 라이센스 문제가 있을 수 있습니다.

 

강좌 목차 보기

  • 현재 강좌 ==> [사물 인터넷 네트워크와 서비스 구축 강좌] #7-2 홈 오토메이션 – 센서장치 만들기

 

 

[사물 인터넷 네트워크와 서비스 구축 강좌] #7-3 홈 오토메이션 – Node.js 서버 만들기

$
0
0

 

강좌 목차 보기

  • 현재 강좌 ==> [사물 인터넷 네트워크와 서비스 구축 강좌] #7-3 홈 오토메이션 – Node.js 서버 만들기

 

 

홈 오토메이션 서비스 기획 중 라즈베리파이 서버를 구현할 차례입니다.

 

이미 이전 실습들을 진행했다면 라즈베리파이에 MQTT 브로커는 설치되어 있을겁니다. 설치되지 않았다면 아래 내용을 참고하세요.

 

MQTT 설치가 되었으면 Node.js 서버를 설정해주면 됩니다.

 

 

라즈베리파이 홈 서버 설치과정

 

우선, 서버에서 사용할 데이터베이스를 생성해야 합니다.

라즈베리파이에서는 MySQL 호환 DBMS 인 MariaDB를 사용합니다. apt-get 을 통해 MariaDB를 설치합니다.

  • sudo apt-get install mariadb-server mariadb-client

 

설치 도중 root 비밀번호를 설정하는 팝업이 뜨는 경우, 비밀번호를 설정해 줍니다.

팝업이 뜨지 않는 경우, 설치 완료 후 다음과 같이 입력하여 root 비밀번호를 설정해 줍니다.

  • sudo mysql_secure_installation

root 패스워드 반드시 지정해주고, 나머지 다 Y 로 대답하면 됩니다.

 

데이터베이스 생성을 위해 MariaDB를 실행합니다.

  • sudo mariadb -u root -p

 

비밀번호를 입력하면 MariaDB가 실행됩니다.

홈 오토메이션 서버에서 사용하는 데이터베이스를 생성합니다.

  • CREATE DATABASE sensor_db;

 

다음, 방금 생성한 데이터베이스에 연결해 채널 테이블과 데이터 테이블을 생성합니다.

connect sensor_db

CREATE TABLE `channel_table` (
  `channel` int(11) NOT NULL AUTO_INCREMENT,
  `channel_info` varchar(20) DEFAULT NULL,
  `auth_code` char(6) DEFAULT NULL,
  `status` char(1) DEFAULT '1',
  PRIMARY KEY (`channel`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

CREATE TABLE `data_table` (
  `_id` int(11) NOT NULL AUTO_INCREMENT,
  `channel` int(11) DEFAULT '0',
  `data` int(11) DEFAULT '0',
  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`_id`)
) ENGINE=InnoDB AUTO_INCREMENT=746 DEFAULT CHARSET=utf8;

 

데이터베이스 생성이 완료되면 Node.js용 패키지 폴더를 생성해 패키지 초기화를 실행합니다. 홈 오토메이션용 Node.js 프로젝트를 시작하는 것입니다.

  • mkdir sensor_nodejs
  • cd sensor_nodejs
  • npm init

 

Node.js로 구현된 홈 오토메이션 예제를 다운 받으세요.

 

다운받은 파일들을 새로 생성한 패키지 폴더에 복사하고 다음의 모듈들을 설치해 줍니다.

  • npm install body-parser mysql mqtt express chart.js pug

 

다음의 모듈들은 홈 오토메이션 예제에서 사용되는 UI framework 인 부트스트랩-  CoreUI 를 사용하기 위해 설치하는 모듈들입니다. 이 모듈들은 CoreUI 모듈을 설치하기 전에 설치해야 정상설치가 됩니다.

  • npm install jquery perfect-scrollbar popper.js bootstrap chalk pace-progress

 

마지막으로 CoreUI 모듈을 설치합니다.

  • npm install @coreui/coreui @coreui/coreui-plugin-chartjs-custom-tooltips

 

package.json 파일을 열어 main 필드를 예제 파일의 app_sensor.js로 변경해 줍니다.

{
  "name": "sensor_nodejs",
  "version": "1.0.0",
  "description": "",
  "main": "app_sensor.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@coreui/coreui": "^2.0.4",
    "@coreui/coreui-plugin-chartjs-custom-tooltips": "^1.2.0",
    "@coreui/coreui-plugin-npm-postinstall": "^1.0.2",
    "body-parser": "^1.18.3",
    "bootstrap": "^4.1.3",
    "chalk": "^2.4.1",
    "chart.js": "^2.7.2",
    "express": "^4.16.3",
    "jquery": "^3.3.1",
    "mqtt": "^2.18.3",
    "mysql": "^2.16.0",
    "pace-progress": "^1.0.2",
    "perfect-scrollbar": "^1.4.0",
    "popper.js": "^1.14.4",
    "pug": "^2.0.3"
  }
}

 

다음 app_sensor.js 파일을 열어 데이터베이스 연결과 관련된 설정을 변경해 줍니다.

const sqlConn = sql.createConnection({
  host: 'localhost',
  user: 'root',
  password: '사용자 비밀번호',
  database: 'sensor_db',
})

앞서 database 이름을 sensor_db 로 했으니 여기서도 똑같이 맞춰줘야 합니다.

 

그리고 서버의 도메인 이름(또는 IP addr)을 설정해줘야 합니다. config.json 파일을 열어서 수정해줍니다.

  • server_addr : 도메인 이름 대신 내부 IP (192.168.x.x)를 사용해도 되지만, 그럼 공유기 외부에서 접속할 수가 없습니다.
  • mqtt_addr : Node.js 가 MQTT 접속하기 위해 쓰는 주소기 때문에 굳이 도메인 이름을 쓸 필요가 없습니다. 내부 IP 를 사용하면 됩니다. 포트도 1883 포트 그대로 쓰면 됩니다.

{
  "server_addr":"http://user.server.com",
  "server_port":1000,
  "mqtt_addr":"mqtt://user.server.com",
  "mqtt_port":1883
}

공유기에 설정된 도메인 주소가 있다면 server_addr 항목에 도메인 주소를 넣어주세요. 그리고 server_port 포트는 원하는대로 수정해주세요. 대신 공유기에 포트 포워딩 설정을 해주셔야 공유기 외부에서 접속이 가능합니다. 이 예제에서는 server_port = 3010 포트로 수정했습니다. 그리고 공유기 포트포워딩 설정을 해줬습니다.

  • 공유기 접속시 : 3010 포트로 접속할 경우
  • 포워딩 : 192.168.x.x 아이피, 3010 포트로 전달되도록 설정

 

Node.js에서 데이터베이스에 접근할 수 있게 하기 위해 MariaDB root 계정에 권한을 부여해야 합니다.

쉘에 다음과 같이 입력하여 MariaDB 접근에 대한 root 권한을 얻어옵니다.

  • sudo mysqld_safe –skip-grant-tables

 

그 후 MariaDB를 실행합니다.

  • sudo mariadb -u root -p

 

MariaDB에서 다음과 같이 입력하여 root 계정에 모든 권한을 부여합니다.

use mysql;
GRANT ALL PRIVILEGES on *.* to 'root'@'localhost' IDENTIFIED BY '사용자비밀번호';
FLUSH PRIVILEGES;

 

이것으로 홈 오토메이션 서버 구동 준비가 끝났습니다.

아래 명령어로 서버를 실행하세요.

  • sudo node app_sensor.js

 

아래 주소로 접속해서 채널 선택 화면이 뜨는지 확인해보세요.

  • http://RPi_IP_Address:3010/login

 

 

화면이 뜨면 Node.js 서버 구동이 성공한 것입니다!

 

 

팁!!

Node.js 서버는 백그라운드로 계속 돌고있어야 합니다. 아래 방법을 사용하면 Terminal 접속과 상관없이 서버가 계속 돌아가도록 만들 수 있습니다.

  • npm install -g forever
  • sudo forever app_sensor.js &

멈출 때는…

  • sudo forever stop 0

 

단, 라즈베리파이가 재구동 되면 다시 실행해줘야 합니다.

 

 

 

주의!!! [사물 인터넷 네트워크와 서비스 구축 강좌] 시리즈 관련 문서들은 무단으로 내용의 일부 또는 전체를 게시하여서는 안됩니다. 계속 내용이 업데이트 되는 문서이며, 문서에 인용된 자료의 경우 원작자의 라이센스 문제가 있을 수 있습니다.

 

강좌 목차 보기

  • 현재 강좌 ==> [사물 인터넷 네트워크와 서비스 구축 강좌] #7-3 홈 오토메이션 – Node.js 서버 만들기

 

 

[사물 인터넷 네트워크와 서비스 구축 강좌] #7-4 홈 오토메이션 –모바일 앱 만들기

$
0
0

 

강좌 목차 보기

  • 현재 강좌 ==> [사물 인터넷 네트워크와 서비스 구축 강좌] #7-4 홈 오토메이션 – 모바일 앱 만들기

 

 

홈 오토메이션 서비스 기획 중 사용자 앱을 구현할 차례입니다.

 

 

모바일 앱 작성

 

우리가 만든 홈 오토메이션 서버는 웹을 통해 사용자 UI를 제공합니다. 따라서 브라우저를 사용하면 접속이 가능하기 때문에 모바일 앱을 굳이 사용할 필요는 없습니다. 대신 모바일 앱 작성시 주의해야 할 사항들만 언급하겠습니다.

 

웹 뷰(Web View)

우리가 만든 node.js 서버는 웹 서버로 동작하면서 사용자가 브라우저를 통해 볼 수 있는 웹 페이지들을 제공합니다.

따라서 모바일 앱을 작성할 때 Web View 를 이용하면 우리가 만든 서버로 접속해서 기능들을 사용할 수 있습니다. 이 경우 앱이 담당해야 할 많은 기능들을 웹 뷰가 대신해주므로 앱 구현이 간단해집니다.

그리고 서버와 interaction 이 필요한 부분이 있다면 javascript-interface 를 이용하면 됩니다. Javascript-interface 는 웹 페이지의 자바스크립트 코드가 안드로이드의 특정 함수를 호출할 수 있도록 해주는 기능입니다. 따라서 서버에서 보내 준 웹 페이지 자체와 안드로이드 앱이 서로 연동해서 동작하도록 만들 수 있습니다.

 

API 호출

우리가 설치한 서버에는 http://서버IP:3010/recent_data 로 POST 요청을 보내면 해당 채널에 저장된 데이터들을 원하는 개수만큼 추출할 수 있습니다. POST 요청을 보낼 때는 아래 JSON 데이터를 함께 보내면 됩니다.

{
   "channel":2,
   "auth_code":"ercwed",
   "num":2
}

이런식으로 보통 서버가 제공하는 API 를 사용하는 것이 가장 일반적인 모바일 앱 동작 방식입니다. 이미 서버에는 센서장치가 보내주는 데이터가 쌓여 있을겁니다. 따라서 이 데이터를 적당히 가공해서 모바일 앱이 사용할 수 있도록 API 를 제공해주면 홈 오토메이션 서비스가 더 세련되게 바뀔겁니다.

이런 HTTP call 을 관리하기 위해서는 Retrofit 같은 라이브러리를 사용하는 것이 좋습니다.

 

MQTT

모바일 앱에서 MQTT 기능을 구현하면 여러모로 좋은 점이 많습니다. MQTT 를 적극적으로 사용하면 센서장치에서 수집해서 보내주는 데이터를 모바일이 바로 받아서 처리할 수도 있고, 모바일 장치가 센서장치에 직접 메시지를 보낼 수도 있습니다. 또한 서버에서 모바일 앱으로 push 메시지를 보낼 수도 있습니다.

하지만 이런 여러 장점에도 모바일 앱에서 MQTT 를 사용하기 어려운 이유가 있습니다. MQTT 는 소켓 통신을 기반으로 하기 때문에 항상 서버에 소켓 통신으로 연결되어 있어야 합니다. 하지만 일반적인 모바일 앱은 배터리 관리, 프로세스 관리 등의 차원에서 framework 에서 백그라운드로 계속 동작하는 것을 막는 경우가 많습니다. 따라서 앱이 백그라운드로 동작하면 MQTT 동작을 100% 확신할 수가 없어집니다.

따라서 사용자가 앱이 사용하는 동안만, 일시적으로 MQTT를 연결해서 동작하도록 서비스를 만들어주는 것이 좋습니다. 안드로이드에서 MQTT를 사용하는 예제는 아래 소스를 참고하세요.

 

Bluetooth

이번 예제에서는 사용하지 않았지만, 만약 사용자가 특정 지역에 왔을 때 센서장치와 상호 작용하도록 만들고 싶은 경우가 있습니다. 이 때는 WiFi 보다는 블루투스가 더 유용하게 사용될 수 있습니다. 근래들어 Beacon, BLE 를 이용한 다양한 서비스가 등장했는데 이는 모두 모바일이 중심이 되어 센서장치와 상호 작용하고 그 결과를 서버와 공유하는 형태로 동작합니다. 대부분의 모바일 폰은 블루투스를 기본으로 탑재하고 있기 때문에 블루투스 기반 서비스, 기능을 구성하기 좋습니다.

안드로이드 폰의 경우 BLE를 사용하기 위해서는 v4.3 이상이 되어야 했지만, 근래의 폰들은 대부분 해당되며 3년 이상 오래된 폰들은 점유율이 미약하기 때문에 BLE 이용에 제약이 거의 없어진 상태입니다.

BLE 앱 예제 소스는 아래 링크를 참고하세요.

 

NFC

근거리 통신 방법인 NFC/RFID 도 앱에서 사용가능한 통신 방법 중 하나입니다. 단, NFC 를 일반 앱이 사용하기에는 제약사항이 많아서 부담스러운 면이 많습니다. 예를 들어 안드로이드 폰의 경우 NFC 를 탑재하지 않은 단말도 많기 때문에 무조건 NFC 기반으로 서비스를 기획하기 힘듭니다. iOS 의 경우 일반 앱이 NFC 사용이 어렵습니다.

대신 NFC를 사용할 수 있는 상황이라면, 결제 등의 시나리오를 구현할 수 있는 강력한 툴을 얻게 되는 것입니다.

 

 

 

참고자료

 

 

주의!!! [사물 인터넷 네트워크와 서비스 구축 강좌] 시리즈 관련 문서들은 무단으로 내용의 일부 또는 전체를 게시하여서는 안됩니다. 계속 내용이 업데이트 되는 문서이며, 문서에 인용된 자료의 경우 원작자의 라이센스 문제가 있을 수 있습니다.

 

강좌 목차 보기

  • 현재 강좌 ==> [사물 인터넷 네트워크와 서비스 구축 강좌] #7-4 홈 오토메이션 – 모바일 앱 만들기

 

 

[사물 인터넷 네트워크와 서비스 구축 강좌] #7-5 홈 오토메이션 –상호 연동 테스트

$
0
0

 

강좌 목차 보기

  • 현재 강좌 ==> [사물 인터넷 네트워크와 서비스 구축 강좌] #7-5 홈 오토메이션 – 상호 연동 테스트

 

 

홈 오토메이션 연동 테스트

 

홈 오토메이션 구현이 모두 끝났으니 동작을 시험해 봐야겠습니다.

먼저 메인 페이지로 접속해 보겠습니다. 라즈베리파이 서버 IP 에 3010 포트로 접속하면 됩니다.

  • http://IP_addr:3010/

 

메인 화면에서는 Login/Register 를 할 수 있습니다. Login 은 채널 보기, Register는 채널 등록입니다.

Register 버튼을 누르면 채널을 등록할 수 있습니다.

 

채널 이름을 설정하고 Register 버튼을 누르세요. 그럼 아래와 같은 팝업이 뜹니다.

 

채널 넘버와 채널 인증 코드가 뜹니다. 이 두 가지는 따로 적어두세요. 반드시 기억해야 합니다.

기존에 센서장치를 만들었죠? 센서장치도 여기서 생성한 채널 번호와 인증 코드를 사용해야만 데이터 등록이 됩니다. [7-2 센서장치 만들기]로 돌아가 채널 넘버/인증 코드를 바꿔서 업로드를 다시해 주세요.

 

그럼 센서장치가 수집한 데이터가 서버에 저장될 겁니다.

 

자 그럼 다시 메인화면으로 접속해서, 채널번호 – 인증코드를 넣고 Login 버튼을 누르세요. 그러면 아래와 같이 실시간 데이터 그래프를 그려주는 화면이 표시될 것입니다.

 

이 화면에서 Sensor On / Sensor Off 버튼을 누르면 해당 커맨드 (‘0’ 또는 ‘1’)가 센서장치로 MQTT를 이용해 전송됩니다. 그러면 센서장치가 데이터 업데이트를 on/off 합니다.

 

러프하지만 홈 오토메이션 서비스가 완성되었습니다!!

 

 

 

강좌를 마치며…

 

Tech DIY, 아두이노 관련한 홈페이지 하드카피월드를 운영하면서 많은 질문들을 받았는데, 그 중 상당수는 사물인터넷 구현, 통신 모듈의 사용법에 관한 것이었습니다. 제가 잘 모르는 부분이 많은 것도 사실이었고, 이런 전문적인 분야에 대한 대답은 댓글 한 두줄로 대체할 수도 없었습니다. 그리고 질문에 대한 솔루션은 제가 작업해도 하루 이틀에 되는게 아닌 경우가 많았습니다.

이 강좌를 만들게 된 계기도 그런 질문 글들 때문이었습니다. 일일이 질문을 올려주는 분들께 하나하나 대답하고 코드를 만들어서 드리는게 불가능하니, 사물인터넷 네트워크와 서비스 구현에 관한 전반적인 기술 매뉴얼을 작성하게 되었습니다. 그리고 기존에 자주 묻는 질문들을 참고해서 가급적이면 사물인터넷의 핵심인 통신 모듈을 다양한 방식으로 사용하는 예제를 첨부했습니다.

그리고 사물인터넷에 관한 개념적인 접근은 다양한 분야에서 많이 언급되지만, 실제 사물인터넷을 구현하기 위한 기술은 체계적으로 정리된 자료가 매우 부족함을 느꼈습니다. 대충 사물인터넷이 어떤거라는 것은 알겠는데, 이걸 구현하려면 뭐부터 시작해야 하나? 제가 작성한 이 긴 글들이 이런 질문에 대한 대답이 되었으면 좋겠습니다.

 

다시 얘기하지만 이 강좌는 꽤나 어렵습니다. 제대로 이해하기 위해서는 아두이노도 조금 다루고, 라즈베리파이도 기본적인 사용법은 알아야 합니다. 그리고 프로그래밍 언어도 하나 정도는 쓸 줄 알아야 합니다. 다양한 기술과 플랫폼이 언급되기 때문에 프로그래밍 언어나 플랫폼의 상세 내용은 다루지 못합니다. 불친절하게도 그건 독자의 몫으로 남겨두었습니다.

그럼에도 이 강좌는 가급적 많은 분들이 보셨으면 좋겠습니다. 개발자나 Tech DIY 를 즐기시는 분이라면 적은 인원, 심지어는 혼자서도 사물인터넷 서비스를 구축할 수 있도록 기본 예제와 설명을 수록해 뒀습니다. 처음부터 혼자 모든걸 공부하고 구축할 때 소모되는 시간과 노력을 상당히 줄여줄 것입니다. 절약된 시간과 노력은 서비스를 더욱 세련되게 다듬는데 투자하세요.

비록 개발자나 Tech DIY에 익숙치 않은 분이라도, 비록 코드를 다 이해하지 못하더라도, 예제들을 따라하면서 기술적인 개념들을 익히시면 많은 도움이 되실겁니다. 실제 사물인터넷은 정해진 몇 개의 방식으로만 구현되는 것이 아닙니다. 사용자에게 가장 편리하고, 서비스가 가장 효율적으로 동작할 수 있는 방법을 찾아 센서장치-서버-통신방법-UI 를 다양하게 변형시키면서 최적의 길을 찾아야 합니다. 이 강좌에서 다루는 기술들이 사물인터넷 서비스를 기획할 때 그리고 최적화 과정을 거칠 때 어떤 방법이 효율적인지, 어디까지가 기술적 한계인지를 정하는데 도움이 될 것입니다.

 

강좌 만드는데 꽤나 오랜 시간이 걸렸습니다. 이 글이 도움이 되셨다면, 세상 좁으니 언젠가 저와 마주치시면 따뜻한 인사와 커피 한 잔 대접해주세요.

 

 

 

 

주의!!! [사물 인터넷 네트워크와 서비스 구축 강좌] 시리즈 관련 문서들은 무단으로 내용의 일부 또는 전체를 게시하여서는 안됩니다. 계속 내용이 업데이트 되는 문서이며, 문서에 인용된 자료의 경우 원작자의 라이센스 문제가 있을 수 있습니다.

 

강좌 목차 보기

  • 현재 강좌 ==> [사물 인터넷 네트워크와 서비스 구축 강좌] #7-5 홈 오토메이션 – 상호 연동 테스트

 

 


아빠표 베이스타디움 –빛의 경기장

$
0
0

 

요즘 베이블레이드라는 팽이 놀이가 아이들 사이에서 인기인가 보더군요.

 

우리 아들 녀석도 어찌나 보채던지… 결국 하나 사주고, 뮤지컬도 다녀오고 그래도 성에 안차서 베이블레이드 경기장 – 베이스타디움도 하나 사왔더라구요.

그런데 베이스타디움이란 녀석이, 가격이 무색하게도 밋밋하고 볼품없는 플라스틱 쪼가리라…

 

그래도 아들 녀석은 좋다고 갖고 놉니다만, 제 성에 차질 않아서 살짝 개조를 해줬습니다. 이 참에 아들한테도 마느님한테도 점수 좀 따야죠.

 

 

기능 구현

 

일단 남는 아두이노는 널려 있고, 집에 갖고 놀던 부품들을 뒤져보니 RGB LED Strip 이 있네요.

화려한 맛을 더해주는데 이만한게 없죠.

아두이노에 아래처럼 APA102 를 연결해 줬습니다.

  • APA102 ==> 아두이노
  • 빨간색 선 ==> Vin
  • 검은색 선 ==> GND
  • 파란색 선 ==> D11  (데이터 선)
  • 녹색 선 ==> D12  (클럭 선)

 

아두이노용 APA102 라이브러리는 아래에서 받을 수 있습니다.

 

귀찮으시면 [스케치 – 라이브러리 포함하기 – 라이브러리 관리] 메뉴에서 apa102 검색하심 됩니다. APA102 항목에서 설치버튼 누르면 끝.

예제 폴더에 쓸만한 컬러 효과 내는 코드가 많네요. 그 중 두 가지를 골라서 사용했습니다.

 

RGB LED Strip 자체는 잘 동작합니다. 그런데 계속 같은 패턴으로 컬러만 변화하니까 재미가 없네요. 다행이 예전에 쓰고 남은 진동 센서가 있어서, 베이블레이드 팽이의 움직임을 감지해서 컬러 패턴과 밝기가 바뀔 수 있도록 만들어 줬습니다.

 

진동 센서는 아래처럼 연결해줍니다.

  • 진동센서 ==> 아두이노
  • + ==> 5V
  • OUT ==> D7
  • – ==> GND

 

연결이 완료된 모습입니다.

이제 소스코드 작성. 평소에는 Normal 모드로 은은한 무지개 빛 광채를 발산하다가 진동이 감지되면 BurstMode 로, 밝기도 상승하고 더 빠르고 화려하게 컬러가 변하도록 설정했습니다.

/* This example shows how to display a moving gradient pattern on
 * an APA102-based LED strip. */
#include <APA102.h>

//---------- Shock sensor
const int shockPin = 7;
unsigned long prevShockTime = 0L;
#define SHOCK_DELAY 1500L

//---------- RGB LED Strip
// Define which pins to use.
const uint8_t dataPin = 11;
const uint8_t clockPin = 12;

// Create an object for writing to the LED strip.
APA102<dataPin, clockPin> ledStrip;

// Set the number of LEDs to control.
const uint16_t ledCount = 60;

// Create a buffer for holding the colors (3 bytes per color).
rgb_color colors[ledCount];

// Set the brightness to use (the maximum is 31).
uint8_t brightness = 1;



void setup()
{
  // Sensor pin
  pinMode(shockPin, INPUT);
}



/* Converts a color from HSV to RGB.
 * h is hue, as a number between 0 and 360.
 * s is the saturation, as a number between 0 and 255.
 * v is the value, as a number between 0 and 255. */
rgb_color hsvToRgb(uint16_t h, uint8_t s, uint8_t v)
{
    uint8_t f = (h % 60) * 255 / 60;
    uint8_t p = (255 - s) * (uint16_t)v / 255;
    uint8_t q = (255 - f * (uint16_t)s / 255) * (uint16_t)v / 255;
    uint8_t t = (255 - (255 - f) * (uint16_t)s / 255) * (uint16_t)v / 255;
    uint8_t r = 0, g = 0, b = 0;
    switch((h / 60) % 6){
        case 0: r = v; g = t; b = p; break;
        case 1: r = q; g = v; b = p; break;
        case 2: r = p; g = v; b = t; break;
        case 3: r = p; g = q; b = v; break;
        case 4: r = t; g = p; b = v; break;
        case 5: r = v; g = p; b = q; break;
    }
    return rgb_color(r, g, b);
}

void normalMode() {
  brightness = 1;
  
  uint8_t time = millis() >> 4;

  for(uint16_t i = 0; i < ledCount; i++)
  {
    uint8_t p = time - i * 8;
    colors[i] = hsvToRgb((uint32_t)p * 359 / 256, 255, 255);
  }

  ledStrip.write(colors, ledCount, brightness);
}

void burstMode() {
  brightness = 10;
  
  uint8_t time = millis() >> 2;
  for(uint16_t i = 0; i < ledCount; i++)
  {
    uint8_t x = time - i * 8;
    colors[i] = rgb_color(x, 255 - x, x);
  }

  ledStrip.write(colors, ledCount, brightness);
}


void loop()
{
  unsigned long currentTime = millis();
  
  if(digitalRead(shockPin)) {
    prevShockTime = currentTime;
  }

  if(currentTime > prevShockTime + SHOCK_DELAY) {
    // End burst mode
    normalMode();
    delay(10);
  } else {
    // Maintain burst mode
    burstMode();
    delay(2);
  }
  
}

 

테스트는 성공적. 팽이가 경기장에 들어왔을 때 모드가 바뀔 수 있도록 진동 센서의 감도만 실험하면서 맞춰주면 됩니다.

 

 

조립

 

APA102 RGB LED String – 1m 짜리면 딱 맞게 베이스타디움을 두를 수 있더군요.

베이스타디움 측면 2군데에 구멍을 내서 RGB LED Strip 만 외부에 보일 수 있도록 설치했습니다.

 

아두이노와 진동센서를 적당한 곳에 위치시키고, 글루건 떡칠. USB 케이블을 연결할 수 있도록 구멍을 내줬습니다.

 

베이블레이드 팽이 진동에 반응 잘하도록 진동 세서의 감도만 조절해 주면 끝!!

아빠표 베이스타디움 – 빛의 경기장입니다.

 

 

플레이 영상은 여기

 

 

 

BLE Beacon 표준들의 데이터 구조

초음파 가습기 모듈 (WATER ATOMIZER, Humidifier, Mist maker)

$
0
0

 

가습기를 직접 제작하고 싶을 때 사용할 수 있는 모듈입니다. 예전에는 aliexpress 에서 검색이 잘 안됐는데 요즘은 검새고 쉽고 가격도 싸네요. 사용법도 굉장히 간단합니다.

aliexpress 에서 humidifier module 등의 단어로 검색하면 됩니다.

 

 

사용 방법

 

아래 제품의 경우 모듈의 동작 전압이 (제품에 따라 틀리지만) 2.4V ~ 5.2V 입니다.

빨간선, 검은선으로 전원만 공급해주면 됩니다.

동그란 진동판에 납땜이 된 쪽이 수증기가 나오는 앞면입니다. 반대편이 물에 닿도록 해주면 동작합니다. 수분을 머금은 휴지나 솜 등을 뒷면에 닿도록 설치해줘도 동작합니다.

진동판 앞쪽 수증기가 나오는 가운데 구멍에 물방울이 맺히면 수증기가 나오질 않으니 설치할 때 주의하세요.

 

간단히 동작만 테스트 해보고 싶다면 빨간선/검은선을 아두이노의 VIN(또는 RAW), GND 핀에 연결해주고, PCB 모서리에 있는 버튼을 눌러주면 됩니다.

아두이노를 이용해서 on/off 제어하고 싶다면 트랜지스터나 mosfet 모듈을 이용하시면 됩니다.

 

아두이노로 제어까지는 필요 없고, 소형 USB 가습기 형태로 만들고 싶다면 아래 제품을 이용하는 것이 훨씬 간편합니다.

 

버튼만 항상 눌러지도록 고정하고, USB 전원만 공급하면 됩니다. 크기도 소형이라 손쉽게 만들 수 있습니다.

 

휴대용 USB 가습기, 그까짓거 DIY

$
0
0

 

몇 년 전에 가습기 모듈을 찾아보니 파는 모듈이 있긴 한데, 가격도 꽤 나가고 품절이라 신경을 껐었죠. 근데 근래에 aliexpress 에서 이걸 검색해보니 가격도 싸고 DIY 하기 좋게 소형화 되어 나오더라구요. 요 모듈 하나면 가습기 직접 만드는건 일도 아니라 즉시 구매…

그리고 2주 정도 기다려서 받은 가습기 모듈(WATER ATOMIZER, Humidifier module) 입니다.

동그란 진동판 뒷쪽에 물이 닿도록 설치하고 오른쪽 아래 버튼을 누르면 안개가 분출됩니다. 잘 동작하네요.

제가 구매한 위 모듈은 2.4~5.2V 에서 동작한다고 적혀있네요. 분무량 꽤 됩니다. 시중에 파는 USB 탁상용 가습기, 그 정도라 보심 될듯. 아들이랑 일단 동작 테스트…

 

 

모듈에는 문제가 없으니 생수병을 이용한 탁상용 USB 가습기 DIY 시작…

 

 

탁상용 USB 가습기 만들기

 

생수병 하나 준비하구요.

플라스틱 마개를 열어 가습기 진동판 붙일 구멍 자리를 확인합니다.

마개 안쪽을 보면 날개처럼 원형으로 길게 솟아오른 부분이 있습니다. 가습기 모듈 진동판이 딱 저 정도 사이즈입니다. 그러니 저 원형보다 좀 더 작게 구멍을 파주면 되겠습니다.

칼질을 잘못해서 너무 크게 구멍을 냈네요;;; 다른 마개를 가져와서 다시 작업 했습니다.

플라스틱 마개에 양면 테입을 발라서 진동판을 고정하고, 글루건 떡칠해서 물이 새지 않도록 감쌌습니다. 모양은 별루지만 다행이 물이 새거나 하진 않습니다.

 

간단히 만들려면 이제 모듈에 전원만 공급되도록 하면 됩니다만… 전 온습도계나 초음파 센서 같은걸 달아서 자동화 하고 싶어서 아두이노에 연결을 해줬습니다. 테스트를 위해 가습기 모듈의 빨간색/검은색 선을 아두이노의 VIN(또는 RAW), GND 에 연결해주면 됩니다.

(USB 만 연결하면 동작하는 간단 버전을 만들려면 아두이노 쓰실 필요 없습니다. 글 마지막에 더 좋은 방법 소개하겠습니다.)

이제 USB 만 꽂으면 동작합니다만, 이 상태로는 너덜너덜하니 종이컵을 이용해서 수납/정리를 좀 해줬습니다. 손재주가 없는 관계로 글루건 떡칠 마무리…

 

이제 좀 그럴싸한 USB 가습기가 완성되었습니다!!

 

 

 

사용을 계속 해보니 진동판 안개가 분출되는 부분과 주변에서 조금씩 물방울이 새는 현상이 나옵니다. 생수병에 물을 많이 담으면 뒤에서 누르는 압이 세서 진동판 동작도 시원찮아지고 물도 미세하게 새는게 아닌가 싶습니다. 가습기 모듈 진동판 뒷면에 꼭 물이 아닌 물을 머금은 솜이나 휴지 등이 닿아도 동작을 하기 때문에, 생수통에 솜이나 휴지를 채워서 쓰는 것이 더 좋을듯 합니다.

그리고 물이 새지 않도록 플라스틱 마개에 진동판을 고정하기 위해 글루건 떡칠을 했는데… 동작은 합니다만… 좀 더 이쁘고 세련되게 만들 수 있는 방법이 있음 좋겠더군요;;;

 

혹시 직접 USB 가습기를 만들고 싶은 분은 제가 구매한 위 모듈말고 아래 모듈을 구매해서 써보세요. USB 케이블로 전원만 넣으면 동작하는 모듈입니다. Aliexpress 에서 [humidifier module] 로 검색하면 나올겁니다.

 

주말에 아들이랑 두어시간 하니까 USB 가습기 하나가 뚝딱 나오네요! 즐거운 DIY 생활 하세요!

 

 

Viewing all 99 articles
Browse latest View live