如何使用pcDuino做香蕉钢琴呢?Arduino是通过模拟USB HID(Human Interface Device)的方法来实现的,而在强大的pcDuino上面直接通过模拟键盘的输入就可以实现。
一:如果模拟键盘输入?
(1)设备有着自己特殊的按键键码,我需要将一些标准的按键,比如0-9,X-Z等模拟成标准按键,比如KEY_0,KEY-Z等,所以需要用到按键模拟,具体方法就是操作/dev/input/eventX文件,向它写入个input_event结构体就可以模拟按键的输入了。我们可用通过 $cat /proc/bus/input/devices可以查看到当前input子系统下面的所有event设备,我们找到键盘: (2)访问由kbd驱动在input子系统中注册的event事件文件,即读写 “/dev/input/event3″。在/usr/include/linux/input.h中有定义了event事件的结构体,API和标准按键的编码等。我们需要将要写入的按键编码填充到结构体中,然后写入键盘或者鼠标的事件设备驱动文件中。下面介绍下event事件结构体: struct input_event { struct timeval time; __u16 type; __u16 code; __s32 value; } type(事件的类型): EV_KEY,:按键事件,如键盘的按键(按下哪个键),鼠标的左键右键(是非击下)等; EV_REL,:相对坐标,主要是指鼠标的移动事件(相对位移); EV_ABS,:绝对坐标,主要指触摸屏的移动事件,但好像这个不能用在鼠标上面,也就是说无法通过这个来获取鼠标的绝对坐标(鼠标是一个相对位移的设备)。 code(事件的代码): 如果事件的类型代码是EV_KEY,该代码code为设备键盘代码。代码植0~127为键盘上的按键代码,0×110~0×116为鼠标上按键代码,其中0×110(BTN_ LEFT)为鼠标左键,0×111(BTN_RIGHT)为鼠标右键,0×112(BTN_ MIDDLE)为鼠标中键。其它代码含义请参看/usr/include/linux /input.h文件,该文件中会定义相应的宏来代表不同的按键。如果事件的类型代码是EV_REL,code值表示轨迹的类型。如指示鼠标的X轴方向REL_X(代码为0×00),指示鼠标的Y轴方向REL_Y,指示鼠标中轮子方向REL_WHEEL。 value(事件的值): 如果事件的类型代码是EV_KEY,当按键按下时值为1,松开时值为0;如果事件的类型代码是EV_ REL,value的正数值和负数值分别代表两个不同方向的值。例如:如果code是REL_X,value是10的话,就表示鼠标相对于上一次的坐标,往x轴向右移动10个像素点。
二:示例代码
#include <core.h> #include <stdio.h> #include <string.h> #include <linux/input.h> #include <fcntl.h> #include <sys/time.h> #include <unistd.h> int InData1 = 0; int InData2 = 0; int InData3 = 0; int InData4 = 0; int InData5 = 0; int TouchSensitivity1 = 38; int TouchSensitivity2 = 800; void simulate_key(int fd, int kval) { struct input_event event; gettimeofday(&event.time, 0); event.type = EV_KEY; event.value = 1; event.code = kval; write(fd, &event, sizeof(event)); event.type = EV_SYN; event.value = 0; event.code = SYN_REPORT; write(fd, &event, sizeof(event)); memset(&event, 0, sizeof(event)); gettimeofday(&event.time, 0); event.type = EV_KEY; event.value = 0; event.code = kval; write(fd, &event, sizeof(event)); event.type = EV_SYN; event.value = 0; event.code = SYN_REPORT; write(fd, &event, sizeof(event)); } void setup() { for(int i = 6; i <= 12; i++) { pinMode(i, OUTPUT); } } void loop() { int fd_mouse ; int fd_kbd ; int i = 0; fd_kbd = open(“/dev/input/event1″, O_RDWR); if(fd_kbd <= 0) { printf(“Can not open keyboard input file\n”); while(1); } while(1) { InData1 = analogRead(A1); InData2 = analogRead(A2); InData3 = analogRead(A3); InData4 = analogRead(A4); InData5 = analogRead(A5); if(InData1 <= TouchSensitivity1) { digitalWrite(7, HIGH); simulate_key(fd_kbd, KEY_S); delay(500); InData1 = 2000; InData2 = 2000; InData3 = 2000; InData4 = 2000; InData5 = 2000; } else digitalWrite(7, LOW); if(InData2 <= TouchSensitivity2) { digitalWrite(8, HIGH); simulate_key(fd_kbd, KEY_D); delay(500); InData1 = 2000; InData2 = 2000; InData3 = 2000; InData4 = 2000; InData5 = 2000; } else digitalWrite(8, LOW); if(InData3 <= TouchSensitivity2) { digitalWrite(9, HIGH); simulate_key(fd_kbd, KEY_F); delay(500); InData1 = 2000; InData2 = 2000; InData3 = 2000; InData4 = 2000; InData5 = 2000; } else digitalWrite(9, LOW); if(InData4 <= TouchSensitivity2) { digitalWrite(10, HIGH); simulate_key(fd_kbd, KEY_G); delay(500); InData1 = 2000; InData2 = 2000; InData3 = 2000; InData4 = 2000; InData5 = 2000; } else digitalWrite(10, LOW); if(InData5 <= TouchSensitivity2) { digitalWrite(11, HIGH); simulate_key(fd_kbd, KEY_H); delay(500); InData1 = 2000; InData2 = 2000; InData3 = 2000; InData4 = 2000; InData5 = 2000; } else digitalWrite(11, LOW); delay(100); } }
三:测试工具
(1)pcDuino和TouchkeyUSB shield: (2)测试线和香蕉(5根): (3)如果你使用的显示器不带扬声器,那么你还需要一个usb声卡和一个音箱(或者耳机),使用音箱需要修改pcDuino的音频输出,下面教你如何修改pcDuino的默认音频输出: (a)查看系统的声卡: ubuntu@ubuntu:~$ aplay -l **** List of PLAYBACK Hardware Devices **** card 0: Device [Generic USB Audio Device], device 0: USB Audio [USB Audio] Subdevices: 0/1 Subdevice #0: subdevice #0 card 1: sun4isndhdmi [sun4i-sndhdmi], device 0: SUN4I-HDMIAUDIO sndhdmi-0 [] Subdevices: 1/1 Subdevice #0: subdevice #0
(可以看出我的系统有两个声卡) (b)设置系统声卡为USB声卡: $vim /etc/asound.conf 内容为:
default.pcm.card 0 default.pcm.device 0 default.ctl.card 0
(因为USB声卡是card 0,需要改为HDMI输出,则修改为card 1即可) (c)重新pcDuino,就修改完成。$ sudo reboot 接线图:
四:测试运行
(1)先在pcDuino上安装scratch:$sudo apt-get install pcduino-scratch: (2)将附件上已将画好的scratch工程下载到pcDuino,并且打开banana paino工程: (3)输入指令:$sudo arduino 打开arduino IDE,输入测试代码、运行: (4)运行效果图:
|