Sample C code not responding w/Maestro 6 Linux

Hi everyone!
I’m using a 6 Channel Maestro and a 1711MG Servo
I have already controlled the servo by using the UscCmd and the MaestroControlCenter examples, but when trying to run the Sample C code I can not control the servo
It does not throws any error nor anything, it bucles in the
if(read(fd,response,2) != 2) part
allow me to post you the code:

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

#ifdef _WIN32
#define O_NOCTTY 0
#else
#include <termios.h>
#endif

int maestroGetPosition(int fd, unsigned char channel)
{
  unsigned char command[] = {0x90, channel};
  if(write(fd, command, sizeof(command)) == -1)
  {
    perror("Error writing");
    return -1;
  }

  unsigned char response[2];
  if(read(fd,response,2) != 2)
  {
    perror("Error reading");
    return -1;
  }

  return response[0] + 256*response[1];
}

int maestroSetTarget(int fd, unsigned char channel, unsigned short target)
{
  unsigned char command[] = {0x84, channel, target & 0x7F, target >> 7 & 0x7F};
  if (write(fd, command, sizeof(command)) == -1)
  {
    perror("error writing");
    return -1;
  }
  return 0;
}

int main()
{
  const char * device = "/dev/ttyACM0"; 
  int fd = open(device, O_RDWR | O_NOCTTY);
  if (fd == -1)
  {
    perror(device);
    return 1;
  }

#ifndef _WIN32
  struct termios options;
  tcgetattr(fd, &options);
  options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
  options.c_oflag &= ~(ONLCR | OCRNL);
  tcsetattr(fd, TCSANOW, &options);
#endif
  
  int position = maestroGetPosition(fd, 0);
  printf("Current is %d.\n", position);

  int target = (position < 6000) ? 7000 : 5000;
  printf("Set to %d (%d us).\n", target, target/4);
  maestroSetTarget(fd, 0, target);

  close(fd);
  return 0;
}

did not found anything by searching in the forum; With “stty -F /dev/ttyACM0 -a” I get:

speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^; erase = ^?; kill = ^U; eof = ^D; eol = ; eol2 = ; swtch = ; start = ^Q; stop = ^S;
susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

Thank you in advance!

Hello.

It looks like you copied that code from the “Cross-Platform C” section under “Serial Example Code” in the Maestro user’s guide. There are instructions at the top of that page, and in comments in the code, about how you need to configure the Maestro. Did you follow the instructions in those comments?

What do mean by “it bucles in the if(read(fd,response,2) != 2)”? Could you post the entire output from the program so I can see what error message it is producing?

–David

Well for setting the serial mode to “USB Dual port” I opened the MaestroControlerCenter and in the “Serial settings” tabs I selected the USB Dual port, I don’t know if there’s another way to do it…

For the device I’m using “/dev/ttyACM0” as It is indicated in the Cross-platform section for linux

And when I run the program I get no error, no nothing, for example if I do this:

int maestroGetPosition(int fd, unsigned char channel)
{
  printf("CheckpointStart\n");
  unsigned char command[] = {0x90, channel};
  printf("CheckpointCommand\n");
  if(write(fd, command, sizeof(command)) == -1)
  {
    perror("error writing");
    return -1;
  }
   
  printf("CheckpointInitResponse\n");
  unsigned char response[2];
  if(read(fd,response,2) != 2)
  {
    perror("error reading");
    return -1;
  }
  printf("CheckpointAnswResponse\n"); 
  return response[0] + 256*response[1];
}

int maestroSetTarget(int fd, unsigned char channel, unsigned short target)
{
  unsigned char command[] = {0x84, channel, target & 0x7F, target >> 7 & 0x7F};
  if (write(fd, command, sizeof(command)) == -1)
  {
    perror("error writing");
    return -1;
  }
  return 0;
}
 
int main()
{
  const char * device = "/dev/ttyACM0"; 
  int fd = open(device, O_RDWR | O_NOCTTY);
  if (fd == -1)
  {
    perror(device);
    return 1;
  }
   
  int position = maestroGetPosition(fd, 0);
  printf("Current position is %d.\n", position); 
 
  int target = (position < 6000) ? 7000 : 5000;
  printf("Setting target to %d (%d us).\n", target, target/4);
  maestroSetTarget(fd, 0, target);
   
  close(fd);
  return 0;
}

I get only this:

CheckpointStart
CheckpointCommand
CheckpointInitResponse

and it won’t do anything further…
I have to kill the process because it wont finish by itself
I don’t know if I’m missing something to do or something

It looks like the “read” function is taking forever, which probably means that your Maestro is misconfigured or that you are connecting to the wrong serial port device.

Did you remember to click the “Apply Settings to Device” button after changing to USB Dual Port mode? Could you make sure that the “Enable CRC” checkbox is unchecked (which is the default)?

What devices do you see if you run “ls /dev/ttyACM*” ?

Do you see the green LED on the Maestro flicker when you run this program?

–David

Ok First the “ls /dev/ttyACM*” listed
/dev/ttyACM0 /dev/ttyACM1
I decided to try first with the one that I had already “/dev/ttyACM0”

Second: Ive double checked the Dual port mode is checked
and the CRC is NOT
Also that the “Apply settings” button was clicked after re-doing this changes

After doing this the servo responded and I can manipulate with the sample code you provide
Maybe I’ve missed something, I couldnt tell… According to me I did all that, anyway…
THANK YOU SO MUCH
Just let me list everything for further help to people that may have the same problem as me in the future…

Open the MaestroControlCenter
go to the “Serial settings” tab and have checked the “USB Dual Port” and unchecked the "CRC"
and click the “Apply settings” button

If using linux make sure that using “/dev/ttyACM0” as the channel ( at least worked for me )

Just one last question…
Im using the 1711MG
and I’m powering it with 6v for 3.5kg/cm
with 5v I DONT have this problem
and I really need to use the 3.5 kg

-------------EDITED---------

If im in 8000 and go lower it does it without any problem
BUT
if im 4000 and go higher
sometimes goes beneath 4000 (maybe a 3000 more or less )
and then goes to the position I try to set
Why is this happening?

—2nd Edition—

Here is how it behaves


by running script

begining
4000
500 wait
8000
500 wait
end

it only goes back and forth
and it does that :S

Please post your actual script so I can see if there is anything wrong with it. Also, could you explain what the circuit board is on the left? How exactly are you powering everything? How is everything connected? Why does the blue LED flicker?

–David

The exact script is this one

begin
8000 0 servo
500 delay
4000 0 servo
500 delay
repeat

And the circuit board on the left is a simple 6v power supply
( 6.03 measured with a multimeter )
I have the positive 6v output in the + bat position in the Maestro
and the negative 6v output in the - bat position in the Maestro
I have the servo in the 0 channel in the Maestro

The blue led is only for indicating if the power supply is on

Since the blue LED is flickering, I suspect your power supply is having problems supplying enough current for your servo, and the output voltage is probably dropping when the servo tries to move. Could you give more details about how your power supply works? How much current can it supply? Do you have an oscilloscope or some other way to monitor the power supply output voltage?

–David