树莓派3+开发Windows 10 IoT Core应用程序

上一篇分享介绍了Windows 10 物联网版(IoT Core)开发环境的搭建,这篇分享在此基础上探索这个平台上应用程序的开发。

Windows 10 IoT Core支持C#和C++等语言开发,这里以C#为例。 微软对于这个系统提供了大量的代码示例,接下来先测试一个简单的Hello World程序,后续再测试连接感测器。

Hello World !

首先通过HelloWorld程序走通编译部署的流程。代码样例:

  1. https://github.com/ms-iot/samples

复制代码

打包下载(124 MB):

  1. https://codeload.github.com/ms-iot/samples/zip/develop

复制代码

用Visual Studio 2015打开HelloWorld工程目录中的HelloWorld.sln,整个工程会在VS中打开。

稍微改下代码,以便和官方程序区分。

接下来开始编译部署工作。

如图,平台选择ARM,位置是远程计算机。

远程计算机已经自动检测到,当然也可以输入IP来连接。

远程连接的对话框在第一次设定后,以后可能不会自动弹出,如果要修改,可以通过项目属性中的调试选项打开。

按下工具栏上的开始调试按钮(就是有绿色箭头的“远程计算机”按钮),程序会自动完成编译生成,部署等工作。

如果之前安装过这个程序,会遇到这个弹窗:

选择“是”继续部署。

程序运行成功:

连接光强度感测器

使用的是BH1750数字环境光强度感测器。模块通过3.3V供电,使用I2C总线通信,连接到Raspberry Pi上的供电口和I2C界面,具体在物联网相关的帖子里已经提到(一起玩树莓派3+体验物联网云服务)。

断电连接好感测器,然后启动Raspberry Pi 3。

复制一份HelloWorld并修改为BH1750。

修改界面布局:

放置2个TextBox用于显示提示文字和感测器结果。

感测器界面代码来自参考资料[2],

注意使用了Windows.Devices.I2c,要在项目引用中添加“Windows IoT Extensions for the UWP”。

主程序如下:

  1. using System;

  2. using System.Collections.Generic;

  3. using System.IO;

  4. using System.Linq;

  5. using System.Runtime.InteropServices.WindowsRuntime;

  6. using Windows.Foundation;

  7. using Windows.Foundation.Collections;

  8. using Windows.UI.Xaml;

  9. using Windows.UI.Xaml.Controls;

  10. using Windows.UI.Xaml.Controls.Primitives;

  11. using Windows.UI.Xaml.Data;

  12. using Windows.UI.Xaml.Input;

  13. using Windows.UI.Xaml.Media;

  14. using Windows.UI.Xaml.Navigation;

  15. using GY30LightSensor;

  16. // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409

  17. namespace HelloWorld

  18. {

  19. /// <summary>

  20. /// An empty page that can be used on its own or navigated to within a Frame.

  21. /// </summary>

  22. public sealed partial class MainPage : Page

  23. {

  24. public GY30LightSensor.GY30LightSensor gy30 { get; set; }

  25. public MainPage()

  26. {

  27. InitializeComponent();

  28. gy30 = new GY30LightSensor.GY30LightSensor();

  29. Loaded += OnLoaded;

  30. }

  31. private async void OnLoaded(object sender, RoutedEventArgs routedEventArgs)

  32. {

  33. await gy30.InitLightSensorAsync();

  34. gy30.Reading += (o, args) =>

  35. {

  36. var task = this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>

  37. {

  38. LightResult.Text = args.Lux + " lux";

  39. });

  40. };

  41. }

  42. }

  43. }

复制代码

编译部署后,运行结果如下:

可以看到已经成功获取感测器数据。

参考

[1] https://developer.microsoft.com/ ... es/i2caccelerometer

[2] https://www.hackster.io/ediwang/ ... ndows-10-iot-148582

附件

  1. BH1750.cs

复制代码

  1. using System;

  2. using System.Diagnostics;

  3. using System.IO;

  4. using System.Threading;

  5. using System.Threading.Tasks;

  6. using Windows.Devices.Enumeration;

  7. using Windows.Devices.I2c;

  8. namespace GY30LightSensor

  9. {

  10. public class GY30LightSensorEventArgs : EventArgs

  11. {

  12. public int? Lux { get; set; }

  13. public GY30LightSensorEventArgs(int? lux)

  14. {

  15. Lux = lux;

  16. }

  17. }

  18. public class GY30LightSensor

  19. {

  20. public int Bh1750Address => 0x23;

  21. public I2cDevice I2CLightSensor { get; private set; }

  22. private Timer PeriodicTimer { get; set; }

  23. public int TimerIntervalMs { get; set; }

  24. public event ReadingEventHandler Reading;

  25. public delegate void ReadingEventHandler(object sender, GY30LightSensorEventArgs e);

  26. private void OnReading(int lux)

  27. {

  28. Reading?.Invoke(lux, new GY30LightSensorEventArgs(lux));

  29. }

  30. public GY30LightSensor(int timerIntervalMs = 500)

  31. {

  32. TimerIntervalMs = timerIntervalMs;

  33. }

  34. public async Task InitLightSensorAsync()

  35. {

  36. string aqs = I2cDevice.GetDeviceSelector();

  37. var dis = await DeviceInformation.FindAllAsync(aqs);

  38. if (dis.Count == 0)

  39. {

  40. throw new FileNotFoundException("No I2C controllers were found on the system");

  41. }

  42. var settings = new I2cConnectionSettings(Bh1750Address)

  43. {

  44. BusSpeed = I2cBusSpeed.FastMode

  45. };

  46. I2CLightSensor = await I2cDevice.FromIdAsync(dis[0].Id, settings);

  47. if (I2CLightSensor == null)

  48. {

  49. throw new UnauthorizedAccessException(string.Format("Slave address {0} on I2C Controller {1} is currently in use by " +

  50. "another application. Please ensure that no other applications are using I2C.", settings.SlaveAddress, dis[0].Id));

  51. }

  52. try

  53. {

  54. I2CLightSensor.Write(new byte[] { 0x10 }); // 1 [lux] aufloesung

  55. }

  56. catch (Exception ex)

  57. {

  58. Debug.WriteLine("Failed to communicate with device: " + ex.Message);

  59. throw;

  60. }

  61. PeriodicTimer = new Timer(this.TimerCallback, null, 0, TimerIntervalMs);

  62. }

  63. private void TimerCallback(object state)

  64. {

  65. var lux = ReadI2CLux();

  66. OnReading(lux);

  67. }

  68. private int ReadI2CLux()

  69. {

  70. byte[] regAddrBuf = new byte[] { 0x23 };

  71. byte[] readBuf = new byte[2];

  72. I2CLightSensor.WriteRead(regAddrBuf, readBuf);

  73. var valf = ((readBuf[0] << 8) | readBuf[1]) / 1.2;

  74. return (int)valf;

  75. }

  76. }

  77. }

复制代码

以上图文内容均是EEWORLD论坛网友:x1816 原创,在此感谢。

欢迎微博@EEWORLD

如果你也写过此类原创干货请关注微信公众号:EEWORLD(电子工程世界)回复“投稿”,也可将你的原创发至:[email protected],一经入选,我们将帮你登上头条!

与更多行业内网友进行交流请登陆EEWORLD论坛。

手机打开