Martin Andersson
Martin Andersson

Reputation: 41

Programming EV3 with c#

Me and my friends are working on a school project where we want to make it write stuff on paper. We are programming it using c# in visual studio.

The problem we have is that it does the commands in wrong order. If we want to make it go forward and then turn it will try to do both at the same time. We have used Task.Delay to fix this problem but the code has gotten really messy and it's annoying to try to find the exact time for the delays.

Does anyone know any other way to fix this? The code below shows a little of how we have been doing things.

    public static async void Go(Brick brick, uint duration, bool forward)//Makes it go forward
    {
        if (!forward)
        {
            await brick.DirectCommand.TurnMotorAtSpeedForTimeAsync(OutputPort.B | OutputPort.C, -speed, duration, true);
            Console.WriteLine("Going backwards");
        }
        else
        {
            await brick.DirectCommand.TurnMotorAtSpeedForTimeAsync(OutputPort.B | OutputPort.C, speed, duration, true);
            Console.WriteLine("Going forward");
        }

    }

    public static async void Turn(Brick brick,float degrees, bool Clockwise)//Turns the robot. If it goes over for exampel 90 degrees it turns back a little
    {
        int direction;
        int speed = 4;
        degrees = Math.Abs(degrees);
        DateTime start = DateTime.Now;
        if (Clockwise)
        {
            direction = 1;
        }
        else
        {
            direction = -1;
        }

        float startposition = brick.Ports[InputPort.Two].SIValue;
        await brick.DirectCommand.TurnMotorAtSpeedAsync(OutputPort.B, speed * direction);
        await brick.DirectCommand.TurnMotorAtSpeedAsync(OutputPort.C, -speed * direction);
        bool loopar = true;
        while (loopar)
        {
            float DeltaPosition = Math.Abs(brick.Ports[InputPort.Two].SIValue - startposition);
            if (DeltaPosition >= degrees)
            {
                await brick.DirectCommand.TurnMotorAtSpeedAsync(OutputPort.B | OutputPort.C, 0);
                loopar = false;
            }
            //await Task.Delay(1);
            Console.WriteLine(DeltaPosition);
        }
        loopar = true;
        await Task.Delay(100);
        await brick.DirectCommand.TurnMotorAtSpeedAsync(OutputPort.B, -1 * direction);
        await brick.DirectCommand.TurnMotorAtSpeedAsync(OutputPort.C, 1 * direction);
        while (loopar)
        {
            float DeltaPosition = Math.Abs(brick.Ports[InputPort.Two].SIValue - startposition);
            if (DeltaPosition <= degrees)
            {
                await brick.DirectCommand.TurnMotorAtSpeedAsync(OutputPort.B | OutputPort.C, 0);
                loopar = false;
            }
            Console.WriteLine(DeltaPosition);
        }
        TimeSpan span = DateTime.Now - start;
        Console.WriteLine(span);
    }

    public static async void L(Brick brick)
    {
        Go(brick, 1000, true);
        await Task.Delay(1000);
        Up(brick);
        await Task.Delay(500);
        Turn(brick, 90, false);
        await Task.Delay(5000);
        Down(brick);
        await Task.Delay(500);
        Go(brick, 500, true);
    }

As i said we dont want to use Task.Delay, but thats only solution we have right now.

Thanks in advance!

Upvotes: 2

Views: 481

Answers (1)

bommelding
bommelding

Reputation: 3037

async void is async but not awaitable. All those calls will execute whenever they feel like it.

Make them async Task like this:

// public static async void Go(Brick brick, uint duration, bool forward)
   public static async Task Go(Brick brick, uint duration, bool forward)

and then await the calls:

public static async void L(Brick brick)
{
    await Go(brick, 1000, true);        
    await Up(brick);        
    await Turn(brick, 90, false);        
    await Down(brick);        
    await Go(brick, 500, true);
}

The L() method should probably be an async Task too, there is not enough info here to tell.

In general, async void is dangerous and should be avoided unless you are very sure about what you are doing.

Upvotes: 5

Related Questions