Sorry for the really late reply, I'm answering this in case someone ever has the same question and stumbles upon this :)
If I ever find the time I will add this to the library...
I recently got the same question by email, so here's my copy/paste answer:
PPM output works best with pins 9-10 since they're directly tied to
Timer 1. As timer 1 generates an interrupt, the hardware will
automatically toggle the value on either pin 9 or 10. However, it's
not that hard to make PPMOut use a different pin, you just need to
toggle the pin you want manually in the interrupt handler. For this
you need to make some changes to PPMOut.cpp:
-In PPMOut::start(), change uint8_t pin = p_a ? 9 : 10; to the pin
number you want and remove this line: rc::Timer1::setToggle(true,
p_a);
-In PPMOut::isr(), toggle your output pin on the first line of that function.
void PPMOut::isr()
{
// fill this in yourself
// set the compare register with the next value
OCR1A += m_timings[m_timingPos];
// update position
++m_timingPos;
if (m_timingPos >= m_timingCount)
{
m_timingPos = 0;
// we're at the end of frame here, so there's plenty of time to update
updateTimings();
}
}
It is possible to toggle an output pin by writing to its input register
uint8_t mask = digitalPinToBitMask();
uint8_t port = digitalPinToPort();
volatile uint8_t out = portInputRegister(port);
out |= mask;
You can simply store the mask and out variable somewhere else (as
member variable of PPMOut for example) and just do *out |= mask in the
isr function. This will keep the amount of code (and time spent) in
the isr to a minimum and ensure the timing precision you want. I
didn't have a chance to test this code since I accidentally melted my
Arduino some time ago (short circuit). It should work though, the same
principle is used for generating a servo signal.
Last edit: dvdouden 2012-10-29
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
At the moment only PIN 9 an 10 can be used as outgoing PIN
Is there a way to modify the g_PPMOut.start(); function to hand over the out pin? For example: g_PPMOut.start(11);
I already tried to change the function but I am not sure because the "p_a" value is also used for the following line: c::Timer1::setToggle(true, p_a);
Sorry for the really late reply, I'm answering this in case someone ever has the same question and stumbles upon this :)
If I ever find the time I will add this to the library...
I recently got the same question by email, so here's my copy/paste answer:
PPM output works best with pins 9-10 since they're directly tied to
Timer 1. As timer 1 generates an interrupt, the hardware will
automatically toggle the value on either pin 9 or 10. However, it's
not that hard to make PPMOut use a different pin, you just need to
toggle the pin you want manually in the interrupt handler. For this
you need to make some changes to PPMOut.cpp:
-In PPMOut::start(), change uint8_t pin = p_a ? 9 : 10; to the pin
number you want and remove this line: rc::Timer1::setToggle(true,
p_a);
-In PPMOut::isr(), toggle your output pin on the first line of that function.
so, to summarize, you'll get something like this:
and
It is possible to toggle an output pin by writing to its input register
You can simply store the mask and out variable somewhere else (as
member variable of PPMOut for example) and just do *out |= mask in the
isr function. This will keep the amount of code (and time spent) in
the isr to a minimum and ensure the timing precision you want. I
didn't have a chance to test this code since I accidentally melted my
Arduino some time ago (short circuit). It should work though, the same
principle is used for generating a servo signal.
Last edit: dvdouden 2012-10-29
Added in [r84], still needs testing
Related
Commit: [r84]