Using a FindBall with an Arduino Jan 18, 2014

This is the second of four posts that will demonstrate using the FindBall NXT (or FindBall Open) with a LEGO® NXT, a LEGO® EV3, an NXT and RobotC, and an Arduino. This post covers how to use the FindBall with an Arduino, or similar microcontroller. A FindBall Open has an easily accessible header on it for connections, however to use a FindBall NXT, a ConnectNXT Breakout is required.

Wiring it up

Arduino and FindBall wired up for testing

Although the photo above shows a FindBall NXT, a FindBall Open can also be used just by using the header connections on the FindBall PCB. The connections have the same names.

FindBall Open / ConnectNXT Breakout Arduino
Vcc 5V
GND GND
SDA SDA (normally A4)
SCL SCL (normally A5)

On recent Arduinos the internal pull-ups are fine, however on other microcontrollers, external 10k pull-up resistors should be used on the SDA and SCL lines.

The example code below requires the USB to be connected to output the information to the serial monitor. As such, power to the Arduino can simply be supplied via USB.

Example Code

Example Code output using a FindBall

To demonstrate how easy it is to work with a FindBall, the example code simply outputs the best sensor and the reading of the best sensor to the serial monitor. If there is an error (generally a bad/incorrect connection) or no 40kHz IR source present, it will say so.

The code uses the inbuilt Wire library to handle I2C communication, which makes the core of the code very simple (most of the code is actually formatting). The code below can also be downloaded from here.

/******************************************************************************
 * File: FindBall Example Arduino Code                                        *
 * Version: 1                                                                 *
 *                                                                            *
 * See http://tris10.com/ for more information.                               * 
 *                                                                            *
 * Copyright (c) 2014 TRIS10 ROBOTICS                                         *
 *                                                                            *
 * Permission is hereby granted, free of charge, to any person obtaining a    *
 * copy of this software and associated documentation files (the "Software"), *
 * to deal in the Software without restriction, including without limitation  *
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
 * and/or sell copies of the Software, and to permit persons to whom the      *
 * Software is furnished to do so, subject to the following conditions:       *
 *                                                                            *
 * The above copyright notice and this permission notice shall be included in *
 * all copies or substantial portions of the Software.                        *
 *                                                                            *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    *
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        *
 * DEALINGS IN THE SOFTWARE.                                                  *
 ******************************************************************************/

#include <Wire.h>

/*** START OF CONFIG ***/

/** 
	The 7-bit address of the FindBall sensor. 
	The default address is 0x01, however it can also be changed to 0x03.
	See page 6 of the datasheet for more information.
*/
#define FB_ADDR_7BIT (0x02 >> 1)

/*** END OF CONFIG ***/

/**
	Reads a byte from an I2C device.

	@param  addr The 7-bit I2C address
	@param  reg  The register to read on the device
	@return The register value or 255 on error
*/
unsigned char read_byte(unsigned char addr, unsigned char reg) {
	Wire.beginTransmission(addr);
	Wire.write(reg);
	Wire.endTransmission();
	
	Wire.requestFrom((uint8_t) addr, (uint8_t) 1);
	if (Wire.available()) {
		return Wire.read(); //Success
	} else {
		return 255; //Error
	}
}

void setup() {
	Serial.begin(9600); //Initialise the Serial output to a host machine
	Wire.begin(); //Initialise the I2C bus

	Serial.println("Beginning FindBall example.  Turn on an RCJ ball or EmitIR.");
}

void loop() {
	unsigned char best_sensor, best_sensor_value;
	
	//Read the sensor data
	best_sensor = read_byte(FB_ADDR_7BIT, 0x42);
	best_sensor_value = read_byte(FB_ADDR_7BIT, 0x43);
	
	//Output the sensor data in a very formatted way
	if (best_sensor == 255) {
		Serial.println("Error: Unable to connect to FindBall!");
	} else if (best_sensor == 0) {
		Serial.println("No sensor can see the RCJ ball or EmitIR");
	} else {
		Serial.print("The best sensor is ");
		Serial.print(best_sensor, DEC);
		Serial.print(" with a value of ");
		Serial.print(best_sensor_value, DEC);
		Serial.println(".");
	}
	delay(150); //Optional: slow down output to make it easier to read
}