NXT-G Code Snippets Index by Brian Davis When the NXT first came out, there was a lot of confusion about exactly how to program in NXT-G. As one of the folks privileged to test the initial software, I had a bit more experience than most and started posting screenshots of solutions to common problems. This is a simple index to these "code snippets". Some of these are out-of-date with new version of the software, obsolete, or very specific, but it can be helpful seeing how somebody else has approached a problem. If anyone has something specific they are confused about, please post your question to NXTasy.org or contact me - I won't write programs for you, but if I get enough requests for the same topic or subject I might draw something up. Here is the entire directory: NXT-G Code snippets And the index of descriptions: | ||
| ||
absmulti - taking the absolute value of a number. Prior to v2.0, there was no "native" way to get the absolute value of a number. Even if you don't need the abs(x) function, this explains how to wire in and out ("multiplex") of Switch structures, a very useful trick | ||
arrays - shows one way to use file operations to simulate a one dimensional array of numbers. Essentially opens a new file for each array element, doing all this manipulation inside two My Blocks, "shielding" it from the user. Very inefficient, but a handy implementation. | ||
arrayread-a & arrayread-b - Jason King's polymorphic arrays (two parts that go together). It turns out there are proper arrays under NXT-G, but so far "official" blocks to access them haven't been released. Jason King, one of the folks who did some of the original NXT-G programming, released some completely unofficial blocks to access this. It requires installing some updates to NXT-G, but it does show how arrays can work there. Useful if you really need arrays in NXT-G, or if you really want to see some of the power under the hood of the language. Note: Not officially supported, and there may be odd behaviors. | ||
atan - calculating an arctangent under integer-only math. Really an exercise in "how to do more work than you really should", this is one way to calculate a reasonable approximation for the atan(x) function, limited to just NXT-G and integer math under v1.0. While impractical for most application, it does show how fixed-point math can be done using integers, which is educational for those that think all numbers in computers have decimal places. | ||
qcos - calculates the cos(x) under integer-only math, using a numerical approximation. Again more math than anyone would probably want to do in NXT-G, but it shows one way of doing this, and works fairly well for when you need a trig function but don't want to install a custom block. Note that with the ability to do cos(x), sin(x) is just "a quadrant away"… | ||
average1 - calculating a simple average. Here a Loop is used to sum a number of sensor readings, and then ultimately divide that sum by the number of readings as a way to "smooth" the sensor readings. Useful for a lot of things, but this also talks about what gets "wired out" of a Loop (and why it's not always what you might think). | ||
average2 - performs what is properly called "exponential smoothing" of a continuous series of sensor readings. This is a special kind of "average" that is very handy because it can smooth data without all that summing, waiting, and "clumping" in the first example. The idea is that each new value modifies the last existing "average", so the entire history of the recent measurements is in the result… but how fast that "average" responds to new values can be fine-tuned. | ||
badloopexit & goodloopexit - ways to trigger out of a Loop. One of the frustrations many people seem to have is getting one sequence to trip a different sequence out of a Loop. The idea is simple, but the Loop never seems to "get the message" to stop. These two examples explain why, and more about what wires do when they cross Loop boundaries. | ||
dicemaster & diceslave - a simple Bluetooth messaging example. This pair of programs was drawn up when people started asking how to use the Bluetooth Send and Receive blocks. Just an example to show how messaging works. | ||
btrc & remote - a simple 2-NXT remote control system. "BTRC" (BlueTooth Remote Control) is the program that runs on the "remote control" NXT, translating movements of the three motors into numbers that are send to the "Remote" program on the receiver (an NXT vehicle usually). This is actually a rather simple example; I've got better ones that are faster, for instance, but this is the easiest to understand. Also uses My Blocks that convert the output of a v1.0 and v1.1 rotation sensor block (a positive number for position, and a logical value indicating direction) to a more "natural" signed integer representation… and back again. Demonstrates two-way communication as well. Images of the controller I use are on Brickshelf, and often the remote vehicle was JennToo, a very simple stable robot base. Alternative building instructions for both the remote & JennToo can be found at LEGOEdWest. | ||
southseeking & compassdrive - shows basic operation of the HiTechnic compass to control a vehicle. Southseeking tries to always orient a two-wheeled robot to "point south", although it shows how to do this before HiTechnic released an NXT-G block for their sensor. Instead it uses the US sensor block to read the compass, and interprets the returned information that way. The result is shown in a YouTube video NXT compass sensor on JennToo. Compassdrive shows an alternative way of keeping a heading, this time while moving forward; it generates an error signal that modifies the steering value for a Move block, continuously tuning the direction. | ||
countpresses & countclaps - simple ways to get numbers into the NXT. Countpresses just records the number of times the select button is pressed, with a long pause (anything over about 2 seconds) signaling when the user is done. Count_claps does the same thing with sounds, except it is set up as a My Block. Both of these examples use a "watchdog timer" to control the main loop, a useful technique in many situations. | ||
crowbar & crowbarpin - opening up a Loop to work within it. One common problem people run into is how to use parallel sequences inside a Loop or Switch, as these structures are usually just big enough to have the main sequence beam in them. A "Crowbar" is a way to pry these boundaries open enough to draw multiple parallel sequences inside them, allowing a lot more variation in what you can do. | ||
dazlr2 - the entire program for an early robot named DAZLR, which spun in place and fired Zamor spheres at any target it detected. Would find, center, shoot, and advance on the target (if needed), ending up back at the starting position and continuing to "watch for targets". A simple example of how to do a lot of different things. A video of this can be seen on YouTube: DAZLR in action, and building plans (a series of pictures) are up on Brickshelf. | ||
decimalmath - a quick example of how (almost!) to do division using integer math. This simple example gives some of the tricks, but I admit it's flawed (in doesn't keep leading zeros on the decimal part, so it only works about 9 times out of 10). Still, just shows an important factor in integer math: multiple before dividing. | ||
detectstall - runs a motor forward while watching to see if it "stalls" (is stopped from turning), stopping the motor at that point. Very useful for closing a mechanical "hand" when you don't know how big the object inside it is, for instance, and a lot of other things. | ||
twolimits & doublewait - one of the most common questions seems to be how to get the NXT to wait for "this or that" to happen. For instance, to drive forward until either a certain time had passed or the touch sensor was pressed. Twolimits is a simple solution for this sort of situation, showing that you can do it with a single sequence. Doublewait is a My Block implementation of the same idea, showing a bit of code that will wait for one of two conditions to be true, and then even return which event happened as a numerical code. | ||
dynamicswitch - normally when you "Switch on sensor", you have to enter the trigger value when you write the program; there is no way to "wire in" a trigger value from somewhere else in the program. You can get the same effect by using a sensor block and a "Switch on logic" | ||
easylog - prior to the Education v2.0, datalogging was not a built-in feature of NXT-G. But the idea is very simple to implement. Here is an example configured as a My Block that makes it very easy to record a series of timestamped values. While this is a simple example, "doing it yourself" actually works better in some ways than the built in function - you can log data faster, or longer, or in more complex ways, than with the stock datalogging environment of v2.0 Edu… and it's still really easy. | ||
fastswap - one thing that is difficult to get NXT-G to do properly is "preemptive multitasking"… like making a sumo robot execute a search routine, but then quickly "swap" to a different behavior if the edge of the ring is encountered. This is one way around that, called a "state machine". One sequence executes whatever sequence has been called for, while a second sequence can change that state rapidly if needed. This uses the timed motor control to your advantage. | ||
fileview - a series of three very brief programs that show how to write, read, and append to a file on the NXT, as well as use the File blocks' "error flag" to determine the number of elements in a file. | ||
getkey - a simple My Block that watches all three front panel buttons, waiting until one is pressed and reporting which button is pressed back to the calling program. This is useful for user input, and perhaps more importantly it shows a good way to design a My Block; one that makes it very easy to reuse and build upon, not one that works only in a few limited circumstances. | ||
scopetest - variables in NXT-G are all global; in other words, all variable blocks with the same name always references the same variable, in any sequence and any My Block in the program. This is an example of that. | ||
ghostvariables - variable definitions have some quirks in NXT-G. One of these is that variable blocks "ripped" into a My Block (that is, selected and then put into a My Block by clicking on the "=" tool button) will function just fine, but when you try to edit them or change them inside the My block you'll find they are "untouchable". This describes that problem, and the solutions. | ||
wiresarelocal - wires in NXT-G function very much like local variables that you can only write a value to once, but can read a value from multiple times. This shows one of the sometimes confusing aspects of that: the fact that the value a wire carries is the value of its source had at the time the wire left it, not the time the wire delivers its cargo "downstream". | ||
guard - a trivial example of wiring a number into a multi-tabbed Switch. In this case, it allows a random sound to be played when something is in front of the US sensor. | ||
irseeker - an example of using the HiTechnic IR Sensor to steer a robot towards a bright IR source (like a robosoccer ball, bright fire, etc.). | ||
linkedmotors - a Loop that "slaves" the C motor to the B motor on a single NXT. Move the B motor ten degrees by hand (or under program control, if you like), and the C motor will "copy" the move. The only problem is what happens under v1.0 or v1.1 if the motor "crosses through" the initial position… try it, it's interesting. | ||
loopcounter & loopvariable - it's easy to tell a Loop to execute a set number of times when you are programming it, but how to get it to run a certain number of times that the program can control is trickier; there is no "target loop count" plug on a Loop. This is easy to handle by comparing the Loop count to some value that is wired in, however, allowing a program to loop for a variable number of time. | ||
modulo - a simple modulo function under v1.0 & v1.1 (integer math blocks). The idea is to take two numbers, and divide one by the other to yield the remainder. Note that this only works this way because the division here is done on integers. | ||
multinxt_bt - a set of programs that networks four NXT together using BlueTooth. Here each "slave" NXT queues up messages to send back to the "master" which displays them, but at the time I originally did this (under v1.0) there were some messages dropped. I'm not sure what the status is now, but it's still a good first example of multi-NXT communication under NXT-G. Note: this uses the v1.0 "miniblocks" in place of stock Display blocks, but functions the same way. | ||
pfcontrol - a simple example of how to drive the PF system using the HiTechnic IRLink sensor and the PF Block. This uses a very early version of the block that does not have the ability to control the power level, but it does show the essentials - that the program needs to continuously send control messages to the IRLink, or the PF Receiver will shut down the motors. | ||
pivotbumper - a novel front bumper design originally suggested by Sivan Toledo, using a beam mounted on a motor; when the beam is pushed into the wall, it turns the motor, and the NXT can detect this, using the motor encoder as a sensor. This actually gives a lot more information than just "something bumped the front", and demonstrates that the motor encoders should be considered as sensors in their own right. | ||
radar - an example program that uses the trig functions to do a "radar plot" of the area around a robot like Jenntoo. As the robot spins, it uses the US sensor to detect the nearest object, and then draws a point at the corresponding spot on the LCD. | ||
randomwait - the Wait block can't have a time wired into it, limiting its use to only cases where the delay is known well in advance. There are a couple ways to do this, here's one where a tight Loop simple waits for a timer to match the value wired in. Here that time is chosen at random, and as another example of the Random block a tabbed switch on the bottom sequence is also driven by a Random block. | ||
waitforit - another example of a custom "wait block", this one built as a My Block so that it is transparent to the user; you can just wire in a timeinterval to wait, and the block does the rest for you, without tying up a timer. There's at least one other way to do this as well - wire a time interval to wait into a Sound block set to zero volume, and check "wait for completion" (as long as you don't want to play any other sounds during that time anyway). | ||
semaphore - sometimes you want two sequences to wait for each other, or synchronize, or one to pause at a certain point. You can do this by "semaphores", having the sequence check variables to see if they have been set to a certain value. In NXT-G, wires work very well in this capacity… especially because a block or structure will not start executing until all the wires leading into them have been validated (are initialized with the data they are to care). This is an example of using that property to synchronize two sequences. | ||
shadowrover - a simple program that allows an US sensor equipped robot to "shadow" a person, moving backwards or forwards to maintain a relatively constant distance from an object moving in front of it. | ||
singus - produces a theremin-like sound by converting the distance reported by the US sensor to a frequency and playing this as a sound. A nice way to instantly show how the US sensor works to a large group of people. | ||
soundmove - another example of multitasking in NXT-G. This starts by playing a sound, and continues playing that sound until another sound block stops it. Makes it very easy to have a continuous sound played while moving or doing other things without having the overhead of an entire separate sequence trying to do it. | ||
sqrt - performs an integer version of the square root function on a number using Herons method. Since it only deals with integers, it's not the actual square root, but it is fairly close. Useful with v1.0 and v1.1 | ||
twomethods - changing the direction that a motor drives in is tricky for some people, and a lot of folks try the first example, using a Switch structure to select from one of two different Motor or Move blocks. But this can be done very easily be remembering all the data plugs that you can take advantage of, as shown in the second example. | ||
ustest - a very old but useful "test" of the US sensor, with the robot moving at a steady pace while recording the distance reported. Useful to figure out if the US sensor is responding linearly, and at what distance an object suddenly stops being visible (due to not enough reflected sound energy). Also, a very basic datalogging experiment that you could complicate and expand on. | ||
zamortimer - an almost embarrassingly simple way to calculate how fast a Zamor sphere is launched. This does nothing more than measure the time between two sounds, the launching sound and the sound of the sphere hitting the floor when it falls back. By knowing the time of flight and using a little physics,it's easy to figure out how fast the sphere was originally going up (slightly faster than 4 meters/second). An example of thinking smart to make your work very simple. |