distorted image in latest http server demo #21

Open
tzapu opened this Issue Feb 18, 2016 · 16 comments

Projects

None yet

6 participants

@tzapu
tzapu commented Feb 18, 2016

hello

When using ArduCAM_Mini_OV2640_websocket_server everything works fine

When i attempt to use ArduCAM_Mini_OV2640_Capture i get garbled frames in both video and static capture

sample
capture

could you help? i tried to look for code differences but byte buffers throw me off... init code seems the same

@tzapu
tzapu commented Feb 18, 2016

the issue seems to be in the read/transmit part of the sketch, i have tried the read code from the working sketch in the new one that distorts and capture seems to work fine
it also seems slower, si i am sure the code is not what it should be..

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

  size_t len = myCAM.read_fifo_length();
  if (len >= 393216){
    Serial.println("Over size.");
    return;
  }else if (len == 0 ){
    Serial.println("Size is 0.");
    return;
  }

  uint8_t temp, temp_last;
  static int i = 0;
  static uint8_t first_packet = 1;
  byte buf[2048];
  uint32_t length = 0;

  myCAM.CS_LOW();
  myCAM.set_fifo_burst();//Set fifo burst mode
  SPI.transfer(0x00);
  //Read JPEG data from FIFO
  while ( (temp != 0xD9) | (temp_last != 0xFF))
  {
    temp_last = temp;
    temp = SPI.transfer(0x00);

    //Write image data to buffer if not full
    if (i < 2048)
    {
      buf[i++] = temp;
      //yield();
    }
    else
    {
      if (first_packet == 1)
      {
        //sendClientData((char*)buf, 2048, 0x02);
        client.write((char*)buf, 2048);
        first_packet = 0;
      }
      else
      {
        client.write((char*)buf, 2048);
      }
      i = 0;
      buf[i++] = temp;

    }
    //yield();
  }
  //Write the remain bytes in the buffer
  if (i > 0)
  {
    //Serial.println("write last 256 bytes");
    client.write((char*)buf, 2048);
    //delay(10);
    //Serial.println("finish write last 256 bytes");
    i = 0;
    first_packet = 1;
  }
  //yield();
  myCAM.CS_HIGH();

}
@tzapu
tzapu commented Feb 18, 2016

it seems modifying buffer size from 4096 to 2048 makes it work, but also seems a lot slower in updating (reads half as much)...
is there anything that could be done?

@ArduCAM
Owner
ArduCAM commented Feb 18, 2016

Please modify the source code in the ESP8266 library like the following:

[WiFiClient.h]
#define WIFICLIENT_MAX_PACKET_SIZE 4096

[ClientContext.h]
add the line
_pcb->snd_buf = TCP_SND_BUF;
before
size_t room = tcp_sndbuf(_pcb);

[lwipopts.h]
#define TCP_MSS 2048

admin@arducam.com

@tzapu
tzapu commented Feb 18, 2016

thanks for the info.
i won t be able to test for a while as it s more involved and probably will be overwritten on any core update
but with 2048 as buffer size it seems to work fine for me in the mean time
thanks

@mozgy
mozgy commented Feb 18, 2016

Changing

static const size_t bufferSize = 2048; // 4096

from 4096 to 2048 works for me too -

arducam

that PCB on keyboard is my ESP8266 to ArduCAM breakout ..

@ArduCAM
Owner
ArduCAM commented Feb 19, 2016

Congratulations Mario. Breakout board looks nice.

@tzapu
tzapu commented Feb 19, 2016

nice, love it when you use a product to demo said product is working :D
which leads me to the question, how many arducams do you have ? :P
lovely breakout, looking foerward to see what you come up with

@ArduCAM
Owner
ArduCAM commented Feb 19, 2016

We now have two models of ArduCAM mini, 2mp and 5mp. We will design another 3MP soon.

@tzapu
tzapu commented Feb 19, 2016

hi, i meant @mozgy :P he took a pic of an arducam with another arducam 📷
but it s nice to know another 3mp is coming, thanks

@mozgy
mozgy commented Feb 19, 2016

As oshpark produces trices I bought two 2MP cams, here's PCB https://oshpark.com/shared_projects/pINKH5In.

@janisalnis

ArduCAM_Mini_OV2640_Capture_uploadToServer.txt

Hello Lee,
thanks for sending Arducam through Ebay.
I see you have sold more than 300 pieces so there is some growing community.
Started to try it out.

Arducam mini board draws nearly 100 mA. For a battery powered
security camera I use PIR detector + FET switching on 3.3V.

Downloaded the library from github on 05. March 2016.
Took some time to figure out that the library should be placed in directory arduino/libraries/ArduCAM.
If the arduino-master directory is placed under the libraries folder, the compiler
can not find *.h files.

First tried an example with Arduino streaming to Windows PC:
"ArduCAM_Mini_OV2640_Video_Streaming".

First issue was that there is no circuit diagram on the webpage. I wanted to use with Arduino nano. It took a while to figure that SDA=A4 and SCL=A5.

Second issues Serial.begin(921600); did not work with Arduino Serial Monitor window.
Changed speed to 115200

Third issue was that Arducam.exe downloaded from the Arducam webpage:
http://www.arducam.com/downloads/demo/arducam_host/ArduCAM_host.zip
did not support speed of 900kbps. Appeared that the program was not the latest version and one should use the program included with the github library example.

Next tried the example with ESP8266 module ESP-12E file: "ArduCAM_Mini_OV2640_Capture"
Serial debugging gave message
Can't find OV2640 module!

if ((vid != 0x26) || (pid != 0x41))
in websocket example camera id number is 0x42. Camera was found after changing to 0x42.

while(1); causes reset after a few seconds, as probably, the ESP8266 had no time to do
other internal things.

In the program, I guess, it should also be nr 16 in the comment line.
// set GPIO15 as the slave select :
const int CS = 16;

I also experienced the problem with images chopped into parts described in this issue with the broken and mixed parts of the image.
Changing of buffer size to 2048 helped, but sometimes still was broken. Changing to 1024 solved.
static const size_t bufferSize = 1024;

There is an easy way to capture a picture without the demonstation html:
http://192.168.1.140/capture

Resolution can be changed with numbers between 0 and 8 in such a way:
http://192.168.1.140/?ql=3

I would like to make a PIR activated alarm camera automatically uploading a picture to a server.
I am a big fan of MobileWebcam:
http://forum.xda-developers.com/showthread.php?t=950933
On a server is a mobilewebcam.php script that receives the picture file and puts it into a
directory with a time tag. My webcams ar at http://asi.lv/alnis
Form Linux picture upload line looks like that:
curl -F userfile=@/tmp/current.jpg asi.lv/alnis/webcammob1/mobilewebcam.php

Php upload is more convenient than FTP upload as the file name can be automatically prepared on the server side. Yesterday using TTL camera example by openhomeautomation I have managed to adapt http POST file on ESP8266. Sketch is attached to this post. (Could not attach ino or zip type).

Sorry about wirting too many things in one post.
Greetings from Latvia, Janis Alnis.

@dmolner
dmolner commented Mar 27, 2016

Great!

I with these is working automatic uploading pictures to my server.
I only had to change name of server and folder.

@ArduCAM
Owner
ArduCAM commented Mar 29, 2016

@Janis from Latvia, thanks for your detail information, it definitely
guides other users much easier. May I know your email address?

On Tue, Mar 8, 2016 at 10:31 AM, janisalnis notifications@github.com
wrote:

Hello Lee, thanks for sending Arducam through Ebay.

Started to try it out. Arducam mini board draws nearly 100 mA. For a
battery powered
version would be probably nice to add a FET switch on power line.

Downloaded the library from github on 05. March 2016.
Library should be placed in directory arduino/libraries/ArduCAM.
If the whole arduino-master directory was placed under the libraries
folder, the compiler
could not find *.h files.

First tried an example with Arduino streaming to Windows PC:
"ArduCAM_Mini_OV2640_Video_Streaming".

Serial.begin(921600); did not work with Arduino Serial Monitor window.
changed to 115200
Arducam.exe downloaded from the Arducam webpage:
http://www.arducam.com/downloads/demo/arducam_host/ArduCAM_host.zip
did not support speed of 900kbps. Appeared that the program was not the
latest version and should use the program included with the github library
example.

Next tried the example with ESP8266: "ArduCAM_Mini_OV2640_Capture"
Serial debugging gave message
Can't find OV2640 module!

if ((vid != 0x26) || (pid != 0x41))
looked in websocket example that needed to change camera id number to 0x42.

while(1); caused reset after a few seconds, as probably, the ESP8266 had
no time to do
other internal things.

In the program, I guess, it should also be nr 16 in the comment line.
// set GPIO15 as the slave select :
const int CS = 16;

I also experienced the problem described in this issue with the broken and
mixed parts of the image.
Changing of buffer size to 2048 helped.
static const size_t bufferSize = 2048;

There is an easy way to capture a picture without the demonstation html:
http://192.168.1.140/capture

Resolution can be changed with numbers between 0 and 8 in such a way:
http://192.168.1.140/?ql=3

I would like to make a PIR activated alarm automatically uploading a
picture to a server.
I am a big fan of MobileWebcam:
http://forum.xda-developers.com/showthread.php?t=950933
On a server is a mobilewebcam.php script that receives the picture file
and puts it into a
directory with a time tag. My webcam page is at http://asi.lv/alnis

Form Linux the upload line looks like that:
curl -F userfile=@/tmp/current.jpg
barbara320.gotdns.com/webcamwr703nRiga/mobilewebcam.php

Php upload is more convenient than FTP upload as the file name can be
automatically prepared on the server side.
I would be very happy if such picture file upload could be implemented on
ESP8266.

Greetings from Latvia, Janis.


Reply to this email directly or view it on GitHub
#21 (comment).

@tzapu
tzapu commented Mar 29, 2016

@janisalnis thank you dude very much for the http upload sample. i could not find that anywhere for the life of me.
if anyone is interested i ve got my work in progress project here:
https://github.com/tzapu/ESP8266ArducamTimelapse
timelapse machine with sd support, ntp sync, deep sleeping, powering off cam, powering off wifi, and a lot more.. but really in progress, did not have enough time to sort everything i wanted yet.

http upload code is one thing that i have been missing dearly. thank you very much

@Shdwdrgn
Shdwdrgn commented Nov 7, 2016

Has there been any further progress on the bufferSize issue? Like others, setting the value to 2048 gives me proper video output, but it is noticeably slower. I'm only trying to stream a 320x240 video, but even that small size has some delay and a lot of skipped frames.

One other thing I noticed, and perhaps someone can explain this to me... I added the timer code from the capture section into the streaming section, so now my serial console shows how long it is taking to output each frame, but the results are confusing. When I first start running my ESP, the first frame will take about 4000ms, but then the next frame takes about 40,000ms -- and it continues alternating between a fast frame and a slow frame that takes 10x as long. Even worse, it slows down quickly over time. After letting it run for about 30 minutes, the frames are alternating between 800,000ms and 8,000,000ms!

My theory on this is that serverStream() is being called multiple times, resulting in overlapping frames and a slow memory leak. I want to test this by adding a static flag at the beginning of the function that exits if the flag is already set, thus only allowing a single instance to run -- unfortunately I have not had a chance to write this and test it out. Also has anyone checked how this program work when called from multiple devices at the same time?

@Shdwdrgn
Shdwdrgn commented Nov 8, 2016

Sorry, I found a mistake in the timing code I added. It looks like it's actually taking about 140ms (consistently) to create and transmit each frame, but that number is still creeping up over time and hits about 170ms in 30 minutes.

So... ignore most of the last two paragraphs in my last comment, but I'd still like to know if there's a way to fix the bufferSize issue to use a larger value? Images of 320x240 appear to contain 6148 or 6149 bytes, and it would be great to capture that in a single pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment