Closed Myzhar closed 8 years ago
I think the problem is in https://github.com/officinerobotiche/uNAV.X/blob/develop/src/system/interrupts.c#L174
Now I don't have time and a correct setup to test this problem at low speeds. @Myzhar or @katodo If you have time, I am happy to help me :smile:
@guiott How have you solved this problem in your board?
I don’t exactly know if the problem could be the same. To expand the dynamic range of the Input Capture I vary its Mode in this way: http://www.guiott.com/Lino/Speed/DynamicIC.htm http://www.guiott.com/Lino/Speed/DynamicIC.htm
Il giorno 25/gen/2015, alle ore 19:24, Raffaello Bonghi notifications@github.com ha scritto:
@guiott https://github.com/guiott How have you solved this problem in your board?
— Reply to this email directly or view it on GitHub https://github.com/officinerobotiche/uNAV.X/issues/36#issuecomment-71384528.
@guiott I'm sure that the problem is generated by overflows in the 16bit counter, so the solution is exactly in changing the prescaler. If you look at the screenshoots that I posted on hangout you can see the big oscillations at low speeds...
According to this:
https://github.com/officinerobotiche/uNAV.X/blob/develop/src/system/system.c#L334 https://github.com/officinerobotiche/uNAV.X/blob/develop/src/system/system.c#L334
it seems that the IC is already configured at max events detection. Even if the comment says “every rising edge”, ICM = 1 means every rising and falling edge. But there still is margin on this:
https://github.com/officinerobotiche/uNAV.X/blob/develop/src/system/system.c#L333 https://github.com/officinerobotiche/uNAV.X/blob/develop/src/system/system.c#L333
halving the interrupt time with ICx = 0
Il giorno 25/gen/2015, alle ore 21:09, Walter Lucetti notifications@github.com ha scritto:
I do not know if it works, I try to attach the screenshoot at the email Il 25/Gen/2015 20:11 "Guido" notifications@github.com ha scritto:
I don’t exactly know if the problem could be the same. To expand the dynamic range of the Input Capture I vary its Mode in this way: http://www.guiott.com/Lino/Speed/DynamicIC.htm < http://www.guiott.com/Lino/Speed/DynamicIC.htm>
Il giorno 25/gen/2015, alle ore 19:24, Raffaello Bonghi < notifications@github.com> ha scritto:
@guiott https://github.com/guiott How have you solved this problem in your board?
— Reply to this email directly or view it on GitHub < https://github.com/officinerobotiche/uNAV.X/issues/36#issuecomment-71384528>.
— Reply to this email directly or view it on GitHub https://github.com/officinerobotiche/uNAV.X/issues/36#issuecomment-71386750 .
— Reply to this email directly or view it on GitHub https://github.com/officinerobotiche/uNAV.X/issues/36#issuecomment-71390154.
Of course also the timer2 prescaler can be modified to not overflow in case of a very long delay between two edges of the ICx. Currently it's at 1:1 value, meaning a short time before overflowing. All the chain must be recalculated to have the best range. E.g.: lowering the pulses from the ICx (ICM) and increasing the prescaler in medium to high RPM in order to have the possibility to change ICM at a very low speed.
@guiott I have a big doubt: I noticed that we use the same timer (TMR2) for events on IC1 and IC2. Could this lead to problems when events on IC1 and IC2 are synchronous?
Could this lead to problems when events on IC1 and IC2 are synchronous?
I think is an exceptional event, but the problem is on overflow variable control on IC interrupt routine.
Raffaello
Il giorno 26/gen/2015, alle ore 08:25, Walter Lucetti notifications@github.com ha scritto:
@guiott I have a big doubt: I noticed that we use the same timer (TMR2) for events on IC1 and IC2. Could this lead to problems when events on IC1 and IC2 are synchronous?
— Reply to this email directly or view it on GitHub.
I’m asking to @rbonghi how the timer is used. If it’s used in free running mode there are no problems at all. In this case the only care to take on is on flagging separately the overflow for the two ICs: https://code.google.com/p/dspid4w/source/browse/trunk/dsPID4W.X/src/dsPID4W.c#1265 https://code.google.com/p/dspid4w/source/browse/trunk/dsPID4W.X/src/dsPID4W.c#1265
And then to reset the appropriate flag when you’ll use the TMR2 value to measure the time: https://code.google.com/p/dspid4w/source/browse/trunk/dsPID4W.X/src/dsPID4W.c#1315 https://code.google.com/p/dspid4w/source/browse/trunk/dsPID4W.X/src/dsPID4W.c#1315
for IC1 and: https://code.google.com/p/dspid4w/source/browse/trunk/dsPID4W.X/src/dsPID4W.c#1348 https://code.google.com/p/dspid4w/source/browse/trunk/dsPID4W.X/src/dsPID4W.c#1348
for IC2.
In fact the TMR2 is used separately by the two ICx just to get a snapshot of its value in ICxBUF registers when the ICx interrupt occurs. Meanwhile the timer is running freely with no care about who is using its register.
See a brief description here: https://code.google.com/p/dspid4w/source/browse/trunk/dsPID4W.X/src/descrEng.txt#290 https://code.google.com/p/dspid4w/source/browse/trunk/dsPID4W.X/src/descrEng.txt#290
and here: https://code.google.com/p/dspid4w/source/browse/trunk/dsPID4W.X/src/descrEng.txt#211 https://code.google.com/p/dspid4w/source/browse/trunk/dsPID4W.X/src/descrEng.txt#211
See Microchip application note AN545 for a detailed discussion about different modes can be used.
Il giorno 26/gen/2015, alle ore 08:25, Walter Lucetti notifications@github.com ha scritto:
@guiott https://github.com/guiott I have a big doubt: I noticed that we use the same timer (TMR2) for events on IC1 and IC2. Could this lead to problems when events on IC1 and IC2 are synchronous?
— Reply to this email directly or view it on GitHub https://github.com/officinerobotiche/uNAV.X/issues/36#issuecomment-71422475.
Ok, my doubt came from STm32 because it starts and stops the timer automatically at raising and falling events and I do not use it in freerun mode
I was looking at the code... The variable overTmrL is used here: https://github.com/officinerobotiche/uNAV.X/blob/develop/src/system/interrupts.c#L179 declared here https://github.com/officinerobotiche/uNAV.X/blob/develop/src/system/interrupts.c#L50 and finally incremented here https://github.com/officinerobotiche/uNAV.X/blob/develop/src/system/interrupts.c#L239
Are you sure that this mechanism works? What about if we have an overflow at the very beginning of the startup when the motors are really really slow?
I think that it should must be incremented at every overflow...
Sorry, I've not understood. The only reason for what the TMR2 triggers an interrupt is when the register overflows over 2^16. The TMR2 register is initialized at the beginning to 0XFFFF before enabling it and its interrupt. So, the variable is always incremented at the right moment.
@rbonghi Isn't it?
Il giorno 26/gen/2015, alle ore 16:37, Walter Lucetti <notifications@github.com mailto:notifications@github.com> ha scritto:
I was looking at the code... The variable overTmrL is used here: https://github.com/officinerobotiche/uNAV.X/blob/develop/src/system/interrupts.c#L179 https://github.com/officinerobotiche/uNAV.X/blob/develop/src/system/interrupts.c#L179 declared here https://github.com/officinerobotiche/uNAV.X/blob/develop/src/system/interrupts.c#L50 https://github.com/officinerobotiche/uNAV.X/blob/develop/src/system/interrupts.c#L50 and finally incremented here https://github.com/officinerobotiche/uNAV.X/blob/develop/src/system/interrupts.c#L239 https://github.com/officinerobotiche/uNAV.X/blob/develop/src/system/interrupts.c#L239 Are you sure that this mechanism works? What about if we have an overflow at the very beginning of the startup when the motors are really really slow?
I think that it should must be incremented at every overflow...
— Reply to this email directly or view it on GitHub https://github.com/officinerobotiche/uNAV.X/issues/36#issuecomment-71479491.
:+1:
My double is on the control "if (timePeriodL)". This means that if "timePeriodL" (as for timePeriodR naturally) is zero (starting condition), the overflow is not takes into account.
If the robot moves at very low speed we can have overflows without incrementing the variable "overTmrL".
It is a limit case, but it can happens!
Let’s ask to @rbonghi
in my version there isn’t such a check https://code.google.com/p/dspid4w/source/browse/trunk/dsPID4W.X/src/dsPID4W.c#1265 https://code.google.com/p/dspid4w/source/browse/trunk/dsPID4W.X/src/dsPID4W.c#1265
Il giorno 27/gen/2015, alle ore 09:37, Walter Lucetti notifications@github.com ha scritto:
My double is on the control "if (timePeriodL)". This means that if "timePeriodL" (as for timePeriodR naturally) is zero (starting condition), the overflow is not takes into account.
If the robot moves at very low speed we can have overflows without incrementing the variable "overTmrL".
It is a limit case, but it can happens!
— Reply to this email directly or view it on GitHub https://github.com/officinerobotiche/uNAV.X/issues/36#issuecomment-71609369.
I agree with that code. I think that I understood the code enough to start to try to solve this issue.
@guiott
I have a doubt. I read with great care your code and I think that I found a possible problem. It is a limit case, but it can happen.
We use the same timer (TMR2) for both IC1 and IC2, so when we change the scale factor we affect the speed measures of both the motors because we use the same KVel.
What does it happen when a motor is moving really slow and the other really fast? This is the case of the rotation on the place using a wheel as rotation pin...
I stated this according to this line of code: https://code.google.com/p/dspid4w/source/browse/trunk/dsPID4W.X/src/dsPID4W.c#665
I'm not changing the TMR2 prescaler but the input capture mode of each single ICx. I.e. the way it's triggered by the encoder pulses: every edge every rising edge every 4th rising edge every 16th rising edge
If you look at here:
https://code.google.com/p/dspid4w/source/browse/trunk/dsPID4W.X/src/dsPID4W.c#553 https://code.google.com/p/dspid4w/source/browse/trunk/dsPID4W.X/src/dsPID4W.c#553
you can see that I change the ICx prescaler according to the speed of every single wheel, even in different way if the run differently.
Il giorno 28/gen/2015, alle ore 19:13, Walter Lucetti <notifications@github.com mailto:notifications@github.com> ha scritto:
@guiott https://github.com/guiott I have a doubt. I read with great care your code and I think that I found a possible problem. It is a limit case, but it can happen.
We use the same timer (TMR2) for both IC1 and IC2, so when we change the scale factor we affect the speed measures of both the motors.
What does it happen when a motor is moving really slow and the other really fast? This is the case of the rotation on the place using a wheel as rotation pin...
— Reply to this email directly or view it on GitHub https://github.com/officinerobotiche/uNAV.X/issues/36#issuecomment-71885220.
ok, but this is usefull for high speed encoder, no for speed near 0, it's right?
Mauro Soligo by Sony Xperia Z
It's useful anyway to expand the dynamic range of the input capture peripherals. You can find the right values for TMR2 and ICx modes in order to find the best compromise for your system.
Keep in mind that you have a 16 bit timer. Using carefully the overflow bit you can expand this to a larger (equivalent) value but it's still a limited value.
Using the ICx modes too you can further expand the dynamic (by a value of 32) finding a good value for both high speed (let's say every 16th rising edge) avoiding to much interrupts that can overflow the MCU capabilities, still maintaining a good range at very low speed where you are able to catch every single edge of the encoders.
All of that still keeping an high rate of speed sampling to have a very responsive PID control.
Il giorno 28/gen/2015, alle ore 20:03, Katodo notifications@github.com ha scritto:
ok, but this is usefull for high speed encoder, no for speed near 0, it's right?
Mauro Soligo by Sony Xperia Z — Reply to this email directly or view it on GitHub https://github.com/officinerobotiche/uNAV.X/issues/36#issuecomment-71894227.
Hello guys! I've an idea to improve the quality of estimation for velocity. In according with, http://www.officinerobotiche.it/tutorial/encoder/ (sorry is an italian page) on "Metodi per calcolare la velocità", we've two different type of estimate velocity from encoders.
If we'll use in both we should decrease the error at low velocity. :smile: I remember that 2 type of measure is "free" because we'll add a little function to evaluate this number.
I using https://github.com/officinerobotiche/uNav_PID_Tuner and I look a strange curve. When the second motor cross zero, the control output on motor zero generate a different number.
@Myzhar
After a few test using the PID tuner I faced that using a 400 CPR encoder there are really serious problems reading speeds below 1 rad/sec. Once the motor exceeds 1 rad/sec the PID starts working very well and the speeds are read correctly.