Working dsPIC30f4011 code to control servo angle from PC via serial

Here’s a working example of servo angle control from the PC, via serial communication to the dsPIC30F4011.

//
// dsPIC30F4011 serial servo control example
// Written by Ted Burke
// Last updated 18-10-2012
//

#include <xc.h>
#include <stdio.h>
#include <libpic30.h>

// Configuration settings
_FOSC(CSW_FSCM_OFF & FRC_PLL16); // Fosc=16x7.5MHz, Fcy=30MHz
_FWDT(WDT_OFF);                  // Watchdog timer off
_FBORPOR(MCLR_DIS);              // Disable reset pin

int main()
{
	char c;
	int d1, d2, d3, d4, value;
	int error = 0;
	
	// Make all port D pins outputs
	TRISD = 0;

	// These are the PDC1 values for 0 and 180 degrees respectively
	double PDC_min = 550, PDC_max = 1930;
	
	// Configure PWM for free running mode
	PWMCON1 = 0x00FF; // supposedly the default, but seems to need to be set
	PTCONbits.PTCKPS = 3; // prescale=1:64 (0=1:1, 1=1:4, 2=1:16, 3=1:64)
	PTPER = 9375;         // 20ms PWM period
	PDC1 = (PDC_max + PDC_min) / 2;  // Start at 90 degrees
	PDC2 = (PDC_max + PDC_min) / 2;  // Start at 90 degrees
	PDC3 = (PDC_max + PDC_min) / 2;  // Start at 90 degrees
	PTMR = 0;
	PTCONbits.PTEN = 1;   // Enable PWM time base
	
	// Setup UART
	U1BRG = 48;            // 38400 baud @ 30 MIPS
	U1MODEbits.UARTEN = 1; // Enable UART
	
	while(1)
	{
		// Check if any characters were received via UART
		if (U1STAbits.URXDA == 1)
		{
			// Check that first character was 's'
			c = U1RXREG;
			if (c != 's') continue;
			
			// Parse 4 digits
			while (U1STAbits.URXDA == 0);
			c = U1RXREG;
			if (c < '0' || c > '9') continue;
			d1 = c - 48;
			while (U1STAbits.URXDA == 0);
			c = U1RXREG;
			if (c < '0' || c > '9') continue;
			d2 = c - 48;
			while (U1STAbits.URXDA == 0);
			c = U1RXREG;
			if (c < '0' || c > '9') continue;
			d3 = c - 48;
			while (U1STAbits.URXDA == 0);
			c = U1RXREG;
			if (c < '0' || c > '9') continue;
			d4 = c - 48;
			
			// Convert specified value from tenths
			// of a degree into a PDC value
			value = d1*1000 + d2*100 + d3*10 + d4;
			if (value > 1800) value = 1800;
			PDC1 = PDC_min + (value / 1800.0) * (PDC_max - PDC_min);
			printf("Angle: %f\n", value/10.0);
		}
	}
	
	return 0;
}

The servo angle is set using a 5 character long command:

  • The first character is ‘s’.
  • The remaining four characters, which must all be digits (0-9), specify the servo angle in tenths of a degree.
Advertisements
This entry was posted in Uncategorized and tagged , , , , , , , , , , , . Bookmark the permalink.

2 Responses to Working dsPIC30f4011 code to control servo angle from PC via serial

  1. Muralidharan says:

    This program not working for me. I cannot receive any data by serial port

    • batchloaf says:

      In this example, the data is transmitted from the PC to the dsPIC, not the other way around. Do you mean that you aren’t receiving any information via the UART pins of the dsPIC? Have you checked with an oscilloscope or something like that to check that the incoming signal is physically present on the dsPIC RX pin? Are you using a USB-to-serial converter or just the PICkit 2? If you can supply some more details about your set up, I might be able to help you track down the problem.

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