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);
}
}
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.
Thank you
@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).
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)?
@mike
Yes, the program is mine.
this is very nice tool, Lego should do this. Question did you have to write out the program?
@Alexander
It’s larger, and I recommend Google for checking prices.
how much does it cost for the net brick, motors ect? and how heavy/large is the net motor compared to the pf xl?
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!
@NXT45
Nope.
Hi, I was wondering if you had the program in NXT-G.
@Ben
Use Google to find tutorials. There are plenty.
how do you make the program into nxt program language?
please contact me if you can tell me how to do it
So I see you did eventually work your way onto mindstorms
@edward dean
BRICKLINK.
where do you get all the pieces for the remote
@Sariel
thank you your reply
@teh_obag
I have no idea, I’m not touching the NXT-G.
can this program programed in NXT-G, and if yes can i get a seample? thank you! ๐
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.
@Stephen
Yeah, finally it worked. I copy/paste it before I released the mouse, then it worked.
@Emil
did you had any luck using the files on this site to use in Robotc?
@Emil
I’m afraid it’s rather difficult.
@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?
@Emil
Must be something wrong with your browser.
@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.
@Stephen
Yes I’ve also installed RobotC.
@Emil
i had the same problem but when i installed Robotc i could copy this. Did you installed Robotc?
@Emil
Yellow box, where, in your browser?
@Sariel
Yes I have already tried that ๐ There just show up a little yellow box, and then I can’t copy them.
@Emil
Did you try to:
1) mark them
2) copy them
3) paste them into a ROBOTC file?
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?
@Emil
thank you. This is very helpful. I’ll keep you informed. Again Thank you
@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.
@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.
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.
@Emil
I don’t know.
@Sariel
Hehe thank you ๐
If I use this converter cable (x1676) then I can control a power function motor with the nxt brick, right?
@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.
@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?
@Emil
You can, but IR Link sensor has nothing to do with it.
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
@Brian Dunphy
Um… there’s a ready-made function for that, check the ROBOTC documentation.
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?
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.
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
@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.
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?