Page 1 of 1
RemoteSetOutputState
Posted: 07 Nov 2010, 20:47
by fuzzball27
I'm working on a program that uses two pots to control the speed of each motor on my robot using BT (an RC bot). The only problem that I'm having is that when I run the program, only motor C responds to commands.
I know that the problem is not the pot assigned to motor A, because I have the values of each pot displayed on the LCD, and IN_4 (the pot assigned to motor A) is displaying accurately. I do not understand why motor A on the receiving end does not respond. Perhaps only one RemoteSetOutputState command can be used at a time? Here is my code:
Code: Select all
task C_MOTOR () //This task is working as expected
{
int speed;
SetSensorType (IN_1, SENSOR_TYPE_TOUCH);
SetSensorMode (IN_1, SENSOR_MODE_RAW);
while (true)
{
speed = SENSOR_1;
speed -= 3;
speed /=5;
NumOut (0, 0, speed);
RemoteSetOutputState (1, OUT_C, speed, OUT_MODE_MOTORON, OUT_REGMODE_IDLE, 0, OUT_RUNSTATE_RUNNING, 0);
Wait (50);
}
}
task A_MOTOR () //This task seems to be "ignoring" the RemotSetOutputState command
{
int speed;
SetSensorType (IN_4, SENSOR_TYPE_TOUCH);
SetSensorMode (IN_4, SENSOR_MODE_RAW);
while (true)
{
speed = SENSOR_4;
speed -= 3;
speed /=5;
NumOut (30, 0, speed);
RemoteSetOutputState (1, OUT_A, speed, OUT_MODE_MOTORON, OUT_REGMODE_IDLE, 0, OUT_RUNSTATE_RUNNING, 0);
Wait (50);
}
}
task main ()
{
Precedes (A_MOTOR, C_MOTOR);
}
Help would be greatly appreciated.
Thank you
Re: RemoteSetOutputState
Posted: 07 Nov 2010, 22:01
by mattallen37
Well, for one thing, you have two tasks trying to run the BT at potentially the same time. If you need to have both tasks running simultaneously (which you don't), then you should use a mutex, or something similar. Try putting it all into one single task.
Re: RemoteSetOutputState
Posted: 07 Nov 2010, 23:11
by afanofosc
Matt's right on the money. I absolutely agree that there is no reason to use two threads here. KISS. Sadly, since you can't send 2 bluetooth direct commands simultaneously there will be a (very short) delay between the two motor commands being processed on the receiving NXT. Remember to include a wait loop after the RemoteSetOutputState call. In the latest test release you can use RemoteConnectionIdle(conn) like this:
Code: Select all
until(RemoteConnectionIdle(theConn));
If both motors are being set to the same speed you can do that with a single SetOutputState direct command. With the standard firmware you can set all motors in a single call by using 0xFF as the motor number. With the enhanced NBC/NXC firmware you can use (from NBCCommon.h):
Code: Select all
#define OUT_AB 0x03
#define OUT_AC 0x04
#define OUT_BC 0x05
#define OUT_ABC 0x06
John Hansen
Re: RemoteSetOutputState
Posted: 07 Nov 2010, 23:26
by fuzzball27
Thanks for the suggestions. I think what I'll do is make a joystick and program one pot for speed, and the other for turn pct.
I got an error when I tried to download the updated program through applescript (when I was following Matt's suggestion for one task). The error was NXT Error #92. When I used the nbc command line in the terminal it worked fine. My command line in applescript was exactly the same, and when I ran another program through applescript it worked fine. It only gave me the error message on that particular program. Any idea what that's all about?
Re: RemoteSetOutputState
Posted: 07 Nov 2010, 23:29
by m-goldberg
If I were investigating this problem, the first thing I would do is recompile the code with the C_MOTOR task disabled -- that is, I would remove C_MOTOR from the Precedes API call. I would want to know if that activates the A_MOTOR on the remote robot.
Base on the results of this test, I would explore two lines of modification:
1. Using a mutex and Acquire and Release as mattallen37 suggested.
2. Investigating how long it takes the remote to receive and respond to the BT command. The thinking here is that the 50 msec wait may not be enough.
Re: RemoteSetOutputState
Posted: 08 Nov 2010, 02:07
by mattallen37
Another option, is to send a string. In this way, you can control multiple motor's speed and direction all with one message. To do this, you need to flatten the control array into a string, send it, and unflatten it back into the individual commands on the slave. This allows for higher speed (only one transaction), and near simultaneous motor reaction; though it requires the slave to be running a program.
Re: RemoteSetOutputState
Posted: 08 Nov 2010, 14:26
by linusa
mattallen37 wrote:Another option, is to send a string. In this way, you can control multiple motor's speed and direction all with one message. To do this, you need to flatten the control array into a string, send it, and unflatten it back into the individual commands on the slave. This allows for higher speed (only one transaction), and near simultaneous motor reaction; though it requires the slave to be running a program.
Such a program already exists as free open source software, see here:
http://www.mindstorms.rwth-aachen.de/tr ... torControl
Although the site describes how to compose strings to that NXC program from a computer, you can as well use another NXC client program to compose those string messages...
Basically, the RemoteSetOutputState command is the simpler version, do as the other posters suggested, and use either a single thread or mutexes, and wait-commands. Depending on what exactly you want to do with your motors (how do you want to move them?), this option might no be enough for you.
Re: RemoteSetOutputState
Posted: 08 Nov 2010, 15:23
by mattallen37
I was actually referring to building it from the ground up, not using a prefab deal. It sounds like he just needs simple motor control (speed and direction), which I have done before, and is really easy to do.