Serial response from micro maestro

I am unable to get a response from the micro maestro when I ask it to give me the position, in µs. A condensed version of the code looks something like this

SerialPort^ maestro = gcnew(“COM4”, 9600);
maestro->Open();
array^serialBytes[4]; //since only 4 bytes are ever needed
array^readBytes[2]; //only ever need 2 bytes to be read
serialBytes[0]=0x90;
serialBytes[1]=0x00;
maestro->Write(serialBytes,0,1);
maestro->Read(readBytes,0,2);

where maestro is a SerialPort class that is able to write just fine, just not read without timing out (500ms). I’ve also tried using a handle with WriteFile and ReadFile with the same effect: I can write to the micro maestro no problem, but ReadFile or WaitCommEvent will time out (I’ve given both methods a 500ms time out).

I’m not super familiar with the Microsoft .NET framework, so maybe I missed something here. Any help would be much appreciated.

Hello,

Have you successfully caused the Maestro to do anything by writing commands? You can monitor the state of the Maestro with the Maestro Control Center, so it should be easy to tell. If you have not verified that the commands you are sending do anything, I recommend that you start with that before getting Read() to work.

A common problem is to forget to put it in the proper serial mode - can you tell me which one you chose and how you selected COM4?

The Pololu Serial Transmitter is a simple program you can use for sending bytes to a COM port to check whether the problem is with your Maestro or with your code. Please try that if you continue to have trouble getting your code to work.

-Paul

Thanks for your response.

This line SerialPort^ maestro = gcnew(“COM4”, 9600) should actually read
SerialPort^ maestro = gcnew SerialPort(“COM4”, 9600)
I can post or send the exact code if needed.

I actually have my code list the available com ports, which are 4 and 5. I also double checked this with device manager, and it listed COM5 as a TTL port and COM4 as the Command Port.

I can write to the maestro without any problem. When I try to read, directly after telling the maestro that I want a position response, it seems as though no characters or bytes, or really anything, is in the read buffer.

I have the maestro set up as USB Chained. I didn’t test it, but I suppose I could toggle between the three modes and see if one of those will give me read.

Hello,

I saw that you said you can write without problems, but I do not know what that means. Have you successfully caused the Maestro to do anything by writing commands? And again, I recommend starting with our serial transmitter.

-Paul

I agree with Paul that you should try using the Pololu Serial Transmitter to test the command you are trying to send, because there is probably something wrong with your code. Specifically, one thing that’s wrong with your code is that you are not sending the entire command, you are only sending the first byte:

serialBytes[0]=0x90;
serialBytes[1]=0x00;
maestro->Write(serialBytes,0,1); // problem: the count param should be 2, not 1

Try fixing your call to maestro->Write.

–David

Whoops! You were right David, I forgot to send it the other bit that it needed. :blush: I knew something was wrong in my code, but didn’t expect it to be something so minor and trivial.

One other quick question. I now have a code that does the following:

serialBytes[0]=0x84;
serialBytes[1]=0x00;
serialBytes[2]=servoPos&0x7F;
serialBytes[3]=(servoPos >> 7) & 0x7F;
maestro->Write(serialBytes,0,4);
_continue=1;
while(_continue==1)
{
	//read the position
	try
	{
		serialBytes[0]=0x90;
		serialBytes[1]=0x00;
		maestro->Write(serialBytes,0,2);
		maestro->Read(readBuffer,0,2);
		thePosition=(short)(((readBuffer[1]&0xFF)<<8)|(readBuffer[0]&0xFF));  //response is 8 low bits, then 8 high bits
		Console::WriteLine(thePosition);
	}
	catch (TimeoutException ^) 
	{
	Console::WriteLine("TIMEOUT");
	}
	serialBytes[0]=0x93;
	maestro->Write(serialBytes,0,1);
	_continue=(short) maestro->ReadByte();
}

The code sets the position of a servo, then reads a position from the maestro and writes the position to the console. The maestro gives a serial communication error every now and again. Every time I get the error I have to clear the read buffer maestro->DiscardInBuffer();.

I’m pretty sure that it must be that the buffer has either more or less bytes than the 2 that I try to read, and so it melts down. My question is, is there a good way around this communication error? Should I add a delay, or am I better off just constantly checking and handling errors every time I want to communicate by serial?

Hello,

What error are you getting? You can check in the Errors Tab of the Control Center. In general, you should not be getting errors if you are communicating over USB.

Also, if you are worried about extra bytes potentially appearing on the serial line, and you only need to talk to a single Maestro, switch your serial mode to USB Dual Port.

-Paul

ahihmc, I would appreciate it if you were more specific (and you could save both of us time). Instead of saying “gives a serial communication error” and “melts down” please say something specific like “maestro->Write throws a TimeoutException” or “the Maestro Control Center tells me that a Serial Protocol Error occurred”. In order to help you be more specific, you should change your code so that you can detect which serial port function is throwing the TimeoutException.

If you write your code correctly, you shouldn’t have to add any delays and you shouldn’t get any errors during normal operation.

You should make sure that the SerialPort.Read method is operating in a blocking way, so that it will block (for at least a few tens of milliseconds) trying to receive the 2 bytes from the Maestro instead of just returning right away with whatever data happens to be in the buffer, which might be nothing. The official Microsoft documentation is not super clear on when SerialPort.Read will block or not block, so you might want to use ReadByte instead because its documentation clearly says that it will block.

You could also check the return value of SerialPort.Read. If it’s not 2, then throw an exception.

–David

Hi guys, I appreciate the help. Sorry about not being more specific or helpful. I’m simply not used to either the Windows API or your device. If I don’t give the info you feel I should, the reason is because I’m not an expert in either of these areas and it’s hard for me to know whether it’s a syntax issue in my code, an issue with my code talking to the maestro, or simply an issue that the maestro has. I’ll try to be more specific in the future.

What I meant by “gives a serial communication error” was that the Maestro Control Center tells me that there is a Serial Protocol Error.

David, your suggestion to change from Read to ReadByte seemed to do the trick, thanks!