Summary of Research

Overview

This blog is the summation of a semester long research project on NXT-Arduino interfacing. The overall goal of this project is to develop a foundation by which a lego NXT controller can be made to communicate with a reference Arduino Uno, for the purposes of enabling advanced sensor functionality on the NXT itself. By interfacing the Arduino Uno as a sensor device the NXT can have access to more advanced sensor capabilities, which can serve as augmentation or even a complete replacement of currently available COTS sensors.

Fig 1. The research objective.
To briefly summarize the functional parts of the project (extended detail is available in the blog posts), the NXT communicates with sensor devices via I2C. Through the use of an NXT breakout board or other similar device, the I2C lines can be exposed for attachment to the Arduino's I2C controller on lines A0 and A1. At this point, software-side control of the Arduino's I2C-hardware is managed by the <Wire.h> library. For this project, it was decided that reference Arduino Unos are optimal to ensure up-to-date libraries can be used, and for ease of referencing online documentation.

It was decided relatively early on that NXT development should follow a RobotC-oriented path. Consequently the NXT was burned with a RobotC bootloader image. All development took place using "RobotC for Mindstorms", and as an additional resource the NXT API is available here (http://www.robotc.net/support/nxt/MindstormsWebHelp/index.htm#page=nxt_functions/Sensors_Digital/Sensor%20Digital.htm). The NXT handles I2C communication through functions exposed by the RobotC API, and as the I2C bus master it will be responsible for polling the Arduino to access any data needed. The Arduino, configured as an I2C slave, will be responsible for responding to any data requests made by the NXT. When not dealing with I2C data communications, the Arduino will perform any sensor processing needed to ensure that data is available for the NXT.

Fig 2. A high-level diagram depicting the structure of the NXT-Arduino communications. The register-bank is explored further in the Week 6 post.

Fig 3. A breakdown of the packet structure used by the NXT to signal the Arduino. The Arduino is purely reactive in that it will only transmit when data is requested by the NXT through the above packet.

Fig 4. A sequencing diagram depicting a polling cycle, in which the NXT queries the Arduino for sensor data.

In order to demonstrate the NXT-Arduino interface, several sensor ideas were considered for implementation. Research and development into these concepts consumed the latter portion of time spent on this project. This is covered in the next topic.

Project Status

As of now, the communications link over I2C can be said to have been finalized. Between the register-bank protocol for communicating and the basic code structure required to achieve workable communications (sample code in the I2C_Slave_Test folder), the only part left unfinished is the form of the physical connection to be used. For the purpose of prototyping during research, a jury-rigged connector was fashioned after cannibalizing an NXT sensor cable. As noted in the relevant post on the matter, it may be easier and cleaner to use an NXT breakout board to attach the I2C lines and NXT power rails to a breadboard.

However, given that the I2C link is functional, the work that remains left to be done involves creating sensors that utilize the link. During this project, I worked on two sensors: An IR receiver, and a sound sensor to recognize frequencies.

As it stands, the IR sensor has been completed and is in a workable state. Sample code is available in the "IR Receiver" folder. The details of the sensor are explored in the Week 11/12 post. The Arduino is equipped with an IR photodiode, and an external IR library is used to decode the signal into a hex value. The Arduino then stores the IR code for later retrieval by the NXT, which when triggered results in the data being packaged for delivery and sent over the I2C bus. In the example code, the NXT is configured to reconstruct the data containing the IR code and emit a tone if a known code is detected.

The second sensor, the sound sensor, is not yet operational. While work has been done on the software front, hardware issues prevented the sensor from being completed. However, the FFT implementation is detailed in the Week 14/15 post, and enough work has been done on the "core" ideas that the only thing needed is a functioning electret mic attached to the Arduino in addition to some parts of the software being expanded upon.

Next Steps

The immediate next step is to complete the tone recognition sensor. As previously mentioned, the major hurdle is actually implementing the researched concepts into a functioning sensor. The FFT piece is effectively handled by the ArduinoFFT library, and the remaining parts to be fleshed out pertain primarily to handling of I2C data transfer, identification of the tone from the FFT results, connection of the electret mic to the Arduino, and implementation of all of the above in a manner that addresses the concerns mentioned in the Week 14/15 post. Once completed, the NXT should ideally have access to realtime sensor readings on ambient tones. For example, the NXT should be able to listen to a tone and identify it by frequency.

Following completion of the sound sensor, it would be beneficial to continue implementing various sensor ideas. As mentioned at the start of research, the goal is to have several sensors suitable for lab-based exercises during class. Hence it should be made a research objective to increase the number of sensors available, and implement as many as possible. The Week 10 post explores the idea of implementing a 6 degrees-of-freedom gyro/accelerometer combination sensor.

Additionally it stands to reason that optimizations could be made to the polling process. Week 13 was dedicated to exploring the possibility of polling the Arduino in realtime, in the background of the user program. This could be achieved using RobotC's task-based multithreading, which could in theory reduce the delay required to access data. If the user program on the NXT requires fast and immediate access to the Arduino's data, background polling could be beneficial.

Lessons Learned

As with every project undertaken, there exists lessons to be taken away from the experience. Here are a few...
  • Try not to use outdated software
Early on in the project I was using outdated Arduino 022 libraries for I2C communications. While this was borne of necessity due to limitations with the ChipKit I was using, it created unnecessary headaches and was a stopping block for the implementation of I2C. Outdated libraries can sometimes be buggy, and they often notoriously undocumented. The latter consideration cannot be understated, especially as this project was intended for future use.
  • Always double check your code
This is a lesson that should come as no surprise, but if you have to pick something to blame when something isn't working, it should first and foremost be your code. During my development of the I2C interface, I was missing a pragma directive in my RobotC code. This sunk countless research hours, and resulted in me wasting time and resources debugging something that could have been easily solved with a code review.
  • It's okay to stand on the shoulders of giants
 In my research into the IR and sound sensors, I tried my hand at implementing the core pieces. It turns out that IR modulation is enough to be a separate project altogether, and don't even get my started on implementing an FFT. Odds are someone has already implemented the function you want, and their implementation is often going to be clean, fast, and reliable. Given time constraints, it may be better to use their libraries instead of trying to re-invent the wheel.