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.
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?
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
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
//
// 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;
}
}
}
}
“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.
@ 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.