Updating the macros in Mindsensors NRLink

May 2008


I built a tracked rover that used two medium Power Function motors and I wanted to have both motors turn on simultaneously. But when I used the sample code provided by Mindsensors.com I discovered that I could only control one motor at a time. Time for some investigations, which led me to write new macros for the Power Function motors that allow both A and B channels to be controlled together using only one I2C bus message. I also show how you can update and load new macros into the NRLink-Nx directly using RobotC…

I read the NRLink-Nx manual from the mindsensors.com website, and I saw that I could add new macros into the EEPROM space starting at address 0xB0. The NRLink registers appear as memory mapped data space, so a write to a register address will store a byte at the address specified. The sendI2CMsg() routine will perform this task for me. So far so good, but what data to write?

For this I turned to the recently released “LEGO Power Functions RC” protocol specification released by the LEGO Group. I realized that the Combo direct mode was required to power both motors simultaneously. The macros provided by the mindsensors sample code only powered one motor at a time. Once I saw this it was a simple matter to write new macros using the bitmap given on page 7 of the specification document.

I wrote a simple installPFMacros() function to load my new macro opcodes into the NRLink-Nx. Each macro is represented as four values; the first byte is the address to load the macro at, the second is the length of the macro, and the final two bytes are the opcodes themselves, taken directly from the RC protocol document.



// Install additional power function macros into the NRLink that allow for

// simultaneously control of both attached motors



void installPFMacros() {

    int i, numPFmacros;

    nxtDisplayTextLine(2, “Writing macro”);
    numPFmacros = sizeof(powerFunctionsMacros);

    for(i=0; i < numPFmacros; i+=4) {
        // install macro into address
        sendI2CMessage(NRLinkPort,    // port the NRLink is connected to
            powerFunctionsMacros[i],   // register address to write the macro into
            powerFunctionsMacros[i+1], // number of bytes in the macro
            powerFunctionsMacros[i+2], // macro command
            powerFunctionsMacros[i+3]);// macro command

    nxtDisplayTextLine(3, “Done”);


The macros to load are stored in the powerFunctionsMacros[] array defined as follows. You can easily modify this array to add additional macros at any address. Note that the maximum addressable EEPROM in the NRLink is 256 bytes (address 0×00 - 0xff) and the macro definitions must be four bytes long each.

// extensions to the default macros loaded into the NRlink to

// allow for control of two motors simultaneously

const ubyte powerFunctionsMacros[] = {

  0xB0,  0x02,  0x01,  0x50, // Motor Ch1 A Forw B Forw

  0xB3,  0x02,  0x01,  0x90, // Motor Ch1 A Forw B Rev

  0xB6,  0x02,  0x01,  0x60, // Motor Ch1 A Rev B Forw

  0xB9,  0x02,  0x01,  0xa0, // Motor Ch1 A Rev B Rev

  0xBC,  0x02,  0x11,  0x50, // Motor Ch2 A Forw B Forw

  0xBF,  0x02,  0x11,  0x90, // Motor Ch2 A Forw B Rev

  0xC2,  0x02,  0x11,  0x60, // Motor Ch2 A Rev B Forw

  0xC5,  0x02,  0x11,  0xa0, // Motor Ch2 A Rev B Rev

  0xC8,  0x02,  0x21,  0x50, // Motor Ch3 A Forw B Forw

  0xCB,  0x02,  0x21,  0x90, // Motor Ch3 A Forw B Rev

  0xCE,  0x02,  0x21,  0x60, // Motor Ch3 A Rev B Forw

  0xD1,  0x02,  0x21,  0xa0, // Motor Ch3 A Rev B Rev

  0xD4,  0x02,  0x31,  0x50, // Motor Ch4 A Forw B Forw

  0xD7,  0x02,  0x31,  0x90, // Motor Ch4 A Forw B Rev

  0xDA,  0x02,  0x31,  0x60, // Motor Ch4 A Rev B Forw

  0xDD,  0x02,  0x31,  0xa0  // Motor Ch4 A Rev B Rev


Note: you have to set the sensorType to sensorI2CCustom9V to avoid bus errors when communicating with the NRLink. The TrackRover.c shows how this is applied in practice.

Last updated 23 May, 2008

All content © 2008 Mark Crosbie  mark@mastincrosbie.com

LEGO® is a trademark of the LEGO Group of companies which does not sponsor, authorize or endorse this site. This site, its owner and contents are in no way affiliated with or endorsed by the LEGO Group. For more please read the LEGO Fair Play policy.