I made Digital Camera using Arducam & WIZwiki-W7500

Dependencies:   Arduino Arducam_OV5642 SDFileSystem Arducam_UTFT_SPI WIZnetInterface_Ricky mbed

main.cpp

Committer:
justinkim
Date:
2015-10-29
Revision:
4:63042b865304
Parent:
3:23d439c8526b

File content as of revision 4:63042b865304:

#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;
}