红外遥控发射器(补)

先上张电路图。pcspkr就是PC机上小喇叭的线,当设定为某个频率时,会发出该频率的[0,+5v]方波信号。当在相应寄存器中写入0时,该引脚无信号。这样只要控制该寄存器值就能控制红外遥控信号的发出了。红外遥控器有一个基准频率,一般为36KHz或者38KHz,视具体的电视机而定,当频率偏离该值时,遥控距离迅速减小(猜测是因为无法达到足够的共振频率)。

image

上次软件篇中提到不能驱动pcspkr发出大于32khz的信号,事实证明这是pcspkr kernel module的一个限制。

http://lxr.free-electrons.com/source/drivers/input/misc/pcspkr.c

 50         if (value > 20 && value < 32767)
 51                 count = PIT_TICK_RATE / value;

这样pcspkr不能发出低于20HZ或者超过32767HZ的声音。严格的说这不算是一个bug,因为这已经属于人耳无法听到的范畴了,但是对想要发出高频红外信号的我来说,却是不小的困惑。

继续研究后,发现Linux下可以通过直接对端口读写来绕过这个限制。这样只需要在应用程序中使用pcspkr.c驱动中的这一小段code就行了。大概曾经在DOS下写过pc小喇叭程序的朋友应该都很熟悉这段code.

 55         if (count) {
 56                 /* set command for counter 2, 2 byte write */
 57                 outb_p(0xB6, 0x43);
 58                 /* select desired HZ */
 59                 outb_p(count & 0xff, 0x42);
 60                 outb((count >> 8) & 0xff, 0x42);
 61                 /* enable counter 2 */
 62                 outb_p(inb_p(0x61) | 3, 0x61);
 63         } else {
 64                 /* disable counter 2 */
 65                 outb(inb_p(0x61) & 0xFC, 0x61);
 66         }

在调试中发现红外发射管的发射强度比较弱(用摄像头和电视遥控器比较结果),于是把电阻换成47欧姆的了!这样最大电流是80毫安,但是因为方波信号的duty cycle是1/2,所以平均电流是40毫安,小于手册的最大持续电流,应该是安全的。PCSPKR只能发出方波信号,这种情况下反而成为一种优点了。

关于遥控器的代码,可以到lirc的网站上去下一个各种remote的网站的大集http://www.lirc.org/remotes.tar.bz2,只要你的遥控器不是太冷门,一般总能找到遥控器的代码。关于遥控器的编码格式可以从这篇博客入门http://jimlu.spaces.live.com/blog/cns!9B1C2AEA8D078F9A!609.entry?sa=211980024,lirc的文档中也能找到不少资料。

参考了下lirc的网站,各种home brew的红外接收发射方案都有,有用串口或者并口的,比较夸张的是通过声卡的line in接口做红外接收的信号分析的。不过貌似用pcspkr的没有,算是pc控制红外发射的一种新方法,呵呵。

最后放上程序,虽然不是通用的,不过稍加修改应该可以适用各种情况。

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/io.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
#include “cycle.h”
#define PIT_TICK_RATE 1193182ul
#define PULSE_FREQ 38000

int console_fd;
struct remote_space_enc {
    int header[2];
    int one[2];
    int zero[2];
    int predata;
    int predata_bits;
    int trail[2];
    int toggle_bit_mask;
};

struct remote_space_enc panasonic_tv =
    {
        {3430, 1700},
        {440, 1320},
        {440, 440},
        0x400401,
        24,
        {400,74158},
        0x0,
    };

inline void vsleep (usec)
{
    ticks tick1 = getticks(), tick2;
    while(1) {
        tick2 = getticks();
        if (elapsed(tick2, tick1) > usec*1600) {
            break;
        }
    }
}

inline void _0 ()
{
    /* disable counter 2 */
        outb(inb(0x61) & 0xFC, 0x61);

}

inline void _1 ()
{
    int count = PIT_TICK_RATE/PULSE_FREQ;
    /* set command for counter 2, 2 byte write */
    outb(0xB6, 0x43);
    /* select desired HZ */
    outb(count & 0xff, 0x42);
    outb((count >> 8) & 0xff, 0x42);
    /* enable counter 2 */
    outb(inb(0x61) | 3, 0x61);
}

inline void pulse(int usec)
{
    _1();
    vsleep (usec);
}

inline void space(int usec)
{
    _0();
    vsleep (usec);
}

inline void send_bits (int one[2], int zero[2], int code, int width)
{
    int i;
    int mask;

    mask = 1<<(width-1);

    for (i=0;i<width;i++) {
        if (code & mask) {
            pulse (one[0]);
            space (one[1]);
        } else {
            pulse (zero[0]);
            space (zero[1]);
        }
        mask = mask >> 1;
    }
}

inline void send_code (struct remote_space_enc * remote, int code, int width)
{
    send_bits(remote->header, remote->zero, 1, 1);
    send_bits(remote->one, remote->zero, remote->predata, remote->predata_bits);
    send_bits(remote->one, remote->zero, code, width);
    send_bits(remote->trail, remote->zero, 1, 1);
}

int main(int argc, char** argv)
{
    int j;
    int len;
    int code;
    if (argc<=1) {
        printf (“Must supply the signal you want to send\n”);
        exit (1);
    }
    console_fd = open (“/dev/console”, O_WRONLY);
    if (console_fd == -1) {
        printf (“open console file handle failed\n”);
        exit (1);
    }
    ioperm (0x42, 2, 1);
    ioperm (0x61, 2, 1);
     len = strlen(argv[1]);
    code = 0;
    for (j=0;j<len;j++) {
        if (argv[1][j] >= ‘0’ && argv[1][j] <= ‘9’) {
            code = (code << 4) + argv[1][j] – ‘0’;
        } else if (argv[1][j] >= ‘a’ && argv[1][j] <= ‘f’) {
            code = (code << 4) + argv[1][j] – ‘a’ + 10;
        } else if (argv[1][j] >= ‘A’ && argv[1][j] <= ‘F’) {
            code = (code << 4) + argv[1][j] – ‘A’ + 10;
        } else {
            break;
        }
    }
    send_code (&panasonic_tv, code, j*4);
    _0();
    close (console_fd);
    printf (“\n”);
    return 0;
}

红外遥控发射器(软件篇)

搞定了硬件电路的问题,接下来就要考虑怎么跟电脑连接了。红外遥控器一般是在一个高频信号(36KHz)上加载一个低频的调制信号,所以实际上我们用的遥控器都会利用一个晶振来产生载波信号。像下面这个图这样这种电路看起来就已经很复杂了,以我现在的电焊水平是没办法应付的。

image

因为是通过电脑控制发射遥控信号,所以我预备通过电脑来控制所有的高低频发射,所以在硬件篇里面的硬件只有两个元件。那么接下来就是通过电脑的哪个外设接口来控制的问题。

一开始考虑用COM口。COM口是标准的可编程外部接口,比特率达到112Kbps,完全能够通过对COM口编程达到驱动红外发射二极管的目的,不过在和同事讨论的时候发现COM口至少有两个问题:

1. COM口的0和1分别是正负电平,虽然二级管能够承受一定的反向电压,但是理想的情况还是没有反向电压的好。

2. COM口的TX信号电压不定,根据手册是5V到9V不等,也就是说稳流电路需要有自适应性。另外如果电压是9V的话,反向电压就超过反向工作电压一倍不到,需要并联一个电阻来匹配反向电压。

于是把目光移到了主板上的另外一个部件,pc speaker上。http://en.wikipedia.org/wiki/Pc_speaker PC speaker是一个典型的方波发生器,只需要写入跟频率倒数有关的数字就能够产生高频方波信号。它的电压也是标准的5V,而且信号是在5V和0V之间变化,和二极管正好匹配。编程也比较方便。

好吧,我承认这是典型的Cowboy Programming,是不符合Code Craft精神的。不过作为业余爱好,还是能少花些力气就少花些力气吧。

先确认PC小喇叭是有声音的以后,把昨天做好的电源组件接到了pc小喇叭上,然后让它发出beep后用数码相机观测,O yeah,成功工作了。其实这样是小有点冒险的,因为不知道pc speaker PIN的输出功率是多少,不过当我打开机箱看到pc小喇叭上写着8欧姆0.5w的字样后就很放心了。

然后就是一些基本的计算,我的电视机兼显示器是Philips的,采用RC5编码,高频信号为36KHz,算下来应该把pcspkr编程为33就可以达到这个频率,可是实际上发现一旦频率大于32khz红外发射管就不亮,不知道是因为什么原因,可能是红外LED管不能工作在这么高的频率下,也可能是pc spkr针脚实际上不能输出这么高频的方波信号,回头改回pc spkr再试一下。好在32khz也能认出来,但是识别距离就变得比较近了,只有离几厘米的距离才能认出。

具体驱动pc spkr的方法参见这个链接:http://tldp.org/LDP/lpg/node83.html

RC5的标准参见这个链接http://en.wikipedia.org/wiki/RC-5,具体的参数可能随不同遥控器而不一样,比如我的遥控器的01信号间隔就是780us而不是上面讲的889us。遥控器信号的获得是利用我的一个usb红外遥控接收器,以前做过一个mce遥控器的libusb app,程序里面有很多调试信息可以打。通过对比标准philips遥控器和红外发射管产生的调试信息,可以逐渐找到合适的信号。

最终结果:我可以通过这个发射器控制电视机的音量啦!这里就不上图了。我的最终目的是要能够通过这个发射器把客厅的电视机和htpc结合起来,通过mce的遥控器来直接控制电视机,这样就能扔掉电视机的遥控器了。随着技术问题的解决,剩下的就只是具体的调试问题了,实践证明通过pc speaker当作遥控器的信号发生器是完全可行的,虽然还不太完美,不过是可以用的。软件篇到此为止,谢谢围观!

红外遥控发射器(硬件篇)

额外的一个小制作,主要还是熟悉一下器材的使用,和建立一些基本的tool,主要目的是制作一个通过pc来控制的红外遥控发射器,这样可以通过程序控制电视,空调等电器的开关。电路异常的简单,希望各位看到最后别吐血就行。

淘宝上买的一些电子元件,主要是模拟器件。数字电路暂时还没啥想法。

P1090902

供电,把一个坏掉的风扇线拆了下来,又改装了一直不用的两个风扇针脚插座,把一根usb线改装成5v电源线,另外一根比较短的线可以直接接主板上的针脚。这样就构成一个可以组合的电源接插件。

P1090903

红外二级管IR333C-A的工作电压是1.1伏特,20mA,这样需要把5V电压降到1.1伏才能使用,最重要的是需要有限流装置,限流电路应该怎么做呢?

P1090896

后来发现自己把问题想复杂了,典型的搞软件的人的想法。最后找了一个220欧姆的电阻串联,这样5V/220欧姆,最高电流也就22.7mA,考虑到二极管和电路也有电阻,最终电流肯定小于20mA。

P1090900

哦也,亮了。照相机拍到的光是红外线,肉眼是看不到亮光的。感谢Shikai同学提供的主意。

P1090899

最终电路的电流是16.5mA,从手册上看到红外发射管的亮度和电流差不多是线性的,这个样子应该也能用了,发射功率应该稍小于16毫瓦,二极管发光的工作效率应该是比较高的。

接下来就是焊接和软件的工作了。就两个元件的电路讲了那么半天,我发觉我确实也挺啰嗦的。不过这个对一个看到电路就头疼的软件工程师来说,没烧掉什么已经算是很不容易了,各位就凑合的等待软件篇吧。

买了些睡莲

今天去附近的花鸟市场买了些睡莲,一共买了四头,黄红蓝紫四种颜色,先种上看看长势怎样,如果好的话再去买几头。买回来的睡莲放在两个花盆里,因为盆子不够,另外两个小一点的根放在一个空的可乐瓶子里,用小石头压住。

P1090880

我觉得放可乐瓶子是一个不错的想法,等回头有更多可乐瓶子可以全部放在里面养。

P1090886

 

P1090890

四世同堂人家

在杭州看到这个,合影留念一下。

P1090863

 P1090868

P1090869

杭州作为一个旅游城市建设得还是不错的,前天晚上Yan夫妇陪着去清河坊看了看,比在别处看到的其它仿古街建设得好很多。没有很多从义乌进口的小玩具,反而有很多现场制作的东东,还看到一个首饰匠做的铜雕馆,馆主相当Enjoy自己做的东西。有意思的是其中一把龙椅,花样做得相当繁复,边上还写了块牌子,“人民的位子,坐,请坐,请上座”,馆主不单好客,还很有幽默感。

铜制的千佛龛

P1090838

铜浮雕

 P1090845

看到这些,你会想,怪不得铜价在涨!

P1090848

 P1090849

生意人对关二爷是相当的情有独钟。

P1090853

传说中的铜龙椅,人实在是太多了,只好把路人甲乙丙丁入镜了。

 P1090856

类固醇计划 — 准备活动

类固醇计划的准备活动开始,就从这种常见的耳麦入手。家里有一个旧的耳麦,想改成无需头戴的坐式麦克风,于是就破坏性的把话筒线和麦克风拆下来了。

P1090803

拆下来的麦克风头就是下面图片这种,叫驻极体咪头,其实里面的核心部件就是一个永久带电荷的电容器,通过声音驱动电容器两极板间距离变化,产生电流输入pc的话筒线,具有灵敏度高的特点,据说里面还有个放大电路,没拆开来研究过。

image

电子产品这类东东拆了才发现成本真的好低 。其实很多时候钱都是付在品牌和质量控制上了。我记得有个音响网站专放拆机高清图,反正有几个品牌的东东压根就没往那边送过。

这个是以前买的一个无线键盘鼠标的接收器,当时还算是个新鲜玩意。工包的花了三百多,而且还中看不中用。现在用的无线键鼠才80多块,比这个好用多了。我打算把这个接收器改造成一个桌式话筒。说起来整天在会议室看着专业的会议系统话筒要想心里不长草是不可能的,姑且仿制一个吧。

P1090817

为了方便制作还买了万用表和烙铁,家里这两样东西还是应该常备的,比如检测电池还有没有电本来都是通过替换法,现在用万用表量下就精确多了。

P1090807 P1090808

咪头装进去以后,果然声音有点小。按照同事的说法,声音“像从很远处传过来”。这是正常的,因为耳麦上的话筒本来就是为了在嘴边拾音设计的,灵敏度达不到桌面拾音的要求。做了下实验,离开二十厘米左右,在录音软件里面就基本是一条直线了。

上网查了下,咪头也有高灵敏度的,价钱和低灵敏度差不多,也就是五毛到一块的水平,不过在类固醇计划正式开始前,还是探索下能不能通过物理方法增加灵敏度。

理论上咪头就是把声音的机械能转化为电能,声音是一种纵波,能够驱动电容极板间距离变化,只要能最大限度的驱动电容极板运动,那么就能增加电信号的幅度。不过咪头被一个铁壳盖着,看不出内部结构是怎样的,只能稍微尝试一下了。

在实验了几种材料以后选用了这个,通过一面塑料片以较大面积拾取声波振动能量,并且把机械能转给咪头内的电容变成电能,理论上就是这样了,实践的结果是有明显效果。

P1090810

最后就是这样个东东,效果只能说勉强达到要求,现在这个麦克风放在桌面上能够拾取到说话声,也不算轻,但是稍微有点闷,还算可以使用。网上十块钱买的高灵敏度话筒比这个做得好多了。不过别着急,类固醇计划还没开始呢。

P1090818

Eighteen Linux Games in Synaptic

上网查询某游戏的时候无意中发现的两个链接。判断Linux下的一个游戏是不是好玩是一件比较麻烦的事情,有了视频就方便多了。当然,Linux下很多游戏本来就是免费的,好不好玩下载回来玩一下就行了。

顺带说一下,通过XBMC下的插件Launcher很容易就能给媒体中心加上游戏功能,如果你只是想在无聊时杀杀时间,或者有朋友来问你的媒体中心能不能打游戏时Show off一下,捡上面几个游戏加到Launcher的列表中,就颇为琳琅满目了。
http://xbmc.org/forum/showthread.php?t=35739

切换到xbmc,vs freevo

最近尝试从freevo切换到xbmc. 原来客厅里的电脑一直是选用linux+freevo的媒体中心解决方案. Freevo是一个老牌媒体中心软件,有了它你就可以忘记窗口键盘和鼠标,可以用遥控器像看电视一样看下载的电影–当然,现在很多几百块钱的媒体播放器也有这样的功能了。

不过有时候觉得freevo也未免太稳定了,这么多年了就没增加什么新功能。这次换了主板,趁机也尝试了另一个媒体中心软件xbmc. 刚开始找媒体中心软件的时候,xbmc还是xbox专用的,没想到现在已经横跨windows, mac, linux三大平台了。

装好以后发现果然很爽,如果说freevo是为crt设计的媒体中心的话,xbmc就是为高清电视机设计的媒体中心软件了。流畅的操作界面,可以直接通过图形界面配置,丰富的插件可以看各种在线视频,还可以自动上网抓电影海报和简介。比较起来,freevo的界面就有些古老了。不想说freevo什么坏话,freevo没有大的缺点,但是xbmc的优点太明显了。Freevo的系统配置好了自己用起来是会很方便,但是界面就像是上个世纪的dvd机,xbmc的界面要强大多了。

附上一个xbmc的视频,用的恰好也是zotac的atom系统,可以直接从一分十秒左右开始看。
http://v.youku.com/v_show/id_XMTA0NzM1NzE2.html

新主板安装完毕

新主板今天到货,折腾了一天终于搞定。因为换了芯片组的缘故,还稍微费了一点周折才把archlinux启动起来,好在不用重装系统和配置了。

测试了一下Atom的性能,上优酷全屏看flash cpu利用率170左右,看来Linux下看flash还是CPU大户。放720p x264 99%。然后打开了mplayer的vdpau加速(利用Nvidia芯片组加速),放720p x264 20%左右,然后试了一下一段1080p的coral, 流畅播放cpu 20%左右。离子平台果然还是很强大的。整个系统CPU温度在40度左右,硬盘只有30度,比原先用1.8G烤土豆凉快多了。

P1090790

升级准系统

2008年五月份的时候买了个浩鑫K45准系统。没想到经过24×7不停的下电影看电影兼上优酷看视频的折磨,终于在上周挂了,享年仅一年八个月。

一开始怀疑是电源挂了,因为电源的风扇在冷启的时候常常发出怪声;而Eric听了症状以后说是内存挂了,可是主板上的电解电容上的小鼓包好像在提示是主板挂了。周五的时候去Yan家里拿了个闲置的电源。到家里用替换法测试后发现果然是主板挂了,内存和电源都没问题。把这个消息告诉Yan, Yan说:“不知道应该恭喜你还是应该表示同情呢?囧”

于是只好考虑怎么换主板了。一个困惑我已久的问题就是浩鑫的准系统到底能不能换第三方的主板,因为浩鑫的主板是BTX版型,CPU是45度角放置的,据说这种放置方法有利于规划散热路径,随之而来的问题是如果把主板拆下来,换块ITX主板上去行不行。在把整个系统大卸八块以后我得到了初步答案。拆去电源,卸下主板,去掉接口背板,剩下的就是一个普通小型机箱,看起来容纳一个itx主板应该没有问题。

P1090784 
整个系统拆开后的样子,打算重用的是1TB WD 硬盘,和边上两条合计3G内存。值得说明的是后面超频三的9025机箱风扇极烂,买了半年多轴承已经粘住了根本就转不动,想上京东评论才发现早就过了评论期,只得在这里发泄一下。

早就看上了离子平台,在京东订了一个Zotac ION-A主板,Atom 330双核四线程,Geoforce 9400M板载显卡,跟原先系统相比,CPU性能可能弱了点,不过显示系统性能要好多了,从很多贴子来看,能轻松播放蓝光和1080p H.264视频,也许还能在电视机上玩3D游戏。顺便买了个银蝠90mm风扇,据说寿命是液体轴承的三倍。

网上搜了下,用这块板子配客厅PC的人还不少,就是性价比低了些。不过考虑到功耗比较低,而且可以直接使用原先的内存和配置好的系统,还是下单了。比较吸引我的是系统用的是一个类似笔记本电源的电源,这样电源可以放在机箱外面,机箱的温度应该会改善不少,也少了电源风扇的噪音。

网上一个用这块主板来配迷你系统的帖子:http://bbs.sjtu.edu.cn/bbstcon?board=PCMarket&reid=1254072009

等待送货中,好像要明天才会到货,鄙视京东的物流。