Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Hand tools and fabrication machines | ||||||
|
I will show you how to make a DIY Digital Camera. It is very easy and simple. Let's start!
Step 1: Materials
We need several materials:
1. WIZwiki-W7500 board
2. Arducam Rev.C
3. micro SD Card
4. OV5642 Camera
5. Battery
6. USB mini B type cable
That's all... for this project~!
Step 2: Hardware
Arducam Rev.C is stacking to WIZwiki-W7500
and OV5642 Camera stacking to Arducam Rev.C
SD card is put to Arducam Rev.C
and connected battery
that's all ! Just stacking !!
Step 3: Software
We need a SoftwareFirmware for WIZwiki-W7500 (mbed source code)
https://developer.mbed.org/users/justinkim/code/DigitalCamera_OV5642_WIZwiki-W7500/
Step 4: Serial Termnal
Serial Terminal Runthat's it~
Step 5: Demo
Demo video
this is 1920x1080p image frame
so... SD Card save time is 5s~15s.
If you want fast save?
please image frame setting under size. (setting is in source code!!)
thank you
#include "mbed.h"
#include "UTFT_SPI.h"
#include "OV5642.h"
#include "OV5642_regs.h"
#include "SDFileSystem.h"
#include "Arduino.h"
#include "EthernetInterface.h"
#include <stdio.h>
#include <string.h>
ArduCAM myCAM(D11, D12, D13, D10, D14, D15);
ArduLCD myGLCD(D11, D12, D13, D10);
SDFileSystem sd(D11, D12, D13, D9, "sd");
Serial pc(USBTX, USBRX);
bool isShowFlag = true;
char fnamecamera[32];
char fnamecntcamera=0;
/* FTP */
#define USER "user "
#define PASS "pass "
#define PASV "pasv "
#define PORT "port "
#define LIST "list "
#define STOR "stor "
#define RETR "retr "
#define END "\r\n"
#define FTP_SERVER_PORT 21
#define MAX_SS 256
bool gDataSockReady = false;
bool gDataPutGetStart = false;
bool ftpclientrun = false;
int remote_port;
char ftpServer_data_ip_addr[4]={0,};
char ftpServer_data_ip_addr_str[20]={0,};
static char buf[256];
static char ID[]={"abc"}; //Set FTPServer Login ID
static char PASSWORD[]={"123"}; //Set FTPServer Login Password
enum CommandFirst {
f_nocmd,
f_put,
};
enum CommandSecond {
s_nocmd,
s_put,
};
enum ftpc_datasock_state{
DATASOCK_IDLE,
DATASOCK_READY,
DATASOCK_START
};
struct Command {
enum CommandFirst First;
enum CommandSecond Second;
};
struct ftpc {
enum ftpc_datasock_state dsock_state;
};
struct ftpc FTPClient;
struct Command FTPCommand;
/* SD Card filesystem */
static FILE *fp_jpeg;
char fname[32];
char fname_server[16];
char fnamecnt=0;
char gMsgBuf[10];
char User_Keyboard_MSG_Cnt;
/* Function*/
char* User_Keyboard_MSG(void);
int pportc(char * arg);
void FTP_server_uploader();
void setup();
void loop();
void itoa( unsigned long long int value, char *str);
int main()
{
*(volatile uint32_t *)(0x41001014) = 0x0060200; //clock 24MHz
setup();
//FTP_server_uploader();
while(1)
{
loop();
}
}
void setup()
{
uint8_t vid,pid;
uint8_t temp;
pc.baud(115200);
pc.printf("ArduCAM Start!\r\n");
uint8_t temp1,temp2;
myCAM.write_reg(ARDUCHIP_TEST1, 0x55); //Write to test1 register by 0x55
myCAM.write_reg(ARDUCHIP_TEST2, 0xAA); //Write to test1 register by 0xaa
wait_ms(1000);
temp1 = myCAM.read_reg(ARDUCHIP_TEST1); //Read from test1 register
temp2 = myCAM.read_reg(ARDUCHIP_TEST2); //Read from test1 register
pc.printf("temp1 : %d\r\n",temp1);
pc.printf("temp2 : %d\r\n",temp2);
wait_ms(1000);
myCAM.write_reg(ARDUCHIP_TEST1, 0x55);
temp = myCAM.read_reg(ARDUCHIP_TEST1);
if(temp != 0x55)
{
pc.printf("SPI interface Error!\r\n");
while(1);
}
//Change MCU mode
myCAM.set_mode(MCU2LCD_MODE);
//Initialize the LCD Module
myGLCD.InitLCD();
//Check if the camera module type is OV5642
myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);
if((vid != 0x56) || (pid != 0x42))
pc.printf("Can't find OV5642 module!\r\n");
else
pc.printf("OV5642 detected\r\n");
//Change to BMP capture mode and initialize the OV5642 module
myCAM.set_format(BMP);
myCAM.InitCAM();
}
void loop()
{
FILE *outFile;
uint8_t buf[256];
static int i = 0;
uint8_t temp,temp_last;
uint8_t start_capture = 0;
//Wait trigger from shutter buttom
if(myCAM.get_bit(ARDUCHIP_TRIG , SHUTTER_MASK))
{
isShowFlag = false;
myCAM.set_mode(MCU2LCD_MODE);
myCAM.set_format(JPEG);
myCAM.InitCAM();
myCAM.OV5642_set_JPEG_size(OV5642_1920x1080);
myCAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK); //VSYNC is active HIGH
//Wait until buttom released
while(myCAM.get_bit(ARDUCHIP_TRIG, SHUTTER_MASK));
wait_ms(1000);
start_capture = 1;
}
else
{
if(isShowFlag )
{
if(!myCAM.get_bit(ARDUCHIP_TRIG,VSYNC_MASK)) //New Frame is coming
{
myCAM.set_mode(MCU2LCD_MODE); //Switch to MCU
myGLCD.resetXY();
myCAM.set_mode(CAM2LCD_MODE); //Switch to CAM
while(!myCAM.get_bit(ARDUCHIP_TRIG,VSYNC_MASK)); //Wait for VSYNC is gone
}
}
}
if(start_capture)
{
//Flush the FIFO
myCAM.flush_fifo();
//Clear the capture done flag
myCAM.clear_fifo_flag();
//Start capture
myCAM.start_capture();
pc.printf("Start Capture\r\n");
}
if(myCAM.get_bit(ARDUCHIP_TRIG ,CAP_DONE_MASK))
{
pc.printf("Capture Done!\r\n");
//Construct a file name
snprintf(fnamecamera, sizeof(fnamecamera), "/sd/jpss%04d.jpg", fnamecntcamera);
fnamecntcamera++;
//Open the new file
outFile = fopen(fnamecamera,"w");
if (! outFile)
{
pc.printf("open file failed\r\n");
return;
}
//Read first dummy byte
//myCAM.read_fifo();
i = 0;
temp = myCAM.read_fifo();
//Write first image data to buffer
buf[i++] = temp;
//Read JPEG data from FIFO
while( (temp != 0xD9) | (temp_last != 0xFF) )
{
temp_last = temp;
temp = myCAM.read_fifo();
//Write image data to buffer if not full
if(i < 256)
buf[i++] = temp;
else
{
//Write 256 bytes image data to file
fwrite(buf,256,1,outFile);
i = 0;
buf[i++] = temp;
}
}
//Write the remain bytes in the buffer
if(i > 0)
fwrite(buf,i,1,outFile);
//Close the file
fclose(outFile);
//Clear the capture done flag
myCAM.clear_fifo_flag();
//Clear the start capture flag
start_capture = 0;
myCAM.set_format(BMP);
myCAM.InitCAM();
isShowFlag = true;
}
}
/* itoa: convert n to characters in s */
void itoa( unsigned long long int value, char *str)
{
int i,j;
char temp[30];
for(i=0; value > 0; i++){
str[i] = value%10+'0';
value=value/10;
}
for(j=0;i>=0;j++,i--){
temp[j]=str[i-1];
}
for(i=0;i<j;i++){
str[i]=temp[i];
}
}
void FTP_server_uploader(){
char Msg_c;
int remain_filesize;
int send_byte;
pc.printf("Hello FTP Camera!\r\n");
uint8_t mac_addr[6] = {0x00, 0x08, 0xdc, 0x12, 0x34, 0x45};
const char ip_addr[] = "192.168.0.123"; // WIZwiki-W7500 IP-address
const char mask_addr[] = "255.255.255.0";
const char gateway_addr[] = "192.168.0.1";
const char ftpServer_control_ip_addr[] = "192.168.0.209"; // my IP address
EthernetInterface eth;
eth.init(mac_addr, ip_addr, mask_addr, gateway_addr); //Use Static
eth.connect();
TCPSocketConnection FTP_CONTROL_SOCK;
TCPSocketConnection FTP_DATA_SOCK;
pc.printf("\r\n----------------------------------------\r\n");
pc.printf("Press menu key\r\n");
pc.printf("----------------------------------------\r\n");
pc.printf("1> Snapshot Picture and Send to FTPServer\r\n");
pc.printf("----------------------------------------\r\n");
Msg_c = pc.getc();
if(Msg_c==0x31){
ftpclientrun = true;
while(ftpclientrun){
//while 2
while(!FTP_CONTROL_SOCK.is_connected()){
pc.printf("Connecting...FTPServer\r\nIP:%s, PORT:%d\r\n", ftpServer_control_ip_addr, FTP_SERVER_PORT);
FTP_CONTROL_SOCK.connect(ftpServer_control_ip_addr, FTP_SERVER_PORT);
FTP_CONTROL_SOCK.set_blocking(false, 15000); // Timeout after (1.5)s
}//end of while 2
//while 3
while(true)
{
//gDataSockReady if
if(gDataSockReady){
gDataSockReady = false;
//FTPCommand.First switch case
switch(FTPCommand.First){
case f_put:
FTP_CONTROL_SOCK.send(STOR, sizeof(STOR)-1);
FTP_CONTROL_SOCK.send(fname_server, sizeof(fname_server));
FTP_CONTROL_SOCK.send(END, sizeof(END)-1);
break;
}//end of FTPCommand.First switch case
}//end of gDataSockReady if
/* received from FTPServer */
int n = FTP_CONTROL_SOCK.receive(buf, sizeof(buf));
if (n <= 0) break;
buf[n] = '\0';
pc.printf("\r\nReceived message from server: '%s'\r\n", buf);
//buf if
if (!strncmp(buf, "220", 3)){
FTP_CONTROL_SOCK.send(USER, sizeof(USER)-1);
FTP_CONTROL_SOCK.send(ID, sizeof(ID));
FTP_CONTROL_SOCK.send(END, sizeof(END)-1);
}
else if(!strncmp(buf, "331", 3)){
FTP_CONTROL_SOCK.send(PASS, sizeof(PASS)-1);
FTP_CONTROL_SOCK.send(PASSWORD, sizeof(PASSWORD));
FTP_CONTROL_SOCK.send(END, sizeof(END)-1);
}
else if(!strncmp(buf, "230", 3)){
FTP_CONTROL_SOCK.send(PASV, sizeof(PASV)-1);
FTP_CONTROL_SOCK.send(END, sizeof(END)-1);
FTPCommand.First = f_put;
}
else if(!strncmp(buf, "227", 3)){
if (pportc(buf) == -1){
pc.printf("Bad port syntax\r\n");
}
else{
pc.printf("Go Open Data Sock...\r\n ");
FTPClient.dsock_state = DATASOCK_READY;
}
}
else if(!strncmp(buf, "150", 3)){
switch(FTPCommand.First){
case f_put:
FTPCommand.First = f_nocmd;
FTPCommand.Second = s_put;
gDataPutGetStart = true;
break;
}
}
else if(!strncmp(buf, "226", 3)){
ftpclientrun = false;
FTP_CONTROL_SOCK.close();
}//end of buf if
//DATASOCK_READY if
if(FTPClient.dsock_state == DATASOCK_READY){
while(!FTP_DATA_SOCK.is_connected()){
pc.printf("Connecting...FTPServer Data sock\r\nIP:%s, PORT:%d\r\n", ftpServer_data_ip_addr_str, remote_port);
FTP_DATA_SOCK.connect(ftpServer_control_ip_addr, remote_port);
FTP_DATA_SOCK.set_blocking(false, 15000); // Timeout after (1.5)s
}
FTPClient.dsock_state = DATASOCK_IDLE;
gDataSockReady = true;
}//end of DATASOCK_READY if
//gDataPutGetStart if
if(gDataPutGetStart){
//FTPCommand.Second switch case
switch(FTPCommand.Second){
case s_put:
pc.printf("put waiting...\r\n");
snprintf(fname, sizeof(fname), "/sd/jpss0000.jpg");
fp_jpeg = fopen(fname, "r");
fseek(fp_jpeg, 0, SEEK_END); // seek to end of file
remain_filesize = ftell(fp_jpeg); // get current file pointer
fseek(fp_jpeg, 0, SEEK_SET); // seek back to beginning of file
do{
memset(buf, 0, sizeof(buf));
if(remain_filesize > MAX_SS)
send_byte = MAX_SS;
else
send_byte = remain_filesize;
fread (buf, 1, send_byte, fp_jpeg);
FTP_DATA_SOCK.send(buf, send_byte);
remain_filesize -= send_byte;
pc.printf("#");
}while(remain_filesize!=0);
fclose(fp_jpeg);
gDataPutGetStart = false;
FTPCommand.Second = s_nocmd;
FTP_DATA_SOCK.close();
break;
}//end of FTPCommand.Second switch case
}//end of gDataPutGetStart if
}//end of while 3
}
}
}
char* User_Keyboard_MSG(void)
{
User_Keyboard_MSG_Cnt = 0;
memset(gMsgBuf, 0, sizeof(gMsgBuf));
do{
gMsgBuf[User_Keyboard_MSG_Cnt] = pc.getc();
if(gMsgBuf[User_Keyboard_MSG_Cnt]==0x08){
User_Keyboard_MSG_Cnt--;
}
else{
User_Keyboard_MSG_Cnt++;
}
}while(gMsgBuf[User_Keyboard_MSG_Cnt-1]!=0x0d);
return gMsgBuf;
}
int pportc(char * arg)
{
int i;
char* tok=0;
strtok(arg,"(");
for (i = 0; i < 4; i++)
{
if(i==0) tok = strtok(NULL,",\r\n");
else tok = strtok(NULL,",");
ftpServer_data_ip_addr[i] = (uint8_t)atoi(tok);
if (!tok){
pc.printf("bad pport : %s\r\n", arg);
return -1;
}
}
remote_port = 0;
for (i = 0; i < 2; i++){
tok = strtok(NULL,",\r\n");
remote_port <<= 8;
remote_port += atoi(tok);
if (!tok){
pc.printf("bad pport : %s\r\n", arg);
return -1;
}
}
pc.printf("ip : %d.%d.%d.%d, port : %d\r\n", ftpServer_data_ip_addr[0], ftpServer_data_ip_addr[1], ftpServer_data_ip_addr[2], ftpServer_data_ip_addr[3], remote_port);
sprintf(ftpServer_data_ip_addr_str, "%d.%d.%d.%d", ftpServer_data_ip_addr[0], ftpServer_data_ip_addr[1], ftpServer_data_ip_addr[2], ftpServer_data_ip_addr[3]);
return 0;
}
Comments