Sunday, September 22, 2013

Week 6: NXT Sensor Data Spec

As I'm still waiting on the NXT, I went ahead and did some reading into how Lego currently communicates with their digital sensors. As we can directly control the I2C link we can implement the communications protocol however we want, but it's probably good to learn how it's performed as it is now.

Briefly summarizing what I learned, the Lego spec adheres to the master-slave rule that I2C normally operates with. The slaves will sit idly on the bus lines, happily processing whatever input they deal with. They will continue to do this until the NXT polls them for data, at which point they reply over I2C with a packet containing the relevant data. They then continue on without much pause. Now the interesting twist to this routine is that the digital sensors are capable of storing and receiving multiple data values.

To clarify, each sensor is responsible for maintaining a local bank of I2C accessible registers. These registers are updated with whatever data is relevant to the process that a particular sensor is performing. For example in a compass sensor, the sensor itself keeps a particular register updated with the current heading. When the NXT polls the compass, it will specify that register in its data request packet, at which point the sensor retrieves the register value and transmits it back to the NXT.

Fig 1. Simple visualization of the register bank concept.
This is interesting because it opens the possibility for multiple data values to be processed by a particular sensor, while still keeping them accessible from the NXT. Particularly in our case, we could fold multiple sensor functions into our Arduino, and still only require one I2C line to return all of them. This also opens the possibility of bidirectional communication, allowing the NXT to send messages to the sensor to be processed. These could be configuration values, or they could be commands. For example the NXT could signal a particular color to be turned on in an LED strip, or the SSID to search for in a WiFi module.

A quick aside: just to make sure the ChipKit is working I uploaded some basic Arduino example programs to the ChipKit, everything seems to be fully compatible.

Idea: Wireless sensor capacity is possible, by linking an Arduino to the output of an I2C line as we're doing now. However instead of the sensor being locally attached, the Arduino can wirelessly interface through an XBee or WiFly controller, or even a Spark Core.

Sunday, September 15, 2013

Week 5: Doldrums

I'm still waiting NXT hardware, and so there isn't too much to report on this week. I'll keep it short: while I have the interconnect between the NXT and ChipKit laid out, I ran into the issue of not being sure how I'm actually going to physically connect the two together. It is possible to simply take a sensor cable and cannibalize it to expose the necessary outputs, and in all likelihood what I'll do for my purposes, however making a bunch of these connectors for classroom use is probably going to be a hassle and less reliable than a more...manufactured approach. Ideally I feel an RJ12 breakout would be the most suitable option, especially given that the class will implement any custom sensors on a breadboard.

To be completely honest I spent a good deal of time experimenting with EAGLE-CAD fashioning a connector to attach directly to the ChipKit. However for the sake of usable results here is a link to an open-sourced NXT connector breakout kit, with assembly available for an extra cost.

https://store.wayneandlayne.com/products/bricktronics-breakout-board.html

Sunday, September 8, 2013

Week 4: Software-side of the I2C communication

I haven't received the NXT for experimentation yet, and I apologize the next few entries may be somewhat short. In the meantime I've been covering some ground on how the software will implement I2C communication between the NXT and ChipKit.

Looking into the ChipKit, it appears that when they say "Arduino Compatible", they really mean Arduino-022 compatible. I'm not going to be sure if this is an issue until I test on hardware, but I just want to note that Arduino-022 and the related libraries are very much out of date. As of late 2011, the Arduino Foundation has released the much newer Arduino v1.0, and all library development has migrated to support that codebase. As many of the v1.0 core libraries are not backwards compatible with Arduino-022, I'm going to have to rely upon the older libraries. I'm not entirely sure what this spells for documentation purposes.

In particular, the library needed will be the Arduino Wire library. This is the Arduino library responsible for managing any hardware I2C function, and while it is possible to bitbang the communication in software, I'd rather stick with what is established. The Arduino Wire library is very straightforward, requiring the device to be initialized with an I2C bus address and communication interrupt handlers during the init() function. I'll explore this part later when I begin coding the ChipKit side.

On the NXT side, the RobotC API exposes two functions for handling I2C access. They are 'sendI2CMsg' and 'readI2CReply' respectively. The I2C send is fairly self explanatory, it will send a message packet on a particular sensor line (remember there are 4) to a particular I2C address. The readI2CReply will send a data request packet across the bus to a specified address, then proceed to receive a user-program specified number of bytes as a response. I will explore this in further detail once I begin NXT coding.

As an aside, I want to make note of an irregularity with the way the NXT handles I2C addressing. The Arduino must be initialized with a particular bus address, it can be anything but I2C only provides 7-bits of addressing so keep to that range. The NXT must be initialized with the same address so it knows where to address the packets it sends on the sensor data line. Even though the NXT and Arduino are directly connected, they are still operating with I2C and thus use address-based communication. However... the address provided to the NXT in RobotC must first be bitshifted left by 1 bit!!!! For example this makes an Arduino I2C address of 0x0A into 0x14, and so on the NXT side all packets will be addressed to 0x14, while the Wire library on the Arduino must be provided with 0x0A. I'm not sure why this irregularity exists, but I'm rolling with it.

Another aside: It should be possible to daisy chain multiple sensor devices off a single port due to I2C being a bus. I'm not going to explore this, but it's an interesting idea.

Also below is the link to the RobotC NXT API, which contains documentation for all NXT-related functions provided by RobotC.

RobotC NXT API:

http://www.robotc.net/support/nxt/MindstormsWebHelp/index.htm#page=nxt_functions/Sensors_Digital/Sensor%20Digital.htm

Sunday, September 1, 2013

Week 3: Examining the I2C Option

Now that I know I'm going to be communicating with I2C, I feel that a quick refresher is in order...more for my benefit if anything.

To briefly sum everything up, I2C (Inter Integrated Circuit) is a bus protocol that facilitates communication between embedded electronic components. The hardware side specifies a two-wire system, consisting of an SDA line (Serial Data) and an SCL line (Serial Clock), both pulled up to whatever logic level is used. All devices on the bus are connected to these two lines, and all communication occurs when a designated 'master' device initiates comms. As the protocol (and our implementation) has it, the master is the only device that can initiate communications, the slaves are entirely reactive.

Fig 1. Example I2C configuration from Wikipedia.

In our system the NXT is the obvious choice to be the bus master. The way I envision the system working has the Arduino independently operating separate from the NXT as an I2C slave, to be polled for info when it is needed. The systems will obviously need to be connected, and thus I researched the pinouts for the NXT's sensor jacks. The lines very neatly expose the SDA/SCL lines in addition to Vdd and an AREF signal (GND). Given that the Arduino operates on a 5V logic level, the lines need to be pulled up with specific resistor values. Going off the suggestion of a site I found (link below), I am proceeding with 82K resistors. After all is said and done, we are left with the connection detailed below.

Fig 2. Basic I2C connection between NXT and Arduino.
One possible issue which may be apparent in the above schematic is that the NXT provides 4.3 volts in its sensor lines. This may be an issue if the Arduino is picky about its logic level voltages, however I am of the opinion that the I2C facilities (and the Wire library) of the Arduino are capable of operating with such voltages.

It bears mentioning that I do not have the full suite of hardware yet, and am thus still in the planning stages. Until I receive all the necessary equipment, the next few posts may be somewhat sparse. In the meantime though I have a pretty monumental decision to make regarding the dev environment for the NXT. The main contenders are LabView for Mindstorms which operates using the graphical language NXT-G, or RobotC which utilizes traditional C. Having taken ECE 1882 I know how painful it is to use LabView on the NXT, and that I despise it with all my soul. Thus my completely unbiased and scientifically formulated conclusion is that RobotC be used at all costs.


Resource website with NXT-Arduino info, a good deal of my work is derived from here:
http://www.dexterindustries.com/howto/connect-the-arduino-and-the-lego-mindstorms-together/