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(); } }
CameraShield.cpp
- Committer:
- davidr99
- Date:
- 2014-12-18
- Revision:
- 0:e5fc19091502
File content as of revision 0:e5fc19091502:
/***************************************************************************************** ** 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; }