Sensor Device Jo, Heeseung
Sensor 실습 HBE-SM5-S4210 에는근접 / 가속도 / 컴파스센서가장착 각센서들을사용하기위한디바이스드라이버와어플리케이션을작성 2
근접 (Proximity) 센서 HBE-SM5-S4210 Camera Module 근접센서디바이스 근접센서는사물이다른사물에접촉되기이전에가까이접근하였는지를검출할목적으로사용 일반적으로생활에서자동문이나엘리베이터, 휴대폰등에서많이사용 HBE-SM5-S4210 에사용되는근접센서는 " 광학근접센서 " - 빛을방사하는방사기 (Emitter) 라고불리는광원과빛의존재를감지하는수신기의쌍으로구성 3
근접 (Proximity) 센서 소스파일작성 근접센서드라이버는 /working/linux-2.6.35- s4210/drivers/misc/hanback/ 참조 드라이버를참고하여 proximity_test 를작성 root@ubuntu:/working/5.sensor/proximity_test# vi proximity_test.c 001: #include <stdio.h> 002: #include <stdlib.h> 003: #include <string.h> 004: #include <sys/ioctl.h> 005: #include <sys/types.h> 006: #include <sys/stat.h> 007: #include <fcntl.h> 008: #include <unistd.h> 009: #include <linux/input.h> 010: #include <termios.h> 011: 012: #define PROXIMITYIO 0x51 013: #define PROXIMITY_IOCTL_ENABLE _IO(PROXIMITYIO, 0x31) 4
근접 (Proximity) 센서 014: #define PROXIMITY_IOCTL_DISABLE _IO(PROXIMITYIO, 0x32) 015: #define PROXIMITY_IOCTL_IS_ENABLE _IOR(PROXIMITYIO, 0x33, int) 016: #define PROXIMITY_IOCTL_DELAY_GET _IOR(PROXIMITYIO, 0x34, int) 017: #define PROXIMITY_IOCTL_DELAY_SET _IOW(PROXIMITYIO, 0x35, int) 018: #define PROXIMITY_IOCTL_DATA _IOR(PROXIMITYIO, 0x36, int) 019: 020: static struct termios initial_settings, new_settings; 021: static int peek_character = -1; 022: 023: void init_keyboard(){ 024: tcgetattr(0,&initial_settings); 025: new_settings = initial_settings; 026: new_settings.c_lflag &= ~ICANON; 027: new_settings.c_lflag &= ~ECHO; 028: new_settings.c_lflag &= ~ISIG; 029: new_settings.c_cc[vmin] = 1; 030: new_settings.c_cc[vtime] = 0; 031: tcsetattr(0,tcsanow,&new_settings); 032: } 5
근접 (Proximity) 센서 033: 034: void close_keyboard(){ 035: tcsetattr(0,tcsanow,&initial_settings); 036: } 037: 038: int kbhit(){ 039: char ch; 040: int nread; 041: if(peek_character!= -1) return 1; 042: 043: new_settings.c_cc[vmin] = 0; 044: tcsetattr(0,tcsanow,&new_settings); 045: nread = read(0,&ch,1); 046: new_settings.c_cc[vmin] = 1; 047: tcsetattr(0,tcsanow,&new_settings); 048: 049: if(nread == 1){ 050: peek_character = ch; 051: return 1; 052: } 053: return 0; 054: } 055: 6
근접 (Proximity) 센서 056: int readch(){ 057: char ch; 058: 059: if(peek_character!= -1) 060: { 061: ch = peek_character; 062: peek_character = -1; 063: return ch; 064: } 065: read(0,&ch,1); 066: return ch; 067: } 068: 069: int main(void) 070: { 071: int fd = 0; 072: int value = 0; 073: int i,j,k,data,result; 074: unsigned short ch = 0; 075: 076: printf("press 'q' exit\n"); 077: fd= open("/dev/proximity", O_RDONLY); 7
근접 (Proximity) 센서 078: if (fd <0) { perror("/dev/proximity"); return -1; } 079: 080: init_keyboard(); 081: 082: result = ioctl(fd,proximity_ioctl_enable); 083: usleep(200000); 084: 085: while(ch!= 'q') 086: { 087: read(fd,&data,sizeof(int)); 088: printf("proximity value = %d\n",data); 089: if(kbhit()){ 090: ch = readch(); 091: } 092: usleep(100000); 093: } 094: result = ioctl(fd,proximity_ioctl_disable); 095: close(fd); 096: close_keyboard(); 097: return 0; 098: } 099: 8
근접 (Proximity) 센서 Makefile 작성 root@ubuntu:/working/5.sensor/proximity_test # vi Makefile CC = arm-linux-gcc CFLAGS = -DNO_DEBUG EXEC=proximity_test OBJS=$(EXEC).o all: $(EXEC) $(EXEC): $(OBJS) $(CC) -o $@ $^ clean: rm -f $(OBJS) $(EXEC) 9
근접 (Proximity) 센서 컴파일 root@ubuntu:/working/5.sensor/proximity_test# ls Makefile proximity_test.c root@ubuntu:/working/5.sensor/proximity_test# make clean;make ------------------ 다음과같은메시지가출력된다 ----------------- rm -f proximity_test.o proximity_test arm-linux-gcc -c -DNO_DEBUG -o proximity_test.o proximity_test.c arm-linux-gcc -o proximity_test proximity_test.o root@ubuntu:/working/5.sensor/proximity_test# ls Makefile proximity_test proximity_test.c proximity_test.o 테스트 nfs/tftpboot/modem 으로 board 에전송후 board 에서실행 10
근접 (Proximity) 센서 실행결과확인 [root@sm5s4210 ~]#./proximity_test ------------------ 다음과같은메시지가출력된다 ----------------- press 'q' exit Proximity value = 187 Proximity value = 228 Proximity value = 203 Proximity value = 88 Proximity value = 75 Proximity value = 78 Proximity value = 69 Proximity value = 62 Proximity value = 3663 PROXIMITY test exit!! 11
가속도, 컴파스센서 가속도센서 HBE-SM5-S4210 에장착된가속도센서는 X,Y,Z 3 축의변화를측정할수있는가속도센서모듈 X 축 : 화면의수평축을나타내며오른쪽을가리킴 Y 축 : 화면의수직축을나타내며위쪽을가리킴 Z 축 : 화면을위로해서테이블에놓여져있을때, 위쪽방향을가리킴 각축의값은 (m/s 2 ) 단위 장비가테이블위에수평으로놓여있을때는표준중력값 - 9.8(m/s 2 ) - 장비가테이블위에서중력에대한반작용으로적용되는힘 12
가속도, 컴파스센서 컴파스센서 HBE-SM5-S4210 M1 Module 에는콤파스센서디바이스가장착 HBE-SM5-S4210 에서는가속도와마그네틱필드센서를융합하여방향센서 (Orientation) 값도함께제공 컴파스센서는가속도센서와마찬가지로 3 축 (X,Y,Z) 으로구성되어있으며센서가가르키는방향은가속도센서와동일 13
가속도, 컴파스센서 소스파일작성 가속도및컴파스센서드라이버는 /working/linux-2.6.35- s4210/drivers/input/misc/im3640.c 참조 - 드라이버를참고하여다음과같이 sensor_test.c 를작성 root@ubuntu:/working/5.sensor/sensor_test# vi sensor_test.c 001: --------------------- 다음과같이작성한다. ----------------------------- 002: #include <stdio.h> 003: #include <stdlib.h> 004: #include <string.h> 005: #include <sys/ioctl.h> 006: #include <sys/types.h> 007: #include <sys/stat.h> 008: #include <fcntl.h> 009: #include <unistd.h> 010: #include <linux/input.h> 011: #include <termios.h> 012: 013: #define IM3640IO 0x50 14
가속도, 컴파스센서 014: #define IM3640_IOCTL_ENABLE _IO(IM3640IO,0x31) 015: #define IM3640_IOCTL_DISABLE _IO(IM3640IO,0x32) 016: #define IM3640_IOCTL_IS_ENABLE _IO(IM3640IO,0x33,int) 017: #define IM3640_IOCTL_DELAY_GET _IOR(IM3640IO,0x34,int) 018: #define IM3640_IOCTL_DELAY_SET _IOR(IM3640IO,0x35,int) 019: #define IM3640_IOCTL_DATA _IOR(IM3640IO,0x36,int[9]) 020: 021: #define ACCELATION(x) ((((9.8*2)/256)/256)*x) 022: #define MEGNETIC(x) (0.2*x) 023: #define ORIENTATION(x) (1.0*x) 024: 025: static struct termios initial_settings, new_settings; 026: static int peek_character = -1; 027: 028: void init_keyboard(){ 029: tcgetattr(0,&initial_settings); 030: new_settings = initial_settings; 031: new_settings.c_lflag &= ~ICANON; 032: new_settings.c_lflag &= ~ECHO; 033: new_settings.c_lflag &= ~ISIG; 034: new_settings.c_cc[vmin] = 1; 035: new_settings.c_cc[vtime] = 0; 15
가속도, 컴파스센서 036: tcsetattr(0,tcsanow,&new_settings); 037: } 038: 039: void close_keyboard(){ 040: tcsetattr(0,tcsanow,&initial_settings); 041: } 042: 043: int kbhit(){ 044: char ch; 045: int nread; 046: if(peek_character!= -1) return 1; 047: 048: new_settings.c_cc[vmin] = 0; 049: tcsetattr(0,tcsanow,&new_settings); 050: nread = read(0,&ch,1); 051: new_settings.c_cc[vmin] = 1; 052: tcsetattr(0,tcsanow,&new_settings); 053: 054: if(nread == 1){ 055: peek_character = ch; 056: return 1; 057: } 16
가속도, 컴파스센서 058: return 0; 059: } 060: 061: int readch(){ 062: char ch; 063: 064: if(peek_character!= -1) 065: { 066: ch = peek_character; 067: peek_character = -1; 068: return ch; 069: } 070: read(0,&ch,1); 071: return ch; 072: } 073: 074: int main(void) 075: { 076: int i, j,quit=1,result; 077: int fd = -1; 078: int recv_buf[9]={0}; 079: float data_buf[9]={0}; 17
가속도, 컴파스센서 080: size_t read_bytes; 081: unsigned short ch = 0; 082: if ((fd = open("/dev/im3640", O_WRONLY)) < 0) 083: { 084: printf("application : /dev/im3640 open fail!\n"); 085: exit(1); 086: } 087: 088: init_keyboard(); 089: result = ioctl(fd,im3640_ioctl_enable); 090: usleep(50000); 091: while(ch!= 'q') 092: { 093: result = ioctl(fd,im3640_ioctl_data,recv_buf); 094: for(j=0;j<9;j++) 095: { 096: if(j<3) 097: data_buf[j] = ACCELATION(recv_buf[j]); 098: else if(j<6) 099: data_buf[j] = MEGNETIC(recv_buf[j]); 18
가속도, 컴파스센서 100: else 101: data_buf[j] = ORIENTATION(recv_buf[j]); 102: } 103: printf("accel_x = %f, accel_y = %f, accel_z = %f \n",data_buf[0],data_buf[1],data_buf[2]); 104: usleep(500); 105: printf("compass_x = %f, compass_y = %f, compass_z = %f \n",data_buf[3],data_buf[4],data_buf[5]); 106: usleep(500); 107: printf("ori_a = %f, ori_p = %f, ori_r = %f \n\n",data_buf[6],data_buf[7],data_buf[8]); 108: if(kbhit()){ 109: ch = readch(); 110: } 111: usleep(400000); 112: } 113: 114: result = ioctl(fd,im3640_ioctl_disable); 115: 116: close_keyboard(); 117: close(fd); 118: return 0; 119: } 19
가속도, 컴파스센서 Makefile 작성 root@ubuntu:/working/5.sensor/sensor_test# vi Makefile CC = arm-linux-gcc CFLAGS = -DNO_DEBUG EXEC=sensor_test OBJS=$(EXEC).o all: $(EXEC) $(EXEC): $(OBJS) $(CC) -o $@ $^ clean: rm -f $(OBJS) $(EXEC) 20
가속도, 컴파스센서 컴파일 root@ubuntu:/working/5.sensor/sensor_test# ls Makefile sensor_test.c root@ubuntu:/working/5.sensor/sensor_test# make clean;make ------------------ 다음과같은메시지가출력된다 ----------------- rm -f sensor_test.o sensor_test arm-linux-gcc -c -DNO_DEBUG -o sensor_test.o sensor_test.c arm-linux-gcc -o sensor_test sensor_test.o root@ubuntu:/working/5.sensor/sensor_test# ls Makefile sensor_test sensor_test.c sensor_test.o 테스트 nfs/tftpboot/modem 으로 board 에전송후 board 에서실행 21
가속도, 컴파스센서 실행결과확인 [root@sm5s4210 ~]#./sensor_test ------------------ 다음과같은메시지가출력된다 ----------------- accel_x = 0.001495, accel_y = 0.001495, accel_z = 0.076862 compass_x = -8.800000, compass_y = 19.000000, compass_z = -34.200001 ori_a = 23.000000, ori_p = -1.000000, ori_r = 0.000000 accel_x = 0.000897, accel_y = 0.001495, accel_z = 0.076263 compass_x = -9.000000, compass_y = 19.200001, compass_z = -35.200001 ori_a = 23.000000, ori_p = 0.000000, ori_r = 0.000000 accel_x = 0.000897, accel_y = 0.001794, accel_z = 0.076563 ----------- 생략 ----------------------- ori_a = 23.000000, ori_p = 0.000000, ori_r = 0.000000 accel_x = 0.000000, accel_y = 0.000000, accel_z = 0.077759 compass_x = -16.400000, compass_y = 15.600000, compass_z = -34.200001 ori_a = 38.000000, ori_p = 0.000000, ori_r = 0.000000 accel_x = 0.000598, accel_y = 0.000897, accel_z = 0.077460 compass_x = -20.600000, compass_y = 11.400000, compass_z = -35.599998 ori_a = 55.000000, ori_p = -1.000000, ori_r = 0.000000 22