WebClient和MotionDetector会在一段时间后停止

时间:2018-01-19 11:10:02

标签: c++ arduino webclient arduino-ide motion

我已经挖了大约一个星期,并没有办法解决这个问题。我的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();
           }
       }
  }

1 个答案:

答案 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)来编写检测到的值(getMovementgetNoMovement是相同的功能,因此将它们分解)。您应该尽可能地重新使用客户端(避免关闭套接字并重新打开它,除非您从任何套接字函数中收到错误)。最后,您可能希望在数字输入引脚上设置一个中断(使用某些软件去抖动)以避免轮询它,这会释放CPU,并且根据配置,可能会释放更多时间来处理SPI消息。

如果LED没有闪烁,请尝试注释SPI相关代码(EthernetClient代码)并检查它是否有效(在这种情况下,我会检查硬件是否有错误,有些套接字代码忙于循环(socket::send执行此操作),它永远不会完成并阻止loop函数继续进行。在这种情况下,如果你使用JTAG来暂停CPU,那么它就会出现问题。使用client.connectclient.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),否则它根本不起作用,甚至一次也不起作用。