Programming Question from our Forum
The following question was posted to our forums by Itry:
"Hi. I'm new to NXT, and trying to figure out the basics of programming. I need a light sensor to detect change in ambient light levels, and if above a certain range to activate rotation of a motor in the forward direction 4 turns & stop, and if below a certain range to activate rotation of the same motor in the reverse direction 4 turns and stop. The motor needs to complete its assigned 4 rotations before being allowed to reverse. The program needs to run continuously, forever, so that once the light level changes beyond the threshold in either direction, the motor will react. HELP?"
Well, here's a screen capture of my solution. My comments in the image should be sufficient to comprehend the program. Maybe other readers can offer up their own ideas.
Comments
--
Brian Davis
Tell me if I'm reading it wrong, but your implementation seems to only work with a single Light sensor value... say it's set to 50 in the Compare block. Then the motor spins forward if it's greater, or reverse if it's less. It doesn't look like it would work if you were testing for >60 and <20 for the two conditions.
Jim
He then checks for direction of movement.
The boolean result"willMove" is passed into the switch block and the direction passed in the move block direction.
--
Brian Davis
You'll probably want to get rid of that last remaining switch block and connect yet another wire to the move block i.e. power=0,>0 or duration =0,4
Yes, you could in fact do away with the Switch all together, by using a series of Math blocks to change the Light sensor value into a zero or something-greater-than-100, but it has certain problems to watch out for as well, not the least of which being that at a power of zero, I'm not sure how if the motor is in a float-like or brake-like mode. For a "deadband" range of 20-60, for instance, you could use something like this:
x = (light sensor reading) - 40
x = x / 20
x = x * 100
The first two operations will generate a zero if the value is between 21 and 59, and something else (+/-1, +/-2, +/-3, etc.) if it is outside that range. The third line will make that result some large number (+/-100 or greater), which you can wire into the Motor block as a power (the Motor block doesn't care about the sign on the power, so there's no reason to "fix" that).
Another slightly speeded-up solution that I was thinking of is to put the Compare block inside the true case of the Switch, just ahead of the Motor block. That way if the Range evaluation isn't going to result in a movement, no time is "wasted" on evaluating the Compare block.
--
Brian Davis
Jim
If you follow the comments from the beginning, you'll see a reference for the forum entry where additional screen shots are attached.
I read the post again. Particularly the frustrating phrase "see attached images here". No images, and no obvious (to me) links.
What am I doing wrong? Please use non-technical words and pretend like your giving phone support to your grandma.
Sorry you're having trouble - I'm running Internet Explorer 7 and I can see one small image below David's post/reply on June 11 at 10:06am and I see another small image (thumbnail) for Brian Davis' post on June 11 at 12:45pm.
Not sure why you can't see them... do you possibly see a link to an image instead of a thumbnail? I know some browsers can get set to display a URL/link instead of a thumbnail... unlikely, but possible in your case.
Jim
I'm guessing you weren't logged in ( accessing as guest). I just changed the permission to allow guests to view attachments. Seems like that should have been enabled by default.
Try it again.
David
As is normal for me I prefer a sequential solution.
Loop Forever
{
IF lightSensor < lowerThreshold
RUN MOTOR REVERSE 4 ROTATIONS
IF lightSensor > upperThreshold
RUN MOTOR FORWARD 4 ROTATIONS
}
One Loop
Two switch statements
Two move blocks
Maybe not as small as Brian's solution, but the logic is very obvious.
> but the logic is very obvious.
And that's a very good point. Understanding your code is an important part, and something that can sometimes get missed in the quest for the "right" way to do it. Another reason I always enjoy seeing a lot of different solutions to problems.
--
Brian Davis
So your pseudo code looks like it closely resembles Jim's screen shot ( on this blog)
If I were to express my screenshot ( on the forum) with pseudo code it would look something like:
Loop Forever
{
IF lightSensor > upperThreshold
RUN MOTOR FORWARD 4 ROTATIONS
ELSE IF lightSensor > lowerThreshold
RUN MOTOR REVERSE 4 ROTATIONS
}
One Loop
Two switch statements (nested)
Two move blocks
To me, slightly easier to read but at the expense of 2nd light sensor reading which Richard pointed out.
By gosh, you're right. Just remove the logic blocks and change the switch statements from value to sensor and you have the same answer. I'm so excited about my new ability to see attachments on the forum that I forgot to look all the way back up at the start of this post.
Due to the horrible slowness of NXT-G V1.0 I tend to avoid nesting switches. On the beta software doing such things sometimes crashed the application on my PC. The new V1.1 is a vast improvement in that respect.
You should be able to post your own attachments ( screen shots) if you register and login to the forum.