我正在尝试使用GPRS屏蔽(Geeetech的SIM900屏蔽)将Arduino传感器数据发送到服务器。我有这个特殊的设置,因为数据将更新到网站,并且设备将漫游。我不能使用http://www.cosm.org,因为据我所知,每15分钟更新一次,我需要每5-10秒更新一次。

为了连接我尝试了下面的代码以形成UDP连接,但它没有通过发送到接收IP和端口。我不知道为什么Arduino端未发生任何错误,并且服务器端已显示可与发送UDP消息的iPhone应用程序配合使用。

///connect
void connectUDP()
{
 mySerial.println("AT+CSTT=\"APN\"");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIICR");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIFSR");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIPSTART=\"UDP\",\"SERVER IP\",\"SERVER PORT\"");
 delay(3000);
 ShowSerialData();
 mySerial.println();

}


///send udp packet to server 
void sendUDP()
{
 for(int x = 0; x < 30; x++){
   mySerial.println("AT+CIPSEND"); 
   delay(100);
   ShowSerialData();
   mySerial.println("\"hello world\"");
   delay(100);
   ShowSerialData();
   mySerial.println((char)26);
   delay(1000);
   ShowSerialData();
 }
 mySerial.println();
 //ShowSerialData();
}


服务器端如下所示(用python编写):

import SocketServer

PORTNO = 14

class handler(SocketServer.DatagramRequestHandler):
    def handle(self):
        newmsg = self.rfile.readline().rstrip()
    print (newmsg)
        self.wfile.write(self.server.oldmsg)
        self.server.oldmsg = newmsg

s = SocketServer.UDPServer(('',PORTNO), handler)
print "Awaiting UDP messages on port %d" % PORTNO
s.oldmsg = "This is the starting message."
s.serve_forever()


我可以看到一个可能的解决方案,可能是将其更改为TCP连接,但我不知道该怎么做。 ..

评论

您是否能够根据您发送的串行端口命令验证GPRS屏蔽能否执行其他功能(例如拨打电话号码)?

是的,它可以基于通过串口发送的AT命令发送短信,打电话和接收http数据。

并且可以验证回显“ test123” | nc -u YOUR_SERVER_IP 14在服务器中产生输出吗?

因此,从arduino或其他设备发送它?因为我已经使用过一个iPhone应用程序,它可以将iPhone传感器数据作为UDP数据包发送。该过程运行完美,服务器正在接收数据,因此服务器端似乎没有问题。

你有没有做这个工作?如果是这样,也许建议一个答案?我主要提到它,因为它具有2k的视图,最好“解决”它。

#1 楼

您的代码似乎有点不完整-我认为这是因为您希望仅包括显着功能。

一旦GeeTech Wiki-Arduino GPRS Shield-一个简单的源代码示例(他们的错字,不是我的)的必需的遗漏行被添加,完整的(最小)代码似乎是:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(7, 8);

///connect
void connectUDP()
{
 mySerial.println("AT+CSTT=\"APN\"");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIICR");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIFSR");
 delay(3000);
 ShowSerialData();
 mySerial.println("AT+CIPSTART=\"UDP\",\"SERVER IP\",\"SERVER PORT\"");
 delay(3000);
 ShowSerialData();
 mySerial.println();
}


///send udp packet to server 
void sendUDP()
{
 for(int x = 0; x < 30; x++){
   mySerial.println("AT+CIPSEND"); 
   delay(100);
   ShowSerialData();
   mySerial.println("\"hello world\"");
   delay(100);
   ShowSerialData();
   mySerial.println((char)26);
   delay(1000);
   ShowSerialData();
 }
 mySerial.println();
 //ShowSerialData();
}

void ShowSerialData()
{
 while(mySerial.available()!=0)
   Serial.write(mySerial.read());
}

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
  connectUDP();
  sendUDP();
}


关于为什么它不起作用,我不确定,我仍在努力。

作为健全性检查,我认为在您的实际Arduino草图中,您用实际值(即,真实的IP地址和端口号)替换了SERVER IPSERVER PORT吗? SERVER IPSERVER PORT都不是变量(全局变量或其他变量),也不是#define。由于您没有包括整个草图,因此很难以其他方式分辨。

此外,请确保您在Arduino草图中指定的服务器地址与运行Python脚本的服务器的IP地址相匹配,并且在Arduino草图中指定的端口与中的PORTNO匹配Python脚本。抱歉,我要说的很明显,但是,就像我说的那样,这是一项健全性检查。

关于第二点:


我可以看到解决方案可能是将其更改为TCP连接,但我不知道该怎么做...


您只需要在以下第一行中将UDP更改为TCP

 mySerial.println("AT+CIPSTART=\"UDP\",\"SERVER IP\",\"SERVER PORT\"");


,这样它就变成了<SERVER IP><SERVER PORT>的实际值,例如:

 mySerial.println("AT+CIPSTART=\"TCP\",\"SERVER IP\",\"SERVER PORT\"");


在服务器端,Python脚本中的以下行:

 mySerial.println("AT+CIPSTART=\"TCP\",\"116.228.221.51\",\"8500\"");


需要更改为:

s = SocketServer.UDPServer(('',PORTNO), handler)
print "Awaiting UDP messages on port %d" % PORTNO


再次,请确保服务器端Python脚本中的PORTNO匹配在AT命令。


1参见m2msupport.net-AT + CIPSTART。相关说明为

s = SocketServer.TCPServer(('',PORTNO), handler)
print "Awaiting TCP messages on port %d" % PORTNO


请注意,该网页有错字,并在Start a UDP connection示例中显示了一个句点,逗号应为逗号。我已在上面的示例中纠正了这种错字。