Arduino Processing客户端无法将文件上传到PHP服务器

时间:2015-10-06 01:58:00

标签: java network-programming arduino processing

背景 我想要压力传感器(他们正在工作)触发内置摄像头并在猫上床时拍照,上传图片并给我发电子邮件,以便我可以在网站上查看实时图像。

PHP服务器 我在这个结构的根上有一个php server running 127.0.0.1:8080

 NetworkedCat -->
                  data --> script-cat.php
                  index.html 
                  NetworkedCat.pde 
                  img.jpg
                  save2web.php
                  swiftmailer --> libs, etc

在浏览器上进行测试save2web.phpcat-script.php正在运行,即脚本正在上传和通过电子邮件发送。

Arduino的

Arduino应用应该执行以下操作:

  1. 从压力传感器接收输入
  2. 验证是否超过阈值
  3. 从内置摄像头拍摄照片
  4. 将图片上传到网站
  5. 发送邮件通知上传
  6. 压力传感器()也在读取和打印,并且已经校准了阈值。

    NetworkedCat.pde不是由串行事件触发的。

    请注意:

    Arduino Processing在另一个localhost打开port 80,因为php server适用于8080

    如果我缩短处理代码,并仅测试图像捕获和上传,则可以正常工作。所以,bug必须与串行事件有关。

    为什么以下处理代码不起作用?

    /*Serial String reader
    Context: Arduino
    
    Reads in a string of characters until it gets a linefeed (ASCII 10).
    then converts the string into a number
    */
    
    import processing.serial.*;
    import processing.video.*;
    import processing.net.*;
    
    Serial myPort;              //the serial port
    float sensorValue = 0;      //the value form the sensor
    float prevSensorValue = 0;  //previous value from the sensor
    int threshold = 200;        //above this number, the cat is on the mat
    
    int currentTime = 0;       //the current time as a single number
    int lastMailTime = 0;      //last minute you sent a mail
    int mailInterval = 60;     //minimum seconds betweeen mails
    String mailUrl = "cat-script.php";
    int lastPicture = 0;       //last minute you sent a picture
    int lastPictureTime = 0;   //last minute you sent a picture
    int pictureInterval = 10;  //minimum seconds between pictures
    
    Capture myCam;            //camera capture library instance
    String fileName = "img.jpg"; //file name for the picture
    
    //location on your server for the picture script:
    String pictureScriptUrl = "save2web.php";
    String boundary = "----H4rkNrF"; //string boundary for the post request
    
    Client thisClient;        //instance for the net library
    
    
    //float xPos = 0;             //horizontal position of the graph
    //float lastXPos = 0;         //previous horizontal position  
    
    
    
    void setup(){
      size(400, 300);
      //list all the available serial ports
      println(Serial.list());
    
      myPort = new Serial(this, Serial.list()[7], 9600);
    
      //reads bytes into a buffer until you get a newline (ASCII 10);
      myPort.bufferUntil('\n');
    
      //set initial background and smooth drawing:
      background(#543174);
      smooth();
      //for a list of cameras on your computer, use this line:
      println(Capture.list());
    
      //use the default camera for capture at 30 fps
      myCam = new Capture(this, width, height, 30);
      myCam.start();
    }
    
    void draw(){
      //make a single number fmor the current hour, minute, and second
      currentTime = hour() * 3600 + minute() * 60 + second();
    
      if (myCam.available() == true) {
        //draw the camera image to the screen;
        myCam.read();
        set(0, 0, myCam);
    
        //get the time as a string
        String timeStamp = nf(hour(), 2) + ":" + nf(minute(), 2)
        + ":" + nf(second(), 2) + "   " + nf(day(), 2) + "-"
        + nf(month(), 2) + "-" + nf(year(), 4);
    
        //draw a dropshadow for the time text:
        fill(15);
        text(timeStamp, 11, height - 19);
        //draw the main time next
        fill(255);
        text(timeStamp, 10, height - 20);
      }
    }
    
    void serialEvent (Serial myPort){
      //get the ASCII string
      String inString = myPort.readStringUntil('\n');
    
      if (inString != null){
        //trim off any whitespace:
        inString = trim(inString);
        //convert to an int and map to the screen height
        sensorValue = float(inString);
        //println(sensorValue);
        sensorValue = map(sensorValue, 0, 1023, 0, height);
        println(sensorValue);
    
        if (sensorValue > threshold){
          if(currentTime - lastPictureTime > pictureInterval){
            PImage thisFrame = get();
            thisFrame.save(fileName);
            postPicture();
            lastPictureTime = currentTime;
          }
          //if the last reading was less than the threshold
          //then the cat just got on the mat
          if(prevSensorValue <= threshold){
            println("Cat is on the mat.");
            sendMail();
          }
        }
        else{
          //if the sensor value is less than the threshold,
          //and the previous value was greater, then the cat
          //just left the mat
          if (prevSensorValue > threshold){
            println("Cat is not on the mat.");
          }
        }
        //save the current value for the next time
        prevSensorValue = sensorValue;
      }
    }
    
    
    void sendMail(){
      //how long has passed since the last mail
      int timeDifference = currentTime - lastMailTime;
    
      if( timeDifference > mailInterval){
        String[] mailScript = loadStrings(mailUrl);
        println("results from mail script:");
        println(mailScript);
    
        //save the current minute for next time
        lastMailTime = currentTime;
      }
    }
    

    修改

    通过排除,错误是在最后一个函数中,但我仍然没有找到它:

    void postPicture(){
     //load the saved image into an array of bytes
      byte[] thisFile=loadBytes(fileName);
    
    
    //open a new connection to the server
     thisClient = new Client(this, "localhost", 80);
    
    //make an HTTP POST request:
    thisClient.write("POST " + pictureScriptUrl + " HTTP/1.1\n");
    
    thisClient.write("Host: localhost\n");
    
    //tell the server you're sending the POST in multiple parts
    //and send a unique string that will delineate the parts
    thisClient.write("Content-Type: multipart/form-data; boundary=");
    
    thisClient.write(boundary + "\n");
    
    
    //form the beginning of the request
    String requestHead ="--" + boundary + "\n";
    
    requestHead +="Content-Disposition: form-data; name=\"file\"; ";
    requestHead += "filename=\"" + fileName + "\"\n";
    requestHead +="Content-Type: image/jpeg\n\n";
    
    
    //form the end of the request
    String tail="\n\n--" + boundary + "--\n";
    
    
    //calculate and send the length of the total request
    //including the head of the request, the file, and the tail
    int contentLength = requestHead.length() + thisFile.length + tail.length();
    
     thisClient.write("Content-Length: " + contentLength + "\n\n");
     //send the header of the request, the file and the tail
     thisClient.write(requestHead);
     thisClient.write(thisFile);
     thisClient.write(tail);
     }
    

    这就是提出来的:

    java.lang.NullPointerException
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
    at    javax.imageio.stream.FileCacheImageOutputStream.close(FileCacheImageOutputStream.java:238)
    at com.sun.imageio.stream.StreamCloser$CloseAction.performAction(StreamCloser.java:130)
    at com.sun.imageio.stream.StreamCloser$1.run(StreamCloser.java:74)
    at java.lang.Thread.run(Thread.java:745)
    

    加上Not a Number例外:

    sensorValue = map(NaN, 1023, 0, height);

    我的系统是Unix。

2 个答案:

答案 0 :(得分:3)

可能最好在Arduino特定版本的堆栈交换上问这个问题。

我的建议让Arduino Processing拍摄(猫的照片)。然后让它将图片上传到PHP网络应用程序。

然后PHP网络应用程序应该接收文件上传(图片)并发送电子邮件给那些想通过电子邮件接收的人。

enter image description here

似乎您在端口8080上运行PHP服务器,然后Arduino Processing应用程序也需要连接到该端口!因此,请更新代码,以便客户端连接到服务器:

Arduino Processing(客户端)需要知道PHP服务器在网络上的位置。因此需要知道DNS名称或服务器的IP地址。因此,请在下面的代码中更正字符串"name-or-ip"

//open a new connection to the server
thisClient = new Client(this, "name-or-ip", 8080);

提示:如果Arduino Processing与PHP Server在同一台计算机上运行,​​那么"localhost"将作为服务器连接。

答案 1 :(得分:0)

String mailUrl应该包含整个字符串:"http://127.0.0.1:8080/cat-script.php",而不仅仅是相对于cat-script.php目录的脚本位置root

另外,save2web.php脚本中存在一个错误 - 此问题中没有出现错误,导致图像无法上传。 move_uploaded_file($fileTempName, $path.fileName);未包含".fileName"

现在一切正常。