Home > Ideas, Mindstorms > NXT Brick-to-Brick Remote

NXT Brick-to-Brick Remote

My second LEGO Mindstorms NXT MOC. Features a Bluetooth remote that controls motors connected to another brick with a speed control and a proportional steering. Β 

Datasheet:

Completion date: 03/03/2012
Power: electric (NXT brick)
Language: ROBOTC
Bricks: 2
Motors: 5 x NXT motor
Sensors: 2 x touch

One of the most interesting features of the NXT brick is that it can create a two-way Bluetooth link with another brick, which is in every way superior to IR link. I wanted to take advantage of this feature by creating a very simple, basic remote allowing to control motors connected to a brick inside a MOC with another brick. The remote was intended for typical wheeled vehicle, hence the drive control with a speed control feature and a proportional steering.

The actual remote is fairly simple, using two NXT motors and two touch sensors. Step-by-step instruction for building it can be found below. In order to work, it requires two-part program: one part is run on the sender brick, and another on the receiver brick. Note that for the bricks to create a Bluetooth link, they need to be first linked manually so that they keep each other in their Bluetooth contact list.

The drive motor, connected to receiver brick’s A port, Β can be controlled with a speed control feature by rotating the knob on the remote’s left motor. Note that the movement of the knob is limited mechanically, thanks to which the programs are simpler. There is an option to make the receiver brick beep while on reverse, just like some trucks beep. Note that this is part of the program’s configuration, which is included entirely in the receiver part. Also note that the volume of the receiver brick can be changed remotely by using arrow buttons on the remote.

The steering motor, connected to receiver brick’s B port, is controlled proportionally, meaning that it’s synchronized with the steering wheel and it maintains the same angle. The steering wheel’s movement is also mechanically limited for simplicity. Note that the margin of 10 degrees is defined in the receiver’s configuration to avoid problems with motors’ inertia which are inevitable when the accuracy of synchronization is too high. Such a situation can lead to the receiver’s steering motor going forward and back endlessly, because it has too much inertia to stop exactly at the desired angle.

Finally the additional motor, connected to receiver brick’s C port is controlled by pressing and holding one of the two touch sensors.

Note that the orange button on the sender brick enables and disables sending of the data. This function is initially disabled when program starts, so that the position of the remote’s controls can be adjusted without affecting the receiver brick. Also note that upon disabling, the remote resets all values except volume, meaning that it stops all motors and returns the steering motor to center. However, once enabled, it will sends again the current values, making the receiver’s motors react accordingly. For example the steering motor is synchronized back, meaning that it moves from the central position to the current position of the steering wheel.

Finally, note that the first line of the remote’s display shows current voltage of remote’s and receiver’s battery, allowing to monitor if either of the two bricks is running low on power. The sender program can be aborted by pressing the sender brick’s default exit button twice.

Sender program:

#pragma config(Sensor,S1,touch1,sensorTouch)
#pragma config(Sensor,S2,touch2,sensorTouch)

bool sending = false;
int soundLevel = 1;

task BatLev()
{
  ubyte valueReceived[1];
  valueReceived[0] = 0;
  while(true)
  {
    cCmdMessageRead(valueReceived, 1, 1);
    nxtDisplayCenteredTextLine(0, "BAT: L%3.1f / R%3.1f", nImmediateBatteryLevel / (float) 1000, valueReceived[0] / (float) 10);
    wait1Msec(50);
  }
  return;
}

task Buttons()
{
  nNxtButtonTask  = -2;
  nNxtExitClicks = 2;
  nxtDisplayCenteredTextLine(1, "Not sending...");
  while(true)
  {
    if(nNxtButtonPressed == 3)
    {
      PlaySound(soundBeepBeep);
      if(sending == false){
        sending = true;
        nxtDisplayCenteredTextLine(1, "Sending...");
      }
      else{
        sending = false;
        ubyte valueToReset[5];
        valueToReset[0] = 0;
        valueToReset[1] = 0;
        valueToReset[2] = 0;
        valueToReset[3] = 0;
        valueToReset[4] = soundLevel;
        cCmdMessageWriteToBluetooth(valueToReset, 5, 1);
        nxtDisplayCenteredTextLine(1, "Not sending...");
      }
    }
    else if (nNxtButtonPressed == 1 && soundLevel < 3) soundLevel = soundLevel + 1;
    else if (nNxtButtonPressed == 2 && soundLevel > 0) soundLevel = soundLevel - 1;
  wait1Msec(350);
  }
}

task main()
{
  StartTask(BatLev);
  StartTask(Buttons);
  bFloatDuringInactiveMotorPWM = true;
  btConnect(1, "NXT2"); // connection: port, brick
  while(true)
  {
    ubyte valueToSend[5];
    valueToSend[0] = nMotorEncoder[motorA];
    valueToSend[1] = nMotorEncoder[motorB];
    valueToSend[2] = SensorValue(touch1);
    valueToSend[3] = SensorValue(touch2);
    valueToSend[4] = soundLevel;
    if(sending == true){cCmdMessageWriteToBluetooth(valueToSend, 5, 1);}
    nxtDisplayTextLine(3, "Drive: %d", valueToSend[0]);
    nxtDisplayTextLine(4, "Steering: %d", valueToSend[1]);
    nxtDisplayTextLine(5, "Touch BLUE: %d", valueToSend[2]);
    nxtDisplayTextLine(6, "Touch RED: %d", valueToSend[3]);
    nxtDisplayTextLine(7, "Volume: %d", valueToSend[4]);
    wait1Msec(50);
  }
}
									

Receiver program:

// config start
//bMotorReflected[motorA] = true;
//bMotorReflected[motorB] = true;
//bMotorReflected[motorC] = true;
bool buzzOnRev = true; // buzzing while on reverse
int steerAcc = 10; // steering accuracy margin (degrees)
// config end

task BatLev()
{
  while(true)
  {
    nxtDisplayCenteredTextLine(0, "BAT: L %3.1fV", nImmediateBatteryLevel / (float) 1000);
    ubyte valueToSend[1];
    valueToSend[0] = nImmediateBatteryLevel / (float) 100;
    cCmdMessageWriteToBluetooth(valueToSend, 1, 1);
    wait1Msec(50);
  }
  return;
}

task main()
{
  StartTask(BatLev);
  nVolume = 1; // starting volume
  ubyte valueReceived[5];
  valueReceived[0] = 0;
  valueReceived[1] = 0;
  valueReceived[2] = 0;
  valueReceived[3] = 0;
  valueReceived[4] = 1;

  while(true)
  {
    cCmdMessageRead(valueReceived, 5, 1);
    nxtDisplayTextLine(2, "Drive: %d", valueReceived[0]);
    nxtDisplayTextLine(3, "Steering: %d", valueReceived[1]);
    nxtDisplayTextLine(4, "Touch BLUE: %d", valueReceived[2]);
    nxtDisplayTextLine(5, "Touch RED: %d", valueReceived[3]);
    nxtDisplayTextLine(6, "Volume: %d", valueReceived[4]);
    nVolume = valueReceived[4];

    // motorA (drive)
    motor[motorA] = 0;
    int afactor = valueReceived[0] / 5;
    if (afactor > 1 && afactor < 15)
    {
      afactor = afactor * 10;
      if (afactor > 100) afactor = 100;
      motor[motorA] = afactor;
      if (buzzOnRev == true) ClearSounds();
    }
    else if (afactor > 1 && afactor > 25)
    {
      afactor = (51 - afactor) * -10;
      if (afactor < -100) afactor = -100;
      motor[motorA] = afactor;
      if (buzzOnRev == true) PlaySound(soundException);
    }

    // motorB (steering)
    motor[motorB] = 0;
    int bfactor = valueReceived[1];
    if (bfactor > 1 && bfactor < 75) bfactor = bfactor;
    else if (bfactor > 1 && bfactor > 75) bfactor = (256 - bfactor) * -1;
    nxtDisplayTextLine(7,"Mtr B: %d/%d",nMotorEncoder[motorB], bfactor);

    if (nMotorEncoder[motorB] < (bfactor + steerAcc)) while(nMotorEncoder[motorB] < bfactor) motor[motorB] = 10;
    else if (nMotorEncoder[motorB] > (bfactor - steerAcc)) while(nMotorEncoder[motorB] > bfactor) motor[motorB] = -10;
    else motor[motorB] = 0;

    // motorC
    motor[motorC] = 0;
    if (valueReceived[2] == 1) motor[motorC] = 100;
    else if (valueReceived[3] == 1)motor[motorC] = -100;

    wait1Msec(50);
  }
}
									

Photos:

1.png 2.png 3.jpg howto_1.png howto_2.png howto_3.png howto_4.png howto_5.png howto_6.png howto_7.png

Video:

Categories: Ideas, Mindstorms Tags:
  1. EV3fan
    December 14th, 2014 at 18:11 | #1

    I’ts a shame a gyro sensr isn’t within the NXT 2.0 set, because otherwise you could build a virtual steering wheel which you just tilt.

  2. mike
    July 9th, 2014 at 16:08 | #2

    Thank you

  3. Sariel
    July 9th, 2014 at 09:22 | #3

    @mike
    1. RobotC. That’s why it says “RobotC” in the description, you know.
    2. http://tinyurl.com/ovblup4
    3. What instructions?
    4. I don’t have the new brick. But it seems RobotC does not officially support it yet (beta tests are ongoing).

  4. mike
    July 9th, 2014 at 01:22 | #4

    I have a few question:
    1. what program did you use?
    2. how did you upload it to the brick?
    3. what were the building instructions?
    4. how reliable is it (does it work with the new brick)?

  5. Sariel
    July 8th, 2014 at 22:25 | #5

    @mike
    Yes, the program is mine.

  6. mike
    July 8th, 2014 at 20:50 | #6

    this is very nice tool, Lego should do this. Question did you have to write out the program?

  7. Sariel
    January 24th, 2014 at 21:32 | #7

    @Alexander
    It’s larger, and I recommend Google for checking prices.

  8. Alexander
    January 24th, 2014 at 19:39 | #8

    how much does it cost for the net brick, motors ect? and how heavy/large is the net motor compared to the pf xl?

  9. Eli
    May 25th, 2013 at 17:56 | #9

    Hey Sariel, Thanks for posting this. You are literally a lifesaver. I needed to figure out how to make a remote control soccer playing robot and this program helped me understand it and I based my program off of it. Thanks!

  10. Sariel
    January 21st, 2013 at 18:50 | #10

    @NXT45
    Nope.

  11. NXT45
    January 21st, 2013 at 18:11 | #11

    Hi, I was wondering if you had the program in NXT-G.

  12. Sariel
    August 15th, 2012 at 10:57 | #12

    @Ben
    Use Google to find tutorials. There are plenty.

  13. Ben
    August 15th, 2012 at 10:32 | #13

    how do you make the program into nxt program language?
    please contact me if you can tell me how to do it

  14. July 21st, 2012 at 17:20 | #14

    So I see you did eventually work your way onto mindstorms

  15. Sariel
    July 16th, 2012 at 23:42 | #15

    @edward dean
    BRICKLINK.

  16. edward dean
    July 16th, 2012 at 23:23 | #16

    where do you get all the pieces for the remote

  17. teh_obag
    July 2nd, 2012 at 11:07 | #17

    @Sariel
    thank you your reply

  18. Sariel
    July 2nd, 2012 at 10:48 | #18

    @teh_obag
    I have no idea, I’m not touching the NXT-G.

  19. teh_obag
    July 2nd, 2012 at 09:34 | #19

    can this program programed in NXT-G, and if yes can i get a seample? thank you! πŸ™‚

  20. arjan
    March 20th, 2012 at 20:12 | #20

    Sariel,
    One day you will be stuck with the fact that you can only use 3 motors with your nxt set.
    You probably want to grab and lift something, but you realize that you normally need 4 motors for that. This will maybe solve you problem by then: http://www.youtube.com/watch?v=YFp8d_zWYkc
    I think many nxt users will like it, because it allows you to grab and lift things with a single motor.

  21. Emil
    March 19th, 2012 at 20:56 | #21

    @Stephen
    Yeah, finally it worked. I copy/paste it before I released the mouse, then it worked.

  22. Stephen
    March 19th, 2012 at 18:47 | #22

    @Emil
    did you had any luck using the files on this site to use in Robotc?

  23. Sariel
    March 17th, 2012 at 00:12 | #23

    @Emil
    I’m afraid it’s rather difficult.

  24. Emil
    March 16th, 2012 at 23:21 | #24

    @Sariel
    I’ve tried with both Firefox and Explorer at two different computers. Are you able to put them at your site, so I can download them?

  25. Sariel
    March 16th, 2012 at 22:58 | #25

    @Emil
    Must be something wrong with your browser.

  26. Emil
    March 16th, 2012 at 20:37 | #26

    @Sariel
    Yes, just a little yellow box in my browser when I try to copy it. It’s pretty crazy. I’ve even tried at two different computers.

  27. Emil
    March 16th, 2012 at 17:23 | #27

    @Stephen
    Yes I’ve also installed RobotC.

  28. Stephen
    March 16th, 2012 at 17:18 | #28

    @Emil
    i had the same problem but when i installed Robotc i could copy this. Did you installed Robotc?

  29. Sariel
    March 16th, 2012 at 16:58 | #29

    @Emil
    Yellow box, where, in your browser?

  30. Emil
    March 16th, 2012 at 16:57 | #30

    @Sariel
    Yes I have already tried that πŸ™‚ There just show up a little yellow box, and then I can’t copy them.

  31. Sariel
    March 16th, 2012 at 16:46 | #31

    @Emil
    Did you try to:
    1) mark them
    2) copy them
    3) paste them into a ROBOTC file?

  32. Emil
    March 16th, 2012 at 16:41 | #32

    Hello Sariel,

    Will you be able to post the sender and receiver program as files, because I’m not able not copy any of them?

  33. Stephen
    March 15th, 2012 at 10:41 | #33

    @Emil
    thank you. This is very helpful. I’ll keep you informed. Again Thank you

  34. Emil
    March 15th, 2012 at 09:43 | #34

    @Stephen
    Hello Stephen

    I were thinking at the same, and I found this site: http://www.robotc.net/teachingmindstorms/setup/documents/firmware.pdf

    I think it’s pretty good.

  35. Sariel
    March 14th, 2012 at 19:48 | #35

    @Stephen
    Thanks, but to do that you need to learn ROBOTC. And there are websites dedicates specifically for teaching it, which you can find very easily.

  36. Stephen
    March 14th, 2012 at 17:46 | #36

    Hello,

    maybe a stupid question because i don’t know much about NXT and all the things around it but i’m learning.
    How do you get the program you wrote into the NXT sender and reciever?
    Like i said, i’m learning. Thnaks..Nice job by the way…I’m watching your site for a while now and you make some awesome stuff.

  37. Sariel
    March 12th, 2012 at 22:41 | #37

    @Emil
    I don’t know.

  38. Emil
    March 12th, 2012 at 21:53 | #38

    @Sariel
    Hehe thank you πŸ™‚
    If I use this converter cable (x1676) then I can control a power function motor with the nxt brick, right?

  39. Sariel
    March 12th, 2012 at 15:28 | #39

    @Emil
    You know, it’s not a secret what the IR link does. It takes 3 seconds of using Google to find: http://www.hitechnic.com/cgi-bin/commerce.cgi?preadd=action&key=NIL1046
    And no, my program works with 2 motors & 2 touch sensors in the sender and 3 motors in receiver, just like you see in the video.

  40. Emil
    March 12th, 2012 at 14:42 | #40

    @Sariel
    Okay thank you for the answer. What does the IR Link sensor then do? If I install the program you have made (sender and receiver program) at my nxt bricks, can I then use 3 motors to control 3 other motors? Or do I then need another program?

  41. Sariel
    March 12th, 2012 at 14:07 | #41

    @Emil
    You can, but IR Link sensor has nothing to do with it.

  42. Emil
    March 12th, 2012 at 13:35 | #42

    Hello Sariel,

    At Facebook there is a picture with a HiTechnic IR Link sensor at (posted the 4th March). So my questions is: If I have 6 nxt motors and 2 nxt bricks, can I then control the one nxt brick where there a connected 3 motors to with the other nxt brick where there also are connected 3 motors to?

    I hope you understand my question πŸ™‚

    Regards,
    Emil

  43. Sariel
    March 10th, 2012 at 20:48 | #43

    @Brian Dunphy
    Um… there’s a ready-made function for that, check the ROBOTC documentation.

  44. March 10th, 2012 at 18:58 | #44

    This is amazing, I’ve been trying to do this for a year but the nxt software is too derp for it, I’ve built a 4×4 to use with this with a gearbox that I need to control, how would I go about getting the motors to turn 90 degrees and stop?

  45. arjan
    March 4th, 2012 at 20:19 | #45

    I like the idea, it would be nice if you can make it bigger. For example with a hailfire droid wheel, as the steering wheel and a big lever/gas pedal, for the throttle. If you can make a table clamp, and use your live feed cam. You can drive around your house, and bully your hamster. Or you can design something to upgrade it to a force feedback wheel.
    I’ve spent much money on a force feedback wheel, but now that i’m thinking off it, it was better when i bought 2 nxt- sets instead of the wheel.

  46. Oil
    March 3rd, 2012 at 22:42 | #46

    Awsome, Shame the nXT brick is so bulky it looks a bit tedious to hold.hope to see you improve this.

    Can’t wait 2 C it in a proper moc

  47. Sariel
    March 3rd, 2012 at 18:32 | #47

    @David Luders
    Yes, obviously. Actually, if you look closely at some trial trucks here in Poland, some of them have been using this kind of solution for quite a while.

  48. David Luders
    March 3rd, 2012 at 18:27 | #48

    This is very useful! Do you think that if one built this into a Lego Trial Truck, one could control it outdoors (in bright sunshine) easier than using a Power Functions remote? Is there enough room (and battery power) in a vehicle to accommodate the oversized NXT motors?

  1. No trackbacks yet.