Using CTS module with AVR/Arduino

The bellow code was implemented using AVR IDE (Eclipse) but should work with no changes on AVRStudio and with minimal changes (will test it and update it accordingly) on Arduino IDE.

 

I used for this application the bellow setup (see picture above):

  • OV7670 FIFO module;
  • CTS v0.4 board;
  • SparkFun’s Serial Controlled Dual Motor Driver (available here). It comes with a L298P dual motor driver with up to 2Amps per channel;
  • 2WD miniQ robot chassis from DFRobot (available here), however, any 2WD or 4WD will work just fine;
  • small Li-Poli battery from eBay.

Once connected the 2 motors and CTS v0.4 module to SparkFun’s board, I got this:

 

Added following code, that will handle the “panning” movement:

#include 
#include 
#include 
#include "main.h"
#include "uart.h"
#include "motorc.h"
#include "delay.h"

// CTS module ranges for pannin
#define WIDTH       128
#define HEIGHT      120

// set max speed
#define MAXSPEED    127
#define COEF	    4

unsigned int i;
unsigned char c;
unsigned char buf[8];
unsigned int cogX;
unsigned int cogY;
unsigned int weight;
unsigned int direction;
unsigned int pdir;
int pspeed;

// define "dead spot" around centre of the image
unsigned int  cDeadBand = 5;

volatile uint8_t counter;

// init timer (INT2)
void timer2_init(){
	OCR2A = 248;
	TCCR2A |= (1 << WGM21);
	TIMSK2 |= (1 << OCIE2A);
	TCCR2B |= ((1<<CS22)|(1<<CS21)|(1<<CS20));
}

ISR(TIMER2_COMPA_vect){
                                        // every counter * 10 ms will trigger an action
    if (counter++ == 5) {		// multiple of 10 ms
      counter = 0;

      // check direction
      if (pdir == 1){
          // turn left, reduce the speed by COEF
    	  panLeft (pspeed/COEF);
      } else if (pdir == 2){
          // turn right, reduce the speed by COEF
    	  panRight (pspeed/COEF);
      } else {
    	  panStop();
      }
    }
}

int main (void){
    //Initialize AVR I/O, UART and Interrupts
    timer2_init();
    sinit(115200);
    ioinit();

    // stop motors
    setDirection(1, 1);
    setSpeed(0, 0);

    // enable interrupt
    sei();

    // init PAN variables
    cogX   = 0;
    cogY   = 0;
    weight = 0;
    pdir   = 0;
    pspeed = 0;

    // loop
    while(1){

        // check serial port
        if (savailable()){

            // check if is package from CTS module (starting 0x42 0x00)  
            c = sgetc();
            if (c == 0x42){
                c = sgetc();
                if (c == 0x00){
                    i = 0;

                    // then receive following 3 bytes
                    for(i = 0; i < 3; i++){
                        buf[i] = sgetc();
                    }
                    cogX = buf[0];
                    cogY = buf[1];
                    weight = buf[2];
                }

                // calculate pan movement
                int midX = WIDTH / 2;
                unsigned int horizFactor = (int)(MAXSPEED/midX);

               if ((cogX > 0) && (cogX <= midX - cDeadBand)){
                    pspeed = ((midX-cogX)*horizFactor);
                    pdir = 1;
                } else if (cogX >= midX + cDeadBand){
                    pspeed = ((cogX-midX)*horizFactor);
                    pdir = 2;
                } else {
                    pspeed = 0;
                    pdir = 1;
                }

                // limit speed to maximum defined
                if (pspeed > MAXSPEED){
                    pspeed = MAXSPEED;
                }
            } else {

                cogX   = 0;
                cogY   = 0;
                weight = 0;
            }
        }
    }
    return 0;
}

 
As a short explanation:

  • Defined a timer using INT2 to be triggered every 50 ms and send speed/direction information to both motors (this will become handy later if you want your “robot” to do more then just panning);
  • Handle serial communication with CTS module (CTS module running in a loop);
  • Implement a very simple algorithm to change the speed direct proportional with the distance from the centre of the image.
NOTE: Code handling the motors is pretty much same with the one provided by SparkFun and is not included. Also, serial communication is using basic serial code as provided by Atmel

 

Advertisements

3 thoughts on “Using CTS module with AVR/Arduino

  1. Hi i wanted to know if is posible to use the Ov7670 camera for face tracking (human faces), thanks for all.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s