物联网 - 将 Raspberry Pi 与 Windows 10 结合使用

作者 Bruno Sonnino

我一直与软件打交道,却还从未与硬件直接打过交道。尽管我开发了许多工作方式与硬件接近的软件,但从未用过可以完全控制的物理电路板。因此,当我有机会使用 Raspberry Pi 时,尤其是在使用 Windows 10 和 Visual Studio 时,我抓住了这个机会。

Raspberry Pi 版本 2 和 3 可以将 Windows 10 用作 OS(尽管并非完整版,但仍可以通过执行通用 Windows 平台 [UWP] 应用来控制其设备)。它很便宜,每台售价不到 35 美元,但功能非常强大。Raspberry Pi 3 具备 4 核、64 位 ARM 处理器、HDMI 视频设备、以太网和 Wi-Fi 网络、蓝牙以及四个 USB 端口。使用它,一定可以做很多事情。

开始使用时,可以单独使用 Raspberry Pi 电路板,但会有些受到限制。如果只使用电路板,则与为计算机或智能手机开发项目一样。还需要使用其他一些硬件。一些制造商推出了附属工具包:原型板、电阻器、LED 指示灯、电位计、传感器和内存卡。可以购买计算机外壳盒,但没有必要这么做,因为应始终打开计算机以方便连接。

拥有电路板和工具包后,是时候开始了解硬件了。首先,应研究一下 Raspberry Pi,了解它包含哪些部件。 图 1 展示了电路板。

图 1:包含 GPIO 的 Raspberry Pi 3 机型 B

图 1 中电路板的右侧,可以看到四个 USB 端口 (1) 和一个以太网连接器 (2)。在底部,从左向右依次是迷你 USB 形式的电源连接器 (3)、HDMI 视频设备 (4)、摄像头端口 (5) 和声音输出设备 (6)。在电路板的左侧,可以看到 micro SD 卡槽 (7) 和 LCD 显示屏连接器 (8)。还可以看到 Wi-Fi 和蓝牙无线收发器 (9)。在电路板的中间,可以看到处理器 (10) 和网络控制器 (11)。顶部为通用输入/输出 (GPIO) 块 (12),可以在这里进行所有连接。每个插针的用途各异,如图顶部所示。

Raspberry Pi 使用两种电源电压: 5V 和 3.3V。黑色插针是接地的,黄色插针是在编程时使用的 GPIO 插针。请注意,插针编号是无序的。因此,除非记性很好,否则手边应留着插针编号图( bit.ly/1WcBUS2 中提供了一个示例图)。

第二步是了解工具包。我不会介绍所有内含物,因为这会因制造商(或你计划购买的产品)而差异很大。对于此项目,需要使用试验电路板、三个 LED 指示灯、电阻器和电线。若要详细了解这些组件及其交互方式,请参阅 Frank La Vigne 在 2016 年 4 月的“新式应用”专栏中发表的“编写适用于物联网的 UWP 应用”一文,网址是 msdn.com/magazine/mt694090

安装第一个电路

了解了电路板和这些简单组件后,就可以安装第一个电路了。通常情况下,此类系统的“Hello World”程序可以让 LED 指示灯闪烁。若要进一步简化操作,可以先创建一个让 LED 指示灯亮起(而不是闪烁)的电路。这种时候,无需运行任何程序,只需了解要构建的电路即可。

如果将 LED 指示灯直接连到 Raspberry Pi 的 3.3V 插针,可能会烧坏 LED 指示灯,因为它无法承受流经它的电流。根据欧姆定律 (V = R*I),需要在电路中添加 220 Ω(红/红/黑)电阻器。如果没有 220 Ω 电阻器,可以使用更大的电阻器。使用更大的电阻器后,电路中的电流变小,就不会烧坏 LED 指示灯了。电阻器不能过大,因为如果电流过小,LED 指示灯就无法亮起。以我为例,我使用了 330 Ω 电阻器,没有出现任何问题。

若要查看试验电路板中的蒙太奇布局,请参阅 图 2 。图像是使用“Fritzing”开放源代码程序进行创建,可以从 fritzing.org 下载此程序。

图 2:安装的电路

安装完电路后(安装时,应关闭 Raspberry Pi 电源,以免烧坏任何组件),连接电源。如果安装正确,LED 指示灯应亮起。如果 LED 指示灯没有亮起,请检查 LED 指示灯的电极放置是否正确,即正极(较长电线)应与 Raspberry Pi 中的 3.3V 插针相连。负极和电阻器(在此示例中,没有极化)必须处于同一线路。电阻器的第二根电线必须与 Raspberry Pi 中的接地插针相连。如果一切都没有问题,请检查 LED 指示灯是否已烧坏。如果是,请予以更换。如果 LED 亮起,可以执行下一步:创建控制 LED 指示灯的程序。

安装并使用 Windows 10

在此之前,不需要使用 OS,因为不需要对 Raspberry Pi 进行编程,但之后将需要进行一些编程。这种时候就需要使用 Windows 10。可以免费下载和安装适用于 Raspberry Pi 的 Windows 10,尽管这与在台式机和平板电脑上运行的版本不完全一样,但仍可以借助它来执行 UWP 程序,而无需进行任何更改。

第一步是在 SD 卡中下载并安装 Windows 10。为此,请从 bit.ly/2lPXrRc 下载并安装 Windows 10 物联网 (IoT) 核心版仪表板工具。

若要在 Raspberry Pi 上安装 Windows 10,必须拥有一个至少为 8GB 的兼容 micro SD 卡。接下来,在仪表板中选择“安装新设备”选项,在 SD 卡中下载并安装 Windows 10。必须能够通过某种方式在计算机上写入此卡。如果没有读卡器,可以购买一个 USB 读卡器。

选择设备类型、OS 以及 SD 卡所在的驱动器。为计算机命名,然后选择管理员密码。单击选中框,接受许可条款,然后单击“安装”按钮。在卡中下载并记录数据后,Windows 10 便已安装,可供使用。将此卡从计算机读卡器中取出,然后放入 Raspberry Pi 的卡槽中。使用以太网线缆或 Wi-Fi(如果使用的是含有 Wi-Fi Dongle 的 Raspberry Pi 3 或 2)连接网络。打开设备。

Windows 10 启动后,可以在 IoT 核心版仪表板中的“我的设备”下看到连接的设备。

可以使用已连接设备的 IP 地址(在端口 8080 上)在浏览器中打开设备门户。以我为例,我可以使用地址 http://192.168.1.199:8080 打开设备门户。必须提供之前设置的管理员密码,才能打开门户,如 图 3 中所示。

图 3:设备门户

在此门户中,可以配置设备、检查已安装的应用,并能验证其性能和存储空间。使用最后一个选项“远程”,可以远程控制设备。如果设备没有连接监视器,此选项就非常有用,因为可以从你的计算机进行远程控制。选中“启用 Windows IoT 远程服务器”框后,可以在设备上启用远程控制,并能从应用商店中下载适用于 Windows 10 的远程控制应用。

安装并运行 Windows IoT 远程控制应用后,即可远程控制设备并与之交互。

现在,可以开始使用 Windows 10 为 Raspberry Pi 开发项目。

使用 Visual Studio 为 Raspberry Pi 开发项目

若要使用 Visual Studio 为 Raspberry Pi 开发项目,必须确保你已安装了工具。可以选择“自定义安装”并检查“功能”选项中是否有“通用 Windows 应用开发工具”,检查是否已安装工具。

执行此操作后,即表明你已安装工具,便可以开始使用 Windows 10 为 Raspberry Pi 开发项目。创建新项目,然后选择“空”UWP 应用。

这会创建一个空应用,你将创建在主屏幕中显示当前计算机的名称的应用。在 Main­Page.xaml 中,添加下面的代码:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  <TextBlock FontSize="32" x:Name="MachineText"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"/>
</Grid>

然后,在 MainPage.xaml.cs 中添加下面的代码,以获取并显示计算机名称:

public MainPage()
  this.InitializeComponent();
  Windows.Security.ExchangeActiveSyncProvisioning.EasClientDeviceInformation eas =
    new Windows.Security.ExchangeActiveSyncProvisioning.EasClientDeviceInformation();
  MachineText.Text = eas.FriendlyName;

如果在本地计算机上运行此应用,它将在一个窗口中显示计算机名称。

然后,运行 Raspberry Pi。选择“解决方案平台”下拉菜单中的“ARM”,然后选择“设备”下拉菜单中的“远程计算机”。此时,系统会打开用于选择远程计算机的对话框。

选择 Raspberry Pi 设备,然后运行应用。应用会部署到 Raspberry Pi,可以在远程控制窗口中查看它的运行情况。请注意,窗口中显示的计算机名称应是你在格式化 SD 卡并在其上安装 Windows 10 时设置的计算机名称。

可以对此应用进行调试,方法与调试本地应用相同,即设置断点、分析变量等。如果在 Visual Studio 中终止应用,应用会关闭,Raspberry Pi 中会显示主屏幕。如果转到浏览器门户,则会发现应用仍已安装,可使用“运行”按钮运行应用,如图 4 中所示。

图 4:显示已安装应用的应用门户

我对 UWP 应用所能实现的兼容性级别深为叹服。为了展示潜力有多大,我将使用并非针对 Raspberry Pi 而开发的应用。我将使用 UWP 社区工具包的示例应用,这个工具包中的组件由 Microsoft 和社区进行开发(bit.ly/2b1PAJY 绝对值得访问)。

下载并编译程序包后,可以将它部署到 Raspberry Pi 并运行(是的,程序运行方式与在桌面设备上完全相同)。顺便说一下,应尝试使用设备中的控件,它们很好用。

与电路板交互

运行程序后,就必须开始与电路板交互。将创建交通信号灯控制器。其中包含三个 LED 指示灯(红色、黄色和绿色),每个指示灯的亮起时间可能不同。

若要在电路板中控制 LED 指示灯,必须获取 GPIO 控制器,并打开要控制的插针,然后根据需要进行设置。在图 1 中,可以看到 GPIO 块中的第八个插针(第二行)是插针 22。将使用插针 22、9 和 19,生成的电路如图 5 中所示。

图 5:交通信号灯的电路

在此电路就绪后,新建一个空 UWP 应用。在 MainPage.xaml 中,输入图 6 中的代码。

图 6:显示交通信号灯的 MainPage.xaml 代码

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  <Border BorderBrush="Black" BorderThickness="3" HorizontalAlignment="Center"
      VerticalAlignment="Center" CornerRadius="5">
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
      <Ellipse Width="50" Height="50" Fill="Red" Opacity="0.5"
        Margin="20,20,20,10" x:Name="RedLed" Stroke="Black"
        StrokeThickness="1"/>
      <Ellipse Width="50" Height="50" Fill="Yellow" Opacity="0.5"
        Margin="20,10,20,10" x:Name="YellowLed" Stroke="Black"
        StrokeThickness="1"/>
      <Ellipse Width="50" Height="50" Fill="LimeGreen" Opacity="0.5"
         Margin="20,10,20,20" x:Name="GreenLed" Stroke="Black"
         StrokeThickness="1"/>
    </StackPanel>
  </Border>
</Grid>

在电路板和显示屏上都可以看到交通信号灯,因此还可以通过查看远程显示屏来了解发生的一切。Mainpage.xaml.cs 中的源代码如图 7 中所示。

图 7:按指定时间间隔打开交通信号灯的源代码

private int _currentLight;
private DispatcherTimer _timer;
private int[] _pinNumbers = new[] { 22, 9, 19 };
private GpioPin[] _pins = new GpioPin[3];
public MainPage()
  this.InitializeComponent();
  if (InitGPIO())
    InitTimer();
private void InitTimer()
  var intervals = new[] { 6000, 2000, 6000 };
  var lights = new[] { RedLed, YellowLed, GreenLed };
  _currentLight = 2;
  _timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(500) };
  _timer.Tick += (s, e) =>
    _timer.Stop();
    lights[_currentLight].Opacity = 0.5;
    _pins[_currentLight].Write(GpioPinValue.High);
    _currentLight = _currentLight == 2 ? 0 : _currentLight + 1;
    lights[_currentLight].Opacity = 1.0;
    _pins[_currentLight].Write(GpioPinValue.Low);
    _timer.Interval = TimeSpan.FromMilliseconds(intervals[_currentLight]);
    _timer.Start();
  _timer.Start();

必须添加对 IoT 扩展的引用,才能运行此代码。右键单击解决方案资源管理器中的“引用”节点,单击“添加引用”,然后转到“扩展”,为 UWP 添加 Windows IoT 扩展。

将创建一个计时器,用于按时间间隔数组设定的时间间隔(在此示例中,为 6 秒、2 秒和 6 秒)打开每个 LED 指示灯。屏幕中椭圆的不透明度设为 0.5,因此它们看起来比较暗,而当指示灯亮起时,每个椭圆的不透明度设为 1。只有在 InitGPIO 函数中为电路板设置 GPIO(如图 8 中所示)后,才能设置计时器。

图 8:初始化 GPIO 和为输出设置 LED 指示灯插针的代码

private bool InitGPIO()
  var gpio = GpioController.GetDefault();
  if (gpio == null)
    return false;
  for (int i = 0; i < 3; i++)
    _pins[i] = gpio.OpenPin(_pinNumbers[i]);
    _pins[i].Write(GpioPinValue.High);
    _pins[i].SetDriveMode(GpioPinDriveMode.Output);
  return true;

为输出打开三个插针,将它们设置为“高”即关闭 LED 指示灯。将插针设置为“低”时,电路中有电流,LED 指示灯亮起。运行程序时,将看到显示交通信号灯的屏幕,其中指示灯的打开和关闭与实际情况一样,电路板如图 9 中的照片所示。

图 9:运行程序的交通信号灯电路板

如你所见,创建与 Raspberry Pi 交互的程序很简单。如果了解 Windows 10 编程,就等于掌握了对 Raspberry Pi 进行编程所需的全部知识(是的,虽然与电路板交互又是另外一回事,但已完成了一半)。程序的创建方法与任何 Windows 10 程序相同(事实上,无需在 Raspberry Pi 中进行任何更改,即可运行 UWP 程序)。唯一的区别是,需要使用 GPIO 控制器来设置和获取数据。如果要拓展知识并尝试其他项目,可以尝试 bit.ly/2llecFZ 中提供的许多示例。这将为你提供众多机会,以便你能够将功能强大的硬件与卓越高效的软件相结合。这是无与伦比的组合。

Bruno Sonnino自 2007 年起被评为 Microsoft MVP。他是开发者、顾问和作者,著有许多与 Windows 开发相关的书籍和文章。可以关注他的 Twitter @bsonnino,也可以阅读他的博客 blogs.msmvps.com/bsonnino

衷心感谢以下 Microsoft 技术专家对本文的审阅: Rachel Appel