Baby-O 168 and Micro Serial Servo Controller problem

Hello All,

I am newbie trying to learn some basic microcontroller programming. I am trying to control a servo (Tower PRO SG-50) using MSSC in Mini SSCII mode. Both MSSC and Baby-O are powered by a voltage regulator connected to a wall-wart. Here’s the code running on my Baby-O (I am using AVRLib for serial IO):

#include <avr/io.h>		// include I/O definitions (port names, pin names, etc)
#include <avr/interrupt.h>	// include interrupt support

#include "global.h"		// include our global settings
#include "timer.h"
#include "buffer.h"
#include "uart.h"

#define START_POS 	20
#define END_POS		200

void MoveServo(u08 Pos)
{
	uartSendByte(0xFF);
	uartSendByte(0x08);
	uartSendByte(Pos);
}

int main(void)
{
	uartInit();
	uartSetBaudRate(9600);
	
	u08 Pos = START_POS;
	double Ctr;

	while(1)
	{
		MoveServo(Pos);
		Pos += 10;
		if ( Pos > END_POS )
		{
			Pos = START_POS;
		}
		Ctr = 20000.0;
		while(Ctr-- > 0.0);
	}
}

Running this code causes the servo to move to some random location and then it does not move any further. I was expecting the servo to move from one end to another in small steps. The green LED blinks on the controller as expected. A video showing the outcome can be found at http://www.youtube.com/watch?v=6mabttoQRqE

To debug, I connected the RX/TX from Baby-O to Pololu USB AVR Programmer in USB-Serial adapter mode (in addition to the signal pin on MSSC) and was able to verify that the commands sent to the MSSC matched the documentation (255 - 8 - Pos - where Pos value changed from START_POS to END_POS). This confirms that the Baby-O is indeed sending the correct data to the MSSC.

Also, I wrote a small C# program to control the MSSC from Windows. This program was able to control the MSSC and the same servo worked fine. Here’s the windows code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;

namespace TestServoControllerCommands
{
    class Program
    {
        private static SerialPort _com4 = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
        private static int _ServoNumber = 0;
        static void Main(string[] args)
        {
            _com4.DataReceived += new SerialDataReceivedEventHandler(_com4_DataReceived);
            Console.WriteLine("Hit ENTER to open the serial port on COM4");
            string cmd = Console.ReadLine();
            _com4.Open();
            if (cmd.ToLower().CompareTo("control") == 0)
            {
                ControlServo();
            }
            else
            {
            }
            Console.ReadLine();
            Console.WriteLine("Closing COM4 serial port");
            _com4.DiscardInBuffer();
            _com4.DiscardOutBuffer();
            _com4.Close();
        }

        private static void ControlServo()
        {
            string pos = Console.ReadLine();
            int nPos = 0;
            while (pos.ToLower().CompareTo("end") != 0)
            {
                if (Int32.TryParse(pos, out nPos))
                {
                    if (nPos >= 0 && nPos < 255)
                    {
                        MoveServo(nPos);
                    }
                }
                pos = Console.ReadLine();
            }
        }

        private static void MoveServo(int nPos)
        {
            byte[] data = new byte[] { 0xFF, 0x08, Convert.ToByte(nPos) };
            _com4.Write(data, 0, 3);
        }

        static void _com4_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            while (_com4.IsOpen && (_com4.BytesToRead > 0))
            {
                Console.WriteLine(_com4.ReadByte());
            }
        }
    }
}

The C# program confirmed that the MSSC and the servo are functional. The video showing this can be found at http://www.youtube.com/watch?v=lk0UTldk9Oc

At this point I have run out of ideas to debug the problem further. Any help would be appreciated…

Thanks
-VK

Forgot to mention that even the servo was powered from the same regulated 5V from the wall-wart. Also tried changing the servo power supply to 5.2V battery.

Hello,

It looks like you’re generally doing the right thing. The one thing I can think of is your ground connections: are the servo controller and Orangutan grounds connected? Can you post a higher-resolution picture of your setup?

- Jan

Hello VK,

I noticed that you are delaying by decrementing a double. I don’t think your compiler is optimizing this away, but in general you want to be able to turn optimizations on and this is the kind of thing that can get optimized away. A better way to delay would be to use the _delay_ms function part of util/delay.h. The _delay_ms function can only delay for a maximum of 13 milliseconds at 20MHz. If you want to delay for more than that, put it in a loop that calls it multiple times.

- Ryan