SMALL - espritmodel.com SMALL - Telemetry SMALL - Radio
Reply
Thread Tools
Old Feb 12, 2013, 07:55 AM
Registered User
United States, NC, Raleigh
Joined Oct 2011
788 Posts
Quote:
Originally Posted by noobee View Post
i thought a bit more about the 3ms interrupt-disabled period for sending out servo pulses. i think it's possible to improve that a little.

- assume that all servo pulses need to be between 1000us and 2000us.
- start by setting all servo channels to high
- program an interrupt exactly 1000us or min pulse width later
- during the ISR, busy wait for each channel and set it to low, for up to 1000us.

the exposure to jitter is 1/4 compared to emitting the channels individually and the interrupt-disable period is at most 1000us.

what do you think?

btw. increase the gain high enough and fly fast enough and the plane should start oscillating
UPDATE 2 Ignore the next two paragraphs. If we are ready to generate output pulses, we should not see another PCINT0 ISR until the next frame. So there should be no issue - Good thing based on Odysis post 272 about the possibility of an interrupted interrupt not resuming.

This is my first experience using the ATmega parts and it is not clear to me how the interrupt priority system works (if there is one). Normally, only a higher priority interrupts can interrupt a lower priority interrupt. If the priority order is the order of the vectors then a timer interrupt cannot interrupt a PCINT0 interrupt.

If this is the case then the MOD_PCINT0 code should probably be used to minimize delaying the timer interrupt.

When would you start the outputs, after the last stabilized channel has been captured?

When we have the times for all three outputs and are ready to set them all high, can't we capture the timer, calculate the 3 timer values for the 3 stop times and schedule the first interrupt at the precise time for the shortest pulse, then the next latter pulse and then the last pulse. We have to be able to handle all 3 pulses ending at the same time and remember which channel gets turned off with which interrupt.

I need to think about this a little more.

I looked at the OpenAero code a little closer and it does not always disable interrupts, however when it does not disable interrupts it knows everything is in sync and the assembler output routine will not be disturbed. The assembler routine is a loop that takes a fixed number of cycles to execute and the timing is done by the number of iterations through the loop.

UPDATE
The 168PA does have an interrupt priority system. From the full specification.

"A flexible interrupt module has its control registers in the I/O space with an additional Global Interrupt Enable bit in
the Status Register. All interrupts have a separate Interrupt Vector in the Interrupt Vector table. The interrupts have
priority in accordance with their Interrupt Vector position. The lower the Interrupt Vector address, the higher the
priority."


John
JohnRB is online now Find More Posts by JohnRB
Last edited by JohnRB; Feb 12, 2013 at 12:26 PM. Reason: Update info on PCINT0 Interrupt
Reply With Quote
Sign up now
to remove ads between posts
Old Feb 12, 2013, 11:31 AM
Life begins at transition
Australia, VIC, Sale
Joined May 2007
3,593 Posts
It does, but they're fixed, and not really workable.
Something in the back of my mind says in an ISR is interupted, it never gets resumed?
Odysis is offline Find More Posts by Odysis
Reply With Quote
Old Feb 12, 2013, 12:28 PM
Registered User
United States, NC, Raleigh
Joined Oct 2011
788 Posts
Quote:
Originally Posted by Odysis View Post
It does, but they're fixed, and not really workable.
Something in the back of my mind says in an ISR is interupted, it never gets resumed?
That does not sound good.

I updated my post above about this not being an issue as no additional input pulses should be received until the next start of frame.

John
JohnRB is online now Find More Posts by JohnRB
Reply With Quote
Old Feb 12, 2013, 12:38 PM
Registered User
idonasch's Avatar
Germany, Berlin
Joined Jun 2004
71 Posts
Interrupt priorties, or the lack of...

let me elaborate a little on interrupt priorities and what it means. "real" cpus have interrupt priorities in the sense that a pending interrupt source signals which level it would like to interrupt the cpu and the cpu has an interrupt level it is running at. only if the IRQ level is higher then that of the cpu the interrupt is executed. in this case interrupts can be nested if a higher priority interrupt fires while the ISR of a lower priority interrupts is serviced (which automatically sets the CPU irq level to that of the serviced interrupt, and gets restored to its previous value on the reti)
this is not to be confused with the interrupt "priority" on the atmega which has only a single interrupt level(==priority) controlled by the interrupt mask bit. what atmel means with priority is the order of precedence an interrupt is serviced when more then one are pending. lower vector number interrupts get serviced first, the others stay pending until the mcu releases the interrupt mask (which is done with the reti instruction) atmega's just have a 1-level interrupt priority!
this implies that interrupts can not be nested and the stack utilization is deterministic. of course you can open the interrupt mask in the ISR and allow pending interrupts to be serviced, but this can also be the same interrupt source you're just servicing and then you're in big doodoo (unless you disable that specific interrupt source). with that little ram I have I would be very very very reluctant to that!
these chips were never meant to do what we are using them for. the chip designers provided input/output capture mechanisms for that purpose but the board designers failed to utilize the few dedicated pins for this. only the input capture on timer1 is available and can be used for precise CPPM frame capture. (maybe also 2 of the outputs, if I recall correctly). and doing 2ms output compares with 1us resolution on a 8-bit timer is also a little bit tricky but at least you would get ~200usec to service the interrupt without introducing any jitter.
(update)
on the V1 elev/rud outputs can easily be done with the 16-bit output capture, if ele/rud inputs are rearranged they can also be used for outputs (with some trickery) and the ail input can act as CPPM catures. in cppm mode and the mentioned reassignment of ports we can make the whole thing 100% jitter free with hardware support. beyond that we have to compromise.
on the V2 we also have the aux-input we can use for hardware assisted output.
(/update)
idonasch is offline Find More Posts by idonasch
Last edited by idonasch; Feb 12, 2013 at 12:50 PM.
Reply With Quote
Old Feb 13, 2013, 07:49 AM
Registered User
Joined Dec 2006
1,437 Posts
right now, there is no detection for the "last rx pulse in the frame". it's just synced to the ELE pulse.

yes, it is possible to fire all 3 servo out at the same time, with 2 followon options in the isr.

- option 1, just handle the immediate pulse and schedule the next isr. this option might be vulnerable to jitter especially if all servo output are the same around 1500ms for example.

- option 2, busy wait and handle all the pulses until the very last one. this option reduces the likelihood of jitter but when it happens, all servos will see the same amount. the other advantage is that the interrupt-disable time is less (max 1ms) compared to busy waiting for the full 2+ms.

in any case, i think scheduling the servo output to be out of the way of rx processing (or after the last pulse) should be a good way to avoid interference. then there's no need to deal with preemption, etc. the tradeoff is that the latency between rx pulse and corresponding servo output is slightly higher. the best option is to use hardware, which is somewhat tricky with the current layout (and timer resource).

i think we might be over optimizing this aspect


Quote:
Originally Posted by JohnRB View Post
When would you start the outputs, after the last stabilized channel has been captured?

When we have the times for all three outputs and are ready to set them all high, can't we capture the timer, calculate the 3 timer values for the 3 stop times and schedule the first interrupt at the precise time for the shortest pulse, then the next latter pulse and then the last pulse. We have to be able to handle all 3 pulses ending at the same time and remember which channel gets turned off with which interrupt.
noobee is offline Find More Posts by noobee
Reply With Quote
Old Feb 13, 2013, 08:31 AM
Registered User
Joined Dec 2006
1,437 Posts
a small update:

i'm working on 3 features next:

1. enabling support on nano_wii. here is the pin mapping as far as i can tell. learnt a huge lesson: never mix arduino pin numbering with port register access. it's all scrambled on the leonardo. there's no LED on the "standard" location too.

Code:
/*
 Nano WII
 PB0 17    (SS/RXLED)    |                        | PD0  3 SCL (SCL)   |                   | PF0 23/A5    (ADC0)
 PB1 15 RX (SCK/PCINT1)  |                        | PD1  2 SDA (SDA)   |                   | PF1 22/A4    (ADC1)
 PB2 16 RX (MOSI/PCINT2) |                        | PD2  0 RXD (RXD)   | PE2       (HWB_)  |
 PB3 14 RX (MISO/PCINT3) |                        | PD3  1 TXD (TXD)   |                   |
 PB4  8 RX (PCINT4)      |                        | PD4  4  SV (ADC8)  |                   | PF4 21/A3 SV (ADC4)
 PB5  9  M (OC1A/OC4B_)  |                        | PD5        (TXLED) |                   | PF5 20/A2 SV (ADC5)
 PB6 10  M (OC1B/OC4B)   | PC6  5  M (OC3A/OC4A_) | PD6 12     (OC4D_) | PE6  7 RX (INT.6) | PF6 19/A1 SV (ADC6)
 PB7 11  M (OC0A/OC1C)   | PC7 13  M (OC4A)       | PD7  6   M (OC4D)  |                   | PF7 18/A0 SV (ADC7)
*/
the core functionality is almost working now. rx in (need to confirm the rx channel mapping), servo out, mpu6050 gyro-only access. cppm and led are still not working. and there's no VR or DIP switches, which brings us to the next feature below.

2. stick config
this one seems important for nano_wii unless we are willing to modify the source for the specific function (mix and aileron modes, as well as VR gains) and program from the IDE (the nano_wii has a arduino bootloader, so i don't want to mess with the ISP programmer).

3. "short term" attitude hold
after doing experiments with simply adding rate to obtain position (or relative attitude), i believe that's how other systems are advertising "3d hold" with just a gyro. the question is how to organize the rate control loop with the attitude control loop, and how to enable/disable this feature in the air. i'm quite keen on this one as it does not look too hard at this time
noobee is offline Find More Posts by noobee
Last edited by noobee; Feb 13, 2013 at 08:49 AM.
Reply With Quote
Old Feb 13, 2013, 11:36 AM
Registered User
United States, NC, Raleigh
Joined Oct 2011
788 Posts
Quote:
Originally Posted by noobee View Post
right now, there is no detection for the "last rx pulse in the frame". it's just synced to the ELE pulse.

yes, it is possible to fire all 3 servo out at the same time, with 2 followon options in the isr.

- option 1, just handle the immediate pulse and schedule the next isr. this option might be vulnerable to jitter especially if all servo output are the same around 1500ms for example.

- option 2, busy wait and handle all the pulses until the very last one. this option reduces the likelihood of jitter but when it happens, all servos will see the same amount. the other advantage is that the interrupt-disable time is less (max 1ms) compared to busy waiting for the full 2+ms.

in any case, i think scheduling the servo output to be out of the way of rx processing (or after the last pulse) should be a good way to avoid interference. then there's no need to deal with preemption, etc. the tradeoff is that the latency between rx pulse and corresponding servo output is slightly higher. the best option is to use hardware, which is somewhat tricky with the current layout (and timer resource).

i think we might be over optimizing this aspect
I agree, I think this really is over optimization.

I thought about it a little more yesterday. Starting all of the outputs and then sorting the widths have a lot of available time for processing (RX_WIDTH_MIN). The problem that concerns me is outputs that fall very close to each other in time. Those would have to be detected and done in a wait loop. Too much delay exiting one interrupt and starting another.

At best 2ms of delay can be avoided for the 2nd (usually 1.5ms) output and 4ms of delay for the 3rd (usually 3ms). With the "precision" that I fly with, I would never notice the difference.

With my bench setup (DX8 & Orange RX 6CH) I am only seeing a maximum of 2us. jitter over a 5 minute period. In addition, the jitter is so infrequent I never see the servo move or hear any sounds being emitted from the servo. This is an order of magnitude better than the original firmware.

It might be just best to detect last channel and start the outputs serially at that time. There should be no other activity except for time compares from the output generation which will not induce jitter (they are generating the output pulses) and timer1 overflows.

I measured the timer compare interrupt execution times yesterday and the first four interrupts vary from about 17.4us to 19.32us with the last interrupt around 10.92us.

The timer1 overflows are 3us and occur every 32.768ms (500ns steps).

All of the times are for 16MHz operation.

I don't think altering the hardware is an alternative - it would greatly limit the number of people that can take advantage of the new firmware. As you already know, only 2 of the outputs (elevator & rudder) are on PWM channels and they are on 8 bit counters so games in firmware are still required.

Do you know of any cases where other interrupts can come in between the end of the last pulse in a frame and the start of a new frame?

John
JohnRB is online now Find More Posts by JohnRB
Reply With Quote
Old Feb 13, 2013, 12:12 PM
Registered User
United States, NC, Raleigh
Joined Oct 2011
788 Posts
Quote:
Originally Posted by noobee View Post
a small update:
1. enabling support on nano_wii. here is the pin mapping as far as i can tell. learnt a huge lesson: never mix arduino pin numbering with port register access. it's all scrambled on the leonardo. there's no LED on the "standard" location too.

Code:
/*
 Nano WII
 PB0 17    (SS/RXLED)    |                        | PD0  3 SCL (SCL)   |                   | PF0 23/A5    (ADC0)
 PB1 15 RX (SCK/PCINT1)  |                        | PD1  2 SDA (SDA)   |                   | PF1 22/A4    (ADC1)
 PB2 16 RX (MOSI/PCINT2) |                        | PD2  0 RXD (RXD)   | PE2       (HWB_)  |
 PB3 14 RX (MISO/PCINT3) |                        | PD3  1 TXD (TXD)   |                   |
 PB4  8 RX (PCINT4)      |                        | PD4  4  SV (ADC8)  |                   | PF4 21/A3 SV (ADC4)
 PB5  9  M (OC1A/OC4B_)  |                        | PD5        (TXLED) |                   | PF5 20/A2 SV (ADC5)
 PB6 10  M (OC1B/OC4B)   | PC6  5  M (OC3A/OC4A_) | PD6 12     (OC4D_) | PE6  7 RX (INT.6) | PF6 19/A1 SV (ADC6)
 PB7 11  M (OC0A/OC1C)   | PC7 13  M (OC4A)       | PD7  6   M (OC4D)  |                   | PF7 18/A0 SV (ADC7)
*/
What is the number 17 after PB0 reference? It is not the 168PA module pin number or the pin designation on my Arduino Nano board.

John
JohnRB is online now Find More Posts by JohnRB
Reply With Quote
Old Feb 13, 2013, 12:18 PM
Registered User
United States, NC, Raleigh
Joined Oct 2011
788 Posts
Quote:
Originally Posted by noobee View Post
2. stick config
this one seems important for nano_wii unless we are willing to modify the source for the specific function (mix and aileron modes, as well as VR gains) and program from the IDE (the nano_wii has a arduino bootloader, so i don't want to mess with the ISP programmer).
How does this work? Do you hold some stick(s) at extremes when the receiver is turned on? If so, how do you know when to let them go for calibration? In some cases the LED may not be visible (mounted under wing).

John
JohnRB is online now Find More Posts by JohnRB
Reply With Quote
Old Feb 13, 2013, 12:43 PM
Registered User
idonasch's Avatar
Germany, Berlin
Joined Jun 2004
71 Posts
Stick configuration

Quote:
Originally Posted by JohnRB View Post
How does this work? Do you hold some stick(s) at extremes when the receiver is turned on? If so, how do you know when to let them go for calibration? In some cases the LED may not be visible (mounted under wing).

John
I already implemented a crude way of configuration for the KK port. attached are the code snipplets and here is the short description:

/*
* enters stick configuratom mode when at powerup elv/ail/rud sticks in any extrem position:
* (stick < STICK_CONFIG_LO || stick > STICK_CONFIG_HIGH )
*
* with elev down (North)
* (NW) and ail/rud left (West) configures aileron mode DUAL, mix mode VTAIL
* (NE) and ail/rud right(East) configures aileron mode DUAL, mix mode DELTA
* with elev up (South)
* (SW) and ail/rud left (West) configures aileron mode SINGLE, mix mode VTAIL
* (SE) and ail/rud right(East) configures aileron mode SINGLE, mix mode DELTA
* configurations are stored in EEPROM and become initial settings on powerup
*
* stick configuration mode is left when sticks are centered. then center calibration is performed.
*
* modifies n_wiggle to show operation mode on elevator.
* pulls up for single aileron mode
* pushes down for dual aileron mode
* steps mode
* ----- ----------
* 1 MIX_NORMAL
* 2 MIX_DELTA
* 3 MIX_VTAIL
*
* returns true while in stick calibration.
*/


Feel free to use it. worked quite well on the KK board.
idonasch is offline Find More Posts by idonasch
Reply With Quote
Old Feb 13, 2013, 01:11 PM
Registered User
United States, NC, Raleigh
Joined Oct 2011
788 Posts
Quote:
Originally Posted by idonasch View Post
I already implemented a crude way of configuration for the KK port. attached are the code snipplets and here is the short description:
Thank you, I did not think about waiting for sticks to return to center to start calibration.

John
JohnRB is online now Find More Posts by JohnRB
Reply With Quote
Old Feb 13, 2013, 10:43 PM
Registered User
Joined Dec 2007
544 Posts
Quote:
Originally Posted by idonasch View Post
on the V2 we also have the aux-input we can use for hardware assisted output.
Do you already have a soft for the hardware generated stuff? I can see only 2 output channels generated by the 16 bit timer 1. Timer1 would also serve CPPM icp input?

The other timers are 8 bit, and that aint enough to run the whole 20ms cycle. These timers would have to be started by software, right ?
Cesco is offline Find More Posts by Cesco
Reply With Quote
Old Feb 14, 2013, 12:55 AM
Registered User
Joined Dec 2006
1,437 Posts
this is the nanowii board with the atmega32u4 processor: http://flyduino.net/Multikopter-FC-Multiwii_1

this link is apparently more controversial: http://www.hobbyking.com/hobbyking/s..._GYRO_ACC.html

i already ordered it before hearing about the issue in another thread: http://www.rcgroups.com/forums/showthread.php?t=1814075

it compiles as the arduino leonardo. the 17 is the arduino pin number.

the atmega32u4 is quite different from the atmega168pa/328. built-in usb is useful as well as the small footprint. the board also comes with the mpu6050, which is great.



Quote:
Originally Posted by JohnRB View Post
What is the number 17 after PB0 reference? It is not the 168PA module pin number or the pin designation on my Arduino Nano board.

John
noobee is offline Find More Posts by noobee
Reply With Quote
Old Feb 14, 2013, 01:04 AM
Registered User
Joined Dec 2006
1,437 Posts
looks great!

i might also consider the scheme that guardian uses (a list of index and ranged value pairs).

this brings me to another issue. somehow the guardian can ensure that the tx direction is deterministic (eg left == 1100 and right == 1900), which means channel reversing for them must apply to the tx signal as well. if this is the case, then i think HK actually got the reversing logic right by forcing the user to reverse channels on the tx when necessary. otherwise, it is not possible to perform stick config consistency (stick to the left might be interpreted as to the right).

UPDATE:

i guess it is possible to use the gain direction on the device to derive the intent of the tx direction. this is easy if we had discrete switches to indicate "reverse", harder if we used the VR knob for direction (since the user could try to zero it to eliminate correction in that axis) and not possible for devices without switches or VRs (in this case, i think a connection to the PC GUI would be needed).


UPDATE 2:
reread the guardian manual again. turns out it can also encounter the same issue if the tx is reversed. then the stick directions for the menu are all reversed. hmmm, can we do better?


Quote:
Originally Posted by idonasch View Post
I already implemented a crude way of configuration for the KK port. attached are the code snipplets and here is the short description:

/*
* enters stick configuratom mode when at powerup elv/ail/rud sticks in any extrem position:
* (stick < STICK_CONFIG_LO || stick > STICK_CONFIG_HIGH )
*
* with elev down (North)
* (NW) and ail/rud left (West) configures aileron mode DUAL, mix mode VTAIL
* (NE) and ail/rud right(East) configures aileron mode DUAL, mix mode DELTA
* with elev up (South)
* (SW) and ail/rud left (West) configures aileron mode SINGLE, mix mode VTAIL
* (SE) and ail/rud right(East) configures aileron mode SINGLE, mix mode DELTA
* configurations are stored in EEPROM and become initial settings on powerup
*
* stick configuration mode is left when sticks are centered. then center calibration is performed.
*
* modifies n_wiggle to show operation mode on elevator.
* pulls up for single aileron mode
* pushes down for dual aileron mode
* steps mode
* ----- ----------
* 1 MIX_NORMAL
* 2 MIX_DELTA
* 3 MIX_VTAIL
*
* returns true while in stick calibration.
*/


Feel free to use it. worked quite well on the KK board.
noobee is offline Find More Posts by noobee
Last edited by noobee; Feb 14, 2013 at 10:53 PM.
Reply With Quote
Old Feb 14, 2013, 10:21 AM
Registered User
United States, NC, Raleigh
Joined Oct 2011
788 Posts
Quote:
Originally Posted by noobee View Post
this is the nanowii board with the atmega32u4 processor: http://flyduino.net/Multikopter-FC-Multiwii_1

this link is apparently more controversial: http://www.hobbyking.com/hobbyking/s..._GYRO_ACC.html
I thought it might be a different board than the Nano I have. I did a search yesterday for Nano wii and did not locate anything. I should have left out the space.

Do you have a schematic for this board? If you do I will go through it and locate and label all of the pins for you. I found a real old schematic on the Multiwii forum but it does not have the board pins listed.

That board seems a bit pricy. The Acro Naze 32 board http://abusemark.com/store/index.php...12c3a70e385515 is a little smaller with a much more powerfully processor for about $22 US. The boards I have include 2 accelerometers with the ADXL345 being disabled by default. I think the earlier design used the Analog Devices part and the latest design uses the InvenSense MPU6050 which is enabled. I don't know why 2 were populated.

John
JohnRB is online now Find More Posts by JohnRB
Reply With Quote
Reply


Thread Tools

Similar Threads
Category Thread Thread Starter Forum Replies Last Post
Sold Flight Stabilization System with Programing Card Woody_99 Aircraft - Electric - Helis (FS/W) 1 Mar 23, 2012 12:50 PM
Sold Flymentor Flight Stabilization with Field Programmer Woody_99 Aircraft - General - Radio Equipment (FS/W) 0 Mar 17, 2012 07:43 AM
Sold Totally Tricked out 400 size with flight stabilization installed, BNF Woody_99 Aircraft - Electric - Helis (FS/W) 2 Mar 12, 2012 06:56 AM
Wanted FY-30A Flight Stabilization System Casey_S FPV Equipment (FS/W) 0 Mar 05, 2012 02:40 PM