Re: TTL Serial Camera - Nothing seems to work

by suranga on Thu Nov 10, 2011 1:47 pm

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

Thanks!
suranga
 
Posts: 19
Joined: Mon Oct 24, 2011 1:11 pm

Re: TTL Serial Camera - Nothing seems to work

by MrTundraMan on Sat May 12, 2012 8:09 pm

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 5:00 pm

Re: TTL Serial Camera - Nothing seems to work

by MrTundraMan on Mon May 14, 2012 5:54 pm

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.
MrTundraMan
 
Posts: 41
Joined: Tue Apr 10, 2012 5:00 pm

Re: TTL Serial Camera - Nothing seems to work

by maveck on Tue May 22, 2012 8:47 pm

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.
maveck
 
Posts: 6
Joined: Mon Nov 14, 2011 3:46 pm

Re: TTL Serial Camera - Nothing seems to work

by MrTundraMan on Fri May 25, 2012 11:39 am

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)
MrTundraMan
 
Posts: 41
Joined: Tue Apr 10, 2012 5:00 pm

Re: TTL Serial Camera - Nothing seems to work

by maveck on Sat May 26, 2012 12:02 pm

Thank you Mr. ! I haven't compiled this code because apparently it works with linux, what OS did you use?
maveck
 
Posts: 6
Joined: Mon Nov 14, 2011 3:46 pm

Re: TTL Serial Camera - Nothing seems to work

by mtbf0 on Sat May 26, 2012 12:11 pm

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.
"i want to lead a dissipate existence, play scratchy records and enjoy my decline" - iggy pop, i need more
User avatar
mtbf0
 
Posts: 1645
Joined: Fri Nov 09, 2007 11:59 pm
Location: oakland ca

Re: TTL Serial Camera - Nothing seems to work

by maveck on Sat May 26, 2012 1:04 pm

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"
maveck
 
Posts: 6
Joined: Mon Nov 14, 2011 3:46 pm

Re: TTL Serial Camera - Nothing seems to work

by MrTundraMan on Sat May 26, 2012 3:24 pm

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 5:00 pm

Re: TTL Serial Camera - Nothing seems to work

by MrTundraMan on Sat May 26, 2012 3:27 pm

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 3:38 pm, edited 1 time in total.
MrTundraMan
 
Posts: 41
Joined: Tue Apr 10, 2012 5:00 pm

Re: TTL Serial Camera - Nothing seems to work

by MrTundraMan on Sat May 26, 2012 3:37 pm

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 5:00 pm

Re: TTL Serial Camera - Nothing seems to work

by MrTundraMan on Sat May 26, 2012 3:56 pm

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 5:00 pm

Re: TTL Serial Camera - Nothing seems to work

by MrTundraMan on Sat May 26, 2012 4:22 pm

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 5:00 pm

Re: TTL Serial Camera - Nothing seems to work

by MrTundraMan on Sat May 26, 2012 4:57 pm

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 5:00 pm

Re: TTL Serial Camera - Nothing seems to work

by MrTundraMan on Sun May 27, 2012 6:17 am

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.
MrTundraMan
 
Posts: 41
Joined: Tue Apr 10, 2012 5:00 pm