Page 1 of 1

Help with NXC multi threading - Solved!

Posted: 28 Jul 2011, 16:52
by haydenstudios
Hi there. I've been learning NXC, (and having quite a lot of fun I might add) but I have ran into a problem. I have been going back-and-forth between John's book and Daniele's tutorial, and have just finished Chapter 7 of the book, and have begun chapter VI of the tutorial. I have copied the example for multi threading shown in the tutorial:

Code: Select all

mutex moveMutex;
task move_square()
{
while (true)
{
Acquire(moveMutex);
OnFwd(OUT_AC, 75); Wait(1000);
OnRev(OUT_C, 75); Wait(500);
Release(moveMutex);
}
}
task check_sensors()
{
while (true)
{
if (SENSOR_1 == 1)
{
Acquire(moveMutex);
OnRev(OUT_AC, 75); Wait(500);
OnFwd(OUT_A, 75); Wait(500);
Release(moveMutex);
}
}
}
task main()
{
Precedes(move_square, check_sensors);
SetSensorTouch(IN_1);
}
The
So that worked, then I decided to make my own program with multi threading which would have the main thread make the motor attached to port A move forward until the touch sensor is pressed, then move backward until it is released, and put that into a loop. The secondary thread would make an image move back-and-forth accross the screen. But for some reason, when I run the program, only the main thread runs. I might add that I received no compilation errors. When I remove the main thread and change the secondary to the main thread, it works fine, so I know theres no problem with the commands of the secondary thread. So my question is, what's wrong with this code here?

Code: Select all

int NUM;
mutex secondary;

task tray()
{
 NUM = 0;
 while(true){
  Acquire(secondary);
  do{
   ClearScreen();
   GraphicOut(NUM, 0, "Tray.ric");
   NUM += 1;
   Wait(30);
   }
   while(NUM <= 76)
  do{
   ClearScreen();
   GraphicOut(NUM, 0, "Tray.ric"); // If you help me out, just substitute your own image.
   NUM -= 1;
   Wait(30);
   }
   while(NUM >= 0)
  Release(secondary);
 }
}

task main()
{
 Precedes(tray);
 SetSensorTouch(IN_1);
 while(true)
 {
  OnFwd(OUT_A, 75);
  until(SENSOR_1);
  OnRev(OUT_A, 75);
  until(!SENSOR_1);
 }
}
P.S. I'm new to NXC, so feel free to advise me on a few habbits I appear no to be into with certain commands, or which techniques you think would be better for me to be used to using if there are any.

Thanks in advance.

Re: Help with NXC multi threading

Posted: 28 Jul 2011, 20:59
by muntoo
Your task tray() never starts. Precedes() waits for the current task (task main()) to end.

Code: Select all

task a()
{

}

task main()
{
    Precedes(a);

    while(1);

    // start a; // Never happens!
}
Try this:

Code: Select all

task tray()
{    
    while(true)
    {
        for(int x = 0; x <= 76; ++x)
        {
            ClearScreen();
            GraphicOut(x, 0, "Tray.ric");
            Wait(30);
        }

        for(int x = 77; x >= 0; --x)
        {
            ClearScreen();
            GraphicOut(x, 0, "Tray.ric");
            Wait(30);
        }
    }
}


task otherstuff()
{
    while(true)
    {
        OnFwd(OUT_A, 75);

        while(!SENSOR_1)
            Yield();

        OnRev(OUT_A, 75);

        while(SENSOR_1)
            Yield();
    }
}


task main()
{
    Precedes(tray, otherstuff);
    SetSensorTouch(IN_1);
}
P.S. You should indent with a tab or 2-4 spaces (4 is the "standard" convention) for each deeper "nest" into a block.
Also, until(cond); isn't C; it's only there because of NQC. I recommend not using until(). Instead, use while(!(cond));.

Re: Help with NXC multi threading

Posted: 29 Jul 2011, 02:47
by haydenstudios
It works! Thanks for your help muntoo!