| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| btklister 
 
 
 Joined: 16 Jul 2009
 Posts: 14
 
 
 
			    
 
 | 
			
				| Multi servo controller. |  
				|  Posted: Sat Apr 10, 2010 8:55 am |   |  
				| 
 |  
				| This code reads UART values and generates 50hz pwm, 50 steps for drive servo motors, 6 servos in this case, but you can change as many as you want by adding extra lines. 
 How it works:
 Every 50us an interrupt is generated, so when passed 400 interrupts 400*50us=20ms required for servo. So by adding some counters to interrupt to count the time passed, we can control when IO port is pulled to 0. When the counter reach 400 we do the same again, creating a pwm.
 
 This controller is a uart slave to control it is require send 3 bytes to it:
 
 0xsomething  > to trigger the ready pin (pin_c3)
 +
 0xID           > ID of servo (0x00 to 0x05 in this case)
 +
 0xPOS        > position of servo (0x00 to 0x32, 50 steps)
 
  	  | Code: |  	  | #include <16F688.h>
 #device adc=8
 
 #FUSES NOWDT                    //No Watch Dog Timer
 #FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
 #FUSES NOPROTECT                //Code not protected from reading
 #FUSES NOBROWNOUT               //No brownout reset
 #FUSES MCLR                     //Master Clear pin enabled
 #FUSES NOCPD                    //No EE protection
 #FUSES PUT                      //Power Up Timer
 #FUSES IESO                     //Internal External Switch Over mode enabled
 #FUSES FCMEN                    //Fail-safe clock monitor enabled
 
 #use delay(clock=20000000)
 #use rs232(baud=9600,parity=N,xmit=PIN_C4,rcv=PIN_C5,bits=8)
 
 
 int16 end=0;
 int8 aux=0,c0=25,s0=25,c1=0,s1=25,c2=0,s2=25,c3=0,s3=25,c4=0,s4=25,c5=0,s5=25;
 int8 code[3];
 int1 flag=0;
 void brain();
 void clear();
 void read();
 void config();
 void getcode();
 
 #int_TIMER0             //Interrupt every 50us
 void  TIMER0_isr(void)
 {
 brain(); //turn of the IO in respective time
 }
 
 
 void main()
 {
 setup_adc_ports(NO_ANALOGS|VSS_VDD);
 setup_adc(ADC_OFF);
 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
 setup_timer_1(T1_DISABLED);
 setup_comparator(NC_NC_NC_NC);
 setup_vref(FALSE);
 enable_interrupts(INT_TIMER0);
 enable_interrupts(GLOBAL);
 
 while(1)
 {
 if(kbhit())    //read uart if a char is arived
 getcode();
 read();
 }
 }
 
 void clear()
 {
 //will reset the pulse
 output_high(pin_c2);
 output_high(pin_c1);
 output_high(pin_c0);
 output_high(pin_a2);
 output_high(pin_a1);
 output_high(pin_a0);
 c0=0;c1=0;c2=0;c3=0;c4=0;c5=0;
 end=0;
 }
 
 void brain()
 {
 if(c0==s0)
 output_low(pin_c2);
 if(c1==s1)
 output_low(pin_c1);
 if(c2==s2)
 output_low(pin_c0);
 if(c3==s3)
 output_low(pin_a2);
 if(c4==s4)
 output_low(pin_a1);
 if(c5==s5)
 output_low(pin_a0);
 
 if(end==400)    //400*50us = 20ms (wave periodo required for drive a servo)
 clear();
 
 c0++;
 c1++;
 c2++;
 c3++;
 c4++;
 c5++;
 
 end++;
 }
 
 void read()
 {
 if(flag==1)
 {
 switch (code[0])
 {
 case 0:
 s0=code[1];
 break;
 case 1:
 s1=code[1];
 break;
 case 2:
 s2=code[1];
 break;
 case 3:
 s3=code[1];
 break;
 case 4:
 s4=code[1];
 break;
 case 5:
 s5=code[1];
 break;
 default:
 break;
 }
 flag=0;
 }
 }
 
 void getcode()
 {
 char c;
 c=getc();
 flag=0;
 switch (aux)
 {
 case 0:     //active ready bit with any char received (trash)
 output_high(pin_c3);
 break;
 case 1:
 code[0]=c;  //store in array servo ID (0-5)
 output_low(pin_c3);
 break;
 case 2:
 if(c>=0 && c<=50)   //sote in array servo position
 code[1]=c;
 flag=1;
 break;
 }
 
 aux++;
 if(flag==1)
 aux=0;
 
 //after the 3 char were received we have an array with trash+ID+POSITION
 }
 
 | 
 Cumpz
 Fabio Rico
 |  |  
		|  |  
		| Ali_P 
 
 
 Joined: 18 Oct 2011
 Posts: 7
 Location: Pakistan
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Thu Oct 20, 2011 4:43 am |   |  
				| 
 |  
				| Greetings btklister, 
 Great code ! I wanted to control 4 servos since your program has 6 servo control. It shouldn't be a problem, but when I simulate your code and send command from tx, 2 servos work properly. But if I add command for the 3rd servo, only the 3rd works and the other two doesn't work. Could you explain why? Or what should I do to counter it?
 
 Best Regards
 _________________
 Ali
 |  |  
		|  |  
		| John P 
 
 
 Joined: 17 Sep 2003
 Posts: 331
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri Oct 28, 2011 6:29 am |   |  
				| 
 |  
				| Even if this works, I don't think it's adequate. With a resolution of 50usec, given that a hobby servo has an "official" active range of 1msec, you only have 20 potential stopping positions. I wouldn't accept a driver that has such coarse control of the servo. 
 By "active range" I mean the time interval over which control is possible, i.e. 1msec < T < 2msec. Some servos will accept wider ranges for increased travel.
 |  |  
		|  |  
		| btklister 
 
 
 Joined: 16 Jul 2009
 Posts: 14
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sun Nov 13, 2011 6:31 am |   |  
				| 
 |  
				| Usually simulators don't work properly with fast sitching pins, try to implement in a test board, it works for me. |  |  
		|  |  
		| mbradley 
 
 
 Joined: 11 Jul 2009
 Posts: 118
 Location: California, USA
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Mon Nov 14, 2011 10:50 pm |   |  
				| 
 |  
				| I am not trying to take away from any ones glory, but here is code for a 32, 16, or 8 chanel servo controller, all tested, opensource, CCS compiled, board available, etc.... 
 http://www.mculabs.com/projects/ssx32.html
 _________________
 Michael Bradley
 www.mculabs.com
 Open Drivers and Projects
 |  |  
		|  |  
		| hasimi20 
 
 
 Joined: 04 Sep 2010
 Posts: 19
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sun Mar 24, 2013 9:21 am |   |  
				| 
 |  
				| It works for me! my Q is, how can I increase the servo positioning angle from 0 to 50, to 0 to 100 maybe? |  |  
		|  |  
		|  |  
  
	| 
 
 | You cannot post new topics in this forum You cannot reply to topics in this forum
 You cannot edit your posts in this forum
 You cannot delete your posts in this forum
 You cannot vote in polls in this forum
 
 |  
 Powered by phpBB © 2001, 2005 phpBB Group
 
 |