Hard time with SSC 32 and C++

Hi everybody!

I am trying to communicate with the SSC-32 under Linux (Ubuntu 10.04) and C++. I am having a hard time with it, and I would deeply appreciate if anyone could give me any hint.

The thing is, if I use minicom with the following configuration I can send commands to the SSC 32 without problems (for example: #4P1000 would move the servo on channel 4 to position 1000 perfectly):
Serial Device: /dev/ttyS0
Bps/Par/Bits : 115200 8N1
Hardware Flow Control : No
Software Flow Control : No

But when I use my own program, it doesn’t work. Here is the source code:

[code]SerialPort.h:

#ifndef SerialPort_h
#define SerialPort_h

#include
class SerialPort
{

private:
std::string mSerialPortName ;

int mFileDescriptor ;

public:

enum BufferSize {
	BUFFER_SIZE = 64 
} ;

SerialPort ( ) ;

bool Open( const std::string& mSerialPortName ) ;

bool Close (  ) ;

bool Write ( const char *writeBuffer, int bufferSize ) ;

int Read ( unsigned char *readBuffer ) ;

} ;

#endif

SerialPort.cpp:

#include
#include
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

#include “SerialPort.h”

SerialPort::SerialPort ( )
{
mFileDescriptor = -1;
}

bool SerialPort::Open( const std::string& mSerialPortName )
{
struct termios ios;

if (mFileDescriptor != -1)
{
	std::cerr << "WARNING: There is one serial port already open. Close it first." << std::endl; 
}

this->mSerialPortName = mSerialPortName; 
std::cout << "Opening: " << this->mSerialPortName << std::endl;

if ((mFileDescriptor = open (this->mSerialPortName.c_str(), O_RDWR | O_NOCTTY )) < 0)
{
	std::cerr << "ERROR: Could not open " << this->mSerialPortName << std::endl;
	return false;
}

if (!isatty(mFileDescriptor))
{
	std::cerr << "ERROR: "<< this->mSerialPortName << " is not a tty." << std::endl;
	Close();
	return false;
}

if ( tcgetattr(mFileDescriptor, &ios) != 0 )
{
	std::cerr << "ERROR: Could not get serial port parameters"<< std::endl;
}

//Set communication speed
cfsetispeed(&ios, B115200);
cfsetospeed(&ios, B115200);

//Set 8 data bits
ios.c_cflag = (ios.c_cflag & ~CSIZE) | CS8;

//Set into raw, no echo mode 
ios.c_iflag = IGNBRK;
ios.c_lflag = 0;
ios.c_oflag = 0;
ios.c_cflag |= CLOCAL | CREAD;


//Disable software flow control
ios.c_iflag &= ~(IXON|IXOFF|IXANY);

//Disable hardware flow control
ios.c_cflag &= ~CRTSCTS;

//Disable parity
ios.c_cflag &= ~(PARENB | PARODD);

//One stop bit
ios.c_cflag &= ~CSTOPB;


if (tcsetattr(mFileDescriptor, TCSANOW, &ios) == -1)
{
	std::cerr << "ERROR: Problem with tcsetattr" << std::endl;
	return false;
}


return true;

}

bool SerialPort::Close ( )
{
std::cerr<< "File descriptor: " << mFileDescriptor << std::endl;

if (mFileDescriptor == -1)
{
	std::cerr << "WARNING: The serial port is not open." << std::endl; 
	return false;
}

if (close(mFileDescriptor)==0)
{
	mFileDescriptor = -1;
	return true;
}
else
{
	perror("ERROR: ");
	std::cerr << "ERROR: Problem closing serial port." << std::endl;
	mFileDescriptor = -1;
	return false;
}

}

bool SerialPort::Write ( const char *writeBuffer, int bufferSize )
{
int s;

if (mFileDescriptor == -1)
{
	std::cerr << "ERROR: Serial port not open." << std::endl;
	return false;
}

s = write(mFileDescriptor, writeBuffer, bufferSize );

if (tcflush(mFileDescriptor, TCIOFLUSH) == -1)
	std::cerr << "WARNING: Could not flush serial port" << std::endl;

if (s!=bufferSize)
{
	std::cerr << "ERROR: Could not write to serial port" << std::endl;
	return false;
}
std::cerr << writeBuffer << std::endl;
std::cerr << "Wrote bytes: " << s << std::endl;

return true;

}

main.c:

#include “SerialPort.h”
#include

int main( int argc, const char **argv)
{

unsigned char buff[SerialPort::BUFFER_SIZE];
SerialPort mySerial;
std::cout << "Created an object of type SerialPort" << std::endl;


if (mySerial.Open("/dev/ttyS0"))
{
	std::cout << "The serial port is open." << std::endl;
}


if (mySerial.Write("#0P1000\r",8))
{
	std::cout << "The servo should move now" << std::endl;
}
else
{
	std::cout << "Oh crap..." << std::endl;
}	


sleep(2);

if (mySerial.Close( ))
{
	std::cout << "Serial port successfully closed." << std::endl;
}

}[/code]

When I execute the main program, I get no errors:
$ ./main
Created an object of type SerialPort
Opening: /dev/ttyS0
The serial port is open.
#0P1000
Wrote bytes: 8
The servo should move now
File descriptor: 3
Serial port successfully closed.

But it looks like the command doesn’t reach the SSC-32 (the green led is always ON). I guess it must be an error in my configuration flags or something like that. Any ideas? I really don’t know what else to do, I’ve surfed the web, ripped out the source code of minicom but yet… no results. You are my last hope :cry:

Thank you very much in advance.
Cosmo.

Sorry, I am not a Linux guy so can not help out much on that end.

If the led on the SSC-32 does not blink at all, it sounds like nothing is getting to the SSC-32. The LED would blink if anything was sent to the SSC-32, even if it was the wrong baud rate or the like.

If it blinked at all, I would say try change the write to end with both \n and \r.

Kurt

Thank you very much for your reply Kurt!

I already tried that and there was no difference.

I decided to try an old implementation of the same procedures in C that I did for another robot and it works… this is very weird, in C works, in C++ doesn’t and the System calls are the same. Finally I solved the issue by importing the C source code into C++ by using ‘extern “C”’

So now I have a class in C++ that wraps the C code that works.

Thank you very much for your time.
Cosmo.

Hi cosmoperis,

here is a link to my linux-/ c-port of Xans Hexapod code.
file-server.servemp3.com/download/main2V1.cpp
Port init from line 322 to 335.
Servo driver from line 1411 to 1461.

Feel free to ask

Greetings
Daniel

Hi Daniel!

Thank you very much for your code :slight_smile: Fortunately I already solved the issue some time ago.

Thank you very much for your answer anyway, I really appreciate it.

Best regards,
Cosmo.