Friday, February 12, 2010

I'm well past the point of being able to construct an oscillator out of an RCX in time for my lab. Just as well since the time to finish the lab is going faster than I thought. So that leaves me with a question of what the hell I'm going to do with the progress I've made (both with the NXT and the RCX). The utility of the NXT is in its sensors and it's mobility. While I have the interface to make it record things with Vernier sensors, I also have the LabQuests, which offer more options for analysis and less hassle to get data from. The NXT sensors are kind of crappy, aside from a compass and a sound intensity meter. The SIM might be useful, especially on a mobile device, to find hotspots and cold spots in a room. Maybe I can make a lab where you find the hot and cold spots?

The RCX looks like it will have more utility than I originally thought. The connectors are really easy to attach to alligator clips, and if I keep the PWM frequency high enough I can try to use it as a variable DC output for electricity labs. Still, programming it is proving to be more difficult due to lack of documentation and similarities/differences from the later versions of leJOS. Right now I'm trying to figure out how to use Sensor Listeners and while I can get one example to work it is still in the "magic" range of things where I can't dissect it and put it back together again.

Labels:

Wednesday, February 10, 2010

and Failure!! Well, not exactly. My original NXT project has worked beautifully and my lab is going off without a hitch . . . at least for those 2 setups. I was hoping that with the same amount of work I could get it running on an RCX. I didn't really think through the project much as I was on deadline for the lab. After spending a lot of time figuring out how to get leJOS on the RCX, and getting the IR Tower to work correctly I ran into a brick wall. That brick wall was in a method called .setPower(). The problem wasn't that there didn't exist a .setSpeed(), I was ready for that since the RCX motors don't have a tachometer built in. That's why I bought a rotation sensor. The problem was that .setPower() only operates on a range from 0-7 unlike .setSpeed() which works from 0-900 deg/sec. The power setting isn't even a linear relationship. After a lot of digging through different languages I couldn't find one that would give me the resolution that I'm looking for, so I'm left with creating my own Pulse Width Modulator. The RCX uses PWM already, but it is over an 8msec interval (thus the 0-7) power setting. I'll have to extend the width in order to make this work, and control the pulse manually. This means that the number of msec that I make the width is equal to my resolution for frequency control (which I still have to calculate and have indirect control of). But the wider I make the width the more difficult the problem becomes. If the width is too long then I can't just have the motor run hot for the duration and cold for the rest. If I want a duty cycle of 2% for a 100msec cycle then I should ideally run hot for 1msec, cold for 49msec then repeat. But that requires a more complicated algorithm that figures out the number of times to run hot for 1msec. It's not that I can't do it . . . it isn't going to be that difficult . . . but I'd rather just leave it as an easy "hot for x, cold for 100-x" system. Anyway, due to these problems I have bought one more NXT brick and will probably buy a new kit next year. Bummer, but at least I'm learning things.

Labels:

Friday, February 05, 2010

Success!!! My oscillator and program both work, and with a string at least 1m in length I can create the first few standing waves. All that means that I can go forward with the lab that I have. As always there is a catch and right now the catch is that I only have 2 working NXT bricks. I do have 2 RCX Bricks, but I haven't gone through the process of setting up leJOS for the RCX. I also would have to build a completely difference oscillator and Lego Digital Design doesn't seem to have the RCX parts built into the library. Maybe I'll have to go back to learning Bricksmith in order to make it work. Unfortunately I don't have any RCX bricks here at home and I don't know if I would want to try to get another version of leJOS running on my version of Eclipse. As it stands right now the law isn't going to be until Tuesday, so that gives me one day to figure all of this stuff out with the RCX or just bag the idea and only have 2 stations for my 4 groups. Whatever, I'll figure it out.

Oh, and I greatly improved upon the oscillator design. I currently has no idler gears and is easier to turn.

Labels:

Tuesday, February 02, 2010

I have had a certain amount of success building my Oscillator. Here's a picture. It is way too big, and needs lots of optimization. I have something like 3 idler gears in there for spacing, and I'm sure I can improve on that when I get to the next model. The whole size of the thing is too large and piece heavy. There is also an awkward height between the bottom support and the middle support (6 holes). While I will definitely improve upon the design the bulk is handy because when it gets going this thing walks a lot.

But the best part is that I added some basic code to the ButtonMath program I had before so that the motor is directly controlled by the buttons on the NXT. After adding a display showing the speed (or at least the speed setting) I now have a frequency controller that can alter the frequency of the oscillator. It still doesn't get high frequencies. The motor does even make it past 900 deg/s (and that is at full battery) and the gearing is 25:1. So at best I can make it up to 62.5 Hz. The next step is to find an elastic string and the right length/tension so that I can get a fundamental frequency in the 12.5 range so that I can see multiple standing waves.

I figured I would post the code just in case I forget how to code it at some point. It is poorly commented . . . but that is because I am a bad programmer.

//This program is designed to directly control the speed of the motor using buttons
//to set the variable MOTORSP. Pressing right adds 1 to the motor speed, pressing
//left subtracts one and pressing enter adds ten. Each time the screen rewrites
//the motor speed.
import lejos.nxt.Button;
import lejos.nxt.ButtonListener;
import lejos.nxt.LCD;
import lejos.nxt.Motor;


public class MotorControl {
static int MOTORSP = 100;
public static void main(String[] args) throws Exception {
LCD.drawInt(MOTORSP, 3, 7);
Button.RIGHT.addButtonListener(new ButtonListener() {
public void buttonPressed(Button b) {
LCD.clear();
MOTORSP += 1;
LCD.drawString("Motor Speed", 3, 6);
LCD.drawInt(MOTORSP, 3, 7);
Motor.A.setSpeed(MOTORSP);
}
public void buttonReleased(Button b){
}
});
Button.LEFT.addButtonListener(new ButtonListener() {
public void buttonPressed(Button b) {
LCD.clear();
MOTORSP -=1 ;
LCD.drawString("Motor Speed", 3, 6);
LCD.drawInt(MOTORSP, 3, 7);
Motor.A.setSpeed(MOTORSP);
}
public void buttonReleased(Button b){
}
});
Button.ENTER.addButtonListener(new ButtonListener() {
public void buttonPressed(Button b) {
LCD.clear();
MOTORSP += 10;
LCD.drawString("Motor Speed", 3, 6);
LCD.drawInt(MOTORSP, 3, 7);
Motor.A.setSpeed(MOTORSP);
}
public void buttonReleased(Button b){
}
});
Motor.A.forward();
Button.ESCAPE.waitForPressAndRelease();
}
}

Labels:

Saturday, January 30, 2010

I've been "working" with LEGO Mindstorms for a while now. The biggest struggle is my poor programming skills. The interface hasn't really helped much. Moving from crappy LabVew style block interfaces to variants of c++. I finally made some "progress" when they got leJOS up and running on OS X. Sure, I guess I could have run it's older Unix counterpart on my Mac . . . but I don't know how. So I've been going through a book that is teaching me how to use Java and it's offshoot leJOS. There have been many things that I have learning, but two things stand out the most.

First, version updates suck because they make the examples you have not quite useless but not quite helpful. I've learned the value of sifting through class lists so that I can figure out what has been depreciated and what hasn't. I've learned that finding examples of code online is great . . . until you realize that code requires a class implementation that you didn't include and don't have. All of these things are well known by real programmers and until recently not by me.

Second, after taking a few months off as I was working on other projects I've realized that without formal eduction it is really easy for me to forget things. As a result I need to make sure that I grow from "lesson" to lesson by at least partially reflecting. So that is what I am going to do with this space. I doubt anyone is still reading, and since I have the space to myself I'm going to reflect on what I have learned in hopes of cementing what paltry advances I make.

1/30/10: I've taken to building an oscillator to replace the "wiggler" we had in Cobb Co. It need to be able to oscillate a string at a variable frequency so that students can create standing waves. I built a wiggler out of Mindstorm pieces and now have to figure out how to control it. There is a direct control mechanism that runs from Terminal, but it only works in "Power" settings through a slide bar. I need to be able to figure out what angular speed the motor rotates at for difference power settings. The trick is that it is under an unknown load so I can't just use the standard graphs online. So I have to find a way to track the angular displacement of the motor as it goes through motion at different settings. That means I need to have a way to record the tachometer and write it to a file. TachoCount gets me the reading I need, but writing a file it tougher than I thought. I struggled through some built in DataLogger classes and eventually found a class online that does what I want it to do and I can figure out how to manipulate the code for. It still has a drawback of the number of data points, but I may be able to improve that with time (or not?).

Once that works I realize that the motor speeds indicated on the standard graphs are going to be roughly true, which is bad because they peak out at less than 3 revolutions per second. So I'm going to have to gear the living daylights out of this assembly if I am going to be able to vary the frequency of the oscillator over even the most trivial range (0-50). As it stands now I can gear it up to 1:20, which will accomplish my needs as long as I can control the motor.

Controlling the motor was frustrating. I wrote a bunch of code that was suppose to increase the motor power incrementally (before I collected the data) but it failed because there is an obvious difference between .setPower() and .forward(). Even after I figured that out it seemed like the .setPower() method wasn't doing anything . . . because it wasn't. Apparently the motors have a speed regulator that has to be disabled by setting .regulateSpeed(false). I can now control the motor, and get a graph telling me what power setting equals what RPM. There is a .setSpeed() rating, but not on the direct control.

Which is why the last project because getting direct control from a program other than NXJControl. That would mean having a button response (or something else). I know that you can create button listeners, but the book I have doesn't talk about it much. I spend a lot of time looking for it online and find nothing until I see a small section of code that tells me how to create listeners. So I decide to create a stupid math program where right= +1, left= -1 and enter= +10. I get moving and get an error when I tell it to increment the variable SCORE. I spent a lot of time trying to figure out how to pass and return a variable to a listener before I realize that one option is to make SCORE a static int (which basically makes it global to the whole class so any object/method can alter it). With that done (and on my first upload) I get my math program up and running on the NXT and it works.

I guess the next step is to write a program where you press the buttons to increase the variable put into .setSpeed(). That way one NXT can directly control one motor and get it to move through the whole frequency range. Then I have to find a string that will have a fundamental frequency in the teens to we can get at least 3 standing waves out of it.

Labels: