我已经挖了大约一个星期,并没有办法解决这个问题。我的Arduino代码工作了一段时间(几次/几天),然后突然停止。我试图在Arduino中实现一个WebClient,每当检测到一个动作/动作停止时,每次(定期 - 每90秒)向其他服务器发送一个HTTP GET请求。
您可以在下面找到代码。有人可以帮忙吗?
#include <Ethernet2.h>
#include <SPI.h>
byte mac[] = { 0x90, 0xA2, 0xDA, 0x10, 0x73, 0x88 };
IPAddress ip(192,168,20,84);
IPAddress server(192,168,50,93); // Google
IPAddress myDns(8, 8, 8, 8);
EthernetClient client;
//getMovement - sends a GET request when motion is detected
void getMovement() {
client.stop();
if (client.connect(server, 8080)) {
client.println("GET /GetARoomMaven/motion?roomId=1&movement=1");
client.println();
Serial.println("Movement Request Sent");
} else {
Serial.println("connection failed");
}
}
//getNoMovement - sends a GET request when motion had stopped
void getNoMovement() {
client.stop();
if (client.connect(server, 8080)) {
client.println("GET /GetARoomMaven/motion?roomId=1&movement=0");
client.println();
Serial.println("Movement Request Sent");
} else {
Serial.println("connection failed");
}
}
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 10;
//the time when the sensor outputs a low impulse
long unsigned int lowIn;
//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 90000;
//
boolean lockLow = true;
boolean takeLowTime;
int pirPin = 2; //the digital pin connected to the PIR sensor's output
int ledPin = 13;
/////////////////////////////
//SETUP
void setup(){
Serial.begin(9600);
pinMode(pirPin, INPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(pirPin, LOW);
Ethernet.begin(mac);
//give the sensor some time to calibrate
Serial.print("calibrating sensor ");
for(int i = 0; i < calibrationTime; i++){
Serial.print(".");
delay(1000);
}
Serial.println(" done");
Serial.println("SENSOR ACTIVE");
delay(50);
loop();
}
////////////////////////////
//LOOP
void loop(){
if(digitalRead(pirPin) == HIGH){
digitalWrite(ledPin, HIGH); //the led visualizes the sensors output pin state
if(lockLow){
//makes sure we wait for a transition to LOW before any further output is made:
lockLow = false;
Serial.print("motion detected at ");
Serial.print(millis()/1000);
Serial.println(" sec");
getMovement();
}
takeLowTime = true;
}
if(digitalRead(pirPin) == LOW){
digitalWrite(ledPin, LOW); //the led visualizes the sensors output pin state
if(takeLowTime){
lowIn = millis(); //save the time of the transition from high to LOW
takeLowTime = false; //make sure this is only done at the start of a LOW phase
}
//if the sensor is low for more than the given pause,
//we assume that no more motion is going to happen
if(!lockLow && millis() - lowIn > pause){
//makes sure this block of code is only executed again after
//a new motion sequence has been detected
lockLow = true;
Serial.print("motion ended at "); //output
Serial.print((millis() - pause)/1000);
Serial.println(" sec");
getNoMovement();
}
}
}
答案 0 :(得分:0)
如果没有更好的症状描述,很难说。 LED仍然闪烁吗?
如果是,套接字代码对我来说似乎不对:
void getMovement() {
client.stop();
你必须记住,TCP需要连接跟踪,所以你不能立即停止套接字,它必须留一点来确认发送的数据包。
如果你看一下实现:
void EthernetClient::stop() {
if (_sock == MAX_SOCK_NUM)
return;
[...]
}
如果您一次打开stop()
(平台上为4),则 MAX_SOCK_NUM
将失败。这会发生吗?
在所有情况下,您应该尽可能避免动态分配,您应该只有一个函数sendMovement(bool detected)
来编写检测到的值(getMovement
和getNoMovement
是相同的功能,因此将它们分解)。您应该尽可能地重新使用客户端(避免关闭套接字并重新打开它,除非您从任何套接字函数中收到错误)。最后,您可能希望在数字输入引脚上设置一个中断(使用某些软件去抖动)以避免轮询它,这会释放CPU,并且根据配置,可能会释放更多时间来处理SPI消息。
如果LED没有闪烁,请尝试注释SPI相关代码(EthernetClient
代码)并检查它是否有效(在这种情况下,我会检查硬件是否有错误,有些套接字代码忙于循环(socket::send
执行此操作),它永远不会完成并阻止loop
函数继续进行。在这种情况下,如果你使用JTAG来暂停CPU,那么它就会出现问题。使用client.connect
或client.println
方法。
如果它仍然不起作用(LED没有闪烁而没有SPI代码),则问题可能是硬件,检查电压/温度/ JTAG连接到电路板以中断CPU以找出它被击中的位置
顺便说一句,如果您正在使用HTTP,请求是错误的,应该是:
GET url HTTP/1.1\r\n
Host: yourserverhost.com\r\n
Connection: Keep-Alive\r\n
\r\n
即使对于HTTP / 1.0,HTTP/1.x
之后的部分GET url
也是绝对必需的。除非您已经编写了自己的服务器(在这种情况下,不需要模仿HTTP),否则它根本不起作用,甚至一次也不起作用。