DPRG
DPRG List  



[DPRG] PIC Dual DC Motor HBridge controller

Subject: [DPRG] PIC Dual DC Motor HBridge controller
From: ellis76016 ellis76016 at tx.rr.com
Date: Sun Jan 14 22:03:16 CST 2007

Vimal,
Yes you can. Attached is a C program that does just that. Warning very non
commented code, sorry.
The main thing you are looking for is:

Set up
	// set up PWM
	// bank 1 set by compiler
	PR2 = 0xFF; 
	CCPR1L = 0; // bank 0
	CCPR2L = 0;
	T2CON = 0b.0011.1100;
	TMR2IF = 0;
	// bank 1
	TMR2IE = 1;
	// bank 0
	PEIE = 1;
	GIE = 1;
	CCP1CON = 0b.0000.1100;
	CCP2CON = 0b.0000.1100;


Changes motor speed, pwm duty cycles, in main loop.
	CCPR1L = pwmR; // bank 0
	CCPR2L = pwmL;

Hope this helps,
David Ellis

-----Original Message-----
From: dprglist-bounces at dprg.org [mailto:dprglist-bounces at dprg.org] On Behalf
Of Vimal Shankar
Sent: Saturday, January 13, 2007 8:19 PM
To: dprglist at dprg.org
Subject: [DPRG] PIC Dual DC Motor HBridge controller

Guys

Did a lot of homework and got incremental and HBridge
controller working for my DC Geared motor control
system.

Now I am finding reason to focus on the firmware, but
am really confused if I can get the
PIC16F877A/PIC18F4550 to output 2 PWM at SAME
frequency (the freq at which the HBridge is driven)
but at 2 different duty cycles (to control the RPM of
the two motors)...

Is is possible to have two different duty cycles of
the same freq from two different pins of a PIC.

I am obviously asking about hardware PWM as a software
solution would tie up the PIC too much AFAIC...

Do get back.

Vimal 


 
____________________________________________________________________________
________
Never miss an email again!
Yahoo! Toolbar alerts you the instant new Mail arrives.
http://tools.search.yahoo.com/toolbar/features/mail/
_______________________________________________
DPRGlist mailing list
DPRGlist at dprg.org
http://list.dprg.org/mailman/listinfo/dprglist
-------------- next part --------------
/*
PWM06.C 2006-05-15
David Ellis
http://home.comcast.net/~ellis76016/robots/
*/

#include "int16CXX.H"

#define LF 10
#define CR 13
#define SP 32

#define Kprop 256 // 1 * 256


#pragma chip PIC16F877

#pragma resetVector 0x0003

bit pin_b5 @ PORTB.5; //J1 Pin 10 = B5, right motor shaft encoder
bit pin_b6 @ PORTB.6; //J1 Pin  8 = B6, left motor shaft encoder
bit pin_d0 @ PORTD.0; //J1 Pin 40 = D0, CMD I1
bit pin_d1 @ PORTD.1; //J1 Pin 38 = D1, CMD I2
bit pin_d2 @ PORTD.2; //J1 Pin 36 = D2, CMD I3
bit pin_d3 @ PORTD.3; //J1 Pin 34 = D3, CMD I4

bit stateR; // state holder for right motor shaft encoder
bit stateL; // state holder for left motor shaft encoder
uns8 RightCount, LeftCount;
uns8 Ticks;
uns8 LeftInterval, RightInterval;

void putc( char ch );
void simplehex( char val );

interrupt int_server(void) {
	int_save_registers // W, STATUS, and PCLATH
	
	// shaft encoder interupt
	if (RBIF) {
		if (stateR != pin_b5) {
			stateR = pin_b5;
			RightCount++;
		}
		if (stateL != pin_b6) {
			stateL = pin_b6;
			LeftCount++;
		}
		RBIF = 0;
	}

	// isr for PWM postscalar interupt
	if (TMR2IF) {
		// 1 tick = 8 * 19.53 Khz or 409.6us
		Ticks++;
		if (Ticks == 100) {
			LeftInterval = LeftCount;
			LeftCount = 0;
			RightInterval = RightCount;
			RightCount = 0;
			Ticks = 0;
		}
		TMR2IF = 0; /* reset flag */ 	
	}
	int_restore_registers // W, STATUS, and PCLATH
}

void putc( char ch ) {
	// Wait for space in the TX buffer
	while ( TXIF == 0 ) ;
	TXREG = ch;
}

// transmits char/byte data as two hex characters, 0 = "00", 255 = "FF"
void SimpleHex( char val ) {
	char nibble;
	char ch;
	nibble = val >> 4;
	if (nibble < 10) 
		ch = nibble + '0';
	else {		
		ch  = 'a' + nibble;
		ch = ch - 10;
	}
	putc(ch);	

	nibble = val & 0x0F;
	if (nibble < 10) 
		ch = nibble + '0';
	else {		
		ch  = 'a' + nibble;
		ch = ch - 10;
	}
	putc(ch);	
}

void main(void) {
	PORTB = 0b.0000.0000;
	TRISB = 0b.1111.1111;
	
	// J1 Pin 27 = C1/CCP2, PWM to CMD, E1-2
	// J1 Pin 29 = C2/CCP1, PWM to CMD, E3-4
	PORTC = 0b.0000.0000;
	TRISC = 0b.1111.1001;

	PORTD = 0b.0000.0000;
	TRISD = 0b.1111.0000;

	Ticks = 0;
	uns8 x , y;
	uns8 tempL, tempR;

	uns8 pwmL, pwmR;
	uns8 setpointL, setpointR;
	int16 errorL, errorR;
	int16 cvL, cvR;

	pwmL = 0;
	pwmR = 0;

	// set up PWM
	// bank 1 set by compiler
	PR2 = 0xFF; 
	CCPR1L = 0; // bank 0
	CCPR2L = 0;
	T2CON = 0b.0011.1100;
	TMR2IF = 0;
	// bank 1
	TMR2IE = 1;
	// bank 0
	PEIE = 1;
	GIE = 1;
	CCP1CON = 0b.0000.1100;
	CCP2CON = 0b.0000.1100;


	// set Sorbotics Compact Motor Driver CMD directions 
	pin_d0 = 1;
	pin_d1 = 0;
	pin_d2 = 0;
	pin_d3 = 1;

	setpointL = 32;
	setpointR = 32;

	while ( 1 ) { // loop forever

		// print duty cycle, left count, right count
		tempL = LeftInterval;
		tempR = RightInterval;
		SimpleHex (pwmL);
		putc(SP);
		SimpleHex (tempL);
		putc(SP);
		SimpleHex (pwmR);
		putc(SP);
		SimpleHex (tempR);
		putc(SP);
		putc(CR);
		putc(LF);

		// set pwm
		errorL = (int16)setpointL - (int16)tempL;
		errorR = (int16)setpointR - (int16)tempR;
		cvL = errorL * Kprop;
		cvR = errorR * Kprop;
		pwmL = pwmL + cvL.high8;
		pwmR = pwmR + cvR.high8;
		CCPR1L = pwmR; // bank 0
		CCPR2L = pwmL;

		/* 
		delay
		y = 0;
		while (--y > 0) {
			x = 0;
			while (--x > 0) {
				nop();
			}
		}
		*/
	}
}

More information about the DPRG mailing list

Copyright © 1984 - 2006 Dallas Personal Robotics Group. All rights reserved.
Website Design by NCC

For the latest robot news visit robots.net