1

I'm trying to send an image from SPIFFS to my external server. When pictures are taken, they are saved into "/pics/" directory within SPIFFS. Ultimately, I'd like to post all the images saved onto "/pics/x.jpg" (x is the a number in increasing order - 7.jpg, 8.jpg, 9.jpg, etc...) to my external server as they come in. Currently, I can access all the images within the internal esp server. Right now, I'm trying to send a single image, "6.jpg" from "/pics/" to my external server. Unfortunately, I'm not seeing anything on the external server side. The http post code occurs in "void setup()". The complete Arduino code is below:

// Program header files
#include <Wire.h>
#include <WiFi.h>
#include <WebServer.h>
#include <ArduCAM.h>
#include <SPI.h>
#include "FS.h"
#include "SPIFFS.h"
#include "memorysaver.h"

#define AP_SSID "apssid"
#define AP_PASSWORD "password"

#define WIFI_SSID "wifissid"
#define WIFI_PASSWORD "password"

#if !(defined (OV2640_MINI_2MP)||defined (OV5640_MINI_5MP_PLUS) || defined (OV5642_MINI_5MP_PLUS) \
    || defined (OV5642_MINI_5MP) || defined (OV5642_MINI_5MP_BIT_ROTATION_FIXED) \
    ||(defined (ARDUCAM_SHIELD_V2) && (defined (OV2640_CAM) || defined (OV5640_CAM) || defined (OV5642_CAM))))
#error Please select the hardware platform and camera module in the ../libraries/ArduCAM/memorysaver.h file
#endif


const int ArduCAM_Power = 32; // Controls power for ArduCAM

const int CS = 5; // GPIO5 as Slave Select for ArduCAM
int wifiType = 0; // 0: Station    1: AP



static const size_t bufferSize = 2048;
static uint8_t buffer[bufferSize] = {0xFF};
static const int fileSpaceOffset = 700000; 


byte buf[256];
static int i = 0;
static int k = 0;
uint8_t temp = 0, temp_last = 0;
uint32_t len = 0;
bool is_header = false;


const String fName = "/res.txt"; // Whatever last resolution that was submitted, will be stored in the file
                                // If power goes out, it will use the last setting stored onto that file
int fileTotalKB = 0;
int fileUsedKB = 0;
int fileCount = 0;
String errMsg = "";
int imgMode = 1; // 0: stream    1: capture
int resolution = 3;
// resolutions:
// 0 = 160x120
// 1 = 176x144
// 2 = 320x240
// 3 = 352x288
// 4 = 640x480
// 5 = 800x600
// 6 = 1024x768
// 7 = 1280x1024
// 8 = 1600x1200


WiFiClient client;

WebServer server(80);


#if defined (OV2640_MINI_2MP) || defined (OV2640_CAM)
ArduCAM myCAM(OV2640, CS);
#endif


void start_capture() 
{
  myCAM.clear_fifo_flag();
  myCAM.start_capture();
}

// Updates properties file with resolution
void updateDataFile()
{

  File f = SPIFFS.open(fName, FILE_WRITE);
  if(!f)
  {
    Serial.println("Property file failed to open");
  }
  else
  {
    Serial.println("========= Writing to Property file =========");

    f.println(resolution);
    Serial.println("Data file updated");
    f.close();
  }

}

void myCAMsaveToSPIFFS()
{
  // Reserves space when memory is full
  if((fileTotalKB - fileUsedKB) < fileSpaceOffset)
  {
    String maxStr = "========= Maximum Data Storage Reached =========";
    Serial.println(maxStr);
    errMsg = maxStr;
    return;
  }

  String str;

  // Flush the FIFO
  myCAM.flush_fifo();
  // Clear capture done flag
  myCAM.clear_fifo_flag();
  // Start capture
  myCAM.start_capture();

  Serial.println("Start capture.");
  while(!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));
  Serial.println("Capture done!");

  // Increase file count since a capture was done
  fileCount++;

  len = myCAM.read_fifo_length();
  Serial.print("The FIFO length is: ");
  Serial.println(len, DEC);

  if(len >= MAX_FIFO_SIZE) // 8M
  {
    Serial.println("Over size!");
  }
  if(len == 0) // 0 KB
  {
    Serial.println("Size is 0 KB.");
  }

  str = "/pics/" + String(fileCount) + ".jpg";

  File f = SPIFFS.open(str, FILE_WRITE);
  if(!f)
  {
    Serial.println("Property file failed to open");
  }
  else
  {
    Serial.println(str);
  }

  i = 0;
  myCAM.CS_LOW();
  myCAM.set_fifo_burst();
  while (len--)
  {
    temp_last = temp;
    temp =  SPI.transfer(0x00);
    //Read JPEG data from FIFO
    if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
    {
      buf[i++] = temp;  //save the last  0XD9
      //Write the remain bytes in the buffer
      myCAM.CS_HIGH();
      f.write(buf, i);
      //Close the file
      f.close();
      Serial.println("CAM Save done!");
      is_header = false;
      i = 0;
    }
    if (is_header == true)
    {
      //Write image data to buffer if not full
      if (i < 256)
        buf[i++] = temp;
      else
      {
        //Write 256 bytes image data to file
        myCAM.CS_HIGH();
        f.write(buf, 256);
        i = 0;
        buf[i++] = temp;
        myCAM.CS_LOW();
        myCAM.set_fifo_burst();
      }
    }
    else if ((temp == 0xD8) & (temp_last == 0xFF))
    {
      is_header = true;
      buf[i++] = temp_last;
      buf[i++] = temp;
    }
  }

}

//////////////////////////////////////////////////////////////////////////////////////////////////
//    Retrieves a stored jpg file and sends to browser based on url: http://IPaddress/1.jpg     //
//////////////////////////////////////////////////////////////////////////////////////////////////
bool loadFromSPIFFS(String path)
{
  String dataType = "text/plain";
  if(path.endsWith("/"))
  {
    path += "index.htm";
  }

  if(path.endsWith(".src"))
  {
    path = path.substring(0, path.lastIndexOf("."));
  }
  else if(path.endsWith(".jpg"))
  {
    dataType = "image/jpeg";
  }

  File dataFile = SPIFFS.open(path.c_str(), FILE_READ);
  if(server.hasArg("download"))
  {
    dataType = "application/octect-stream";
  }

  if(server.streamFile(dataFile, dataType) != dataFile.size())
  {

  }

  dataFile.close();
  return true;
}

/////////////////////////////////////////////////////////////
//  sets the HTML used for the resoultions drop down       //
/////////////////////////////////////////////////////////////
String getDropDown()
{
  String webString = "";
  webString += "<select name=\"rez\">\n";
  webString += "   <option value\"0\"  ";

  if (resolution == 0)
    webString += " selected=\"seleted\" ";
  webString += ">160x120</option>\n";

  webString += "   <option value=\"1\" ";
  if (resolution == 1)
    webString += " selected=\"seleted\" ";
  webString += ">176x144</option>\n";

  webString += "   <option value=\"2\" ";
  if (resolution == 2)
    webString += " selected=\"seleted\" ";
  webString += ">320x240</option>\n";

  webString += "   <option value=\"3\" ";
  if (resolution == 3)
    webString += " selected=\"seleted\" ";
  webString += ">352x288</option>\n";

  webString += "   <option value=\"4\" ";
  if (resolution == 4)
    webString += " selected=\"seleted\" ";
  webString += ">640x480</option>\n";

  webString += "   <option value=\"5\" ";
  if (resolution == 5)
    webString += " selected=\"seleted\" ";
  webString += ">800x600</option>\n";

  webString += "   <option value=\"6\" ";
  if (resolution == 6)
    webString += " selected=\"seleted\" ";
  webString += ">1024x768</option>\n";

  webString += "   <option value=\"7\" ";
  if (resolution == 7)
    webString += " selected=\"seleted\" ";
  webString += ">1280x1024</option>\n";

  webString += "   <option value=\"8\" ";
  if (resolution == 8)
    webString += " selected=\"seleted\" ";
  webString += ">1600x1200</option>\n";

  webString += "  </select>\n";

  return webString;
}

void camCapture(ArduCAM myCAM)
{
  WiFiClient client = server.client();

  len  = myCAM.read_fifo_length();
  if (len >= MAX_FIFO_SIZE) // 8M
  {
    Serial.println("Over size.");
  }
  if (len == 0 ) // 0KB
  {
    Serial.println("Size is 0.");
  }

  myCAM.CS_LOW();
  myCAM.set_fifo_burst();

  if (!client.connected()) return;

  i = 0;
  while ( len-- )
  {
    temp_last = temp;
    temp =  SPI.transfer(0x00);
    //Read JPEG data from FIFO
    if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
    {
      buffer[i++] = temp;  //save the last  0XD9     
      //Write the remain bytes in the buffer
      if (!client.connected()) break;
      client.write(&buffer[0], i);
      is_header = false;
      i = 0;
      myCAM.CS_HIGH();
      break; 
    }  
    if (is_header == true)
    { 
      //Write image data to buffer if not full
      if (i < bufferSize)
      {
      buffer[i++] = temp;
      }
    else
    {
      //Write bufferSize bytes image data to file
      if (!client.connected()) break;
      client.write(&buffer[0], bufferSize);
      i = 0;
      buffer[i++] = temp;
    }        
    }
    else if ((temp == 0xD8) & (temp_last == 0xFF))
    {
      is_header = true;
      buffer[i++] = temp_last;
      buffer[i++] = temp;   
    } 
  } 
}

void serverCapture()
{
  delay(1000);
  start_capture();
  Serial.println("CAM Capturing");

  int total_time = 0;

  total_time = millis();
  while (!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));
  total_time = millis() - total_time;
  Serial.print("capture total_time used (in miliseconds):");
  Serial.println(total_time, DEC);

  total_time = 0;

  Serial.println(F("CAM Capture Done."));
  total_time = millis();
  camCapture(myCAM);
  total_time = millis() - total_time;
  Serial.print("send total_time used (in milliseconds): ");
  Serial.println(total_time, DEC);
  Serial.println("CAM send Done!");
}

void serverStream()
{
  WiFiClient client = server.client();

  String response = "HTTP/1.1 200 OK\r\n";
  response += "Content-Type: multipart/x-mixed-replace; boundary=frame\r\n\r\n";
  server.sendContent(response);

  while (1)
  {
    start_capture();
    while (!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));
    size_t len = myCAM.read_fifo_length();
    if (len >= MAX_FIFO_SIZE) // 8M
    {
      Serial.println(F("Over size."));
      continue;
    }
    if (len == 0 ) // 0 KB
    {
      Serial.println(F("Size is 0."));
      continue;
    }

    myCAM.CS_LOW();
    myCAM.set_fifo_burst();

    if (!client.connected()) break;
    response = "--frame\r\n";
    response += "Content-Type: image/jpeg\r\n\r\n";
    server.sendContent(response); 

    while (len--)
    {
      temp_last = temp;
      temp =  SPI.transfer(0x00);

      //Read JPEG data from FIFO
      if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
      {
        buffer[i++] = temp;  //save the last  0XD9     
        //Write the remain bytes in the buffer
        myCAM.CS_HIGH();; 
        if (!client.connected()) break;
        client.write(&buffer[0], i);
        is_header = false;
        i = 0;
      }  
      if (is_header == true)
      { 
        //Write image data to buffer if not full
        if (i < bufferSize)
        {
          buffer[i++] = temp;
        }
        else
        {
          //Write bufferSize bytes image data to file
          myCAM.CS_HIGH(); 
          if (!client.connected()) break;
          client.write(&buffer[0], bufferSize);
          i = 0;
          buffer[i++] = temp;
          myCAM.CS_LOW();
          myCAM.set_fifo_burst();
        }        
      }
      else if ((temp == 0xD8) & (temp_last == 0xFF))
      {
        is_header = true;
        buffer[i++] = temp_last;
        buffer[i++] = temp;   
      } 
    }
    if (!client.connected()) break;
  }
}

void handleNotFound()
{
  String ipAddr = WiFi.localIP().toString();
  if(wifiType == 1)
  {
    ipAddr = WiFi.softAPIP().toString();
  }



  Serial.print("Server URI: ");
  Serial.println(server.uri());

  if(server.uri().indexOf(".jpg") != -1)
  {
    loadFromSPIFFS(server.uri());
    return;
  }

  //// Default HTML
  String message = "<html><head>\n";
  message += "</head><body>\n";
  message += "<form action=\"http://" + ipAddr + "/submit\" method=\"POST\">";
  message += "<h1>ESP32 Arducam Mini</h1>\n";
  if (errMsg != "")
  {
    message += "<div style=\"color:red\">" + errMsg + "</div>";
  }


  if (imgMode == 0) // stream mode
  {
    message += "<div><h2>Video Streaming</h2></div> \n";
    message += "<div><img id=\"ArduCam\" src=\"http://" + ipAddr + "/stream\" ></div>\n";
    imgMode = 1; // set back to capture mode so it doesn't get stuck in streaming mode

  }
  else
  {
    message += "<div>";
    message += getDropDown();

    message += " <input type=\"radio\" id=\"strm\" name=\"imgMode\" value=\"stream\" ";

    if (imgMode == 0)
    {
      message += " checked ";
    }
    message += "> Stream \n";

    message += " <input type=\"radio\" id=\"capt\" name=\"imgMode\" value=\"capture\"  ";
    if (imgMode == 1)
      message += " checked ";
    message += "> Capture \n";

    message += "&nbsp; <input type='submit' value='Submit'  >\n";
    message += " &nbsp;  <a style=\"font-size:12px; font-weight:bold;\" href=\"http://" + ipAddr + "\">Refresh</a>";
    message += " &nbsp; &nbsp; <a style=\"font-size:12px; font-weight:bold;\" onclick=\"return confirm('Are you sure? This will delete all stored images.')\" ";
    message += " href=\"http://" + ipAddr + "/clear\">Clear Data</a>\n";

    message += "</div>\n";

    fileTotalKB = (int)SPIFFS.totalBytes();
    fileUsedKB = (int)SPIFFS.usedBytes();


    if (fileCount > 0)
    {
      int percentUsed = ((float)fileUsedKB / (float)(fileTotalKB - fileSpaceOffset)) * 100;
      String colorStr = "green";
      if (percentUsed > 90)
        colorStr = "red";

      message += "<div style=\"width:450px; background-color:darkgray; padding:1px;\">";
      message += "<div style=\"position:absolute; color:white; padding-top:2px; font-size:11px;\"> &nbsp; space used: " + String(percentUsed) + "%</div>";
      message += "<div style=\"width:" + String(percentUsed) + "%; height:16px; background-color: " + colorStr + ";\"></div></div>\n";

    }

    message += "<table><tr>";
    int colCnt = 0;
    for (int i = 1; i <= fileCount; i++)
    {
      message += "<td><a href=\"/pics/" + String(i) + ".jpg\">" + i + ".jpg</a></td>\n";

      colCnt++;
      if (colCnt >= 10) //  columns
      {
        message += "</tr><tr>";
        colCnt = 0;
      }
    }
    message += "</tr></table>\n";

    //useful for debugging max data storage
      /*
        message += "<table><tr><td>Total Bytes: </td><td style=\"text-align:right;\">";
        message += fileTotalKB;
        message += "</td></tr><tr><td>Used Bytes: </td><td style=\"text-align:right;\">";
        message += fileUsedKB;
        message += "</td></tr><tr><td>Remaing Bytes: </td><td style=\"text-align:right;\">";
        message += (fileTotalKB - fileUsedKB);
        message += "</td></tr></table>\n";
      */
      /*
        float flashChipSize = (float)ESP.getFlashChipSize() / 1024.0 / 1024.0;
        message += "<br>chipSize: ";
        message += flashChipSize;
      */

      message += "<div><img id=\"ArduCam\" src=\"http://" + ipAddr + "/capture\" ></div>\n";


  }

  message += "</form> \n";
  message += "</body></html>\n";

  server.send(200, "text/html", message);
}


void setCamResolution(int reso)
{
  switch (reso)
  {
    case 0:
      myCAM.OV2640_set_JPEG_size(OV2640_160x120);
      resolution = 0;
      break;

    case 1:
      myCAM.OV2640_set_JPEG_size(OV2640_176x144);
      resolution = 1;
      break;

    case 2:
      myCAM.OV2640_set_JPEG_size(OV2640_320x240);
      resolution = 2;
      break;

    case 3:
      myCAM.OV2640_set_JPEG_size(OV2640_352x288);
      resolution = 3;
      break;

    case 4:
      myCAM.OV2640_set_JPEG_size(OV2640_640x480);
      resolution = 4;
      break;

    case 5:
      myCAM.OV2640_set_JPEG_size(OV2640_800x600);
      resolution = 5;
      break;

    case 6:
      myCAM.OV2640_set_JPEG_size(OV2640_1024x768);
      resolution = 6;
      break;

    case 7:
      myCAM.OV2640_set_JPEG_size(OV2640_1280x1024);
      resolution = 7;
      break;

    case 8:
      myCAM.OV2640_set_JPEG_size(OV2640_1600x1200);
      resolution = 8;
      break;

  }
}


void clearData()
{
  errMsg = "======  Data Storage Cleared =========";
  File dir = SPIFFS.open("/pics");
  while (dir.openNextFile()) 
  {
    SPIFFS.remove(dir.name());
  }

  fileCount = 0;
  fileTotalKB = 0;
  fileUsedKB = 0;

  handleNotFound();
}

void handleSubmit()
{
  errMsg = "";
  Serial.println( "--- Form Submited ---");
  Serial.println( "Server args " + server.args());

  if (server.args() > 0 ) 
  {
    for ( uint8_t i = 0; i < server.args(); i++ ) 
    {

      // can be useful to determine the values from a form post.
      Serial.println( "Server arg " + server.arg(i));
      Serial.println( "Server argName " + server.argName(i) );
      if (server.argName(i) == "imgMode")
      {
        Serial.println(" Image Mode: " + server.arg(i));

        if (server.arg(i) == "stream")
        {
          imgMode = 0;
        }
        else
        {
          imgMode = 1; // capture mode
        }
      }

      if (server.argName(i) == "rez") 
      {

        if (server.arg(i).toInt() != resolution)
        {

          setCamResolution(server.arg(i).toInt());

          updateDataFile();

          //// IMPORTANT: removing or reducing the delay can result in dark images
          delay(1500); // add a delay to allow the white balance to adjust to new resolution
        }
      }
    }
  }

  if (imgMode == 1) // capture
  {
    myCAMsaveToSPIFFS();
  }

  handleNotFound();

}




void setup() 
{
  SPIFFS.begin();
  delay(10);

  Wire.begin();
  Serial.begin(115200);
  SPI.begin();
  SPI.setFrequency(4000000); //4MHz
  pinMode(CS, OUTPUT);

  pinMode(ArduCAM_Power, OUTPUT);
  digitalWrite(ArduCAM_Power, HIGH);

  Serial.println();

  // Check for properties file
  File f = SPIFFS.open(fName, FILE_READ);

  if(!f)
  {
    // No file exists. Format and create properties file.
    Serial.println("Please wait for SPIFFS to be formatted.");

    SPIFFS.format();
    Serial.println("SPIFFS Formatted!");

    f = SPIFFS.open(fName, FILE_WRITE);
    if(!f)
    {
      Serial.println("Properties file failed to open.");
    }
    else
    {
      Serial.println("========= Writing to Property file =========");

      f.println(resolution);
      f.close();
    } 
  }
  else
  {
    Serial.println("Properties file exists! Reading...");

    while(f.available())
    {
      String str = f.readStringUntil('\n');

      Serial.println(str);

      resolution = str.toInt();
    }

    f.close();
  }

  uint8_t vid, pid;
  uint8_t temp;



  while(1)
  {
    //Check if the ArduCAM SPI bus is OK
    myCAM.write_reg(ARDUCHIP_TEST1, 0x55);
    temp = myCAM.read_reg(ARDUCHIP_TEST1);
    if (temp != 0x55) {
      Serial.println(F("SPI interface Error!"));
      delay(2);
      continue;
    }
    else
      break;
  }

  #if defined (OV2640_MINI_2MP) || defined (OV2640_CAM)
  //Check if the camera module type is OV2640
  myCAM.wrSensorReg8_8(0xff, 0x01);
  myCAM.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid);
  myCAM.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid);
  if ((vid != 0x26 ) && (( pid != 0x41 ) || ( pid != 0x42 )))
    Serial.println(F("Can't find OV2640 module!"));
  else
    Serial.println(F("OV2640 detected."));
  #endif

  //Change to JPEG capture mode and initialize the OV2640 module
  myCAM.set_format(JPEG);
  myCAM.InitCAM();

  setCamResolution(resolution);
  myCAM.clear_fifo_flag();

  if (wifiType == 0)
  {
    if(!strcmp(WIFI_SSID,"SSID"))
    {
      Serial.println(F("Please set your SSID"));
      while(1);
    }
    if(!strcmp(WIFI_PASSWORD,"PASSWORD"))
    {
      Serial.println(F("Please set your PASSWORD"));
      while(1);
    }
    // Connect to WiFi network
    Serial.println();
    Serial.println();
    Serial.print(F("Connecting to "));
    Serial.println(WIFI_SSID);

    WiFi.mode(WIFI_STA);

    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

    while (WiFi.status() != WL_CONNECTED) 
    {
      delay(500);
      Serial.print(F("."));
    }

    Serial.println(F("WiFi connected"));
    Serial.println("");
    Serial.println(WiFi.localIP());
  }
  else if (wifiType == 1)
  {
    Serial.println();
    Serial.println();
    Serial.print(F("Shared AP: "));
    Serial.println(AP_SSID);
    Serial.print(F("The password is: "));
    Serial.println(AP_PASSWORD);

    WiFi.mode(WIFI_AP);

    WiFi.softAP(AP_SSID, AP_PASSWORD);

    Serial.println();
    Serial.print("AP IP Address is: ");
    Serial.println(WiFi.softAPIP());
  }

  File normPicture = SPIFFS.open("/pics/6.jpg", FILE_READ);
  uint32_t jpgLen = normPicture.size();

  Serial.print("Sending image of ");
  Serial.print(jpgLen, DEC);
  Serial.println("bytes"); 


  // Prepare request
  String start_request = "";
  String end_request = "";
  start_request = start_request + "\n" + "--AaB03x" + "\n" + "Content-Type: image/jpeg" + "\n" + "Content-Disposition: form-data; name=\"fileToUpload\"; filename=\"6.jpg\"\n" + "Content-Transfer-Encoding: binary\n\n";
  end_request = end_request + "\n--AaB03x--\n";  
  uint32_t extra_length;  
  extra_length = start_request.length() + normPicture.size() + end_request.length();  
  //Serial.println("Extra length:");  
  //Serial.println(extra_length);  
  long leng = jpgLen + extra_length;

  // Connect to server
  Serial.println("Starting connection to external server!");
  if (client.connect("172.xx.xx.x", 80)) 
  {  
    Serial.println("Connected");  
    client.print("POST /www/upload.php HTTP/1.1");  
    client.println("Host: 172.xx.xx.x" );  
    client.println("Content-Type: multipart/form-data; boundary=AaB03x");  
    client.print("Content-Length: ");  
    client.println(extra_length);  
    client.println();
    client.print(start_request);  
    Serial.println("Connected1");  

    while(normPicture.available())
    {
      client.write(normPicture.read());
    }

    Serial.println("END REQUEST");
    client.println(end_request);

  }
  else
  {
    Serial.println("Connection failed!");
  }


  // Setup handlers for internal server
  server.on("/capture", HTTP_GET, serverCapture);
  server.on("/stream", HTTP_GET, serverStream);
  server.on("/submit", handleSubmit);
  server.on("/clear", clearData);
  server.onNotFound(handleNotFound);
  server.begin();
  Serial.println("Internal Server started");


  File dir = SPIFFS.open("/pics");
  while(dir.openNextFile())
  {
    fileCount++;
  }

  fileTotalKB = (int)SPIFFS.totalBytes();
  fileUsedKB = (int)SPIFFS.usedBytes();

}

void loop() 
{
  server.handleClient();


  //delay(15000);  
}

My php code (upload.php) is below:

<?php
if (!empty($_FILES) && isset($_FILES['fileToUpload'])) {
    switch ($_FILES['fileToUpload']["error"]) {
        case UPLOAD_ERR_OK:
            $target = "upload/";
            $target = $target . basename($_FILES['fileToUpload']['name']);

            if (move_uploaded_file($_FILES['fileToUpload']['tmp_name'], $target)) {
                $status = "The file " . basename($_FILES['fileToUpload']['name']) . " has been uploaded";
                $imageFileType = pathinfo($target, PATHINFO_EXTENSION);
                $check = getimagesize($target);
                if ($check !== false) {
                    echo "File is an image - " . $check["mime"] . ".<br>";
                    $uploadOk = 1;
                } else {
                    echo "File is not an image.<br>";
                    $uploadOk = 0;
                }

            } else {
                $status = "Sorry, there was a problem uploading your file.";
            }
            break;

    }

    echo "Status: {$status}<br/>\n";

}
?>

I don't believe that I need any html code, since the php file receives the image and sends it to the "uploads/" folder in "www/uploads/" from my external server. My upload.php file is located in "www/".

UPDATE1: I believe my error is either the client headers, or when writing the image to send to the external server. I get an error 400 226 on the external server when trying to send the image. The 400 for a bad client request, and I believe the 226 is the amount of bytes sent/received.

Thanks!

  • you can do client.write(normPicture); – Juraj Apr 8 at 4:56
  • To get image on PHP Side using move_uploaded_file() you need to send them using a HTML Form with input like <input type="file" multiple="multiple" name="tcom_file[]" id="liste_upload" size="100" />. So or you "simulate" such a form, or you send data directly. In that case, maybe the easiest way would be to have a folder on you remote server with a specific FTP acces to send data to it. Look for FTP Arduino on Google. – Peter Apr 8 at 12:25
  • @Juraj I did try doing while(normPicture.available()){client.write(normPicture))} but it ends up writing incomplete. It starts writing fine like 56,78...,45, and then ends with a -1. On the external server, I get error 400 226. The 400 is a bad client request, and I believe the 226 is the bytes the external server received? – fern132 Apr 9 at 11:42
  • @Peter Thanks for the input. I’ll definitely look into it! – fern132 Apr 9 at 11:50
  • use esp8266 arduino package 2.4.2. Peter is right that you could do a direct upload, not a form simulation, but I don't understand his FTP recommendation. It would be a completely different approach – Juraj Apr 9 at 12:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.