Jump to content

Recommended Posts

Hello,

 

I am using a PIC16F684 to control two servomotors and a variable dc motor. I am having trouble outputting the AD values from my accelerometer and interfacing the servomotors. Some of the problems that I have encountered are as follows: I will be using two servomotors but there is only one PWM modulated output from the PR1 register. The two servomotors will need to operate separately based on the accelerometer readings. The variable dc motor will control the speed of the airplane. This means that a square wave signal with a varying frquency will need to be output to increase and decrease motor functionality. Can anyone suggest how to output my AD values from the accelerometer, how to implement two separate PWM signals on the output ports to control the servomotors, and how to implement a a square wave with a varying frequency?

 

 

Thx.

Link to post
Share on other sites
Hello,

 

I am using a PIC16F684 to control two servomotors and a variable dc motor. I am having trouble outputting the AD values from my accelerometer and interfacing the servomotors. Some of the problems that I have encountered are as follows: I will be using two servomotors but there is only one PWM modulated output from the PR1 register. The two servomotors will need to operate separately based on the accelerometer readings. The variable dc motor will control the speed of the airplane. This means that a square wave signal with a varying frquency will need to be output to increase and decrease motor functionality. Can anyone suggest how to output my AD values from the accelerometer, how to implement two separate PWM signals on the output ports to control the servomotors, and how to implement a a square wave with a varying frequency?

 

 

Thx.

 

This sounds like fun.

 

How come you're using a one channel PWM device if you need more channels?

 

Anyway, Mike Predko (PIC book author) implements a bit bang PWM, Microchip has application notes on motor control (Zilog too). Perhaps you could use one HW PWM, and one in SW.

 

I've seen articles on using the accelerometers with MCU - check Microchip, google, and Steve Ciarcia's contest respondents

Link to post
Share on other sites

PWM on the PIC is usually not good for servos since they always opperate at such low duty cycles and the pic cannot resolve fine control at this duty cycle. I would implement a 1 meg hz interrupt ( using the timer ) and have interrupt software generate the pulses. This will give you 1 us control over a 1 ms signal. I have done this for a single channel, should be able to extend it to more ( but not me, now now ). Motor control for RC can be done with the same servo type pulses using an esc. Do not know why you need to output the AD values from the accelerometer. What are you going to output them too.

 

This guy/page http://embeddedadventures.blogspot.com/200...example-im.html seems to have done a lot of the stuff for the pic, may be of use. He also posts on this forum.

 

russ_hensel

 

 

 

 

Hello,

 

I am using a PIC16F684 to control two servomotors and a variable dc motor. I am having trouble outputting the AD values from my accelerometer and interfacing the servomotors. Some of the problems that I have encountered are as follows: I will be using two servomotors but there is only one PWM modulated output from the PR1 register. The two servomotors will need to operate separately based on the accelerometer readings. The variable dc motor will control the speed of the airplane. This means that a square wave signal with a varying frquency will need to be output to increase and decrease motor functionality. Can anyone suggest how to output my AD values from the accelerometer, how to implement two separate PWM signals on the output ports to control the servomotors, and how to implement a a square wave with a varying frequency?

 

 

Thx.

Link to post
Share on other sites

Hi. If you are using normal servos then they will be expecting a pulse of between 1 and 2ms every 20ms. I'd guess your two controls are aileron (or rudder) and elevator. They don't need to be operated exactly together so you can simply make servo1 go high for between 1 and 2ms then low, then do the same for servo2. Then wait about 17ms and start again. The 1-2ms is important but the 20ms timing is not. You might be able to do this with delays, or otherwise just wait for a 16bit timer to reach appropriate values before making ports high/low.

 

If your motor control is via a commercial electronic speed control it will be expecting the same signal. So you can simply tag this on after servo1 and 2 and reduce the delay before starting the next cycle. This 'sequential' approach will work with up to 10 devices.

 

Clearly you will need a whole bunch of logic to convert pitch and roll movements picked up by your accelerometers into servo instructions.

Regards, David.

Link to post
Share on other sites

The easiest way to do this is with the special events trigger of the CCP module.

 

Here is some example code that controls 2 servos. In main just write the position of the servos (1000 to 2000) to Servo1Pos and Servo2Pos and the interrupt will do the rest.

 

This routine can easily be extended to drive upto 8 servos with uS accuracy.

 

#include <system.h>
#include <boostc.h>

#pragma DATA _CONFIG, _CP_OFF & _CCP1_RB0 & _DEBUG_ON 
	& _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF 
	& _MCLR_ON & _PWRTE_OFF & _WDT_OFF & _INTRC_IO

int Servo1Pos,Servo2Pos;
char state;

void interrupt(void) {
int Time;
switch (state++)
{
	case 0:
	case 5:
		portb.1=1;
		Time=Servo1Pos;
		state=1;   
		break;
	case 1:
		portb.1=0;
		Time=2500-Servo1Pos;   
		break;
	case 2:
		portb.2=1;
		Time=Servo2Pos;   
		break;
	case 3:
		portb.2=0;
		Time=2500-Servo2Pos;   
		break;
	case 4:
		Time=15000;   
		break;
	default:
}
ccpr1l=Time&255;
ccpr1h=Time/256; 
pir1.CCP1IF=0;			  //clear CCP1 interrupt
}

void main(void){
osccon=0x60;				//4meg
cmcon=7;
ansel=0;
trisb=0b11111001;
ccp1con=0b00001011;		 //Special event trigger
t1con=0b10000001;		   //Timer 1 on with Pre=1
Servo1Pos=1500;			 //set first servo to mid position
Servo2Pos=2000;			 //and second servo fully right
pie1.CCP1IE=1;			  //enable CCP1 interrupt
intcon.PEIE=1;			  //enable peripheral interrupts
intcon.GIE=1;			   //enable glogal interrupts
while(1){
}
}

 

The above is for a 16f88 but should work on most 16 series chips.

 

Mike.

Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...