跳转到主要内容

AZURE 与 EDISON 的连接性以及采用一款 WINDOWS 手机应用来控制 EDISON

editor 提交于

<strong> 简介</strong>

本文将介绍连接 Edison 和 Windows azure 的流程,并完成一些炫酷的动作,比如控制。本示例仅开启和关闭连接至 Edison 开发板(与 Arduino breakout 开发板搭配使用)任意数字针脚的 LED。首先让我们看看它是如何工作的。azure 移动服务在 Edison 和控制器(此处使用 Windows 手机应用)之间充当桥梁的作用。Edison 将从移动服务的表中读取某个属性的值。Windows 手机应用将更新表中的值,因此我们要根据相应的值对 Edison 代码进行修改。

<strong> 先决条件</strong>

假设读者对 Windows 手机应用开发有一些基本的了解,并且能够连接该应用与 azure 移动服务。如果不了解如何创建应用后端,请点击该链接。

<strong> 硬件要求</strong>

1、带有 Arduino breakout 开发板的英特尔 Edison

2、LED

<strong> 软件要求</strong>

1、Visual studio

2、Arduino IDE

<strong> 服务要求</strong>

1: Azure 移动服务

首先创建 azure 移动服务。许多文章介绍了如何创建 azure 移动服务。访问本链接,创建包含单个表格(我们称之为 controltable)的移动服务。该表格包含两列,分别名为 "status" 和"name"。status 列的值为 1 或 0。name 列的值设置为 Edison/Arduino。

<center><img src="http://intel.eetrend.com/files/2016-04/wen_zhang_/100001418-2327-screen…; alt=""></center>

现在我们要开发将添加/修改属性值的 windows 手机应用。下图向我们展示了 azure sql 表的截图。请注意,“device” 的属性值无关紧要。你甚至可以删除这一属性。

接下来是如何开发 Windows 手机应用。

<strong>Windows 手机应用</strong>

我们的应用仅包含两个按钮:on 和 off。应用截图如下所示。

<center><img src="http://intel.eetrend.com/files/2016-04/wen_zhang_/100001418-2328-wpss2…; alt=""></center>

你可以忽略退出按钮,实际上我是想尝试添加一些特性。那么,这些按钮有什么作用?它们可以更新 “status” 属性的值。如果按下 on 按钮,“status” 的值将变成 1 或 0。

尽管有一个问题。 如果什么都没有创建,那么更新什么? 为此,我们要两次部署该应用。 第一次,创建表格,分配一些默认值。 第二次,仅更新之前更新过的值。

现在,应用已经就绪。测试该应用,并检查 “status” 是否已经更新。如果已经更新,这样就可以了。应用准备好了。接下来是 Edison 代码部分。

<strong>Edison 代码</strong>

下面我们进入 Edison 部分。编写 Edison 代码之前,请按照此处的步骤对 Edison 进行配置。连接 Edison 后,注意一下通讯端口的编号。然后打开 Arduino IDE,并从开发板中选择英特尔 Edison。如果没有找到英特尔 Edison 选项,需要通过 boards manager 选项下载所需的文件。

<center><img src="http://intel.eetrend.com/files/2016-04/wen_zhang_/100001418-2329-screen…; alt=""></center>

打开 Arduino IDE 后,将有两个之前提到的函数。Void setup() 和 void loop()。Edison 内置了 Wi-Fi。我们将使用 Wi-Fi 联网。因此第一步是纳入面向 Wi-Fi 的库。前往 Sketch->include library->Wi-Fi。然后,添加以下代码,连接 Wi-Fi。

01 #include <SPI.h>
02 #include <WiFi.h>
03 WiFiClient client;
04
05
06 char ssid[] = "networkssid"; // your network SSID (name)
07 char pass[] = "password"; // your net ork password (use for WPA, or use as key for WEP)
08 int keyIndex = 0; // your network key Index number (needed only for WEP)
09 int status = WL_IDLE_STATUS;
10
11 void setup()
12 {
13 pinMode(13,OUTPUT);
14 digitalWrite(13,HIGH);
15 Serial.begin(115200);
16 while (!Serial) {
17 ; // wait for serial port to connect. Needed for Leonardo only
18 }
19
20 // check for the presence of the shield:
21 if (WiFi.status() == WL_NO_SHIELD) {
22 Serial.println("WiFi shield not present");
23 // don't continue:
24 while(true);
25 }
26
27 String fv = WiFi.firmwareVersion();
28 if( fv != "1.1.0" )
29 Serial.println("Please upgrade the firmware");
30
31 // attempt to connect to Wifi network:
32 while (status != WL_CONNECTED) {
33 Serial.print("Attempting to connect to SSID: ");
34 Serial.println(ssid);
35 // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
36 status = WiFi.begin(ssid, pass);
37 }
38 }

上述代码负责通过 Wi-Fi 将 Edison 连接至互联网。我们还把 PIN 13 设置成输出模式,当前状态为关闭状态。我们要使用 IDE 的 serial monitor 监控该流程。现在,前往 void loop()。从 azure 检索数据通过 http get 方法完成。

1 void loop()
2 {
3 send_request();
4 wait_response();
5 read_response();
6 end_request();
7 delay(100);
8 }

这些函数将从 azure 表格检索数据。但在深入了解这些方法之前,我们需要添加一些全局变量以连接 Edison 和 azure 服务。添加这些全局变量。

1 const char* server= "YourAzureService.azure-mobile.net";
2 const char* table_name= "TableName";
3 const char* ams_key="YourApplicationKey";

1 char buffer[64];

应用密钥位于azure 门户的 manage keys 按钮中。现在,我们要为 void loop() 中的方法编写代码。

01 void send_request()
02 {
03 Serial.println("\nconnecting...");
04
05 if (client.connect(server, 80))
06 {
07
08 sprintf(buffer, "GET /tables/%s HTTP/1.1", table_name);
09 client.println(buffer);
10
11 // Host header
12 sprintf(buffer, "Host: %s", server);
13 client.println(buffer);
14
15 // Azure Mobile Services application key
16 sprintf(buffer, "X-ZUMO-APPLICATION: %s", ams_key);
17 client.println(buffer);
18
19 // JSON content type
20 client.println("Content-Type: application/json");
21
22 // Content length
23 client.print("Content-Length: ");
24 client.println(strlen(buffer));
25
26 // End of headers
27 client.println();
28
29 // Request body
30 client.println(buffer);
31
32 }
33 else
34 {
35 Serial.println("connection failed");
36 }
37 }

我们执行 HTTP 请求并调用 GET,指定了前面提到的表格的名称,以及服务器和代码密钥的成名,这样有利于准确检索数据。然后将数据检索的格式规定为 JSON 格式。现在我们来编写 wait_response() 的代码

01 void wait_response()
02 {
03 while (!client.available())
04 {
05 if (!client.connected())
06 {
07 return;
08 }
09 }
10 }

然后需要读取检索的数据。由于采用 JSON 格式,我们需要解析 JSON 字符串,以获取所需的值。如下所示为某示例字符串。

{"id":"2492D996-C471-48F0-B3C9-F33E3B37477F","status":"0","name":"arduino"}

ArduinoJson 是一种非常高效的库,可以完成大部分解析。但检索的 JSON 字符串封存在 '[' and ']'中。必须删除它们,库才能工作。因此,首先你需要将库纳入代码中,添加以下全局变量,并添加

1 #include <ArduinoJson.h>

1 #define RESPONSE_JSON_DATA_LINENNO 10

1 int charIndex=0; StaticJsonBuffer<200> jsonbuffer;

然后在 read_response method() 中编写以下代码。

01 void read_response()
02 {
03 boolean bodyStarted;
04 int jsonStringLength;
05 int jsonBufferCntr=0;
06 int numline=RESPONSE_JSON_DATA_LINENNO;
07 //Ignore the response except for the 10th line
08 while (client.available())
09 {
10 //Serial.println("Reading:");
11 char c = client.read();
12 if (c == '\n')
13 {
14 numline -=1;
15 }
16 else
17 {
18 if (numline == 0 && (c!='[')&& (c!=']') )
19 {
20 buffer[jsonBufferCntr++] = c;
21 buffer[jsonBufferCntr] = '\0';
22 }
23 }
24 }
25 Serial.println("Received:");
26 Serial.println(buffer);
27 Serial.println("");
28 parse();
29 }

上述代码将读取响应,而解析方法负责解码字符串。parse() 方法如下所示。In the Parse() method itself, we will change the status of the PIN13.

01 void parse()
02 {
03 StaticJsonBuffer<150> jsonbuffer;
04 JsonObject& root = jsonbuffer.parseObject(buffer);
05 if(!root.success())
06 {
07 Serial.println("PARSING FAILED!!!");
08 return;
09 }
10 int f= root["status"];
11 Serial.println("Decoded: ");
12 Serial.println(f);
13 if(f==0)
14 digitalWrite(13,LOW);
15 else
16 digitalWrite(13,HIGH);
17 }

在上述代码中,f 保存状态属性值。然后,我们检查 f 的值,并最终将 PIN 设置为 HIGH 或 LOW。

如欲获取有关 ArduinoJson 库的详细文档,请访问此链接。 不过,该库存在一个问题。这点我们稍后讨论。现在我们来编写其他方法的代码。

1 void end_request()
2 {
3 client.stop();
4 }

现在,你会发现,编译代码时,很可能遇到一些错误。需要将这些错误删除。继续下一步之前,看一下这个问题。 文件 WString.h 丢失了几行代码。 从此处可看出差异。你需要更新此处的文件。

C:\Users\Username\AppData\Roaming\Arduino15\packages\Intel\hardware\i686\1.6.2+1.0\cores\arduino\WString.h

更新之后,错误将得以排除。编译代码后,将其刻录至 Edison,这样就完成了。将代码刻录至 Edison时,将 LED 较长的一端连接至 PIN13,较短的一端连接至 Gnd。还可以通过较长的那端添加一个可选的 233 欧姆电阻器。这样,通过 Windows Azure 控制 Edison 的Windows手机应用就已准备就绪。如下所示为 Edison 作用时串行窗口的截图。

第一阶段是 Edison 尝试连接 Wi-Fi 网络。

<center><img src="http://intel.eetrend.com/files/2016-04/wen_zhang_/100001418-2330-screen…; alt=""></center>

下一阶段是 Edison 尝试连接 Azure 移动服务。连接后,它可获取 JSON 数据,获取的数据由JSON库进行解码,然后我们就可以获得解码后的结果。解码后的结果负责Edison上PIN13 的状态。

<center><img src="http://intel.eetrend.com/files/2016-04/wen_zhang_/100001418-2331-screen…; alt=""></center>

<strong>总结: </strong>

我们在本文学习了如何通过Azure 移动服务控制 Edison。移动服务充当桥梁,发挥连接的作用。Windows手机应用修改azure 表格中的数据,并最终控制 Edison。本文没有介绍 Windows 手机应用开发,不过提供了相关链接,以提供大家需了解的信息。整个Edison代码以文本文件的形式上传。

文章来源:<a href="https://software.intel.com/zh-cn/articles/azure-connectivity-with-ediso…