Table of Contents

Useful Macros

#define ABS(x)          (((x) > 0)?(x):(-(x))) 
 
#define MAX(x, y)	(((x) > (y))?(x):(y))
#define MIN(x, y)	(((x) < (y))?(x):(y))
 
#define CONVERT_BCD_TO_DEC(n)	(((((n) >> 4) & 0x0F) * 10) + ((n) & 0x0F))
#define CONVERT_DEC_TO_BCD(n)	(((n) > 99) ? 255 : (((((n) / 10) << 4) & 0xF0) | (((n) % 10) & 0x0F)))
 
// set, delete and check bitpositions/-patterns
#define SETBIT(AllBits, BITPOS)                 ((AllBits) |= (1 << (BITPOS)))
#define CLEARBIT(AllBits, BITPOS)               ((AllBits) &= ~(1 << (BITPOS)))
#define CHECKBIT(AllBits, BITPOS)               ((AllBits) & (1 << (BITPOS)))
#define GETBIT(AllBits, BITPOS)                 (((AllBits) >> (BITPOS)) & 0x1)
#define SETPAT(AllBits, BITPAT)                 ((AllBits) |= (BITPAT))
#define CLEARPAT(AllBits, BITPAT)               ((AllBits) &= ~(BITPAT))
#define CHECKPAT(AllBits, BITPAT)               ((AllBits) & (BITPAT))
#define COMPAREBIT(AllBits1, AllBits2, BITPOS)  ((((AllBits1)^(AllBits2)) >> BITPOS) & 0x1)  // 1 if bits are equal
 
#define BSWAP_16(x) (((x) & 0x00ff) << 8 | ((x) & 0xff00) >> 8)
#define BSWAP_32(x) \
     ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) | \
      (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
 
#define __isleap(year)	((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
 
#define PRINTTIME     {struct timeval tv; gettimeofday(&tv,0); printf("%d:%06d\n",tv.tv_sec,tv.tv_usec);}
#define PRINTTIMEL(x) {struct timeval tv; gettimeofday(&tv,0); printf("%d:%06d (%d)\n",tv.tv_sec,tv.tv_usec, x);}

Image Acquisition

Acquiring images from the camera basically consists of the following steps:

This can be illustrated by a simple example which takes one image in single shot mode.

#include <iostream>
#include <stdio.h>
 
#include "OCamera.h"  /* include the camera API header */
 
using namespace std;
 
void SaveImageToFile(unsigned char *buf, int len, char * filename)
{
    FILE *f = fopen(filename,"w+");
    if (f)
    {
      fwrite(buf,1,len,f);
      fclose(f);
    }
}
 
int main(int argc, char *argv[])
{
  /* open the camera interface for the image sensor MT9V403 */
  OCamera *pCamera = OCamera::CreateCameraInterface(OCamera::CAM_TYPE_MT9V403);
  if (pCamera)
    {
      /*
       * adjust camera settings: window, exposure time, trigger, gain
       */
      pCamera->Open(640*480*4);                /* specify frame buffer size = four images */
      pCamera->SetCameraWindow(0,0,640,480);   /* use full VGA window */
      pCamera->SetShutterTime(2000);           /* 2000us exposure time */
      pCamera->SetIlluminationMode(OCamera::ILL_MODE_OFF);   /* no illumination */
      pCamera->SetTriggerSource(OCamera::TRIG_SRC_SOFTWARE); /* trigger by software */
      pCamera->SetGain(5);                                   /* set camera ADC gain */
      pCamera->SetReadTimeout(2000000);                      /* do not wait longer than 2s for an image */
 
      /*
       * start image acquisition in single shot mode
       */
      pCamera->SetAcquisitionMode(OCamera::ACQ_MODE_SINGLE_SHOT);
 
      /*
       * get an image via the driver internal image buffer space
       */      
      OCameraImage img;                  /* image containter */
      int ret = pCamera->GetImage(&img); /* trigger camera and read an image to container */
      if (ret == 0)
      {
        /* do desired work with the image... here: save it to a file */
        SaveImageToFile(img.pData,640*480,"img1.raw");
	/* inform the driver that this buffer can be used again */
        pCamera->ReleaseImage(&img);
      }
      else
      {
        cout << "GetImage returned error code: " << ret << endl;
      }
 
      pCamera->SetAcquisitionMode(OCamera::ACQ_MODE_STOP);
      pCamera->Close();
      pCamera->Destroy();
    }
 return 0;
}

FRAM Access

Simple example showing

file access to the FRAM.

ATTENTION: The WHOLE FRAM will be overwritten inside this example!!

#include <unistd.h> // usleep
#include <stdio.h>  // printf, fopen
#include <stdlib.h> // EXIT_FAILURE
 
// lowlevel file access
#include <fcntl.h>  // open, read write
#include <sys/types.h>
#include <sys/stat.h>
 
int main(void)
{
  // now camera is accessable
  printf("\nHello!\n\n");
 
  // you can check the contents of the FRAM with "cat /dev/fram0" via telnet session
  int  i;
  char cReadChar;
  long lPosition;
  int  iNoBytes;
  char puffer[] = "opqrs";
 
  char CharField[3000];
  for(i = 0; i < 3000; i++)
  {
    if (i < 2000)
    {
      if (0 == i % 10)
        CharField[i] = '*';
      else
        CharField[i] = '.';
    } else
    {
      if (0 == i % 10)
        CharField[i] = '=';
      else
        CharField[i] = ':';
    }
  }
 
  //---------------------------------------------------------------------------
  // highlevel access
  //---------------------------------------------------------------------------
  FILE *pFile;
  int  iWrittenChar;
 
  // attaching FRAM to write to
  pFile = fopen("/dev/fram0", "w"); // a+, a, w+, r+ are also possible but
                                    // read/write position ALWAYS starts at FRAM[0]
  if (pFile == NULL)
  {
    printf("Error opening FRAM\n");
    goto Error_Start;
  }
  // fill whole FRAM with characters
  // writing to indizes > 2047 BLOCKS application immedeately and for infinite!!
  for(i = 0; i < 2048; i++)
  {
    iWrittenChar = fputc(CharField[i], pFile);
  }
  fclose(pFile);
 
  pFile = fopen("/dev/fram0", "r+");
  iNoBytes = fprintf(pFile, "1234567890");  // starts at FRAM[0]
 
  // another write operation starts one byte after the last write operation
  // but you CANNOT ask for the actual position of the write pointer (s.a. lseek down below)
  lPosition = fseek(pFile, 0L, SEEK_CUR); // actual position request returns ALWAYS 0!! => DON'T use it
  printf("Actual write position after 1. write operation: \n \
          \tReturnvalues fseek() == %d   <>   fprintf() = %d\n", lPosition, iNoBytes);
  iNoBytes = fprintf(pFile, "abcdefghi");  // starts at FRAM[10]
 
  // begin writing at predefined index (offset from actual position)
  fseek(pFile, 5L, SEEK_CUR);
  iNoBytes = fwrite(puffer, 1, sizeof(puffer), pFile);  // starts at FRAM[24]
  // begin writing at predefined index (offset starting at FRAM[0])
  fseek(pFile, 3L, SEEK_END);
  iNoBytes = fprintf(pFile, "wwww");  // starts at FRAM[3]!!!
  fseek(pFile, 14L, SEEK_SET);
  for(i = 0; i < 4; i++)
    fputc('u', pFile);  // starts at FRAM[14]
 
  // read 7 bytes starting at FRAM[13]
  fseek(pFile, 13L, SEEK_SET);
  for(i = 0; i < 7; i++)
  {
    cReadChar = fgetc(pFile);
    printf("%c = %d = %#lx\n", cReadChar, cReadChar, cReadChar);
  }
  fclose(pFile);
 
  fseek(pFile, 13L, SEEK_SET);
  fscanf(pFile,"%c",&cReadChar);
  printf("%c = %d = %#lx\n", cReadChar, cReadChar, cReadChar);
 
  printf("\nNow waiting for lowlevel FRAM access for 5 Seconds ... ");
  fflush(stdout);
  usleep(5000000);
  printf("Starting\n\n");
 
 
  //---------------------------------------------------------------------------
  // lowlevel access (PREFERABLE)
  //---------------------------------------------------------------------------
  int  iFileHandle;
  char Character;
 
  if (-1 == (iFileHandle = open("/dev/fram0", O_RDWR)))
  {
    printf("Error opening FRAM\n");
    goto Error_Start;
  }
 
  // fill into FRAM predefined values
  iNoBytes = write(iFileHandle, &CharField[0], 60*sizeof(char));
  printf("%d Bytes written starting at FRAM[0]\n", iNoBytes);
 
  // actual position of filepointer in FRAM
  lPosition = lseek(iFileHandle, 0L, SEEK_CUR);
  printf("Actual Position of rw-pointer is at %d\n",lPosition);
 
  Character = '>';
  lPosition = lseek(iFileHandle, 29, SEEK_SET); // you can also use SEEK_END instead
  iNoBytes = write(iFileHandle, &Character, sizeof(Character));  // starts at FRAM[29]
  printf("%d Bytes written starting at FRAM[%d]\n", iNoBytes, lPosition);
 
  // read 4 bytes starting at FRAM[28]
  lPosition = lseek(iFileHandle, 28, SEEK_END); // you can also use SEEK_SET instead
  for(i = 0; i < 4; i++)
  {
    iNoBytes = read(iFileHandle, &cReadChar, sizeof(cReadChar));
    printf("FRAM[%d]: %c = %d = %#lx\n", lPosition + i, cReadChar, cReadChar, cReadChar);
  }
 
  lPosition = lseek(iFileHandle, 0L, SEEK_CUR);
  printf("Actual Position of rw-pointer is at %d\n",lPosition); // at FRAM[32]
 
  close(iFileHandle);
 
Error_Start:
  printf("\nGoodbye!\n\n");
  return(EXIT_SUCCESS);
}

Digital IO/LED

Input access with OCameraInputs interface

Implemented are three different input wait strategies:

#include "OCamera.h"
 
#include <sys/time.h> // struct timeval, gettimeofday()
#include <unistd.h>   // usleep
#include <stdio.h>
#include <stdlib.h>   // EXIT_FAILURE
 
OCameraInputs   *pIn;
 
int main(void)
{
  pIn = OCameraInputs::poCreateInterface();
  if(pIn == 0)
  {
    printf("Error creation Inputs interface\n");
    goto Error_Input;
  }
  if(pIn->iOpen() < 0)
  {
    printf("Error opening Inputs\n");
    goto Error_InOpen;
  }
 
  // now all interfaces are successfully attached and opened
  printf("\nHello!\n\n");
 
  //////////////////////////////////////////////////////////////////////////////////////
  // now enter code for personal use
  //////////////////////////////////////////////////////////////////////////////////////
  int InValue;
  struct timeval  StartTime, EndTime;
  InValue = pIn->iGetInputs();
  printf("Actual Input-State %#x\n", InValue);
  printf("\tInputs 1 0 = %s %s\n", (InValue & OCameraInputs::INPUT_I1) ? "ON" : "OFF", \
                                   (InValue & OCameraInputs::INPUT_I0) ? "ON" : "OFF");
 
  int iRetVal;
  //---------------------------------------------------------------------------
  // Wait infinite
  pIn->iSetTimeout(-1);
  do
  {
    printf("Waiting infinite until Input 0 changes from 0 -> 1\n");
    gettimeofday(&StartTime,0);
 
    // clear sticky edge detection bits
    iRetVal = pIn->iClearEdges((OCameraInputs::INPUT_I0_RE | OCameraInputs::INPUT_I0_FE | OCameraInputs::INPUT_I1_RE | OCameraInputs::INPUT_I1_FE));
 
    // stop program execution until input zero changes to 1
    iRetVal = pIn->iWaitForInput(OCameraInputs::INPUT_I0_RE, 1);
    gettimeofday(&EndTime,0);
    InValue = pIn->iGetInputs();
    printf("Returncode = %d\tTime elapsed: %dsec %dusec\n", iRetVal, \
                   (EndTime.tv_sec - StartTime.tv_sec), (EndTime.tv_usec - StartTime.tv_usec));
    printf("Actual Input-State %#x\n", pIn->iGetInputs());
    printf("\tInputs 1 0 == %s %s\n", (InValue & OCameraInputs::INPUT_I1) ? "ON" : "OFF", \
                                     (InValue & OCameraInputs::INPUT_I0) ? "ON" : "OFF");
    printf("Exit if Inputs 1 0 == ON ON\n");
  } while ((InValue & OCameraInputs::INPUT_ALL) != OCameraInputs::INPUT_ALL);
 
  printf("\nRelease Inputs!!\n\n");
  usleep(3000000);
 
  //---------------------------------------------------------------------------
  // Wait with timeout
  pIn->iSetTimeout(3000); // no more infinite waiting!!
  do
  {
    printf("Wait until Input 0 and 1 equal each 1 OR 3000ms elapsed\n");
    gettimeofday(&StartTime,0);
    // stop program execution until
    //   - input zero changes to 1   OR
    //   - input one changes to 1    OR
    //   - 3000 milliseconds elapsed
    iRetVal = pIn->iWaitForInputs(OCameraInputs::INPUT_ALL, 3);
    gettimeofday(&EndTime,0);
    InValue = pIn->iGetInputs();
    printf("Returncode == %d\tInValue == %d\n",iRetVal,InValue);
    if (iRetVal < 0)
    {
      // timeout or error occurred
      printf("\tTimeout: Time elapsed: %ldusec\n", (EndTime.tv_sec - StartTime.tv_sec)*1000 + (EndTime.tv_usec - StartTime.tv_usec));
    } else
    {
      printf("\tInput: Time elapsed: %dlusec\n", (EndTime.tv_sec - StartTime.tv_sec)*1000 + (EndTime.tv_usec - StartTime.tv_usec));
      printf("\t\tInputs 1 0 == %s %s\n", (pIn->iGetInput(OCameraInputs::INPUT_I1)) ? "ON" : "OFF", \
                                          (pIn->iGetInput(OCameraInputs::INPUT_I0)) ? "ON" : "OFF");
    }
    printf("Exit if Inputs 1 0 == ON ON [%#x]\n", InValue);
  } while ((InValue & OCameraInputs::INPUT_ALL) != OCameraInputs::INPUT_ALL);
 
  printf("\nRelease Inputs!!\n\n");
  usleep(3000000);
 
  //---------------------------------------------------------------------------
  // Wait infinite for input changes
  pIn->iSetTimeout(-1); // set timeout value to wait infinite
  do
  {
    printf("Wait until Input 0 OR 1 changes\n");
    gettimeofday(&StartTime,0);
    // stop program execution until
    //   - input zero changes   OR
    //   - input one changes
    iRetVal = pIn->iWaitForInputsChange(OCameraInputs::INPUT_I0 | OCameraInputs::INPUT_I1);
    gettimeofday(&EndTime,0);
    InValue = pIn->iGetInputs();
    printf("Returncode = %d\tTime elapsed: %dsec %dusec\n", iRetVal, \
                   (EndTime.tv_sec - StartTime.tv_sec), (EndTime.tv_usec - StartTime.tv_usec));
    printf("Actual Input-State %#x\n", pIn->iGetInputs());
    printf("\tInputs 1 0 = %s %s\n", (InValue & OCameraInputs::INPUT_I1) ? "ON" : "OFF", \
                                     (InValue & OCameraInputs::INPUT_I0) ? "ON" : "OFF");
    printf("Exit if Inputs 1 0 == ON ON\n");
  } while ((InValue & OCameraInputs::INPUT_ALL) != OCameraInputs::INPUT_ALL);
  //////////////////////////////////////////////////////////////////////////////////////
 
  //---------------------------------------------------------------------------
  // Cleanup
  //---------------------------------------------------------------------------
  // defined cleanup of all interfaces
  pIn->iClose();
Error_InOpen:
  pIn->Destroy();
Error_Input:
 
  printf("\nGoodbye!\n\n");
  return(EXIT_SUCCESS);
}

Output access with OCameraOutputs interface

This application opens the interface to the three digital outputs and manipulates their state.

#include "OCamera.h"
 
#include <unistd.h> // usleep
#include <stdio.h>
#include <stdlib.h> // EXIT_FAILURE
 
OCameraOutputs  *pOut;
 
int main(void)
{
  pOut = OCameraOutputs::poCreateInterface();
  if(!pOut)
  {
    printf("Error creation Outputs interface\n");
    goto Error_Output;
  }
  if(pOut->iOpen() < 0)
  {
    printf("Error opening Outputs\n");
    goto Error_OutOpen;
  }
 
  // now all interfaces are successfully attached and opened
  printf("\nHello!\n\n");
 
  //////////////////////////////////////////////////////////////////////////////////////
  // now enter code for personal use
  //////////////////////////////////////////////////////////////////////////////////////
  int OutValue;
  OutValue = pOut->iGetOutputs();
  printf("Actual Output-State %#x (2 1 0)\n", OutValue);
  printf("\tOutputs 2 1 0 = %s %s %s\n", (OutValue & OCameraOutputs::OUTPUT_O2) ? "ON" : "OFF", \
                                         (OutValue & OCameraOutputs::OUTPUT_O1) ? "ON" : "OFF", \
                                         (OutValue & OCameraOutputs::OUTPUT_O0) ? "ON" : "OFF");
 
  pOut->iSetOutput(OCameraOutputs::OUTPUT_O0, 1);
  usleep(300000);
  pOut->iSetOutput(OCameraOutputs::OUTPUT_O1, 1);
  usleep(300000);
  pOut->iSetOutput(OCameraOutputs::OUTPUT_O2, 1);
  usleep(300000);
  pOut->iSetOutput(OCameraOutputs::OUTPUT_O0, 0);
  usleep(300000);
  pOut->iSetOutput(OCameraOutputs::OUTPUT_O1, 0);
  usleep(300000);
  pOut->iSetOutput(OCameraOutputs::OUTPUT_O2, 0);
  usleep(300000);
  pOut->iSetOutput(OCameraOutputs::OUTPUT_ALL, 1);
  usleep(300000);
  pOut->iSetOutput(OCameraOutputs::OUTPUT_ALL, 0);
  usleep(300000);
 
  // activate ONLY outputs zero and two even if a iState of 0x7 is chosen!!
  pOut->iSetOutputs(OCameraOutputs::OUTPUT_O0 | OCameraOutputs::OUTPUT_O2, 0x7);
  printf("Actual Output-State %#x\n", pOut->iGetOutputs());
  printf("\tOutput 1 = %s\n", (pOut->iGetOutput(OCameraOutputs::OUTPUT_O1)) ? "ON" : "OFF");
  usleep(1000000);
 
  // toggle some outputs
  pOut->iToggleOutputs(OCameraOutputs::OUTPUT_O1 | OCameraOutputs::OUTPUT_O2);
  printf("Actual Output-State %#x\n", pOut->iGetOutputs());
  usleep(800000);
 
  pOut->iToggleOutput(OCameraOutputs::OUTPUT_O0);
  printf("Actual Output-State %#x\n", pOut->iGetOutputs());
  usleep(800000);
  //////////////////////////////////////////////////////////////////////////////////////
 
  //---------------------------------------------------------------------------
  // Cleanup
  //---------------------------------------------------------------------------
  // defined cleanup of all interfaces
  pOut->iClose();
Error_OutOpen:
  pOut->Destroy();
Error_Output:
 
  printf("\nGoodbye!\n\n");
  return(EXIT_SUCCESS);
}

Simple LED toggle

This simple application opens the interface to the leds and toggles them.

#include "OCamera.h"
 
void main(void)
{
	OCameraLEDs LED;
 
	LED.iToggleLEDs(LED_ALL_GREEN); // toogle all green leds on the camera
}

More experienced LED access

This demo-application opens the interface to the led-handler and demonstrates the usage of manipulating the led-states (color).

#include "OCamera.h"
 
#include <unistd.h> // usleep
#include <stdio.h>
#include <stdlib.h> // EXIT_FAILURE
 
OCameraLEDs     *pLED;
 
int main(void)
{
  pLED = OCameraLEDs::poCreateInterface();
  if(!pLED)
  {
    printf("Error creation LEDs interface\n");
    goto Error_LED;
  }
  if(pLED->iOpen() < 0)
  {
    printf("Error opening LEDs\n");
    goto Error_LEDOpen;
  }
 
  // now all interfaces are successfully attached and opened
  printf("\nHello!\n\n");
 
  //////////////////////////////////////////////////////////////////////////////////////
  // now enter code for personal use
  //////////////////////////////////////////////////////////////////////////////////////
  int LEDValue;
  LEDValue = pLED->iGetLEDs();
  printf("Actual LED-State %#x (D C B A)\n", LEDValue);
  printf("\tLED A green  red = %s %s\n", (LEDValue & OCameraLEDs::LED_0_GREEN)  ? "ON" : "OFF", \
                                        (LEDValue & OCameraLEDs::LED_0_RED)    ? "ON" : "OFF");
  printf("\tLED B green  red = %s %s\n", (LEDValue & OCameraLEDs::LED_1_GREEN)  ? "ON" : "OFF", \
                                        (LEDValue & OCameraLEDs::LED_1_RED)    ? "ON" : "OFF");
  printf("\tLED C yellow red = %s %s\n", (LEDValue & OCameraLEDs::LED_2_YELLOW) ? "ON" : "OFF", \
                                        (LEDValue & OCameraLEDs::LED_2_RED)    ? "ON" : "OFF");
  printf("\tLED D yellow red = %s %s\n", (LEDValue & OCameraLEDs::LED_3_YELLOW) ? "ON" : "OFF", \
                                        (LEDValue & OCameraLEDs::LED_3_RED)    ? "ON" : "OFF");
 
  pLED->iSetLED(OCameraLEDs::LED_ALL, 1);
  usleep(500000);
  pLED->iSetLED(OCameraLEDs::LED_ALL, 0);
  usleep(300000);
  pLED->iSetLED(OCameraLEDs::LED_0_GREEN, 1);
  usleep(200000);
  pLED->iSetLED(OCameraLEDs::LED_0_RED, 1);
  usleep(200000);
  pLED->iSetLED(OCameraLEDs::LED_1_GREEN, 1);
  usleep(200000);
  pLED->iSetLED(OCameraLEDs::LED_1_RED, 1);
  usleep(200000);
  pLED->iSetLED(OCameraLEDs::LED_2_YELLOW, 1);
  usleep(200000);
  pLED->iSetLED(OCameraLEDs::LED_2_RED, 1);
  usleep(200000);
  pLED->iSetLED(OCameraLEDs::LED_3_YELLOW, 1);
  usleep(200000);
  pLED->iSetLED(OCameraLEDs::LED_3_RED, 1);
  usleep(200000);
  pLED->iSetLED(OCameraLEDs::LED_0_GREEN, 0);
  usleep(200000);
  pLED->iSetLED(OCameraLEDs::LED_0_RED, 0);
  usleep(200000);
  pLED->iSetLED(OCameraLEDs::LED_1_GREEN, 0);
  usleep(200000);
  pLED->iSetLED(OCameraLEDs::LED_1_RED, 0);
  usleep(200000);
  pLED->iSetLED(OCameraLEDs::LED_2_YELLOW, 0);
  usleep(200000);
  pLED->iSetLED(OCameraLEDs::LED_2_RED, 0);
  usleep(200000);
  pLED->iSetLED(OCameraLEDs::LED_3_YELLOW, 0);
  usleep(200000);
  pLED->iSetLED(OCameraLEDs::LED_3_RED, 0);
  usleep(200000);
  pLED->iSetLED(OCameraLEDs::LED_ALL_RED, 1);
  usleep(500000);
  pLED->iSetLED(OCameraLEDs::LED_ALL_RED, 0);
  usleep(300000);
  pLED->iSetLED(OCameraLEDs::LED_ALL_GREEN, 1);
  usleep(500000);
  pLED->iSetLED(OCameraLEDs::LED_ALL_GREEN, 0);
  usleep(300000);
  pLED->iSetLED(OCameraLEDs::LED_ALL_YELLOW, 1);
  usleep(500000);
  pLED->iSetLED(OCameraLEDs::LED_ALL_YELLOW, 0);
  usleep(300000);
 
  // activate ONLY LEDs C and D and two even if a iState of 0xFF is chosen!!
  pLED->iSetLEDs(OCameraLEDs::LED_2_YELLOW | OCameraLEDs::LED_2_RED | \
                 OCameraLEDs::LED_3_YELLOW | OCameraLEDs::LED_3_RED, 0xFF);
  printf("Actual LED-State %#x\n", pLED->iGetLEDs());
  printf("\tLED C yellow red = %s %s\n", (pLED->iGetLED(OCameraLEDs::LED_2_YELLOW)) ? "ON" : "OFF", \
                                         (pLED->iGetLED(OCameraLEDs::LED_2_RED)) ? "ON" : "OFF");
  printf("\tLED D yellow red = %s %s\n", (pLED->iGetLED(OCameraLEDs::LED_3_YELLOW)) ? "ON" : "OFF", \
                                         (pLED->iGetLED(OCameraLEDs::LED_3_RED)) ? "ON" : "OFF");
  usleep(500000);
 
  // toggle some outputs
  pLED->iToggleLEDs(OCameraLEDs::LED_2_YELLOW | OCameraLEDs::LED_3_RED);
  printf("Actual LED-State %#x\n", pLED->iGetLEDs());
  printf("\tLED C yellow red = %s %s\n", (pLED->iGetLED(OCameraLEDs::LED_2_YELLOW)) ? "ON" : "OFF", \
                                         (pLED->iGetLED(OCameraLEDs::LED_2_RED)) ? "ON" : "OFF");
  printf("\tLED D yellow red = %s %s\n", (pLED->iGetLED(OCameraLEDs::LED_3_YELLOW)) ? "ON" : "OFF", \
                                         (pLED->iGetLED(OCameraLEDs::LED_3_RED)) ? "ON" : "OFF");
  usleep(500000);
 
  pLED->iToggleLED(OCameraLEDs::LED_3_YELLOW);
  printf("Actual LED-State %#x\n", pLED->iGetLEDs());
  printf("\tLED C yellow red = %s %s\n", (pLED->iGetLED(OCameraLEDs::LED_2_YELLOW)) ? "ON" : "OFF", \
                                         (pLED->iGetLED(OCameraLEDs::LED_2_RED)) ? "ON" : "OFF");
  printf("\tLED D yellow red = %s %s\n", (pLED->iGetLED(OCameraLEDs::LED_3_YELLOW)) ? "ON" : "OFF", \
                                         (pLED->iGetLED(OCameraLEDs::LED_3_RED)) ? "ON" : "OFF");
  usleep(500000);
  //////////////////////////////////////////////////////////////////////////////////////
 
  //---------------------------------------------------------------------------
  // Cleanup
  //---------------------------------------------------------------------------
  // defined cleanup of all interfaces
  pLED->iClose();
Error_LEDOpen:
  pLED->Destroy();
Error_LED:
 
  printf("\nGoodbye!\n\n");
  return(EXIT_SUCCESS);
}

CAN

CAN Analyser

This program displays messages of the CAN bus.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>     /* exit */
#include <sys/ioctl.h>  /* ioctl */
#include <signal.h>
 
#include "can.h" /* from the camera's /include directory */
 
static int can_fd;
static int in_fd;
static int bInputsIsOn = 0; /* test for inputs */
 
void main_cleanup (int signal)
{
  int ret;
  /* added for stability reasons
   * => change to the device's initial startup mode
   */
  ret = ioctl(can_fd, CAN_IOC_MODE, CAN_CONFIG_MODE);
  if (ret < 0) perror("ioctl reset to normal mode");
 
 
  ioctl(can_fd, CAN_IOC_RESET, 0);  // added to avoid rx buffer full messages in dmesg
  close(can_fd);
  if(bInputsIsOn)
  {
    close(in_fd);
  }
  exit(0);
}
 
int read_inputs(void)
{
   char buf[64];
   int val = 0;
   if (in_fd > 0)
   {
      lseek(in_fd,0,SEEK_SET);
      int len = read(in_fd,buf,sizeof(buf));
      if (len != 0) sscanf(buf,"0x%x",&val);
    }
    return (val & 0x3);
}
 
void print_msg(struct msg_t *msg)
{
  int i;
 
  printf("%04ld:%06ld ", msg->rx_time/1000000, msg->rx_time%1000000);
  if(bInputsIsOn)
  {
    printf("I=%d ID 0x%03x ", read_inputs(),msg->ident);
  }else
  {
    printf("ID 0x%03x ", msg->ident);
  }
 
  if (msg->bits & 0x01)	printf("EID 0x%05x ", msg->eident);
  if (msg->bits & 0x02)	printf("RTR\n");
  else
    {
      printf("[");
      for (i = 0; i < msg->data_length; i++)
      if (i == 0) printf("0x%02x",msg->data[i]);
      else printf(" 0x%02x",msg->data[i]);
      printf("]\n");
    }
}
 
void print_usage(void)
{
  printf("\ncanalyser for festo cameras\n\n");
  printf("arguments: -b <baudrate>\n");
  printf("           -i (for additional input tracing)\n\n");
}
 
int main(int argc, char *argv[])
{
  char device[] = "/dev/can0";
  struct msg_t msg;
  int i,ret;
  struct mcp2515_filter_t filter;
  int baudrate = 1000000;
 
  /*
   * check for -h or --help
   */
  for (i=1; i<argc; i++)
    {
      if ((strcmp(argv[i],"-?") == 0) ||
          (strcmp(argv[i],"-h") == 0) ||
          (strcmp(argv[i],"--help") == 0))
        {
          print_usage();
          return 0;
        }
    }
 
  /*
   * check for baudrate argument
   */
  for (i=1; i<argc; i++)
    {
      if (strcmp(argv[i],"-b") == 0)
        {
          if (i+1 < argc)
            {
              baudrate = atoi(argv[i+1]);
            }
        }
    }
 
  /*
   * check for input argument
   */
  for (i=1; i<argc; i++)
    {
      if (strcmp(argv[i],"-i") == 0)
        {
          bInputsIsOn = 1;
 
          /*
           * open input driver
           */
          in_fd = open("/proc/inputs", O_RDONLY);
          if (in_fd < 0)
          {
            perror("Can't open input device");
            exit(-1);
          }
        }
    }
 
  /*
   * open the CAN driver
   */
  can_fd = open(device, O_RDWR);
  if (can_fd < 0)
    {
      perror("Can't open device file ");
      exit(-2);
    }
 
  /*
   * set listen only mode
   */
  ret = ioctl(can_fd, CAN_IOC_MODE, CAN_LISTEN_MODE);
  if (ret < 0) perror("ioctl set listen only mode");
 
  /*
   * set baud rate
   */
  ret = ioctl(can_fd, CAN_IOC_BAUDRATE, baudrate);
  if (ret < 0) perror("ioctl baudrate - ");
 
  /*
   * set receive filter to receive all messages
   */
  filter.rollover = 0x0;
  filter.filter_mode[0] = 0x3; /* no filter, receive all */
  filter.filter_mode[1] = 0x3; /* no filter, receive all */
  filter.mask_sid[0] = 0x700;
  filter.mask_sid[1] = 0x700;
  filter.mask_eid[0] = 0x3FF00;
  filter.mask_eid[1] = 0x3FF00;
  for (i=0; i<6; i++)
    {
      filter.filter_frame[i] = 0x1;
      filter.filter_sid[i] = 0x600;
      filter.filter_eid[i] = 0x20100 | (i & 0xF);
    }
  ret = ioctl(can_fd, CAN_IOC_FILTER, &filter);
  if (ret < 0) perror("ioctl filter");
 
  /*
   * signal handling for Ctrl-C
   */
  (void) signal (SIGINT, main_cleanup);   // Ctrl-C
  (void) signal (SIGTERM, main_cleanup);  // terminate
 
  /*
   * receive CAN messages and send them back!
   */
  printf("starting CAN message reception (%d), stop with Ctrl-C \n", baudrate);
  while(1)
    {
      ret = read(can_fd, &msg, sizeof(msg));
      if (ret == sizeof(msg))
      {
        print_msg(&msg);
      }
    }
 
  return 0;
}

HALCON

This is an example, that

make.arm-festo-linux2.6

#------------------------------------------------------------------------------
#  system dependent part of the makefile (Linux with gcc-3.4)
#------------------------------------------------------------------------------
#
#------------------------------------------------------------------------------
# Copyright (c) 2007 MVTec Software GmbH, http://www.mvtec.com
#
# To adapt:
#   - The variable HALCONROOT_CROSS
#   - The variable CROSSROOT
#
# HALCONROOT_CROSS: includes and libraries to cross compile 
#                   HALCON applications for the Festo SBO series
# CROSSROOT:        cross environment for the Festo SBO series
#-------------------------------------------------------------------------------
.EXPORT_ALL_VARIABLES:
ifneq ($(HALCONROOT_CROSS),)
ifneq ($(HALCONROOT),)
$(warning Information: Using HALCONROOT_CROSS instead of HALCONROOT)
endif
HALCONROOT           = $(HALCONROOT_CROSS)
endif
 
ifeq ($(HALCONROOT),)
$(error The environment variable HALCONROOT must be set!)
endif
 
CROSSROOT            = /opt/sbo/gcc332
 
#------------------------------------------------------------------------------
#  Machine dependent part of the makefile
#------------------------------------------------------------------------------
#
#
CAMERAROOT     = $(CROSSROOT)/arm-linux
PATH           := $(CROSSROOT)/bin:$(PATH)
X11ROOT        = $(CAMERAROOT)/lib
 
# Compiler
CC              = arm-linux-gcc
CCFLAGS         = -DLINUX -DFAST \
                  -Wall -Wno-strict-aliasing \
                  -pipe -fPIC \
                  -Os -fomit-frame-pointer -msoft-float 
CPP             = arm-linux-g++
CPPFLAGS        = $(CCFLAGS)
 
# Linker
SHLIB_LINKER    = arm-linux-gcc 
SHLIB_EXTENSION = so
STD_LIBS        = -lpthread -lm -lc
 
H_INCLUDE      = $(HALCONROOT)/include
HCPP_INCLUDE   = $(HALCONROOT)/include/cpp
HDEV_INCLUDE   = $(HALCONROOT)/include/hdevengine
H_LIB          = $(HALCONROOT)/lib/$(HALCONARCH)
 
CAM_INCLUDE    = $(CAMERAROOT)/usr/include
CAM_LIBS       = -L$(CAMERAROOT)/lib -lcamera
 
X11_LIBS       = -L$(X11ROOT) -lXext -lX11

makefile

#----------------------------------------------------------------------------
# USAGE:     make [PROG=<filename>]
#
#----------------------------------------------------------------------------
# Copyright (c) 2007 MVTec Software GmbH, http://www.mvtec.com
#
#-------------------------------------------------------------------------------
.EXPORT_ALL_VARIABLES:
 
HALCONARCH   = arm-festo-linux2.6
 
include ../../make.$(HALCONARCH)
 
PROG           = example3
 
all: $(PROG)
 
 
$(PROG): $(PROG).o 
	$(CPP) -o $(PROG) $(PROG).o $(STD_LIBS) \
	-L$(H_LIB) -lhalcon -lhalconcpp $(X11_LIBS)
 
$(PROG).o: $(PROG).cpp 
	$(CPP) $(CPPFLAGS) -I$(H_INCLUDE) -I$(HCPP_INCLUDE) \
	-c -o $(PROG).o $(PROG).cpp
 
 
.PHONY: clean mostlyclean
mostlyclean:
	-rm -f *.o Cache.log
 
clean: mostlyclean
	-rm -f $(PROG)

example3.cpp

/*****************************************************************************
 * example3.cpp
 ***************************************************************************** 
 *
 * Project:      HALCON/C++ for Festo SBO series
 * Description:  Example program for HALCON/C++ for Festo SBO series
 *
 * (c) 2007 by MVTec Software GmbH
 *               www.mvtec.com
 *****************************************************************************
 *   - open framegrabber     
 *   - grab images
 *   - display live images
 *   - program ends by mouse click
 *****************************************************************************
 */
 
#include "HalconCpp.h"
#include "HIOStream.h"
#if !defined(USE_IOSTREAM_H)
using namespace std;
#endif
 
 
int main(int argc, char *argv[])
{
  using namespace Halcon;
  int        Button;
  HDPoint2D  Point;
 
  cout << "--------------------------------------------------" << endl;
  cout << "Example program for HALCON/C++ for Festo SBO series:" << endl;
  cout << "--------------------------------------------------" << endl;
  cout << "- open framegrabber" << endl;
  cout << "- grab images" << endl;
  cout << "- display live images" << endl;
  cout << "- program ends by mouse click" << endl << endl;
 
  close_all_framegrabbers();
 
  HFramegrabber Framegrabber("festo",1,1,640,480); /* open the framegrabber  */
  HImage Image = Framegrabber.GrabImageAsync(-1); /* grab first image       */
 
  HWindow Window;
  if (Image.Width() > 1000)                       /* open window for display*/
    Window.SetWindowExtents(0,0,Image.Width()/2,Image.Height()/2);
  else
    Window.SetWindowExtents(0,0,Image.Width(),Image.Height());
  Window.SetPart(0,0,Image.Height()-1,Image.Width()-1);
 
  Image.Display(Window);
 
  cout << "To quit program: Click with right button into graphics window ..." 
       << endl;
 
  Button = 0;
 
  while (Button != 4)
  {
    Image = Framegrabber.GrabImageAsync(-1);  
    Image.Display(Window); 
 
    Point = Window.GetMposition(&Button);
    switch (Button) {
      case 1: 
        printf("-> Left button pressed!\n");
        break;
      case 2: 
        printf("-> Middle button pressed!\n");
        break;
      case 4: 
        printf("-> Right button pressed!\n");
        break;
    }     
  }                                                  
 
  cout << "The End." << endl;
  return(0);
}

Laser Profiling

This example shows how a laser profile is acquired from the camera. Basically this is done by the following steps:

/*****************************************************************************
 * laser_demo.cpp
 *****************************************************************************
 *
 * Description:  Program demonstrating FPGA-based laser-profile aquisition
 *
 ****************************************************************************/
 
#include <stdio.h>
#include "OCamera.h"
 
/*-----------------------------------------------------------------------------
 *                                                                       main()
 *-----------------------------------------------------------------------------
 */
 
int main(int argc, char *argv[])
{
  OCamera *pCamera;
  OCameraImage img;       /* image containter */
  bool acquisitionError;
 
  unsigned short *pProf;  /* pointer to laser profile */
  float value;            /* single profile value */
 
pCamera = OCamera::CreateCameraInterface(OCamera::CAM_TYPE_MT9V403);
  if (pCamera) {
 
    /* basic camera setup */
    int width = 640;
    int height = 480;
    int x0 = 0;
    int y0 = 0;
    pCamera->Open(width*height*2);
    pCamera->SetCameraWindow(x0,y0,width,height);
    pCamera->SetFrequency(OCamera::FREQU_40MHz);
    pCamera->SetShutterTime(2000);
    pCamera->SetGain(5);
    pCamera->SetIlluminationMode(OCamera::ILL_MODE_OFF);
    pCamera->SetTriggerSource(OCamera::TRIG_SRC_SOFTWARE);
    pCamera->SetTriggerDelay(0);
    pCamera->SetReadTimeout(2000000);
    pCamera->SetAcquisitionMode(OCamera::ACQ_MODE_SINGLE_SHOT); /* take single shots */
 
    /* laser profiling setup */
    int tmin = 100;     /* threshold min */
    int tmax = 255;     /* threshold max */
    int amin = 500;     /* area min      */
    int amax = 5000;    /* area max      */
    OCamera::ePointPriority prio = OCamera::PRIO_FIRST_POINT;     /* line priority     */
    OCamera::eProfileDirection dir = OCamera::DIRECTION_TOP_DOWN; /* profile direction */
 
    pCamera->SetupLaserProfiling(true,x0,y0,width,height,prio,dir,tmin,tmax,amin,amax);
 
    /* trigger camera and transfer a laser profile */
    int ret = pCamera->GetImage(&img); 
 
    if (ret < 0)
      acquisitionError = true;
    else {
      acquisitionError = false;
 
      /* processing the profile data of the acquired image. */
      pProf = (unsigned short *)img.pData;
      for (int i=0;i<width;i++) {
 
        /* the 16 bit output value has a fractional part of four bits,
           therefore we divide by 16 to get the resulting column-value */
        value = (float)(pProf[i])/16;
 
        /* in this example we print all column-values to stdout */
        fprintf(stdout,"value %d:\t %.4f\n",i,value);
      }
      pCamera->ReleaseImage(&img);
    }
 
    /* close camera interface */
    pCamera->SetAcquisitionMode(OCamera::ACQ_MODE_STOP);
    pCamera->Close();
    pCamera->Destroy();
  }
  return 0;
}

Visual Applets Programming

To support Visual Applets on the camera it is required to install the Visual Applets Runtime package on the camera. This package is available via your distributor or directly at Silicon Software. The package contains necessary libraries needed to handle hardware applet files (.hap) that are generated by the Visual Applets IDE.

Acquiring images through FPGA designs produced by Visual Applets several steps have to be performed:

The following example opens a .hap file, activates the FPGA desing and acquires an image through thas design. The resulting image is written to file.

In this example license data is taken from an array of unsigned integers. This is ok. if you use your application on just one camera. A better solution is to strictly split licence storage from application code to manage application and license issues independently. The camera supports license file storage via it's /proc filesystem, e.g. /proc/license/visualapplets. This license file entry is a pseudo file which is mapped to physical flash memory (/dev/mtd9 or config block 2, see flash partition information). Application code may read in licence data from this pseudo file. To help managing licenses see the Camera Info page on each camera which supports license file download.

//
// Visual Applets programming example.
// Activate a .hap-file and take one image.
// 
 
#include <iostream>
#include <sys/ioctl.h>  // ioctl()
#include <unistd.h>     // read(), write()
#include <sys/types.h>  // open()
#include <sys/stat.h>   // open()
#include <fcntl.h>      // open()
 
#include "sisoeneo.h"
#include "hapregs.h"
#include "OCamera.h"
 
int main(int argc, char* argv[])
{
  const va_hap_handle* hap;
  void *board;
  int numParam;
  unsigned long long value;
  int i,id,ret;
  char buf[128];
 
  /* check if applet is given on the command line */
  if (argc != 2)
  {
    std::cout << "usage: " << argv[0] << " <hap-file>" << std::endl;
    return -1;
  }
 
  /* open the register interface to FPGA settings */
  board = OpenReg32();
 
  /* open the hardware applet and initialize parameter interface */
  hap = SisoReadHap(argv[1]);
  if(!hap)
  {
    printf("could not load hap");
    return -1;
  }
  std::cout << "SisoInitParameter: " << SisoInitParameter(hap,board) << std::endl;
 
  /* set license, Unique ID: 000800d89e00 */
  unsigned int Lic[4] = {0x1BD53B18,0x432210EE,0xCC2DE4F4,0x526E492C};
 
  /* enable Visual Applets License */
  std::cout << "SisoEnableLicense: " << SisoEnableLicense(0,Lic) << std::endl;
 
  /* display all parameters stored in the hap */
  numParam = SisoGetNrOfParameter(hap);
  std::cout << "SisoGetNrOfParameter: " << numParam << std::endl;
  for(i=0; i<numParam; ++i)
    {
      strcpy(buf,SisoGetParameterName(hap,i));
      std::cout << "Param " << i << ": " << buf;
      id = SisoGetParameterId(hap,i);
      std::cout << " (id=" << id << ") = ";
      ret = SisoGetParameter(hap,i,&value);
      if (ret == 0) std::cout << value << std::endl;
      else std::cout << "error" << std::endl;
    }
 
  /* initialze camera interface */
  OCamera* pCamera;
  ret = 0;
  pCamera = OCamera::CreateCameraInterface(OCamera::CAM_TYPE_MT9V403);
  ret = pCamera->Open(640*480*4); /* frame buffer = four images */
  ret = pCamera->SetCameraWindow(0, 0, 640, 480 );
  ret = pCamera->SetFrequency( OCamera::FREQU_40MHz );
  ret = pCamera->SetShutterTime( 10000 );
  ret = pCamera->SetGain(2); /* set camera ADC gain */
  ret = pCamera->SetFrameRate(10);
  ret = pCamera->SetIlluminationMode(OCamera::ILL_MODE_OFF);
  ret = pCamera->SetTriggerSource( OCamera::TRIG_SRC_SOFTWARE );
  ret = pCamera->SetReadTimeout( 2000000 );
  ret = pCamera->SetIlluminationModeExternal( OCamera::ILL_MODE_EXT_OFF );
  ret = pCamera->SetHardwareApplet( true, 640 * 480 );
  ret = pCamera->SetAcquisitionMode(OCamera::ACQ_MODE_SINGLE_SHOT); /* take single shots */
 
  /* acquire one image through activated hardware applet */
  OCameraImage img;
  ret = pCamera->GetImage(&img); /* trigger camera and read an image to container */
  std::cout << "ret: " << ret << " size: " << img.nSize << std::endl;
  /* write the acquired image to current directory */
  FILE *fimg = fopen("image.raw","w+");
  if (fimg)
  {
    fwrite(img.pData,img.nSize,1,fimg);
    fclose(fimg);
  }
 
  /* close and cleanup */
  SisoCloseHap(hap);
  CloseReg32(board);
  pCamera->Close();
  pCamera->Destroy();
 
  return 0;
}