Sunday 29 April 2012

A quick camera api

By about 6 on Saturday I fully understood the cameras and had them communicating properly, so I decided to write a proper api for them, and test them in full. There's been a bit too much code on this blog lately so I don't want to spend too much time on it, but it's worth mentioning, especially as this might be useful to anyone trying to do the same thing.

This class shows my basic camera api:


class CCamera
{
public:

    CCamera();
    bool Begin(HardwareSerial* serial);
    bool Begin(SoftwareSerial* serial);
    bool Update(); //returns true if idle after update
    bool IsDone();
    ECameraState GetState();
    bool Wait(unsigned long timeout_ms=0); //pass 0 for 'infinite'
    bool Reset();
    bool StartTakingPicture();
    bool GetFileSize(unsigned long* size_buffer);
    bool GetContent(uint8_t* buffer, unsigned long* amount_read_buffer, unsigned long bytes, unsigned long address);
    bool StopTakingPicture();
    bool SetDimensions(ECameraImageDimensions dims);
    bool SetCompressionRatio(unsigned long ratio_0_to_255);
    bool EnterPowerSaving();
    bool LeavePowerSaving();
    bool SetBaudRate(ECameraBaudRate rate);
        
private:
    //... member variables here
};


Download the full code here: camera.zip

You start it up by passing a hardware or serial interface, and can then give it commands to execute. Each command simply posts a request to the camera. Once posted, you keep calling 'Update' until it returns true. This allows you to use the camera in a none-blocking manner which will be needed for MmBot, as she needs to be able to do multiple things at once and never stop responding. In the event that you do actually want to block until a command is ready, you simply call 'Wait' which will internally just keep calling Update until it's done. This little snippet shows me using the 'GetContent' function to read from camera and print it to Serial1 (which has the blue tooth connected to it!):


  while(address < fsize)
  {  
    //read data
    Camera.GetContent(buffer,&amount_read,32,address);
    Camera.Wait();
    
    //print data
    for(int i = 0; i < amount_read; i++)
    {
      printbyte(buffer[i]);
      Serial1.print(",");
    }
    Serial1.println("");
    delay(100);
    
    address += amount_read;
  }      

I got all commands working, however setting the baud rate is tricky (as you then have to change the baud rate you try and talk to it at, and then restarting confuses things etc etc). I also noticed a slight oddity with the cameras - changing compression ratio takes a few images to take effect, so don't be surprised if you set it to highly compressed and your images don't get smaller for a few frames. I think this is just a property of the LinkSprite cameras though.

One thing I have realised after much experimentation is that I'm not gonna be getting more than 1fps out of this, so the pc based image processing will be limited until my raspberry pi arrives (at which point I can use high speed web cams and process them without needing to transmit across a network).

OK, that's enough for this quick little post. Cameras are now fully functional, and I've managed to send data across blue tooth back to the pc. Next up it's time to build the eyes and head.

-Chris

No comments:

Post a Comment