Putting robotics at your service™

Free shipping on orders over $200

Hard time with SSC 32 and C++

Print view Share :
Previous topicNext topic

Page 1 of 1 [ 5 posts ]

New ( offline )
Posts: 3
Posted: 2011-06-27 05:30 
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 <string>
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 <iostream>
#include <string>
#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 <iostream>

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;
   }
}


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.


User avatar
Guru ( offline )
Posts: 4913
Posted: 2011-06-27 09:11 
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


New ( offline )
Posts: 3
Posted: 2011-06-27 21:16 
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.


User avatar
Novice ( offline )
Posts: 64
Posted: 2011-11-30 16:19 
Hi cosmoperis,

here is a link to my linux-/ c-port of Xans Hexapod code.
http://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

_________________
The genius mastered the chaos.
I am the Chaos!


New ( offline )
Posts: 3
Posted: 2011-12-01 23:04 
Hi Daniel!

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

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

Best regards,
Cosmo.


 

cron
All times are UTC - 5 hours [ DST ]. It is currently 2014-10-25 13:26
Feedback Form
Feedback Form