Exchanger 는 뜻 그대로 쓰레드상에서 두 개의 인스턴스를 교환해주는 역할을 한다. 만약 한쪽의 쓰레드에서만 교환 메소드를 호출한다면 다른쪽에서 교환 메소드를 호출하기 전까지 대기하고 있는데. 이 클래스는 java 의 gc 와 같은 동작에서 사용할 수 있다. 예를 들어 설명하면 다음과 같다. (이해를 돕기 위하여 '요청' 이라는 표현을 사용하였다. 정확히는 교환 대상이 되는 인스턴스 값을 인자로 하는 교환 메소드 호출이다.) 1. 데이터를 '스택에 쌓는 쓰레드' 와, '스택을 비우는 쓰레드' 가 있다. 이 두 개의 쓰레드에는 각각의 '스택' 이 있다. 2. 데이터를 '스택에 쌓는 쓰레드' 는 계속해서 데이터를 자신의 '스택' 에 추가한다. 이 동작을 반복하다 스택이 가득차면 '스택' 교환을 요청하고..
이전 포스팅 '저렴한 RGB LED(WS2812B) 구임/사용기' 라는 포스팅에서 WS2812B 에 대하여 잠깐 소개한적이 있다. 간단한 사용 방법에 대하여 소개를 하지 않아서 본격적으로 사용법에 대하여 소개를 하려고 한다. 우선 구입은 Aliexpress 와 같은 해외 사이트를 추천한다. 글을 올린 시간 기준으로 100개에 약 18달러정도 한다. (http://www.aliexpress.com/premium/WS2812B-100pcs-Heatsink.html?ltype=wholesale&d=y&origin=y&SearchText=WS2812B+100pcs+Heatsink&isPremium=y&initiative_id=SB_20141005041503&isViewCP=y&catId=) 뿐만 아니라 LED ..
우선 CRC 와 CRC CITT 에 대한 설명은 아래 두 사이트에서 볼 수 있다. CRC(cyclic redundancy check) 에 관한 설명, 위키 링크(클릭)CRC16-CITT 에 대한 설명과 코드 페이지 링크(클릭) 보통 구글링을 하면 나오는 CRC 코드는 CRC 값 계산을 위한 테이블을 미리 생성하거나 코드에 포함시키기 때문에 아두이노에 올리기에 부담스럽다. 아두이노 UNO 의 메모리 크기는 달랑 2Kbyte 밖에 안 되는데 CRC 값 계산을 위한 테이블은 이론상 512byte 씩이나 되기 때문이다. (실제로는 좀 더 작은 크기를 점유하고 있다.) SRAM을 직접 연결하거나 메모리 쉴드를 달면 조금 나아지겠지만, 일단 그냥 올리기에는 부담스러운 것이 사실이다. 그래서 인터넷 이곳 저곳에서 긁..
우선 AndroidManifest.xml 에서 액티비티를 설정할 때, 속성값으로 액티비티 활성화/비활성화 값을 줄 수 있다. 만약 액티비티 비활성화를 한다면, Context 내의 startActivity 메소드를 이용하여 비활성화 된 액티비티를 호출시 앱은 ActivityNotFoundException 을 발생시키고 크래쉬가 발생하게 된다. 또 런처에서 실행시키기 위하여 내부의 설정 앨리먼트 로 과 옵션을 지정해줬다고 해도 런처내에 액티비티의 아이콘이 표시되지 않는다. 그리고, 이 것을 Manifest 파일에서만이 아닌 코드상에서도 PackageManager 의 setComponentEnabledSetting 으로 제어할 수 있다. 사용법은 무지 간단한데, 만약 Activity 내부에서 호출한다면 다음과..
CyclicBarrier 를 사용하면 동시에 실행되는 쓰레드 내부 원하는 지점에서 대기를 걸어주고 모든 쓰레드가 대기 상태에 들어갔을때, 대기를 풀어주는 동작을 할 수 있다. 예를들어 설명하면 N 개의 쓰레드가 돌고 있다고 가정하고 CyclicBarrier 를 생성할 때 인자값으로 N 을 준다. 각각의 쓰레드 내에서 CyclicBarrier 의 await() 를 호출하고 호출 횟수가 N번에 도달했을 때, N개의 모든 쓰레드의 대기 상태가 해제된다. 아래 그림 참고. 설명이 조금 애매한데, 그냥 대충 보고 눈치것 이해하는 것이 좋다. CyclicBarrier를 활용한 예제코드:public class main { private final static int THREADS = 5; private static ..
만약 백그라운드에서 실행되고 있는 싱글 쓰레드가 종료되기를 기다리는 코드를 작성해야 한다면 당장 Thread 클래스의 join() 메소드 부터 떠올리게 될 것이다. 아래와 같이 말이다. 간단한 join() 사용예:Thread thread = new Thread() { @Override public void run() { System.out.println("start trhead."); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("end trhead."); } }; thread.start(); try { // 스레드가 끝날때 까지 대기한다. thread.join();..
이전에 알리 익스프레스에서 구입한 OLED 사용기(http://dev.re.kr/47)에서 OLED 제어에 대하여 간략하게 올린적이 있습니다만 그것보다 더 편리한 u8glib 사용에 대하여 정리해 보도록 하겠습니다. 좀 더 자세한 튜토리얼과 레퍼런스는 이 곳 https://code.google.com/p/u8glib/wiki/u8glib?tm=6 페이지 에서 확인 할 수 있습니다. 우선 제어하려고 하는 OLED 가 SPI 로 통신하는지 I2C 로 통신하는지부터 알아야 하며, 내장 컨트롤러에 대한 정보도 알아야 한다. OLED 를 판매하는 인터넷 쇼핑몰 페이지의 상세 정보나 데이터시트를 참고하거나, 모델명으로 구글링해보면 OLED 컨트롤러에 대한 정보를 얻을 수 있다. 지금 테스트 해보려는 OLED 는 아..
3V 를 소비하는 LED 가 있다고 가정해 보자. 이 LED 의 밝기를 제어하기 위하여 전압을 변경할 수 있지만, 좀 더 간단한 방법으로 아두이노의 PWM 제어 기능을 이용하여 밝기를 조절할 수 있다. 만약 LED 에 전류를 1초간 공급했다가 다시 1초동안 끊고 또 다시 1초간 공급하는 과정을 반복한다면 우리 눈에는 LED 가 깜빡거리는 것으로 보인다. 하지만, 0.1 초 간격으로 신호를 끊고 다시 연결하고를 반복한다면 우리눈에는 LED 밝기가 원래 밝기에 비해 좀 어둡게 출력되는 것으로 보일 것이다. 이런 신호 폭을 조절하여 LED 의 밝기를 제어할 수 있다. PWM 제어에 대한 자세한 설명 : http://www.hanbit.co.kr/network/view.html?bi_id=1087 아두이노 우노..
우선 가장 간단한 방법으로는 ActivityManager 를 사용하는 방법이다. 그러나 이 것으로 현재 메모리상에 생성된 Activity 의 객체들을 가져올수도 없고 매니페스트에 퍼미션도 줘야 하는데 영 찜찜하다. 다른 개발자들은 동적으로 ActivityStack 에 있는 액티비티의 인스턴스를 어떻게 가져오나 궁금하여 스택 오버플로우를 찾아봤는데, 많은 개발자들이 Application 클래스를 상속받아 이 곳에 Activity를 관리하는 별도의 리스트를 만들어 사용하고 있었다. 하지만 프로젝트마다 이렇게 구현하면 여간 귀찮은 것이 아니라서, 그냥 각 Task 내의 Activity 의 래퍼런스들을 담고있는 리스트를 갖고 있는 싱글톤 객체를 이용하여 ActivityStack 을 구현해 보았다. 우선 코드는 ..
우선 아래 포스팅은 근본적인 해결책이 아니다. 본인 같은 경우에는 드라이버 및 OS 업데이트를 통하여 이 문제를 해결하였다. 맥을 사용하고 OS는 매버릭스를 사용하는 환경에서 이와 같은 문제가 발생한다. (어쩌면 윈도우에서도 발생할지 모르겠다.) 구글링을 해보니 아두이노판 스텍 오버플로우에서 쉽게 찾을 수 있었다. 먼저 이게 드라이버의 문제인지 뭐가 잘못된건지 잘 모르겠지만 FTDI 드라이버를 아두이노에 연결하여 컴파일된 코드를 올리면 다음과 같은 에러가 발생한다. (물론 드라이버는 최신 상태로 업데이트 하였다. 간혹 잘 되는 경우도 있다. ㅡ, ㅡ;;) 아주 열받는 상황이다. 조금 귀찮은 트릭을 사용하여 이 문제를 해결할 수 있다. 우선 상단 메뉴에서 Arduino->환경 설정 을 열어서 다음과 같은 ..
u8glib 라이브러리를 활용한 좀 더 쉬운 OLED 사용법은 http://www.dev.re.kr/51 에 포스팅 해 놓았습니다. 바로 이전 포스팅에 이어서 이번에도 알리 익스프레스에서 구매했다. 6.66$ 나름대로 저렴한 가격이다. I2C 를 사용한다고 하는데, 이 통신 방법에 대해서는 다음 위키 페이지에서 요약된 정보를 확인할 수 있다. http://ko.wikipedia.org/wiki/I%C2%B2C 앞 모습. 보호 필름이 발라져 있다. 뒷 모습. 핀헤더 아래를 보면 Address Select 라고 써져있는 부분이 보인다. 이 부분을 자세히 보자. 주소가 0x78 으로 표시되어 있는데, 각 디바이스마다 고유의 주소 값을 갖고 있고, 이 것을 선택하여 여러대의 I2C 기기를 컨트롤 할 수 있다고한..
(WS2812B 사용법및 예제 소스는 다음 포스팅 http://www.dev.re.kr/57 에서 확인할 수 있습니다.) 뭐를 만드려고 하는데, RGB LED 개 열 개 정도 필요하게 되었다. 좋은 대안은 컨트롤하기 편한 Adafruit 에서 만든 NeoPixel 이 되겠다. 이 녀석은 디지털 출력 포트 하나로 여러 모듈을 동시에 컨트롤 할 수 있다는 것이 가장 큰 장점이다. 하지만, 좀비싸다. ㅠㅠ 알리 익스프레스를 뒤져본 결과 NeoPixel 에 들어가는 WS2812B가 올라간 모듈을 아주 싼 가격에 팔고 있었다. 100개에 17.99달러!! 나는 10개만 필요하기 때문에 불량품이 있을 것을 감안하여 20개를 구입하였다. 무료 배송을 선택하고 2주 하고 5일 뒤에 상품이 왔다.이런식으로 붙어있긴 하지..
약 한 달 전에 알리 익스프레스라는 곳을 알게 되었다. 이전에는 국내에서 구하기 힘든 물건들은 이베이나 아아존 구매대행 사이트나 배송대행 업체를 이용하여 직구하기도 하였는데, 수수료와 배송비의 압박으로 부터 자유롭지 못 했다. 하지만 중국판 아마존인 알리 익스프레스는 달랐다. 중국 소포를 이용한 무료 배송을 해주는 상점이 많고, 제품들도 무척 저렴했다. - 당연히 구매 절차는 매우 간단하다. VISA 카드등 해외 결제가 가능한 체크카드나 신용 카드만 있으면 된다. - 물론 가품이나 문제가 있는 제품도 많아서 마치 확률 높은 도박을 해야한다는 단점이 있다. 인터넷을 뒤져보면 풍부한 구매 후기등이 있는데, 많은 수가 사기를 당하거나 문제있는 제품을 구매했다고한다. - 아마도 물건 구매에 실패한 사람들이 속상..
0. Node.js 튜토리얼 정리한 블로그 (감사합니다.ㅠㅠd) http://nodeqa.com/ 1. Node.js http://www.nodejs.org/ 2. Socket.io http://socket.io/ 3. MySQL 튜토리얼 http://markshust.com/2013/11/07/creating-nodejs-server-client-socket-io-mysql 4. Auto realod http://nodemon.io/ 5. ORM http://sequelizejs.com/ 5. Key value store http://pgte.github.io/alfred/
(android.text.Layout 에 대한 참고 페이지 : http://sudarnimalan.blogspot.kr/2012/06/android-understating-text-drawing.html )우선 항상 아래롤 스크롤되는 TextView 를 만들기 위해 다음과 같은 방법으로 스크롤을 가능하게 만들어줘야 한다. ::스크롤 가능한 TextView 만들기mTextView.setMovementMethod(new ScrollingMovementMethod()); 두 번째로 다음과 같은 메소드를 사용하여 항상 아래로 스크롤되는 텍스트 뷰를 적용할 수 있다. :: 항상 아래로 스크롤되는 TextView 메소드. (TextView 를 상속받는 EditText 에도 적용 가능하다.)private void s..
r글 작성중...
우선 안드로이드 개발 문서를 살펴보자.http://developer.android.com/guide/topics/connectivity/bluetooth.html친철하게도 한글로 번역해놓은 분도 계시다. (감사합니다 b >.< d) http://hardroid.net/profiles/blogs/bluetooth 요즘은 안드로이드 관련 이슈나 API 문서를 한글로 번역해 놓는 분들이 많아서 참 고맙다. 친분이 있다면 치맥이라도 대접해 드리고 싶은 심정이다. 그동안 안드로이드 개발해오면서 사운드 관련 API와 함께 블루투스 관련 API 는 깔끔한 편에 속하는 것 같다. (개인적인 느낌으로는...) UI 관련 API는 멘탈이 강하지 않으면 사용하기 힘들다. 단, 요즘은 3.x 이하 버전을 버리는 추세라서 많이..
1편 HC-06 블루투스 모듈을 설정하는 방법에 이어서 이번에는 안드로이드에 연동하는 방법에 대하여 공유하겠다. 아래는 HC-06 모듈을 달고 있는 아두이노로 메세지를 보내면 그것을 되돌려 받는 안드로이드 앱의 스샷이다. 구글 플레이 스토어 앱 : https://play.google.com/store/apps/details?id=kr.re.Dev.BluetoothEcho Github 안드로이드 프로젝트 소스 : https://github.com/ice3x2/HC-06_Arduino_Echo 우선 안드로이드에서 블루투스를 시리얼 포트 모드로 이용하기 위한 간단한 모듈을 작성 하였는데, 관련 내용은 이 포스팅에서 볼 수 있다. 동작하는 원리는 아주 간단하다. 그냥 안드로이드에서 문자열을 보내면 아두이노에서 ..
무슨 이야기냐 하면은... 우선 아래 두 개의 스샷을 보자.왼쪽은 넥서스S , 오른쪽은 갤럭시 S2 다. (모두 4.1.1 버전이다. ) 이 두 녀석처럼 하드웨어 버튼을 갖고 있을 경우 액션바(Actionbar) 상의 오른쪽에 오버플로우(Overflow) 메뉴 버튼을 띄워주지 않고, 하드웨어 버튼을 누를 경우 우측 사진처럼 아래에 메뉴창을 띄워준다. 전형적인 메뉴 버튼 달린 기기 스타일이다. (요즘 기기들은 하드웨어 메뉴 버튼이 사라지고 액션바 오버플로우 버튼이 그 자리를 대신한다.) 참, 중요한 사실은 그동안 3.x 이하 버전에서도 액션바를 제대로 지원하기 위하여 Support Library 를 사용 할때는 문제가 없었다. 하지만 최소 버전을 4.0 이상으로 설정하면서 SDK 내부의 기본 API 를 사..
Arduino 와 Android 디바이스와의 블루투스 통신을 하기 위하여 다른 모듈 대비 저렴한 HC-06 을 사용하였다. HC-06 블루투스 모듈은 블루투스 2.0 을 사용하고 슬레이브 모드(마스터 모드와 슬레이브 모드가 있다. 슬레이브 모드는 기기를 한 대 밖에 연결하지 못 한다. 관련 설명 페이지)만을 사용하며 가격이 다른 모듈에 비해 비교적 저렴한 것이 특징이다. 또 관련 자료도 많이 접할 수 있다. 옥션 같은 곳에서 12,000 원대에 구할 수 있지만 이베이에서는 국내 판매 가격보다 훨씬 저렴한 가격으로 구할 수 있다. 그냥 HC-06 알맹이만 있는 녀석은 4$~5$ 정도 한다. 다만, 배송비의 압박이 만만치 않다. 나는 5v 로 사용할 수 있는 HC-06 시리얼 모듈을 구입하였다. 모듈을 구입..
우선 테스트 영상. 첫 번째 실습부터 삽질이다. 칩 두이노에 LED 와 스위치를 연결하여 스위치를 한 번 누르면 LED 가 켜지고 다시 한 번 누르면 깜빡 거리고 다시 한 번 누르면 더 빨리 깜빡거리고 마지막으로 꺼지는 것을 만들고자 하였다. 마치 자전거용 전조등처럼 말이다. 추후에 자전거 전조등 자작을 염두에 둔 실습이었는데, 스위치에 좋지 않은 문제가 하나 있었다. 바로 기계식 스위치가 갖고 있는 문제인 바운스 현상이라 하는데, 스위치 내부에 스프링위에 올라간 접점이 붙거나 떨어질때 탄성으로 인하여 한 번 더 붙거나 하는 현상이 다. 아래 그림을 보면 이해가 쉬울 것 이다. 스위치 바운스. 처음에는 본인 직업인 소프트웨어 개발자 답게 코딩으로 딜레이를 주는 방식으로 해결해볼려고 했는데 아무래도 물리적..
요즘 즐겨보는 간행물인 Make 에 보면 아두이노는 꼭 빠지지 않는 단골 소재다. 이 잡지를 보면서 항상 아두이노에 대하여 감탄해왔다. 그리고 최근 결정적으로 아두이노에 입문하게 되게 해준 계기가 있었는데, 바로... 이 녀석들 이다.. 스노보드와 자전거가 취미인 내게 고글에 속도가 디스플레이 된다는 것이 큰 매력으로 다가왔다. 하지만 가격이 적어도 한국 돈으로 40만원 이상 하는 것들이라 가난한 월급쟁이인 저는 좌절 할 수밖에 없었다. 하지만 그 순간! 아두이노가 머릿속에 떠올랐다! 그리고 아두이노와 기기들에 대하여 조사를 해 본 결과 웨어러블 기기를 만드는데 딱 좋은 사이즈인 Cheapduino 라는 좋은 제품을 발견할 수 있었다. 요즘 많이 사용하는 아두이노 우노 R3에 비하여 스팩과 퍼포먼스가 많..
1. AndroidManifest.xml 파일에서 화면 회전을 막고자 하는 해당 액티비티의 엘리먼트에 다음과 같은 속성을 추가. android:screenOrientation="landscape" android:screenOrientation="portrait" 2. Activity 의 public 메소드인 setRequestedOrientation 사용. 런타임 환경에서 강제로 화면을 회전시킬 수 있다. setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
앱을 실행하자마자 아래와 같은 이미지를 띄우고 대략 2~3초 뒤에 메인 화면으로 넘어가는 동작을 구현해 보겠습니다. 우선 가장 무난한 페이스북 인트로 화면을 예제로 잡아보겠습니다. 우선 아래와 같이 인트로로 사용할 이미지를 준비합니다. 저는 가장 무난한 페이스북 이미지에 나인패치를 입혀서 적용했습니다. 화면을 다 덮는 이미지를 사용해도 되지만 intro 화면에 사용될 Drawable 을 정의한 xml 파일을 사용하는 것이 좋습니다. 우선 values 폴더의 style.xml 파일에 다음과 같은 테마를 하나 추가시켜줍니다. 액션바와 타이틀을 제거하고 인트로에 사용될 배경 이미지를 출력하는 테마입니다. 그리고 AndroidManifest.xml 에서 Intro 를 보여줄 Activity 에 해당하는 엘리먼트..
ActionBar 의 View 를 가져올 수 있으며 아래 코드는 Activity 내부에서 사용한 예. private View getActionBarView() { Window window = getWindow(); View v = window.getDecorView(); int resId = getResources().getIdentifier("action_bar_container", "id", "android"); return v.findViewById(resId); } 이렇게 가져온 ActionBar 의 view 를 이용하여 애니메이션등을 구현할 수 있습니다.
자주쓰는 함수라 매번 코딩하기 귀찮아서 올려 놓는다. 아래는 4개의 길이를 갖는 byte 배열을 int 로 바꾸거나 int 를 4개의 길이를 갖는 byte 배열로 바꾸는 것이다.// 아래의 방법 외에 다음과 같이 간단한 방법도 존재한다. :// byte[] byteArray = ByteBuffer.allocate(4).putInt(value).array(); public byte[] intToByteArray(int value) { byte[] byteArray = new byte[4]; byteArray[0] = (byte)(value >> 24); byteArray[1] = (byte)(value >> 16); byteArray[2] = (byte)(value >> 8); byteArray[3] = ..
안드로이드의 Task 내부에는 여러 액티비티들을 갖고 있으며 이 것들은 동일한Affinity 값을 갖고 있고 하나의 스택위에 유지되고 있다. 우선 첫 번째로 동일한 Task 내에서 액티비티를 시작할 때, 자주 쓰이는 플래그값에 대하여 알아보겠다. 아래 설명되는 옵션들은 아래와 같이 사용할 수 있다. Intent intent = new Intent(this, activity.class); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(intent); 참고로 startActivity 는 Context 의 메소드이다. 실제로 어떻게 동작하는지 궁금하여 아래 스샷과 같이 실험 앱을 만들어보고 정리해 보았다. (코드를 너무 날림으로 만들어서 공개..
짜증나는 월요일. 턱을 괴고 무념 무상으로 마우스 오른쪽 버튼을 딸깍딸깍 거리고 있는 지루한 월요일 오전에 간담을 서늘하게 만드는 문자가 한 통이 왔다. 그림1. 또 걸린거야?! ㅠㅠ 어라? 그런데, 링크 주소가 조금 수상했다. 무인단속장비에 적발 되었다는데 URL 은 유사 국민은행? 그림2. 고객님 당황하셨어요 여기서 그냥 넘어갈 수 없었다. 서늘했던 마음이 타오르면서 분노가 들끓었다. 그래서 직접 당해보기로 했다. 물론 테스트용 공기계로. 그림3. 뜬금없는 다운로드. 문자 메세지로 날아온 URL을 통하여 웹 브라우저로 접속하면, 난데없이 APK(앱 설치파일) 을 다운로드 받는다. 그림4. 스미싱앱의 요구 권한ㅡ , ㅡ 위에 표시된 권한 외에 핸드폰 시작시에 자동 시작되도록 하는 권한도 있다. 위 그림..
구글 플레이 서비스가 설치되어 있지 않은 안드로이드 디바이스에서 구글 API (구글 플러스, GCM, 구글 맵, 구글 드라이브등) 를 사용하려고 하면 아래와 비슷한 Exception 을 발생시키며 죽는다. android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=http://play.google.com/store/apps/details?id=com.google.android.gms flg=0x80000 pkg=com.android.vending } 우선 이 문제가 발생하는 이유 첫 번째로 기기에 설치되어 있는 플레이 서비스가 너무 구 버전이거나 또는 아예 설..
(2015년 3월 추가. 지금은 안드로이드 SDK 에서 x86 에뮬레이터를 제공하기 때문에 Genymotion 이 필요 없습니다. ) Genymotion 을 이용하면 Android SDK 에 포함된 느려터진 기본 에뮬레이터 대신 VirtualBox 위에서 돌아가는 x86 기반의 빠른 안드로이드를 이용하여 편하게 개발할 수 있다. 또, GPS와 같은 센서에서 받아오는 값등을 임의로 입력할 수 있고, 네트워크 환경을 다양하게 바꿀 수 있는등 개발에 편리한 기능들을 제공한다. 다만 다음과 같은 단점이 있는데, 이를 유념하여야 한다.- 실제 기기에서 돌아가는 것과 100% 동일하지 않다.- Genymotion 의 안드로이드 에뮬레이터는 x86 기반이므로 arm 으로 컴파일된 NDK 를 사용할 수 없다.- Gen..
- Total
- Today
- Yesterday
- ndk
- 블루투스
- 부트로더
- 칩두이노
- NeoPixel
- 아두이노
- Java
- 침블락
- 스마트 무드등
- json
- activity
- ATtiny85
- 이더넷
- Android
- HC-06
- oled
- 안드로이드 개발
- arduino
- Iot
- 안드로이드
- ESP8266
- 개발
- 알리익스프레스
- Cheapduino
- noidemcu
- 병렬 프로그래밍
- ENC28J60
- WS2812B
- 가습기
- bluetooth
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |