毫无疑问,我是一个软件人。在学校,我学习了电气工程专业的相关课程,然后我学习了LED课程,再然后,像其他人一样,我学习了小型计算机,我知道了大多数零件的“伏特”和“安培”,但是,我的硬件知识也就到此为止了。我的硬件技能的上限也就是在某处添加一个LED和一些电阻来关闭USB适配器。
我对像Clint Rutkas那样的硬件爱好者心生敬畏,我的意思是他只是基于个人的兴趣,就从零开始制作了一个T-shirt炮,真的很令人吃惊。今天,Clint邮寄给我一块“Netduino”板(具体可以参考:http://netduino.com/)。除了使用.NET Micro Framework以外,它几乎和“Arduino”板一样。你说“Micro”吗?它是“tiny ass(Analog imulation System:模拟仿真系统) framework”的技术术语。
2004年我制作了一份SPOT表。它使用的是Smart Personal Objects Technology,这是“tiny ass(Analog imulation System:模拟仿真系统) framework”的营销术语。这个表已经使用6年了(它一直运行的很好,实际上,现在它正放在我的书桌上),它使用的是.NET。
让我们回到现在,我发现我自己正在把这块“Netduino ”板插到我的计算机上,通过Pete的Hello World教程(关于这个教程,具体可以参考如下页面:http://10rem.net/blog/2010/09/02/first-experiences-with-netduino-and-the-net-micro-framework),我看到了这些命名空间:
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
一切又回来了!
OK,把它们一起放到上下文环境中。“Netduino”是一块基本上和“Arduino”兼容的板,而且,它还提供了一张电路图(“Netduino”电路图的PDF版本,可以参考如下页面:http://www.netduino.com/netduino/schematic.pdf),所以,如果你有兴趣的话,也可以自己制作一个这样的板。.NET Micro Framework(一些人也叫他TinyCLR)只是字面上的叫法而已——实际上它是运行.NET字节码的一个微型的CLR(Common Language Runtime:公共语言运行时)。你可以编写C#代码,然后使用很小的内存(比如64K)在微型的CPU上运行这些代码。它已经存在相当长的一段时间了,围绕它已经建立起了一个强大的社区。
.NET Micro Framework 4.1的源代码可以从如下页面下载:http://www.microsoft.com/downloads/en/details.aspx?FamilyID=CCDD5EAC-04B1-4ECB-BAD9-3AC78FB0452B&displaylang=en,它是开源的(开源许可证是:Apache 2.0 License)。(新的微软简直令我激动万分,居然有这么多的代码悄悄地通过开源许可证来公开。)详细情况可以参考Pete的blog(关于Pete的Blog,具体可以参考如下页面:http://10rem.net/blog/2010/09/02/first-experiences-with-netduino-and-the-net-micro-framework)。
这是“Netduino”板的外观:
我正在思考一些硬件方面的创意——我可以用它来制作些什么呢?我获得了更多的功能和传说中的Tahoe II(带有触摸屏,加速计,按钮等等)(关于Tahoe II,具体可以参考:http://devicesolutions.net/Products/TahoeII.aspx)。如果你对快速构建原型或使用现成的板构建一个完整的系统感兴趣,请不要错过它!这是Tahoe II的外观。记住,所有这些板都是使用C#和.NET的。使用我过去熟悉的语言和框架来为硬件编写程序是多么令人叹为观止啊!毫不夸张地说,在学习曲线方面,它让我节省了80%的时间和精力。
这是GHI Electronics EMX Development system,我们可以有很多的选择。
要使用这些板(和其他类似的板),你只需要Micro Framework 4.1和针对特定的板的SDK就可以了。它已经集成到了Visual Studio 2010中。如果你想对这个产品做出改进,他们正在.NETMF论坛中征集各种建议:http://www.netmf.com/Discussion/Forums/SingleForum.aspx?mode=singleForum&forum=5d5ba383-e09d-470c-af8b-988cbf828630。
入门:
你需要的东西:
Netduino板(Scott:或其他.NET Micro Framework板)
USB线(早期的Netduino单元带有USB线)(Scott:通常是一个微型的或模拟的USB)
Visual Studio 2010和.NET Micro Framework 4.1 SDK(可以从如下页面下载:http://blogs.msdn.com/b/netmfteam/archive/2010/07/19/netmf-versions-4-1-released-to-web.aspx)(如果你没有Visual Studio,你可以使用C# Express 2010)
32位的Netduino SDK或64位的Netduino SDK,这主要取决于你的主机操作系统是32位的还是64位的。
可选:在netduino版上,shields和starter kits(具体可以参考如下页面:http://www.makershed.com/SearchResults.asp?Cat=43)可以做很多很“酷”的事情。它和现有的Arduino shields是兼容的。一个shield只是一个附加的“卡”,它和板上的引脚是匹配的。
为了和Netduino进行交互,这个SDK会安装一个设备驱动。你一定要选择和你的主机操作系统相匹配的位数(64位/32位),并且你一定要在Netduino连接到PC以前安装它。在安装这个SDK以前,我已经安装了Visual Studio 2010,但是这并不是很重要。
如果你使用USB线插入了Netduino,你应该可以看到这个设备的驱动已经安装好了,同时,这个板上的电源指示灯也应该被点亮了。
使用Morse Code的Hello World
现在,我只有一块Netduino板,我并没有得到其他的任何附件。如果我是一个硬件爱好者,我相信我会尝试着拆开一个烤面包机,来实现远程控制,并且我会清楚这样一些事情(比如:在引脚输出***的情况下,这个烤面包机只需要1欧姆的电阻,所以我可以反转电压,然后我就可以通过蓝牙来烤面包了),但是,我不知道这些事情。我能用Netduino做的所有事情就是让它的LED灯不停地闪烁,就像Pete指出的那样:
public static void Main()
{
OutputPort onboardLed = new OutputPort(Pins.ONBOARD_LED, false);
while (true)
{
onboardLed.Write(true);
Thread.Sleep(500);
onboardLed.Write(false);
Thread.Sleep(500);
}
}
让我们把它变得更新奇一点。使用Morse Code来输出字符串怎么样?维基上说一个点是100ms长,一个短划线是300ms长。这很难做到吗?
我参考了StackOverflow站点上的实现,因为他们进行了一项比赛,比赛的内容是看看谁能编写出体积最小的程序,程序的功能很简单,就是获取一个字符串,然后输出Morse Code。他们有一个极端优化的解决方案(相对于代码行数而言)。我也可以使用了一个Hashtable,但是两个平行的数组会更好一些。.NET Micro Framework,是“微型”的,所以它并没有提供完整的框架所提供的所有功能。但是它是开源的,它已经采用了一些社区的贡献,4.1版本已经包含了一个Hashtable的实现。我甚至可以直接调试连接的那块板!
这是我那“可悲的”小程序(它十分简单!)
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using System.Text;
using System.Collections;
namespace NetduinoApplication1
{
public class Program
{
public static void Main()
{
OutputPort onboardLed = new OutputPort(Pins.ONBOARD_LED, false);
while (true)
{
onboardLed.Write(false);
foreach (char c in " hello scott hanselman ")
{
string morse = ConvertTextToMorse(c);
Debug.Print(c + " = " + morse);
TransmitDotOrDash(onboardLed, morse);
}
}
}
private static Char[] Letters = new Char[] {'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', ' '};
private static String[] MorseCode = new String[] {".-", "-...", "-.-.",
"-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..",
"--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
"...-", ".--", "-..-", "-.--", "--..", "-----", ".----", "..---",
"...--", "....-", ".....", "-....", "--...", "---..", "----.", " "};
public static String ConvertTextToMorse(char c)
{
int index = -1;
index = Array.IndexOf(Letters, c);
if (index != -1)
return MorseCode[index];
return string.Empty;
}
public static void TransmitDotOrDash(OutputPort port, string dotordash)
{
foreach (char c in dotordash)
{
TransmitDotOrDash(port, c);
}
Thread.Sleep(300); //gap between letters
}
public static void TransmitDotOrDash(OutputPort port, char dotordash)
{
if (dotordash == ' ')
{
port.Write(false);
Thread.Sleep(700); //gap between words
}
else //it's something
{
port.Write(true);
if (dotordash == '.')
Thread.Sleep(100); //dot
else
Thread.Sleep(300); //dash
port.Write(false);
}
}
}
}
当我在这块板上闪烁“hello scott hanselman”时候,这是调试输出:
没有什么比这更容易的了。下次,我将会在Tahoe II上做一些工作,也许我会给男孩子们制作一个游戏。也许我会连接一个扬声器和一个近距离的传感器,然后看看它们是否可以在上面工作。