VC0706 driver for radio shack camera shield
Sample Code
#include "mbed.h" #include "SDFileSystem.h" #include "CameraShield.h" #include <stdio.h> unsigned char VC0706_rx_buffer[80]; SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd", PTE6, SDFileSystem::SWITCH_POS_NO, 25000000); // MOSI, MISO, SCLK, SSEL CameraShield camera(PTC17, PTC16); void CapturePhoto() { uint32_t frame_length = camera.VC0706_get_frame_buffer_length(); //get frame buffer length uint32_t vc_frame_address = READ_DATA_BLOCK_NO; FILE* camFile = fopen("/sd/temp.jpg", "w"); while(vc_frame_address<frame_length) { camera.VC0706_read_frame_buffer(vc_frame_address - READ_DATA_BLOCK_NO, READ_DATA_BLOCK_NO); wait_ms(9); //get the data with length=READ_DATA_BLOCK_NObytes camera.buffer_read(VC0706_rx_buffer, 80); // write data to temp.jpg fwrite(VC0706_rx_buffer + 5, sizeof(char), READ_DATA_BLOCK_NO, camFile); //read next READ_DATA_BLOCK_NO bytes from frame buffer vc_frame_address = vc_frame_address + READ_DATA_BLOCK_NO; } // get the last data vc_frame_address = vc_frame_address - READ_DATA_BLOCK_NO; uint32_t last_data_length = frame_length - vc_frame_address; camera.VC0706_read_frame_buffer(vc_frame_address, last_data_length); wait_ms(9); //get the data camera.buffer_read(VC0706_rx_buffer, 80); fwrite(VC0706_rx_buffer+5, sizeof(char), last_data_length, camFile); fclose(camFile); } int main (void) { // Check to see if the file exists: // if exists,delete the file: sd.remove("/sd/temp.jpg"); camera.Init(); camera.VC0706_image_size(VC0706_640x480); camera.ResumeVideo(); wait_ms(500); while(1) { camera.ResumeVideo(); wait_ms(1000); camera.TakeSnapShot(); CapturePhoto(); } }
Diff: CameraShield.cpp
- Revision:
- 0:e5fc19091502
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CameraShield.cpp Thu Dec 18 04:35:50 2014 +0000 @@ -0,0 +1,568 @@ +/***************************************************************************************** +** File: CameraShield.cpp ** +** ** +** For radio shack Camera Shield. ** +** http://blog.radioshack.com/2013/01/radioshack-camera-shield-for-arduino-boards/ ** +*****************************************************************************************/ + +#include "CameraShield.h" + + +CameraShield::CameraShield ( PinName tx, PinName rx, int speed ) : _serial(tx, rx) +{ + _serial.baud(speed); +} + + +void CameraShield::Init() +{ + VC0706_compression_ratio(63); + wait_ms(100); + + VC0706_frame_control(3); + wait_ms(10); +} + + +void CameraShield::TakeSnapShot() +{ + VC0706_frame_control(0); + wait_ms(10); + _serial.rxBufferFlush(); +} + + +void CameraShield::ResumeVideo() +{ + VC0706_frame_control(3); + wait_ms(10); + _serial.rxBufferFlush(); +} + + +/******************************************************************************* + * Function Name : VC0706_reset + * Description : Reset VC0706 + * + * Input : None + * + * Output : None + * Return : None + *******************************************************************************/ +void CameraShield::VC0706_reset(void) +{ + unsigned char tx_vcbuffer[4]; + + tx_vcbuffer[0]=VC0706_PROTOCOL_SIGN; + tx_vcbuffer[1]=VC0706_SERIAL_NUMBER; + tx_vcbuffer[2]=VC0706_COMMAND_RESET; + tx_vcbuffer[3]=0x00; + + buffer_send(tx_vcbuffer, 4); +} + + + +/******************************************************************************* + * Function Name : VC0706_get_version + * Description : Request version string from VC0706 + * + * Input : None + * + * Output : None + * Return : None + *******************************************************************************/ +void CameraShield::VC0706_get_version() +{ + unsigned char tx_vcbuffer[4]; + + tx_vcbuffer[0]=VC0706_PROTOCOL_SIGN; + tx_vcbuffer[1]=VC0706_SERIAL_NUMBER; + tx_vcbuffer[2]=VC0706_COMMAND_GEN_VERSION; + tx_vcbuffer[3]=0x00; + + buffer_send(tx_vcbuffer, 4); +} + + +/******************************************************************************* + * Function Name : VC0706_tv_out_control + * Description : stop or start TV output from VC0706 + * + * Input : on=0 stop tv output + ; : on=1 start tv output + * + * Output : None + * Return : None + *******************************************************************************/ +void CameraShield::VC0706_tv_out_control(int on) +{ + unsigned char tx_vcbuffer[5]; + + tx_vcbuffer[0]=VC0706_PROTOCOL_SIGN; + tx_vcbuffer[1]=VC0706_SERIAL_NUMBER; + tx_vcbuffer[2]=VC0706_COMMAND_TV_OUT_CTRL; + tx_vcbuffer[3]=0x01; + tx_vcbuffer[4]=on; + + buffer_send(tx_vcbuffer, 5); +} + +/******************************************************************************* + * Function Name : VC0706_osd_add_char + * Description : ADD OSD CHARACTERS TO CHANNELS(CHANNEL 1) + * + * Input : col : Display column + * ` row: Display Row + * osd_string : display string (max 14 characters) + * + * Output : None + * Return : None + *******************************************************************************/ +void CameraShield::VC0706_osd_add_char(int col, int row, char * osd_string) +{ + unsigned char tx_vcbuffer[80]; + unsigned char col_row; + int string_length; + int i; + + col&=0x0f; + row&=0x0f; + col_row=(unsigned char)(col<<4 | row); + + string_length=strlen(osd_string); + if (string_length>14) + string_length=14; // max 14 osd characters + + tx_vcbuffer[0]=VC0706_PROTOCOL_SIGN; + tx_vcbuffer[1]=VC0706_SERIAL_NUMBER; + tx_vcbuffer[2]=VC0706_COMMAND_OSD_ADD_CHAR; + tx_vcbuffer[3]=string_length+2; + tx_vcbuffer[4]=string_length; // character number + tx_vcbuffer[5]=col_row; + + for (i=0;i<string_length;i++) + { + tx_vcbuffer[i+6]=osd_string[i]; + } + + + buffer_send(tx_vcbuffer, string_length+6); +} + + +/******************************************************************************* + * Function Name : VC0706_w_h_downsize + * Description : control width and height downsize attribute + * + * Input : scale_width = 0 1:1 + * = 1 1:2 + * = 2 1:4 + * scale_height= 0 1:1 + * = 1 1:2 + * = 2 1:4 + * + * Output : None + * Return : None + *******************************************************************************/ +void CameraShield::VC0706_w_h_downsize(int scale_width, int scale_height) +{ + int scale; + unsigned char tx_vcbuffer[5]; + + if (scale_width>=2) scale_width=2; + if (scale_height>scale_width) scale_height=scale_width; + scale=(unsigned char)(scale_height<<2 | scale_width); + + + tx_vcbuffer[0]=VC0706_PROTOCOL_SIGN; + tx_vcbuffer[1]=VC0706_SERIAL_NUMBER; + tx_vcbuffer[2]=VC0706_COMMAND_DOWNSIZE_SIZE; + tx_vcbuffer[3]=0x01; + + tx_vcbuffer[4]=scale; //bit[1:0] width zooming proportion + //bit[3:2] height zooming proportion + + buffer_send(tx_vcbuffer, 5); +} + +/******************************************************************************* + * Function Name : VC0706_read_frame_buffer + * Description : read image data from FBUF + * + * Input : buffer_address(4 bytes); buffer_length(4 bytes) + * + * Output : None + * Return : None + *******************************************************************************/ +void CameraShield::VC0706_read_frame_buffer(unsigned long buffer_address, unsigned long buffer_length) +{ + unsigned char tx_vcbuffer[16]; + + tx_vcbuffer[0]=VC0706_PROTOCOL_SIGN; + tx_vcbuffer[1]=VC0706_SERIAL_NUMBER; + tx_vcbuffer[2]=VC0706_COMMAND_READ_FBUF; + tx_vcbuffer[3]=0x0c; + tx_vcbuffer[4]=FBUF_CURRENT_FRAME; + tx_vcbuffer[5]=0x0a; // 0x0a=data transfer by MCU mode; 0x0f=data transfer by SPI interface + tx_vcbuffer[6]=buffer_address>>24; //starting address + tx_vcbuffer[7]=buffer_address>>16; + tx_vcbuffer[8]=buffer_address>>8; + tx_vcbuffer[9]=buffer_address&0x0ff; + + tx_vcbuffer[10]=buffer_length>>24; // data length + tx_vcbuffer[11]=buffer_length>>16; + tx_vcbuffer[12]=buffer_length>>8; + tx_vcbuffer[13]=buffer_length&0x0ff; + tx_vcbuffer[14]=0x00; // delay time + tx_vcbuffer[15]=0x0a; + + + buffer_send(tx_vcbuffer, 16); +} + + +/******************************************************************************* + * Function Name : VC0706_get_frame_buffer_length + * Description : Get frame buffer length + * + * Input : None + * Output : Frame Length + * Return : None + *******************************************************************************/ +uint32_t CameraShield::VC0706_get_frame_buffer_length() +{ + unsigned char tx_vcbuffer[20]; + uint32_t frame_length; + + _serial.rxBufferFlush(); + + //get frame buffer length + VC0706_get_framebuffer_length(0); + wait_ms(10); + buffer_read(tx_vcbuffer, sizeof(tx_vcbuffer)); + + // store frame buffer length for coming reading + frame_length = (tx_vcbuffer[5]<<8) + tx_vcbuffer[6]; + frame_length = frame_length << 16; + frame_length = frame_length + (0x0ff00 & (tx_vcbuffer[7]<<8)) + tx_vcbuffer[8]; + + return frame_length; +} + + + +/******************************************************************************* + * Function Name : VC0706_frame_control + * Description : control frame buffer register + * + * Input : frame_control=control flag(1byte) + * : 0 = stop current frame ; 1= stop next frame;2=step frame;3 =resume frame; + * + * Output : None + * Return : None + *******************************************************************************/ +void CameraShield::VC0706_frame_control(char frame_control) +{ + unsigned char tx_vcbuffer[5]; + + if(frame_control>3)frame_control=3; + tx_vcbuffer[0]=VC0706_PROTOCOL_SIGN; + tx_vcbuffer[1]=VC0706_SERIAL_NUMBER; + tx_vcbuffer[2]=VC0706_COMMAND_FBUF_CTRL; + tx_vcbuffer[3]=0x01; + tx_vcbuffer[4]=frame_control; + + buffer_send(tx_vcbuffer, 5); +} + + +/******************************************************************************* + * Function Name : VC0706_motion_detection + * Description : get motion monitoring status in communication interface. + * + * Input : control_flag = 0 stop motion monitoring + * = 1 start motion monitoring + * + * Output : None + * Return : None + *******************************************************************************/ +void CameraShield::VC0706_motion_detection(int control_flag) +{ + unsigned char tx_vcbuffer[5]; + + + if(control_flag>1)control_flag=1; + tx_vcbuffer[0]=VC0706_PROTOCOL_SIGN; + tx_vcbuffer[1]=VC0706_SERIAL_NUMBER; + tx_vcbuffer[2]=VC0706_COMMAND_COMM_MOTION_CTRL; + tx_vcbuffer[3]=0x01; + tx_vcbuffer[4]=control_flag; + + buffer_send(tx_vcbuffer, 5); +} + +/******************************************************************************* + * Function Name : VC0706_motion_control + * Description : motion control + * + * Input : control_flag = 0 forbid motion monitoring + * = 1 enable motion monitoring + * + * Output : None + * Return : None + *******************************************************************************/ +void CameraShield::VC0706_motion_control(int control_flag) +{ + unsigned char tx_vcbuffer[7]; + + + if(control_flag>1)control_flag=1; + tx_vcbuffer[0]=VC0706_PROTOCOL_SIGN; + tx_vcbuffer[1]=VC0706_SERIAL_NUMBER; + tx_vcbuffer[2]=VC0706_COMMAND_MOTION_CTRL; + tx_vcbuffer[3]=0x03; + tx_vcbuffer[4]=0x00; //motion control attribute + tx_vcbuffer[5]=0x01; //mcu uart control + tx_vcbuffer[6]=control_flag; + + buffer_send(tx_vcbuffer, 7); +} + + + + + + +/******************************************************************************* + * Function Name : VC0706_get_framebuffer_length + * Description : get byte-lengths in FBUF + * + * Input : fbuf_type =current or next frame + * 0 = current frame + * 1 = next frame + * + * Output : None + * Return : None + *******************************************************************************/ +void CameraShield::VC0706_get_framebuffer_length(char fbuf_type) +{ + unsigned char tx_vcbuffer[5]; + + if(fbuf_type>1)fbuf_type=1; + tx_vcbuffer[0]=VC0706_PROTOCOL_SIGN; + tx_vcbuffer[1]=VC0706_SERIAL_NUMBER; + tx_vcbuffer[2]=VC0706_COMMAND_GET_FBUF_LEN; + tx_vcbuffer[3]=0x01; + tx_vcbuffer[4]=fbuf_type; + + buffer_send(tx_vcbuffer, 5); +} + + + +/******************************************************************************* + * Function Name : VC0706_uart_power_save + * Description : stop current frame for reading + * + * Input : power_on =1 start power-save + * = 0 stop power-save + * + * Output : None + * Return : None + *******************************************************************************/ +void CameraShield::VC0706_uart_power_save(char power_save_on) +{ + unsigned char tx_vcbuffer[7]; + + tx_vcbuffer[0]=VC0706_PROTOCOL_SIGN; + tx_vcbuffer[1]=VC0706_SERIAL_NUMBER; + tx_vcbuffer[2]=VC0706_COMMAND_POWER_SAVE_CTRL; + tx_vcbuffer[3]=0x03; + tx_vcbuffer[4]=00; //power save control mode + tx_vcbuffer[5]=01; // control by UART + tx_vcbuffer[6]=power_save_on; //start power save + + + buffer_send(tx_vcbuffer, 7); +} + + +/******************************************************************************* + * Function Name : VC0706_uart_color_control + * Description : stop current frame for reading + * + * Input : show_mode = 0 automatically step black-white and colour + * 1 manually step color, select colour + * 2 manually step color, select black-white + * + * Output : None + * Return : None + *******************************************************************************/ +void CameraShield::VC0706_uart_color_control(char show_mode) +{ + unsigned char tx_vcbuffer[6]; + + if(show_mode>2) show_mode=2; + tx_vcbuffer[0]=VC0706_PROTOCOL_SIGN; + tx_vcbuffer[1]=VC0706_SERIAL_NUMBER; + tx_vcbuffer[2]=VC0706_COMMAND_COLOR_CTRL; + tx_vcbuffer[3]=0x02; + tx_vcbuffer[4]=01; //control by UART + tx_vcbuffer[5]=show_mode; // automatically step black-white and colour + + buffer_send(tx_vcbuffer, 6); +} + + +/******************************************************************************* + * Function Name : VC0706_image_size + * Description : resizing the image + * + * Input : VC0706_640x480 + * VC0706_320x240 + * VC0706_160x120 + * + * Output : None + * Return : None + *******************************************************************************/ +void CameraShield::VC0706_image_size(int ratio) +{ + unsigned char tx_vcbuffer[9]; + + tx_vcbuffer[0]=VC0706_PROTOCOL_SIGN; + tx_vcbuffer[1]=VC0706_SERIAL_NUMBER; + tx_vcbuffer[2]=VC0706_COMMAND_WRITE_DATA; + tx_vcbuffer[3]=0x05; + tx_vcbuffer[4]=0x04; + tx_vcbuffer[5]=0x01; + tx_vcbuffer[6]=0x00; + tx_vcbuffer[7]=0x19; + tx_vcbuffer[8]=ratio; //data + + buffer_send(tx_vcbuffer, 9); +} + + + +/******************************************************************************* + * Function Name : VC0706_compression_ratio + * Description : stop current frame for reading + * + * Input : ration >13(minimum) + * <63(max) + * + * Output : None + * Return : None + *******************************************************************************/ +void CameraShield::VC0706_compression_ratio(int ratio) +{ + unsigned char tx_vcbuffer[9]; + + if(ratio>63)ratio=63; + if(ratio<13)ratio=13; + int vc_comp_ratio=(ratio-13)*4+53; + tx_vcbuffer[0]=VC0706_PROTOCOL_SIGN; + tx_vcbuffer[1]=VC0706_SERIAL_NUMBER; + tx_vcbuffer[2]=VC0706_COMMAND_WRITE_DATA; + tx_vcbuffer[3]=0x05; + tx_vcbuffer[4]=01; //chip register + tx_vcbuffer[5]=0x01; //data num ready to write + tx_vcbuffer[6]=0x12; //register address + tx_vcbuffer[7]=0x04; + tx_vcbuffer[8]=vc_comp_ratio; //data + + buffer_send(tx_vcbuffer, 9); +} + + +/******************************************************************************* + * Function Name : VC0706_motion_windows_setting + * Description : motion windows setting + * + * Input : register_address(2 bytes); + * data(4 bytes)= data ready to write + * + * Output : None + * Return : None + *******************************************************************************/ +void CameraShield::VC0706_motion_windows_setting(unsigned int register_address, unsigned long data) +{ + unsigned char tx_vcbuffer[12]; + + tx_vcbuffer[0]=VC0706_PROTOCOL_SIGN; + tx_vcbuffer[1]=VC0706_SERIAL_NUMBER; + tx_vcbuffer[2]=VC0706_COMMAND_WRITE_DATA; + tx_vcbuffer[3]=0x08; + tx_vcbuffer[4]=01; //chip register + tx_vcbuffer[5]=0x04; //data num ready to write + tx_vcbuffer[6]=register_address>>8; //register address + tx_vcbuffer[7]=register_address&0x0ff;; + + tx_vcbuffer[8]=data>>24; // data ready to write + tx_vcbuffer[9]=data>>16; + tx_vcbuffer[10]=data>>8; + tx_vcbuffer[11]=data&0x0ff; + + buffer_send(tx_vcbuffer, 12); +} + + + +/******************************************************************************* + * Function Name : buffer_send + * Description : Transmit buffer to VC0706 + * + * Input : buff pointer + * : buffer length + * + * Output : None + * Return : None + *******************************************************************************/ +void CameraShield::buffer_send(unsigned char *buff, int buffSize) +{ + int i=0; + + for (i=0;i<buffSize;i++) + _serial.putc(buff[i]); + + // Wait for buffer to send + while(_serial.txIsBusy()) + { + wait_us(1); + } +} + + + +/******************************************************************************* + * Function Name : buffer_read + * Description : Receive buffer from VC0706 + * + * Input : buffer pointer + * : buffer size + * + * Output : length of buffer read + * Return : None + *******************************************************************************/ +int CameraShield::buffer_read(unsigned char *buff, int buffSize) +{ + bool validity=true; + int rx_counter = 0; + + buff[0]=0; + while (_serial.readable() > 0 && rx_counter < buffSize) + { + buff[rx_counter++]= _serial.getc(); + } + + if (buff[0]!=0x76) + validity=false; + if (buff[1]!=VC0706_SERIAL_NUMBER) + validity=false; + + if (validity) + return 0; + + return rx_counter; +} \ No newline at end of file