| Spectronix RamCam Last Modified: 2006-11-13 | | |
| Acroname Robotics | PDF webpage version | ||
Introduction A machine that can see is a robot builder's dream. Unfortunately, the reality of computer vision is often a big pile of expensive hardware and complex image processing software that took several man-years to develop. Many image processing problems remain unsolved. However, recent advances in imaging technology have greatly simplified some of the hardware. This article describes a simple color image acquisition system based on the Spectronix RamCam RCM-1-C. The RCM-1-C is a 160x120 pixel Bayer color-filtered CMOS digital camera combined with a frame grabber and 128K image memory buffer. The entire unit fits in a 2x2x2 inch cube! A typical robotic vision system has three main components: camera, frame grabber, and image processing unit. The camera captures an image and sends out a stream of video data. The frame grabber receives this stream of video data and stores it in memory as an array of digital pixels. The processing unit identifies features of interest in the digital image. The RamCam is an ideal solution for the camera and frame grabber hardware. Its large frame buffer also provides a work area for image processing algorithms. This is especially important for microprocessors with limited RAM.
Circuit Schematic The RamCam can interface to a standard memory bus. It can also interface easily to any microcontroller with enough I/O pins. Controlling the RamCam is done by reading and writing its 16 memory registers. The simplest operating mode, Mode 0, requires a minimum of 15 digital I/O pins for the interface: 8 pins for data, 4 pins for register addressing, and 3 pins for read-write control. The Parallax Basic Stamp II-SX has 16 I/O pins. It doesn't have enough computing speed to do serious real-time image processing, but it is sufficient for demonstrating the RamCam interface and serially transmitting pixel data to a host computer. The RamCam can interface to a standard memory bus. It can also interface easily to any microcontroller with enough I/O pins. Controlling the RamCam is done by reading and writing its 16 memory registers. The simplest operating mode, Mode 0, requires a minimum of 15 digital I/O pins for the interface: 8 pins for data, 4 pins for register addressing, and 3 pins for read-write control. The Parallax Basic Stamp II-SX has 16 I/O pins. It doesn't have enough computing speed to do serious real-time image processing, but it is sufficient for demonstrating the RamCam interface and serially transmitting pixel data to a host computer. ![]() Source Code The program is fairly straightforward. The first step is setting a few registers to initialize the camera. The second step is initializing the frame acquisition and reading the acquired image pixels in a loop. A few extra subroutines are necessary since some RamCam operations indicate completion by changing specific bits. Configuring the RamCam's I2C registers also requires some extra reading and writing. The program takes advantage of the "autoincrement" mode which makes it possible to read sequential pixels without having to reset the pixel address for each read. The addresses, bit masks, and initialization data come directly from the RamCam Documentation. However, the constants for the register addresses are bit-reversed. This is because it was slightly easier to make a header cable with the address lines reversed. A plain Basic Stamp II will also work for this project. Appropriate settings for Stamp II serial communication are included in comments. ' RAMCAM interface demo
N9600 con 16624 ' BS2-SX (use 16468 for BS2)
N19200 con 16494 ' BS2-SX (use 16416 for BS2)
N38400 con 16429 ' BS2-SX (use 16390 for BS2)
COM1 con 16
COMMX con N9600 ' select desired baud rate here
i var nib
j var byte
n var word
m var word
bdata var byte
i2caddr var byte
i2cdata var byte
waddr var word
' RCPIN
c_addr var OUTD ' 10-13 8 bit address output
c_oe con 11 ' 27 1 bit output enable output (active low)
c_ce con 10 ' 30 1 bit camera enable output (active low)
c_wr con 9 ' 31 1 bit write control output (active low)
' bit-reversed register addresses (due to header construction)
'1248
cr_ctrl con %0000 '$0 ' camera control
cr_stat con %1000 '$1 ' camera status
cr_cnfg con %0100 '$2 ' camera config
cr_imsk con %1100 '$3 ' interrupt mask control
cr_rdat con %0010 '$4 ' ram data
cr_i2cd con %1010 '$5 ' i2c data
cr_i2ca con %0110 '$6 ' i2c address
cr_i2cc con %1110 '$7 ' i2c control
cr_cac1 con %0001 '$8 ' camera address counter[7:0]
cr_cac2 con %1001 '$9 ' camera address counter[15:8]
cr_capg con %0101 '$A ' camera address page
cr_uac1 con %0011 '$C ' user address counter[7:0]
cr_uac2 con %1011 '$D ' user address counter[15:8]
cr_uapg con %0111 '$E ' user address page
' camera control fields
STRT con %00000001
SYNC con %00000010
RD_INC_ENA con %00100000
WR_INC_ENA con %01000000
LED con %10000000
' camera status fields
FRAME_READY con %00000001
I2C_RD_DONE con %00000010
I2C_WR_DONE con %00000100
I2C_ERROR con %00001000
TOF con %00010000
ACQ_PEND con %00100000
I2C_BUSY con %01000000
ACQ_BUSY con %10000000
'---------------------------------------------------
'
'=============== INITIALIZE CONTROL BITS
'
DIRH=$FE
c_addr=$00
high c_ce: high c_oe: high c_wr ' active low
pause 200
'
'=============== CONFIGURE THE RAMCAM
'
' Grey scale, Mode 0, VV5300/VV6300
' (docs say config register can not be read)
' set auto increment bits and LED on
' image starts at addr 0 (19200 byte image only needs one page)
'
c_addr=cr_cnfg: bdata=$00: gosub sr_outportb
c_addr=cr_ctrl: bdata=$E0: gosub sr_outportb
'
'============== CONFIGURE I2C
'
' 0x10 <- 0x07 configure output to 8 bit data
' 0x14 <- 0x4D FST=norm, QCK=fast, FST enable, (clock data only)
'
i2caddr=$10: i2cdata=$07: gosub sr_write_i2c
i2caddr=$14: i2cdata=$4D: gosub sr_write_i2c
'============== READY TO ACQUIRE IMAGE
gosub sr_blink
acquire:
serin COM1,COMMX,[WAIT("A")]
gosub sr_blink
c_addr=cr_cac1: bdata=$00: gosub sr_outportb
c_addr=cr_cac2: bdata=$00: gosub sr_outportb
c_addr=cr_capg: bdata=$00: gosub sr_outportb
c_addr=cr_ctrl: gosub sr_inportb
bdata=bdata | STRT: gosub sr_outportb
gosub sr_check_acq
waddr=$0001 ' compensate for timing glitch
c_addr=cr_uac1: bdata=waddr.lowbyte: gosub sr_outportb
c_addr=cr_uac2: bdata=waddr.highbyte: gosub sr_outportb
c_addr=cr_uapg: bdata=0: gosub sr_outportb
c_addr=cr_rdat
DIRL=$00
m=19199 ' full image
for n=0 to m
low c_ce: low c_oe:
bdata=INL
high c_ce: high c_oe:
serout COM1,COMMX,[bdata]
next
goto acquire
end
'---------------------------------------------------------------
sr_outportb:
'
' calling routine must set c_addr
'
DIRL=$FF
low c_ce: low c_wr
OUTL=bdata
high c_wr: high c_ce
return
sr_inportb:
'
' calling routine must set c_addr
'
DIRL=$00
low c_ce: low c_oe:
bdata=INL
high c_ce: high c_oe:
return
sr_blink:
c_addr=cr_ctrl
for i=1 to 8
gosub sr_inportb
bdata=bdata ^ LED
gosub sr_outportb
pause 250
next
return
sr_write_i2c:
'
' clear I2C RD bit
' then set outgoing data
' setting I2C address will begin write operation
' wait for I2C write to complete
'
c_addr=cr_i2cc: bdata=$00: gosub sr_outportb
c_addr=cr_i2cd: bdata=i2cdata: gosub sr_outportb
c_addr=cr_i2ca: bdata=i2caddr: gosub sr_outportb
gosub sr_check_i2c
return
sr_read_i2c:
'
' set I2C RD bit
' setting I2C address will begin read operation
' wait for I2C read to complete
' get incoming data
'
c_addr=cr_i2cc: bdata=$01: gosub sr_outportb
c_addr=cr_i2ca: bdata=i2caddr: gosub sr_outportb
gosub sr_check_i2c
c_addr=cr_i2cd: gosub sr_inportb
i2cdata=bdata
return
sr_check_i2c:
sr_check_i2c_busy:
c_addr=cr_stat: gosub sr_inportb
if (bdata & I2C_BUSY) then sr_check_i2c_busy
return
sr_check_acq:
sr_check_acq_busy:
c_addr=cr_stat: gosub sr_inportb
if (bdata & ACQ_BUSY) then sr_check_acq_busy
return
Image Properties The RamCam RCM-1-C image has 19200 (160x120) pixels. The resolution is quite low when compared to digital cameras with photographic quality. This can be an advantage for some image processing algorithms since fewer pixels means less processing time. The horizontal field of view is about 25 degrees. The vertical field of view is about 19 degrees. The camera has an automatic exposure and gain mode which works well under varying light conditions. The lens requires manual focus adjustment. Color Properties For color imaging, the camera employs a Bayer color filter. The Bayer color filter is a grid of red, green, and blue filters over individual pixels. It is organized such that a 2x2 neighborhood of pixels has a red pixel, blue pixel, and two green pixels. One 2x2 neighborhood of pixels is equivalent to a large RGB color pixel. This effectively reduces the resolution of the color image to 80x60. (Interpolation techniques can improve the color resolution, but that is beyond the scope of this article.) The camera is more sensitive to green than red or blue so it is necessary to increase the gain for red and blue pixels in software. A gain of 1.5 for both red and blue is a good starting point. The two green pixels may be averaged. The next figure illustrates the color conversion process. ![]() The RamCam offers random access to all the image pixels. In operating Mode 0, random access requires writing to the pixel address registers and reading from the data register. In addition to random access, the RamCam also has a special "autoincrement" mode. With this mode, it is unnecessary to write the address of each pixel prior to reading its value. After the camera receives a starting address repeated read commands will access sequential pixels and increment the RamCam address registers. The following chart displays the order in which these pixels are accessed.
Sample Images The following images are from a RamCam mounted a few inches above the floor. This is a typical camera position for a small robot. The environment is an office here at Acroname. Like most offices, the colors are fairly subdued. The pictures of a candle at different ranges demonstrate the camera's ability to automatically adjust its exposure and gain. ![]() Going Further For those who bought one before they were discontinued, the Spectronix RamCam RCM-1-C is an excellent choice for a robotic vision project. Combining more powerful processors with the RamCam is the next step towards a flexible and functional system. Some possibilities include a laptop, a dedicated 68HC11 board, or even a BasicX BX-24. The BX-24 is pin-for-pin compatible with the Stamp II, but has more speed and memory. A powerful processor makes a huge number of computer vision techniques possible. The literature on the subject is truly vast and covers everything from simple thresholding to neural networks. The addition of only limited vision capability is a huge leap in performance for most robots. Hopefully, this project can help make that leap. Credits Many thanks go to Eric Olsen, formerly of Spectronix, for his technical assistance on this project. Revision History:
| ||||||||
| voice: 720-564-0373, email: sales@acroname.com, address: 4822 Sterling Dr., Boulder CO, 80301-2350, privacy © Copyright 1994-2008 Acroname, Inc., Boulder, Colorado. All rights reserved. |