반응형

어렸을적 위대한 발명가, 과학자 하면 단연 손꼽는 일인자가 있었는데 누군가 물어본다면 100 이면 100 다 토마스 에디슨을 떠올릴 것입니다.. 그런데 커보니 에디슨은 발명가나 과학자라기보다는 사업가에 가까운 사람이었고 정반대 편에 니콜라 테슬라라는 진정 위대한 과학자가 존재함을 알게되었습니다.

테슬라의 위대한 발명품중에 단연 인지도 최강 아이템.

 

바로 테슬라 코일 되시겠습니다.

 

제가 과학도도 아니고 테슬라코일의 원리나 구조에 대해 이야기할건 아니고요. 알리익스프레스에서 2000원 정도의 저렴한 가격에 구입할 수 있는 킷이 있어 구입을 해 보았습니다.

 

개달 1700 원, 2개를 구입했고 배송비까지 5000원

 

일단 배송비가 있어 2세트를 주문 했는데 배송비까지 모두 해서 5000원 정도에 구입을 하였습니다. 

 

약 1달여가 지나 도착했고.... 아래와 같이 포장이 되어 있었습니다.

알리다운 포장상태네요

 

그냥 비닐백에 싸여 왔습니다. 물론 알리 특유의 회색 비닐백안에 들어있었습니다.

음.. 좀 조잡한데?

 

전체 부품들

 

부품은 별거 없습니다만.... 별도의 조립 설명서 같은건 없군요...

 

음... 조립 설명서가 없다라...

 

 

보드에 뭔가 적혀있는 것을 자세히 봤습니다.

메인보드

 

음.. 대략적으로 감은 오는데... 

네 어려울 건 없네요. 

 

그냥 생긴데로 끼우면 되는거였습니다.

딱히 잘못 조립할 수있는 유일한 부품은 LED 군요.

다행인건 보드에 표시가 되어 있고 LED 의 극성을 구분하는 것은 쉬운 일이니까요. LED 안쪽을 자세히 보면 핀과 연결된 부분이 보이는데 넓은 면이 - 입니다. 다리 길이로 보면 긴쪽이 + 가 되지요.

 

그레서 바로 조립해 보았습니다.

조립은 간단했다.

조립하는데에는 15분도 걸리지 않습니다. 제가 어렸을 적 라디오 키트 조립 같은게 유행했었는데 말이죠. 그 시절의 저였다면 초등학생이지만 가능한 간단한 조립입니다.

참고로 코일 원통에 선이 위로 한가닥 아래로 한가닥이 나오는데요. 보드에는 T 라고 써있는 부분에 한가닥만 연결하시면 됩니다.

다른 한가닥은 바로 스파크를 내뿜는 곳이죠.

 

그리고 코일통과 보드는 따로 고정해줄 수 있는 구조가 없기 때문에 실리콘이나 본드로 붙이셔야 합니다.

저는 E7000 본드로 고정을 해주었습니다.

 

 

어쨌든 2개를 샀으니 하나는 아들내미에게 기회를 한번 줘 볼까 합니다.

 

 

 

드디어 조립완료

 

12V 아답터를 연결하니 LED 가 똭!

 

굴러다니는 12V 아답터를 연결해주니 안쪽의 LED가 켜지면서 동작이 되네요. 가운데 보이는 스위치로 껏다 켰다 할수도 있습니다.

 

 

자 이제 테슬라코일임을 즐겨야겠지요?

 

동봉되어 있는 부품중에 할로겐 전구 같은 전구가 하나 있습니다.

그 전구가 바로 테스트용 전구인데요. 테슬라 코일을 동작시키로 가까이 가져가면 불이 켜지는것을 테스트 해보기 위한 재료입니다.

 

두구두구

드디어 사진이나 영상으로만 보던걸 제 손으로 해보는 군요.

 

두구두구두구.. 

 

불이켜진다.

 

쨔쨘~ ㅋㅋ

올~~

진짜 되는군요.

 

그럼 진짜배기 테스트를 해봐야 겠지요?

형광등을 하나 준비합니다. 굴러다니는 삼파장 등이면 됩니다.

 

두구두구

 

올. 형광등도 켜집니다.

 

올~~~~

 

ㅋㅋㅋ

정말 재미있네요.

 

내일은 아이들에게 신기한 장면을 좀 보여주어야 겠습니다.

상단에 코일 끝부분에서 스파크가 나오는데 ... 음.. 사진이 제대로 찍힌게 없어서 올리지는 못하겠네요.

나중에 제대로 나온 사진이 있으면 본 포스트에 추가하도록 하겠습니다.

 

 

오늘도 재미있는 놀거리를 하나 만들었습니다. 만들기도 쉽고 가격도 저렴하고요. 아이들과 니콜라 테슬라라는 과학자에 대한 이야기를 나누어 볼수도 있겠네요.

 

그럼 오늘의 포스팅을 마치겠습니다.

 

2020/06/17 - [DIY/Arduino] - [DIY] 아두이노로 통합(만능) 리모콘 만들기 3/3

 

[DIY] 아두이노로 통합(만능) 리모콘 만들기 3/3

아두이노로 통합(만능) 리모콘 만들기 3/3 이라 쓰고 왠지 이번 포스트에서 끝나지 않을 것 같은 느낌이 강하게 듭니다. 지난 포스트에서 아두이노 IR 센서를 이용하여 신호를 해킹하고 또 필요한

diy-dev-design.tistory.com

2020/04/03 - [DIY] - LEGO 블럭을 이용한 전자담배 기기 직접 제작하기

 

LEGO 블럭을 이용한 전자담배 기기 직접 제작하기

전자담배를 피는 입장에서 늘 불안한건 사용중인 전자담배를 어딘가에 놓고 오거나 고장나는 등의 이유로 대체할 기계가 없는 순간이 왔을 때 인것 같습니다. 전자담배는 연초 담배를 대신할 ��

diy-dev-design.tistory.com

2020/03/03 - [DIY] - [놀이감] BB탄 사격놀이 용 과녁판 만들기

 

[놀이감] BB탄 사격놀이 용 과녁판 만들기

요즘 신종 코로나 바이러스 때문에 재택근무를 하게 된 1 인 입니다. 뭐 모든 직장인들의 꿈만 같은 시간이지만 막상 준비되지 않은채 갑자기 주어지니 생활 패턴도 달라지고 혼란스러움도 있네

diy-dev-design.tistory.com

2020/01/20 - [DIY/PaperCraft] - JEEP WRANGLER RC BODY on HS18311

 

JEEP WRANGLER RC BODY on HS18311

대륙의 실수라고 제가 올린 중국산 RC 카 모델이 있습니다. HS18311 인데요. 썬더 스톰이라는 녀석이죠. 2019/12/23 - [DIY/RC] - [대륙의 실수] 가성비 RC 카 Storm Thunder, HS118311 [대륙의 실수] 가성비 RC..

diy-dev-design.tistory.com

 

반응형
반응형

이놈의 블루투스 스피커가 애물단지네요. 막상 소리가 좋아 어디 야외에 나갈때나 집에서도 컴퓨터 스피커보다는 훨씬 음악듣기 좋은 피스넷 하이엔드. 

또 고장이네요.

오늘은 충전기를 꼽으면 빨간 불이 빠르게 깜박깜박 거리며 정작 충전은 되지 않는 문제가 발생되었습니다.

충전은 되지 않고 빨간불만 1초에 두세번 간격으로 빠르게 깜박거리는 증상.

음..

버려야 하나.. 

싶다가 어짜피 버릴거면 뜯어나 보자 싶어서 뜯어 보았습니다.

 

뜯는 방법은 간단합니다.

전면부 그릴 망의 주변과 테두리 금속 마감재 사이로 얇은 분해공구를 이용해서 살살 재껴가면서 사방을 계속 재껴주면 전면부 그릴망이 후둑 하고 뽑힙니다.

첨엔 도대체 어떻게 분해를 하는지 알수 없어 골머리를 썩었더랬죠.

 

저는 그런 얇은 틈새 부분을 분해할 때 요런 공구(???) 를 사용합니다.

한때 이름도 유명했던 바바라 ㅋ

저게 뭐냐요고? ㅋ

바로 물감 섞을때 사용하는 나이프 입니다. 이래뵈도 미대 출신이니까요.

밥로스 선생님께서 반다이크 브라운으로 나뭇가지를 틱틱 찍어서 그려주던 바로 그 나이프랍니다. ㅋ

 

어쨌든

막상 해보면 어렵지 않습니다.

그릴망을 뜯어내면 보이는 구멍속에 나사가 있는데요. 얇은 드라이버를 이용해 모두 풀어 줍니다.

 

그러면 뒷판을 분해하실 수 있습니다.

 

뜯어도 제가 확인 할 수 있는 건 뭐 별게 없습니다. 선이 단락 되었거나 지난번 처럼 스위치 따위가 고장인지 확인하는 수준이지요.

추가로 한가지 더해보자면 배터리 쪽이 의심이 되더군요.

사용한지 오래되기도 하였고 가끔씩 켜놓은채로 하루종일 둔적도 있고 말이죠.

만약 배터리 문제라면 생각보다 쉽겠다 싶어서 전원먼저 체크해 보았습니다.

테두리 금속 마감재까지 벗겨낸 모습입니다. 배터리는 바깥으로 빼두었습니다.

상판에 정맣 별거 없네요.
전원 입력 단자 부분

상판 보드를 살짝 들어보니 저 위치로 배터리 전원이 입력이 되는 것 같습니다.

 

사진에 + - 표시해 놓은 곳의 전압을 테스터기로 체크해 보았다.

바로 테스터기를 가져와 전압을 체크해 보았습니다.

 

예스!!

 

전압이 0V 가 뜨네요.

배터리가 완전 방전이 되었었습니다.

ㅋㅋ

 

와이프한테 한바탕 잔소리를 시전한 뒤 (라고 쓰지만 안쓸때는 꺼주었으면 좋겠어 라고 했지만요)

 

수리 들어갑니다.

 

 

 

원인발견! 수리시작!

바로 배터리 문제였다는 것을 확인하였으니 이제 다음 순서는 간단합니다.

미련없이 배터리는 잘라버림

 

미련 없이 배터리를 잘라냅니다. 0V 이긴 하지만 혹시 모르니 한번에 한줄씩 잘라 줍니다.

그리고 스피커쪽 끝부분 피복을 살 짝 벗긴 후 RC 카 용으로 만들어 둔 7.4V 2S1P 배터리를 가져와서 테스트를 해보았습니다.

일단 편의상 밸런스 짹에 끼워서 테스트

 

일단 밸런스 짹에 끼워서 테스트를 해봅니다.

 

오 켜지네요.

 

그럼 바로 다음 작업 진행합니다.

3pin 암놈짹을 가져와 달아 주었습니다.

XT30 짹 (배터리 사진에서 노랗게 보이던 짹) 은 RC 카에 넣어야 하니 흔하디 흔한 2.54mm 3pin female 짹을 달아 주었습니다.

알리에서 구입하시면 100 개에 3천원 정도 합니다. 더 싼곳도 있을 거에요.

 

3pin 중에 양쪽 끝부분을 사용하면 바로 7.4를 사용할 수 있기 때문이죠.

다시하번 정식으로 배터리를 연결해서 테스트

이제 작업한 짹에 정식으로 연결하여 테스트를 진행합니다.

 

두근!

기쁨의 파란불이 들어왔다.

 

끼야홋!

 

네 성공입니다. ㅋㅋㅋㅋ

대박이네요.

 

이번에도 땡전 한푼 들이지 않고 또다시 부활한 피스넷 하이엔드!!! ㅋㅋㅋㅋ

이건 뭐 거의 좀비 수준이네요.

진동으로 인해 노잊가 생기지 않도록 꼭꼭 쑤셔넣자.

원래 있던 자리에 배터리를 다시 안착 시켜 줍니다.

원래 18650 배터리가 들어있던 자리여서 아주 꼭 잘맞습니다.

 

다시 차근차근 조립하여 복구해주면 끝

피스넷 하이엔드 스피커 고치기. 참쉽죠?

 

아... 보람되네요.

버려진 노트북 배터리랑 고장난 파워뱅크 주워와서 18650 꺼내 놓은게 참으로 유용하게 사용되었습니다.

심지어 이번에는 배터리 짹 작업도 해놓았으니 다음에 배터리가 또 방전되면 RC 배 배터리 여분으로 갈아끼우기만 하면 바로 수리가 되니 이것 참 편리한 상태가 되었습니다.

 

참고로 

제조사에서 몇시간 동안 신호도 없고 사용이 없으면 전원을 차단한다던가, 최소 전압이 얼마 미만이면 강제로 전원을 차단 하는 간단한 기능 정도는 넣어 주어도 되지 않을까 하는 생각도 해봅니다. 

소리가 좋아 유명해진 본연의 기능에 충실한 제품이라면 위와 같은 아주 기본이 되는 기능 정도는 넣어 주어도 좋지 않을까 싶은 생각에 아쉬움이 있네요.

이상으로 이번 포스팅을 마칩니다. 본문과 관련된 참고할 만한 포스트를 아래 링크해 놓습니다.

 

 

2019/11/05 - [DIY] - [repair] 고장난 블루투스 스피커 고치기 - 피스넷 하이엔드

 

[repair] 고장난 블루투스 스피커 고치기 - 피스넷 하이엔드

맑은 하늘과 푸르른 잔디밭, 공원에 누워 따사로운 햇살을 받으며 누워 있을때 필요한 건 모다? 바로 블루투스 스피커 되시겠습니다. 2017년도 쯤이었나요.. 보스 사운드링크 미니와 피스넷 하이�

diy-dev-design.tistory.com

버려진 폐 배터리에서 18650 적출하기, 그리고 재생하기는 아래 포스트를 참고하세요.

2020/03/03 - [DIY] - [재활용] 버려진 외장배터리에서 18650 적출하기, 부활시키기

 

[재활용] 버려진 외장배터리에서 18650 적출하기, 부활시키기

재활용 쓰래기장은 저와 같은 부류의 사람에게는 보물 창고 입니다. 오늘도 음식 쓰레기 버리러 가는 길에 폐 배터리 수거함을 슬쩍 보니 외장 배터리 2개가 버려져 있더군요. 게다가 하나는 샤�

diy-dev-design.tistory.com

18650 배터리를 이용하여 2S1P 밸런스 충전용 배터리 만드는 방법은 아래 포스트를 보시면 됩니다.

2019/12/27 - [DIY/RC] - Storm Thunder 용 2S1P 7.4v 18650 배터리 DIY

 

Storm Thunder 용 2S1P 7.4v 18650 배터리 DIY

RC 카를 가지고 놀다가 중간에 배터리가 떨어지면 정말 김이 팍 샙니다. 항상 잊지 말고 챙겨야 할게 바로 배터리인데요. 이 배터리가 항상 계륵 같은 존재 입니다. 내차에 맞는 배터리를 구입하�

diy-dev-design.tistory.com

2020/07/01 - [DIY] - 미니 테슬라코일 만들기 - 알리 DIY KIT

 

미니 테슬라코일 만들기 - 알리 DIY KIT

어렸을적 위대한 발명가, 과학자 하면 단연 손꼽는 일인자가 있었는데 누군가 물어본다면 100 이면 100 다 토마스 에디슨을 떠올릴 것입니다.. 그런데 커보니 에디슨은 발명가나 과학자라기보다��

diy-dev-design.tistory.com

2022.04.08 - [DIY] - [수리기] ssaper 무드등 블루투스 스피커 수리하기

 

[수리기] ssaper 무드등 블루투스 스피커 수리하기

고장난 블루투스 스피커 고쳐드립니다~ 라고 광고를 한것도 아닌데.. 지인이 스피커가 고장났다며 대뜸 고쳐줄 수 있냐고 물건을 보내왔습니다. 유명한 브랜드인지는 모르겠는데 ssaper 라는 브

diy-dev-design.tistory.com

 

어쨌든 버려진 것들을 재활용 했다는 점, 고장난 제품을 직접 고쳐 다시 사용하게 되었다는 것에 큰 만족을 느끼며 이번 포스트를 마칩니다.

 

2020/05/17 - [DIY] - [재활용] 고장난 LED 바 수리하기 > 화장대 조명 만들기

2020/03/10 - [DIY] - [수리기] 닌텐도 Wii 리모컨 고장 수리. #간단 #초보 가능

 

반응형
반응형

카테고리를 c# 으로 해야 할지 Arduino 로 해야할지 조금 고민이 되는 포스트  입니다.

음....

arduino 로 하는게 좋겠네요. 따지고 보면 C# 으로 만든 어플이 중요한게 아니라 아두에노에서 시리얼 통신으로 메시지를 받는게 중요한거니까요.

일단 한번 해보겠습니다. 자 시작하죠.

 

우선 이번 포스트에서 다룰 주제는 아래와 같습니다.

  • C# 에서 시리얼 통신 사용하기
  • 시리얼 통신으로 문자열 송신하기
  • 아두이노에서 문자열 수신하기
  • LCD 에 수신된 문자열 표시하기

간단하죠?

내용도 간단하니까 걱정 붙들어 매시고 따라오시면 됩니다.

 

 

C#에서 시리얼 통신 사용하기

먼저 비주얼 스튜디오를 열고 c# .net 플랫폼을 선택하신 후 window form 프로젝트를 하나 만들어 줍니다.

window forms 앱 을 선택합니다.
적당히 이름을 만들어 주세요. 닷넷 버전은 그냥 건드리지 않았습니다.

 

이렇게 하시고 만들기를 누르시면 윈도우 창이 나올텐데요.

간단하게 label, combobox, button 을 하나씩 만들어주고 사이즈를 적당히 조절합니다.

간단한 메뉴 구성 완료

 

이제 폼이 실행되면 combobox 에 연결 가능한 시리얼 포트를 띄워 주겠습니다. 그리고 버튼을 누르면 해당 포트로 메시지를 전달하도록 할 예정입니다.

만들어진 UI 상단에 Form1 이라고 써있는 타이틀바를 더블클릭해 줍니다.

그럼 아래와 같이 Load 이벤트와 함께 함수가 하나 만들어 집니다.

이제 이번 포스트에 필요한 지시문과 콤보박스에 시리얼을 연결하는 방법을 소개해 드리겠습니다.

먼저 맨윗줄 지시문이 있는 그룹에 아래와 같이 추가해 줍니다.

using System.IO.Ports;

 

그런 다음 이번 예제에서 사용할 시리얼 포트를 만들어 주고요 

public partial class Form1 : Form
{
  private SerialPort mySerial; //<-- 요 부분이죠

  public Form1()
  {
  	InitializeComponent();
  }

 

아까 만들어 진 Form1_Load 함수에 아래와 같이 시리얼포트를 생성해주고 콤보박스에는 데이터를 담습니다.

private void Form1_Load(object sender, EventArgs e)
{
  mySerial = new SerialPort();
  comboBox1.DataSource = SerialPort.GetPortNames();

}

 

이제는 콤보박스의 선택정보가 변경될 때 시리얼 포트가 열려있지 않다면 포트이름과 설정을 지정해 주고 열도록 하겠습니다. 

UI 메뉴에서 콤보 박스를 더블클릭하면 함수가 자동으로 생성되는데요. 만들어진 함수에 아래와 같이 코드를 작성하시면 됩니다.

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
  if (mySerial.IsOpen) // 특정 포트가 이미 열려 있다면 설정이 되지 않기 때문에 우선 닫는다.
  {
  	mySerial.Close();
  }
  if (!mySerial.IsOpen)  //시리얼포트가 닫혀있을 때만
  {
    mySerial.PortName = comboBox1.Text;  // 선택된 combobox 의 이름으로 포트명을 지정하자
    mySerial.BaudRate = 9600;  //아두이노에서 사용할 전송률를 지정하자
    mySerial.DataBits = 8;
    mySerial.StopBits = StopBits.One;
    mySerial.Parity = Parity.None;

    mySerial.Open();  //시리얼포트 열기
  }
  else
  {
    MessageBox.Show("해당포트가 이미 열려 있습니다.");
  }
}

 

 

 

 

시리얼 통신으로 문자열 송신하기

뭐 거의 다 되었습니다. 이제 버튼을 누르면 아두이노로 메시지를 전달하기만 하면 됩니다.

문자열을 전송하기 위한 byte 배열로 바꾸어주는 함수를 하나 만들어 보겠습니다.

private byte[] StringToByte(string _str)
{
  byte[] tmpBytes = Encoding.UTF8.GetBytes(_str);
  return tmpBytes;
}

요렇게 만들어 주었다면 이제 UI 생성하는 페이지에서 만들어 두었던 버튼을 두번 클릭하여 버튼을 눌렀을때 실행할 함수를 하나 만들어 줍시다.

그런다음 아래와 같이 메시지를 보내보겠습니다.

private void button1_Click(object sender, EventArgs e)
{
  byte[] datas = StringToByte("Hello Arduino?\n"); // 줄바꿈 기호인 \n 은 끝에 꼭 들어가야 합니다.
  mySerial.Write(datas, 0, datas.Length);
}

 

자 C# 어플리케이션은 완성이 되었습니다. 

 

벌써요?

네 벌써 완료 되었습니다. 정상적으로 동작한다면 아두이노 LCD 에 Hello Arduino? 가 뜰 것입니다.

제 포스트를 보시면서 천천히 하셔도 아마 15분이면 충분할만한 분량이지요. 

 

전체 코드도 올립니다.

더보기

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;

namespace csharp2arduino_serial
{
    public partial class Form1 : Form
    {
        private SerialPort mySerial;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            mySerial = new SerialPort();
            comboBox1.DataSource = SerialPort.GetPortNames();

        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
        	if (mySerial.IsOpen)
            {
                mySerial.Close();
            }
            if (!mySerial.IsOpen)  //시리얼포트가 닫혀있을 때만
            {
                mySerial.PortName = comboBox1.Text;  // 선택된 combobox 의 이름으로 포트명을 지정하자
                mySerial.BaudRate = 9600;  //아두이노에서 사용할 전송률를 지정하자
                mySerial.DataBits = 8;
                mySerial.StopBits = StopBits.One;
                mySerial.Parity = Parity.None;

                mySerial.Open();  //시리얼포트 열기
            }
            else
            {
                MessageBox.Show("해당포트가 이미 열려 있습니다.");
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // 텍스트 박스 추가한 버전
            string myMsg = textBox1.Text;
            if (myMsg != "")
            {
                myMsg += "\n";
            }
            else
            {
                myMsg = "Hello Arduino?\n";
            }
            byte[] datas = StringToByte(myMsg);
            mySerial.Write(datas, 0, datas.Length);
        }

        private byte[] StringToByte(string _str)
        {
            byte[] tmpBytes = Encoding.UTF8.GetBytes(_str);
            return tmpBytes;
        }
    }
}

 

 

 

아두이노에서 시리얼 메시지 받기

아두이노에서 시리얼 메시지를 받는것은 사실 매우 쉽습니다. 아두이노 기본 예제 중에 Serial 을 사용하는 것을 많이 보셨죠? 아두이노는 Serial 을 사용하기 위하여 별도로 설정할것이 거의 없습니다.

아두이노를 열어 주시고 아래와 같이 코드를 작성합니다.

String myStr = "";

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {

  if(Serial.available()){//시리얼에 데이터가 있다면

    char data = (char)Serial.read();//한 문자씩 읽어 문자형 변수에 담고
    
    if((int)data != 10){ //개행문자 '\n' -> newline 이 아니라면 스트링에 계속 저장
      myStr += data;
      
    }else{
      // \n 을 만나면 여기로 와서 문자열을 출력하면 된다.

      // LCD 에 문자를 여기서 출력하면 됨

      //그리고 문자열은 다시 초기화를 해주겠습니다.
      myStr = "";
    }
  }
}

 

완전 간단하죠? 시리얼 신호가 들어오면 \n 이라는 줄바꿈 문자열이 오기 전까지 계속해서 한글자씩 문자열 변수에 추가를 해주었다가 \n 을 만나면 필요한 결과를 수행하고 원래 문자열 변수를 초기화 하는 것이죠.

 

 

물론 아직 LCD 를 붙이지 않았으므로 시리얼을 받아도 뭔가 표시는 안되겠지요?

그래서 이제 LCD 를 붙여 보겠습니다.

 

 

 

 

아두이노 OLED LCD 에 시리얼 통신 결과 출력하기

 

지난 LCD 예제를 참고하시면 되며 이번에는 바로 시리얼을 출력해 보겠습니다.

2020/05/26 - [DIY/Arduino] - 0.96 inch OLED 디스플레이 구동하기

 

0.96 inch OLED 디스플레이 구동하기

가끔 아두이노로 무엇인가를 만들어 보려고 하다보면 디스플레이가 있으면 하는 생각이 들때가 있습니다. 아두이노는 작은 컴퓨터이기는 하지만 모름지기 컴퓨터라 한다면 입력장치 - 중앙처��

diy-dev-design.tistory.com

 

상단에 필요한 요소들을 추가해주고 기본적인 셋팅을 해준뒤 제 포스트의 주제인 DIY DEV DESIGN 을 출력하고 시작하겠습니다. ㅋ

(작성자의) 편의상 그냥 전체 코드블럭을 올립니다. 라이브러리나 LCD 구동 관련된사항은 위 포스트에서 확인하시면 됩니다.

#include <Wire.h> 
#include <Adafruit_SSD1306.h>
#include <splash.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#include <Fonts/FreeMono9pt7b.h>


#define OLED_ADDR   0x3C

// reset pin not used on 4-pin OLED module
Adafruit_SSD1306 display(-1);  // -1 = no reset pin

//#if (SSD1306_LCDHEIGHT != 64)
//#error("Height incorrect, please fix Adafruit_SSD1306.h!");
//#endif

String myStr = "";
int linegap = 2;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
  display.setFont();
  display.clearDisplay();
  display.display();
  display.setTextSize(1);

  draw_text(2, 25, "DIY DEV DESIGN", false); // 폰트 표시를 쉽게 하기 위해 제가 만든 함수 입니다.
  draw_text(3, 4, "C# -> Arduino Serial", false);

  display.display();
  delay(3000);
  
}

void loop() {

  if(Serial.available()){//시리얼에 데이터가 있다면

    char data = (char)Serial.read();//한 문자씩 읽어 문자형 변수에 담고
    
    if((int)data != 10){ //개행문자 '\n' -> newline 이 아니라면 스트링에 계속 저장
      myStr += data;
      
    }else{
      // \n 을 만나면 여기로 와서 문자열을 출력하면 된다.

      // LCD 에 문자를 여기서 출력하면 됨
      display.clearDisplay();
      draw_text(2, 10, myStr, false);
      display.display();
      //그리고 문자열은 다시 초기화를 해주겠습니다.
      myStr = "";
    }
  }
}

void draw_text (int line, int xPos, String txt, bool isSelected)
{
   int cHeight = (line-1) * 8 + ((line-1) * linegap);
   if(isSelected)
   {
      display.fillRect(xPos - 2, cHeight, 127, 8, WHITE);
      display.setTextColor(BLACK);
   }else{
      display.setTextColor(WHITE);
   }
   display.setCursor(xPos, cHeight);
   display.print(txt);
}

 

음 뭐 간단하다면 간단한 내용이죠?

 

자 아두이노를 컴파일하고 올려야 하는데요. 아까 c#에서 만들어놓은 APP 을 실행해 놓으면 소스가 업로드 되지 않습니다. App 을 열어두었다면 끄고 업로드를 해야 합니다.

 

 

 

 

결과 확인하기

이제 결과를 확인해 보겠습니다.

먼저 아두이노를 업로드 해보면 아래와 같은 화면이 나오게 됩니다.

ㅎㅎ 저렇게 작은 글씨가 보이는게 귀엽네요. 

 

만들어 두었던 시리얼 통신용 어플을 실행해 볼까요?

간단한 화면

이제 버튼을 눌러보면 아래와 같이 아두이노와 연결된 OLED LCD 에 전송한 글자가 표시됩니다.

성공!

 

전송한 메시지가 잘 표시가 되네요.

우하하하핫

이때가 기분이 제일 좋은 순간이지요. 

 

 

끝으로..

C# 으로 개발하기 귀찮은 분들을 위해 테스트용 앱을 만들어 보았습니다.

요렇게 하단에 메시지 박스를 이용해서 원하는 메시지를 보낼 수 있는 툴입니다.

아두이노 LCD 에는 이렇게 받아지죠.

시리얼 통신으로 받은 메시지들

 

시리얼 메시지 테스터는 아래 파일을 다운로드 받으셔서 압축을 해제하신 후 실행하시면 됩니다.

csharp2arduino_serial.7z
0.00MB

 

바이러스 따위는 없으니 안심하셔도 됩니다. 

 

이렇게 해서 간단하게 아두이노로 PC 에서 메시지를 보내는 방법을 설명해 드렸습니다.

만약 다른 정보일지라도 문자열로 바꾸어서 보내준뒤 아두이노 코드에서 해석해서 받으면 어떤 정보든 전달하는 것이 가능하겠죠? 어렵지 않으리라 생각됩니다.

 

C# 레퍼런스는 정말 어마어마 하게 많기 때문에 우리가 생각하는 거의 모든 것들을 만들어 내는 것이 가능할 것입니다. 

아두이노같은 작은 컴퓨터에서 우리가 PC 로 하는 많은 것들을 알려주고 동작하게 하는 것. 아두이노 만큼 손쉽게 실제 동작하는 기구를 만들 수 있는 도구가 또 어디 있겠습니까? 

시작이 어렵지 잘만들어진 레퍼런스 하나면 바로 첫 삽을 뜰 수 있답니다.

일단 통신만 뚫었다면 그 다음은 일사 천리아니겠습니까? 

 

예를 들면 제가 아두이노를 이용해서 TV 리모컨 신호를 해킹한 적이 있는데요. 적외선 기능이 없는 노트북에서 TV 를 켜고 채널을 바꾸는것도 간단한 프로젝트로 해볼만할 것 같습니다. 

 

 

그럼 이만~

뎃글, 공감 은 블로그 작성자에게 큰 힘이 된답니다. 
도움이 되었다 생각되시면  클릭!!  부탁드려요~

 

 

2020/06/17 - [DIY/Arduino] - [DIY] 아두이노로 통합(만능) 리모콘 만들기 3/3

2020/05/26 - [DIY/Arduino] - 0.96 inch OLED 디스플레이 구동하기

2020/03/23 - [DIY/Arduino] - Arduino(아두이노) 무작정 시작하기

2019/06/27 - [DIY/Arduino] - 아두이노를 이용한 간단한 화분 자동 물주기 시스템

 

반응형
반응형

안녕하세요 주인장입니다.

코로나로 인한 개학연기로 아이들이 집안에서만 딩굴딩굴 거려 답답하신가요?

아이들에게 신나는 연산 문제를 내 주는건 어떨까요?

 

??

 

는 아니고 VBA 로 제가 그동안 덧셈, 뺄셈을 자동으로 만드는 방법을 소개해 드렸었는데요, 이번에는 두자릿수 곱셈문제를 추가해 보았습니다. 

아이들의 계산 공간을 위하여 기존의 가로 문제가 아닌 세로 연산 레이아웃이 필요했고요.

문제수를 조금 줄여 보았습니다.

문제는 난이도를 조금 조정할 수 있는 데 계산에 사용되는 최대 숫자의 크기 제한을 서서히 높이는 방식으로 구성하였으므로 엑셀 VBA 를 조금 이해하시는 분이라면 직접 수정하여 사용하시는 것도 가능합니다.

 

그냥 간단히 설명 드리자면 문제의 난이도를 수정하려면 아래의 순서로 하시면 됩니다.

버튼 --> 마우스 우클릭 --> 매크로 지정 --> 매크로창에서 선택되어 있는 매크로 편집 --> 최대값 변경

 

선우수학숙제..xls
0.08MB

 

 

그리고...

 

채첨해보시면서 일일이 계산하는 것도 번거로운 일인듯 하여 정답보기 버튼을 추가로 넣었습니다.

문제를 출제 --> 프린트 --> 정답보기 --> 채점 또는 프린트 하여 채점 하는 식으로 사용하시면 됩니다.

다시 문제를 내버리면 이전에 만들어진 문제는 사라지므로 그렇게 된 경우엔 채첨하실때 직접 계산을 하시는 수 밖에 없답니다.

 

아들내미가 이걸로 며칠 하더니 연산 실력이 부쩍 올랐습니다. 늘 하던 실수도 많이 줄더군요.

그리고는 하는말이 우리 선생님한테 이런게 들어가지 않았으면 좋겠다고 하더라고요. ㅋㅋ. 매일 쪽지시험보면 어쩌냐고요.. 

 

 

선생님들. 어머님들 너무 심하게 시키지는 말아주세요~

 

본 포스트에 첨부된 엑셀 파일로 덧셈, 곱셈, 뺄셈을 모두 출재하실 수 있으니 기존의 포스트는 참고만 하시면 될 것 같습니다. 

 

그럼 더운 여름 코로나로 답답한 아이들에게 시원한 연산문제를 선물해줘보세요~

2019/09/10 - [DEV/VBA] - [VBA] 엑셀로 초등학교 저학년 문제집 만들기 (자동버전)

 

[VBA] 엑셀로 초등학교 저학년 문제집 만들기 (자동버전)

이번 포스트를 통해 꼬마아이들의 공공의적 이 될런지도 모릅니다. 바로 초등 저학년 연산문제를 끝도 없이 만들수 있는 파일을 준비했기 때문입니다. 지난번 포스트에서 연산문제를 만드는 VBA

diy-dev-design.tistory.com

 

2020/04/17 - [DEV/VBA] - [vba] 초등학교 연산 문제 자동 출제, 이번엔 뺄셈에 도전

 

[vba] 초등학교 연산 문제 자동 출제, 이번엔 뺄셈에 도전

VBA를 이용하여 초등학교 연산 문제를 내는 것을 만들어 올린적이 있었습니다. 개학이 늦어지면서 집안에서 아이들 공부시키랴 밥해먹이랴 엄마들이 고생이 많을텐데요. 그사이 아이들의 학습 �

diy-dev-design.tistory.com

 

스크립트의 원리가 궁금하시다면 아래 포스트를 참고해주세요.

2019/09/03 - [DEV/VBA] - [VBA] 초등학교 저학년 수학 연산 문제 자동으로 만들기

 

[VBA] 초등학교 저학년 수학 연산 문제 자동으로 만들기

안녕하세요. 이번 강좌에서는 VBA 를 이용하여 초등학교 저학년 아이를 위한 연산문제를 자동으로 내주는 스크립트를 작성해 보겠습니다. VBA 를 좀 해봤다 하면서 막상 일상 생활에 사용하려면 �

diy-dev-design.tistory.com

 

이참에 본격적으로 VBA 도 한번 배워 보고 싶으시다면? 

2019/06/01 - [DEV/VBA] - 엑셀 VBA 시작하기

 

엑셀 VBA 시작하기

마이크로 소프트 엑셀은 수많은 기능과 자동화된 연산 처리, 편리한 템플릿 가공, 다양한 그래프 드을 이용한 데이터의 시각화 외에도 아주 많은 유용한 기능을 제공하여 사무 업무의 표준 프로

diy-dev-design.tistory.com

 

반응형
반응형

나의 어릴쩍 기억부터 줄곧 내 머릿속에 자리매김하고 있는 특이한 차를 손꼽을때 빼 놓을수 없는 차중의 하나가 바로 현대 자동차의 소나타가 아닐까 생각됩니다 

처음 소나타가 출시되었을때만 해도 정말 충격적인 모습이었습니다. 세련된 해드램프와 바디라인, 그런데 소나타 2를 지나 소나타 3가 도래했을때 즈음 정말 그동안 내가 받은 충격은 충격이라 말할 후 없을 정도의 변화를 보여주었었던 기억이 납니다. 

남성의 ...

음..

여기까지...

 

 

 

시간이 많이 지났지만 여전히 우리 시대에 중형차이며 국민차량같은 느낌의 차종인 소나타는 많은 사람들의사랑을 한몸에 받고 있는 듯 합니다.

언제나 부동의 1위의 판매량을 자랑하는 차종이었었죠. SUV의 시대가 오기 전 가지는 말이지요...

 

어쨌든 소나타는 현대차에서도 항상 실험적인 디자인을 적극적으로 도입하는 차량이었으며 이번 신형 소나타 역시 정말 과감한 디자인을 여러곳에 보여주었습니다.

사실 전 어려서부터 자동차 디자인에 관심이 많았었기에 새로운 차량이 생산될때마다 여러가지 것들을 매니아로써 봐왔던것 같습니다.

 

 

결론적으로 이야기 하자면

늘 소나타는 새로운 디자인의 방향을 이야기 하는데 성공했지만 결과적으로는 별로였다!

지극히 개인적인 생각입니다만.

이런거죠.

아래 사진을 볼까요?

소나타 디자인 개선버전? ㅋ 그냥 스케치해본 버전

 

오른쪽 차량이 뭐냐고요?

ㅎㅎ 

그런 차는 없습니다. 제가 개인적으로 만든 차니까요.

바로 옆에있는 차량과 동일한 차량이지만 해드라이트와 범퍼를 조금 수정하였더니 완전히 새로운 느낌이 들지 않나요?

어쨌든 제 생각에는 현대차의 대표 차량이라면 뭔가 좀 더 신경을 써야 했던게 아닐까 생각은 듭니다. 한명의 예비 소비자로써 아쉬움이 있지요.

어쩌면 새로나온 아반떼와 느낌적으로 비슷한 부분이 있기는 한데요, 사실 그 느낌적으로 비슷한 부분이 디자인 아이덴티티, 차종별로 그 비슷한듯한 느낌을 소화해 내는 것이 디자이너의 몫이 아니겠습니까?

사실 기아자동차와 현대 자동차가 경쟁하듯 디자인을 개선시켜 차량을 만들어내는 것을 보면서 즐거움과 아쉬움이 항상 함께 있습니다.

현대의 xx 한 부분이 기아에도 적용되었담녀 정말 죽여줬을텐데... 라든지 그 반대의 경우도 말이지요.

 

어쨌든 국가대표 세단의 앞으로의 길이 기대 됩니다.

해당 플랫폼으로 왜건도 좀 나왔으면 하는 바램도 있지요 ㅋ

 

 

2020/06/18 - [DESIGN] - 현대차에서 이런 왜건 차량이 나온다면 ?

 

현대차에서 이런 왜건 차량이 나온다면 ?

대한민국은 정말 왜건 차량의 무덤인것 같습니다. 저는 개인적으로 해치백이나 왜건 형태의 차량을 선호합니다. 스포티해 보이기도 하고 실용적이기도 하지요. 실제로 트렁크가 달려있는 세단�

diy-dev-design.tistory.com

 

2021/02/25 - [DESIGN] - [아이오닉5] 현대차에 바란다. 이런차 만들어줭

 

[아이오닉5] 현대차에 바란다. 이런차 만들어줭

어제 아이오닉 온라인 공개 라이브 방송을 봤습니다. 음... 현대차가 이제 본격적으로 칼을 갈고 있구나... 하는 마음 한 켠에는 아쉬운 마음이 사라지지 않는데요. 바로 웨건을 향한 저의 마음이

diy-dev-design.tistory.com

 

반응형
반응형

대한민국은 정말 왜건 차량의 무덤인것 같습니다. 

저는 개인적으로 해치백이나 왜건 형태의 차량을 선호합니다. 스포티해 보이기도 하고 실용적이기도 하지요. 실제로 트렁크가 달려있는 세단보다 트렁크부분을 잘라낸듯한 해치백이 차량의 운동성능이 훨씬 좋기 때문에 랠리 차량의 경우 대부분 해치백과 같은 형태의 디자인을 하고 있는 것을 알 수 있죠.

유럽의 경우 해치백이나 왜건 차량이 우리나라와 비교하면 압도적으로 많을 정도로 많은 사랑을 받고 있는 차의 형태이기도 합니다. 차종도 아주 다양하고 거의 대부분의 차량 라인업에 아반트, 에스테이트 등의 명칭으로 왜건모델이 함께 만들어지고 있는 것도 운전자들의 선호도를 반영하는 것이기도 합니다.

 

BMW 와 AUDI 의 전형적인 왜건

심지어 아우디의 RS6 와 같은 준 슈퍼카급 모델도 초기에는 왜건형태의 차량으로 유명해 졌으며 벤츠나 BMW, 볼보와 같은 프리미엄급 차량에서도 슈팅브레이크나 크로스컨트리 같은 승용차의 플랫폼에 왜건형태의 차량을 만들고 있는걸 보면 정말 많은 인기를 누리고 있지 않나 생각합니다.

 

Volvo V90 과 Benz Shooting Break

 

 

 

 

그런데 말입니다. 우리나라는....

우리나라는 작년 유일한 왜건 차량인 i40 가 단종되는 기이한 상황이 도래했습니다. 위에 장황하게 적어놓은 것 과는 너무나 대조적이지요? 왜건의 강국인 유럽 소비자를 타겟으로 심혈을 기울여 만든 만큼 실제로 유럽에서는 i30, i40 시리즈가 많은 인기를 얻었으며 i40 의 경우 첫번째 개발된 플랫폼으로 무려 9년이라는 긴 시간을 자리를 지켜왔으니 정말 잘만든 차량이기는 했던것 같습니다. 하지만 긴 시간동안 신차가 나오지 못해서 였는지 결국 소비자의 외면속에 역사속으로 사라지는 비운의 차량이 되기도 했습니다.

 

그렇다면 왜 국내 소비자는 i40을 그렇게 멀리했던 걸까요? 정말 대한민국은 왜건의 무덤인걸까요? 정말 SUV 에 비하여 왜건은 상품성이 떨어지는 걸까요?

 

 

아파트 주차장에 서있는 볼보 V90 크로스컨트리와 V60, 길가에 흔히 돌아다니는 BMW 3,5시리즈 왜건, 지나가면 사람들의 눈길을 사로잡는 벤츠의 CLS 슈팅브레이크를 보고 있자면 과연 우리나라 사람들이 왜건을 싫어 하는 걸까 하는 의문마져 듭니다. 심지어 그렇게 안팔렸다던 i40 은 고속도로에서 심심찮게 보이기도 합니다.

 

정말 소비자의 문제인걸까요?

 

 

아쉬운 제가 한번 만들어 봤습니다. 

 

그래서 제가 한번 대충 이런 모델이 나오면 어떨까 싶어서 제가 갖고 싶은 그런 차를 그려 보았습니다. 

 

싼타페를 기반으로 디자인해 본 왜건 

 

어떻습니까? 괜찮지 않습니까?

이정도로만 나와 준다면 그리고 볼보 V90보다 약 3~4천만원 저렴하다면?

볼보는 그냥 씹어먹지 않겠습니까?

손 덴김에 후측면도 한번 만들어 보았습니다.

 

내가 타고싶은 왜건 후측면

 

어떠신가요?

진심으로 저라면 볼보 V60이나 V90이라면 고민할 것도 없이 위의 모델을 구입하겠습니다. 물론 약간의 옵션이나 상품성이 보장되어야 하겠죠. 

기존 i40 처럼 유럽스타일의 탄탄한 하체, 싸구려같지 않은 마감재, 준수한 오디오, 편안한 승차감이 받침된다면 정말 바랄것이 없을 것 같네요.

사실 왜건의 장점은 타본사람만 안다는 이야기가 있습니다. 승차감만 비교하면 비슷한 기술력을 가진 차량 제조사에서 만들어진 차량이라면 왜건이 압도적으로 좋습니다. 코너링도 안정적이며 고속으로 갈수록 비교할 수가 없죠.

 

 

결론

국내 소비자를 위하여도 좀더 다양한 차량 선택지가 주어지도록 꾸준히 디자인을 개선하고 상품성 높은 차량을 만들어 간다면 결국 소비자의 사랑을 받게 되지 않을까요? 

모두들 왜건의 매력이 빠지는 그날이 오기를 기대해 봅니다.

 

SUV 와는 다른 매력의 Wagon .. 어떠세요?

 

<이미지 출처 : 구글검색 / 현대자동차 공식 사이트>

정말 저런 차를 기다리고 기다리는 한명의 현대차 오너입니다. 제말 만들어 주세요.
문제가 되면 삭제하도록 하겠습니다. 

2021/02/25 - [DESIGN] - [아이오닉5] 현대차에 바란다. 이런차 만들어줭

 

[아이오닉5] 현대차에 바란다. 이런차 만들어줭

어제 아이오닉 온라인 공개 라이브 방송을 봤습니다. 음... 현대차가 이제 본격적으로 칼을 갈고 있구나... 하는 마음 한 켠에는 아쉬운 마음이 사라지지 않는데요. 바로 웨건을 향한 저의 마음이

diy-dev-design.tistory.com

2020/06/19 - [DESIGN] - 쏘나타에 관한 고찰 - 새로운 디자인 ???

 

쏘나타에 관한 고찰 - 새로운 디자인 ???

나의 어릴쩍 기억부터 줄곧 내 머릿속에 자리매김하고 있는 특이한 차를 손꼽을때 빼 놓을수 없는 차중의 하나가 바로 현대 자동차의 소나타가 아닐까 생각됩니다 처음 소나타가 출시되었을때�

diy-dev-design.tistory.com

 

2020/04/16 - [DIY/RC] - [대륙의실수] 가성비 RC 카 HS18301, 안쪽까지 상세 보기, 4만원의 행복

 

[대륙의실수] 가성비 RC 카 HS18301, 안쪽까지 상세 보기, 4만원의 행복

중국산 제품은 이제 우리 생활에 뗄레야 뗄수 없는 필수 품이 되었습니다. 사실 나도 모르는 사이에 사용하는 거의 대부분의 제품이 중국에서 생산된 제품일 가능성이 높습니다. 제가 얼마전에

diy-dev-design.tistory.com

2019/08/18 - [DIY/PaperCraft] - [Paper Craft] WPL RC Custom body modeling

 

[Paper Craft] WPL RC Custom body modeling

WPL 의 대표 RC 카 중의 하나인 C24 섀시에 커스텀 바디 모델링을 제작하여 얹어 보았습니다. C24 모델도 워낙 디자인이 괜찮지만 RC 하는 분들이라면 새로운 바디를 올려보고 싶은 욕심이 나게 마련

diy-dev-design.tistory.com

2020/01/20 - [DIY/PaperCraft] - JEEP WRANGLER RC BODY on HS18311

 

JEEP WRANGLER RC BODY on HS18311

대륙의 실수라고 제가 올린 중국산 RC 카 모델이 있습니다. HS18311 인데요. 썬더 스톰이라는 녀석이죠. 2019/12/23 - [DIY/RC] - [대륙의 실수] 가성비 RC 카 Storm Thunder, HS118311 [대륙의 실수] 가성비 RC..

diy-dev-design.tistory.com

 

반응형
반응형

아두이노로 통합(만능) 리모콘 만들기 3/3 이라 쓰고 왠지 이번 포스트에서 끝나지 않을 것 같은 느낌이 강하게 듭니다. 지난 포스트에서 아두이노 IR 센서를 이용하여 신호를 해킹하고 또 필요한 신호를 따서 기록하는 것까지 소개해 드렸는데요.  해당 포스트는 아래 링크를 참고해 주세요.

2019/11/10 - [DIY/Arduino] - [DIY] 아두이노로 만능 (통합) 리모콘 만들기 1/3

 

[DIY] 아두이노로 만능 (통합) 리모콘 만들기 1/3

도대체 영화 한편 보려면 몇개의 리모콘을 사용하는지... TV 전원을 켜기위해 TV 리모컨을 찾아야 하고 안드로이드 TV 셋톱을 켜기위해 안드로이드 TV 리모콘을 역시 찾아야 하며 막상 틀었더니 소

diy-dev-design.tistory.com

2019/11/10 - [DIY/Arduino] - [DIY] 아두이노로 통합(만능) 리모콘 만들기 2/3

 

[DIY] 아두이노로 통합(만능) 리모콘 만들기 2/3

먼저 포스트에서 아두이노를이용하여 다양한 리모콘의 신호를 해킹하는 방법을 알아 보았습니다. https://diy-dev-design.tistory.com/65 [DIY] 아두이노로 만능 (통합) 리모콘 만들기 1/3 도대체 영화 한편 �

diy-dev-design.tistory.com

 

이번 포스트에서는 본격적으로 SW 를 설계하고 HW 를 만들어가는 과정을 소개해 드릴까 합니다.

먼저 조사했던 여러가지 기능을 모두 소화하기에 아두이노의 입력핀은 너무 적기 때문에 기기 전환 버튼같은 기능을 두어서 버튼은 동일한 레이아웃을 가지고 아두이노의 동일한 핀으로 입력 신호가 들어가더라도 실제 출력해주는 IR  신호는 다르게 보내주는 방식으로 구현을 할 계획입니다.

 

필요한 재료

  • 3cm x 7cm 양면 만능기판 (2.54mm 규격) x 2EA
  • 아두이노 나노
  • Attiny85
  • SW-200D 진동/틸트 스위치 양쪽 다리형
  • Push switch (2pin) x 14 EA
  • LED (red, SMD) x 4EA
  • LED (green, SMD) x 1EA
  • 5V DCDC Converter, Step Up Power Supply 보드
  • TP4056 18650 charge module
  • 0.1F 전해콘덴서 (슈퍼콘덴서??) 꼭 필요한지 모르겠음
  • 대충 33옴 정도되는 저항, 낮아도 별 상관 없음 (SMD LED 연결용)
  • IR LED (송신용) x 1EA
  • 18650 배터리 1EA

 

 

 

SW 를 대충 설계해보자.

먼저 아두이노의 인풋, 아웃풋 키와 함께 각각의 기능을 매칭하는 테이블을 만들어야겠습니다. 아무래도 여러가지 기능이 동작되어야 하므로 나중에 실수하지 않으려면 각각의 입력핀에 연결될 버튼과 기능을 정의하는게 중요합니다.

4개의 제품의 동작별로 기록한 신호와 기능명칭들 가장 오른쪽은 아두이노의 핀번호

위와 같이 각각의 기능을 테이블로 만들어 보았습니다. 가장 우측의 비고에 해당하는 열이 아두이노의 핀번호가 되겠으며 9~12번은 4개의 제품에 해당되는 LED 를 켜주기 위한 출력핀입니다. 18번은 제품전환용 버튼 입력핀이 됩니다.

제일 좌측에 S01~S14까지 번호가 있는데요. 이번호들은 각각 아래와 같은 형태로 배치할 계획입니다.

리모컨 버튼부 레이아웃

저는 양면 만능기판을 사용할 계획이고요. 만능기판의 끝부분에 단자용도로 사용할 수 있는 납이 붙어있어 그부분까지 일단 납땜을 하여 연결해 보기로 합니다. 중앙 상단의 네게의 흐릿한 동그라미가 LED 1234 와 연결이 되는 것이죠.

14개의 버튼은 모두 1개의 그라운드핀과 연결되며 나머지 한쪽 다리를 아래쪽 단자에 순차적으로 매칭을 시켜줍니다.

LED 역시 그라운드를 모두 한꺼번에 연결하고 아래쪽 LED 핀은 아두이노 디지털 출력핀과 연결해주어 선택된 제품에 불이 켜지도록 하겠습니다.

 

만능기판에 버튼을 실장한 사진은 아래와 같습니다.

총 14개의 버튼이 위와같이 배치된다.

총 14개의 버튼이 위와 같이 아름답게 배치됩니다. 만능기판의 크기를 생각해보면 아주 아담한 리모컨이 만들어 질 것 같네요.

 

 

 

 

아두이노 나노와 전원 공급 모듈

전원 입력은 3.7V 리튬이온 18650 배터리를 이용할 계획인데요. 아두이노가 5V 이상의 전압이 필요하기 때문에 5V 로 승압을 해주는 보드를 하나 장착이 필요하고요, 이 제품을 연속으로 사용하지 않을 경우 자동으로 전원 공급이 중단되도록 할 필요가 있을듯 하여 attiny85 를 이용하여 일정 시간이 지나면 전원 공급이 중단되도록 할 계획입니다. atiny는 sleep 모드라는 것을 지원하는데 sleep 모드로 들어가면 거의 전기를 먹지않는 놀라운 기능을 수행하게 됩니다.

다시 동작할때는 reset 핀에 GND 를 입력해주면 다시 동작을 시작하게 되는데 틸트 스위치를 이용하여 움직임을 감지하여 물리적으로 움직임이 발생되면 attiny85의 reset핀으로 신호를 보내줌으로써 attiny 가 전원 공급을 시작하는 것이죠. 이번 제작하는 리모컨 자체가 전류를 거의 사용하지 않기 때문에 문제는 없을 듯 하지만 그래도 attiny 의 디지털 출력핀이 충분한 전기를 공급할 수 있을지는 미지수입니다.

그래서 0.1F 정도의 콘덴서를 전원 공급용으로 하나 달아 보았습니다. ( 사실 전기/전자 지식이 매우 얕아서 저렇게 하면 되는지는 잘 모르겠어요)

 

그렇게 만들어진 보드가 바로 아래와 같이 만들어졌습니다.

 

위에서 설명드린 것처럼 우측 상단에 attiny85 가 자리잡고 있고요. (SMD 버전입니다) 중간에 검은 통이 틸트 스위치입니다. 약간 기울여서 달아주어야 평소에 눕혀져 있을때 신호가 끊어지기 때문에 기울여서 부착을 했고요, 아래 검은 네모박스가 0.1F 전해 콘덴서 입니다. 어디서 떼어낸건지는 기억이 안나는데 버리는 가전제품에서 떼어낸 부품입니다.

실제 아두이노 나노로 입력되는 전원은 전해콘덴서와 연결이 되어 있어 attiny 가 sleep 모드로 들어가더라도 일정시간 전원을 공급하여 주는 역할을 하게 됩니다.

우측의 단자부분은 이미 납땜이 마구 되어 있는데요, 위에 소개해드린 버튼부분과 연결이 되게 됩니다.

 

 

 

 

 

고난의 시작 ! 인정사정 없이 납땜시작

정말 납땜하다가 정신병 걸리는 줄 알았습니다.

왼쪽은 아두이노 나노를 포함한 메인 컨트롤 부, 오른쪽은 버튼 조작부와 LED 되겠습니다. LED 는 우측 끝에 매달려 있는데 잘 안보이시죠? 작은 회로기판 같은데 신호용으로 아주아주 작은 SMD 타입의 LED가 붙여 있는 것을 보셨을 텐데요, 고 녀석들을 떼어내서 부탁을 해주었습니다. 일부러 구입할일은 없으니까요.

각각의 선들은 위에서 설계한 것처럼 연결을 해주었는데 설계할때는 이게 이렇게나 복잡할거라고는 생각을 못했습니다.

위쪽에 보이는 작은 초록색 기판이 3.7 --> 5V 승압회로 , 그사이에 아주 작게 보이는 파란색 보드가 USB 전원을 이용하여 3.7V 배터리를 충전할 수 있는 충전 보드 입니다. 

이렇게 하면 완전한 하나의 제품에 해당되는 부품을 모두 제작한 셈이 되겠네요.

두 보드는 이렇게 접어서 조립할 예정입니다.

위에서 보았던 두개의 보드는 위 사진처럼 접어서 조립할 계획입니다. 안쪽역시 매우 지저분하네요. 저렇게 만들어진 배선이 과연 잘 붙어있을까 궁금합니다.

두개의 보드 중간에는 절연을 위하여 얇은 실리폰 패드를 하나 넣어줄 계획입니다.

 

전원 입력!

전원이 들어오게 되면 위사진과 같이 불이 켜집니다. 계획에는 LED가 4개였지만 메인 전원이 들어왔는지 여부를 판단하기 위하여 연두색 SMD LED를 하나 추가하였습니다. 

 

 

 

코딩 시작!

자 순서가 좀 바뀐것 같지만 이제부터는 지루한 SW 코딩 부분입니다.

SW 구현할때 다음의 것들이 동작해야 하는 것이 중요합니다.

  • 하나의 버튼에 의해 주어진 신호는 4개의 제품에 대한 신호를 보낼 수 있어야 한다.
  • 마지막으로 사용한 제품을 기억했다가 다시 동작할때 세팅해준다.
  • 신호가 한번에 입력이 안될 경우를 대비하여 연속으로 n번 보낼 수 있도록 구성한다.

뭐 별건 없습니다만 두번째에 해당되는 부분은 제가 처음해보는 관계로 저도 공부를 좀 했습죠.

 

 

 

EEPROM 을 사용해보자!

아두이노 나노에 사용되는 Atmega328 칩에는 무려 1kb 라는 비 휘발성 저장공간이 존재합니다. EEPROM 이라고 부르는데요, 프로그램이 저장되는 공간 외에 사용자가 데이터를 저장할 수 있는 공간말입니다.

무려 1kb 요.

-_-;;

1kb 라니.. 장난하냐..

 

 

 

싶겠지만 있는게 어딥니까?

이 저장공간을 이용하여 우리는 마지막 동작했던 제품의 정보를 기억할 건데요. 따지고 보면 차고도 넘치는 양이지요.

자 그럼 EEPROM 에 데이터는 어떻게 저장하고 읽어 들이는지 볼까요?

#include <EEPROM.h>

int sw_02;
int productIdx = 0; //0 : TV / 1: TV BOX / 2: BTV / 3: SPK
bool chkon = false;

//LED
const int L00 = 9;    // TV
const int L01 = 10;   // TV BOX
const int L02 = 11;   // BTV
const int L03 = 12;   // LONPOO SPEAKER

void setup()
{
    pinMode(s02, INPUT_PULLUP);
    productIdx = EEPROM.read(0); // EEPROM 에 저장된 제품의 번호를 불러오는 부분
}

void loop() {

  sw_02 = digitalRead(s02);

   // change product
  if (sw_02 == HIGH) {
    chkon = true; // 연속으로 눌리는 것을 방지하기 위하여 on 상태일때만 기기 변경이 되도록 한다.
    ledON(productIdx);
  }else{
    if (chkon)
    {
      productIdx++;
      if (productIdx > 3) productIdx = 0;
      EEPROM.write(0, productIdx); // 이부분이 EEPROM 에 현재 제품의 번호를 저장하는 부분
      chkon = false;
    }
    
    ledON(productIdx);
}

void ledON (int idx) // 선택된 인덱스에 맞게 LED 를 켜주는 함수
{
  digitalWrite(L00, LOW);
  digitalWrite(L01, LOW);
  digitalWrite(L02, LOW);
  digitalWrite(L03, LOW);
  switch (idx) {
  case 0:
    digitalWrite(L00, HIGH);
    break;
  case 1:
    digitalWrite(L01, HIGH);
    break;
  case 2:
    digitalWrite(L02, HIGH);
    break;
  case 3:
    digitalWrite(L03, HIGH);
    break;
  default:
    break;
  }
}

어렵지 않죠? 제일 위에 해당 라이브러리를 불러들여 주고요,

Setup 시에 저장되어 있는 값을 불러옵니다.

버튼은 눌렀을때 LOW 가 되도록 하고 항상 HIGH 한 상태를 만들어 줍니다. HIGH 한 상태가 되면 chkon 이 true 가되고 버튼이 눌렸을때 기기의 인덱스를 변경한 뒤 EEPROM 에 값을 저장하고 chkon 을 false 로 만들어 다음 신호를 기다리게 됩니다. 이렇게 하면 버튼을 연속으로 누르고 있어도 신호는 한번만 가게 되겠죠. 마지막으로 사용한 제품도 저장이 됩니다.

 

 

 

 

버튼 하나로 4개의 제품은 어떻게 제어를 할까요?

//setup, 변수 선언 등은 생략합니다.

void loop() {

if (sw_03 == HIGH) {    //s03 은 전원 버튼입니다.
  }else{    
    digitalWrite(13, HIGH);
    press_S03(productIdx);
  }
  // 생략
}


void press_S03 (int idx) // power
{
  switch (idx) {
  case 0:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x2DF10EF,32);   // tv power
    break;
  case 1:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x807F02FD,32);   // tv box power
    break;
  case 2:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x1FE807F,32);   // Btv power1 
    break;
  case 3:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x40BF807F,32);   
    break;
  default:
    // statements
    break;
  }
}

바로 Switch 문을 이용하여 입력되는 idx 에 따라 각각 다른 신호를 보내주는 것이지요. 

아래 press_S03 버튼이 바로 전원을 켜고 끄는기능을 담당하는 함수가 되는 것이죠.

저런 식으로 버튼 개수만큼 함수를 만들어 주면 됩니다. 좀더 효율적으로 코딩할수도 있겠지만 초보인 저에게는 저렇게 쉽게 코딩하는게 나중에 뜯어 고치지도 좋을 것 같아 이란 저런 방식으로 작성을 하였습니다.

 

 

 

포스트가 점점 길어지네요.. 

자 이제 전체 소스 갑니다.

중요한 내용은 위에 다 설명 드렸고 이전 포스트를 참고하시면서 내용 확인해 보시면 되고요. 꼭 저와 동일하게 만들 필요는 없으니 참고만 해주시면 됩니다.

 

길이가 대단하니 조심하세요~ ㅋ

#include <boarddefs.h>
#include <IRremote.h>
#include <IRremoteInt.h>
#include <ir_Lego_PF_BitStreamEncoder.h>
#include <EEPROM.h>
/*
 * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
 * An IR LED must be connected to Arduino PWM pin 3.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */
/*
 * tv (NEC)
 * power :      0x2DF10EF, 32
 * input :      0x2DFD02F, 32
 * chnnel up :  0x2DF00FF, 32
 * chnnel dn :  0x2DF807F, 32
 * volumn up :  0x2DF40BF, 32
 * volumn dn :  0x2DFC03F, 32
 * OK :         0x2DF22DD, 32
 * sw up :      0x2DF02FD, 32
 * sw dn :      0x2DF827D, 32
 * sw left :    0x2DFE01F, 32
 * sw right :   0x2DF609F, 32
 * 
 * android tv (NEC)
 * power :      0x807F02FD, 32
 * sw up :      0x807F6897, 32
 * sw dn :      0x807F58A7, 32
 * sw left :    0x807F8A75, 32
 * sw right :   0x807F0AF5, 32
 * sw OK :      0x807FC837, 32
 * back :       0x807F9867, 32
 * volumn up :  0x807F18E7, 32
 * volumn dn :  0x807F08F7, 32
 * 
 * 
 * lonpoo speaker
 * power :      0x40BF807F, 32
 * volumn up :  0x40BF50AF, 32
 * volumn dn :  0x40BFD02F, 32
 * bt :         0x40BFA05F, 32
 * bt esc :     0x40BF906F, 32
 * opt :        0x40BF20DF, 32
 * 
 * 
 * LED
 * tv :     9
 * tv box : 10
 * btv :    11
 * spk :    12
 * 
 * input
 * s01 
 * 
 * 
 * 
 * 
 */

#include <IRremote.h>

const int s01 = 0;
const int s02 = 18;   // select sw 
const int s03 = 1;
const int s04 = 2;
const int s05 = 19;
const int s06 = 4;
const int s07 = 5;
const int s08 = 6;
const int s09 = 7;
const int s10 = 8;
const int s11 = 14;
const int s12 = 15;
const int s13 = 16;
const int s14 = 17;
//LED
const int L00 = 9;    // TV
const int L01 = 10;   // TV BOX
const int L02 = 11;   // BTV
const int L03 = 12;   // LONPOO SPEAKER

//
// define sw value
int sw_01;
int sw_02;
int sw_03;
int sw_04;
int sw_05;
int sw_06;
int sw_07;
int sw_08;
int sw_09;
int sw_10;
int sw_11;
int sw_12;
int sw_13;
int sw_14;

// 
int productIdx = 0; //0 : TV / 1: TV BOX / 2: BTV / 3: SPK

int addr = 0;
bool chkon = false;
IRsend irsend;

void setup()
{
  pinMode(s01, INPUT_PULLUP);
  pinMode(s02, INPUT_PULLUP);
  pinMode(s03, INPUT_PULLUP);
  pinMode(s04, INPUT_PULLUP);
  pinMode(s05, INPUT_PULLUP);
  pinMode(s06, INPUT_PULLUP);
  pinMode(s07, INPUT_PULLUP);
  pinMode(s08, INPUT_PULLUP);
  pinMode(s09, INPUT_PULLUP);
  pinMode(s10, INPUT_PULLUP);
  pinMode(s11, INPUT_PULLUP);
  pinMode(s12, INPUT_PULLUP);
  pinMode(s13, INPUT_PULLUP);
  pinMode(s14, INPUT_PULLUP);
  
  pinMode(L00, OUTPUT);
  pinMode(L01, OUTPUT);
  pinMode(L02, OUTPUT);
  pinMode(L03, OUTPUT);
  
  pinMode(13, OUTPUT);
  
  productIdx = EEPROM.read(0);
}

void loop() {

  digitalWrite(13, LOW);
  
  sw_01 = digitalRead(s01);
  sw_02 = digitalRead(s02);
  sw_03 = digitalRead(s03);
  sw_04 = digitalRead(s04);
  sw_05 = digitalRead(s05);
  sw_06 = digitalRead(s06);
  sw_07 = digitalRead(s07);
  sw_08 = digitalRead(s08);
  sw_09 = digitalRead(s09);
  sw_10 = digitalRead(s10);
  sw_11 = digitalRead(s11);
  sw_12 = digitalRead(s12);
  sw_13 = digitalRead(s13);
  sw_14 = digitalRead(s14);
  
  // change product
  if (sw_02 == HIGH) {
    chkon = true;
    ledON(productIdx);
  }else{
    if (chkon)
    {
      productIdx++;
      if (productIdx > 3) productIdx = 0;
      EEPROM.write(0, productIdx);
      chkon = false;
    }
    
    ledON(productIdx);
  }
  
  if (sw_01 == HIGH) {    
  }else{    
    digitalWrite(13, HIGH);
    press_S01(productIdx);
  }
  if (sw_03 == HIGH) {    
  }else{
    digitalWrite(13, HIGH);
    press_S03(productIdx);
  }
  if (sw_04 == HIGH) {    
  }else{
    digitalWrite(13, HIGH);
    press_S04(productIdx);
  }
  if (sw_05 == HIGH) {    
  }else{
    digitalWrite(13, HIGH);
    press_S05(productIdx);
  }
  if (sw_06 == HIGH) {    
  }else{
    digitalWrite(13, HIGH);
    press_S06(productIdx);
  }
  if (sw_07 == HIGH) {    
  }else{
    digitalWrite(13, HIGH);
    press_S07(productIdx);
  }
  if (sw_08 == HIGH) {    
  }else{
    digitalWrite(13, HIGH);
    press_S08(productIdx);
  }
  if (sw_09 == HIGH) {    
  }else{
    digitalWrite(13, HIGH);
    press_S09(productIdx);
  }
  if (sw_10 == HIGH) {    
  }else{
    digitalWrite(13, HIGH);
    press_S10(productIdx);
  }
  if (sw_11 == HIGH) {    
  }else{
    digitalWrite(13, HIGH);
    press_S11(productIdx);
  }
  if (sw_12 == HIGH) {    
  }else{
    digitalWrite(13, HIGH);
    press_S12(productIdx);
  }
  if (sw_13 == HIGH) {    
  }else{
    digitalWrite(13, HIGH);
    press_S13(productIdx);
  }
  if (sw_14 == HIGH) {    
  }else{
    digitalWrite(13, HIGH);
    press_S14(productIdx);
  }
	
	delay(75); //5 second delay between each signal burst
}

void press_S14 (int idx) // vol -
{
  switch (idx) {
  case 0:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x2DFC03F,32);   // tv vol -
    break;
  case 1:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x807F08F7,32);  // tv box vol -
    break;
  case 2:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x1FE42BD,32);  // BTV box vol -
    break;
  case 3:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x40BFD02F,32);  //  spk vol -
    break;
  default:
    // statements
    break;
  }
}

void press_S13 (int idx) // chnl -
{
  switch (idx) {
  case 0:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x2DF807F,32);   // tv chnl -
    break;
  case 1:
    //for (int i = 0; i < 1; i++) irsend.sendNEC(0x807F18E7,32);  // tv box vol +
    break;
  case 2:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x1FE827D,32);   // Btv chnl -
    break;
  case 3:
    //for (int i = 0; i < 1; i++) irsend.sendNEC(0x40BF50AF,32);  //  spk vol +
    break;
  default:
    // statements
    break;
  }
}

void press_S12 (int idx) //vol +
{
  switch (idx) {
  case 0:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x2DF40BF,32);   // tv vol +
    break;
  case 1:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x807F18E7,32);  // tv box vol +
    break;
  case 2:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x1FEC23D,32);   // Btv vol +
    break;
  case 3:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x40BF50AF,32);  //  spk vol +
    break;
  default:
    // statements
    break;
  }
}

void press_S11 (int idx) // chnl +
{
  switch (idx) {
  case 0:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x2DF00FF,32);   // tv chnl +
    break;
  case 1:
    //for (int i = 0; i < 1; i++) irsend.sendNEC(0x807F58A7,32);  // tv box
    break;
  case 2:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x1FE02FD,32);   // Btv chnl +
    break;
  case 3:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x40BF906F,32);  //  spk bt esc
    break;
  default:
    // statements
    break;
  }
}

void press_S10 (int idx) // down
{
  switch (idx) {
  case 0:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x2DF827D,32);   // tv down
    break;
  case 1:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x807F58A7,32);  // tv box down 
    break;
  case 2:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x1FE52AD,32);   // Btv down
    break;
  case 3:
    //for (int i = 0; i < 1; i++) irsend.sendNEC(0x40BF20DF,32);  //  
    break;
  default:
    // statements
    break;
  }
}

void press_S09 (int idx) // right
{
  switch (idx) {
  case 0:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x2DF609F,32);   // tv right
    break;
  case 1:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x807F0AF5,32);  // tv box right 
    break;
  case 2:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x1FE32CD,32);   // Btv right
    break;
  case 3:
    //for (int i = 0; i < 1; i++) irsend.sendNEC(0x40BF20DF,32);  // tv box up 
    break;
  default:
    // statements
    break;
  }
}
void press_S08 (int idx) // ok
{
  switch (idx) {
  case 0:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x2DF22DD,32);   // tv ok
    break;
  case 1:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x807FC837,32);  // tv box ok 
    break;
  case 2:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x1FE629D,32);   // Btv ok
    break;
  case 3:
    //for (int i = 0; i < 1; i++) irsend.sendNEC(0x40BF20DF,32);  // tv box up 
    break;
  default:
    // statements
    break;
  }
}

void press_S07 (int idx) // arrow left
{
  switch (idx) {
  case 0:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x2DFE01F,32);   // tv left
    break;
  case 1:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x807F8A75,32);  // tv box left 
    break;
  case 2:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x1FED22D,32);   // Btv left
    break;
  case 3:
    //for (int i = 0; i < 1; i++) irsend.sendNEC(0x40BF20DF,32);  // tv box up 
    break;
  default:
    // statements
    break;
  }
}
void press_S06 (int idx)
{
  switch (idx) {
  case 0:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x2DF02FD,32);   // tv back
    break;
  case 1:
    //for (int i = 0; i < 1; i++) irsend.sendNEC(0x807F9867,32);  // tv box back 
    break;
  case 2:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x1FE728D,32);   // Btv back
    break;
  case 3:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x40BF20DF,32);  // spk OPT 
    break;
  default:
    // statements
    break;
  }
}

void press_S05 (int idx) // arrow up
{
  switch (idx) {
  case 0:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x2DF02FD,32);   // tv up
    break;
  case 1:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x807F6897,32);  // tv box up 
    break;
  case 2:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x1FE926D,32);   // Btv up
    break;
  case 3:
    //irsend.sendNEC(0x40BFA05F,32);  
    break;
  default:
    // statements
    break;
  }
}

void press_S04 (int idx)
{
  switch (idx) {
  case 0:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x2DFD02F,32);   //외부입력
    break;
  case 1:
    //irsend.sendNEC(0x2DF10EF,32);   
    break;
  case 2:
    //irsend.sendNEC(0x2DF10EF,32);   
    break;
  case 3:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x40BFA05F,32);   // blue tooth
    break;
  default:
    // statements
    break;
  }
}

void press_S03 (int idx) // power
{
  switch (idx) {
  case 0:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x2DF10EF,32);   // tv power
    break;
  case 1:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x807F02FD,32);   // tv box power
    break;
  case 2:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x1FE807F,32);   // Btv power1 
    break;
  case 3:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x40BF807F,32);   
    break;
  default:
    // statements
    break;
  }
}
void press_S01 (int idx) //  S01
{
  switch (idx) {
  case 0:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x2DF10EF,32);   
    break;
  case 1:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x807F02FD,32);   
    break;
  case 2:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x1FE807F,32);   
    break;
  case 3:
    for (int i = 0; i < 1; i++) irsend.sendNEC(0x40BF807F,32);   
    break;
  default:
    // statements
    break;
  }
}
void ledON (int idx)
{
  digitalWrite(L00, LOW);
  digitalWrite(L01, LOW);
  digitalWrite(L02, LOW);
  digitalWrite(L03, LOW);
  switch (idx) {
  case 0:
    digitalWrite(L00, HIGH);
    break;
  case 1:
    digitalWrite(L01, HIGH);
    break;
  case 2:
    digitalWrite(L02, HIGH);
    break;
  case 3:
    digitalWrite(L03, HIGH);
    break;
  default:
    // statements
    break;
  }
}

 

자 이렇게 해서 프로그램까지 마쳤습니다.

원래 3편에 걸쳐 포스팅을 완료하려고 하였으나 너무 길어져서 최종 케이스제작과 동작 테스트는 다음 포스트로 미루도록 하겠습니다. 죄송합니다.

또 얼마가 걸릴지 모르겠네요. 

 

어쨌든 핵심이 되는 내용은 이번 편까지인것 같고 하드웨어 구성은 여러분께서 마음껏 하셔도 될 것 같습니다. 기능도 변경해보시고요, 좀 고민해보면 더 많은 기능을 구성하는 것도 가능할 수도 있습니다.

이번 프로젝트로 무려 4개의 리모컨을 1개로 통합하는 작업을 해보았는데요, 사실 제가 생각했던것과 아주 유사한 제품이 판매되는 제품도 있습니다. 가격이 아주 비싼것도 아니고요. 다만 이런것을 직접 해봄으로 해서 우리는 또 많은 것을 배울 수 있지 않겠습니까?

저는 이번 프로젝트에서 EEPROM 과 IR 신호를 제어하는 것을 배울 수 있는 좋은 기회였던 것 같습니다.

 

자 그럼 케이스 까지 완성되는 그날을 기대하며 ~

 

완성된 리모컨 구경하려면?

2022.08.16 - [DIY/Arduino] - [DIY] 아두이노로 통합(만능) 리모콘 만들기 (최종)

 

[DIY] 아두이노로 통합(만능) 리모콘 만들기 (최종)

만능 리모컨을 만들기로 해놓고 정말 많은 시간이 흘렀습니다. 2019.11.10 - [DIY/Arduino] - [DIY] 아두이노로 만능 (통합) 리모콘 만들기 1/3 2019.11.10 - [DIY/Arduino] - [DIY] 아두이노로 통합(만능) 리모콘..

diy-dev-design.tistory.com

 

뎃글, 공감 은 블로그 작성자에게 큰 힘이 된답니다. 
도움이 되었다 생각되시면  클릭!!  부탁드려요~

 

IR 리모컨 제작 관련 링크는?

2019/11/10 - [DIY/Arduino] - [DIY] 아두이노로 만능 (통합) 리모콘 만들기 1/3

 

[DIY] 아두이노로 만능 (통합) 리모콘 만들기 1/3

도대체 영화 한편 보려면 몇개의 리모콘을 사용하는지... TV 전원을 켜기위해 TV 리모컨을 찾아야 하고 안드로이드 TV 셋톱을 켜기위해 안드로이드 TV 리모콘을 역시 찾아야 하며 막상 틀었더니 소

diy-dev-design.tistory.com

2019/11/10 - [DIY/Arduino] - [DIY] 아두이노로 통합(만능) 리모콘 만들기 2/3

 

[DIY] 아두이노로 통합(만능) 리모콘 만들기 2/3

먼저 포스트에서 아두이노를이용하여 다양한 리모콘의 신호를 해킹하는 방법을 알아 보았습니다. https://diy-dev-design.tistory.com/65 [DIY] 아두이노로 만능 (통합) 리모콘 만들기 1/3 도대체 영화 한편 �

diy-dev-design.tistory.com

 

다른 아두이노 예제는?

 

2020/05/26 - [DIY/Arduino] - 0.96 inch OLED 디스플레이 구동하기

 

0.96 inch OLED 디스플레이 구동하기

가끔 아두이노로 무엇인가를 만들어 보려고 하다보면 디스플레이가 있으면 하는 생각이 들때가 있습니다. 아두이노는 작은 컴퓨터이기는 하지만 모름지기 컴퓨터라 한다면 입력장치 - 중앙처��

diy-dev-design.tistory.com

2019/10/29 - [DIY/Arduino] - [DIY] 아두이노를 이용한 수경재배 시스템

 

[DIY] 아두이노를 이용한 수경재배 시스템

아두이노는 정말 놀라운 하드웨어가 아닐수 없죠. 우리가 생각하는 이런건 자동으로 해주는거 없나? 이런게 자동으로 되면 좋을텐데... 이런걸 왜 자동으로 안하는거야?? 같은 대부분의 자동화 �

diy-dev-design.tistory.com

2019/06/27 - [DIY/Arduino] - 아두이노를 이용한 간단한 화분 자동 물주기 시스템

 

아두이노를 이용한 간단한 화분 자동 물주기 시스템

얼마뒤면 베트남으로 가족 여행을 떠날 예정입니다. 7박이나 하고 올 예정이므로 집을 비우기 전 준비해야 할 것들이 많습니다. 이것저것 여행준비를 하던 찰나 베란다에 내어 둔 화분이 걱정이

diy-dev-design.tistory.com

2020/03/23 - [DIY/Arduino] - Arduino(아두이노) 무작정 시작하기

 

Arduino(아두이노) 무작정 시작하기

아두이노, Arduino 여기저기서 많이 들었을 겁니다. 이걸 해야 된다는 말이 귀에 못이 박히도록 이야기 합니다. 대충 뭔지는 알겠는데 개발자도 아닌 내가 과연 이걸로 뭘 할 수 있을까 싶기도 하��

diy-dev-design.tistory.com

2020/06/29 - [DIY/Arduino] - C# 에서 아두이노로 시리얼 통신 하기

 

C# 에서 아두이노로 시리얼 통신 하기

카테고리를 c# 으로 해야 할지 Arduino 로 해야할지 조금 고민이 되는 포스트 입니다. 음.... arduino 로 하는게 좋겠네요. 따지고 보면 C# 으로 만든 어플이 중요한게 아니라 아두에노에서 시리얼 통신

diy-dev-design.tistory.com

 

반응형
반응형

저는 회사에서 디자인팀에 있고 전공도 디자인과 출신이며 심지어는 고등학교도 예체능계열 고등학교를 나왔습니다만 지금 회사에서 하는일의 95% 정도는 개발을 하고 있습니다. 실제로 제가 포토샵, 일러스트 및 기타 디자인툴을 다루는 시간을 다 합쳐도 비주얼 스튜디오를 사용하는 시간의 1/10 도 안될거에요.

요즘은 대부분의 개발을 c# 으로 진행하고 있습니다. 포토샵 스크립트를 이용해서 이미지 컨트롤은 할 수 있겠지만 좀더 복잡하고 다양한, 그리고 시스템 차원에서 뭔가를 하기에는 부족한 부분이 있습니다. 하지만 포토샵에는 레이어 컨트롤이나 layer effect 와 같은 놀라운 기능들이 있기 때문에 버리기는 아까운 부분이 있습니다.

그래서 저는 C# 을 이용하여 개발을 하되 포토샵을 이미지 자동화 편집 툴로 사용할때가 종종 있습니다. javascript 로 개발된 이미지 편집용 스크립트를 C# application 에서 포토샵으로 전달하여 자동화를 하는 것이지요.

 

??

 

이게 가능하냐고요? 

예전에 제가 엑셀 비주얼 베이직을 이용하여 엑셀과 포토샵이 연동되는 것을 소개해 드린적이 있는데요, 개념적으로는 크게 다르지 않습니다.

2019/10/01 - [DEV/VBA] - [VBA] 엑셀 VBA로 포토샵 연동이 가능할까?

 

개념적으로는 윈도우의 COM 오브젝트를 이용하는 것과 동일한데요. 연결해주는 방법에 약간 차이가 있고 C# 에서 포토샵 스크립트 작성이 쉽지 않으니 개발은 Extend Script Tool kit 으로 하고 실행만 C#이 하는 역할을 하는 겁니다.

이렇게 되면 C#이 다양한 파일 처리, 관리를 하는 동안 이미지 편집이 필요한 순간에 Photoshop 을 호출하여 이미지를 열고 자동화 편집 스크립트를 통해 이미지 편집을 진행하고 그 다음 나머지 파일 처리를 하는 방식 인 겁니다.

 

 

 

C# 에서 COM 오브젝트 선언하는 방법

Type ptsApp = Type.GetTypeFromProgID("Photoshop.Application");
dynamic psApp = Activator.CreateInstance(ptsApp);
psApp.doJavaScript("alert(\"ds\")"); // 여기에 수행되어야 할 포토샵 스크립트를 문자열로 작성하여 전달

dynamic 개체를 이용하여 선언이 가능하며 .NET4.0 이상의 플랫폼에서 지원합니다.

이렇게 했을 때 빌드를 하게 되면 아래와 같은 오류가 나타나는 경우가 있는데요. 

Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create' 멤버가 필요한 컴파일러가 없습니다

 

우측의 솔루션 탐색기 '참조' 부문에서 마우스 우클릭 후 '참조 추가' 로 참조할 개체를 추가해 주어야 하는데요.

Microsoft.CSharp 

을 추가해주시면 정상적으로 빌드가 진행이 됩니다.

 

막상 포토샵 오브젝트를 추가해 주었지만 실제 실행될 때 C# 에서 포토샵 코드를 작성하는 것이 여간 귀찮은 일이 아닙니다. 그런 경우 미리 javascript 로 필요한스크립트를 작성하여 준뒤 아래와 같이 실행시킬 수 있습니다. 이렇게 하면 실행시 미리 변수를 전달 할 수 있기 때문에 상당히 유연한 개발을 진행할 수 있게 됩니다.

dynamic[] args = new dynamic[2];
args[0] = "test string 1";
args[1] = "test string 2";

dynamic app = Activator.CreateInstance(Type.GetTypeFromProgID("Photoshop.Application"));

String scriptPath = @"D:\test\route_point_extractor_samples\script1.jsx";
string scriptStr = File.ReadAllText(scriptPath);
app.DoJavaScriptFile(scriptPath, args);

변수는 위에 보시는것 과 같이 dynamic 배열 개체를 생성한뒤 필요한 값을 입력해주고 스크립트와 함께 전달하는 방식을 사용하면 됩니다. 

 

 

 

 

포토샵 스크립트 실행 완료 후 반환(리턴) 값이 필요한 경우라면?

무언가 일을 시켰다면 피드백이 있어야 하겠지요? 만들어진 개체의 파일 명이든 무엇이든 간에 어떤 피드백을 받아야 하는 경우 아래와 같이 작성합니다.

 

Javascript (포토샵에서 실행되어야 할 스크립트)

var value1 = arguments[0]; // C# 으로 부터 전달 받는 인자 
var value2 = arguments[1]; // C# 으로 부터 전달 받는 인자

main(value1, value2)

function main (val1, val2)
{
	string myString = "";
    
    // 실제 필요한 계산, 동작을 작성한다.
    
    myString = val1 + "," + val2 ;
	
    return myString; // 이 값이 C# 으로 반환된다.
}

 

C#

dynamic[] args = new dynamic[2];
args[0] = "test string 1";
args[1] = "test string 2";

dynamic app = Activator.CreateInstance(Type.GetTypeFromProgID("Photoshop.Application"));

String scriptPath = @"D:\test\route_point_extractor_samples\script1.jsx";
string scriptStr = File.ReadAllText(scriptPath);

string myResult = app.DoJavaScriptFile(scriptPath, args);

// 결과값은 "test string 1,test string 2" 가 반환된다.

이렇게 해주면 myResult 라는 문자열 변수에 입력한 변수들을 합친 문자열이 반환이 되는것이죠.

어떠신가요? 어렵지 않죠?

 

 

 

 

 

이렇게 하면 C# 으로 빠르고 편리한 이미지 관리 프로그램을 만들어 포토샵으로 강력한 이미지 편집 기능을 함께 이용할 수 있는 기능을 개발 할 수 있습니다. 물론 ImageMagick 과 같은 강력한 이미지 편집 프로그램이 있긴 하지만 이미 만들어져 있는 PSD 파일 등의 레이어속성을 조회하거나 변경하고, 특정 레이어들을 이용하여 어떤 작업을 해야 한다면 ImageMagick 으로는 한계가 있습니다. 

직접 한번 코딩을 해보시면서 테스트 해보시길 바랍니다.

 

궁금하신 부분은 뎃글로 남겨 주시면 답변 드릴 수 있도록 하겠습니다.

이만 포스팅을  마칩니다.

뎃글, 공감 은 블로그 작성자에게 큰 힘이 된답니다. 
도움이 되었다 생각되시면 클릭!!  부탁드려요~

 

 

 

2020/04/03 - [DEV/c#] - ImageMagick 을 이용하여 이미지 컨트롤 해보기

 

ImageMagick 을 이용하여 이미지 컨트롤 해보기

포토샵 없이 이미지를 편집하는 방법이 없을까 고민하다가 알게된 라이브러리, 바로 ImageMagick 입니다. 먼저 포스트에서 ImageMagick 을 프로젝트에 가져오는 방법을 아래와 같이 소개해 드린적이 ��

diy-dev-design.tistory.com

2019/06/21 - [DEV/c#] - [C#] C# .NET 프로젝트에서 ImageMagick 이용하기

 

[C#] C# .NET 프로젝트에서 ImageMagick 이용하기

이미지 관련된 툴을 개발함에 있어 다양한 이미지 포멧을 만들고 변경하기 위한 코어를 개발하는 것은 말도 안되게 힘든 작업입니다. 저는 디자이너라는 타이틀을 가지고 있기 때문에 포토샵이

diy-dev-design.tistory.com

2020/01/03 - [DEV/c#] - [C#] C# APP 에서 엑셀 연동해보기

 

[C#] C# APP 에서 엑셀 연동해보기

엑셀에서 VBA 로 코드를 짜다 보면 막상 특정 엑셀 파일에만 VBA 가 적용이 가능하기 때문에 막상 다른 엑셀 파일에서 동일한 동작을 하려면 또 코드를 복사해 넣고 실행을 해야 하는 경우가 있습�

diy-dev-design.tistory.com

2019/06/10 - [DEV/Adobe Script] - [포토샵 스크립트] 강좌, 무작정 따라해보기

 

[포토샵 스크립트] 강좌, 무작정 따라해보기

어도비 포토샵은 자체 스크립트를 이용하여 다양한 기능을 수행할 수 있는 툴을 지원합니다. 언어는 자바 스크립트 이며 작성된 자바스크립트를 포토샵에서 실행하는 방법과 Extend Script Tool Kit �

diy-dev-design.tistory.com

2020/01/23 - [DEV/Adobe Script] - [포토샵스크립트] 레이어 컨텐츠 영역 선택하기

 

[포토샵스크립트] 레이어 컨텐츠 영역 선택하기

오늘 소개해 드릴 스크립트는 간단한 내용이지만 일반 적인 스크립트상으로 개발이 불가능하기에 경우에 따라는 아주 유용한 스크립트가 되겠습니다. 우리는 작업 중 상당한 빈도로 포토샵 레�

diy-dev-design.tistory.com

 

 

반응형
반응형

여러분들 집에는 작은 텃밭 하나씩 있으신가요? 저는 없습니다만 처갓집에는 작은 비닐 하우스와 텃밭이 있습니다. 요즘처럼 날씨가 가물거나 하우스 안에 텃밭을 가지고 계신 분들은 매일매일 물주기에 바쁘시죠? 물조리에 물을 담아 뿌리는것도 생각보다 큰 일입니다. 물 한통을 부어 봐야 토양의 표면만 살짝 촉촉해 질 뿐 뿌리있는 곳까지 흠뻑 주려면 몇번, 또는 몇 수십번은 왔다갔다 해야 하는 귀찮은 일이지요.

장인어른의 일손을 좀 덜어보고자 넓은 텃밭에 물을 손쉽게 주는 방법이 있을까 하여 찾아본 결과 적당한 아이템을 발견하였습니다.

알리익스프레스에서 2만원도 안되는 금액에 재료를 구입할 수 있었습니다.

총 25m 의 호스와 수도 연결부, 50 개의 T 형 연결구, 50개의 샤워 토출구가 세트로 준비되어 있습니다. 

먼저 물이 나오는걸 테스트 해보았습니다. 음.. 소개페이지에 나온 것처럼 예쁘게 잘 나오는 군요.

 

이제 설치만 하면 됩니다. 기존 수도 역시 사용해야 하기 때문에  T 형으로 나온 분배기를 하나 구입하였으며 한쪽은 벨브가 달린 타입을 구입하였습니다. 벨브가 달린 쪽에 텃밭에 물주는 호스를 연결하게 되면 벨브만 열어주면 텃밭에 물이 공급이 될 겁니다.

 

조립하고 설치하는건 간단 합니다.

생각보다 길이가 긴 호스, 우측의 T 벨브는 온라인에서 5000원 정도면 구입가능하다.

먼저 수도에 연결하기 위하여 사진에 보이는 것처럼 연결해주고, 사진의 우측 하단에 보이는 T 형 벨브타입 소켓을 연결해 줍니다.

기존의 수도꼭지를 떼어내고 T 벨브를 연결한뒤 다시 수고꼭지를 연결해 줍니다.

수도 파이프와 꼭지에 연결되는 부분은 테프론 테이프를 꼭 감아주자

 

호스에 연결된 소켓은 테프론을 감을 필요는 없다.

벨브를 열면 물이 공급이 되겠지요.

 

원하는 길이만큼 먼저 호스를 길게 자리잡아 봅니다.

그다음 일정한 간격으로 호스를 잘라 구입한 부품중에 T 자 연결부품의 양쪽을 끼워주고 나머지 한쪽에는 물 공급용 마개를 달아주는 거죠.

쭈그리고 앉아 30분 정도 작업을 했을까요?

일단 완성이 되었습니다. 맨 마지막 부분도 역시 마개를 달아주었습니다.

30cm 정도 간격으로 연결해주었다.

마개는 빨간 부분을 돌려서 물이 나오는 양을 조절할 수 있게 되어있습니다. 한쪽으로 돌려 열어주면 나오는 물의 양이 많아 지고 다른 쪽으로 돌리면 물이 아얘 잠기는 방식입니다.

음... 그런데 

샤워기처럼 예쁘게 나온다.

첫번째 토출구만 이렇게 예쁘게 나오는군요. 나머지는 쫄쫄쫄입니다. 

제일 끝부분은 거의 나오지도 않는군요. 

실제 틀어 보니 물이 처음 한개로 테스트할 때와는 사뭇 다른 형태로 분사가 되었습니다. 거의 분사라고 보기 어려울 정도로 쫄쫄쫄 흘러나오네요. 

아마 호스 자체가 너무 얇아 흐를 수 있는 물의 양에 한계가 있고 수압 역시 한계가 있어서 인 듯 합니다.

 

만약 아주 길게 연결을 해야 한다면 좀더 두꺼운 고무 호스를 연결하고 호스 중간중간 구멍을 뚫어 샤워형 토출구를 직결하면 모든 꼭지에 물이 샤워형태로 분사가 될 것 같습니다.

 

이번에 작업한 텃밭은 크기도 크지 않거니와 어짜피 물이 바닥에 스며들고 또 스며들면 점차 전체적으로 땅이 젖을 것 이므로 전체적으로 동일한 양이 나올 수 있게 마개를 돌려 수량을 조절해 주었습니다. 맨 끝으로 갈수록 많이 열어주고 수도쪽으로 올수록 마개를 닫아 주어야 겠지요.

넓지않은 텃밭이지만 한가족 야채는 충분히 공급 가능한 텃밭

 

어쨌든 결과는 만족스럽습니다. 이렇게 하면 이제 더이상 물조리를 들고 화단 이쪽 저쪽을 옮겨 다니며 시간을 버리는 일은 없을 것입니다. 같은 시간에 화단에 잡초도 뽑아주고 관리하는데 더 신경을 쓸 수 있을거라 생각합니다.

 

어떠신가요? 2만원도 안되는 저렴한 금액으로 많은 시간과 노동을 절약할 수 있는 방법. 한번 도전 해 보실까요?

 

나중에 시간이 되면 집안에서 화단 물주기 호스의 벨브를 열었다 닫았다 할 수 있도록 리모컨을 만드는 것도 한번 도전해 볼까 합니다. 아니면 토양 수분센서를 이용하여 수분이 마르게 되면 자동으로 급수를 해주는 시스템도 괜찮겠네요. 이렇게 되면 완전 스마트 팜 아니겠습니까? 

지식을 쌓는 다는건 우리의 삶이 좀더 윤택해 질 수 있도록 바꾸어 나가는 것이라 잠시 생각해 봅니다.

 

2019/06/27 - [DIY/Arduino] - 아두이노를 이용한 간단한 화분 자동 물주기 시스템

 

아두이노를 이용한 간단한 화분 자동 물주기 시스템

얼마뒤면 베트남으로 가족 여행을 떠날 예정입니다. 7박이나 하고 올 예정이므로 집을 비우기 전 준비해야 할 것들이 많습니다. 이것저것 여행준비를 하던 찰나 베란다에 내어 둔 화분이 걱정이

diy-dev-design.tistory.com

2019/10/29 - [DIY/Arduino] - [DIY] 아두이노를 이용한 수경재배 시스템

 

[DIY] 아두이노를 이용한 수경재배 시스템

아두이노는 정말 놀라운 하드웨어가 아닐수 없죠. 우리가 생각하는 이런건 자동으로 해주는거 없나? 이런게 자동으로 되면 좋을텐데... 이런걸 왜 자동으로 안하는거야?? 같은 대부분의 자동화 �

diy-dev-design.tistory.com

2022.05.21 - [DIY/micro:bit] - [DIY] micro:bit - 병아리 부화기 만들어 보기 (초딩도 가능)

 

[DIY] micro:bit - 병아리 부화기 만들어 보기 (초딩도 가능)

딸내미 : "아빠! 할머니 집에서 가져오는 계란은 유정란이야?" 나 : "그럼~. 암탉도 있고 수탉도 있으니 유정란이겠지?" 딸내미 : "그럼 내가 저거 품으면 병아리가 나오는 거야?" 나 : "흠... 아니....

diy-dev-design.tistory.com

 

반응형

+ Recent posts