Main Site Documentation

MotorController L298 and Pulse Count


#1

Hi, i’m new to these forums, though i’ve been using the modules for 6 months now.
My question is this:
I have a DC motor with an Encoder hooked up to the MotorController Module and The PulseCount. Controlling the Motor works fine, reading the pusle works fine. The problem is when i try to do both, it starts the motor, and after a long time, it finally starts reading the Count on the PulseCount Module. The Motors are used to activate a gear on a robotic hand, so they do stop moving on their own at some point. The problem is that i need to be able to read the counts as soon as it starts. I tried Threads, Timers, and so far these work even less than the solution i have. Here is the Code:

void joystick_JoystickPressed(Joystick sender, Joystick.JoystickState state)
{

        if(MotorDirection == (int)Direction.Forward)
        {
            MotorMoving[0] = true;
            led7r.TurnLightOn(1, true);
            MotorController1.MoveMotor(MotorControllerL298.Motor.Motor2, 100);
            
            while (MotorMoving[0])
            {
                CheckMotor1();
            }
            MotorDirection = (int)Direction.Backward;
        }
        else
        {
            MotorMoving[0] = true;
            led7r.TurnLightOn(1, true);
            MotorController1.MoveMotor(MotorControllerL298.Motor.Motor2, -100);
            
            while (MotorMoving[0])
            {
                CheckMotor1();
            }
            MotorDirection = (int)Direction.Forward;
        }
        

    }
    bool CheckMotor1()
    {
        LastEncoder[0] = MotorEncoder[0];
        MotorEncoder[0] = Encoder2.GetCount();
        Debug.Print("Encoder 1 Value: " + MotorEncoder[0].ToString());
        if ((LastEncoder[0] <= MotorEncoder[0] + 5 && LastEncoder[0] >= MotorEncoder[0] - 5) && MotorMoving[0])
        {
            MotorController1.MoveMotor(MotorControllerL298.Motor.Motor2, 0);
            led7r.TurnLightOn(2, true);
            Debug.Print("Motor 1 Stopped");
            MotorMoving[0] = false;
        }
        return MotorMoving[0];
    }

Thank you for your help


#2

Welcome to the forum!

Can you please show your multithreaded approach?

Please use code tags for the code fragments in posts .It is a button with 1 and 0 or use [ code ] and [/ code ] (without spaces)


#3

well, though i did delete the code, the basis was to start a thread, which had a while true in it , and all it did was to read the encoder. The problem with that one was that i had trouble accessing the encoder without making it static, and that created more problems.

But the one time i made it work, what happened was that because i was continuously reading it, nothing moved, so i added some suspend Thread commands while the motor was off, and resume thread the moment the motor came back on. The threads never stopped, and kept shutting off my motors.

The code is basically the same except that the following code was running in the thread
instead.

bool CheckMotor1()
{
LastEncoder[0] = MotorEncoder[0];
MotorEncoder[0] = Encoder2.GetCount();
Debug.Print("Encoder 1 Value: " + MotorEncoder[0].ToString());
if ((LastEncoder[0] <= MotorEncoder[0] + 5 && LastEncoder[0] >= MotorEncoder[0] - 5) && MotorMoving[0])
{
MotorController1.MoveMotor(MotorControllerL298.Motor.Motor2, 0);
led7r.TurnLightOn(2, true);
Debug.Print("Motor 1 Stopped");
MotorMoving[0] = false;
}
return MotorMoving[0];
}

Hope this helps


#4

Regarding static vs non-static. You can’t access non-static members from static methods. I think your thread functions was static and that was the issue. I pretty sure you can use non-static methods as thread functions or you can always pass the class instance as a parameter to a static thread function. That way you can access any public instance properties.

Resume/suspend are “expensive”. I would use Thread.Sleep or even an event object. That way you can wait on event object to be set in your counter thread. And set it when you do need to read the counter in the main thread.


#5

How would you go by to make that event object to control it, I’ve tried reading forums and articles, but can’t wrap my mind around how to do it. That was one thing i wanted to do but could not try, creating custom events.

And if you could supply some code that would be great! Thank you.


#6

Here is the documentation on AutoResetEvent:

http://msdn.microsoft.com/en-us/library/hh434102.aspx

Looks like there is not much there.

Do something like this:


//Create event in non signaled state
AutoResetEvent readCountEvent = new AutoResetEvent(false);

In your counter read thread


while( true)
{
//this method blocks here, until the even is set 
readCountEvent.WaitOne();

//Read counter
...
}

To signal the event, when you need the counter thread to start reading, call:


//signal the event
readCountEvent.Set();


#7

Alright thank you, ill try this out as soon as i can, and ill reply once i have an answer.
Again thank you, you should get an answer by sunday! (Im fairly busy until saturday!)


#8

I am not in any hurry, just trying to help you.
:slight_smile:


#9

i’ve managed to create the threads, and they work great! here’s my code

Declaration of the Events:


AutoResetEvent ReadCount1Event = new AutoResetEvent(false);
AutoResetEvent Motor1StoppedEvent = new AutoResetEvent(false);

Declaration of the Thread:


            Thread Encoder1Thread = new Thread(Reader1.EncoderRead);
            Encoder1Thread.Priority = ThreadPriority.Highest;
            Encoder1Thread.Start();

when i press the Joystick:


        void joystick_JoystickPressed(Joystick sender, Joystick.JoystickState state)
        {
            Debug.Print("Joystick Pressed");
            if (Motordirection == Direction.Forward)
            {
                MotorMoving[0] = true;
                led7r.TurnLightOn(1, true);
                MotorController2.MoveMotor(MotorControllerL298.Motor.Motor1, -20);

                Reader1.StartRead.Set();
                Reader1.StopRead.WaitOne();
                MotorController2.MoveMotor(MotorControllerL298.Motor.Motor1, 0);
                Reader1.StopRead.Reset();

                Debug.Print("Motor Forward Complete");
                Motordirection = Direction.Backward;
            }
            else
            {
                MotorMoving[0] = true;
                led7r.TurnLightOn(1, true);
                MotorController2.MoveMotor(MotorControllerL298.Motor.Motor1, 20);
                MotorEncoder[1] = Encoder3.GetCount();

                Reader1.StartRead.Set();
                Reader1.StopRead.WaitOne();
                MotorController2.MoveMotor(MotorControllerL298.Motor.Motor1, 0);
                Reader1.StopRead.Reset();

                Debug.Print("Motor Backwards Complete");
                Motordirection = Direction.Forward;
            }


        }

the code in the thread:

public void EncoderRead()
        {
            while (true)
            {
                StartRead.WaitOne();
                LastCount = CurrentCount;
                CurrentCount = Encoder.GetCount();
                if(LastCount <= CurrentCount +50 && LastCount >=CurrentCount-50)
                {
                    StopRead.Set();
                }
            }
        }

but now i have another problem, the GetCount property of the PulseCounts do not return a value, yet when i observe the variable, the read variable in it has a value, as well as the write values! Why can’t i access that value (its private for some odd reason) and why is get count always giving back 0?

Again thank You for your assistance!!!


#10

Hi!

Are you trying wheel encoder?