Maestro C Serial communication in Linux

Hey ,
i’m also trying to ‘talk’ with micro maestro 6 channel from a user space program (linux).

i have tried to do something like that :

/*********************************************************************************/
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

int main (int argc, char* argv[])
{
	int fd;
	char buf = 0x55; // I have know idea what this value suppose to do , this is a guess .. :/

	fd = open("/dev/ACM0", O_RDWR);
	if (fd < 0){
		perror("Cannot open /dev/ACM0 (userspace) \n");
		return EXIT_FAILURE;
	}				
	write(fd,&value,1);
	return EXIT_SUCCESS;
}
/*********************************************************************************/

Ok ,so i really don’t know in which protocol way i should talk with the maestro ?
Does it PIC PROTOCOL ?
How should i send the commands ? something like [id,channel-number,value] ?
Does it take init values for start ?

Hey ,
i tried to control servo with the following program :

#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <termios.h>

#define DEBUG 1

void openPort(int * fd);
void setBaudRate(int * fd);
void maestroGetPosition(int * fd , unsigned char channel , unsigned short * position);
void maestroSetTarget(int *port, unsigned char channel, unsigned short target);
void closePort(int *fd);

int main(){
	int mainFd , channel=0;
	unsigned short target=7000, position=0;
	openPort(&mainFd);
	setBaudRate(&mainFd);
	maestroGetPosition(&mainFd,channel,&position);
	maestroSetTarget(&mainFd,channel,target);
	exit(0);
}

/* Open the Maestro's serial port. */
void openPort(int * fd){
	*fd=open("/dev/ACM1",O_RDWR | O_NOCTTY | O_NDELAY);
	if(0>fd){
		printf("Cannot open /dev/ACM1 :/\n");
		exit(1);
	}
#if DEBUG
	printf("Port open successfully :)\n");
#endif
}

/* Choose the baud rate (bits per second).*/
void setBaudRate(int * fd){
	struct termios options;
	// Get the current settings of the serial port.
	tcgetattr (*fd, &options);
	// Set the read and write speed to 19200 BAUD.
	// All speeds can be prefixed with B as a settings.
	cfsetispeed (&options, B9600);
	cfsetospeed (&options, B9600);
	// Now to set the other settings. Here we use the no parity example. Both will assumme 8-bit words.
	// PARENB is enabled parity bit. This disables the parity bit.
	options.c_cflag &= ~PARENB;
	// CSTOPB means 2 stop bits, otherwise (in this case) only one stop bit.
	options.c_cflag &= ~CSTOPB;
	// CSIZE is a mask for all the data size bits, so anding with the negation clears out the current data size setting.
	options.c_cflag &= ~CSIZE;
	// CS8 means 8-bits per work
	options.c_cflag |= CS8;
}

/** Implements the Maestro's Get Position serial command.
* channel: Channel number from 0 to 23
* position: A pointer to the returned position value (for a servo channel, the units are quarter-milliseconds)
* Returns 1 on success, 0 on failure.
* For more information on this command, see the "Serial Servo Commands"
* section of the Maestro User's Guide: https://www.pololu.com/docs/0J40 */
void maestroGetPosition(int * fd , unsigned char channel , unsigned short * position){
	int ret=0;	
	unsigned char command[2];
	unsigned char response[2];
	// Compose the command.
	command[0] = 0x90;
	command[1] = channel;
	// Send the command to the device.
	ret=write(*fd,command,2);
	printf("maestroGetPosition , write %d\n",ret);
	// Read the response from the device.
	ret=read(*fd,response,2);
	printf("maestroGetPosition , read %d\n",ret);
	// Convert the bytes received in to a position.
	*position = response[0] + 256*response[1];
	printf("Current position is %d.\n", *position);
}

/** Implements the Maestro's Set Target serial command.
* channel: Channel number from 0 to 23
* target: The target value (for a servo channel, the units are quarter-milliseconds)
* Returns 1 on success, 0 on failure.
* Fore more information on this command, see the "Serial Servo Commands"
* section of the Maestro User's Guide: https://www.pololu.com/docs/0J40 */
void maestroSetTarget(int * fd, unsigned char channel, unsigned short target){
	int ret=0;	
	unsigned char command[4];
	// Compose the command.
	command[0] = 0x84;
	command[1] = channel;
	command[2] = target & 0x7F;
	command[3] = (target >> 7) & 0x7F;
	// Send the command to the device.
	ret=write(*fd,command,4);
	printf("maestroGetPosition , write %d\n",ret);
}

/* Closing the Maestro's serial port. */
void closePort(int *fd){
	close(*fd);
}

it doesn’t work for me , can u see any problem ?

thanks for the help …

My micromaestro configure to usb dual port …

Hello.

I split your posts into their own thread. Please do not post at the bottom of unrelated threads and please do not post the same message twice. Also, if you are submitting code, please add code tags around it. There is a button above the posting text box to do it.

- Ryan

Hello.

I would not expect your code to work because your port name looks wrong. It should be “/dev/ttyACM0”. If you continue to have problems, please simplify your code to the simplest thing that should work but doesn’t and tell us what is actually going wrong.

You should use the Maestro’s serial protocol which is describe in the “Serial Interface” section of the Maestro User’s Guide.

–David