ESP-NS에서는 2개의 Digital Input과 4개의 Digital Output이 준비되어 있습니다. 이를 이용하면 스위치입력등과 같은 외부 입력을 받을 수 있고, 특히 4개의 Digital Output은 외부로 신호를 주는 것 외에도 Open Collector로 되어 있어서 12V 또는 24V로 전원을 이용하여 외부 기기를 켜거나 끄는 등의 제어를 할 수 있습니다.
Digital Input
Digital Input에 대한 그림입니다. 콘솔포트를 위로 했을 때, 아래부터 DI PORT0, DI PORT1이 되겠습니다.
각 포트별로 보드에 LED가 배치되어 있기 때문에 입력을 주면 바로 확인할 수 있습니다.
Digital Output
Digital Output 포트에 대한 위치와 각 핀에 대한 그림 설명입니다.
역시 Digital Output 포트에도 LED가 준비되어 있어서 측정장비가 필요없이 출력을 확인하실 수 있습니다.
예제 프로그램
필요한 파일을 ESP-NS CD 에 제공되는 esp_ns.h와 아래의 예제 소스입니다. 이해를 돕기 위해 가급적 파일 하나로 작성했습니다. Digital Input 쪽에 2개의 스위치를 달고 2개의 스위치 ON/OFF에 따라 Digital Output 의 출력을 바꾸는 예제입니다.
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <fcntl.h> #include <string.h> #include "esp_ns.h" int esp_ns_dev; #define PORT_DO0 0 #define PORT_DO1 1 #define PORT_DO2 2 #define PORT_DO3 3 #define PORT_DI0 0 #define PORT_DI1 1 #define STATE_ON 1 #define STATE_OFF 0 void esp_init( void ) { // 화일을 연다. esp_ns_dev = open("/dev/esp", O_RDWR|O_NDELAY ); if (esp_ns_dev == -1 ) { // 화일 열기 실패 printf( "Device Open Fail /dev/esp\n"); printf( " mknod /dev/esp c 222 0\n" ); exit(1); } } void esp_close( void ) { // 파일을 닫는다.. close( esp_ns_dev ); } /*------------------------------------------------------------------------------ 설명 : DI Port의 값을 읽는다, 반환 : DI 입력 값 [ 0 또는 1 ] 에러시 -1을 반환한다. --------------------------------------------------------------------------------*/ int eps_di_read( unsigned int vport ) { static esp_ns_io_t di_rd; di_rd.size = 0; switch( vport ) { case PORT_DI0 : ioctl( esp_ns_dev, ESP_NS_GET_DI0, &di_rd ); break; case PORT_DI1 : ioctl( esp_ns_dev, ESP_NS_GET_DI1, &di_rd ); break; } if( di_rd.size > 0 ) return di_rd.buff[0]; return -1; } /*------------------------------------------------------------------------------ 설명 : DO Port를 ON/OFF 시킨다. state 0 : OFF 1 : ON --------------------------------------------------------------------------------*/ void esp_do_write( unsigned char state, unsigned int vport ) { printf( "%d %d ", state, vport); switch( vport ) { case PORT_DO0 : ioctl( esp_ns_dev, ESP_NS_SET_DO0, state ); printf("D00 \n"); break; case PORT_DO1 : ioctl( esp_ns_dev, ESP_NS_SET_DO1, state ); printf("D01 \n"); break; case PORT_DO2 : ioctl( esp_ns_dev, ESP_NS_SET_DO2, state ); printf("D02 \n"); break; case PORT_DO3 : ioctl( esp_ns_dev, ESP_NS_SET_DO3, state ); printf("D03 \n"); break; } } /*------------------------------------------------------------------------------ 설명 : 부져를 ON 시킨다. vmsec : 시간 설정 변수 1. 부져를 ON --> OFF 시간 타임 설정을 한다. msec 단위 2. 부져를 ON 상태로 유지하기 위해서는 시간설정에 0 을 입력하면 된다. --------------------------------------------------------------------------------*/ void esp_buzzer_on( unsigned long delay ) { ioctl( esp_ns_dev, ESP_NS_BUZZER_ON, delay ); } /*------------------------------------------------------------------------------ 설명 : 부져를 OFF --------------------------------------------------------------------------------*/ void esp_buzzer_off( void ) { ioctl( esp_ns_dev, ESP_NS_BUZZER_OFF, 0 ); } int main( void) { int io_0; int io_1; int bit_io; esp_init(); printf( "ESP-NS가 초기화되었습니다.\n"); // 모든 출력 포트를 켜고 2초간 대기합니다. esp_do_write( STATE_ON, PORT_DO0 ); esp_do_write( STATE_ON, PORT_DO1 ); esp_do_write( STATE_ON, PORT_DO2 ); esp_do_write( STATE_ON, PORT_DO3 ); sleep( 2); // 모든 출력 포트를 끄고 2초간 대기합니다. esp_do_write( STATE_OFF, PORT_DO0 ); esp_do_write( STATE_OFF, PORT_DO1 ); esp_do_write( STATE_OFF, PORT_DO2 ); esp_do_write( STATE_OFF, PORT_DO3 ); sleep( 2); // 입력 포트 값에 따라서 각 출력 포트의 상태를 변경합니다. while( 1) { io_0 = eps_di_read( PORT_DI0); io_1 = eps_di_read( PORT_DI1); bit_io = io_0 + (io_1 << 1); // sw1과 sw2의 값에 따라 0부터 3까지의 값을 갖게 됩니다. printf( "IO_0=%d IO_1=%d bit=%x\n", io_0, io_1, bit_io); switch( bit_io) { case 0: esp_do_write( STATE_ON , PORT_DO0 ); esp_do_write( STATE_OFF, PORT_DO1 ); esp_do_write( STATE_OFF, PORT_DO2 ); esp_do_write( STATE_OFF, PORT_DO3 ); break; case 1: esp_do_write( STATE_OFF, PORT_DO0 ); esp_do_write( STATE_ON , PORT_DO1 ); esp_do_write( STATE_OFF, PORT_DO2 ); esp_do_write( STATE_OFF, PORT_DO3 ); break; case 2: esp_do_write( STATE_OFF, PORT_DO0 ); esp_do_write( STATE_OFF, PORT_DO1 ); esp_do_write( STATE_ON , PORT_DO2 ); esp_do_write( STATE_OFF, PORT_DO3 ); break; default : esp_do_write( STATE_OFF, PORT_DO0 ); esp_do_write( STATE_OFF, PORT_DO1 ); esp_do_write( STATE_OFF, PORT_DO2 ); esp_do_write( STATE_ON , PORT_DO3 ); } } esp_close(); return 0; }
프로그램 내용을 보시면 아시겠지만 역시 리눅스 시스템 답게 포트를 파일처럼 처리하고 있습니다.
int esp_ns_dev;
esp_ns_dev는 포트를 처리하기 위한 파일 디스크립터입니다. MS 윈도우에서는 핸들이라고 합니다. 우선 장치에 대한 파일 디스크립터를 구해야 합니다. 이를 위해 esp_init()를 호출합니다.
void esp_init( void ) { // 화일을 연다. esp_ns_dev = open("/dev/esp", O_RDWR|O_NDELAY ); if (esp_ns_dev == -1 ) { // 화일 열기 실패 printf( "Device Open Fail /dev/esp\n"); printf( " mknod /dev/esp c 222 0\n" ); exit(1); } }
열기에 실패했다면 쉘에서 직접 mknod 명령을 실행해서 장치명을 등록하신 후 다시 실행하십시오.
성공적으로 장치에 대한 디스크립터를 얻었다면 read() 함수를 이용하여 DI값을 읽어 올 수 있고, , write() 함수를 이용하여 DO포트로 출력할 수 있습니다.
DI 포트로부터 입력값을 읽어 오려면,
io_0 = eps_di_read( PORT_DI0); // Digital Input Port 0 번의 값을 읽어 들입니다.
io_1 = eps_di_read( PORT_DI1); // Digital Input Port 1 번의 값을 읽어 들입니다.
DO 포트로 출력하려면,
esp_do_write( STATE_ON, PORT_DO0 ); // Digital Output Port 0 번으로 출력
esp_do_write( STATE_ON, PORT_DO1 ); // Digital Output Port 1 번으로 출력
esp_do_write( STATE_ON, PORT_DO2 ); // Digital Output Port 2 번으로 출력
esp_do_write( STATE_ON, PORT_DO3 ); // Digital Output Port 3 번으로 출력
출력 포트에 LED와 팬을 연결
Digital Output 에는 12V 또는 설정에 따라 24V의 높은 전압의 전류가 흐르므로 저항 1K 오옴짜리 저항으로 LED를 보호해서 연결했습니다.
LED에는 극성이 있기 때문에 조심해야 합니다. 오른쪽 그림에서 처럼 LED의 핀 2개 중에 짧은 쪽이 (-) 극성입니다. 또는 LED안에 접시모양으로 넓게 생긴 부분과 연결된 핀이 (-) 극성입니다. 참고하세요.....^^
이번에는 팬 연결입니다. 팬은 극성이 없기 때문에 12v와 DO 핀과 연결하면 끝입니다.
동영상 설명
글로 말씀 드리기 어려운 Open Collector 내용과 실제 테스트 내용을 동영상으로 준비했습니다. 소프트웨어 개발자라고 하더라도 하드웨어에 대한 기초 지식을 가지고 있다면 시스템에 대한 이해를 돕고 하드웨어 개발자와의 대화에도 도움이 될 것 같아서 비록 지식은 짧지만 알고 있는 내용을 짜내서 작성해 보았습니다. 그러다 보니 많이 엉성하네요. 이점 양해를 부탁드립니다.