Raspberry Pi 3 运行 Windows 10 带有自定义程序的核心显示划掉的 x
Raspberry Pi 3 running Windows 10 Core with custom program shows crossed-out x
我有一个非常简单的项目,我的目标是能够通过直接方法调用(通过 Azure IoT 中心)在我的 Raspberry Pi 3、运行 上切换 LED宁 Windows 10 个物联网核心。
目前我写的程序只显示一个白色的盒子,里面有一个x,就像邮件信封一样,后端光控代码不响应直接方法调用。但是,当连接到 Visual Studio 2017 远程调试器时,UI 背后的代码似乎 运行 非常好(或者我认为如此),所以我认为直接方法调用失败是由于我的互联网连接(正如我在 this question 中询问的那样)。
然而,UI 背后的代码正在请求将一个小的程序执行更新打印到文本框中,而不存在的 UI 从未响应,因此阻止了该程序首先继续打开 Azure Iot Hub 设备客户端。
而不是完全放弃 UI,我想弄清楚是什么阻止了我的 UI 做任何事情。奇怪的是,当我第一次尝试我的程序(减去 IoT 代码)时,UI 工作得很好。
坦率地说,我完全不知道什么会突然出错(Pi 是 在头部模式下,如果你想知道的话),所以我想我最好的行动方案是发布我的代码,看看是否有其他人可以复制这些问题。
与其将我所有的代码都转储到这个 post 中,否则有人必须将它重建到一个项目中,然后可能会遗漏一些东西,等等......我只是把它全部推到一个Git 存储库,可在此处找到:
https://github.com/Hermanoid/UltimateLED2
我还有一些旁白要问...首先,我忘记在回购协议中删除我 Raspberry Pi 的设备密钥和 ID。这会是一个(半途可行,或至少可能)安全问题吗?
而且,我的 VS 错误列表中有一大堆版本不匹配警告。在其他项目中,我会简单地在 Web.xml 或 App.xml 文件中启动一些版本重定向,但是("Runtime Directives" XML 文件除外)那些不会存在于这个项目中。我能做些什么来解决这些问题?
谢谢!
卢卡斯·尼沃纳
应用程序的功能需要增强。由于应用程序现在需要将双向信息从它发送到 Azure。它需要在应用程序清单中检查客户端和服务器
另外对于Stuart Smith的回复,正如你在GitHub中提供的代码,会导致死锁,因为当所有操作都已完成时,Task方法没有标记为完成done.You可以参考this题目,也许你会明白Task.Wait
和await
的区别。我修改了如下代码,它工作正常。
public sealed partial class MainPage : Page
{
const string DeviceId = "<deviceId>";
const string DeviceKey = "<device primary key>";
const string HubEndpoint = "<azure iothub host name>";
const int LEDPinNumber = 5;
GpioPin LEDPin;
bool LEDPinState;
Brush StatusNormalBrush;
DeviceClient deviceClient;
public MainPage()
{
this.InitializeComponent();
StatusNormalBrush = StatusIndicator.Fill;
if (!TryInitGPIO().Result)
{
WriteMessage("GPIO initialization failed");
}
deviceClient = DeviceClient.Create(HubEndpoint,
AuthenticationMethodFactory.CreateAuthenticationWithRegistrySymmetricKey(DeviceId, DeviceKey), TransportType.Mqtt_WebSocket_Only);
deviceClient.SetMethodHandlerAsync("ToggleLED", new MethodCallback(ToggleLEDMethod), null);
}
private Task<MethodResponse> ToggleLEDMethod(MethodRequest methodRequest, object userContext)
{
WriteMessage("Recieved Direct Request to toggle LED");
LEDPinState = !LEDPinState;
UpdateLight();
return Task.FromResult( new MethodResponse(Encoding.UTF8.GetBytes("{\"LightIs\":\"" + (LEDPinState ? "On" : "Off") + "\"}"), 200));
}
public Task<bool> TryInitGPIO()
{
GpioController gpioController = GpioController.GetDefault();
if (gpioController == null)
{
WriteMessage("This Device is not IoT friendly! (No GPIO Controller found)", true);
return Task.FromResult(false);
}
if (gpioController.TryOpenPin(LEDPinNumber, GpioSharingMode.Exclusive, out LEDPin, out GpioOpenStatus openStatus))
{
WriteMessage($"Output Pin ({LEDPinNumber}) Opened Successfully!!");
}
else
{
WriteMessage($"Output Pin ({LEDPinNumber}) Failed to Open", true);
return Task.FromResult(false);
}
LEDPin.SetDriveMode(GpioPinDriveMode.Output);
LEDPin.Write(GpioPinValue.High);
LEDPinState = true;
UpdateLight();
WriteMessage("Output Pin initialized and on");
return Task.FromResult(true);
}
private async void WriteMessage(string message, bool isError = false)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
StringBuilder sb = new StringBuilder(OutputBox.Text);
if (isError)
{
sb.AppendLine();
sb.AppendLine("*************ERROR**************");
}
sb.AppendLine(message);
if (isError)
{
sb.AppendLine("*************END ERROR**************");
sb.AppendLine();
}
OutputBox.Text = sb.ToString();
});
}
private void ManualToggle_Click(object sender, RoutedEventArgs e)
{
WriteMessage("Recieved Manual Toggle");
LEDPinState = !LEDPinState;
UpdateLight();
}
private async void UpdateLight()
{
LEDPin.Write(LEDPinState ? GpioPinValue.High : GpioPinValue.Low);
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
StatusIndicator.Fill = LEDPinState ? new SolidColorBrush(Colors.Red) : StatusNormalBrush;
});
}
}
我有一个非常简单的项目,我的目标是能够通过直接方法调用(通过 Azure IoT 中心)在我的 Raspberry Pi 3、运行 上切换 LED宁 Windows 10 个物联网核心。
目前我写的程序只显示一个白色的盒子,里面有一个x,就像邮件信封一样,后端光控代码不响应直接方法调用。但是,当连接到 Visual Studio 2017 远程调试器时,UI 背后的代码似乎 运行 非常好(或者我认为如此),所以我认为直接方法调用失败是由于我的互联网连接(正如我在 this question 中询问的那样)。
然而,UI 背后的代码正在请求将一个小的程序执行更新打印到文本框中,而不存在的 UI 从未响应,因此阻止了该程序首先继续打开 Azure Iot Hub 设备客户端。
而不是完全放弃 UI,我想弄清楚是什么阻止了我的 UI 做任何事情。奇怪的是,当我第一次尝试我的程序(减去 IoT 代码)时,UI 工作得很好。 坦率地说,我完全不知道什么会突然出错(Pi 是 在头部模式下,如果你想知道的话),所以我想我最好的行动方案是发布我的代码,看看是否有其他人可以复制这些问题。
与其将我所有的代码都转储到这个 post 中,否则有人必须将它重建到一个项目中,然后可能会遗漏一些东西,等等......我只是把它全部推到一个Git 存储库,可在此处找到:
https://github.com/Hermanoid/UltimateLED2
我还有一些旁白要问...首先,我忘记在回购协议中删除我 Raspberry Pi 的设备密钥和 ID。这会是一个(半途可行,或至少可能)安全问题吗?
而且,我的 VS 错误列表中有一大堆版本不匹配警告。在其他项目中,我会简单地在 Web.xml 或 App.xml 文件中启动一些版本重定向,但是("Runtime Directives" XML 文件除外)那些不会存在于这个项目中。我能做些什么来解决这些问题?
谢谢!
卢卡斯·尼沃纳
应用程序的功能需要增强。由于应用程序现在需要将双向信息从它发送到 Azure。它需要在应用程序清单中检查客户端和服务器
另外对于Stuart Smith的回复,正如你在GitHub中提供的代码,会导致死锁,因为当所有操作都已完成时,Task方法没有标记为完成done.You可以参考this题目,也许你会明白Task.Wait
和await
的区别。我修改了如下代码,它工作正常。
public sealed partial class MainPage : Page
{
const string DeviceId = "<deviceId>";
const string DeviceKey = "<device primary key>";
const string HubEndpoint = "<azure iothub host name>";
const int LEDPinNumber = 5;
GpioPin LEDPin;
bool LEDPinState;
Brush StatusNormalBrush;
DeviceClient deviceClient;
public MainPage()
{
this.InitializeComponent();
StatusNormalBrush = StatusIndicator.Fill;
if (!TryInitGPIO().Result)
{
WriteMessage("GPIO initialization failed");
}
deviceClient = DeviceClient.Create(HubEndpoint,
AuthenticationMethodFactory.CreateAuthenticationWithRegistrySymmetricKey(DeviceId, DeviceKey), TransportType.Mqtt_WebSocket_Only);
deviceClient.SetMethodHandlerAsync("ToggleLED", new MethodCallback(ToggleLEDMethod), null);
}
private Task<MethodResponse> ToggleLEDMethod(MethodRequest methodRequest, object userContext)
{
WriteMessage("Recieved Direct Request to toggle LED");
LEDPinState = !LEDPinState;
UpdateLight();
return Task.FromResult( new MethodResponse(Encoding.UTF8.GetBytes("{\"LightIs\":\"" + (LEDPinState ? "On" : "Off") + "\"}"), 200));
}
public Task<bool> TryInitGPIO()
{
GpioController gpioController = GpioController.GetDefault();
if (gpioController == null)
{
WriteMessage("This Device is not IoT friendly! (No GPIO Controller found)", true);
return Task.FromResult(false);
}
if (gpioController.TryOpenPin(LEDPinNumber, GpioSharingMode.Exclusive, out LEDPin, out GpioOpenStatus openStatus))
{
WriteMessage($"Output Pin ({LEDPinNumber}) Opened Successfully!!");
}
else
{
WriteMessage($"Output Pin ({LEDPinNumber}) Failed to Open", true);
return Task.FromResult(false);
}
LEDPin.SetDriveMode(GpioPinDriveMode.Output);
LEDPin.Write(GpioPinValue.High);
LEDPinState = true;
UpdateLight();
WriteMessage("Output Pin initialized and on");
return Task.FromResult(true);
}
private async void WriteMessage(string message, bool isError = false)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
StringBuilder sb = new StringBuilder(OutputBox.Text);
if (isError)
{
sb.AppendLine();
sb.AppendLine("*************ERROR**************");
}
sb.AppendLine(message);
if (isError)
{
sb.AppendLine("*************END ERROR**************");
sb.AppendLine();
}
OutputBox.Text = sb.ToString();
});
}
private void ManualToggle_Click(object sender, RoutedEventArgs e)
{
WriteMessage("Recieved Manual Toggle");
LEDPinState = !LEDPinState;
UpdateLight();
}
private async void UpdateLight()
{
LEDPin.Write(LEDPinState ? GpioPinValue.High : GpioPinValue.Low);
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
StatusIndicator.Fill = LEDPinState ? new SolidColorBrush(Colors.Red) : StatusNormalBrush;
});
}
}