TTL Serial Camera - Nothing seems to work

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
suranga
 
Posts: 19
Joined: Mon Oct 24, 2011 2:11 pm

Re: TTL Serial Camera - Nothing seems to work

Post by suranga »

I got it working on with the SD card...I think there is a problem with python code given in the examples.

Thanks!

mrtundraman
 
Posts: 41
Joined: Tue Apr 10, 2012 6:00 pm

Re: TTL Serial Camera - Nothing seems to work

Post by mrtundraman »

Did anyone get the python code working?
I am having the same issue:

VC0706 Camera found
Snap!
47076 bytes to read
ERROR READING PHOTO
Traceback (most recent call last):
File "getimage0706.py", line 141, in <module>
photodata = ''.join(photo)
TypeError


Also, I had to put a 2 sec sleep after the call to reset:

Code: Select all

reset()

[b]time.sleep(2)[/b]

if (not getversion()):

mrtundraman
 
Posts: 41
Joined: Tue Apr 10, 2012 6:00 pm

Re: TTL Serial Camera - Nothing seems to work

Post by mrtundraman »

After about 10 hours of reading/testing, I got it working better. Changed the 10 ms line to 20 ms (at least I think that's what I did :)

Code: Select all

    while (addr < bytes + 32):
        command = readphotocommand + [(addr >> 24) & 0xFF, (addr >> 16) & 0xFF,
                                      (addr >> 8) & 0xFF, addr & 0xFF]
        command +=  [0, 0, 0, 32]   # 32 bytes at a time
        command +=  [2,0]         # delay of 20ms (was 10 ms) <<<<<<<<<<<<<<<<<<<<<<
        #print map(hex, command)
        cmd = ''.join(map (chr, command))
Hopefully this will help other people who are trying to get this working.

maveck
 
Posts: 6
Joined: Mon Nov 14, 2011 4:46 pm

Re: TTL Serial Camera - Nothing seems to work

Post by maveck »

Thank you, Mr TundraMan:

I'd like to know if you python code is working, I'm trying to run this on python, but always I have a problem, could you tell me what did you change in the ladyada code?

Thank you indeed.

mrtundraman
 
Posts: 41
Joined: Tue Apr 10, 2012 6:00 pm

Re: TTL Serial Camera - Nothing seems to work

Post by mrtundraman »

Yes, I got it working. Here's my code which has some extra debug messages added and some commented out:

Code: Select all

# python code for interfacing to VC0706 cameras and grabbing a photo
# pretty basic stuff
# written by ladyada. MIT license

import serial
import time

BAUD = 38400
PORT = "/dev/ttyACM0"
TIMEOUT = 0.2

SERIALNUM = 0    # start with 0

COMMANDSEND = 0x56
COMMANDREPLY = 0x76
COMMANDEND = 0x00

CMD_GETVERSION = 0x11
CMD_RESET = 0x26
CMD_TAKEPHOTO = 0x36
CMD_READBUFF = 0x32
CMD_GETBUFFLEN = 0x34

FBUF_CURRENTFRAME = 0x00
FBUF_NEXTFRAME = 0x01
FBUF_STOPCURRENTFRAME = 0x00

getversioncommand = [COMMANDSEND, SERIALNUM, CMD_GETVERSION, COMMANDEND]
resetcommand = [COMMANDSEND, SERIALNUM, CMD_RESET, COMMANDEND]
takephotocommand = [COMMANDSEND, SERIALNUM, CMD_TAKEPHOTO, 0x01, FBUF_STOPCURRENTFRAME]
getbufflencommand = [COMMANDSEND, SERIALNUM, CMD_GETBUFFLEN, 0x01, FBUF_CURRENTFRAME]

def checkreply(r, b):
    r = map (ord, r)
    #print 'checkreply: completed  map, len=', len(r)
    #print 'r =', r
    if (r[0] == 0x76 and r[1] == SERIALNUM and r[2] == b and r[3] == 0x00):
        return True
    print 'checkReply() failed'
    return False

def reset():
    cmd = ''.join (map (chr, resetcommand))
    s.write(cmd)
    reply = s.read(100)
    r = list(reply)
    if checkreply(r, CMD_RESET):
        return True
    print 'reset(): failure'
    return False
        
def getversion():
    cmd = ''.join (map (chr, getversioncommand))
    s.write(cmd)
    reply =  s.read(16)
    r = list(reply);
    if checkreply(r, CMD_GETVERSION):
        return True
    return False

def takephoto():
    cmd = ''.join (map (chr, takephotocommand))
    s.write(cmd)
    reply =  s.read(5)
    r = list(reply);
    if (checkreply(r, CMD_TAKEPHOTO) and r[3] == chr(0x0)):
        return True
    return False   

def getbufferlength():
    cmd = ''.join (map (chr, getbufflencommand))
    s.write(cmd)
    reply =  s.read(9)
    r = list(reply);
    if (checkreply(r, CMD_GETBUFFLEN) and r[4] == chr(0x4)):
        l = ord(r[5])
        l <<= 8
        l += ord(r[6])
        l <<= 8
        l += ord(r[7])
        l <<= 8
        l += ord(r[8])
        return l
               
    return 0

readphotocommand = [COMMANDSEND, SERIALNUM, CMD_READBUFF, 0x0c, FBUF_CURRENTFRAME, 0x0a]


def readbuffer(bytes):
    addr = 0
    photo = []
    
    while (addr < bytes + 32):
        command = readphotocommand + [(addr >> 24) & 0xFF, (addr >> 16) & 0xFF,
                                      (addr >> 8) & 0xFF, addr & 0xFF]
        command +=  [0, 0, 0, 32]   # 32 bytes at a time
        command +=  [2,0]         # delay of 20ms (was 10 ms)
        #print map(hex, command)
        cmd = ''.join(map (chr, command))
        s.write(cmd)
        reply = s.read(32+5)
        r = list(reply)
        if (len(r) != 37):
            continue
        #print r
        if (not checkreply(r, CMD_READBUFF)):
            print "ERROR READING PHOTO"
            return
        photo += r[5:]
        addr += 32
    return photo
    
######## main

s = serial.Serial(PORT, baudrate=BAUD, timeout=TIMEOUT)

reset()

time.sleep(2)

if (not getversion()):
    print "Camera not found"
    exit
print "VC0706 Camera found"

if takephoto():
    print "Snap!"
    
bytes2read = getbufferlength()

print bytes2read, "bytes to read"

photo = readbuffer(bytes2read)

f = open("photo.jpg", 'w')
photodata = ''.join(photo)
f.write(photodata)
f.close()
#print length(photo)

maveck
 
Posts: 6
Joined: Mon Nov 14, 2011 4:46 pm

Re: TTL Serial Camera - Nothing seems to work

Post by maveck »

Thank you Mr. ! I haven't compiled this code because apparently it works with linux, what OS did you use?

mtbf0
 
Posts: 1645
Joined: Sat Nov 10, 2007 12:59 am

Re: TTL Serial Camera - Nothing seems to work

Post by mtbf0 »

maveck - try changing /dev/ttyACM0 in the line

Code: Select all

PORT = "/dev/ttyACM0"
to the name of whatever com port you're plugged into on your windows box.

maveck
 
Posts: 6
Joined: Mon Nov 14, 2011 4:46 pm

Re: TTL Serial Camera - Nothing seems to work

Post by maveck »

Hi:

The serial port seems open ok, but the program shows this message:

"if (r[0] == 0x76 and r[1] == SERIALNUM and r[2] == b and r[3] == 0x00):IndexError: list index out of range"

mrtundraman
 
Posts: 41
Joined: Tue Apr 10, 2012 6:00 pm

Re: TTL Serial Camera - Nothing seems to work

Post by mrtundraman »

I am running Linux. I am still having some problems although it was working the other day.

I am getting an error in checkReply. I put in a piece of debug code and I am getting:

checkReply(): failed, r= [237, 66, 126, 128, 211, 118, 0, 50, 0, 0]

The first 5 bytes look "left over" from the previous run and the string 118,0,50... looks like what it should be finding.

Here is the modified code I am using:

Code: Select all

def checkreply(r, b):
    r = map (ord, r)
    #print 'checkreply: completed  map, len=', len(r)
    #print 'r =', r
    if (r[0] == 0x76 and r[1] == SERIALNUM and r[2] == b and r[3] == 0x00):
        return True
    print 'checkReply(): failed, r=', r
    return False
I am wondering if there's an issue with the read.

Does someone from AdaFruit (preferably LadyAda herself know) - Is LadyAda's computer running an older version of Python? (pre-2.7 that is)? I found this in the notes for PySerial:
read(size=1)
Parameters:

size – Number of bytes to read.

Returns:

Bytes read from the port.

Read size bytes from the serial port. If a timeout is set it may return less characters as requested. With no timeout it will block until the requested number of bytes is read.

Changed in version 2.5: Returns an instance of bytes when available (Python 2.6 and newer) and str otherwise.
If the previous version returned strings and the current version returns an instance of bytes could that cause this issue?

I am not a Python expert to be sure.

mrtundraman
 
Posts: 41
Joined: Tue Apr 10, 2012 6:00 pm

Re: TTL Serial Camera - Nothing seems to work

Post by mrtundraman »

Speculating some more. If the code returns a 0 in the data (which it probably would) and a string was being parsed it would take that as a shorter string leaving some missing data.

Any Python folks out there who could help?
Last edited by mrtundraman on Sat May 26, 2012 4:38 pm, edited 1 time in total.

mrtundraman
 
Posts: 41
Joined: Tue Apr 10, 2012 6:00 pm

Re: TTL Serial Camera - Nothing seems to work

Post by mrtundraman »

maveck - You got:
"if (r[0] == 0x76 and r[1] == SERIALNUM and r[2] == b and r[3] == 0x00):IndexError: list index out of range"
I haven't gotten that error since I added the time delay after the reset command (in main):

Code: Select all

reset()

time.sleep(2) # added this line which 'fixed' the list index out of range.

if (not getversion()):
    print "Camera not found"
    exit
print "VC0706 Camera found"

mrtundraman
 
Posts: 41
Joined: Tue Apr 10, 2012 6:00 pm

Re: TTL Serial Camera - Nothing seems to work

Post by mrtundraman »

A "good" return value looks like this:
['v', '\x00', '2', '\x00', '\x00', 'v', '\x00', '2', '\x00', '\x00', '\x12', '\x0b', 'Q', '\x04', 'Q', '\x04', '\x00', '\x00', '\xff', '\xdb', '\x00', '\x84', '\x00', '\x05', '\x03', '\x04', '\x04', '\x04', '\x03', '\x05', '\x04', '\x04', '\x04', '\x06', '\x05', '\x05', '\x06']
The "bad" return value looks like this:
['\x08', '\r', '\x08', '\x08', '\x07', 'v', '\x00', '2', '\x00', '\x00', 'v', '\x00', '2', '\x00', '\x00', '\x07', '\x08', '\x0f', '\x0b', '\x0c', '\t', '\r', '\x12', '\x10', '\x13', '\x13', '\x12', '\x10', '\x12', '\x11', '\x14', '\x17', '\x1d', '\x18', '\x14', '\x15', '\x1b']
As can be seen the "header" has an extra 5 characters at the start for the 'bad' return value. My code returns a fairly random number of 32+5 byte packets before it crashes.

mrtundraman
 
Posts: 41
Joined: Tue Apr 10, 2012 6:00 pm

Re: TTL Serial Camera - Nothing seems to work

Post by mrtundraman »

OK, getting closer...

from the manual for the part:
1.3.2.7.READ_FBUF
Command function :read image data from FBUF.
Command format :0x56+serial number+0x32+0x0C+FBUF type(1 byte)+control mode(1 byte)
+starting address(4 bytes)+data-length(4 bytes)+delay(2 bytes)
FBUF type:current frame or next frame
0:current frame
1:next frame
Control mode:the mode by which image data transfer
Bit0:0:data transfer by MCU mode
1:data transfer by DMA mode
Bit[2:1]:2'b11
Bit3: 1'b11
Starting address: the address in fbuf to store the image data.
Data-length:the byte number ready to read, it must be the multiple of 4.
Delay:the delay time between command and data, the unit is 0.01 millisecond.
LadyAda's code has:
def readbuffer(bytes):
addr = 0
photo = []

while (addr < bytes + 32):
command = readphotocommand + [(addr >> 24) & 0xFF, (addr >> 16) & 0xFF,
(addr >> 8) & 0xFF, addr & 0xFF]
command += [0, 0, 0, 32] # 32 bytes at a time
command += [1,0] # delay of 10ms
As I read the manual, the time units are .01 mSec. The first byte is 1 times 256 plus 0 for the second byte or a delay of about .01 * 256 = 2.56 mS. Her comment says 10 mS. That would appear to be incorrect.

I just changed the value to match the example:
command += [0x10,0] # delay of 40.96 ms)
That's 4096 * .01 mS or 40 mSecs. I was able to read an entire frame without it hanging.

However, I must have broken something since the file is half the size that the program indicated it should be and I can't view it. But it's no longer crashing as it download the image...

mrtundraman
 
Posts: 41
Joined: Tue Apr 10, 2012 6:00 pm

Re: TTL Serial Camera - Nothing seems to work

Post by mrtundraman »

OK, I got it working 2 pictures in a row (fixed the 1/2 dropped data issue). Here's what I ended up with for the readbuff() function. Hopefully it will work for you:

Code: Select all

def readbuffer(bytes):
    addr = 0
    photo = []
    
    while (addr < bytes + 32):
        command = readphotocommand + [(addr >> 24) & 0xFF, (addr >> 16) & 0xFF,
                                      (addr >> 8) & 0xFF, addr & 0xFF]
        command +=  [0, 0, 0, 32]   # 32 bytes at a time
        command +=  [0x10,0]         # delay of 40.96 ms (was 10 ms)
#        print 'cmd=', map(hex, command)
        cmd = ''.join(map (chr, command))
        s.write(cmd)
        reply = s.read(32+5)
        r = list(reply)
#        print r
        if (len(r) != 37):
            # print 'Receive count error'
            # print 'Command sent was: ', cmd
            # print 'r is:', r
            continue
        if (not checkreply(r, CMD_READBUFF)):
            print "ERROR READING PHOTO"
            exit()
        photo += r[5:]
        addr += 32
    print 'photo en=', len(photo)
    return photo
Good luck. Takes fairly decent pictures but they look muted like the example so for $42 I wouldn't expect the world.

Perhaps the adafruit folks could take a look at what I did and update their code (at least with a comment that some computers seemed to need this longer delay time).

mrtundraman
 
Posts: 41
Joined: Tue Apr 10, 2012 6:00 pm

Re: TTL Serial Camera - Nothing seems to work

Post by mrtundraman »

By watching the RX, TX LEDs on my UNO, I noticed that the camera's windows application did mostly reads and few writes when loading pictures. My guess was that the camera buffer was read in one long read.

I sped up the camera reads dramatically by making the read buffer larger (2048 instead of 256 bytes). I took the buffer size from 32 bytes and made it configurable. Just change the size of READSIZE to read different sized buffers:

Code: Select all

READSIZE = 2048

def readbuffer(bytes):
    addr = 0
    photo = []
    
    while (addr < bytes + READSIZE):
        command = readphotocommand + [(addr >> 24) & 0xFF, (addr >> 16) & 0xFF,
                                      (addr >> 8) & 0xFF, addr & 0xFF]
        command +=  [0, 0, (READSIZE>>8) & 0xFF, READSIZE & 0xFF]   	# READSIZE bytes at a time
        command +=  [0x10,0]        # delay of 40.96 ms (was 10 ms)
#        print 'cmd=', map(hex, command)
        cmd = ''.join(map (chr, command))
        s.write(cmd)
        reply = s.read(READSIZE + 5)
        r = list(reply)
#        print r
        if (len(r) != READSIZE + 5):
            # print 'Receive count error'
            # print 'Command sent was: ', cmd
            # print 'r is:', r
            continue
        if (not checkreply(r, CMD_READBUFF)):
            print "ERROR READING PHOTO"
            exit()
        photo += r[5:]
        addr += READSIZE
    print 'photo len=', len(photo)
    return photo
Incidentally, since changing the delay time to 40.96 mSecs, I haven't had another camera crash in the python code.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”