Baby-O and Arduino won't talk

I set myself on a new venture today, to send a character from Arduino, through Serial and than to read that on Baby-O. Baby-O should blink Red LED when it recognizes the sent character. Now, I did only minimal changes to the existing code I found in examples. I did connect RX to TX and TX to RX and Arduino ground to Baby-O ground.

This is Arduino code, it simply sends letter ‘B’ every 3 seconds to Serial. I tried both Serial.print(‘B’); and Serial.write(66); to no avail:

#include <LiquidCrystal.h>

byte incomingByte    = 'B';      // Arduino receiving incoming serial data into int variable.

// Initialize the library for the LCD display.
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  
  // Set up the LCD:
  lcd.begin(16, 2);
  // Print startup message to LCD.
  lcd.print("OK, 9600 baud");
  delay(2000);                  // waits for a two seconds,
  
  // Prepare the Serial.
  Serial.begin(9600);
  Serial.flush();
}

void loop() {

  ///Serial.print(incomingByte);     // Transmit received character back to Serial.
  Serial.write(66);

  delay(3000);                    // Wait a second or two.
}

The stuff for Baby-O is unchanged, apart from recognition of the character ‘B’ in switch statement:

#include <pololu/orangutan.h>  
  
// receive_buffer: A ring buffer that we will use to receive bytes on PD0/RXD.
// The OrangutanSerial library will put received bytes in to
// the buffer starting at the beginning (receiveBuffer[0]).
// After the buffer has been filled, the library will automatically
// start over at the beginning.
char receive_buffer[32];

// receive_buffer_position: This variable will keep track of which bytes in the receive buffer
// we have already processed.  It is the offset (0-31) of the next byte
// in the buffer to process.
unsigned char receive_buffer_position = 0;

// send_buffer: A buffer for sending bytes on PD1/TXD.
char send_buffer[32];

// My function added to show some reaction, on Baby-O, to received input:
void on_input_blink_red_x3() {

    red_led(1);              // red LED on
    delay_ms(500);           // waits for a second
    red_led(0);              // red LED off
    delay_ms(500);           // waits for a second

    red_led(1);              // red LED on
    delay_ms(500);           // waits for a second
    red_led(0);              // red LED off
    delay_ms(500);           // waits for a second

    red_led(1);              // red LED on
    delay_ms(500);           // waits for a second
    red_led(0);              // red LED off
    delay_ms(500);           // waits for a second
}

void on_input_blink_red_x2() {

    red_led(1);              // red LED on
    delay_ms(500);           // waits for a second
    red_led(0);              // red LED off
    delay_ms(500);           // waits for a second

    red_led(1);              // red LED on
    delay_ms(500);           // waits for a second
    red_led(0);              // red LED off
    delay_ms(500);           // waits for a second
}

// wait_for_sending_to_finish:  Waits for the bytes in the send buffer to
// finish transmitting on PD1/TXD.  We must call this before modifying
// send_buffer or trying to send more bytes, because otherwise we could
// corrupt an existing transmission.
void wait_for_sending_to_finish() {

	while(!serial_send_buffer_empty());
}

// process_received_byte: Responds to a byte that has been received on
// PD0/RXD.  If you are writing your own serial program, you can
// replace all the code in this function with your own custom behaviors.
void process_received_byte(char byte) {

	switch(byte) {

		// If the character 'B' is received, turn on the green LED.
		case 'B':
			on_input_blink_red_x3();
			break;

		// If the character 'b' is received, turn off the green LED.
		case 'b':
			on_input_blink_red_x2();
			break;

		// If any other character is received, change its capitalization and
		// send it back.
		default:
			wait_for_sending_to_finish();
			send_buffer[0] = byte ^ 0x20;
			serial_send(send_buffer, 1);
			break;
	}
}

void check_for_new_bytes_received() {

	while(serial_get_received_bytes() != receive_buffer_position) {

		// Process the new byte that has just been received.
		process_received_byte(receive_buffer[receive_buffer_position]);

		// Increment receive_buffer_position, but wrap around when it gets to
		// the end of the buffer. 
		if (receive_buffer_position == sizeof(receive_buffer)-1) {
			receive_buffer_position = 0;
		} else {
			receive_buffer_position++;
		}
	}
}

int main() {

	// Set the baud rate to 9600 bits per second. Each byte takes ten bit
	// times, so you can get at most 960 bytes per second at this speed.
	serial_set_baud_rate(9600);

	// Start receiving bytes in the ring buffer.
	serial_receive_ring(receive_buffer, sizeof(receive_buffer));

    while(1) {

		// Deal with any new bytes received.
		check_for_new_bytes_received();

		// If the user presses the middle button, send "Hi there!"
		// and wait until the user releases the button.
		if (button_is_pressed(MIDDLE_BUTTON)) {

			wait_for_sending_to_finish();
			memcpy_P(send_buffer, PSTR("Hi there!\r\n"), 11);
			serial_send(send_buffer, 11);

			// Wait for the user to release the button.  While the processor is
			// waiting, the OrangutanSerial library will take care of receiving
			// bytes using the serial reception interrupt.  But if enough bytes
			// arrive during this period to fill up the receive_buffer, then the
			// older bytes will be lost and we won't know exactly how many bytes
			// have been received.
			wait_for_button_release(MIDDLE_BUTTON);
		}
    }
}

Middle button part of the code is still there but it does nothing.

Can anybody help get Arduino and Baby-O talk through Serial?

One additional note, I am connecting Arduino RX/TX, on pins 0 and 1 to Baby-O’s pins for RX/TX. Is there a problem with that?

Hello.

I’m sorry you are having trouble in your new venture.

The Baby Orangutan does not have pins labeled RX and TX. RX is PD0 and TX is PD1. So do you have PD0 connected to the Arduino’s TX line?

Did you know that the Arduino’s RX and TX lines are already being used for the USB connection and bootloading? In fact, connecting the Baby Orangutan’s TX (PD1) to the Arduino’s RX line would prevent you from programming the Arduino: the Baby Orangutan would hold the Arduino’s RX line high and the USB connection would be unable to drive it low because it is impeded by a 1k resistor. This shouldn’t be a problem for you yet, because you’re not trying to send data from the Baby Orangutan to the Arduino; you can disconnect the Baby Orangutan’s TX/PD1 line. But if you want to do that later, I recommend using the NewSoftSerial library so you can have your serial connection on different pins.

–David

I was just using verbal shortcuts. I did mean PD0 and PD1.

Yeah, I worked out that it is UART / USB / RX/TX conflict inside Arduino, so I disconnected Arduino from USB but it still won’t work. I’ll try NewSoftSerial library.

Now there is another major mystery. I introduced this simple method on_input_blink_red_x3(); just for debugging. If that method is on the first line, after main() { …, like this:

int main() {
on_input_blink_red_x3();
// Set the baud rate to 9600 bits per second. Each byte takes ten bit
// times, so you can get at most 960 bytes per second at this speed.
serial_set_baud_rate(9600);

than I am in luck, and upon programming Baby-O, it dutifully blinks 3 times. But if I move the method coll just one line down, like this:

int main() {
// Set the baud rate to 9600 bits per second. Each byte takes ten bit
// times, so you can get at most 960 bytes per second at this speed.
serial_set_baud_rate(9600);
on_input_blink_red_x3();

than, after reboot, Baby-O blinks only once. I can not work that one at all.

Anyway, Baby-O is such a powerful device, it is a pity that there is no single fool-proof serial example, with wiring and all, for us newbies to benefit from. I mean, what is Baby-O meant for, if not for serving Arduino as a slave board?

I would be grateful if you can point me to an example of Arduino to Baby-O serial communication that includes wiring and it works straight of the bat.

I mean, I am wasting two days of my holiday that I put aside for this little project and I am getting to a dead end.

I think that it would be fair from Pololu to publish a working example with wiring and code for both Baby-O and Arduino. Basically Baby-O is a little gem that can not be used.

I wrote some Arduino code, based around NewSoftSerial, but this wouldn’t work either:

/*
 * There are internal UART / USB / RX/TX conflicts that prevent Arduino from simultaneous
 * reading from pins 0 and 1 (RX/TX) and being connected to USB. In order to bypass that
 * I am trying here NewSoftSerial.h library, by modifying this example:
 * 
 *   https://www.pololu.com/docs/0J44/6.7.1
 *
 * We will be using pin 6 (RX) and pin 7 (TX) on Arduino.
 *
 */
#include <NewSoftSerial.h> 
#include <LiquidCrystal.h>

#define rxPin 6  // pin 6 connects to SMC TX  (not used in this example)
#define txPin 7  // pin 7 connects to SMC RX 

NewSoftSerial mySerial =  NewSoftSerial(rxPin, txPin);

int  intBufferLength = 0;
byte incomingByte    = 'B';    // Arduino receiving incoming serial data into int variable.

// Initialize the library for the LCD display.
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  
  // Set up the LCD:
  lcd.begin(16, 2);
  // Print startup message to LCD.
  lcd.print("NSS-9.6 kbts");
  delay(2000);                  // waits for a two seconds,

  // initialize software serial object with baud rate of 9.6 kbps
  mySerial.begin(9600);
}

void loop() {

  mySerial.print(0x42, BYTE);     // Transmit 'B' character back to NewSoftSerial.

  delay(3000);                    // Wait a second or two.
}

Main problem is that Baby-O only has one output, the red LED, and it is difficult to debug.

Hello.

I’m sorry you’re having trouble getting things to work, and I know it must be frustrating, but the Baby Orangutan has the same microcontroller as an Arduino Uno, and given that it runs faster and has more integrated hardware, I think it is reasonable to consider it more capable. While it can be used as a serial slave, it was certainly not intended as an Arduino slave board. It can be used as a standalone robot controller, or it can be used to supplement any of the many microcontroller boards on the market.

Can you describe how you are powering everything in your system and how everything is connected? Are you making sure to run example code for the correct AVR on your Baby Orangutan?

I suggest you temporarily remove the Arduino from the system and just focus on establishing serial communication with your Baby Orangutan. Please try loading an unmodified version of the serial1 example, located in:

libpololu-avr/examples/atmega328p/serial1

Or you can find the precompiled hex file here:

libpololu-avr/examples/atmega328p/hex_files/serial1.hex

With that loaded, please connect your Baby Orangutan to your Pololu USB AVR programmer’s serial lines, with the programmer’s TX connected to pin PD0, the programmer’s RX connected to pin PD1, and the programmer’s ground connected to the Baby Orangutan’s ground. You should then be able to use a terminal program like hyperterm to connect to the virtual COM port corresponding to your programmer’s USB-to-TTL-serial adapter and send serial bytes to the Baby Orangutan. If you send an ‘x’, you should see ‘X’ echoed back from the Baby Orangutan. Please let me know what happens when you try this.

Edit: By the way, your LED blinking problem can be explained by the fact that the Baby Orangutan’s red LED is on pin PD1, which is also Orangutan’s serial transmit line. As soon as you enable the serial module by setting the baud rate, the UART hardware takes control of PD1 and makes it an output, which turns on the LED (and essentially turns it into a serial-activity indicator). If you have some through-hole LEDs lying around, you can connect those to arbitrary Baby Orangutan I/O lines (make sure you use an appropriate current-limiting resistor, such as 1k!) and use those to help you debug what is going on. However, if you can get serial working, that is probably a better way to debug things.

- Ben

@Ben: Thanks, this advice is spot on. I’ll act on that.

I didn’t know that ISP Programmer can be hooked on Baby-O. I might buy Orangutan SV just for debugging and code development.

You might find this section of the programmer user’s guide helpful:

pololu.com/docs/0J36/6

- Ben