Hello all,
I am intended to manage a PID o PANDA II (or at least a Proportional error correction in a first time) ? The final goal is to display time on fez touch in seconds while controlling the PID (input : the speed of the motor is given by a sensor wich can pulse up to 200hz , output : a PWM wich sets the speed of the motor)
The issue is that in C# managed code, when I install an interrupt for counting time between two pulses, the interrupt seems to be disrupted by other tasks running in main process and so It doesn’t measure the correct interval of time. i.e, every second a little buffer is sent to fez touch screen, and that cause lack of precision on the interval time between two pulses of the motor
static void motor_OnInterrupt(uint data1, uint data2, DateTime time)
{
lSystemTickCurrentUs = Utility.GetMachineTime().Ticks;
fDelayMotorUs = lSystemTickCurrentUs - lSystemTickPreviousUs;
lSystemTickPreviousUs = lSystemTickCurrentUs;
fDutyCycleFiltered = (fDutyCycleFiltered + fDutyCycle * 0.02f) / 1.02f; //filtering for minimizing the lack of precision
if (fDutyCycleFiltered > 100) { fDutyCycleFiltered = 100; }
pwmMotor.Set(Param.iPWMFreqHz, (byte)fDutyCycleFiltered);
fDutyCycle = fDelayMotorUs / KP;
}
Indeed I know that .NET MicroFramewoek is not for reaI time, also decided to manage the PID process in native code for best performances : for the moment, I start with an interrupt wired on my motor sensor ; and I would like to get system tick in order to get time measurement between two pulse. Is there a way to get system tick directly in my interrupt or should I create a timer wich will invrement a value periodically?
Here is how I start at the moment :
// RLP_PID.c
#include "./RLP_User/RLP.h"
void isr(unsigned int Pin, unsigned int PinState, void* Param )
{
// change the pin state just for exemple and checking that interrupt works
state = !state;
RLPext->GPIO.WritePin(pin, state);
// Here I would get an absolute time in order to process a P(ID) control
}
// CSharp Method
// byte[] barray = new byte[];
// PID_c.Invoke(uint [] generalArray,byte[] byteArray, byte filler);
int PID_c(unsigned int *generalArray, void **args, unsigned int argsCount, unsigned int *argSize)
{
//SETUP MOTOR INTERRUPT
pin = *(unsigned char*)args[0];
state = *(unsigned char*)args[1];
RLPext->GPIO.EnableOutputMode(pin, state);
RLP_InterruptInputPinArgs ia;
ia.GlitchFilterEnable = RLP_FALSE;
ia.IntEdge = RLP_GPIO_INT_EDGE_LOW;
ia.ResistorState = RLP_GPIO_RESISTOR_PULLUP;
RLPext->GPIO.EnableInterruptInputMode(20, &ia, isr, 0); // 20 :Pin D0 motor pulse will fire the interrupt
return 0 ;
}
How to get tick from there?
I guess next steps for me are :
- find a way to get the tick or the period between two interrupts
2)control PWM with PWM0xxx registers
3)process a light PI control
Any help/tips/suggestions would be appreciated!