| View previous topic :: View next topic |
| Author |
Message |
ginge Site Admin
Joined: 14 Jan 2006 Posts: 1029 Location: Manchester, UK
|
Posted: Mon Mar 01, 2010 11:47 pm Post subject: OpenServo v4 Software |
|
|
Okay Folks, we have started discussing the creation of a V4 hardware that pushes OpenServo forward with more and flasher features:
http://www.openservo.com/Forums/viewtopic.php?t=925
Now we need software.
The new OpenServo hardware is going to be based around the new Atmel XMEGA chipset, most probably the XMEGA32A4.
This poses some challenges in porting the existing OpenServo as well opening a new opportunity to rearchitect some of the "cruftier" code.
I think it would be reasonable to start by looking at the v3-dev tree for inspiration for the software.
Here is a quick rundown of where we are vs where we need to be. I will break down into bad code (concept or actual code) and good code (concept or actual)
Bad OpenServo Code
* I2C routines. Although we would need new I2C drivers anyway, the current method of reading writing I2C is not always atomic. Sometimes a value can be read from the registers during an interrupt while the I2C is writing. This is more pronounced when you do fast and constant IO.
We should strive to make the whole I2C read.write cycle either atomic or interrupt safe. We could use the DMA engine for this.
* Init code. In fact this is pretty terrible as it stands. Sometimes the servo does an almighty twitch before it settles. We had this almost right in the stock v3 and v3-dev but occasionally it crops up. We need to rearchitect the whole pin/port init to make sure it is a clean well understood mechanism.
* PID. v4 should have a new PID routine that has some better safeguards for overshoot and non-linearity. Thanks again to kbb.
* PWM. This is good but not perfect. the PWM module has to generate a single PWM at any one time while pulling the other channel low.
With the new xmega, we can do differential pulses with an automatic deadtime. This should give us more torque as we are using both sides of the bride at the same time.
* other targets. v3-dev has a massive feature dependancy tree so you can build for other targets. Although I don't think this was a bad thing on the whole, it needs a lot of simplifying. Some mechanisms are worth keeping, such as the automatic feature activation using single config files. This should allow the new hardware units to be activated easily.
Good OpenServo Code
* Banks. v3-dev has additional stuff in banks. This works for me, but isn't the easiest thing to understand. I would like to see this arranged better if only for clarity.
* the rest.
XMEGA oh-oh moments things we need to think about
Clocks in the xmega work differently. They give us much more control over timers. I personally would like to see the clock architecture overhauled, and I am sure kbb has some ideas here.
ADC is another factor. The XMEGA is 12 bit ADC. This means we can sample at much higher quality, meaning we need to adjust lots of chunks of code to deal with 12 bit. While we are doing this we should look at supporting 12 bit PWM too. The hires modules support it, and it would be nice to have.
Another big change that I am considering is using the motion engine as default. This has pros and cons that should be considered:
Pros
* It gives us free automatic speed control measured in 10ms intervals
* We can still use the modified PID to control the servo.
* we could add another register in to change the slope params to allow soft start and stop with S trapeziodal or cubic curves. Experiments to now has been met with mixed results. More research to follow.
cons
* The PID values start to become very small because the final position is now a very small moving target instead of a large fixed value. Becauseof this, we might even need to rewrite PID values with a different precision offset, such as 6:10 instead of 8:8
* it is pretty heavy on the math
New stuff
I would like to see serial supported by default, but this depends on the connector configuration and if we can squeeze 2x uarts on the header.
Bootloader
We need a new one. The old one is almost completely redundant with this new chip. Time for an overhaul with features:
* brownout detection. If we reset because of brownout, then just the timer wait and get straight into the application.
* instant boot without bootloader countdown. Not sure how yet, will need a pin to be bridged or something. Thoughts?
conclusions
We should try and keep as much of the v3-dev feature layout as possible. This is pretty future proofed with the banks, and should serve well with the additional ram.
I will be creatin some unit test cases for each module we need to port before starting the hardware port, so we need to think about large changes before the port proper starts. _________________ http://www.headfuzz.co.uk/
http://www.robotfuzz.co.uk/ |
|
| Back to top |
|
 |
kbb
Joined: 01 Jun 2007 Posts: 180
|
Posted: Thu Mar 04, 2010 12:50 am Post subject: Re: OpenServo v4 Software |
|
|
Loads of stuff to think about. Here are a few thoughts.
| ginge wrote: | | The new OpenServo hardware is going to be based around the new Atmel XMEGA chipset, most probably the XMEGA32A4. |
With all the new ideas around, I like the look of the ATXMEGA64A4, it has twice the flash and twice the EEPROM, and (at current prices for one-offs) is only 39p more! This seems reasonable for a considerable future proofing margin (in terms of what software features can be packed in). I would pay the extra 39p...
| ginge wrote: | | I2C routines. Although we would need new I2C drivers anyway, the current method of reading writing I2C is not always atomic. Sometimes a value can be read from the registers during an interrupt while the I2C is writing. This is more pronounced when you do fast and constant IO. We should strive to make the whole I2C read.write cycle either atomic or interrupt safe. |
There are probably several simple ways to fix that. One (slightly more complex) method that comes to mind is if register reading/writing was accomplished through a dispatch table with specialised functions (which possibly confers other advantages, but of course uses up memory, of which there is now more), the code could then be made safe against multi-byte registers being modified (host) whilst read (firmware) or read (host) whilst being modified (firmware) - which I assume is what the problem is. But whilst it is being discussed, do we continue to allow the host to part update a multi-byte register, such as “target position”?
| ginge wrote: | | We could use the DMA engine for this. |
Seems complicated! Also, I assume (suspect) that you can still read/write memory locations that are being shifted around via DMA, so you would still need to deal with the problem.
| ginge wrote: | | Clocks in the xmega work differently. They give us much more control over timers. I personally would like to see the clock architecture overhauled, and I am sure kbb has some ideas here. |
I feel that better and more consistent operation would be achieved if the basic PID and PWM existed as a software layer which is driven from a timer interrupt. Motion control code or velocity control/PIDs code would then communicate with this layer to indicate (for example) what the current position should be (probably based around some form of internal time-keeping clock, which should also feature as part of the new firmware).
| ginge wrote: | | ADC is another factor. The XMEGA is 12 bit ADC. This means we can sample at much higher quality, meaning we need to adjust lots of chunks of code to deal with 12 bit. While we are doing this we should look at supporting 12 bit PWM too. The hires modules support it, and it would be nice to have. |
That new PID stuff is already assuming a higher resolution pot position (and doesn’t it show in all the fiddling that is in there)! So it will be nice to clean it up. I think most/all things are using 16-bit registers to hold the existing 10-bit ADC values but they are dealing with just the raw numbers and not the “value” (for example 768 rather than an actual voltage). Loads of improvements come to mind... including more ADC sampling for the pot position...
The question above also raises the question as to whether things like the voltage register, when read by the host, should return a (calibrated) voltage (for example: 500 for 5V, 520 for 5.2V and so on), or the ADC measurement as currently happens. If voltage rather than ADC value, then this would be another advantage of the dispatch table mentioned at the top of this post.
| ginge wrote: | | Another big change that I am considering is using the motion engine as default. This has pros and cons that should be considered: [snip] |
It could be made selectable through a configuration register, there should be plenty of room for a “simple velocity algorithm”, like the one recently presented, and/or a simple Velocity PID.
| ginge wrote: | | * The PID values start to become very small because the final position is now a very small moving target instead of a large fixed value. Becauseof this, we might even need to rewrite PID values with a different precision offset, such as 6:10 instead of 8:8 |
Use floats or 32-bit integers. There should even be room to use 64-bit integers with the new CPU. The new CPU has better support for 16-bit and 32-bit integer maths, therefore things should be more efficient.
| ginge wrote: | | I would like to see serial supported by default, but this depends on the connector configuration and if we can squeeze 2x uarts on the header. |
I don’t think there shouldn’t be a “big” problem supporting one of either TWI, serial or SPI as long as only one is used at any one time, by sharing the pins. For example: pins 4, 5, 6 and 7 on port D are already shared with a USART and SPI port, so those 4 pins routed to the host connector allow for use of serial or SPI (but not “at the same time”). And I think if we’re careful with the design, we can connect a TWI bus directly to two of those 4 pins. If you don’t want to use the clock part of the serial bus, then you can get two on to the 4 pins... Otherwise more pins are needed...
User or programming errors could be made which might physically damage something, and we need to look at how the selection would be made by the user: possibly a jumper on board to select a default which can be changed from software as well.
The 4 pins do not include ground!
| ginge wrote: | | * brownout detection. If we reset because of brownout, then just the timer wait and get straight into the application. |
I think this aught to be a configuration option then. Personally I think I might prefer a servo that has suffered a browned (indicating that something may have gone awry) not to do anything, rather than start moving again.
| ginge wrote: | | * instant boot without bootloader countdown. Not sure how yet, will need a pin to be bridged or something. Thoughts? |
If you want to avoid the “bridge a pin method” (depends on now many pins are on the host connector), then the following seems like one possibility.
1: On boot, wait for “firmware update activity” for a configurable amount of time, the delay would normally be set to very short, such as 1/50 second. With co-operation from the boot loader application this means that if the firmware becomes “messed up” that there is a chance of getting it reflashed without having to resource to “ISP” to fix it. When working on the development of a new firmware at risk of getting stuck, one might increase the delay to account for this. A zero length delay could be set.
2: Probe for OpenServo firmware: if found launch it, if not enter the firmware update part of the boot loader. Provide a firmware reboot option that says “reboot to flash firmware” (possibly retaining the current device address), rather than just “reboot”.
3: Don’t monkey around with the device address. For example: “set default” should not change the device address as it currently does. The firmware should check the device address is valid and make it conform if it is not.
4: Optional complexity: Is there someway to have things check there aren’t duplicate devices on the bus and take some form of appropriate action? May depends on which bus type is being used.
5: Maybe a watchdog should be set to reset the system if it gets “stuck” whilst running the firmware, if the watchdog does trip, then the bootloader would wait for “firmware update activity” for several seconds?
So under normal circumstances (when things are not messed up) the “firmware updating utility” simply instructs the firmware to boot back in to the bootloader in “firmware updating mode”. |
|
| Back to top |
|
 |
kbb
Joined: 01 Jun 2007 Posts: 180
|
Posted: Thu Mar 04, 2010 1:05 am Post subject: Re: OpenServo v4 Software |
|
|
| kbb wrote: | Loads of stuff to think about. Here are a few thoughts.
| ginge wrote: | | The new OpenServo hardware is going to be based around the new Atmel XMEGA chipset, most probably the XMEGA32A4. |
With all the new ideas around, I like the look of the ATXMEGA64A4, it has twice the flash and twice the EEPROM, and (at current prices for one-offs) is only 39p more! This seems reasonable for a considerable future proofing margin (in terms of what software features can be packed in). I would pay the extra 39p... |
I have just noted that AVR Studio does not currently seem to have support for the ATxmega_64_A4... it is listed as being supported on their website, but does not appear in the device menu. I guess I will email them and see what's what. |
|
| Back to top |
|
 |
jharvey co-admin
Joined: 15 Mar 2009 Posts: 350 Location: Maine USA
|
Posted: Thu Mar 04, 2010 10:02 am Post subject: |
|
|
| About the boot loader, I don't mind the 3 second delay, but I do agree that in many situations it would be handy to make it go away. I like kbb's idea of a variable time that can be set to way low. Another idea would be to allow it to be turned on and off. Such that if you don't want it's delay and you've already programmed it, you simply turn it off. Then if you want it, you have to first turn it on, then make sure the time is long enough, then reboot. |
|
| Back to top |
|
 |
ginge Site Admin
Joined: 14 Jan 2006 Posts: 1029 Location: Manchester, UK
|
Posted: Thu Mar 04, 2010 5:50 pm Post subject: Re: OpenServo v4 Software |
|
|
| kbb wrote: | I like the look of the ATXMEGA64A4, it has twice the flash and twice the EEPROM, and (at current prices for one-offs) is only 39p more! This seems reasonable for a considerable future proofing margin (in terms of what software features can be packed in). I would pay the extra 39p...
|
I think at the current development rate, the 32 will be more than enough for the pre-built shop items. Nothing to stop us making both and adding 39p on 39p starts to add up when you get 1000's of them
| kbb wrote: | | There are probably several simple ways to fix that. One (slightly more complex) method that comes to mind is if register reading/writing was accomplished through a dispatch table with specialised functions (which possibly confers other advantages, but of course uses up memory, of which there is now more), |
You are right, there are many ways to look at this issue.A dispatch table is not a bad idea. I will look at the options here.
| kbb wrote: | | But whilst it is being discussed, do we continue to allow the host to part update a multi-byte register, such as “target position”? |
Good question. I think the answer should be no. I can't see a good enough reason to continue allowing this.
| kbb wrote: |
| ginge wrote: | | We could use the DMA engine for this. |
Seems complicated! Also, I assume (suspect) that you can still read/write memory locations that are being shifted around via DMA, so you would still need to deal with the problem.
|
As you probably guessed, I like the idea of the DMA silicon doing all of the work moving data to the registers. You bring up a good point with the above. I need to look at this a lot harder than I have been.
| Quote: | | I feel that better and more consistent operation would be achieved if the basic PID and PWM existed as a software layer which is driven from a timer interrupt. Motion control code or velocity control/PIDs code would then communicate with this layer to indicate (for example) what the current position should be (probably based around some form of internal time-keeping clock, which should also feature as part of the new firmware). |
I think I get the gist of what you are saying, but I would like for you to elaborate.
In previous versions of the OS, it was important for us to send the current position as close to the PID calculation as possible. This was achieved through an ADC timer that once conversion is completed, instantly feeds into the PID. in electronic terms the 10ms between calculations is an age. If we had a pot sample from the beginnig of the cycle and then fed that into PID we might be as much as 10ms behind the real pot reading. The ADC->PID synchronisation was done for a very good reason. It will be even more important in the v4 because we have 12bit ADC.
Now, we could let the ADC freewheel in the background, running at the maximum speed of somewhere in the region of 125 thousand samples per second (accross all channels). This would still leave a small area where the servo will lag.
The -dev branch used a heartbeat system that takes an adc sample every x ms, and then triggers the pid and pwm code in sequence.
Just something we need to think about.
| Quote: | The question above also raises the question as to whether things like the voltage register, when read by the host, should return a (calibrated) voltage (for example: 500 for 5V, 520 for 5.2V and so on), or the ADC measurement as currently happens.
|
I'm pretty easy on this one. I think that feature should be on the nice to have sheet, and would certainly be easy to do.
| kbb wrote: | | ginge wrote: | | * The PID values start to become very small because the final position is now a very small moving target instead of a large fixed value. Becauseof this, we might even need to rewrite PID values with a different precision offset, such as 6:10 instead of 8:8 |
Use floats or 32-bit integers. There should even be room to use 64-bit integers with the new CPU. The new CPU has better support for 16-bit and 32-bit integer maths, therefore things should be more efficient.
|
I was referring more in terms of Host->OpenServo access, or the OpenServo API rather than internal code.
| kbb wrote: | | Personally I think I might prefer a servo that has suffered a browned (indicating that something may have gone awry) not to do anything, rather than start moving again. |
I prefer the former, so let us do both. As jHarvey has pointed out, it could easily be a config variable. Now what would the safe default be?
| kbb wrote: | 1: On boot, wait for “firmware update activity” for a configurable amount of time, the delay would normally be set to very short, such as 1/50 second. With co-operation from the boot loader application this means that if the firmware becomes “messed up” that there is a chance of getting it reflashed without having to resource to “ISP” to fix it. When working on the development of a new firmware at risk of getting stuck, one might increase the delay to account for this. A zero length delay could be set.
|
We went there on the v1. It wasn't really a bad way to go with the 1/50th second timeout, but we never really got a grip on when to start talking to the cpu over the bus. Those AVRs take time to stabilise, and although a set of values worked for me, Mike in hotter climates had slightly different vales. Therefor the timeout was set high.
I like the idea of pulling aconnector pin low on startup to signal we need to go into the bootloader. I do something similar already with my off-tree branch so I can have them instantly come back online.
| kbb wrote: | 2: Probe for OpenServo firmware: if found launch it, if not enter the firmware update part of the boot loader. Provide a firmware reboot option that says “reboot to flash firmware” (possibly retaining the current device address), rather than just “reboot”.
|
Sounds like a good alternative. We can do that fairly easily with an eeprom flag.
Do we want to keep the current device address? What happens if we glitch, end up in the bootloader, and the host continues to write? We start overwriting the program memory. We could add additional stuff into the bootloader to stop this happening without an init sequence, but it adds more code. discuss
| kbb wrote: | | 3: Don’t monkey around with the device address. |
I'm sold. It goes in.
| Quote: | 4: Optional complexity: Is there someway to have things check there aren’t duplicate devices on the bus and take some form of appropriate action? May depends on which bus type is being used.
|
This would generally be done with a multimaster protocol. we tried to get multimaster working a couple of years ago, but between Mike and myself, we gave it up. The 168 is way too buggy with way too many corner cases to make it work well.
I think this should be on the 4.5 ideas list.
| Quote: | 5: Maybe a watchdog should be set to reset the system if it gets “stuck” whilst running the firmware, if the watchdog does trip, then the bootloader would wait for “firmware update activity” for several seconds?
|
We could roll this in with the brownout detection.
I will start getting some of this into the wiki. _________________ http://www.headfuzz.co.uk/
http://www.robotfuzz.co.uk/ |
|
| Back to top |
|
 |
kbb
Joined: 01 Jun 2007 Posts: 180
|
Posted: Thu Mar 04, 2010 9:26 pm Post subject: Re: OpenServo v4 Software |
|
|
| ginge wrote: | | kbb wrote: | | ginge wrote: | | * The PID values start to become very small because the final position is now a very small moving target instead of a large fixed value. Becauseof this, we might even need to rewrite PID values with a different precision offset, such as 6:10 instead of 8:8 |
Use floats or 32-bit integers. There should even be room to use 64-bit integers with the new CPU. The new CPU has better support for 16-bit and 32-bit integer maths, therefore things should be more efficient.
|
I was referring more in terms of Host->OpenServo access, or the OpenServo API rather than internal code. |
Me too Higher precision values could be sent from the host, the lack of precision and range is (probably) one of the problems with the current PID for high power servos. Whether the transfer remains in a fixed point “float” format, or uses a true floating point format probably doesn’t matter - cross platform support for floating point numbers is easy to arrange (on the host end). IEEE! |
|
| Back to top |
|
 |
kbb
Joined: 01 Jun 2007 Posts: 180
|
Posted: Thu Mar 04, 2010 10:00 pm Post subject: Re: OpenServo v4 Software |
|
|
| ginge wrote: | | kbb wrote: | | I feel that better and more consistent operation would be achieved if the basic PID and PWM existed as a software layer which is driven from a timer interrupt. Motion control code or velocity control/PIDs code would then communicate with this layer to indicate (for example) what the current position should be (probably based around some form of internal time-keeping clock, which should also feature as part of the new firmware). |
I think I get the gist of what you are saying, but I would like for you to elaborate.
In previous versions of the OS, it was important for us to send the current position as close to the PID calculation as possible. This was achieved through an ADC timer that once conversion is completed, instantly feeds into the PID. in electronic terms the 10ms between calculations is an age. If we had a pot sample from the beginnig of the cycle and then fed that into PID we might be as much as 10ms behind the real pot reading. The ADC->PID synchronisation was done for a very good reason. It will be even more important in the v4 because we have 12bit ADC.
Now, we could let the ADC freewheel in the background, running at the maximum speed of somewhere in the region of 125 thousand samples per second (accross all channels). This would still leave a small area where the servo will lag.
The -dev branch used a heartbeat system that takes an adc sample every x ms, and then triggers the pid and pwm code in sequence.
|
Yep, that’s essentially what I was previously suggesting and what I trying to imply above, I haven’t hammered out exactly what mechanism would be used.
Briefly: firstly, we arrange for “continuous” ADC sampling, every other sample to be used for super-sampling the pot (position) using a running N-slot average (N is a small number). The others samples are the “less important” battery volts, current, temperature... Then at the chosen rate, as soon as the latest pot sample/average is ready, it is that sample from within the ADC ISR which would trigger the PID that then feeds directly into the PWM control (rather than using a “heartbeat flag loop” running from a separate timer). For example: the Mth (to get the correct rate) sample for the POT would be used to trigger an event/lower-level interrupt which would run the PID algorithm and PWM control. Thus all the other activities that may be going on have considerably less of an impact on how tight and well timed the ADC(pot)-PID-PWM loop is. Loading of new parameters into the PID/PWM (be that a new target position or control parameters such as the gain) would be achieved using a signalling method. |
|
| Back to top |
|
 |
kbb
Joined: 01 Jun 2007 Posts: 180
|
Posted: Thu Mar 04, 2010 10:09 pm Post subject: Re: OpenServo v4 Software |
|
|
| ginge wrote: | Do we want to keep the current device address? What happens if we glitch, end up in the bootloader, and the host continues to write? We start overwriting the program memory. We could add additional stuff into the bootloader to stop this happening without an init sequence, but it adds more code. discuss  |
On the one hand, a boot loader should really have a defined protocol to stop that from happening. On the other the ATxmega32A4 has a 4KB boot loader with separate “lock bits” to protect it! |
|
| Back to top |
|
 |
ginge Site Admin
Joined: 14 Jan 2006 Posts: 1029 Location: Manchester, UK
|
Posted: Fri Mar 05, 2010 6:36 pm Post subject: |
|
|
I was more concerned about overwriting the openservo application code, not the bootloader! Either way, you point is taken that it should have a more defined protocol rather than the eeprom style interface we preset at the moment. _________________ http://www.headfuzz.co.uk/
http://www.robotfuzz.co.uk/ |
|
| Back to top |
|
 |
jharvey co-admin
Joined: 15 Mar 2009 Posts: 350 Location: Maine USA
|
Posted: Sat Mar 06, 2010 11:22 pm Post subject: |
|
|
I think "unexpected brown out detection" would be a handy feature in a new design. Or at least I would have found it handy in a recent issue I had.
The issue I had was relative to setting my power supply current limit to approximately .5 amps. The servo was not working hard just free wheeling the servo shaft only. My front end wasn't buffered enough, and the inrush was enough to cause a brown out, but not long enough to make the over current light on my supply light.
I couldn't help but think that at the end of the start up (EOS), a bit could be set that specifies that it's up and running. If EOS notices that that this bit is already set, it knows it browned out unexpectedly and stores an error indicator somewhere. Then when you want to do a normal power down, you turn off that bit, then kill power. This option would allow for a feature that perhaps isn't currently available. It would be a handy feature for diagnostic, or failure detection.
I wonder is there a better way to detect power supply issues? I know my supply shouldn't be soggy, but if it is, can it be detected and acted upon? |
|
| Back to top |
|
 |
ginge Site Admin
Joined: 14 Jan 2006 Posts: 1029 Location: Manchester, UK
|
Posted: Sun Mar 07, 2010 12:56 pm Post subject: |
|
|
| jharvey wrote: | I think "unexpected brown out detection" would be a handy feature in a new design. Or at least I would have found it handy in a recent issue I had.
|
It is pretty simple to implement. The AVR has an internal register that is set on conditions causing reboot. It has flags for Brown Out Detection, Watchdog Timer, and user request.
We then filter these on boot and take the right action.
Forexample we could use the user reset request to mean we should go into the bootloder mode, and not jump into the application.
We need to think of a good signalling scheme, and decide if using the internal flags is enough, or if we need to use an eeprom flag.
| jharvey wrote: |
I wonder is there a better way to detect power supply issues? I know my supply shouldn't be soggy, but if it is, can it be detected and acted upon? |
Maybe, but tricky. You are better off doing that on the host. Monitor current and voltage and plot them on a graph. Compare to a good PSU. You should quickly see the differences in response. Design an algorithm around this difference (it is pretty linear) and port it to the openservo. _________________ http://www.headfuzz.co.uk/
http://www.robotfuzz.co.uk/ |
|
| Back to top |
|
 |
ginge Site Admin
Joined: 14 Jan 2006 Posts: 1029 Location: Manchester, UK
|
Posted: Sun Mar 07, 2010 1:05 pm Post subject: ADC |
|
|
Okay folks, let's talk about ADC and clocks.
I have some working PWM code along with some crude TWI code, so now we need to talk about the trickier aspects: Timings.
So:-
ADC is set in freewheel sample mode for the position with supersampling on the values.
After a clock timeout, we keep the last x pot samples, and trigger a high priority interrupt to calculate the PID.
PID then triggers another interrupt to change the PWM.
With the interrupt triggering the conversion and output generation, we are not relying on flags and waiting for things to happen. This makes it a lot more asynchronous, but makes the critical regions more susceptible to overlapping interrupts.
Kbb, Is this anything like your proposal?
Questions
What speed are we going to run the new PID loop? I assume we are going for the same 10ms?
[b]oes anyone use the timer value as exposed by the API? (Power saving is going to be looked over at some point.)
Does anyone have any suggestions before I go ahead and implement some clocks? _________________ http://www.headfuzz.co.uk/
http://www.robotfuzz.co.uk/ |
|
| Back to top |
|
 |
kbb
Joined: 01 Jun 2007 Posts: 180
|
Posted: Mon Mar 08, 2010 9:18 pm Post subject: Re: ADC |
|
|
| ginge wrote: | Okay folks, let's talk about ADC and clocks.
I have some working PWM code along with some crude TWI code, so now we need to talk about the trickier aspects: Timings.
So:-
ADC is set in freewheel sample mode for the position with supersampling on the values.
After a clock timeout, we keep the last x pot samples, and trigger a high priority interrupt to calculate the PID.
PID then triggers another interrupt to change the PWM.
With the interrupt triggering the conversion and output generation, we are not relying on flags and waiting for things to happen. This makes it a lot more asynchronous, but makes the critical regions more susceptible to overlapping interrupts.
kbb, Is this anything like your proposal? |
Again, loads of potential methods.
As I am not currently writing any code, or in a position hardware wise to try, here is some very broad brush stroke "pseudo" code of what I was suggesting, based on there being a timer (running off the ADC interrupt would be another way of doing it, but will potentially consume more CPU resources).
| Code: | ISR Timer_highpriority()
{
if(IsTimeForPIDUpdatingRun()) // This is how you set the interval
{
potValue=0
potCount=16 // Some configurable number, super-sampling count or for average, etc
enableADC()
}
}
ISR ADC()
{
if(potCount<=0)
{
otherResults=ADCResult
} else
potValue=putValue+ADCResult
potCount=potCount-1
if(potCount==0)
{
triggerPIDPWMInterruptOrEvent(lowerpriority)
}
}
if(!moreSamplesNeeded)
{
disableADC()
}
}
ISR/EVENT PIDPWM_lowerpiority()
{
calculatePID()
updatePWM()
} |
NOTE: We don’t need to keep N values...
NOTE: A perfectionist is probably enabling/disabling the ADC as indicated by the names, rather than continually "starting a conversion". If it was run from the ADC interrupt, with the ADC free wheeling, then an approach to the reducing the extra use of resources would be to throw the extra samples away (ignore them and return from the ISR as fast a possible) in "ISR ADC()".
| ginge wrote: | | , but makes the critical regions more susceptible to overlapping interrupts. |
I don't think it will be a problem unless inappropriate timing is chosen? Maybe a flag can/should be added to detect interrupt over-run. The same issue exists in the existing code if you try to make it run too frequently.
Edit: I am of the opinion a flag should be implemented so that the code can self-check that it has not be caused to reenter itself and take appropriate action: ignore the “call” that time, set an error bit in a status register.
Last edited by kbb on Tue Mar 09, 2010 8:57 am; edited 1 time in total |
|
| Back to top |
|
 |
kbb
Joined: 01 Jun 2007 Posts: 180
|
Posted: Mon Mar 08, 2010 9:31 pm Post subject: Re: ADC |
|
|
| ginge wrote: | | What speed are we going to run the new PID loop? I assume we are going for the same 10ms? |
How frequently should it “fire” (rather to avoid the loop as it exists in the existing code, see above)... I don’t know, I think it depends on what the new hardware/firmware is capable of - from the stuff I was doing on the V3 code I suspect: the faster the better, the more accurate in time the better. Although I doubt the individual winnings themselves multiply out.
| ginge wrote: | | Does anyone use the timer value as exposed by the API? |
I have used it, but not for overly important reasons. I cannot think of a reason to exclude it from being available tho. |
|
| Back to top |
|
 |
ginge Site Admin
Joined: 14 Jan 2006 Posts: 1029 Location: Manchester, UK
|
Posted: Sun Mar 14, 2010 10:22 am Post subject: |
|
|
hi guys.
I have most of the OpenServo modules working in real hardware (XMEGA32D4)
It has taken longer than expected as I have had to rewrite the avr-libc ioxm32d4.h include header to fill in a bunch of missing registers (grr)
The scheme I am currently testing is ADC in freewheel mode, running at 800khz.
The ADC is running at 4x the system timer in order to get all channel samples before the interrupt.
| Code: |
ISR Timer_highpriority()
{
if(IsTimeForPIDUpdatingRun()) // This is how you set the interval
{
triggerPIDPWMInterruptOrEvent(lowerpriority)
}
}
ISR ADC() //freewheeling int he background at 800khz
{
position = takeSample()
addToRollingAverage(position)
}
ISR/EVENT PIDPWM_lowerpiority()
{
position = getPosition()
calculatePID(position)
updatePWM()
}
|
I will run some tests on the hardware to try and find corner cases, or see how long the sample to calculation time is.
The TWI slave module is up and running. I have multimaster mode enabled in hardware, so I will see if we can utillise this.
I have also written in the hardware support for the secondary TWI master module, ready for the OpenEncoder to drop in.
The PWM module is giving me a bit of grief at the moment due the the complexity f timings using the new AWEX module, but I have it almost right. Trying to emulate the setup we have with regards to the PWM hardware is a nightmare, as the PWM_DIV value etc no longer map into the same meaningful values. I will bring this one back up once it looks like it is closer to working. _________________ http://www.headfuzz.co.uk/
http://www.robotfuzz.co.uk/ |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|