Invalid JPEG returned Arducam SPI 5M

  1. Where did you get the camera module(s)?
    Amazon

  2. What hardware/platform were you working on?
    PICO

  3. Instructions you have followed. (link/manual/etc.)
    GitHub - ArduCAM/PICO_SPI_CAM

  4. Problems you were having?
    Doesn’t return a valid JPEG image as soon as I try to change the resolution

  5. What help do you need?
    I need the module to return valid images

The code I’m using

    mode = 0
    start_capture = 0
    stop_flag=0
    once_number=128
    value_command=0
    flag_command=0
    buffer=bytearray(once_number)

    mycam = ArducamClass(4, 3, 2, 5, 0, 1, 0)
    mycam.Camera_Detection()
    mycam.Spi_Test()
    mycam.Camera_Init()
    mycam.Spi_write(ARDUCHIP_TIM,VSYNC_LEVEL_MASK)
    utime.sleep(1)
    mycam.clear_fifo_flag()
    mycam.Spi_write(ARDUCHIP_FRAMES,0x00)


    mycam.OV5642_set_JPEG_size(OV5642_640x480)

    mycam.flush_fifo();
    mycam.clear_fifo_flag();
    print("Taking picture")
    mycam.start_capture();
    utime.sleep_ms(2000)

    while mycam.get_bit(ARDUCHIP_TRIG,CAP_DONE_MASK)==0:
        pass

    print("Image Ready")

    count=0
    lenght=mycam.read_fifo_length()
    mycam.SPI_CS_LOW()
    mycam.set_fifo_burst()
    while True:
        mycam.spi.readinto(memoryview(buffer)[0: once_number])
        if count == 0:
            print(list(buffer[:10]))
        # usb_cdc.data.write(buffer)
        utime.sleep(0.00015)
        count+=once_number
        if count+once_number>lenght:
            count=lenght-count
            mycam.spi.readinto(memoryview(buffer)[0: count])
            # usb_cdc.data.write(buffer)
            mycam.SPI_CS_HIGH()
            mycam.clear_fifo_flag()
            break

    print("DONE")

This code prints the first 10 bytes of the image and JPEG images should start by :[255, 216, 255,

This is not the case as soon as I try changing the resolution of the camera. For example last time I ran this code I got:

[60]
86 66
CameraType is OV5642
SPI interface OK
Taking picture
Image Ready
[17, 183, 139, 131, 211, 174, 161, 197, 47, 105]
DONE

As we can see the first 3 bytes are not 255, 216, 255 as they should for JPEG images.

Is there a bug in the driver code ?

@GuillaumeLeclerc
Hi, Thanks for your detail message.
Yes, you are right, the data you send is not the jpeg header. Many factor will cause this phenomenon.
Such as the long cable line and unstable hardware connection etc.
Have you tested the demo we released? We should have tested the demo we released. in order to split the issue, my suggestion is please use a shorter cable line and our demo to test it firstly to make sure the hardware is normal, Then let’s check the issue step by step.
Feel free to let me know if you need more help.
Bin from Arducam support team.

Hello,

The cables are very short (<10cm) and when I keep the 320px default resolution I get a correct JPEG header every single time so I’m extremely confident that there are no issues there.

If you look carefully at my script you would see that the functions I’m calling are the ones from your Pico repository. The only difference is that I’m not taking the commands from the computer because the Camera Host app that you ship in the RPI Pico repository doesn’t work. I get “Failed to execute script camera2” Every time I try to run it. (And also I need to be able to run the camera without it being plugged to a computer obviously, otherwise I would have bought a USB camera…)

I ported your Arduino library to PICO boards and I managed to get an image so my wiring has to be correct. There is clearly a problem with your CircuitPython library

To convince you that this is not a problem with the wires here is a screenshot of the result of a logic analyzer. We see me writing the 0x3C byte to start the burst mode and we see that the values of the first bytes are not JPEG signatures

@lvbin Hi again

I’ve spend ludicrous amount of time troubleshooting I hope you could give me some insights here. In the end what I ended up doing was to use a multichannel oscilloscope and track all signals and compare the two drivers (The Arduino one that works and the circuit python that doesn’t)

After interpreting the signals I decoded the SPI protocol and compared the two drivers side by side. See the diff below: Arduino is Left and Python is right.

  • Above this we have the 0x41 calls which check if the image is ready (this repeats for a while)
  • At line 500 for both driver the image becomes available
  • From there the size of the image is read with with reads at address 0x42, 0x43 and 0x44
  • Line 515 the command to read in burst (0x3C) is then written on the bus and we should start receiving the image
  • On the left (The arduino version) we see the 0xFFD8FF denoting a JPEG image, but on the right we see 0x3FEFB2 instead

Something I’m wondering is why the Arducam would answer 0x08 to the 0x41 command on Arduino when the image is ready but 0x9 for the Python version (line 500).

I would really appreciate some help here, we are developing a product that would need hundreds of these camera module so getting them to work is really important to us.

Best regards

@GuillaumeLeclerc
Thanks for your detail check information. Your diagnosis is very professional. In fact, After start capture, we loop read the 0x41 address until the value in the address is 0x08 which means one frame is over.

4-image-data-tranfer-through-i2c-and-how-it-shows-up-on-oscilloscope-1024x186
We just need to care about bit[3]. Don’t worry and we will test it and reply you as soon as possible.

I did the same analysis for the I2C protocol and in this case the two drivers match perfectly except that there are two delays in the Arduino version

Here Arduino is left and Python is Right

Other than this the I2C protocol is bit identical.

I know only bit[3] is relevant here but this is literally the only thing that differ between the two drivers other than the size of the image and the content of the image itself so I thought it might a clue at what is going on and wanted to tell you about it.

Since the data on the buses seem to match maybe it’s a timing problem. Are there restrictions anywhere : some delays that are crucial or maybe things that need to happen really fast ?

Thanks again for the help!

If that can be of any help I have the Capture files in the .sal format for both drivers. I wanted to upload them here but the forum only accepts images.

I found the issue. The python version doesn’t have the delay(1) in wrSensorReg16_8 but the Arduino has. After adding it it works now! I suggest you update the code and test your python driver more thoroughly.

@GuillaumeLeclerc
Hi,
Thanks for your detail test. I have tested it just now and it works normal. I use our demo without any modification.

Maybe Micropython is faster than CircuitPython which makes the delay necessary ?

@GuillaumeLeclerc
I am not sure about the speed of the micropython and CircuitPython. But I think it is necessary to add delay between the i2c write in order to make sure the sensor init is normal.