PriNXT – Mindstorms NXT Printer

24 02 2012

All finished! It took a bit longer than expected (I’ve been tinkering around with some final upgrades and fine tuning for the past few days), but now, at last, it’s working! Check out this video I shot of PriNXT (clever name, I know) yesterday when it was drawing the epically awesome WilsonTech1:

Since this is a pretty long post, I’ve split it up into a few sections for you: Hardware/ Design, Image Processing, Programming, and Conclusion. How considerate of me.

Hardware/ Design – Motors

PriNXT has three motors: two control the X and Y motion, and the third lifts the pen.

The first motor, the one in the middle, is very straight forward – it has two long axes coming out of it that connect to two tiny gears that can drive around on a series of gear racks, moving the contraption about the Y axis. The second and third motor are a bit more complex, since they both point inward and have to move their power around a lot.

The left one, which controls motion on the X axis, basically just gears its power to a really long row of worm wheels, which, when spun, slowly move the part that holds the pen from left to right. The third motor similarly transfers its power to the outside, after which it moves a long rod up and down, pulling the pen along with it no matter where it is. For more details, see PriNXT’s very own Hardware Post.

Hardware/ Design – Sensors

The robot has a total of four sensors: two touch, one light, and one color.

The touch sensors serve the simple purpose to calibrate the robot – it blindly drives towards them until it registers that they’re pressed, which tells PriNXT where to start drawing. The color sensor is used as a signal light to show that the robot has finished calibrating.

The light sensor, only added two days ago, is used for moving the pen, which has actually been one of the hardest parts of this project. Because the beam that moves the pen up and down is slightly flexible, it had to be slightly higher or lower depending on how far to the right the pen was. When the pen would move, this would cause conflicts, so now, instead of being static, the pen now continuously moves up and down a bit to compensate for this movement. The light sensor guides it in this, reading its position and telling it to either go higher or lower.

For the design part, I mostly kept this project in my usual red/ white/ shades of gray color scheme, which I’m actually starting to enjoy using more and more.

Image Processing

A big part of PriNXT was to get it to draw complex shapes and pictures like the one in the picture below.

So this is how it works: first, I import the image into Paint.NET, where I make it black and white, and then edit it a bit to get a better looking result. Then, I export it as a .PBM file, which basically turns the whole picture into a bunch of 1′s and 0′s. Then, I import those 1′s and 0′s into NotePad++, where I reformat them to something my program will understand. Finally, I copy the results into a pre-made array in RobotC, fill in the height and width of gthe image, and I’m done!

For a more detailed description on how to do this, and on how to use this method to display detailed images on your NXT, see this post here: How To: Display Images on Your NXT using RobotC (JPEG, PNG, etc.)

Programming

Mostly, the code for PriNXT consists of the following (in order):

  • Calibration functions for the X and Y motors, which basically drive them both backwards until they hit their respective touch sensors, and then reset their encoders
  • A “moveLinear” function, which very niftily calculates the amount of degrees needed to get to the user specified position, and then calculates speeds for both that allow it to go there in a straight line (if one motor has to move a lot more than the other motor, the other motor slows itself down to help it keep up)
  • A “movePen” function, which.. moves the pen up and down
  • A “drawBinaryImage” function, which draws the image according to the 1′s and 0′s I copy into its 2D “imageToDraw” array using two for loops, one inside the other
  • A “controlPen” task, which keeps the pen at the right height even when the “movePen” function is not called
  • The main task, which controls the rest
Here’s a link to the program: PriNXT.c (SF Code Download)

Conclusion

So yeah, I really enjoyed doing this project, even if it was challenging at times. For even moar pictures and other stuff my robot printed, check out my Google Plus profile (heck, you could even circle me)

And yes, it also drew the text in the header. Go ahead, scroll up and take a look at it :)





How To: Display Images on Your NXT using RobotC (JPEG, PNG, etc.)

18 02 2012

First of all, let me say that people have found various ways to do this, and that this might not be the easiest way. A big benefit, though, is that the image data you end up getting is very easily accessible and manipulable. Also, this works with *a lot* of image formats, including JPEG, JPG, PNG, BMP, and others. Anyhow, let’s get started, shall we?

What you need

  • A MindStorms NXT intelligent brick
  • RobotC
  • Paint.NET, a free image creation/ editing software which you’re going to use to create your image, with this plugin [LINK] installed. Don’t know how to install Paint.NET plugins? Refer to this page here [LINK].

Step 1: Creating or Importing your image

For creating your own image: open Paint.NET, click the “Image” menu, and then open the “Canvas size…” option. In the wizard, specify any image size, up to 100 pixels wide and 64 pixels high. Then use the pencil or any of the other tools to create your image.

For importing an image: open Paint.NET, click “open,” navigate to the desired image, and double click it. Then, go to the “Image” menu, open the “Image size…” option, and, in the wizard, specify any image size, up to 100 pixels wide and 65 pixels high.

Step 2: Making your image black and white

First, open the “Adjustments” menu and click “Black and White.” Then, again in the “Adjustments” menu, open “Brightness/ Contrast,” and, in the wizard that pops up, set the contrast to 100.

You can play around with the brightness to change how dark a color needs to be to become black, and how light a color needs to be to end up white. Once you’re satisfied with your results, hit the “OK” button and your image is ready for the next step.

Step 3: Saving your image

Open the “File” menu and click “Save as…”. You can save your image under any name, anywhere, as long as you make sure you select “Portable Bit Map Files (*.pbm)” from the “Save as Type” drop down menu. If this option is not available, you didn’t install the plugin right, so re-install it and try again. Click image to enlarge.

Step 4: Reformatting your image’s code

Next up, you need to turn the image you just created into something the NXT can actually use. Go to the folder you saved your image in, right click the picture, and hit “Edit with Notepad++”. In the code you end up with, remove everything before the 1′s and 0′s (usually the top two lines).

Then, hit ctrl and f on your keyboard to open the “Find” wizard. The next steps are very important, so pay close attention:

  1. In the wizard, go to the second tab, which should say “Replace”
  2. In the “find what” box, type ” ” [hit the space bar once], and in the “Replace with” box, type nothing. Hit “Replace all.”
  3. In the “find what” box, type “1″, and in the “Replace with” box, type “1,”. Hit “Replace all.”
  4. In the “find what” box, type “0″, and in the “Replace with” box, type “0,”. Hit “Replace all.”
  5. Finally, turn the code into a single line by going to the end of every line of code and hitting delete

Step 5: Displaying the image on your NXT

First of all, copy this code into your program somewhere:

int i, j;
int image[HEIGHT][WIDTH] = {PUT 1'S AND 0'S HERE};
for(i=0; i<HEIGHT; i++){
  for(j=0; j<WIDTH; j++){
    if(image[i][j] == 0){
      nxtSetPixel(j,-i+HEIGHT-1);
    }
  }
}

Replace “WIDTH” with the width of your image, “HEIGHT” with the height of your image, and “PUT 1′S AND 0′S HERE” with your image code (copy and paste it between the curly brackets).

And there you have it: you can now display any image you want on your NXT screen using RobotC and some freeware :)





Skype Car – Going Wireless

7 01 2012

Read this first: Interactive Skype-Controlled Mindstorms NXT Car (original post)

Some of you might have noticed that my Skype car has been offline since last night. Why, you wonder? I was trying to solve the issue with the wire tangling around the robot all the time – first, I tried putting it on a high pole, but that just made it worse. Then I remembered an amazing Mindstorms NXT robot I once read about: Pulito, a floor cleaning robot that could look for its own power source using infrared light, and then plug itself in.

Since I do not have any equipment to read infrared light, I had to find another way for the robot to plug in. Here’s what I did:

  • Because the environment my robot was in was way more controllable (a square lined with cardboard boxes), I decided to use the sonar sensor, and make the robot follow the walls.
  • I then made a gap in one part of the wall, so the robot wouldn’t know where the corner was. That causes it to just keep on driving forwards, until it hit the wall on the other side.
  • This is where I got lucky: when I ordered the charger for my new battery, I got the wrong one (the one for the other kind of battery, which was hooked up to my other NXT). Having a spare one, I decided to cut it in half:

  • So when the car hits the wall, it’ll automatically start charging
  • For the programming, I added some code for the ultrasonic sensor and the touch sensors, and wrote some sequences to happen when the robot needs to start charging, and when it’s done.
In other news:
  • The instructions on the actual remote control page are much clearer now, too
  • The robot is now back online.

To read more about my Skype car, click here.

Disclaimer: The Skype name, associated trade marks and logos, the Skype “Call Me” button and the “S” logo are trade marks of Skype.





We’ve Moved! The code, that is.

5 09 2011

After a great holiday in Canada and moving from Germany to the US, I’m finally settled in and have everything installed and ready to go. As the title suggests, I will be changing the way I deal with code and programs on this website – no more RobotC code copied and pasted into word to get WP to upload it. From now on, everything will go to my project page on Sourceforge.

The following image cannot be displayed: SF code hosting screenshot

Sorry ’bout the chrome ads (but you should still get Chrome though ;)). This link will get you there:

https://sourceforge.net/projects/dimastero/files/.

The old downloads will still be available where they used to be until I find some time to move them.





RobotC: Status Update Program

1 07 2011

UPDATE: Download this program w/ setup and usage instructions here; get the driver (optional) here.

This little program/ driver is great for debugging and viewing the progress of your robot. Insert

updateStatus("> your status", amount of history to display);
//example
updateStatus("> calibrating motors", 4);

in between two lines of code, and the robot will display it, along with a history of up to 7 old status updates, on the display. There are two ways to do that. Firstly, you could save

string status[9];
void updateStatus(string currentStatus, int statusUpdateAmount){
  int i;
  for(i=statusUpdateAmount; i>0; i--){
    status[i] = status[i-1];
  }
  status[0] = currentStatus;
  for(i=0; i<statusUpdateAmount; i++){
    nxtDisplayTextLine(i, "%s", status[statusUpdateAmount-1-i]);
  }
}

as statusUpdate-driver.h and include it into your program using the code below on the very top

#include "drivers/statusUpdate-driver.h"

Otherwise, you could just copy and paste the big block of code in the beginning of your program, but that would add extra lines to your code :). Here’s some screenshots of it at work:

The following image cannot be displayed: Status Update Program Screenshot 1 (made using RobotC's NXT Remote Screen Feature)The following image cannot be displayed: Status Update Program Screenshot 2 (made using RobotC's NXT Remote Screen Feature)





RobotC: Precise Motor Positioning Tool

27 05 2011

UPDATE: Download this program w/ setup, usage instructions and a demo here; get the driver (optional) here.

Programming my current project, Bionic NXTPod 3.0, I broke the actuators a few times by having the slide run into either the top or bottom. This was caused by my motor control: every time it went up or down, the encoders were reset, not considering whether or not the motor was exactly on target. As the errors built up, the actuators were torn down.

Looking for a solution, I saw HiTechnic‘s motor PID block – for NXT-G – which lets the motor move to an absolute encoder position, without resetting in between. Using this method, the error – usually not more than 2-3 degrees – is eliminated every time the motor moves to a new position, because the block compares the desired position to the actual position, not the assumed “0 point”. For example:

  • The motor needs to go to 200 degrees and then back to 100
  • The program starts, and the motor overshoots to 201 degrees
  • Without the HiTechnic block: the motor would move back 100 degrees – because it thinks it’s at exactly 200 degrees – ending up at 101
  • With the HiTechnic block: the motor would move back 101 degrees (201-100) ending up at 100
But, since the block’s for NXT-G, that wouldn’t work for me. So, I made a similar (but not quite as versatile) RobotC function:

void PositionMotor(char motorToTurn, int absoluteDegrees){
  if(nMotorEncoder[motorToTurn] == absoluteDegrees){}
  else if(nMotorEncoder[motorToTurn] < absoluteDegrees){
    bMotorReflected[motorToTurn] = false;
    nMotorEncoderTarget[motorToTurn] = absoluteDegrees-nMotorEncoder[motorToTurn];
    motor[motorToTurn] = 75;
    while(nMotorRunState[motorToTurn] != runStateIdle){}
    motor[motorToTurn] = 0;
  }
  else{
    bMotorReflected[motorToTurn] = false;
    nMotorEncoderTarget[motorToTurn] = nMotorEncoder[motorToTurn]-absoluteDegrees;
    bMotorReflected[motorToTurn] = true;
    motor[motorToTurn] = 75;
    while(nMotorRunState[motorToTurn] != runStateIdle){}
    motor[motorToTurn] = 0;
  }
}

All you do is input the motor you want to move – like “motorA” or “motorC” – and the amount of degrees, measured from your “0 position” (by default, this is the position your motor is in when the program starts), and it does all the work for you.




HiTechnic Experimenter’s kit I2C output addresses

2 05 2011

I couldn’t find all of these addresses anywhere, so I tested them to see what pins (B0 – B5) they’d turn on. A white box means that that address is turned on, and a black box means it’s off. Thanks to Xander and bullestock for helping me complete this list:

The following image cannot be displayed: I2C output addresses on HiTechnic Experimenters Kit





How To: make Custom NXT – PF Cables

26 03 2011

This guide will tell you how to create your own Lego Mindstorms NXT to Lego Power Functions cable, to control any PF motor or light, how to program it, and what you can do with it.

What you’ll need:

  • An expendable regular NXT cable
  • An expendable PF (could be an extension cord, light, motor of XL motor)
  • Soldering equipment
  • Insulation wire
  • Some very basic electricity knowledge
  • If under 18: permission from parent/ guardian to solder, and cut your NXT/ PF wires

Steps

  1. Get a good workspace set up; make sure you’re either outside or keep some windows open (solder is toxic); also lay something on your table to catch falling solder.
  2. Cut the NXT and PF cables in half, keeping about 5 cm (2 inches) of wire on both.
  3. Strip both wires down to the copper; for the NXT cable, cut off the blue, yellow, green and red wires; strip the black and white onesNXT to PF illustration 1
  4. Connect one of the middle two PF wires to the white NXT wire (it doesn’t really matter which one; if you’re making multiple cables, though, keep consistent), and connect the other one to the black wire.NXT to PF illustration 2
  5. Solder these connections and individually insulate them so they’ll never be able to touch each other
  6. Twist the wires together and insulate the whole thing to complete your cable, you can heat shrink it if you have the means to.NXT to PF illustration 4

Programming

Since both the Lego power functions and Mindstorms NXT work on 9v (6 AA batteries), programming them together isn’t very difficult. All you need to do is use a regular motor function (or motor block in NXT-G) to send power through one of the three possible ports (this won’t work with sensor input ports). One very important thing, though, is to turn off the built in motor PID control, because the program doesn’t get any feedback from the PF it’s controlling. So, it’ll always turn the power to 100 to compromise the speed it doesn’t think it has.

So this (RobotC code):

task main(){
  int waitMSecs = 50;
  nMotorPIDSpeedCtrl[motorA] = mtrNoReg;
  nMotorPIDSpeedCtrl[motorB] = mtrNoReg;
  nMotorPIDSpeedCtrl[motorC] = mtrNoReg;
  motor[motorB] = 25;
  motor[motorC] = 50;
  while(true){
    motor[motorA] = 0;
    wait1Msec(waitMSecs);
    motor[motorA] = 100;
    wait1Msec(waitMSecs);
  }
}

would make the PF function connected to…

  • Port A: flicker on and off every 50 mSecs
  • Port B: turn on to 25% of the maximum power
  • Port C: turn on to 50% of the maximum power

So, now you’re able to connect ANY Lego power function straight to you’re NXT, and, without any difficult programming, control it straight from there very accurately, with the possibility to use timers, loops, reverse power, dimming and much more!

Links:





RobotC: NXT-G-like motor control

13 03 2011

Sometimes, especially when testing robots, it’s nice to be able to whip a small program up in seconds. That’s easy in NXT-G, with its blocks. But, in RobotC, that usually takes some more time. So, this function allows you to program a motor in a single command, which requires the same amount of input as the NXT-G motor block

void motorBlock(char motorPort, bool directionForwards, int power, int durartionMSecs, bool nextActionStop){
  ClearTimer(T1);
  while(time1[T1] < durartionMSecs){
    if(directionForwards == true){
      motor[motorPort] = power;
    }
    else{
      motor[motorPort] = -power;
    }
  }
  if(nextActionStop == true){
    motor[motorPort] = 0;
  }
}

so, the following program:

task main(){
  motorBlock(motorB, false, 100, 1000, true);
}

would make motor B run in reverse at a 100% power for one second, braking afterwards. The only problem is that you’d need to copy/ paste the void in for every program.





Light Sensor as Switchable Light

9 01 2011

One very cool feature of the NXT 2.0 is that the color sensor can be used as light (beacon). But, as it turns out, that effect can be achieved wit the NXT 1.0 light sensor as well (in RobotC, at least). Why? the color sensor can be set to a different mode (active or inactive) within the program, and not just when configuring the sensor ports. When the sensor is used in its inactive mode, it reads the regular light value, while the active mode reads the reflected light. To read the reflected light, the NXT turns the red LED (the lower glass thing) on, and to read the regular light, it turns it off.

In order to use this function, one needs to configure the light sensor using #pragma config(Sensor…, setting it as either “sensorLightActive” (light turned on) or “SensorLightInactive” (light turned off), whichever one is needed first. Then, anywhere within the code insert “SensorType[lightSensor] = sensorLightActive;” or ”SensorType[lightSensor] = sensorLightInactive;”, where the part between the square brackets is equal to the name specified within the pragma part. Here’s an example

#pragma config(Sensor, S1,     lightSensor,         sensorLightActive)//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//
task main(){
  int i;
  nxtDisplayCenteredTextLine(2, "Light turned");
  for(i=0; i<49; i++){
    SensorType[lightSensor] = sensorLightActive;
    nxtDisplayCenteredBigTextLine(4, "ON");
    wait10Msec(i);
    SensorType[lightSensor] = sensorLightInactive;
    nxtDisplayCenteredBigTextLine(4, "OFF");
    wait10Msec(i);
  }
}

It’s really useful, as it can be used for super quick communication between two NXTs, as the light can be turned off in a few milliseconds.








Follow

Get every new post delivered to your Inbox.

Join 34 other followers