Http Arduino以太网解析XML

Http Arduino以太网解析XML,http,get,arduino,Http,Get,Arduino,我正在使用Arduino Uno和以太网屏蔽从OpenWeatherMap.org提取xml数据。我有api链接和一个密钥,在web浏览器上一切正常。下面是我的代码,但是当我读取get命令的响应时,我得到的只是“ÿ”,而不是我所期望的 当我把arduino用作服务器时,我可以连接到它,我可以在命令提示符下ping它,这样我就知道它在网络上,并且电路板没有故障,所以一定是我的代码出了问题。我在arduino站点上遵循了教程并加载了示例以获取数据,但这也不起作用,我得到的只是一条“未连接”消息 有人

我正在使用Arduino Uno和以太网屏蔽从OpenWeatherMap.org提取xml数据。我有api链接和一个密钥,在web浏览器上一切正常。下面是我的代码,但是当我读取get命令的响应时,我得到的只是“ÿ”,而不是我所期望的

当我把arduino用作服务器时,我可以连接到它,我可以在命令提示符下ping它,这样我就知道它在网络上,并且电路板没有故障,所以一定是我的代码出了问题。我在arduino站点上遵循了教程并加载了示例以获取数据,但这也不起作用,我得到的只是一条“未连接”消息

有人能看看我的代码,看看我做错了什么吗

编辑:我添加了额外的循环来打印所有xml数据,但是程序仍然在(!client.available())时卡在
。如果我把它注释掉,我会进入“等待服务器响应”,但不会再进一步了。我已检查arduino si是否与网络中的所有其他设备位于同一子网掩码上

// Based on:
// Read Yahoo Weather API XML
// 03.09.2012
// http://forum.arduino.cc/index.php?topic=121992.0
//


#include <SPI.h>
#include <Ethernet.h>
#include <TextFinder.h>



int cityID=2644487; //Lincoln, UK
byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02};
byte ip[] = {192, 168, 1, 89};
byte gateway[] = {192, 168, 1, 254};
byte subnet[] = {255, 255, 255, 0};
//Open weather map xml
char server[] = "http://api.openweathermap.org";
int port = 80; //usually 80 for http.
char APIkey[33] = "HIDDENAPIKEY";


EthernetClient client;
char temperature[30];


void setup()
{
  pinMode(10, OUTPUT);
  digitalWrite(10,HIGH);
  Serial.begin(9600);
  Serial.println("Initialising...");

  // Start Ethernet
  if(!Ethernet.begin(mac)){//if DHCP does not automatically connect
     Serial.println("Invalid Connection");
  }


    Serial.println("");
    Serial.print("Connecting to OWM server using cityID: ");
    Serial.println(cityID);
    Serial.print("Using API key: ");
    Serial.println(APIkey); 

  if (client.connect(server,port))
  {
    client.println("GET /data/2.5/weather?id=2644487&appid=HIDDENAPIKEY&mode=xml&units=metric HTTP/1.1");
    client.println("HOST: api.openweathermap.org");
    client.println();
    Serial.println("Connected to XML data.");

   while(!client.available()); //wait for client data to be available
   Serial.println("Waiting for server response...");
   while(client.available()){

      char c = client.read();
      Serial.println(c);
   }
  } 


}

void loop()
{

}
//基于:
//阅读雅虎天气API XML
// 03.09.2012
// http://forum.arduino.cc/index.php?topic=121992.0
//
#包括
#包括
#包括
int cityID=2644487//林肯,英国
字节mac[]={0x00,0xAA,0xBB,0xCC,0xDE,0x02};
字节ip[]={192,168,1,89};
字节网关[]={192168,1254};
字节子网[]={255,255,255,0};
//开放式天气图xml
字符服务器[]=”http://api.openweathermap.org";
int端口=80//http通常为80。
char APIkey[33]=“HIDDENAPIKEY”;
以太网络客户端;
焦温[30];
无效设置()
{
pinMode(10,输出);
数字写入(10,高);
Serial.begin(9600);
Serial.println(“初始化…”);
//启动以太网
如果(!Ethernet.begin(mac)){//如果DHCP没有自动连接
Serial.println(“无效连接”);
}
Serial.println(“”);
Serial.print(“使用cityID连接到OWM服务器”);
序列号println(cityID);
Serial.print(“使用API密钥:”);
Serial.println(APIkey);
if(客户端连接(服务器、端口))
{
client.println(“GET/data/2.5/weather?id=2644487&appid=HIDDENAPIKEY&mode=xml&units=metric-HTTP/1.1”);
client.println(“主机:api.openweathermap.org”);
client.println();
println(“连接到XML数据”);
while(!client.available());//等待客户端数据可用
Serial.println(“等待服务器响应…”);
while(client.available()){
char c=client.read();
序列号println(c);
}
} 
}
void循环()
{
}

对于开始,您的主机标题错误,请仅使用域名:

client.println("HOST: api.openweathermap.org");
我在这里看到的第二个问题是,您并没有从服务器读取整个响应,而是只读取一个字符。 您必须等待响应数据可用,然后读取所有数据并在开始时对其进行解析或打印

这部分是错误的:

char c = client.read();
Serial.println(c);
应该类似于:

while (!client.available());  //Wait client data to be available
while (client.available()) {  //Print all the data
    char c = client.read();
    Serial.println(c);
}

为什么只打印单个字符?你必须得到完整的回应,看看会发生什么。请记住,您需要从响应中解析出标题。要查找此项,请搜索\r\n\r\n序列。之后,您的身体数据与XMLX一起存在,您的计算机是否在同一网络上,并且能够访问internet?如果是,请转到cmd并键入命令“ipconfig”。检查Arduino上的子网掩码,确保它与您的计算机匹配。如果它与网络的其他部分不同,则只能进行部分连接。谢谢,在您提出建议后,我已更改了代码。我还检查了子网掩码,所有设备都在同一子网中,我编辑了原始帖子来解释。谢谢你,我添加了一些额外的串行打印,以查看代码被卡住的地方,似乎它没有从get命令得到响应。我从未得到“等待服务器响应”serial.println(“连接到XML数据”)的串行打印;而(!client.available())//等待客户端数据可用Serial.println(“等待服务器响应…”);虽然(!client.available()){char c=client.read();Serial.println(c);}我已经纠正了第二个while循环。不应该有!因为您正在循环,而数据可供读取。谢谢,它确实看起来很奇怪,因为它是同一个循环!然而,它仍然停留在等待GET命令的响应上,我已经将原始帖子编辑为clarify@tilz0R我不相信你的代码,假设服务器正在发送100个字节,只要第一个字节到达,你就检查'client.available()'它等于一,因此你通过第一个循环,进入第二个循环。现在您读取了一个字符,但无论出于何种原因,在再次检查“client.available()”之前,来自服务器的下一个字节没有放入传入缓冲区:现在您离开循环,无法读取所有传入数据。[继续][继续]如果你以某种方式将所有东西都放入一个外部循环,并正确处理它,那么你就可以毫无问题地处理这种情况。。但是,在本例中,指令“while(!client.available());”这似乎毫无意义。