Serial communication between Arduino Mega and Baby Orangutan

In this project, we are attempting to use the Arduino Mega 2560 for high-level control, path planning, etc. Additionally, we want to use the Pololu Baby Orangutan B-328 for low-level feedback and motor control. It is our intention that the Arduino will prescribe a joint position and send the command to the Orangutan. The Orangutan will then drive the motor to obtain the required position.

WHAT IS WORKING SO FAR:
The serial output of the Arduino Mega successfully sends commands to both the Arduino serial window and the Microsoft Hyper Terminal via the Pololu USB AVR Programmer.

The Baby Orangutan successfully sends data to the Hyper Terminal (only one device is connected at a time).

The Baby Orangutan is receiving something and outputting something to the Hyper Terminal that is related to the data sent by the Arduino.

WHAT DOES NOT WORK YET:
It is not clear what is being received by the Orangutan.

It is not clear if the Orangutan is sending exactly what is received.

The value sent by the Arduino Mega is “1257”, the values printed from the Baby Orangutan are:
12
1257
1257
1257257
257
1257

I cannot tell if the sending and receiving char types are actually 8-bit or 10-bit with some kind of trigger.

THE CURRENT CODE:

*********** For the Arduino Mega
void setup()
{
  Serial.begin(9600);
}
int thisByte = 1257;
void loop()
{
Serial.print(thisByte);
Serial.print("\r\n");
}
*********** For the Pololu Baby Orangutan B-328 (mostly from the C++ User Guide)
#include <pololu/orangutan.h>
#include <string.h>
#include <stdlib.h>
char receive_buffer[128];
unsigned char receive_buffer_position = 0;
char send_buffer[32];
void wait_for_sending_to_finish()
	{
		while(!serial_send_buffer_empty());
	}
void process_received_byte(char byte)
	{
		wait_for_sending_to_finish();
	}
void check_for_new_bytes_received()
	{
		while(serial_get_received_bytes() != receive_buffer_position)
			{
			process_received_byte(receive_buffer[receive_buffer_position]);
			if (receive_buffer_position == sizeof(receive_buffer)-1)
				{
					receive_buffer_position = 0;
				}
					else
				{
			receive_buffer_position++;
			}
		}
	}
int main()
{
	serial_set_baud_rate(9600);
	serial_receive_ring(receive_buffer, sizeof(receive_buffer));
	while(1)
		{
			check_for_new_bytes_received();
			serial_send(receive_buffer, 10);
			wait_for_sending_to_finish();
			receive_buffer_position = 0;
	}
}

Thanks for the products, and in advance, for the help,
Ben

Hello.

I put the “code” tags around your code so I could read it easily. Please do this yourself in the future when you are posting code. (You can just select the code and click the “Code” button on the top of the editor.)

With this compiler, a char is 8 bits. You can have either an “unsigned char” or a “char” but both of them are 8 bits, and both are commonly called a “byte”. When you send a byte on a serial port, the UART adds a start bit and a stop bit to it, which means it takes 10 bit times to transmit 1 byte of data. The start and stop bits don’t contain any data so you don’t get to read or write them in your program. For the most part, you don’t have to worry about them at all.

I noticed that you have three lines in your program that are definitely going to be messing you up:

serial_send(receive_buffer, 10);
wait_for_sending_to_finish();
receive_buffer_position = 0;

The first line sends the first 10 bytes of the receive ring buffer, which is a 128 byte buffer. This will result in old/duplicate data being sent most of the time. The third line makes the program forget where it was reading from the receive ring buffer, making it impossible for the program to tell which bytes it has processed already. It’s kind of like removing the bookmark from a book you are reading and putting it at the beginning. I think you should remove all three of these lines.

I don’t understand why you removed all the code from “process_received_byte” and replaced it with a single call to “wait_for_sending_to_finish”. The idea of the example code you copied is that if you want to process incoming serial bytes, you can easily process them one at a time as they come in by writing your own code inside of “process_received_byte”. The example code shows you how you would change the capitalization of an incoming byte and send it back. If you just want to send the byte back without modifying it, you could do this:

void process_received_byte(char byte)
{
    wait_for_sending_to_finish();
    send_buffer[0] = byte;  
    serial_send(send_buffer, 1); 
}

Also, I recommend adding a delay of 1 second in the Arduino main loop while you are debugging the serial communication. This should prevent your terminal from getting flooded with messages and make it easier to see what’s going on.

I think if you make these three changes you will probably see a more sensible output in your terminal.

–David Grayson

Some more thoughts:

You might want to look carefully at how serial is done in our 3pi Robot serial slave example. It is available in the Pololu AVR C/C++ library under libpololu-avr\examples\atmega328p\3pi-serial-slave. The Baby Orangutan’s hardware is a subset of the 3pi Robot’s hardware, so this example code will probably work with little or no modification on the Baby Orangutan and allow you to drive the motors by sending the right serial commands.

Also, these two lines make me worried that you might have some misunderstandings:

int thisByte = 1257;
Serial.print(thisByte);

An int is 16-bits, so “thisByte” is a misleading name for it. Bytes can only represent values between 0 and 255 (or -128 to 127 if you consider them to be signed) so 1257 is can not be stored in a single byte. The Arduino Serial.print function sends ASCII strings that contain the decimal representation of the number given to them. If you just want to send a single byte, use Serial.write. For example:

Serial.write(170);

–David