uSSC doesn't work after reset

I had a hard time coming up with an accurate subject line; here’s my problem:

I have an arduino whose pin 7 I’m using to output with SoftwareSerial at 4800 baud.
SoftwareSerial uses timers and your baudrate to do serial comm in software instead of through the UART.

I have the arduino and uSSC reset lines tied together so that when the arduino resets, the uSSC resets. I’m just trying to do an absolute position command delay, and then do another position, then delay again before looping.

So… I reset the arduino, and on the uSSC, the red light is SOLID, the green light BLINKS. No Servo movement.
Nevertheless, if I unplug the serial line, reset the arduino, and then plug in the serial line, the uSSC works like a champ.

Any ideas? If I use the UART, the uSSC works fine after the reset. So it’s something to do with SW serial initialization.

This is the code (Originally from someone at Pololu, I think)

#include <SoftwareSerial.h>
#define TX_PIN 7
#define RX_PIN 6
#define RST_SSC 3

#define SET_PULSE_WIDTH 0x4




SoftwareSerial s=SoftwareSerial(RX_PIN, TX_PIN);


/* Pololu Protocol: 
 BYTE 0:  HEADER (always 0x80)
 BYTE 1:  Command to send
 BYTE 2:  Target Servo
 BYTE 3:  First data byte
 BYTE 4:  Second date byte. (If necessary)
 
 Data must be sent in LSB. 
 SoftwareSerial::print() does this via: 
 for (mask = 0x01; mask; mask <<= 1) { ... } 
 */


void servo_cmd( uint8_t servo, uint8_t cmd, uint8_t data1, uint8_t data2) 
{ 

  s.print( 0x80, BYTE );
  s.print( 0x01, BYTE);
  s.print( cmd, BYTE ); 
  s.print( servo, BYTE ); 
  s.print( data1, BYTE  ); 
  s.print( data2, BYTE  );

}

void servo_angle( int servo, int angle ) {
  //Convert the angle data into two 7-bit bytes
  unsigned int temp;
  unsigned char pos_hi,pos_low;
  temp=angle&0x1f80;
  pos_hi=temp>>7;
  pos_low=angle & 0x7f;
  
  servo_cmd( servo, SET_PULSE_WIDTH, pos_hi, pos_low );
}


void setup() {

  pinMode(RX_PIN, INPUT);
  pinMode(TX_PIN, OUTPUT);
  s.begin(4800);
  digitalWrite( TX_PIN, HIGH);  //idle state, just to be sure
  


  
  delay(1000); 

} 

void loop() {

  while(1) {


    servo_angle( 0, 2000 );

    digitalWrite(13, HIGH); //blink the LED
    
    delay(500);
    
    servo_angle( 0, 4000 );

    digitalWrite(13, LOW);   

    delay(500);
  }

}

Hello.

I believe I’ve heard that the Arduino’s I/O lines do some strange things while the bootloader is running. If you have an oscilloscope you could take a look at the software serial line as the Arduino resets and the bootloader executes to see what it’s doing. The red LED indicates a fatal serial error, which I’m guessing is caused by garbage on the software serial line.

- Ben

I don’t have the Arduino bootloader running on anything at the moment, but I took a quick look through it’s source code, and it doesn’t seem to be doing anything with Digital Pin 7 (PD7 on the ATMega168). Oddly, I see exactly the same behavior you’re describing when I compile your Arduino code and load it onto a baby Orangutan (also based on the ATMega168), so long as I leave the AVRISP mkII programmer plugged in. The cause is different, but the result is the same, so there’s a chance the same fix will work.

I can avoid this problem by waiting to set the TX_PIN as an output until after the s.begin() function, so that would be worth a try:

void setup(){
	pinMode(RX_PIN, INPUT);
	s.begin(4800);
	pinMode(TX_PIN, OUTPUT);
	delay(1000);
}

At first I thought it might just be that the programmer was physically resetting the AVR in mid-byte, but adding long delays to the beginning of the setup function didn’t make a difference. I’m not really sure what else having the programmer plugged in is doing to screw things up, but I haven’t yet looked at the source of the software serial library, or tried to decompile the Arduino hex code. At some point I’ll get the bootloader running (or just finally pick up a real arduino) and take a look at what’s really going on with an oscilloscope, but until then let us know if this solves your problem. If not you might also try using other free pins as your serial output.

Happy 4’th!

-Adam

Yay, I recompiled the Arduino bootloader to run on a Baby Orangutan, and that same fix (setting the TX pin as an output AFTER the s.begin function) works great for me. The s.begin function must be doing something to the pin that confuses the servo controller, especially while it’s trying to auto-detect the baud-rate.

Does it work for you now?

-Adam

Out of curiosity, did you have to change the bootloader at all to function at 20 MHz, or did you not go so far as to compile an Arduino bootloader that could actually program the Baby Orangutan? The Arduino bootloader is one thing I didn’t really look into when researching how to make the Orangutans compatible with the Arduino environment, mainly because since you already need an external USB-to-serial adapter, why not just use an ISP? Still, it seems like it could be something worth knowing about.

- Ben

I’ve been curious about using the Arduino bootloader on Orangutans for a while, and I wanted to see if my fix really solved the servo controller problem (in case it did have something to do with the bootloader itself). I did recompile the bootloader with the processor clock speed set to 20 MHz in the makefile, and options selected for the Arduino NG, which uses a long bootloader delay (rather than the Diecimila, which uses handshaking lines to reset the AVR and then a short delay). The Arduino compiler has an option to burn the bootloader with a variety of programmers, but to use an AVRISP mkII you need to uninstall the Atmel drivers and configure it to use libUSB, so I ended up just using AVR Studio (and manually setting the various fuses, as defined here).

I flashed it to my Baby Orangutan B-168, then uploaded the servo control program directly from the Arduino environment over a USB to Serial adapter, which worked just great. I was thinking about posting it this morning, or maybe modifying it slightly so that holding one of the Orangutan pushbuttons would keep you in bootloader mode, but then I noticed that the serial software was operating as if it still expected to be running on a 16MHz clock (outputting at 6000bps when it was set to 4800bps, which I didn’t catch at first since my servo controller auto-detected the baud rate just fine). I tried just redefining F_CPU at the beginning of the sketch, but some other definition seems to take precedence. After some digging I found that F_CPU is defined as 16MHz in the makefile in “arduino\hardware\cores\arduino”, and if it isn’t defined already, it’s also defined in “arduino\hardware\cores\wiring\WConstants.h”.

Changing it to 20MHz in the makefile had no effect on the operation of the code, and when I also changed it to 20MHz in WConstants.h, I found I could no longer download the code produced. I’m not sure what’s going on, but by then it was time to go to work and worry about it later. If it’s this much trouble to set up, it sort of negates the simplicity of the Arduino approach.

It also makes me wonder if things like serial baud rates and delays in general run half as fast on the LilyPad Arduino, which uses the internal 8MHz clock.

-Adam

I posted some code here that I THOUGHT worked, but setting the output line high AFTER the s.begin function works.

The SoftwareSerial::begin() sets the serial line high (idle) so maybe that throws off the auto-rate detect.

Once again, Thanks for the help!

-Nate

Hello Nate,
I tried the code out you posted. Sure I changed the lines to:

s.begin(4800);
pinMode(TX_PIN, OUTPUT);

The green LED on the Pololu blinks and it seems to work but the servo connected on the uSSC made no movement.
How had you connected the arduino with the uSSC? I tried your code setting the uSSC in Pololu Mode and the Mini SSC Mode, but nothing worked. Only the blinking LED.
Is there any need to configure the uSSC that it could adress the motor before starting your program? Additional power was adepted by me on the servo row and at the bottom left corner (if the servo row is placed on the right hand side).

Any idea what I could try to get the servo move?
Thanks for your help
Andy

Hello,

In Mini SSC II mode, the servos should all go to their neutral positions after the first byte gets received. You can tell if servos are holding their positions by trying to rotate the output shaft and seeing if the servo resists. If you get that to happen, you might be sending commands to the wrong servo. If you don’t get that to happen, you probably have a problem with your servo or your power setup.

- Jan

Thank you jan,
I’ll try this. But therefore I have to configure a neutral position, mustn’t I ? In Mini SSC-Mode I have to calibrate NO speed, neutral position and so on before the servo goes to it’s neutral position, is this right?

I think that should be easy to test :slight_smile:
Otherwise I will ask again :wink:
Thanks for your help

It works now! Had something todo with the Powersetup I think. After fixing the voltage for the Pololu uSSC and removing the Jumper from J1 it worked and my servo runs from 0 to round about 140°. To add my second uSSC I configured the adressrange by the command 0x80 0x02 0x01 so that I can adress now 16 Servos :slight_smile: great. I haven’t tried it yet but with one uSSC it works great.
Thank you
Greetings !!
Andy

Dear Specialists,
I’ve tried to setup the servo speed with the following telegram:

SoftwareSerial s=SoftwareSerial(RX_PIN, TX_PIN);

s.print( 0x80, BYTE );
s.print( 0x01, BYTE);
s.print( 0x1, BYTE );
s.print( servo, BYTE );
s.print( setspeed, BYTE );

I tried with servo 1 and setspeed=40 :frowning: nothing happend.
Inside the usersguide i’ve read that 0 is default speed so I chose 0 as speed to set.
Now my uSSC doesn’t react at any telegrams.
By the way it reacts but only with the red LED light all the time and the green LED flashing.
What did I do wrong?
I can’t do anything with my uSSC every telegram has the same effect after the yellow status LED extinguishes the red gets on and the green is blinking fast.

Has anybody an idea how to fix my uSSC?
Thanks a lot
Andi

Hello,

Red LED on and green LED flashing means a baud rate detection problem. Does your earlier program that worked still work? If not, what did you change? There isn’t any state saved in the servo controller that would affect this start-up portion of its behavior.

- Jan

Hello Jan,
my earlier program also doesn’t work. No reaction from the uSSC on any command I’m sending. After a time always the same error.
The last thing i changed was to run a initialize-Routine in my programm:
set speed for every servo, and then

servo_angle(servonumber,3000); //for each servo

with this function that worked before

void servo_angle( int servo, int angle ) {
          //Convert the angle data into two 7-bit bytes
       int tmpAngle;
      Serial.println(servo);
      if(servo < 16)
      {
      //Convert the angle data into two 7-bit bytes
      unsigned int temp;
      unsigned char pos_hi,pos_low;
      temp=angle&0x1f80;
      pos_hi=temp>>7;
      pos_low=angle & 0x7f;
      servo_cmd( servo, SET_PULSE_WIDTH, pos_hi, pos_low );
      }
}

doing this had the effect that all servos initialized at the same time.
–> my macbook displayed a message: “Voltage consumption for USB-Device to high,MAC OSX is Disabling Port”

After a reboot of my macbook the USB Port was activated and the communication with my arduino microcontroller works but the communication from the arduino to the Pololu uSSC doesn’t work anymore.

I had a second arduino microcontroller so i tried the second one but the same problem with my uSSC.

Any idea what i could do, or have i to buy 2 new uSSCs ??? :frowning:
perhaps the high amps comsuption by the servos has damaged something on the uSSCs…
Thanks a lot.
Greetz Andy

I think I don’t understand your setup well, but are you trying to power servos through your USB port? That generally wouldn’t be good. If nothing strange happened with the servo controllers, I am concerned that your problem might be with your USB port or your USB adapter. Do you have a different computer you can try (and don’t power any servos through USB!)?

- Jan

Hello Jan,
My setup is like the following:
connected 2 uSSCs to 1 Arduino. The uSSCs get their voltage from the arduino 5V output pin and its GND.
This is power from the USB-Port but I’ve only connected the uSSC voltage to this output, not the servos.
Each uSSC has it’s own power supply to power the servos.
I found the problem. If i initialize all servos at the same time they drive full speed to their startposition and because of that many servos (18) there is much traffic on the Signallines.
I got some jitter or glitches on the signalline. By initializing the servos one by one all servos find their home position. it works.
But one more question:
After setting the speed for each servo:

void servo_speed( uint8_t servo, uint8_t setspeed) 
{
  s.print( 0x80, BYTE );
  s.print( 0x01, BYTE);
  s.print( 0x1, BYTE ); 
  s.print( servo, BYTE ); 
  s.print( setspeed, BYTE  ); 
}

The speed is not accepted by the servo. each servo drives FULLSPEED if adressing it the first time.
The second move is with the selected speed, the set_speed - command was accepted.
What could i make that the servos don’t drive full speed at the first time they get the command?
Is there a dummy_command so that the change of speed is accepted without driving the servo?

Thanks a lot :slight_smile: have a nice weekend