Servo Controller Code Not Working

Hi,

Here is the code I am running from a PIC18F4520 microcontroller. The command is: printf("\xFF\x00\x640"); setting the servo position to 1600us. All that happens is that the red LED is on and the yellow one flashes. Below is the full code. Thanks.

#include <18F4520.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High Power Osc >4MHz
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV20                   //Brownout reset at 2.0V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES PBADEN                   //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#use delay (clock=20000000)


void main(void){
   setup_adc_ports(AN0_TO_AN7|VSS_VDD); 
   setup_adc(ADC_CLOCK_DIV_8|ADC_TAD_MUL_16); 
   setup_psp(PSP_DISABLED); 
   setup_spi(SPI_SS_DISABLED); 
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); 
   setup_timer_1(T1_INTERNAL); 
   setup_timer_2(T2_DIV_BY_16,196,16); 
   setup_comparator(NC_NC_NC_NC); 
   setup_vref(FALSE); 
   enable_interrupts(INT_AD); 
   enable_interrupts(GLOBAL); 
   setup_ccp1(CCP_CAPTURE_RE); 
   setup_ccp2(CCP_CAPTURE_FE); 
   setup_comparator(NC_NC_NC_NC); 
   setup_vref(FALSE); 
   
   
      delay_ms(1000);
      printf("\xFF\x00\x640");
   
}

Hello.

First of all, what product of ours are you using? I’ll assume it’s a Maestro but you should really tell us what specific product you are using so we can better help you.

There is an extra zero at the end of the command you wrote above, which means that you are sending an un-needed fourth byte, which will just be the ASCII encoding of 0 (0x30). That should be OK, but I would fix it. It looks like you are using a CCS compiler; please try using the example code we have here:
pololu.com/docs/0J40/5.h.1

Also, you will need to put your Maestro into the appropriate serial mode (UART, fixed baud rate, 9600).

If it still doesn’t work for you, please post your Maestro configuration file, a detailed description of all the electrical connections you have made, and your code.

–David

I apologize. I’m using the Micro Serial Servo Controller (sparkfun.com/datasheets/Robo … _guide.pdf).

The connections are the ones listed in the datasheet with all grounds mixed and powered by 5V. I am running it in Mini SSC II Mode.

Hi, Pavel.

The hex number 0x640 cannot be represented in a single byte, so it does not make sense to use it with a protocol that only has one byte for the servo position. Does it work when you change your code to something like this:

printf("\xFF\x00\x7D");

- Ryan

Same result - flashing yellow LED and no servo movement.

Did you reset the servo controller before trying that serial command? If the servo controller gets a bad command, it has to be reset before it will accept new, correct commands.

Also, I am somewhat concerned about your power setup that you described to me on the phone. Can you post a picture of your setup, or a schematic of the power connections? Specifically, I am worried that your regulator or batteries might not be able to supply enough current to power the servo. Can you look at the 5V line on your oscilloscope when you send a command?

- Ryan

Hello.

Can you describe your connections? Is your PIC using inverted or non-inverted serial? Do you have the Mini SSC jumper on?

- Ben

I am powering it using 4 AAs and sending it through a LM2940 voltage regulator(national.com/ds/LM/LM2940.pdf). It is a simple power connection directly from the regulator. I can see the 5V line on the oscope. The pic is using non-inverted serial. I have the mini ssc jumper on.

I mean all your connections, not just power. How are you connecting your PIC to the controller? I see some mention of “rs232” in your code, and RS-232 is inverted serial. Can you verify with your scope that it really is non-inverted?

- Ben

Pin 25 is hooked up to the COM pin on the servo board: uncbme.com/uploads/pic_connection.png

Board connections image: uncbme.com/uploads/IMG_20110916_152028.jpg

The serial pin you are using is for RS-232 serial (i.e. inverted) serial connections. If your serial is non-inverted, you should be using the SIN pin (I suspect this is the reason for your problems). If you don’t know for sure if your serial is inverted or not, you can verify it with your scope.

- Ben

I took out the blue short and tried it with the SIN pin, didn’t work. I inverted the signal (#use rs232(baud=9600,parity=N,FORCE_SW, xmit=PIN_C6,rcv=PIN_C7,INVERT,bits=8)) and used it in the rs-232 pin and it also didn’t work. Neither did combinations of the 2.

I think it’s best if you actually figure out what your PIC is doing rather than taking a trial-and-error approach; you might have multiple problems, which could make you think that one of your combinations is wrong when it is actually correct. For example, looking at your picture again, I notice that you aren’t actually supplying your servo with power, so it’s not surprising that it is not moving.

If you want to send a MiniSSC command, you need to have the blue shorting block on, so removing that is definitely not helpful. I suspect you have non-inverted serial, which means you should be making your connection to the SIN pin. Please verify with your scope that this is correct. With these two things fixed, I expect you will stop seeing the red LED solid/flashing yellow LED when you send your command. If that does indeed happen, then you should see your servo move when you power it properly.

- Ben

I didn’t realize that the servo power pins were not connected to the power pins of the board. I added that in and still nothing. The original code sends a non-inverted signal and does not work when connected to the SIN pin. Adding the INVERT command to the rs-232 setup I get an inverted signal which also does not work when connected to the COM pin. :confused:

I do not expect the indicator LEDs to behave the same when you change the serial input connection from the COM pin to the SIN pin. Did the LED pattern change? If so, these are important things to note and relay when troubleshooting! The LEDs give important information about what is going on, but lately all you’ve been telling me is that “things didn’t work”. You have all the tools necessary to figure out what is going on: you can verify with your scope that you are sending the proper bytes at the proper baud rate. The LED behavior you described at the beginning of this thread indicates that the controller is measuring a baud rate that is too low.

Another thing to consider is whether your PIC might be putting some initial noise on the serial line. This could confuse the servo controller into thinking that the noise is the initial command byte, which it would measure as having an invalid baud rate. Can you use your scope to check for any such noise? You can also try to reset the serial controller after the PIC has initialized its serial module.

- Ben

Another interesting thing. When I unhook the serial line and touch it back to the SIN pin, the servo moves. If I keep tapping the pin, the servo moves to the max position CW. If I plug in the servo to a different pin (such as 5), and do the same, it also moves the servo in those short jerks to the max position CW.

The LEDs did not change behavior. The Red is still on and the yellow is still blinking. The green one turns on when the SIN pin is connected. The oscope shows the correct pulse duration. I reset the controller (set the reset low) during each new run so that should take care of the noise issue if one existed.

I think your most immediate goal should be to send a byte without having the LEDs indicate an error. Can you simplify your program down to something that just sends the first byte of the MiniSSC protocol: 0xFF? For example, you could have the program initialize the UART, delay for 5 seconds (during which time you or the PIC should reset the servo controller), and then send a single byte. Also, I’m not sure what the current state of your code is, but make sure you have reverted back to using non-inverted serial.

If you see the LEDs indicate an error as soon as you transmit that first byte, we can take a closer look at what the controller’s serial line is seeing. Can you capture this byte on your oscilloscope and post a picture/screenshot of the capture (hopefully one that is clear enough for me to tell what each of the bits are and what the time scale is so I can verify the baud rate)?

- Ben

Hi. So I got the other problem fixed. The resistor value was off by a few ohms in the 20MHz oscillator connection, which made the baud rate off from 9600 as you correctly predicted. My current issue is with the controller flashing the red led and having the yellow led on. The way this usually happens:
-Turn on system, everything is working fine, green LED is on and the servos are moving
-Randomly the controller stops and the red LED flashes. I turn the power off, then back on and it usually corrects the problem.

I am controlling the position using a potentiometer, which alters a voltage that I read in through the micocontroller and then output a position value to the servo as a function of that. What would be a possible reason for the flashing red led? Would it do that if a value of >256 was set as the position? Any other reasons?

Thanks