X10을 이용한 가전기기 제어 CGI 프로그램에서...

gnoygnas의 이미지

C로 웹상에서 가전제품을 제어하는 CGI를 구현했습니다..
그중 일부 소스 코드인데, 문제는 전체적으로 화면에 표시해 주질 못합니다.
여기 그림을 포함시킬수 없어 링크 걸어 놓았습니다..

http://www.gnio.net/zboard/view.php?id=gLab2&page=1&sn1=&divpage=1&sn=off&ss=on&sc=on&select_arrange=headnum&desc=asc&no=19

그림에서 보듯이 맨 아래 부분에 그림으로 표시해주어야 할 부분이 태그로 보입니다.

테스트는 Wowlinux 7.1 [gcc 2.96] , BOA 0.94.17 Webserver에서 했습니다.
그런데 이상하게도 gcc 3.2.x 버전에서 컴파일한 Gentoo Linux나 Redhat 8.0에서는 제대로 나옵니다..정말로 컴파일러 버전 차이때문일까요? 제 나름대로 추측....

메인에서 아래 fX10ENTRY()를 호출합니다.

졸업 작품인 관계로 좀 많이 급합니다..
도움 주시면 어떻게라도 후사하겠습니다... :lol:

//----------------------------------------------------------------------------------------------------
// NAME         : fX10ENTRY()
// FUNCTION     : 
// DESCRIPTION  : 전체 LAYOUT 표시하고 해당 값을 출력
//----------------------------------------------------------------------------------------------------
void fX10ENTRY()
{   
	int x;
	int y;
    int houseZone;
    int tmphCnt = hCnt;
	int i = 0;
    int j = 0;
    int count = 0;

    char str[1000];

    // x10.zone의 데이타에 따라 houseZone에 해당값 대입 (0,1,2....) 
    if (strcmp(x10.zone, "mainroom") == 0) {
        houseZone = 0;
    }
    else if (strcmp(x10.zone, "livingroom") == 0) {
        houseZone = 1;
    }
    else if (strcmp(x10.zone, "kitchen") == 0) {
        houseZone = 2;
    }
    else if (strcmp(x10.zone, "smallroom") == 0) {
        houseZone = 3;
    }
    else if (strcmp(x10.zone, "studyroom") == 0) {
        houseZone = 4;
    }
    else if (strcmp(x10.zone, "balcony") == 0) {
        houseZone = 5;
    }
    else if (strcmp(x10.zone, "") == 0) {
        houseZone = 0;
    }    
	
	printf("<div id='Layer1' style='position:absolute; left:385px; top:170px; width:477px; height:333px; z-index:0'>\n");
	printf("<table width='100%' border='0' cellspacing='1' cellpadding='3'>\n");
	printf("<tr align='right'>\n");
	printf("<td colspan='8'><a href='/cgi-bin/x10.cgi?x10.mode=2&x10.zone=%s&x10.houseCode=%s&x10.cmd=auoff'>ALL UNIT OFF</a></td>\n", ptr[houseZone][j]->roomName, ptr[houseZone][j]->houseCode);
	printf("</tr>\n");
	printf("<tr align='center' bgcolor='#eeeeff' height='35'>\n");
	printf("<td width='10%'><font color='000000'>코드</font></td>\n");
	printf("<td width='12%'><font color='000000'>스타일</font></td>\n");
	printf("<td><font color='000000'>이름</font></td>\n");
	printf("<td colspan='2' width='22%'><font color='000000'>제어</font></td>\n");
	printf("<td colspan='2' width='18%'><font color='000000'>밝기 조정</font></td>\n");
	printf("<td width='11%'><font color='000000'>상태</font></td>\n");
	printf("</tr>\n");

		
	// DEVICE
	for (j = 0 ; j < pdev[houseZone].dCnt ; j++) {
		// 넘겨져온 데이타 출력 - 테스트
		printf("PTR1 - [현재의 HOUSE ZONE - houseZone:[%d]-[h.dCnt:[%d] : %s\n<br>", houseZone, pdev[houseZone].dCnt, ptr[houseZone][j]->houseCode);
		printf("PTR2 - [현재의 HOUSE ZONE - houseZone:[%d]-[h.dCnt:[%d] : %s\n<br>", houseZone, pdev[houseZone].dCnt, ptr[houseZone][j]->roomName);
		printf("PTR3 - [현재의 HOUSE ZONE - houseZone:[%d]-[h.dCnt:[%d] : %s\n<br>", houseZone, pdev[houseZone].dCnt, ptr[houseZone][j]->unitNumber);
		printf("PTR4 - [현재의 HOUSE ZONE - houseZone:[%d]-[h.dCnt:[%d] : %s\n<br>", houseZone, pdev[houseZone].dCnt, ptr[houseZone][j]->unitStyle);
		printf("PTR5 - [현재의 HOUSE ZONE - houseZone:[%d]-[h.dCnt:[%d] : %s\n<br>", houseZone, pdev[houseZone].dCnt, ptr[houseZone][j]->unitName);
		printf("PTR6 - [현재의 HOUSE ZONE - houseZone:[%d]-[h.dCnt:[%d] : %s\n<br>", houseZone, pdev[houseZone].dCnt, ptr[houseZone][j]->unitStatus);
		printf("PTR7 - [현재의 HOUSE ZONE - houseZone:[%d]-[h.dCnt:[%d] : %s\n<br><br>", houseZone, pdev[houseZone].dCnt, ptr[houseZone][j]->unitBright);

		// 현재 설정 내용을 본다
		printf("<tr align='center' bgcolor='#eeeeee' height='30'>\n");
		printf("<td>%s</td>\n",ptr[houseZone][j]->unitNumber);

		// UNIT STYLE이 LAMP이면 LAMP 그림 표시하고 APPLIANCE이면 해당 그림 표시
		if (strcmp(ptr[houseZone][j]->unitStyle, "lamp") == 0) {
			printf("<td><img src='/images/main_lamp.gif' border='0'></td>\n");
		}
		else if (strcmp(ptr[houseZone][j]->unitStyle, "appliance") == 0) {
			printf("<td><img src='/images/main_appliance.gif' border='0'></td>\n");
		}
		else {
			;
		}

		printf("<td>%s</td>\n", ptr[houseZone][j]->unitName);

		// 전등을 ON / OFF (POST 방식)
		printf("<td><p align='right'>\n");
		//printf("<a href='/cgi-bin/x10.cgi?x10.mode=2&x10.zone=%s&x10.action=turn&x10.houseCode=%s&x10.unitNumber=%s&x10.cmd=on'><img src='/images/main_device_on.gif' border='0' alt='ON'></a>", ptr[houseZone][j]->roomName, ptr[houseZone][j]->houseCode, ptr[houseZone][j]->unitNumber);
		printf("<form method='POST' action='/cgi-bin/x10.cgi'>\n");
		printf("<input type='hidden' name='x10.mode' value='2'>\n");
		printf("<input type='hidden' name='x10.zone' value='%s'>\n", ptr[houseZone][j]->roomName);
		printf("<input type='hidden' name='x10.action' value='turn'>\n");
		printf("<input type='hidden' name='x10.houseCode' value='%s'>\n", ptr[houseZone][j]->houseCode);
		printf("<input type='hidden' name='x10.unitNumber' value='%s'>\n", ptr[houseZone][j]->unitNumber);
		printf("<input type='hidden' name='x10.cmd' value='on'>\n");
		printf("<input type='image' src='/images/main_device_on.gif'>\n");
		printf("</form>\n");
		printf("</p>\n");
		printf("</td>\n");

		printf("<td><p align='left'>\n");
		//printf("<a href='/cgi-bin/x10.cgi?x10.mode=2&x10.zone=%s&x10.action=turn&x10.houseCode=%s&x10.unitNumber=%s&x10.cmd=off'><img src='/images/main_device_off.gif' border='0' alt='OFF'></a>", ptr[houseZone][j]->roomName, ptr[houseZone][j]->houseCode, ptr[houseZone][j]->unitNumber);
		printf("<form method='POST' action='/cgi-bin/x10.cgi'>\n");
		printf("<input type='hidden' name='x10.mode' value='2'>\n");
		printf("<input type='hidden' name='x10.zone' value='%s'>\n", ptr[houseZone][j]->roomName);
		printf("<input type='hidden' name='x10.action' value='turn'>\n");
		printf("<input type='hidden' name='x10.houseCode' value='%s'>\n", ptr[houseZone][j]->houseCode);
		printf("<input type='hidden' name='x10.unitNumber' value='%s'>\n", ptr[houseZone][j]->unitNumber);
		printf("<input type='hidden' name='x10.cmd' value='off'>\n");
		printf("<input type='image' src='/images/main_device_off.gif'>\n");
		printf("</form>\n");
		printf("</p>\n");
		printf("</td>\n");

		// 전등을 ON / OFF 한다 (GET 방식)

		// LAMP이면서 ON일 경우에만 밝기 조절 가능
		if (strcmp(ptr[houseZone][j]->unitStatus, "1") == 0 && strcmp(ptr[houseZone][j]->unitStyle, "lamp") == 0) {
			printf("<td><p align='right'>\n");
			//printf("<a href='/cgi-bin/x10.cgi?x10.mode=2&x10.zone=%s&x10.houseCode=%s&x10.unitNumber=%s&x10.cmd=dim&x10.val=25'><img src='/images/main_lamp_dim.gif' border='0'></a>");
			printf("<form method='POST' action='/cgi-bin/x10.cgi'>\n");
			printf("<input type='hidden' name='x10.mode' value='2'>\n");
			printf("<input type='hidden' name='x10.zone' value='%s'>\n", ptr[houseZone][j]->roomName);
			printf("<input type='hidden' name='x10.action' value='turn'>\n");
			printf("<input type='hidden' name='x10.houseCode' value='%s'>\n", ptr[houseZone][j]->houseCode);
			printf("<input type='hidden' name='x10.unitNumber' value='%s'>\n", ptr[houseZone][j]->unitNumber);
			printf("<input type='hidden' name='x10.cmd' value='dim'>\n");
			printf("<input type='hidden' name='x10.val' value='25'>\n");
			printf("<input type='image' src='/images/main_lamp_dim.gif'>\n");
			printf("</form>\n");
			printf("</p>\n");
			printf("</td>\n");

			printf("<td><p align='left'>\n");
			//printf("<a href='/cgi-bin/x10.cgi?x10.mode=1&x10.zone=%s&x10.houseCode=%s&x10.unitNumber=%s&x10.cmd=bright&x10.val=25'><img src='/images/main_lamp_bright.gif' border='0'></a>");
			printf("<form method='POST' action='/cgi-bin/x10.cgi'>\n");
			printf("<input type='hidden' name='x10.mode' value='2'>\n");
			printf("<input type='hidden' name='x10.zone' value='%s'>\n", ptr[houseZone][j]->roomName);
			printf("<input type='hidden' name='x10.action' value='turn'>\n");
			printf("<input type='hidden' name='x10.houseCode' value='%s'>\n", ptr[houseZone][j]->houseCode);
			printf("<input type='hidden' name='x10.unitNumber' value='%s'>\n", ptr[houseZone][j]->unitNumber);
			printf("<input type='hidden' name='x10.cmd' value='bright'>\n");
			printf("<input type='hidden' name='x10.val' value='25'>");
			printf("<input type='image' src='/images/main_lamp_bright.gif'>\n");
			printf("</form>\n");
			printf("</p>\n");
			printf("</td>\n");
		}
		// 램프이면서 OFF일 경우에만 보여지는 아이콘
		else if (strcmp(ptr[houseZone][j]->unitStatus, "0") == 0 && strcmp(ptr[houseZone][j]->unitStyle, "lamp") == 0) {
			printf("<td><p align='right'><img src='/images/main_lamp_dim-off.gif' border='0'></p></td>");
			printf("<td><p align='left'><img src='/images/main_lamp_bright-off.gif' border='0'></p></td>");
		}
		// 램프가 아닌 경우
		else {
			printf("<td colspan='2'><img src='/images/main_lamp_none.gif' border='0'></td>");
		}

		// 램프 ON / OFF에 따라 나타나는 그림 색깔이 달라짐 / 램프 ON시 REPEAT 가능
		if (strcmp(ptr[houseZone][j]->unitStatus, "1") == 0) {
			printf("<td><p align='center'>\n");
			//printf("<a href='/cgi-bin/x10.cgi?x10.mode=2&x10.zone=%s&x10.action=repeat&x10.houseCode=%s&x10.unitNumber=%s&x10.cmd=0&x10.val=5'><img src='/images/main_lamp_on.gif' border='0' alt='REPEAT'></a>", ptr[houseZone][j]->roomName, ptr[houseZone][j]->houseCode, ptr[houseZone][j]->unitNumber);
			printf("<form method='POST' action='/cgi-bin/x10.cgi'>\n");
			printf("<input type='hidden' name='x10.mode' value='2'>\n");
			printf("<input type='hidden' name='x10.zone' value='%s'>\n", ptr[houseZone][j]->roomName);
			printf("<input type='hidden' name='x10.action' value='repeat'>\n");
			printf("<input type='hidden' name='x10.houseCode' value='%s'>\n", ptr[houseZone][j]->houseCode);
			printf("<input type='hidden' name='x10.unitNumber' value='%s'>\n", ptr[houseZone][j]->unitNumber);
			printf("<input type='hidden' name='x10.cmd' value='1'>\n");
			printf("<input type='hidden' name='x10.val' value='5'>");
			printf("<input type='image' src='/images/main_lamp_on.gif'>\n");
			printf("</form>\n");
			printf("</p>\n");
			printf("</td>\n");
		}
		else {
			printf("<td><p align='center'><img src='/images/main_lamp_off.gif' width='30' height='31' border='0'></p></td>");
		}

		printf("</tr>\n");
	}

	// 각 ZONE별로 DEVIE 개수를 표시함
	printf("<tr align='right' bgcolor='#eeeeff' height='30'>");
	printf("<td colspan='9'>DEVICES IN THIS SECTION : [%d]&</td>" , pdev[houseZone].dCnt);
	printf("</tr>");
	printf("</table>");
	printf("</div>");
}
[/code]
dg의 이미지

함수끝에다가 fflush(stdout); 추가해보면 혹시 되지 않을까요?

지리즈의 이미지

일단은 웹브라우저에서 소스보기로 해서... HTML소스를 올려 주시면...

보다 편할 것 같구요...

간혹가다... cgi 출력 버퍼 문제로 인해서... 웹서버로 나가는 모든 양의
html코드가 다 안나가고 중간에서 짤려 버리는 경우가 있습니다.

이건 웹서버 메모리 설정(혹은 그때의 웹서버의 컨디션--;;)하고
관련이 되어서 까다롭구요...
중간이 잘려나간다면... iframe이나 다른 frame을 사용해서.
표준 html이나 php와 섞어 사용하여 cgi가 출력하는 html의 양을 줄이는 것도
방법입니다.

There is no spoon. Neo from the Matrix 1999.

지리즈의 이미지

음 천천히 생각해보니... 2.96문제인것 같은 생각도 드네요...
저도 비슷한 경험을 한 적이 있어서...

일단... 소스가 넘 기네요...
이정도 길이의 소스리면... (2.96에서)한 오브젝트로 생성한다음...
실행시 코어덤프할 가능성도.. 있어보이군요...
cgi니까 콘솔에서 실행시킬때 출력이 다되는지 확인해 보세요...
foo@bar $./xx.cgi > result.html

혹시 core가 생성된다면... 쪼개야 겠네요...

내부에서 중복되는 내용은 따로 함수를 만들고 다른 오브젝트에서
불러와야 할 것 같군요...

There is no spoon. Neo from the Matrix 1999.

gnoygnas의 이미지

위에 dg님이 알려주신대로 fflush(stdout);를 함수내 가장 아래에 넣어주니
문제는 쉽게 해결이 되었습니다.. (근데 이 함수의 역활은 무엇인지요?)

알고보면 해결책은 별거 아닌데, 이것때문에 고생하고 생쑈한걸 생각하면...ㅠ.ㅠ

지리즈님께도 감사드립니다...

직접적으로 해결책을 알려주신 dg님...
이글 보시면 제 email로 연락처 알려주세요...
gnoygnas at hotmail.com

책이라도 한권 선물해 드리죠...^^

좋은 하루 되세요~

One must, In fact, Love your pursuit
My home is below...Well, just go own your gait!

maximus의 이미지

c로 cgi 를 짜게 되면 버퍼 문제로 인해 제대로 페이지가 안보이는 경우 생기더군요..

fflush(stdout) 은 현재 버퍼에 있는 내용을 표준출력으로 출력(비우는)하는 명령입니다..

printf 문이 실행되더라도 시스템 환경에 따라 실제 출력시 버퍼에 다 차게 될때 까지 기다리는듯 합니다..

그래서 마지막에 그런 명령을 주어 버퍼에 남기지 말고 다 출력 토록 하는것일것 같습니다..

아시겠지만 CGI 에서는 표준출력이 웹서버 process 로 향하게 됩니다..

=================================
:: how about a cup of tea ? ::
=================================

gnoygnas의 이미지

이 문제 때문에 헛다리 집고 고생한거 생각하면.....한숨만 나옵니다.

얼른 문제 해결해야 하는데,,,얼른 해야 하는데,,, 하면서
자다가도 생각하고.....
얼마나 소스를 부라리고 쳐다보았는지, 다 외울 지경이었습니다...^^
결국은 여기에 한번 도움을 부탁드려볼까 적어 본것이
해결의 실마리를 찾게 되었습니다...

역시 아는것이 시간 절약이고, 헛고생 하지 않는 길인가 봅니다...

fflush(stdout)은 시간이 지나도 잊혀지지 않겠네요...

모두 감사드리고, 저도 많이 알아서 도움주는 이가 되고 싶네요... :lol:

One must, In fact, Love your pursuit
My home is below...Well, just go own your gait!

gnoygnas의 이미지

그런데 한가지더 궁금한 것이 있다면....
레드햇이나 젠투 리눅스에서는 아무 문제없이 되지만, 유독 와우 7.1에서만
이 문제가 발생합니다...이는 어느 특정 부분이 달라서 (커널이라든지, bash_profile).....발생할 수 있다는 것을 추측할 수 있는데 구체적으로 알고 싶네요..

위에 maximus님께서도 시스템 환경에 따라 달라질 수 있다고 말씀하셨듯이..

어느 부분을 체크해 보면 될까요?

One must, In fact, Love your pursuit
My home is below...Well, just go own your gait!

lobsterman의 이미지

오..멋지군요...
제가 취미겸 공부겸 집에서 가전제품제어를 하려고 시도를 하려고 하고 있는중인데요
예전에 전 php로 제어를 하려고 했는데...
기본적으로 배포되어진 소스에다가 실행조건만 php로 제어하려고 했지요...
잠시 손을 놓아둔상태인데...
졸업하시고 나시면 소스배포를 하실계획은 있으신지요?
저두 한번 써보고 싶네요...만들어논 circuit 모듈은 있읍니다만. 내부나 외부에서 텔넷이나 터미널로 제어를 하거든요...제어환경 감시는 캠을 통해서 하구요...ㅋ

무한한 상상력과 강한실행욕구는 엔지니어의 마지막 무기~

choissi의 이미지

마지막에 printf("</div>"); 를
printf("</div>\n");
하면 원하는 바를 얻을수 있을꺼 같네요..

울랄라~ 호기심 천국~!!
http://www.ezdoum.com

gnoygnas의 이미지

Quote:

오..멋지군요...
제가 취미겸 공부겸 집에서 가전제품제어를 하려고 시도를 하려고 하고 있는중인데요
예전에 전 php로 제어를 하려고 했는데...
기본적으로 배포되어진 소스에다가 실행조건만 php로 제어하려고 했지요...
잠시 손을 놓아둔상태인데...
졸업하시고 나시면 소스배포를 하실계획은 있으신지요?
저두 한번 써보고 싶네요...만들어논 circuit 모듈은 있읍니다만. 내부나 외부에서 텔넷이나 터미널로 제어를 하거든요...제어환경 감시는 캠을 통해서 하구요...

이렇게 칭찬을 해 주시니.... :oops:

3명이 팀을 이뤄 졸업 작품을 진행했습니다.
모두의 동의가 있어야지만 소스 배포가 가능할 것으로 보입니다...

잠시 소개를 하자면...
기본적으로 X10이라는 전력선 모듈로 웹상에서 제어를 합니다. 물론 텔넷을 통해서도 가능합니다.
모든 가전기기를 ON/OFF 할수 있고, 램프는 밝기 조절까지 가능합니다.

전력선을 이용하므로 별도의 IP를 필요로 하지 않는게 장점이라 할수 있겠네요.....

이 프로그램이 CGI로 되어 있어서 제약이 있네요..(몰라서 제대로 구현 못한거겠죠...) 아직 고칠게 수드륵.....

그럼 모두 좋은 하루 되세요~

One must, In fact, Love your pursuit
My home is below...Well, just go own your gait!

gnoygnas의 이미지

One must, In fact, Love your pursuit
My home is below...Well, just go own your gait!

lobsterman의 이미지

밝기 조정도 가능하군요...저와 비슷한것을 진행하시는군요...고민이 하나 더 늘었네요...밝기조정을 어찌 해야 될런지...
x10 이라는 것이 크기가 아담한것이 작군요...(전력선 제어는 첨 보는군요...)
전 리눅스 서버로(pda 접근이 용이하거더요.) 가전기기제어한답시고...무식하게 파워릴레이를 이용했어요...열었다 닫았다 하면 철컹철컹 합니다...^^;;;
저두 첨엔 담배갑만 하게 작게 만들려고 리드릴레이를 구하러 댕겼었는데... 국내에는 파는곳이 없어 동내방내 다돌아댕겼지요...결국 국내 수입품이 있긴하더군요...
그런데 제가 아는 분이 조언하기를 높은 전압의 제어를 하려면 릴레이 점접이 커야지 된데요...냉장고나 밥솓제어하려면 접점이 작아서 타거나 녹아버린다는 말에 겁을 먹구서 파워릴레이를 선택했었는데...그것두 작다고 하더군요... 중간에 교류전자계패기를 하나 더 달아라는 말에 고개를 절래절래 저었어요...그리 큰 전압제어를 하는 것은 아니니깐...괜찮을 것이라고 생각을 합니다...나중에 타버리면 하나더 만들 각오를 하고 말이지요... 전 페러렐 병렬로 연결해서 전원부도 마찬가지로 배선이 쉡게 병렬로 제어를 하는 방식입니다.(8개 제어 또는 선점적인 16개 제어가 가능해요...)
아직 남아도는 8개 짜리 코드가 없어 만들지 않았지만요...^^;;;
8개를 코드로 분배하기는 아까워서 캠에 릴레이 한개(캠 2개 제어가능) 또나머지는 조명제어에 2~3개 나머지는 코드 이런식으로 배분을 할 계획입니다.
TV리모콘으로도 제어를 하려고 합니다.(누워서 켰다 끌려고...)
제 서버가 너무 구형보드라 그런지 IRDA 제어를 하려는 시리얼쪽에 디바이스 컴파일이 안되 애먹고 있읍니다.
어쨋든 저와 같은 것을 진행하는 분을 보니 방갑군요...ㅋ

제가 진행하고 있는 참고 사진은

http://bbs.kldp.org/viewtopic.php?t=21866

입니다.

무한한 상상력과 강한실행욕구는 엔지니어의 마지막 무기~

gnoygnas의 이미지

무에서 유를 창조하는 님이 진정한 엔지니어이십니다... :D

저는 X10 모듈이라는 것을 가지고 고작 Device 드라이버, 웹 CGI, Embedded Gateway 등을 하는데, 님은 뭔가 크게 다르네요.....

배선 박스 사다가 릴레이 붙이고, 회로 만들고, 부품 구하기 조차 어려웠을 텐데....휴~ 쉬운일이 절대 아닌데...
어떻게 이런걸 만들 생각을 다 하셨는지 존경스럽네요...

Quote:
가전기기제어한답시고...무식하게 파워릴레이를 이용했어요...열었다 닫았다 하면 철컹철컹 합니다...^^;;;
저두 첨엔 담배갑만 하게 작게 만들려고 리드릴레이를 구하러 댕겼었는데... 국내에는 파는곳이 없어 동내방내 다돌아댕겼지요...결국 국내 수입품이 있긴하더군요...

파워 릴레이라 하면 저도 어떤것인지 아는데 무접점 전자릴레이를 사용해보면 어떨까요? 그거 용량도 꽤 크고 무접점이다보니 소리도 안날테고....그냥 생각나서 한번 적어봅니다..

암튼...조금은 다르지만, 저와 비슷한 프로젝트를 진행하시는 분을 만나니 반갑기 그지 없네요...서로 정보 공유하면 어떨까요? 진행하는 프로젝트의 관련 매뉴얼이던지, 자료를 정리해서 제 웹페이지에 올릴 예정입니다...(1달이내....~~)

좋은 하루되세요~

One must, In fact, Love your pursuit
My home is below...Well, just go own your gait!

지리즈의 이미지

실제 필드(공장, 산업용 실험실)에서는
NI나 advantech사의 DIO 보드를 많이 사용합니다.

NI같은 경우는 리눅스용 드라이버가 꽤 나와 있습니다.

국내에서는 SENA와 같은 회사가 온라인으로 계측기 제어에 대해서
연구를 많이 했었으나, 아직 까지는 시장성이 없더군요...

대신 SENA는 TCP/IP <-> Rs232(UART) 컨버터 제품을 활용한 여러
제품들을 내놓아 시장을 개척하고 있습니다.

웹컨트롤(WebControl)이라는 계획으로 전에 근무하던 회사에서
연구했는데... 역시 자본력있는 대기업에서 손대면 끝이더군요...
사업성이 없어서 프로젝트도 접고, 지금은 퇴사해서 다른 회사에서
근무하고 있습니다.

개인적으로 비교적 기발한 아이디어가 많이 있었은데...
혹시 관심있으시면... 이곳에 글을 올려주세요.

There is no spoon. Neo from the Matrix 1999.

lobsterman의 이미지

진정한 엔지니어라니 정말 과찬의 말씀이십니다... :oops:

호기심 많은 삼질맨이라고 보시면 되겠네요...

SSR을 붙이려고도 해봤읍니다...(가격이 원채 비싸서 취미로 하기에는 제 용돈내에서 해결하기에는 좀 아깝더라구요...ㅋ)

Quote:
저와 비슷한 프로젝트를 진행하시는 분을 만나니 반갑기 그지 없네요...서로 정보 공유하면 어떨까요?

저두 여기저기 뒤지며 자료를 뒤져 보았지만 많은 자료를 구할수 없어 HOWTO 문서를 기반으로 나머지는 나도 알 수 없는 나의 자그마한 기량으로 지지고 뽁는 스타일이라서...자료공유에 대한 내용은 정말 좋은 생각일 것 같읍니다.

일반적인 시험기기와는 달라 실용적인면이 있어 일반적인 생활하면서 써먹을 수 있는 것이 가전기기제어의 매력인것 같읍니다. 내가 만들었음 이라는 자부심도 생기구요...ㅋ

전 이 아이템에 대해 사업성을 따져 생각해 보진 않았지만...HOME MADE라는 매력적인면도 있어 그리 어렵게 생각을 해보진 않았읍니다. 제 공부도 되구요...

단점은 무한삽질을 해야지 된다는 경우도 생기지만 직장생활을 마치고 나머지 여유가 생기면서 나만의 프로젝트를 진행해도 충분하다고 생각이 들더라구요...

또 단점은 이런거 집에서 진행하면 불안전한 시험이 이루어진다는 것이지요...
나름데로 배선을 잘했다고 하더라도 "퍽"하면 서버고 머고 홈페이지고 머고 다 날라 간다는 생각을 해본적도 있읍니다....^^;;;
좀 스펙타클합니다만...

그래도 단점보다는 장점이 많은것 같더라구요...

어찌 되었던 gnoygnas님과 같은 분은 만나니 방갑읍니다.

지리즈님의 좋은글도 감사합니다.

무한한 상상력과 강한실행욕구는 엔지니어의 마지막 무기~

지리즈의 이미지

ON/OFF와 전력량을 조절하는 것으로 가전기기를 제어하는 것에는
한계가 있더군요...

조명이나 장치를 키고 끄는 이상외에는 거의 없으니깐요...
물론 커튼이나, 창문단기와 같은 모터제어도 여기에 포함이 되겠지요...
하지만... 이런 것들은 기본설비를 크게 바뀌어야 하는 단점이 있습니다.
비용이 들고, 건축후반이나, 내장 당시 고려가 되어야 하지요....

반면... 더 싸고 간편하면서도 많은 가전제품을 제어할 수 있는
방법이 있습니다.

바로 리모콘을 장악하는 것이지요...

실제로 우리들 주변에서 많은 리모콘을 지원하는 가전제품들이나와 있고...
(심지어면 벽에 붙어 있는 조명 스위치에 리모콘센서가 붙은 제품도
나오고 있습니다.)
우린 이 장치들을 움지이는 리모콘의 적외선(혹은 전파)의 주파수 특성만
알아내고 쏘면 되지요. 또 선이 필요하지 않다는 장점도 있습니다.

전에 PDA제품 중에 적외선 전파특성을 복사할 수 있는 기능을
가진 것들이 있었는데...
이걸 자동차 훔치는데 사용한다는 글을 읽은 적도 있습니다. ^^;;

당분간 만약 이 분야로 본격적인 사업으로 뛰어 든다면...
이쪽으로 접근하는 것도 좋을 것 같습니다.

There is no spoon. Neo from the Matrix 1999.

lobsterman의 이미지

우선 lirc라는 프로젝트가 있는데...적외선 수신기를 간단히 집에서 만든 후

시리얼로 연결한 다음 일반적인 TV리모콘으로 IRDA제어가 가능합니다.

그냥 프레젠테이션 페이지 넘기기나 리눅스박스로 TV카드로 시청시 채녈변경인데요...

가전제어기를 사용하면 선풍기와 전등의 가전제품제어가 가능합니다.

가만히 누워서 말이지요...

TV리모콘 -> IRDA interface -> 리눅스박스 -> RS-323 ->가전모듈 -> 가전기기

머 간단히 콘센트나 이런걸 튜닝하면 내장안해도 되구요....전선 몇가닥만 튜닝하면 끝~ 이에요..

그런데...현제 컴파일이 안되어서 삽질중인데요...

lirc의 프로젝트 주소는 http://www.lirc.org/ 입니다.

내부에서는 TV리모콘으로도 제어가 가능합니다.

외부에서의 제어는 리눅스서버 기능을 이용하구요 PDA의 인터넷을 통해서 미리 밥솥이나 난방시스템 등등을 켜놀수 있구...화상감시도 가능하겠어요...
wince에 넷미팅기능이 있는지요? 아니면 리눅스기반 PDA에서 그놈미팅이나 리얼서버를 이용하면 되겠구요...
도둑이 들어올수 없게 미리 적당한 시간에 전등도 켜놓구(장기간 출장시...) 머 중국이나 미국에서도 이동통신이 되면 제어가 가능하겠네요...
또 집에 있는 강아지밥주는 기계 이런거 만들어도 되겠지요...ON하면 사료가 주르르..하고... 다시 OFF하면 주르르 쏫아지던것이 복귀되는 그런 형식으로 말이지요....^^;;;
또 내부적으로도 PDA로 제어할려면 자체적인 IRDA를 이용할수도 있읍니다. 그럼 IRDA 수신부의 제작비용이 좀 높아질것 같더군요...

대충 가전제어가 가능한 접근방법을 설명했는데...완전하게 이루어 장착되려면 시간이 많이 걸리겠지요...?

무한한 상상력과 강한실행욕구는 엔지니어의 마지막 무기~

ahearf의 이미지

저도 비슷한 일을 하려고 합니다...

일단 기본적으로 리눅스를 기반으로 시리얼 통신을 이용하여 여러 가전기기들과

기타등등(홈네트워킹)을 제어하고싶은 와중에 이글을 보게되어서

염치 불구 하구 도움을 구하고자 이렇게 한자 올립니다..

항상 윈도우 프로그램만 짜오다가 리눅스로 갑자기 짜게 되어서 막막하네요

윈도우프로그램(기본적으로 MFC) 의 경우에는 comm 등을 사용해서 쉽게(?)

구현이 가능한데 리눅스에선 어떤식으로 그부분들을 처리하는지...

그리고 어떤 문서나 서적을 이용하면 좀더 쉽게 접근이 가능한지...

아차~~~ 한가지더 그리구 메인 폼은 efltk를 사용해서 구현하려구 하구요

이것 역시 막막하기만 하네요~~쉽게 지원이 가능한 윈도우하곤 엄청다르니..

시작부터 어질어질합니다... 그럼 좋은 하루 되세요~~

lobsterman의 이미지

우선 리눅스에서는 기본적인 시리얼이 아닌 페러렐의 병렬포트를 기본적인 베이스를 이용합니다.
만약에 시리얼을 베이스로 사용한다면 마이크로 콘드롤러와 PIC베이스의 부가적인 제어장치가 동원이 되어야지 될것 같은데요...엄청 복잡해 지지요...하지만 섬세하게 작동이 될것 같은데요....PC에서의 가정에서의 제어는 그러한 정교함까지 필요한지 생각해 보지 않았지만 만일에 시험기기나 장비를 이용할시에는 아마도 적당할것 같읍니다.
리눅스에서는 parport_pc lp의 기본적인 커널모듈로 on/off제어를 합니다.
시리얼쪽은 내부의 제어 수신부 베이스로 이용을 하면 좋을겉 같구요...
순수하게 TCP/IP만을 이용하면 효용성이 떨어질것 같구요...
IRDA와 같은 적외선 수신부를 달면 한층더 좋은 인터페이스가 될것 같네요.
문서는 HOWTO문서를 뒤져보시면 되겠구요....

무한한 상상력과 강한실행욕구는 엔지니어의 마지막 무기~

dorado2의 이미지

ahearf wrote:
저도 비슷한 일을 하려고 합니다...

일단 기본적으로 리눅스를 기반으로 시리얼 통신을 이용하여 여러 가전기기들과

기타등등(홈네트워킹)을 제어하고싶은 와중에 이글을 보게되어서

염치 불구 하구 도움을 구하고자 이렇게 한자 올립니다..

항상 윈도우 프로그램만 짜오다가 리눅스로 갑자기 짜게 되어서 막막하네요

윈도우프로그램(기본적으로 MFC) 의 경우에는 comm 등을 사용해서 쉽게(?)

구현이 가능한데 리눅스에선 어떤식으로 그부분들을 처리하는지...

그리고 어떤 문서나 서적을 이용하면 좀더 쉽게 접근이 가능한지...

아차~~~ 한가지더 그리구 메인 폼은 efltk를 사용해서 구현하려구 하구요

이것 역시 막막하기만 하네요~~쉽게 지원이 가능한 윈도우하곤 엄청다르니..

시작부터 어질어질합니다... 그럼 좋은 하루 되세요~~

저도 어느 정도는 이와 관련된 작업을 하고 있습니다.

전력선 모뎀 기반으로 가전 기기 제어를 하는데, serial port랑 전력선 모뎀이 연결됩니다.

저는 하드웨어 쪽이 아니지만,
제어 어플리케이션을 java base로 개발 중인데, 하드웨어는 그렇다 치고 serial 제어는 정말 쉽습니다.(parallel도 마찬가지입니다.)

javax.comm 라이브러리를 가져다 쓰면, 금방 구현하실수 있을겁니다.
참고로 arm-linux에서 개발하고 있습니다.

지리즈의 이미지

lobsterman님께서 올려주신 http://www.lirc.org/ 사이트 열심히
뒤져보고 있습니다. ^^

cross/platform을 지원하는 comm library에 관한
언급이 종종 되어지더군요...

하드웨어에 대한 제어는 드라이버 레벨이라..
운영체제에 종속되어 cross/platform을 지원하는 경우가 거의
없는 것으로 보이지만....

예외도 있지요...
바로 Network에 관련된 라이브러리들인데...
여기에 관련되는 cross/platform 라이브러리들이 꽤 나와있습니다.

만약 efltk와 같이 cross/platform을 염두에 두신다면...
먼저 선행되어저야할 것이 serial(comm)에 대한
cross/platform library의 작성인 것 같습니다.

물론 자바로 개발된다면... 필요없어지겠지요. ^^

There is no spoon. Neo from the Matrix 1999.

gnoygnas의 이미지

lobsterman님께서 알려주신곳을 가보았는데, 처음봐서 그런가 어떻게 구성이 되어 제어가 되는지 생소하네요..

데몬으로 돌아가는 것을 이용해서 뭔가를 한다는건 짐작하겠는데,
구체적으로 IRDA를 어떻게 제어하나요? 머리속에 그림이 그려지질 않는군요~ ^^

One must, In fact, Love your pursuit
My home is below...Well, just go own your gait!

lobsterman의 이미지

쉽게 생각하시면 됩니다.
TV리모콘에 기본적인 IRDA수신부를 제작하여 드라이버 설치 후 정해 놓은 명령어로 실행을 하게 되는데...리모콘 1번 눌리면 xmms뜬다...2번 눌리면 CD-ROM배출 3번 눌리면 CD-ROM mount...
이런식으로 진행이 되지요...
또 다른식으로 접근을 하자면...가전제어기를 붙여논 상태애서 1번눌리면 현관의 전등(1번 릴레이) 2번 눌리면 내방의 전등(2번 릴레이) 3번눌리면 콘센트1번쪽 연결된 선풍기 (3번 릴레이) 4번 눌리면 콘센트 2번쪽 연결된 거실 에어컨(4번 릴레이)...기타(~8번 릴레이) 이런식으로 제어가 가능합니다.

지리즈님 말씀데로 cross/platform을 논의하신데로 리눅스에서 lirc는 드라이버에 대한 지원은 되는데...기본적인 시리얼 커널모듈이 지원되지 않는것 같군요...아~정말 인식시키기 어렵군요...
커널컴파일을 해야지 될것 같은데...
lirc를 실제적으로 설치해보신 분 계신지 모르겠어요...
이글을 보시고 lirc 설치에 성공하신분 답변 부탁드리겠읍니다.(현제 수신부는 연결되어 있는 상태입니다.)
추신 : 결정적으로 lirc 설치성공에 보답하신분 께는 IRDA 수신부 부속을 보내어 드리겠읍니다.^^v

무한한 상상력과 강한실행욕구는 엔지니어의 마지막 무기~

lobsterman의 이미지

우선 저의 사양은 레드헷9커널에 커널업데이트를 하지 않은 상태입니다.
(커널버전 2.4.20-8) 그리고 보드는 via 보드구(-,.-;;) 팬II 233(over266) 메모리 256

cmos에서 com2 닫은상태입니다.

설치는 cvs에서 최신버전 받아다가 설치했읍니다.
cvs -d:pserver:anonymous@cvs.lirc.sourceforge.net:/cvsroot/lirc login

컴파일 순서는

./autogen.sh
./setup.sh
(1. Driver configuration (driver:serial io:0x3f8 irq4 -> 1  Home-brew (16x50 UART compatible serial port)  -> (X) 1  COM1 (0x3f8, 4)  -> [X] 2  Software generated carrier -> 3  Save configuration & run configure  )
make
make install 
순서인데요...

/etc/modures.conf 화일에

alias char-major-61 lirc_driver

드라이버 모듈을 올렸읍니다.

그리고 xmode2 실행을 하면

xmode2: No such device
xmode2: error opening /dev/lirc

라고 드라이버를 찾지못하는군요...

/dev/lirc 퍼미션을 666으로 준 다음

화일목록 상태입니다.

[root@lobsterman root]# ls -al /dev/lirc
crw-rw-rw-    1 root     root      61,   0  8월 17 22:13 /dev/lirc

[root@lobsterman root]# lsmod
Module                  Size  Used by    Not tainted
tuner                  11808   1  (autoclean)
bttv                   74176   0  (autoclean)
i2c-algo-bit            8872   1  (autoclean) [bttv]
i2c-core               19172   0  (autoclean) [tuner bttv i2c-algo-bit]
videodev                8288   2  (autoclean) [bttv]
sb                      9204   0  (autoclean)
sb_lib                 44686   0  (autoclean) [sb]
uart401                 8388   0  (autoclean) [sb_lib]
sound                  74228   0  (autoclean) [sb_lib uart401]
soundcore               6404   5  (autoclean) [bttv sb_lib sound]
ipt_MASQUERADE          2200   1  (autoclean)
ipt_LOG                 4152   1  (autoclean)
ipt_state               1048   1  (autoclean)
ip_nat_ftp              4112   0  (unused)
iptable_nat            21720   2  [ipt_MASQUERADE ip_nat_ftp]
ip_conntrack_ftp        5296   1
ip_conntrack           26976   3  [ipt_MASQUERADE ipt_state ip_nat_ftp iptable_nat ip_conntrack_ftp]
parport_pc             19076   1  (autoclean)
lp                      8996   0  (autoclean)
parport                37056   1  (autoclean) [parport_pc lp]
autofs                 13268   0  (autoclean) (unused)
ppp_synctty             7904   0  (unused)
ppp_async               9440   1
ppp_generic            24444   3  [ppp_synctty ppp_async]
slhc                    6740   0  [ppp_generic]
8139too                18088   2
mii                     3976   0  [8139too]
ipt_REJECT              3928   6  (autoclean)
iptable_filter          2412   1  (autoclean)
ip_tables              15096   8  [ipt_MASQUERADE ipt_LOG ipt_state iptable_nat ipt_REJECT iptable_filter]
sg                     36524   0  (autoclean)
sr_mod                 18136   0  (autoclean)
microcode               4668   0  (autoclean)
ide-scsi               12208   0
scsi_mod              107160   3  [sg sr_mod ide-scsi]
ide-cd                 35708   0
cdrom                  33728   0  [sr_mod ide-cd]
keybdev                 2944   0  (unused)
mousedev                5492   1
hid                    22148   0  (unused)
input                   5856   0  [keybdev mousedev hid]
usb-uhci               26348   0  (unused)
usbcore                78784   1  [hid usb-uhci]
ext3                   70784   3
jbd                    51892   3  [ext3]

결국은 lirc 모듈을 찾은수가 없군요...

제가 할 수 있는 부분은 다했다고 생각을 하는데...모자란 부분이 있는지요....

무한한 상상력과 강한실행욕구는 엔지니어의 마지막 무기~

gnoygnas의 이미지

답변 고맙습니다...리모콘으로 컴퓨터 프로그램을 제어해 본다?
참 재미있겠네요....

lobsterman wrote:
lirc를 실제적으로 설치해보신 분 계신지 모르겠어요...
이글을 보시고 lirc 설치에 성공하신분 답변 부탁드리겠읍니다.(현제 수신부는 연결되어 있는 상태입니다.)
추신 : 결정적으로 lirc 설치성공에 보답하신분 께는 IRDA 수신부 부속을 보내어 드리겠읍니다.^^v

해보고는 쉽지만, 졸업작품이다 조금있으면 개강이다 여력이 있을지 모르겠네요....지금은 당장 못하더라도 님덕분에 이런게 있다는 것만으로도 큰 수확이었다 봅니다. ^^

그나저나 X10 웹 CGI 버그가 많아서 이래저래 손봐야 하는데......
휴......

One must, In fact, Love your pursuit
My home is below...Well, just go own your gait!

hyunuck의 이미지

저도 이 게시물을보고 관심이 생겨서 여기저기 찾아봤는데,
PHP로 sourceforge 프로젝트가 진행중이군요.

C로 제어하고 PHP에서 실행하는 방식인것 같습니다.
http://php-x10.sourceforge.net/index.php

이쯤되면 소스가 있으니, 초보인 저도 한번 시험해 보고 싶은데 X10 트랜스미터하고 리시버는 어디서 얼마쯤에 구입할수 있나요??

daihoon의 이미지

http://kelp.or.kr/korweblog/stories.php?story=03/06/03/7304727

위 사이트 한번 참고해 보세요. ^^;

lobsterman의 이미지

x10에서 php로 제어가 되는 것이면 coffee machine 에서도 실행조건만 같다면 구동을 해볼수도 있겠군요...

http://php-x10.sourceforge.net/index.php

위에서 가르쳐 주신 사이트에서 소스를 다운받아 조금 살펴 보았는데요...

실행문으로 exec()와 system()문을 사용하여 컴파일된 C파일을 실행을 하는 것 같더군요...

제가 php로 coffee machine을 제어하려다가 에로사항을 느낀점은...

노버디 권한에서 php를 실행시킨다면 실행문이 안먹힌다는 것이지요...

너무 최근의 아파치 버전과 php 버전을 썻는지도 모르겠읍니다.(보안 때문에 막았나 봐요...)

어떤분께서 popen()문을 써보라고 하였는데 아직 직접실행해 보지 않았읍니다.

더 연구를 해봐야지 되겠읍니다.(허접 phper 가 되니 답이 나오지를 않더군요...)

정말 좋은 자료이군요...

http://kelp.or.kr/korweblog/stories.php?story=03/06/03/7304727 

위 사이트 한번 참고해 보세요. ^^;

좋은 참고가 되겠읍니다.

무한한 상상력과 강한실행욕구는 엔지니어의 마지막 무기~

gnoygnas의 이미지

swimmingly wrote:
저도 이 게시물을보고 관심이 생겨서 여기저기 찾아봤는데,
PHP로 sourceforge 프로젝트가 진행중이군요.

C로 제어하고 PHP에서 실행하는 방식인것 같습니다.
http://php-x10.sourceforge.net/index.php

이쯤되면 소스가 있으니, 초보인 저도 한번 시험해 보고 싶은데 X10 트랜스미터하고 리시버는 어디서 얼마쯤에 구입할수 있나요??

www.x10.com에 홈 오토메이션에 필요한 모든것을 판매합니다.
저는 Home automation Kit과 여기다가 Appliance 모듈과 Lamp 모듈을 더 추가 구입해서 미화 200 달러 안팎으로 줬습니다...
단점은 이것이 미국에서 사용하는 것이다보니 110 용이라는 것입니다.

220V용도 있다고 들었는데 아직 정확한정보가 아니라 말씀 드리지 못하겠네요..

윈도우상에서 돌아가는 실행 프로그램도 CDROM으로 제공하니 쉽게 구축이 가능하리라 봅니다...더 찾아보고 유용한 정보 알려드리죠...

좋은 하루 되세요~ :D

One must, In fact, Love your pursuit
My home is below...Well, just go own your gait!

M.W.Park의 이미지

X10 관련해서 검색하니 돌아돌아 여기로 오게되네요.

오래된 글이지만 질문 하나 올려봅니다. 220V 환경에서도 잘 동작하나요?
다시말해, 램프나 기기 제어시에 110V로 전압을 낮추어서 기기를 꽂게 될텐데 그쪽 110V 라인 쪽에 트랜시버랑 제어할 기기를 다 꽂아야하는지요?
아니면 다음과 같은 환경에서도 동작하는지요?

기기 -- 110V 변압기 #1 -- 220V -- 110V 변압기 #2 -- 트랜시버

-----
오늘 나의 취미는 끝없는, 끝없는 인내다. 1973 法頂

-----
오늘 의 취미는 끝없는, 끝없는 인내다. 1973 法頂

M.W.Park의 이미지

결론은 안되는 것이군요. Orz.
220V용 제품도 있긴있는 것같습니다.

http://kbase.x10.com/wiki/110VAC_at_60Hz

Quote:
Products sold by X10.Com are strictly 110/120V, 60Hz only.

-----
오늘 나의 취미는 끝없는, 끝없는 인내다. 1973 法頂

-----
오늘 의 취미는 끝없는, 끝없는 인내다. 1973 法頂