QC Control software

Dependencies:   mbed

Fork of dgps by Colin Stearns

Files at this revision

API Documentation at this revision

Comitter:
dylanembed123
Date:
Fri Feb 21 15:15:25 2014 +0000
Parent:
3:87c4cd4cb752
Child:
7:c75d5e5e6bfc
Commit message:
Camera takes an image and sends it back to the USB.

Changed in this revision

camera.cpp Show annotated file Show diff for this revision Revisions of this file
camera.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
usb.cpp Show annotated file Show diff for this revision Revisions of this file
usb.h Show annotated file Show diff for this revision Revisions of this file
--- a/camera.cpp	Sun Feb 16 22:12:08 2014 +0000
+++ b/camera.cpp	Fri Feb 21 15:15:25 2014 +0000
@@ -0,0 +1,372 @@
+/*************************************************** 
+  This is a library for the Adafruit TTL JPEG Camera (VC0706 chipset)
+
+  Pick one up today in the adafruit shop!
+  ------> http://www.adafruit.com/products/397
+
+  These displays use Serial to communicate, 2 pins are required to interface
+
+  Adafruit invests time and resources providing this open source code, 
+  please support Adafruit and open-source hardware by purchasing 
+  products from Adafruit!
+
+  Written by Limor Fried/Ladyada for Adafruit Industries.  
+  BSD license, all text above must be included in any redistribution
+ ****************************************************/
+
+
+#include "camera.h"
+
+Serial* Camera::camera=NULL;
+uint8_t Camera::serialNum=0;
+
+Serial& Camera::getSerial(){
+    if(camera==NULL){
+        // Init Camera
+        camera=new Serial(CAMERAPINTX,CAMERAPINRX);
+        camera->baud(CAMERABAUD);
+        serialNum=0;
+        Camera temp;
+        temp.reset();
+    }
+    return *camera;
+}
+
+bool Camera::reset() {
+  uint8_t args[] = {0x0};
+  return runCommand(VC0706_RESET, args, 1, 5);
+}
+
+/*
+// Initialization code used by all constructor types
+void Camera::common_init(void) {
+  swSerial  = NULL;
+  hwSerial  = NULL;
+  frameptr  = 0;
+  bufferLen = 0;
+  serialNum = 0;
+}
+
+// Constructor when using SoftwareSerial or NewSoftSerial
+#if ARDUINO >= 100
+Camera::Camera(SoftwareSerial *ser) {
+#else
+Camera::Camera(NewSoftSerial *ser) {
+#endif
+  common_init();  // Set everything to common state, then...
+  swSerial = ser; // ...override swSerial with value passed.
+}
+
+// Constructor when using HardwareSerial
+Camera::Camera(HardwareSerial *ser) {
+  common_init();  // Set everything to common state, then...
+  hwSerial = ser; // ...override hwSerial with value passed.
+}
+
+boolean Camera::begin(uint16_t baud) {
+  if(swSerial) swSerial->begin(baud);
+  else         hwSerial->begin(baud);
+  return reset();
+}
+
+
+boolean Camera::motionDetected() {
+  if (readResponse(4, 200) != 4) {
+    return false;
+  }
+  if (! verifyResponse(VC0706_COMM_MOTION_DETECTED))
+    return false;
+
+  return true;
+}
+
+
+uint8_t Camera::setMotionStatus(uint8_t x, uint8_t d1, uint8_t d2) {
+  uint8_t args[] = {0x03, x, d1, d2};
+
+  return runCommand(VC0706_MOTION_CTRL, args, sizeof(args), 5);
+}
+
+
+uint8_t Camera::getMotionStatus(uint8_t x) {
+  uint8_t args[] = {0x01, x};
+
+  return runCommand(VC0706_MOTION_STATUS, args, sizeof(args), 5);
+}
+
+
+boolean Camera::setMotionDetect(boolean flag) {
+  if (! setMotionStatus(VC0706_MOTIONCONTROL, 
+            VC0706_UARTMOTION, VC0706_ACTIVATEMOTION))
+    return false;
+
+  uint8_t args[] = {0x01, flag};
+  
+  runCommand(VC0706_COMM_MOTION_CTRL, args, sizeof(args), 5);
+}
+
+
+
+boolean Camera::getMotionDetect(void) {
+  uint8_t args[] = {0x0};
+
+  if (! runCommand(VC0706_COMM_MOTION_STATUS, args, 1, 6))
+    return false;
+
+  return camerabuff[5];
+}
+*/
+uint8_t Camera::getImageSize() {
+  uint8_t args[] = {0x4, 0x4, 0x1, 0x00, 0x19};
+  if (! runCommand(VC0706_READ_DATA, args, sizeof(args), 6))
+    return 0xFF;
+
+  return camerabuff[5];
+}
+
+bool Camera::setImageSize(uint8_t x) {
+  uint8_t args[] = {0x05, 0x04, 0x01, 0x00, 0x19, x};
+  return runCommand(VC0706_WRITE_DATA, args, sizeof(args), 5);
+}
+/*
+// downsize image control 
+
+uint8_t Camera::getDownsize(void) {
+  uint8_t args[] = {0x0};
+  if (! runCommand(VC0706_DOWNSIZE_STATUS, args, 1, 6)) 
+    return -1;
+
+   return camerabuff[5];
+}
+
+boolean Camera::setDownsize(uint8_t newsize) {
+  uint8_t args[] = {0x01, newsize};
+
+  return runCommand(VC0706_DOWNSIZE_CTRL, args, 2, 5);
+}
+
+// other high level commands 
+*/
+char * Camera::getVersion(void) {
+  uint8_t args[] = {0x01};
+  
+  sendCommand(VC0706_GEN_VERSION, args, 1);
+  // get reply
+  if (!readResponse(CAMERABUFFSIZ, 200)){
+    return 0;
+  }
+  camerabuff[bufferLen] = 0;  // end it!
+  return (char *)camerabuff;  // return it!
+}
+/*
+
+// high level photo comamnds
+
+void Camera::OSD(uint8_t x, uint8_t y, char *str) {
+  if (strlen(str) > 14) { str[13] = 0; }
+
+  uint8_t args[17] = {strlen(str), strlen(str)-1, (y & 0xF) | ((x & 0x3) << 4)};
+
+  for (uint8_t i=0; i<strlen(str); i++) {
+    char c = str[i];
+    if ((c >= '0') && (c <= '9')) {
+      str[i] -= '0';
+    } else if ((c >= 'A') && (c <= 'Z')) {
+      str[i] -= 'A';
+      str[i] += 10;
+    } else if ((c >= 'a') && (c <= 'z')) {
+      str[i] -= 'a';
+      str[i] += 36;
+    }
+
+    args[3+i] = str[i];
+  }
+
+   runCommand(VC0706_OSD_ADD_CHAR, args, strlen(str)+3, 5);
+   printBuff();
+}
+
+boolean Camera::setCompression(uint8_t c) {
+  uint8_t args[] = {0x5, 0x1, 0x1, 0x12, 0x04, c};
+  return runCommand(VC0706_WRITE_DATA, args, sizeof(args), 5);
+}
+
+uint8_t Camera::getCompression(void) {
+  uint8_t args[] = {0x4, 0x1, 0x1, 0x12, 0x04};
+  runCommand(VC0706_READ_DATA, args, sizeof(args), 6);
+  printBuff();
+  return camerabuff[5];
+}
+
+boolean Camera::setPTZ(uint16_t wz, uint16_t hz, uint16_t pan, uint16_t tilt) {
+  uint8_t args[] = {0x08, wz >> 8, wz, 
+            hz >> 8, wz, 
+            pan>>8, pan, 
+            tilt>>8, tilt};
+
+  return (! runCommand(VC0706_SET_ZOOM, args, sizeof(args), 5));
+}
+
+
+boolean Camera::getPTZ(uint16_t &w, uint16_t &h, uint16_t &wz, uint16_t &hz, uint16_t &pan, uint16_t &tilt) {
+  uint8_t args[] = {0x0};
+  
+  if (! runCommand(VC0706_GET_ZOOM, args, sizeof(args), 16))
+    return false;
+  printBuff();
+
+  w = camerabuff[5];
+  w <<= 8;
+  w |= camerabuff[6];
+
+  h = camerabuff[7];
+  h <<= 8;
+  h |= camerabuff[8];
+
+  wz = camerabuff[9];
+  wz <<= 8;
+  wz |= camerabuff[10];
+
+  hz = camerabuff[11];
+  hz <<= 8;
+  hz |= camerabuff[12];
+
+  pan = camerabuff[13];
+  pan <<= 8;
+  pan |= camerabuff[14];
+
+  tilt = camerabuff[15];
+  tilt <<= 8;
+  tilt |= camerabuff[16];
+
+  return true;
+}
+
+*/
+bool Camera::takePicture() {
+  frameptr = 0;
+  return cameraFrameBuffCtrl(VC0706_STOPCURRENTFRAME); 
+}
+/*
+boolean Camera::resumeVideo() {
+  return cameraFrameBuffCtrl(VC0706_RESUMEFRAME); 
+}
+
+boolean Camera::TVon() {
+  uint8_t args[] = {0x1, 0x1};
+  return runCommand(VC0706_TVOUT_CTRL, args, sizeof(args), 5);
+}
+boolean Camera::TVoff() {
+  uint8_t args[] = {0x1, 0x0};
+  return runCommand(VC0706_TVOUT_CTRL, args, sizeof(args), 5);
+}
+*/
+bool Camera::cameraFrameBuffCtrl(uint8_t command) {
+  uint8_t args[] = {0x1, command};
+  return runCommand(VC0706_FBUF_CTRL, args, sizeof(args), 5);
+}
+
+uint32_t Camera::frameLength(void) {
+  uint8_t args[] = {0x01, 0x00};
+  if (!runCommand(VC0706_GET_FBUF_LEN, args, sizeof(args), 9))
+    return 0;
+
+  uint32_t len;
+  len = camerabuff[5];
+  len <<= 8;
+  len |= camerabuff[6];
+  len <<= 8;
+  len |= camerabuff[7];
+  len <<= 8;
+  len |= camerabuff[8];
+
+  return len;
+}
+/*
+
+uint8_t Camera::available(void) {
+  return bufferLen;
+}
+
+*/
+uint8_t * Camera::readPicture(uint8_t n,uint8_t* outSize) {
+  uint8_t args[] = {0x0C, 0x0, 0x0A, 
+                    0, 0, frameptr >> 8, frameptr & 0xFF, 
+                    0, 0, 0, n, 
+                    CAMERADELAY >> 8, CAMERADELAY & 0xFF};
+
+  if (! runCommand(VC0706_READ_FBUF, args, sizeof(args), 5, false))
+    return 0;
+
+
+  // read into the buffer PACKETLEN!
+  int outputSize=readResponse(n+5, CAMERADELAY)-5;
+  if (outputSize == 0) 
+      return 0;
+  if(outSize!=NULL)*outSize=outputSize;
+
+  frameptr += outputSize;
+
+  return camerabuff;
+}
+
+
+//
+// Low level commands
+//
+
+bool Camera::runCommand(uint8_t cmd, uint8_t *args, uint8_t argn, uint8_t resplen, bool flushflag) {
+  // flush out anything in the buffer?
+  if (flushflag) {
+    readResponse(100, 10); 
+  }
+
+  sendCommand(cmd, args, argn);
+  if (readResponse(resplen, 200) != resplen) 
+    return false;
+  if (! verifyResponse(cmd))
+    return false;
+  return true;
+}
+
+
+void Camera::sendCommand(uint8_t cmd, uint8_t args[], uint8_t argn) {
+    getSerial().putc(0x56);
+    getSerial().putc(serialNum);
+    getSerial().putc(cmd);
+    
+    for (uint8_t i=0; i<argn; i++) {
+      getSerial().putc(args[i]);
+    }
+}
+
+uint8_t Camera::readResponse(uint8_t numbytes, uint8_t timeout) {
+  uint8_t counter = 0;
+  bufferLen = 0;
+ 
+  while ((timeout != counter) && (bufferLen != numbytes)){
+    int avail = getSerial().readable();
+    if (avail <= 0) {
+      wait_ms(1);
+      counter++;
+      continue;
+    }
+    counter = 0;
+    // there's a byte!
+    camerabuff[bufferLen++] = getSerial().getc();
+  }
+  return bufferLen;
+}
+
+bool Camera::verifyResponse(uint8_t command) {
+  if ((camerabuff[0] != 0x76) ||
+      (camerabuff[1] != serialNum) ||
+      (camerabuff[2] != command) ||
+      (camerabuff[3] != 0x0))
+      return false;
+  return true;
+  
+}
+
+void Camera::printBuff() {
+}
\ No newline at end of file
--- a/camera.h	Sun Feb 16 22:12:08 2014 +0000
+++ b/camera.h	Fri Feb 21 15:15:25 2014 +0000
@@ -1,3 +1,92 @@
 /**
   *  \brief Camera interface
-  **/
\ No newline at end of file
+  **/
+#define CAMERABUFFSIZ 100
+#include "usb.h"
+#include "mbed.h"
+
+/// Define Pinout
+#define CAMERAPINTX p9
+//p13
+#define CAMERAPINRX p10
+//p14
+/// Define Baud
+#define CAMERABAUD 38400
+
+/// Define commands
+#define VC0706_RESET  0x26
+#define VC0706_GEN_VERSION 0x11
+#define VC0706_READ_FBUF 0x32
+#define VC0706_GET_FBUF_LEN 0x34
+#define VC0706_FBUF_CTRL 0x36
+#define VC0706_DOWNSIZE_CTRL 0x54
+#define VC0706_DOWNSIZE_STATUS 0x55
+#define VC0706_READ_DATA 0x30
+#define VC0706_WRITE_DATA 0x31
+#define VC0706_COMM_MOTION_CTRL 0x37
+#define VC0706_COMM_MOTION_STATUS 0x38
+#define VC0706_COMM_MOTION_DETECTED 0x39
+#define VC0706_MOTION_CTRL 0x42
+#define VC0706_MOTION_STATUS 0x43
+#define VC0706_TVOUT_CTRL 0x44
+#define VC0706_OSD_ADD_CHAR 0x45
+
+#define VC0706_STOPCURRENTFRAME 0x0
+#define VC0706_STOPNEXTFRAME 0x1
+#define VC0706_RESUMEFRAME 0x3
+#define VC0706_STEPFRAME 0x2
+
+#define VC0706_640x480 0x00
+#define VC0706_320x240 0x11
+#define VC0706_160x120 0x22
+
+#define VC0706_MOTIONCONTROL 0x0
+#define VC0706_UARTMOTION 0x01
+#define VC0706_ACTIVATEMOTION 0x01
+
+#define VC0706_SET_ZOOM 0x52
+#define VC0706_GET_ZOOM 0x53
+
+#define CAMERABUFFSIZ 100
+#define CAMERADELAY 10
+
+
+
+
+/// \brief Camera class
+class Camera{
+    static Serial* camera;
+    static uint8_t  serialNum;
+    uint8_t bufferLen;
+    uint8_t  camerabuff[CAMERABUFFSIZ+1];
+    uint16_t frameptr;
+public:
+    /// \brief Call this function to get a hold of the serial for camera.
+    static Serial& getSerial();
+    /// \brief Reset the camera
+    bool reset();
+    /// \brief Get the camera version
+    char * getVersion(void);
+    
+    bool takePicture();
+    bool cameraFrameBuffCtrl(uint8_t command);
+    uint8_t* readPicture(uint8_t n,uint8_t* outSize=NULL);
+    uint32_t frameLength(void);
+    /// \brief Get the image Size
+    uint8_t getImageSize();
+    /// \brief Set the image Size
+    bool setImageSize(uint8_t x);
+    //
+    // Low level commands
+    //
+    // Run a command
+    bool runCommand(uint8_t cmd, uint8_t *args, uint8_t argn, uint8_t resplen, bool flushflag = true);
+    // Output the buffer over the USB
+    void printBuff();
+    // Varify the response
+    bool verifyResponse(uint8_t command);
+    // Read the response
+    uint8_t readResponse(uint8_t numbytes, uint8_t timeout);
+    // Send the command
+    void sendCommand(uint8_t cmd, uint8_t args[] = 0, uint8_t argn = 0);
+};
\ No newline at end of file
--- a/main.cpp	Sun Feb 16 22:12:08 2014 +0000
+++ b/main.cpp	Fri Feb 21 15:15:25 2014 +0000
@@ -1,10 +1,13 @@
 #include "mbed.h"
 #include <string>
 #include <sstream>
-
+#include "usb.h"
+#include "camera.h"
+/*
 Serial pc(USBTX,USBRX);
 Serial xbee(p9,p10);//tx, rx
 Serial gps(p28,p27);
+Serial camera(p13,p14);
 
 typedef struct {
     int latitude;  //in .0001 minutes
@@ -147,14 +150,44 @@
         reading = true;
      }
 }
-
+*/
 int main(){
-    gps.baud(57600);
-    xbee.baud(9600);
-    pc.baud(57600);
+    //USB::getSerial().printf("------Starting Program------\n");
+    Camera cam;
+    char* version = cam.getVersion();
+    //USB::getSerial().printf("Camera Version:\n%s\n",version);
+    uint8_t targetSize=VC0706_640x480;//VC0706_160x120;
+    cam.setImageSize(targetSize);
+    uint8_t realSize=cam.getImageSize();
+    //USB::getSerial().printf("Image Size | Target: %d, Real %d",targetSize,realSize);
+    if (! cam.takePicture()) {
+        USB::getSerial().printf("Failed to snap!\n");
+        while(1){}
+    } else {
+        //USB::getSerial().printf("Picture taken!\n");
+    }
+    int size=cam.frameLength();
+    //USB::getSerial().printf("Image Size %d\n",size);
+    int i;
+    for(i=0;i<size;){
+        // read 32 bytes at a time;
+        uint8_t bytesToRead = min(64, size-i); // change 32 to 64 for a speedup but may not work with all setups!
+        uint8_t bytesRead=0;
+        uint8_t* buffer = cam.readPicture(bytesToRead,&bytesRead);
+        for(int a=0;a<bytesRead;a++){USB::getSerial().putc(buffer[a]);}
+        //USB::getSerial().write(buffer,bytesToRead);
+        //USB::getSerial().printf("Read: %d/%d - %d/%d\n",i,size,bytesRead,bytesToRead);
+        i+=bytesRead;
+    }
+    //USB::getSerial().printf("Done(%d)\n",i);
+    while(1){
+    }
+//    gps.baud(57600);
+//    xbee.baud(9600);
+//    pc.baud(57600);
     
 //    sendGpsCommand("PMTK301,1");
 //    while(true){pc.putc(gps.getc());}
-    gps.attach(&handleGpsData, Serial::RxIrq);
+//    gps.attach(&handleGpsData, Serial::RxIrq);
 //    xbee.attach(&handleXbeeGps, Serial::RxIrq);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb.cpp	Fri Feb 21 15:15:25 2014 +0000
@@ -0,0 +1,13 @@
+
+#include "usb.h"
+
+Serial* USB::pc=NULL;
+
+Serial& USB::getSerial(){
+    if(pc==NULL){
+        // Init Serial USB
+        pc=new Serial(USBTX,USBRX);
+        pc->baud(115200);//57600);
+    }
+    return *pc;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb.h	Fri Feb 21 15:15:25 2014 +0000
@@ -0,0 +1,11 @@
+#ifndef _USB_H_
+#define _USB_H_
+#include "mbed.h"
+class USB{
+private:
+    static Serial* pc;
+public:
+    /// \brief Call this function to get a hold of the serial for USB.
+    static Serial& getSerial();
+};
+#endif
\ No newline at end of file