
Interruptions whit the timers
#1
Posted 21 January 2013 - 03:10 PM
#2
Posted 21 January 2013 - 03:27 PM
#3
Posted 21 January 2013 - 08:20 PM
What PWM frequency are you using?
I'm using a frecuency of 52 Hz.
I don't have another U3 how ever I could go to the lab in my faculty in use the osciloscope.Do you know what the resulting signal looks like? What is wrong with it? Perhaps if you have another U3, you could use LJStreamUD to capture a data set with the signals so we can see what they are doing.
Post a little code snippet that shows where you update the PWM duty-cycle every 100ms. Perhaps we will see something there.
In the code a program a little funtion that allows to change the duty-cycle named Servomotor, the funtion gets and the angle and move the rotor of the Servo. In another funtion I call this funtion every 100ms. code it's this ones.
public void Medicion() { while (true){ E = (Ref * 3.1416 / 180) - (angulo * 3.1416 / 180); U = ((Kp + (To * Ki)) * E) - (Kp * Eant) + Uant; Eant = E; if (U > 3.1416) { U = 3.1416; } if (U < 0) { U = 0; } Uant = U; Servomotor(Ref); //This it's the funtion that change the duty cicle. double dblDriverVersion; LJUD.IO ioType = 0; LJUD.CHANNEL channel = 0; double dblValue = 0; int dummyInt = 0; double dummyDouble = 0; dblDriverVersion = LJUD.GetDriverVersion(); try { //Request a single-ended reading from AIN0. LJUD.AddRequest(u3.ljhandle, LJUD.IO.GET_AIN, 0, 0, 0, 0); } catch (LabJackUDException a) { showErrorMessage(e); } try { //Execute the requests. LJUD.GoOne(u3.ljhandle); LJUD.GetFirstResult(u3.ljhandle, ref ioType, ref channel, ref dblValue, ref dummyInt, ref dummyDouble); } catch (LabJackUDException a) { showErrorMessage(e); } try { LJUD.GetNextResult(u3.ljhandle, ref ioType, ref channel, ref dblValue, ref dummyInt, ref dummyDouble); } catch (LabJackUDException a) { showErrorMessage(e); } angulo = dblValue * 46.59 - 10.16; AIN0 = (int)angulo; this.SetText(AIN0.ToString()); tiempo = tiempo + To; this.SetChart(chart1); Thread.Sleep(100); } }
and this it's the code of the funtion Servomotor. what I do it's calculate the ns that I'll send to the PWM16 funtion for the angle I get. I tested that funtion before and it worked fine, but if you see and error please let me know.
public void Servomotor(double angulo) { LJUD.IO ioType = 0; LJUD.CHANNEL channel = 0; double dblValue = 0; // Variables to satisfy certain method signatures int dummyInt = 0; double dummyDouble = 0; double[] dummyDoubleArray = { 0 }; double ns, tao,grad; grad = angulo * 180 / 3.1416; tao = (0.00001 * grad + 0.000565); ns = (0.01911 - tao) * (65536 / 0.01911); try { //First requests to configure the timer and counter. These will be //done with and add/go/get block. //Set the timer/counter pin offset to 4, which will put the first //timer/counter on FIO4. LJUD.AddRequest(u3.ljhandle, LJUD.IO.PUT_CONFIG, LJUD.CHANNEL.TIMER_COUNTER_PIN_OFFSET, 4, 0, 0); //Use the 48 MHz timer clock base with divider. Since we are using clock with divisor //support, Counter0 is not available. LJUD.AddRequest(u3.ljhandle, LJUD.IO.PUT_CONFIG, LJUD.CHANNEL.TIMER_CLOCK_BASE, (double)LJUD.TIMERCLOCKS.MHZ48_DIV, 0, 0); //LJUD.AddRequest(u3.ljhandle, LJUD.IO.PUT_CONFIG, LJUD.CHANNEL.TIMER_CLOCK_BASE, LJUD.TIMERCLOCKS.MHZ24_DIV, 0, 0); //Use this line instead for hardware rev 1.20. //Set the divisor to 48 so the actual timer clock is 1 MHz. LJUD.AddRequest(u3.ljhandle, LJUD.IO.PUT_CONFIG, LJUD.CHANNEL.TIMER_CLOCK_DIVISOR, 14, 0, 0); //LJUD.AddRequest(u3.ljhandle, LJUD.IO.PUT_CONFIG, LJUD.CHANNEL.TIMER_CLOCK_DIVISOR, 24, 0, 0); //Use this line instead for hardware rev 1.20. //Enable 1 timer. It will use FIO4. LJUD.AddRequest(u3.ljhandle, LJUD.IO.PUT_CONFIG, LJUD.CHANNEL.NUMBER_TIMERS_ENABLED, 1, 0, 0); //Configure Timer0 as 16-bit PWM. Frequency will be 1M/256 = 3906 Hz. LJUD.AddRequest(u3.ljhandle, LJUD.IO.PUT_TIMER_MODE, 0, (double)LJUD.TIMERMODE.PWM16, 0, 0); //Set the PWM duty cycle LJUD.AddRequest(u3.ljhandle, LJUD.IO.PUT_TIMER_VALUE, 0, ns, 0, 0); //Execute the requests. LJUD.GoOne(u3.ljhandle); } catch (LabJackUDException e) { showErrorMessage(e); } //Get all the results just to check for errors. try { LJUD.GetFirstResult(u3.ljhandle, ref ioType, ref channel, ref dblValue, ref dummyInt, ref dummyDouble); } catch (LabJackUDException e) { showErrorMessage(e); } bool finished = false; while (!finished) { try { LJUD.GetNextResult(u3.ljhandle, ref ioType, ref channel, ref dblValue, ref dummyInt, ref dummyDouble); } catch (LabJackUDException e) { // If we get an error, report it. If the error is NO_MORE_DATA_AVAILABLE we are done if (e.LJUDError == UE9.LJUDERROR.NO_MORE_DATA_AVAILABLE) finished = true; else showErrorMessage(e); } } }
#4
Posted 22 January 2013 - 09:25 AM
#5
Posted 22 January 2013 - 05:33 PM
#6
Posted 23 January 2013 - 08:41 AM
First thing I would try is to add a new function that just updates the Value (duty-cycle) of Timer0. So, rename you current Servomotor() function to ServomotorConfig(), and make a new function called ServomotorDutyCycleUpdate(). In this new function, just do something like:
LJUD.ePut(u3.ljhandle, LJUD.IO.PUT_TIMER_VALUE, 0, ns, 0);
... with nothing else.
When you do the full timer configuration it resets the timer each time, which could be causing you a problem that you can see in the motor. When you just use ePut to update the timer Value, you are changing the duty-cycle without a full reset of the timer. This can still have glitching depending on the exact timing of where the PWM is at when the duty-cycle update comes in, but should be smoother than what you have now.
I try this but I still have the same problem. Lets see if it works whit the PWM8...
#7
Posted 23 January 2013 - 09:03 AM
The glitching I describe is when you get a cycle with totally different PWM than you have specified. For example, you want to change from 25% to 75%, but get 1 cycle of 50% in-between.
In 16-bit PWM, firmware looks at the current state of the cycle to try and make the change without a glitch, but it is not foolproof.
In 8-bit PWM, there are actually 2 separate registers, so 8-bit does not glitch. Try using 8-bit if you think such a glitch might be your problem.
I try the PWM8 and I still had the same problem. I don't know what else to do. I did a lot of testing and I realize the problem started when I use the angle I'm getting from the sensor, I meassure this value whit the labjack and then whit the controler send the signal. So it's there any way the problem could that I'm sending a signal that comes from the AIN0??
#8
Posted 23 January 2013 - 09:11 AM
#9
Posted 23 January 2013 - 05:36 PM
First I would make a log of the "ns" values you are sending to the ePut PUT_TIMER_VALUE call. Record a few seconds of values when the servo is not behaving as expected and post these values here.
Then, if those values look good to you, you will need to acquire the PWM signal using a scope or similar to see if the signal agrees with the values you are commanding.
I chec the ns and also try sending a different PWM signal every 100ms, I used a Ref and every 100 ms a incresed the Ref, the motor work just fine. the code goes like this.
while (true){ Ref = Ref + 5; Servomotor(Ref); Thread.Sleep(100); }
So I try ussing the value from the AIN0 and send it, it's the same thing I did in the previos code but know ussing the value token from the LabJack, it goes like this
while (true){ Medicion(); //now I have the current angle Servomotor(AIN0+5); Thread.Sleep(100); }
this should at lest move the motor until the 180° which it's the limit. but just keep moving like crazy. any ideas I can try. I think the function Servomotor it's working fine but somenthing happen when I interact whit the value reading from the LabJack and used to send a new signal to the servomotor.
#10
Posted 23 January 2013 - 09:53 PM
Say you use 16-bit PWM with TimerClockBase = 48 MHz/div and TimerClockDivisor = 14. That results in a PWM8 frequency of 52.3 Hz:
http://labjack.com/s...s-guide/2.9.1.1
That is a period of 19.115 ms, so to get a pulse-width of 1-2 ms you need a duty cycle of about 5.2% to 10.4%. That means you want the time low to be 94.8% to 89.6%, which means you need to pass a Timer Value that varies from 62128 to 58720.
In the code you sent, you say you are passing a Timer Value of AIN0+5. If your AIN0 reading varies from 0-5V, that means you are passing a Timer Value of 5 to 10, which will not get you a 1-2 ms pulse.
#11
Posted 24 January 2013 - 05:18 AM
No the funtion Servomotor it's one that I program my self, I used a ecuation to transfor the Angle of the Potenciometer to the tao, which it's the representation of duty cycle in miliseconds and previosly I obtain, the ns that that it's a value between 63000 and 57500 the. I'm ussing an standar ServoMotor the Hitec HS-311. it goes like this. the servomotor I'm ussing gets a pulse-width from 0.5 to 2.3 ms.What type of servo is this? Typically an R/C servo wants a ~50Hz signal with a pulse-width that varies from 1 ms to 2 ms.
Say you use 16-bit PWM with TimerClockBase = 48 MHz/div and TimerClockDivisor = 14. That results in a PWM8 frequency of 52.3 Hz:
http://labjack.com/s...s-guide/2.9.1.1
That is a period of 19.115 ms, so to get a pulse-width of 1-2 ms you need a duty cycle of about 5.2% to 10.4%. That means you want the time low to be 94.8% to 89.6%, which means you need to pass a Timer Value that varies from 62128 to 58720.
In the code you sent, you say you are passing a Timer Value of AIN0+5. If your AIN0 reading varies from 0-5V, that means you are passing a Timer Value of 5 to 10, which will not get you a 1-2 ms pulse.
public void Servomotor(double angulo) { LJUD.IO ioType = 0; LJUD.CHANNEL channel = 0; double dblValue = 0; // Variables to satisfy certain method signatures int dummyInt = 0; double dummyDouble = 0; double[] dummyDoubleArray = { 0 }; double ns, tao,grad; grad = angulo * 180 / 3.1416; tao = (0.00001 * grad + 0.000565); ns = (0.01911 - tao) * (65536 / 0.01911);
This are the firts line of the funtion Servomotor. so I get the angle. an the obtain the ns and that the value I send to the timer. but the AIN0 it's not a value betwen 5 or 0 I have the ecuation that translate the voltage of the potenciometer to the angle in degrees.
angulo = dblValue * 46.59 - 10.16; AIN0 = (int)angulo;
dblValue it's the value that comes directly from the potenciometre through the Labjack, and then I obtain the angle.
#12
Posted 24 January 2013 - 09:21 AM
while (true) { eGet(handle, LJ_ioGET_AIN, 0, &volts, 0); DutyCycle = (5500*(volts/5.0)) + 57500; //assuming AIN0 reading is 0-5V printf(DutyCycle); ePut(handle, LJ_ioPUT_TIMER_VALUE, 0, DutyCycle, 0); wait(100); }
Connect AIN0 to a fixed steady voltage between 0 and 5V for this test.
#13
Posted 24 January 2013 - 11:39 AM
while (true) { eGet(handle, LJ_ioGET_AIN, 0, &volts, 0); ePut(handle, LJ_ioPUT_TIMER_VALUE, 0, 60000, 0); wait(100); }
#14
Posted 27 January 2013 - 08:34 PM
And if that still has problems try an even simpler loop:
while (true) { eGet(handle, LJ_ioGET_AIN, 0, &volts, 0); ePut(handle, LJ_ioPUT_TIMER_VALUE, 0, 60000, 0); wait(100); }
Nothing, I still have the same problem I have try everything and I don't know what else can I do. I really need to fix this problem. How can I control the interruptions of the LabJack??
#15
Posted 28 January 2013 - 11:05 AM
while (true) { ePut(handle, LJ_ioPUT_TIMER_VALUE, 0, 60000, 0); wait(100); }
Have you been able to use a scope to look at the PWM signal in both cases?
#16
Posted 28 January 2013 - 11:43 AM
while (true) { eGet(handle, LJ_ioGET_AIN, 0, &volts, 0); ePut(handle, LJ_ioPUT_TIMER_VALUE, 0, 60000, 0); wait(100); }
With or without the LJ_ioGET_AIN in the loop made no difference. Either way I got a solid 52 Hz signal with ~8% duty-cycle. Don't see anything unusual.
#17
Posted 29 January 2013 - 04:09 PM
I just did a test in LabVIEW. I have UD driver V3.32 and U3 firmware V1.45. I configured 1 timer on FIO4 as 16-bit PWM with TimerClockBase = 48 MHz/div and TimerClockDivisor = 14. I then had the basic test loop:
while (true) { eGet(handle, LJ_ioGET_AIN, 0, &volts, 0); ePut(handle, LJ_ioPUT_TIMER_VALUE, 0, 60000, 0); wait(100); }
With or without the LJ_ioGET_AIN in the loop made no difference. Either way I got a solid 52 Hz signal with ~8% duty-cycle. Don't see anything unusual.
I fix the problem, Thanks for the help.
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users