Go Down

Topic: Camera data to SD corrupted when using SPI (Read 1 time) previous topic - next topic

wnekid

Mar 24, 2018, 01:34 am Last Edit: Mar 24, 2018, 01:39 am by wnekid Reason: Added wiring pic
My goal here is to get a VC0706 camera working on my DUE. I was advised to use this library which should do just as that.

https://github.com/Seeed-Studio/Camera_Shield_VC0706

By following the instruction of the README I've successfully captured images using UART mode through hardware serial but this takes about a whole minute to capture and save. Meanwhile with SPI enabled the image is saved in about a second. The downside here is that the SPI transferred image is corrupted every single time. The COM output shows that each image is exactly the same size so I know right away the image is bad. Enabling the debug option didn't point to any real error either. (Just a read error that shows up after every reset, which it does in successful UART trials anyways).

So could anyone lend some input? I'm assuming my wiring is correct or else I wouldn't be able to save images through UART mode to begin with.

ard_newbie

#1
Mar 24, 2018, 06:18 am Last Edit: Mar 24, 2018, 06:18 am by ard_newbie
Your picture is not a schematic, it's very difficult to see connections with shadows !

I understand that you communicate thru Serial1 to the camera, and you store pictures in the SD card via SPI and I guess you followed readme instructions of the library with the SPI option.

I have seen lots of threads reporting issues with SD card in SPI. Sometimes, the device won't tri-state properly, see this tutorial:


https://www.dorkbotpdx.org/blog/paul/better_spi_bus_design_in_3_steps

wnekid

Thanks for the reply, here's at least a description of my wiring

SD breakout board:
CS   ->  Pin 10
DI    ->  MOSI
DO   ->  MISO
CLK  ->  SCK
GND ->  GND
5V    ->  5V

Camera:
TX -> RX1
RX -> TX1
GND ->  GND
5V    ->  5V

And yes the data from the camera is coming from Serial1 and as far as I believe that shouldn't be affected by the change from UART/SPI. However from looking at the code the size of the images seem to be independent from any SPI functions, so I'm not sure why I'm seeing corrupted file size measurements each time in SPI mode. SPI mode is already enabled by default so the only changes I'm making to the code is switching it from software serial to hardware serial.

Thanks for the link but after doing some troubleshooting nothing has changed. A pull up resistor didn't help and I also checked the MISO line and measured the voltage I was expecting (about 1.7V so half of 3.3V). The third step didn't seem especially useful when I only have one SPI device so I didn't try to alter any code with that.

ard_newbie


Did you try to make your SD card device work alone (read/write a short file) in SPI?


BTW, I would be cautious with powering DUE peripherals with 5V without logic level shifters...

wnekid

Did you try to make your SD card device work alone (read/write a short file) in SPI?
Yes I just used the example SD ReadWrite program, seems to be no issues there. Successfully read/wrote through SPI and when I plugged the SD into my computer I got a proper uncorrupted text file. 

Seeing that the SPI example works I'm beginning to think that the camera program's SPI functions are outdated  (seeing that it was last updated 4 years ago). Albeit after trying two older versions of the IDE (1.5.7 & 1.6 which are about as old as the last update) I'm still not seeing any differences.


BTW, I would be cautious with powering DUE peripherals with 5V without logic level shifters...
Wait I'm a little confused here, why would I step down a 5V signal if that's what the devices call for?

weird_dave

The Due is a 3v3 device, not 5v, all of its I/O is 3v3, so connecting 5v devices could cause damage to either/both.

What speed are you writing at when using SPI? Wiring it as you have will likely fail at high speed, I had to use coax cable for the clock to make it work in a similar wiring scenario.

wnekid

The Due is a 3v3 device, not 5v, all of its I/O is 3v3, so connecting 5v devices could cause damage to either/both.
Right I knew that they were 3.3V but didn't think a 5V peripheral would effect the I/O pins. I checked anyways and didn't measure any voltages over 3.3V on the I/O lines but I'll keep that in mind.

What speed are you writing at when using SPI? Wiring it as you have will likely fail at high speed, I had to use coax cable for the clock to make it work in a similar wiring scenario.
By default the divider is 4 so about 21MHz, I changed it to 5 for 16MHz without change. In fact I tried various dividers and the transfer time was still approximately 500ms each time which doesn't seem right. I'm not that familiar enough with coax cables, how did that effect anything? Reduce interferences?

weird_dave

What are you using to measure the voltages on the IO pins? What are the part numbers of the devices you're using, datasheets are the proper way to check.
The coax stopped the clock spewing RF all over the place, it was causing corruption on the data lines, but my wires/cables were a bit longer (I now have a PCB made with appropriate shielding of the SPI lines).

There might be a fault with the code, it may be worth pasting it here.

wnekid

What are you using to measure the voltages on the IO pins?
What are the part numbers of the devices you're using, datasheets are the proper way to check.
An Agilent 34461a.

Well I can't seem to find a data sheet for the breakout board but it's made by Adafruit:
https://www.adafruit.com/product/254?gclid=EAIaIQobChMIgrO8grTz2AIVRRppCh1b0A-EEAQYAiABEgLYT_D_BwE
and the SD card:
https://www.adafruit.com/product/1294

The camera is a "PTC08" according to the data sheet also courtesy of Adafruit:
https://www.adafruit.com/product/397

The coax stopped the clock spewing RF all over the place, it was causing corruption on the data lines, but my wires/cables were a bit longer (I now have a PCB made with appropriate shielding of the SPI lines).

There might be a fault with the code, it may be worth pasting it here.
Okay that makes sense, my clock line is about 3 inches or so but at least works with other SPI programs.

Sure I'm not sure how much I should paste here because it's all contained in the github link in my original post but here's some of the important bits/lines I changed.

This is the main code that had only some minor changes to initialize hardware serial (just involved commenting out 3 lines regarding software serial and uncommenting the hardware serial option):

Code: [Select]

//#include "SoftwareSerial.h"
#include <VC0706_UART.h>
#include <SD.h>
#include <SPI.h>
#define SS_SD  10

//use software serial
//SoftwareSerial cameraconnection(2,3);//Rx, Tx
//VC0706 cam = VC0706(&cameraconnection);
//use hardware serial
VC0706 cam = VC0706(&Serial1);

void setup()
{
    Serial.begin(9600);
    Serial.println("VC0706 Camera Snapshot Test ...");
   
    if (!SD.begin(SS_SD)) {
        Serial.println("SD Card init failed...");
        return;
    } 
    if(true == cameraInit()){
        snapShot();
    }else{
        Serial.println("camera init error...");
    }
}

void loop()
{
    //nothing to do
}

bool cameraInit()
{
    cam.begin(BaudRate_19200);
    char *reply = cam.getVersion();
    if (reply == 0) {
        Serial.println("Failed to get version");
        return false;
    } else {
        Serial.println("version:");
        Serial.println("-----------------");
        Serial.println(reply);
        Serial.println("-----------------");
        return true;
    }
}

void snapShot()
{
    Serial.println("Snap in 3 secs...");
    delay(3000);
    if (! cam.takePicture()){
        Serial.println("Failed to snap!");
    }else {
        Serial.println("Picture taken!");
    }
    // Create an image with the name IMAGExx.JPG
    char filename[13];
    strcpy(filename, "IMAGE00.JPG");
    for (int i = 0; i < 100; i++) {
        filename[5] = '0' + i/10;
        filename[6] = '0' + i%10;
        // create if does not exist, do not open existing, write, sync after write
        if (! SD.exists(filename)) {
            break;
        }
    }
    // Open the file for writing
    File imgFile = SD.open(filename, FILE_WRITE);
    Serial.print("create ");
    Serial.println(filename);
    uint16_t jpglen = cam.getFrameLength();
    Serial.print("wait to fetch ");
    Serial.print(jpglen, DEC);
    Serial.println(" byte image ...");
    int32_t time = millis();
    cam.getPicture(jpglen);
    uint8_t *buffer;
    while(jpglen != 0){
         uint8_t bytesToRead = min(32, jpglen);
         buffer = cam.readPicture(bytesToRead);     
         imgFile.write(buffer, bytesToRead);
         //Serial.print("Read ");  Serial.print(bytesToRead, DEC); Serial.println(" bytes");
         jpglen -= bytesToRead;   
    }
    imgFile.close();
    time = millis() - time;
    Serial.println("Done!");
    Serial.print("Took "); Serial.print(time); Serial.println(" ms");
    cam.resumeVideo();   
}



The actual SPI protocols aren't in the main file but in the library's cpp file, here's a snippet of where things may be acting up. I've tried different setting for the clock divider and data mode without luck. I also manually swapped SLAVE_PIN with pin 10 because it almost seems like SLAVE_PIN is set in the header file to pin 8 yet is set to pin 10 in the main file and isn't changed. I almost thought I had solved the problem but that didn't change anything either.
Code: [Select]

#if TRANSFER_BY_SPI
pinMode(SLAVE_PIN, OUTPUT);
digitalWrite(SLAVE_PIN,HIGH);
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV4);
SPI.setDataMode(SPI_MODE0);
SPI.begin();
#endif


And in the header file the only changes were commenting out SoftwareSerial.h and setting USE_SOFTWARE_SERIAL to 0.

weird_dave

An Agilent 34461a.
I'm wary of using multimeters for checking the level of switching waveforms, even though it has min/max. But let's see what the datasheets say...


Well I can't seem to find a data sheet for the breakout board but it's made by Adafruit:
https://www.adafruit.com/product/254?gclid=EAIaIQobChMIgrO8grTz2AIVRRppCh1b0A-EEAQYAiABEgLYT_D_BwE
and the SD card:
https://www.adafruit.com/product/1294
Click on technical details on the right, it will scroll you down to a link to the schematic, 5v just provides 3v3 so we're all good with this part.

The camera is a "PTC08" according to the data sheet also courtesy of Adafruit:
https://www.adafruit.com/product/397
Did you modify the board as per the instructions to get 3v3 I/O operation rather than RS232 levels?

There's two things I would consider doing at this point.
1) get a scope on the SPI lines and see what's happening.
2) Junk the SPI method used and use SPI.beginTransaction.

However, from what you've posted it looks like you're trying to read the data from the camera via SPI, which (obviously?) won't work. (I had assumed the problem was saving the data via SPI to the SD card instead of serial to a PC).

wnekid

You're talking about that modification in page 2 of the data sheet? Then no I have not physically altered anything.

I hope it's not actually trying to capture the image through SPI because from my understanding it was using serial to get the image and using UART or SPI to actually "transfer" the image.

I'll give SPI.beginTransaction a shot and start using a scope to see if what's going on.

weird_dave

Rs232 levels with a max232 will give you about +/-7v on the IO pins, this isn't particularly good, there is 400R in-line so that's probably saving you.

Can you clarify exactly what you're doing. There are 2 transfer mechanisms in place, one for the camera and one for the SD card. The SD card can only use SPI. The camera can only use RS232 (preferably as 3v3 levels!).
Are you trying to transfer the image from the camera using SPI? (you can't)

wnekid

In a nutshell I simply want to snap and image and have it saved to the SD card in a reasonable amount of time (maybe less than a few seconds). The library has two options for transmission, UART and SPI. While UART works fine it takes too long (about a minute to save to the SD). So I was thinking switching to SPI mode would work much quicker as its an option in the library. From my understanding the image is taken using serial and put in a buffer before being saved either through UART or SPI.

weird_dave

The SPI code in the VC0706 library is for communicating with the camera only, nothing to do with saving to the SD card. (Note that your camera doesn't have the SPI port available, so this won't work, and if you did have one you'd need to connect it to the SPI port too).
The SD card comms should already be using SPI, which is why it's connected to the SPI port.

wnekid

Hm looks like I misunderstood the library then. Odd that they give you the option to use SPI on that very same product without any mention of some very important board alterations...

Oh well I've decided to just stick with the UART mode, I don't exactly get amazing save speeds but bumping up the baud rate and reducing image resolution might just work for my purposes.

Thanks for all you help.

Go Up