Using a BX-24 to control a servomotor

Tom's Main Menu

Physical Computing Home

Intro to Physical Computing Syllabus

Networked Objects

Sustainable Practices

blog

Resources

code, circuits, & construction

my del.icio.us links

 

To control a servo, supply power and ground to the servo, then supply a series of pulses to the control wire of the servo to tell it what angle to set the motor at. Using the BX-24, you can do this using the PULSEOUT command.

You have to pulse the servo once every 20 milliseconds, even if you're not moving it. The pulse has to be between one and two milliseconds long, depending on the angle. For example, if you wanted to make the servo stay still at 90 degrees, you'd pulse it for 1.5 ms every 20 ms.

This example pulses the servo to its minimum position, waits two seconds, pulses it to the middle, waits two seconds, pulses it to the maximum position, and starts over.

In practice, different servos have slightly different pulsewidth requirements. You may have to modify the minPulse and maxPulse easily to find what works for your servo.

 ' Servo testing example
'	in this example, a servo attached to pin 12 
'	should travel slowly from one side to the other, 
'	then quickly back to the beginning. 
'	The program starts pulsing the servo at its 
'	minimum pulsewidth, then increments the pulsewidth 
'	a small amount with each new pulse until it reaches 
'	the maximum pulsewidth.  Then it sets the 
'	pulsewidth back to minimum. 

dim minPulse as single	     ' the minimum pulseWidth
dim maxPulse as single	     ' the maximum pulseWidth
dim pulseWidth as single	   ' the servo's pulsewidth
dim refreshPeriod as single ' the time between pulses

Sub main()
	call delay(0.5)  ' start  program with a half-second delay 

	' set initial values for variables:

	' you may need to change the minimum and maximum 
	' pulseWidths for your servo to get the full 
	' range of motion.  The ideal servo
	' has a minimum of 1 milliseconds (0.001) and 
	' an maximum of 2 milliseconds (0.002). In practice, 
	' however, this varies. Connect your servo and try 
	' different values for the max and min below:

	minPulse = 0.0008
	maxPulse = 0.0022
	pulseWidth = minPulse
	refreshPeriod = 0.02

	' the main loop:
	  do
		
	   	' pulse the servo:
	   	call pulseOut(12, pulseWidth, 1)

		   ' increase the pulsewidth for the next pulse:
	   	if pulseWidth <= maxPulse then
	      		pulseWidth = pulseWidth + 0.00001
	   	else
		      	pulseWidth = minPulse
   		end if

	   	' wait 20 milliseconds before pulsing again
	   	call sleep(refreshPeriod)
  	loop
End Sub
 
This next example also uses the BX-24's multitasking capabilities. For more on that, see the multitasking notes. Don't use this example if you're confused about the basics of BX-24 BASIC. If you're comfortable with the environment, however, this example can simplify the process of keeping correct timing on the servo while doing other things.
	' Servo testing example


const servoPin as byte = 12				' the pin the servo is on
const refreshPeriod as single = 0.02	' the time between servo pulses


	' you may need to change the minimum and maximum pulseWidths for
	' your servo to get the full range of motion.  The ideal servo
	' has a minimum of 1 milliseconds (0.001) and a maximum of 
	' 2 milliseconds (0.002). In practice, however, this varies.
	' connect your servo and try different values for the constants
	' below:


const minPulse as single = 0.0003		' the minimum pulseWidth
const maxPulse as single = 0.0022		' the maximum pulseWidth

dim pulseWidth as single				' the servo's pulsewidth


dim servoStack(1 to 30) as byte			' memory for the servoTask


Sub main()
	call delay(0.5)  ' start  program with a half-second delay 

	debug.print "start"

	' set initial values for variables:
	pulseWidth = minPulse
	
	' start the servoTask loop running:
	callTask "servoTask", servoStack
	
	' the main loop:
	do
		pulsewidth = minPulse
		debug.print "minimum angle"
		call sleep(2.0)

		pulseWidth = ((maxPulse - minPulse) / 2.0) + minPulse
		debug.print "middle"
		call sleep(2.0)

		pulseWidth = maxPulse
		debug.print "maximum angle"
		call sleep(2.0)

		' this sleep makes sure your main loop runs 
		' as much as possible.
		call sleep(0.0)
	loop
End Sub

sub servoTask()
	do
		call pulseOut(servoPin, pulseWidth, 1)

		' wait 20 milliseconds before pulsing again
		call sleep(refreshPeriod)
	loop
end sub