bitluni / ESP32CameraI2S

176 stars 61 forks source link

Performance improvement for web server #3

Closed derekmulcahy closed 5 years ago

derekmulcahy commented 6 years ago

Hi,

I suggest writing the output to the client in one block instead of iterating.

client.write(bmpHeader, BMP::headerSize);
client.write(camera->frame, camera->xres * camera->yres * 2);

gave me a 6 frames per second instead of one frame every three seconds.

I added a pull request for these changes.

Cheers, Derek

malloc32 commented 6 years ago

I use this code and the performance increase is amazing. Thank you.

espiot328266 commented 5 years ago

hi thanks for improving the code can you add more explain because i don't know how to edit the part of the code that improve the preference

espiot328266 commented 5 years ago

I use this code and the performance increase is amazing. Thank you.

please help me to edit the program because i don't have any idea

malloc32 commented 5 years ago

Here you can see the pull request made by derekmulcahy. You have to make these changes.

espiot328266 commented 5 years ago

i can't find the part in the code o that i can make the change thank you for your attention

Here you can see the pull request made by derekmulcahy. You have to make these changes.

i can't find the part in the code o that i can make the change thank you for your attention

malloc32 commented 5 years ago

The file ESP32_I2S_Camera/ESP32_I2S_Camera.ino , about line 90 . You have to found where you have installed the library.

espiot328266 commented 5 years ago

The file ESP32_I2S_Camera/ESP32_I2S_Camera.ino , about line 90 . You have to found where you have installed the library.

i'm so stupid i guess because i can't understand what you mean can you make it easy for dummy me

espiot328266 commented 5 years ago

The file ESP32_I2S_Camera/ESP32_I2S_Camera.ino , about line 90 . You have to found where you have installed the library.

i'm so stupid i guess because i can't understand what you mean can you make it easy for dummy me

i have done this `#include

include

include <lwip/err.h>

include <lwip/sockets.h>

include "BMP.h"

include "OV7670.h"

include "wifi_internal.h"

WiFiClient client;

const int SIOD = SDA; const int SIOC = SCL;

const int VSYNC = 32; const int HREF = 39;

const int XCLK = 18; const int PCLK = 36;

const int D0 = 12; const int D1 = 14; const int D2 = 27; const int D3 = 26; const int D4 = 25; const int D5 = 35; const int D6 = 34; const int D7 = 33;

define SSID "Test"

define MAX_PACKET_SIZE 1460

define MAX_DATA_SIZE 1450

struct PacketHeader { uint8_t frame; uint32_t offset; uint32_t len; };

OV7670 *camera;

byte bmpHeader[BMP::headerSize]; int udp_server = -1; struct sockaddr_in destination; bool video_running = false;

void setup() { Serial.begin(115200);

WiFi.disconnect(true);

// Force data rate wifi_internal_rate_t rate; rate.fix_rate = RATE_MCS4_SP; esp_wifi_internal_set_rate(100, 1, 4, &rate);

WiFi.softAP(SSID); WiFi.onEvent(onClientChange, SYSTEM_EVENT_AP_STACONNECTED); WiFi.onEvent(onClientChange, SYSTEM_EVENT_AP_STADISCONNECTED);

// Change beacon_interval because 100ms is crazy! wifi_config_t conf; esp_wifi_get_config(WIFI_IF_AP, &conf); conf.ap.beacon_interval = 3000; esp_wifi_set_config(WIFI_IF_AP, &conf);

camera = new OV7670(OV7670::Mode::QQVGA_RGB565, SIOD, SIOC, VSYNC, HREF, XCLK, PCLK, D0, D1, D2, D3, D4, D5, D6, D7); BMP::construct16BitHeader(bmpHeader, camera->xres, camera->yres);

// Init socket udp_server = socket(AF_INET, SOCK_DGRAM, 0); destination.sin_addr.s_addr = (uint32_t)IPAddress(255,255,255,255); destination.sin_family = AF_INET; destination.sin_port = htons(3333);

Serial.println("Up, Waiting for clients"); }

void onClientChange(system_event_id_t event) { // Only start sending video after a client connects to avoid flooding // the channel when the client is attempting to connect. video_running = WiFi.softAPgetStationNum() != 0; if (video_running) { Serial.println("Video started!"); } else { Serial.println("STOPPED"); } }

void loop() { if (!video_running) { client.write(bmpHeader, BMP::headerSize); client.write(camera->frame, camera->xres camera->yres 2); return; }

camera->oneFrame();

static byte packet[MAX_PACKET_SIZE]; static uint8_t framenum = 0; PacketHeader header = (PacketHeader)packet; header->frame = framenum++; header->len = camera->frameBytes;

for (int i = 0; i < camera->frameBytes; i += MAX_DATA_SIZE) { bool end = i + MAX_DATA_SIZE > camera->frameBytes; int len = end ? camera->frameBytes - i : MAX_DATA_SIZE; header->offset = i; memcpy(packet + sizeof(PacketHeader), camera->frame + i, len); int sent = sendto( udp_server, packet, sizeof(PacketHeader) + len, 0, (struct sockaddr*) &destination, sizeof(destination) ); }

// FPS counter static unsigned int frames = 0; static unsigned long last = millis(); ++frames; unsigned long now = millis(); if (now - last > 1000) { Serial.println(frames); last = now; frames = 0; } }`

espiot328266 commented 5 years ago

i just need code that work well is too complected to get all this

espiot328266 commented 5 years ago

thank you so much you for your attention to my problem it have being compiled and no problem but did not try it yet

the code that you gave me little bit different then the one is in the link i have a nother qeustion should i upload only that code or all the other codes to the esp32 because he said "Move sketch to an appropriately named subfolder" what dose this mean

espiot328266 commented 5 years ago

i get this error

ESP32_I2S_Camera:39:57: error: 'no' was not declared in this scope

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, 0/no reset/);

                                                     ^

Multiple libraries were found for "WiFi.h" Used: C:\Users\pc\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.1\libraries\WiFi Not used: C:\Users\pc\Downloads\arduino-nightly\libraries\WiFi Using library Adafruit-GFX-Library-master at version 1.3.6 in folder: C:\Users\pc\Documents\Arduino\libraries\Adafruit-GFX-Library-master Using library Adafruit-ST7735-Library-master at version 1.2.7 in folder: C:\Users\pc\Documents\Arduino\libraries\Adafruit-ST7735-Library-master Using library SPI at version 1.0 in folder: C:\Users\pc\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.1\libraries\SPI Using library WiFi at version 1.0 in folder: C:\Users\pc\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.1\libraries\WiFi exit status 1 'no' was not declared in this scope

espiot328266 commented 5 years ago

i just need code that work well is too complected to get all this

include "OV7670.h"

include // Core graphics library

include // Hardware-specific library

include

include

include

include "BMP.h"

const int SIOD = 21; //SDA const int SIOC = 22; //SCL

const int VSYNC = 34; const int HREF = 35;

const int XCLK = 32; const int PCLK = 33;

const int D0 = 27; const int D1 = 17; const int D2 = 16; const int D3 = 15; const int D4 = 14; const int D5 = 13; const int D6 = 12; const int D7 = 4;

const int TFT_DC = 2; const int TFT_CS = 5; //DIN <- MOSI 23 //CLK <- SCK 18

define ssid1 "ssid"

define password1 "pass"

//#define ssid2 "" //#define password2 ""

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, 0/no reset/); OV7670 *camera;

WiFiMulti wifiMulti; WiFiServer server(80);

unsigned char bmpHeader[BMP::headerSize];

void serve() { WiFiClient client = server.available(); if (client) { //Serial.println("New Client."); String currentLine = ""; while (client.connected()) { if (client.available()) { char c = client.read(); //Serial.write(c); if (c == '\n') { if (currentLine.length() == 0) { client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println(); client.print( "" "" ""); client.println(); break; } else { currentLine = ""; } } else if (c != '\r') { currentLine += c; }

    if(currentLine.endsWith("GET /camera"))
    {
        client.println("HTTP/1.1 200 OK");
        client.println("Content-type:image/bmp");
        client.println();

         client.write(bmpHeader, BMP::headerSize);
        client.write(camera->frame, camera->xres * camera->yres * 2);
    }
  }
}
// close the connection:
client.stop();
//Serial.println("Client Disconnected.");

} }

void setup() { Serial.begin(115200);

wifiMulti.addAP(ssid1, password1); //wifiMulti.addAP(ssid2, password2); Serial.println("Connecting Wifi..."); if(wifiMulti.run() == WL_CONNECTED) { Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); }

camera = new OV7670(OV7670::Mode::QQVGA_RGB565, SIOD, SIOC, VSYNC, HREF, XCLK, PCLK, D0, D1, D2, D3, D4, D5, D6, D7); BMP::construct16BitHeader(bmpHeader, camera->xres, camera->yres);

tft.initR(INITR_BLACKTAB); tft.fillScreen(0); server.begin(); }

void displayY8(unsigned char frame, int xres, int yres) { tft.setAddrWindow(0, 0, yres - 1, xres - 1); int i = 0; for(int x = 0; x < xres; x++) for(int y = 0; y < yres; y++) { i = y xres + x; unsigned char c = frame[i]; unsigned short r = c >> 3; unsigned short g = c >> 2; unsigned short b = c >> 3; tft.pushColor(r << 11 | g << 5 | b); } }

void displayRGB565(unsigned char frame, int xres, int yres) { tft.setAddrWindow(0, 0, yres - 1, xres - 1); int i = 0; for(int x = 0; x < xres; x++) for(int y = 0; y < yres; y++) { i = (y xres + x) << 1; tft.pushColor((frame[i] | (frame[i+1] << 8))); } }

void loop() { camera->oneFrame(); serve(); displayRGB565(camera->frame, camera->xres, camera->yres); }

please reply

espiot328266 commented 5 years ago

i don't need to use the tft or mqtt because basically i need to use the webserver to show date can i remove the tft in the code dose it will work like that because i did what he said in the video and comented them and is compiling

espiot328266 commented 5 years ago

@malloc32 @derekmulcahy @akarsh98 can i not use the tft because i want to access to camera jus with webserver like this code is compile

include "OV7670.h"

include // Core graphics library

include // Hardware-specific library

include

include

include

include "BMP.h"

const int SIOD = 21; //SDA const int SIOC = 22; //SCL

const int VSYNC = 34; const int HREF = 35;

const int XCLK = 32; const int PCLK = 33;

const int D0 = 27; const int D1 = 17; const int D2 = 16; const int D3 = 15; const int D4 = 14; const int D5 = 13; const int D6 = 12; const int D7 = 4;

const int TFT_DC = 2; const int TFT_CS = 5; //DIN <- MOSI 23 //CLK <- SCK 18

define ssid1 "ssid"

define password1 "pass"

//#define ssid2 "" //#define password2 ""

//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, 0/no reset/); OV7670 *camera;

WiFiMulti wifiMulti; WiFiServer server(80);

unsigned char bmpHeader[BMP::headerSize];

void serve() { WiFiClient client = server.available(); if (client) { //Serial.println("New Client."); String currentLine = ""; while (client.connected()) { if (client.available()) { char c = client.read(); //Serial.write(c); if (c == '\n') { if (currentLine.length() == 0) { client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println(); client.print( "" "" ""); client.println(); break; } else { currentLine = ""; } } else if (c != '\r') { currentLine += c; }

if(currentLine.endsWith("GET /camera"))
{
    client.println("HTTP/1.1 200 OK");
    client.println("Content-type:image/bmp");
    client.println();

     client.write(bmpHeader, BMP::headerSize);
    client.write(camera->frame, camera->xres * camera->yres * 2);
}

} } // close the connection: client.stop(); //Serial.println("Client Disconnected."); } }

void setup() { Serial.begin(115200);

wifiMulti.addAP(ssid1, password1); //wifiMulti.addAP(ssid2, password2); Serial.println("Connecting Wifi..."); if(wifiMulti.run() == WL_CONNECTED) { Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); }

camera = new OV7670(OV7670::Mode::QQVGA_RGB565, SIOD, SIOC, VSYNC, HREF, XCLK, PCLK, D0, D1, D2, D3, D4, D5, D6, D7); BMP::construct16BitHeader(bmpHeader, camera->xres, camera->yres);

//tft.initR(INITR_BLACKTAB); //tft.fillScreen(0); server.begin(); }

void displayY8(unsigned char frame, int xres, int yres) { //tft.setAddrWindow(0, 0, yres - 1, xres - 1); int i = 0; for(int x = 0; x < xres; x++) for(int y = 0; y < yres; y++) { i = y xres + x; unsigned char c = frame[i]; unsigned short r = c >> 3; unsigned short g = c >> 2; unsigned short b = c >> 3; //tft.pushColor(r << 11 | g << 5 | b); } }

void displayRGB565(unsigned char frame, int xres, int yres) { //tft.setAddrWindow(0, 0, yres - 1, xres - 1); int i = 0; for(int x = 0; x < xres; x++) for(int y = 0; y < yres; y++) { i = (y xres + x) << 1; //tft.pushColor((frame[i] | (frame[i+1] << 8))); } }

void loop() { camera->oneFrame(); serve(); displayRGB565(camera->frame, camera->xres, camera->yres); }

malloc32 commented 5 years ago

ok, then now it is working?, Some time ago I leave to program microcontrollers, no time :(.

espiot328266 commented 5 years ago

i did not try it yet the esp32 will arive tomorrow the i have edited on it is that okay because i don't want to use tft basically

espiot328266 commented 5 years ago

i have compared the code you gave me and the original code i found that you are missing somethings and i have added it now it have compiled with not much change

just he one you have gave me thank you all for the help and attention

`#include "OV7670.h"

include // Core graphics library

include // Hardware-specific library

include

include

include

include "BMP.h"

const int SIOD = 21; //SDA const int SIOC = 22; //SCL

const int VSYNC = 34; const int HREF = 35;

const int XCLK = 32; const int PCLK = 33;

const int D0 = 27; const int D1 = 17; const int D2 = 16; const int D3 = 15; const int D4 = 14; const int D5 = 13; const int D6 = 12; const int D7 = 4;

const int TFT_DC = 2; const int TFT_CS = 5; //DIN <- MOSI 23 //CLK <- SCK 18

define ssid1 "YOUR_WIFI_SSID"

define password1 "YOUR_PASSWORD"

//#define ssid2 "" //#define password2 ""

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, 0/no reset/); OV7670 *camera;

WiFiMulti wifiMulti; WiFiServer server(80);

unsigned char bmpHeader[BMP::headerSize];

void serve() { WiFiClient client = server.available(); if (client) { //Serial.println("New Client."); String currentLine = ""; while (client.connected()) { if (client.available()) { char c = client.read(); //Serial.write(c); if (c == '\n') { if (currentLine.length() == 0) { client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println(); client.print( "" "" ""); client.println(); break; } else { currentLine = ""; } } else if (c != '\r') { currentLine += c; }

    if(currentLine.endsWith("GET /camera"))
    {
        client.println("HTTP/1.1 200 OK");
        client.println("Content-type:image/bmp");
        client.println();

        client.write(bmpHeader, BMP::headerSize);
        client.write(camera->frame, camera->xres * camera->yres * 2);
    }
  }
}
// close the connection:
client.stop();
//Serial.println("Client Disconnected.");

}
}

void setup() { Serial.begin(115200);

wifiMulti.addAP(ssid1, password1); //wifiMulti.addAP(ssid2, password2); Serial.println("Connecting Wifi..."); if(wifiMulti.run() == WL_CONNECTED) { Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); }

camera = new OV7670(OV7670::Mode::QQVGA_RGB565, SIOD, SIOC, VSYNC, HREF, XCLK, PCLK, D0, D1, D2, D3, D4, D5, D6, D7); BMP::construct16BitHeader(bmpHeader, camera->xres, camera->yres);

tft.initR(INITR_BLACKTAB); tft.fillScreen(0); server.begin(); }

void displayY8(unsigned char frame, int xres, int yres) { tft.setAddrWindow(0, 0, yres - 1, xres - 1); int i = 0; for(int x = 0; x < xres; x++) for(int y = 0; y < yres; y++) { i = y xres + x; unsigned char c = frame[i]; unsigned short r = c >> 3; unsigned short g = c >> 2; unsigned short b = c >> 3; tft.pushColor(r << 11 | g << 5 | b); }
}

void displayRGB565(unsigned char frame, int xres, int yres) { tft.setAddrWindow(0, 0, yres - 1, xres - 1); int i = 0; for(int x = 0; x < xres; x++) for(int y = 0; y < yres; y++) { i = (y xres + x) << 1; tft.pushColor((frame[i] | (frame[i+1] << 8))); }
}

void loop() { camera->oneFrame(); serve(); displayRGB565(camera->frame, camera->xres, camera->yres); }`

espiot328266 commented 5 years ago

the code now worked but there is a problem the image dose not give me good colors and i have changed pin 17 with pin 25 because i can't find pin 17 do yo have any ideas

malloc32 commented 5 years ago

ufff, sorry It was many time ago, even now I have not the schema..., but I remember that I had good colors, not very good image quality because the resolution.. and the price of the camera... about 2€ in aliexpress, so....

espiot328266 commented 5 years ago

the colors i got is not good at all i berly can see my face i have esp32 wroom and it dose not have pin 17 how can i change the pin with no problem there the esp i have 51835731_804088226613058_8543762027120689152_n and i want to know how the chnage the screen size so i can see it full using the phone

espiot328266 commented 5 years ago

i have 17 pin is tx2 but now when i changed the router it dose not show the ip addressee of the esp in serial monitor

espiot328266 commented 5 years ago

@derekmulcahy @malloc32 i need to add code led control in the camera code any help?

did this code but i need to optimized it

include "OV7670.h"

include // Core graphics library

include // Hardware-specific library

include

include

include

include "BMP.h"

String header;

// Auxiliar variables to store the current output state String output22State = "off";

// Assign output variables to GPIO pins const int D25 = 25; String output25State = "off"; const int SIOD = 21; //SDA const int SIOC = 22; //SCL

const int VSYNC = 34; const int HREF = 35;

const int XCLK = 32; const int PCLK = 33;

const int D0 = 27; const int D1 = 17; const int D2 = 16; const int D3 = 15; const int D4 = 14; const int D5 = 13; const int D6 = 12; const int D7 = 4;

const int TFT_DC = 2; const int TFT_CS = 5; //DIN <- MOSI 23 //CLK <- SCK 18

define ssid1 "YOUR_WIFI_SSID"

define password1 "YOUR_PASSWORD"

//#define ssid2 "" //#define password2 ""

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, 0/no reset/); OV7670 *camera;

WiFiMulti wifiMulti; WiFiServer server(80);

unsigned char bmpHeader[BMP::headerSize];

void serve() { WiFiClient client = server.available(); if (client) { //Serial.println("New Client."); String currentLine = ""; while (client.connected()) { if (client.available()) { char c = client.read(); //Serial.write(c); if (c == '\n') { if (currentLine.length() == 0) { client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println(); client.print( "" "" ""); client.println(); break; } else { currentLine = ""; } } else if (c != '\r') { currentLine += c; }

    if(currentLine.endsWith("GET /camera"))
    {
        client.println("HTTP/1.1 200 OK");
        client.println("Content-type:image/bmp");
        client.println();

        client.write(bmpHeader, BMP::headerSize);
        client.write(camera->frame, camera->xres * camera->yres * 2);
    }
  }
}
// close the connection:
client.stop();
//Serial.println("Client Disconnected.");

}
}

void setup() { Serial.begin(115200);

pinMode(D25, OUTPUT); // Set outputs to LOW digitalWrite(D25, LOW);

wifiMulti.addAP(ssid1, password1); //wifiMulti.addAP(ssid2, password2); Serial.println("Connecting Wifi..."); if(wifiMulti.run() == WL_CONNECTED) { Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); }

camera = new OV7670(OV7670::Mode::QQVGA_RGB565, SIOD, SIOC, VSYNC, HREF, XCLK, PCLK, D0, D1, D2, D3, D4, D5, D6, D7); BMP::construct16BitHeader(bmpHeader, camera->xres, camera->yres);

tft.initR(INITR_BLACKTAB); tft.fillScreen(0); server.begin(); }

void displayY8(unsigned char frame, int xres, int yres) { tft.setAddrWindow(0, 0, yres - 1, xres - 1); int i = 0; for(int x = 0; x < xres; x++) for(int y = 0; y < yres; y++) { i = y xres + x; unsigned char c = frame[i]; unsigned short r = c >> 3; unsigned short g = c >> 2; unsigned short b = c >> 3; tft.pushColor(r << 11 | g << 5 | b); }
}

void displayRGB565(unsigned char frame, int xres, int yres) { tft.setAddrWindow(0, 0, yres - 1, xres - 1); int i = 0; for(int x = 0; x < xres; x++) for(int y = 0; y < yres; y++) { i = (y xres + x) << 1; tft.pushColor((frame[i] | (frame[i+1] << 8))); }
}

void loop()

{ camera->oneFrame(); serve(); displayRGB565(camera->frame, camera->xres, camera->yres); { WiFiClient client = server.available(); if (client) { //Serial.println("New Client."); String currentLine = ""; while (client.connected()) { if (client.available()) { char c = client.read(); //Serial.write(c); if (c == '\n') { if (currentLine.length() == 0) { if (header.indexOf("GET /26/on") >= 0) { Serial.println("GPIO 26 on"); output25State = "on"; digitalWrite(D25, HIGH); delay(7000);
digitalWrite(D25, LOW);

          Serial.println("GPIO 25 off");
          output25State = "off";
          digitalWrite(D25, LOW);

        }

        // Display the HTML web page
        client.println("<!DOCTYPE html><html>");
        client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
        client.println("<link rel=\"icon\" href=\"data:,\">");
        // CSS to style the on/off buttons 
        // Feel free to change the background-color and font-size attributes to fit your preferences
        client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
        client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;");
        client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
        client.println(".button2 {background-color: #555555;}</style></head>");

        // Web Page Heading
        client.println("<body><h1>ESP32 Web Server</h1>");

        // Display current state, and ON/OFF buttons for D25  
        client.println("<p>GPIO 25 - State " + output25State + "</p>");
        // If the output26State is off, it displays the ON button       
        if (output25State=="off") {
          client.println("<p><a href=\"/25/on\"><button class=\"button\">ON</button></a></p>");
        } else {
          client.println("<p><a href=\"/25/off\"><button class=\"button button2\">OFF</button></a></p>");
        }     
         client.println("</body></html>");

        // The HTTP response ends with another blank line
        client.println();
        // Break out of the while loop
        break;
      } else { // if you got a newline, then clear currentLine
        currentLine = "";
      }
    } else if (c != '\r') {  // if you got anything else but a carriage return character,
      currentLine += c;      // add it to the end of the currentLine
    }
  }
}
// Clear the header variable
header = "";
// Close the connection
client.stop();
Serial.println("Client disconnected.");
Serial.println("");

} } }

derekmulcahy commented 5 years ago

Thanks for the merge!