本帖最后由 树·水·风 于 2012-11-16 08:59 编辑
前一段时间看《终极审判》,潜水员利用声音发送摩斯电码给潜艇最终获救,于是突发灵感:既然普通人无法记住每个字幕的摩斯电码,何不做一个自动接收器,将白光闪烁信号解析为字母呢?于是就开始做了。
整个系统包括两个部分:发送端和接收端。
发送端,使用Arduino控制LED手电发出闪光。MorseCode库参见程晨老师的Arduino开发实战指南,我所做的是在上面加了一些扩充。
Arduino代码如下: - /*
- @Date:2012/11/10
- @Author:huaweidong
- @Description:MorseDemo03-自定义字符串,每次接收到的新的字符串替换原先的字符串,并开始循环发送
- */
- #include "MorseCode.h"
- char words[20];
- int i = 0;
- MorseCode Morse(13);
- void setup()
- {
- Morse.setInterval(250);
- Serial.begin(9600);
- }
- void loop()
- {
- if(Serial.available())
- {
- i = 0;
- while(Serial.available())
- {
- words[i] = Serial.read();
- i++;
- }
- }
- int k;
- for(k = 0; k < i; k++)
- {
- Serial.print(words[k]);
- if(words[k] == ' ')
- {
- Morse.WordInterval();
- }
- else
- {
- Morse.transfor(words[k]);
- Morse.CharInterval();
- }
- }
- Serial.println();
- Morse.WordInterval();
- }
复制代码
用户打开串口工具后,可以自定义字符串(可包含空格),发送到Arduino板中,如SOS,Arduino之后便会循环发送SOS,直到用户输入新的字符串替换到原有字符串。
我使用的设备是小手电(原本想使用Android手机的闪光灯的,但是发现Android的闪光灯无法单独调用,只能连摄像头一起开启,而一旦开启摄像头,那么闪光灯的响应速度就变得很慢,无法达到想要的效果),原想使用三极管放大电路从而让Arduino控制小手电,后来发现小手电的额定电压也不过4.5V,于是就直接把小手电插在了Arduino板上。如下图所示:
图中小手电显示这么灰暗是因为我用手机拍照的缘故,实际上小手电的亮度是足够的(14个led灯),在夜间测试20米远完全没有问题。
于是摩斯电码发送端就算做好了,小手电可以发出间歇性的"."和"_"了,信息就存在与这些间歇性的闪光中。
下面就是接收端。
接收端我用的是一个摄像头,利用计算机视觉的方法,检测视频图像的颜色信息,根据颜色变化确定"."和"_",然后进一步确定每个英文字符,最后组成一个单词。
代码如下(未经优化,有很多冗余代码,大家见谅):
上面一些阈值(如区分"."与"_"以及空格)需要根据电脑运行速度来设定。
为了提高视频处理速度,我只是对视频整个画面的一小部分做颜色判断,做实验时也把手电和摄像头离得比较近,当距离较远时,就需要把手电正对着摄像头,这样才能检测明显。
最后,执行上面的C++程序,便可以跳出两个窗口,如下图所示
一个窗口显示视频画面,一个输出解析的字母。(细致的同学会发现出现了一个E,这是由于我用手拿着手电遮挡了所造成的,后面就稳定地输出CCNT PVC了。)
发送端和接收端做好后,就可以拿到空旷的场地试验了。 |