NXTI2C: a library for making the Arduino an I2C slave for the NXT. Download here.
Current version: V1.0
Here is a list of user-accessible functions included in the library (in the NXTI2CClass class):
- void Setup(byte = 0x02, char* = “Arduino”, char* = “V1.00″, char* = “Mt Allen”); Do all the setup work of making the Arduino an I2C slave. Optionally set the address, sensor name, version number, and manufacturer’s name. The address is in the format used by the NXT (7 msbs).
The following can all optionally be reset by passing a true value to them. If you do pass them a true value, they will read the value, reset it, and then return the value they did have.
- byte NewData(byte reset = false); A flag for indicating that data has been written to the register system. The flag is set to the value of the number of bytes written.
- byte NewComm(byte reset = false); A flag for indicating that there has been communication (read or write). It is either true of false.
- byte Command(byte reset = false); A flag for indicating that there has been a command issued. The value is set to the last command received.
- unsigned long LastActivity(byte reset = false); Returns the number of milliseconds since the last I2C activity (read or write).
- unsigned long LastWrite (byte reset = false); Returns the number of milliseconds since the last I2C write.
- unsigned long LastRead (byte reset = false); Returns the number of milliseconds since the last I2C read.
- unsigned long LastCommand (byte reset = false); Returns the number of milliseconds since the last I2C command.
There is a public byte array called “I2CBuf” that you can access from the user-code on the Arduino as the I2C register system.
The I2C master must always send the address, register, and count (number of user-bytes), for all messages (read and write). So there are three bytes of overhead instead of the typical 2 bytes.
I dis-allowed the master from over-writing registers 0x00-0x17 (version number, manufacturer’s name, and sensor type), as well as the command register (0x41). However, the Arduino user-program can over-write these registers.
PFIR: a library for making the Arduino a Lego Power Functions controller. Download here.
Current version: V1.0
I’m not sure what wavelength of IR is recommended, but I have been using a 940nm IR LED without any problems.
Resources that cannot be used for other purposes:
– D12 (Digital IO pin number 12)
– Timer 1
You can change the digital IO pin that controls the IR LED, from 12, to any other pin that supports output. All you need to do is redefine PFIR_LED in the PFIR.h file.
Here is a list of user-accessible functions included in the library:
- void SetPermissions(byte = NA, byte = NA, byte = NA, byte = NA, byte = NA, byte = NA); Set the individual bits of the ActiveChannel byte. Pass a true to set the bit to 1. Pass a false to set the bit to 0. Pass NA to leave that bit alone. All parameters default to NA.
- byte SendingEnabled(byte = NA); Enable/Disable sending IR messages. Pass a true to enable, or a false to disable. If disabled, the Arduino will finish sending the message it is currently sending, and then stop immediately after. If you don’t pass it a value, it will return true if sending is enabled, or false if sending is disabled.
- void SendMessage(byte, byte, byte, byte = true); Send a Power Functions message. The parameters are as follows: Nibble 1, Nibble 2, Nibble 3, and optionally a parameter for enabling the Arduino to send to the channel (defaults to true).
You can also directly access the “ActiveChannel” byte from the user-code. This is useful if you want to read the states of the bits, or mass set them to e.g. 0x00.
The bits of ActiveChannel are used for permissions as following (copied from the .h file):
#define MASK_CH_EN_1 0x01 // Bit mask for enabled channel 1 #define MASK_CH_EN_2 0x02 // '' 2 #define MASK_CH_EN_3 0x04 // '' 3 #define MASK_CH_EN_4 0x08 // '' 4 #define MASK_COMP_CON 0x10 // Mask for the bit that means I have complete control of all IR. #define MASK_FAST_OFF 0x20 // Mask for really short blank messages.
If you don’t care about any other IR communications within range, you can set bits COMP_CON and FAST_OFF of ActiveChannel to true. However, the Arduino will send messages so rapidly that I doubt any other IR signals could be used within the range of the IR LED. Setting those bits to true would greatly decrease the time from issuing a message (using SendMessage), until the PF Receiver responds.
Any time you want to stop transmitting to a certain PF channel, you can simply set the appropriate CH_EN bit of ActiveChannel to 0. When the FAST_OFF bit is set, leaving an unused channel transmitting will use time in the cycle, and significantly reduce the update rate of the channels you want to be transmitting on.
Basically for greatest update speed, only leave the CH_EN bits set for the channels that must be sent to, and set COMP_CON and FAST_OFF to true. Doing so makes a significant difference in update performance.
When I designed the transmitting characteristics of the program, I tried to pretty much follow the specs provided by TLG. However, there are many things I didn’t completely adhere to, for the sake of simplicity and speed. Setting COMP_CON or FAST_OFF to true will make the Arduino totally dis-regard some of the timing characteristics specified by TLG.
I have not implemented the Toggle bit of Nibble 1, but the receiver does not verify it in either “Combo direct” or “Combo PWM” mode. According to documentation by TLG, the PF Receiver does verify the Toggle bit for all other modes, so only expect these two modes to work with this version of the library.
I can only create a limited number of scenarios for testing my libraries, so please contact me with any issues you find.