[SOLVED] FEZ Mini with Existing Car motor

Hi William, thanks for looking.

I just tested your code, and it is running, but;

When I call Drive(5) or Drive(50) or every other number, the ESC runs always fullpower.

Have changed, again so many times, the period and neutral, forward, reverse settings to:

            // Declare timings for Electronic Stability Control (ESC)
            const int PERIOD = 20000; //Us
            const int NEUTRAL = 1400; //1500us = 1.5ms
            const int FULLFORWARD = 1550;
            const int FULLREVERSE = 1200;

And it looks like it is working now. Have to check reverse for couple of times but, i can configure forward from Drive(5) to drive very slow to Drive(100) for fullpower.

Have to work now, but will test more in the evening (in about 10 hours from now.

Well let you know.

Btw, William, can you explain “OC is started on full blast in ctor” some more for me?

Thanks!

In the constructor (i.e. ctor). The OutputCompare was created with state to true - or full speed. This should be false.

public SpeedController(FEZ_Pin.Digital pin)
            {
                //
                // Create Output Compare Object
                //
                oc = new OutputCompare((Cpu.Pin)pin, true, 2);
            }

It is also possible that the added Stop and Sleep in the ctor helped to “arm” the esc. Not sure. You can comment out the Stop and Thread.Sleep and see if it still works without it and let me know as I am curious.


    public SpeedController(FEZ_Pin.Digital pin)
    {
        // Start OC low (not full blast).
        oc = new OutputCompare((Cpu.Pin)pin, false, 2);
 
        // "Arm" the ESC. Guessing this might be required for ESC, but should not hurt if not.
        Stop();
        Thread.Sleep(500);
    }

Not clear on your last post. I sounds like you got it working forward and back - great news!!
Is anything not working?

Hi William,

Well, is it working, but not very well, like i said, the timings are now:

            const int NEUTRAL = 1400; //1500us = 1.5ms
            const int FULLFORWARD = 1550;
            const int FULLREVERSE = 1200;

Going to check your new code snippet in a minute. Removing Stop and Sleep in public SpeedController.

Be back in a minute :wink:

One general question, when the Stop command is called, the timing is Neutral (1500 us), but this is not a stop signal, this is a Neutral signal, so no reverse and no forward.
How can i stop the motor running immediately? Having Ramp speed in the function? (speed++ and speed–).

This is what i’ve got now. Code look running fine now. I really don’t et why I had to change the fullforward, fullreverse and netural timings, to what i’ve got now. Maybe this isn’t something that could be explaind :wink:

//
// Import Namespaces
//
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.Hardware;
//
// FEZ NETMF Namespace
//
namespace GHIElectronics.NETMF.FEZ
{
    //
    // FEZ_Components Partial Class
    //
    public static partial class FEZ_Components
    {
        //
        // SpeedController Class
        //
        public class SpeedControllerWilliam : IDisposable
        {
            readonly OutputCompare oc;
            readonly uint[] timings = new uint[2];
            int currentSpeed;

            // Declare timings for Electronic Stability Control (ESC)
            const int PERIOD = 20000;
            const int NEUTRAL = 1400;
            const int FULLFORWARD = 1550;
            const int FULLREVERSE = 1200;

            public SpeedControllerWilliam(FEZ_Pin.Digital pin)
            {
                // Start OC low (not full blast = false).
                oc = new OutputCompare((Cpu.Pin)pin, false, 2);
            }

            public void Dispose()
            {
                Stop();
                oc.Dispose();
            }

            public void Drive(int speed)
            {
                if (speed < -100 || speed > 100) throw new ArgumentOutOfRangeException("speed");

                // Gradually ramp up/down speed until we match given value.
                int rampDir = (speed > currentSpeed) ? 1 : -1;

                while (speed != currentSpeed)
                {
                    uint newSpeed = (uint)ScaleRange(currentSpeed, -100, 100, FULLREVERSE, FULLFORWARD);
                    SetSpeed(newSpeed);
                    currentSpeed = currentSpeed + rampDir;
                    Debug.Print("New Speed:" + currentSpeed + " (" + newSpeed + ")");
                    Thread.Sleep(10);
                }

            }

            public void Stop()
            {
                Drive(0);
            }

            private void SetSpeed(uint speedUs)
            {
                timings[0] = speedUs;
                timings[1] = PERIOD;
                oc.Set(true, timings, 0, 2, true);
            }

            private static int ScaleRange(int oldValue, int oldMin, int oldMax, int newMin, int newMax)
            {
                return ((oldValue - oldMin) * (newMax - newMin) / (oldMax - oldMin)) + newMin;
            }
        }
    }
}

Took some pictures of the assambled RC Car. (without the sensors ;-))

Picture 1;

Picture 2;

The following components are assembled:

  • FEZ Mini (including Controller and Power Circuit Board)
  • Servo for Steering
  • ESC Speed Controller

Todo:

  • Ultrasonic Sensor (Front)
  • Sharp IR Sensor (Left & Right)
  • Sharp IR Sensor (Back, not in stock :wink:
  • GPS with UART (Navigator, not in stock :wink:

So how fast are we?

Gus, In Km/h or what? :wink:

I have created a Code Project:

http://code.tinyclr.com/project/290/rc-car-esc-speed-controller/

Congrats! :smiley:

“I really don’t et why I had to change the fullforward, fullreverse and netural timings, to what i’ve got now. Maybe this isn’t something that could be explaind”

The 1ms - 2ms range for servos and esc is rule of thumb. The fine details vary between devices. If you don’t have scope then trial and error can work also. Glad it working for you.

I am now curious if the ramping “while” is required here? The ESC should be doing this internally if it was required. I would not think the receiver or transmitter is doing this when your just plain RC mode?
Does it work without the ramping?

Well do some more test with and without the ramping code. I do remember that when I don’t use ramping, neutral timing is not directly a ‘stop’ command, but neutral (e.g. no gas ;-)). But i will do some more tests this evening.

About the timings, thanks for explaining. And also thanks for your help.

Ramping does not seem related to neutral or stop. Stop should just be oc.Set(false); - yes?

EDIT: Sorry - Misread something, ignore this :).

Xarren, :wink:

William, crystal clear, will check it when I am back at home (at work now ::))

@ Colin, Your program features such as the speedcontroler.drive method will block this function, you really have to remove. With your current solution will control the car and future sensor expansion not show enough CPU time for a proper response this.
This certainly applies to the Thread.Sleep function in your main procedure. In a non Car excessive speed of 1 km / hour (= 30 cm / sec) you will still get hard enough to respond to a floor line.
Good luck with your project.

“speedcontroler.drive method”, you mean the ramping stuff in it, and the Thread.Sleep(10)?
Like i said, will remove it and test it.

Or isn’t this what you ment?

In my program for the DC motor I use a separate thead for it.