Hello,
For my project I'm trying to build my own 16 channel transmitter.
The transmitter has to work with PPM2 signal (jeti tu2 compatable).
At the moment I have used an existing program here at arduino forum and adjusted some values to create what I want to reach.
What is important is that the signal time is from 800 - 2200us per signal (ppm2 is 400 - 1100us)
It has to read in 16 analog values (10 by the normal analog pins and another 6 with an 4051 multiplexer IC.
But a couple of thins doesn't seems right and I think it's with the timer settings. I've downloaded the atmel cortex m3 manual. But the REG_TC0_CMR0 can't be found in the manual, or explained anywhere on the internet. A dirty fix i've used now is to recalculate the signal times making them smaller. It works but is not an pretty way of fixing this.
But the largest issue that's with the source code without adjustments also is the very poor resolution in the PPM signal. Steps are 40us each. Which means about 25 steps with the normal servo time 1000us. It should be at least 100 but higher is prefered. I'm guessing the timer is making this low resolution? How can I change the timer settings how does this timer settings exactly work out?
#define PPM_PIN 2 // Welke pin PPM out
#define MAX_PPM_CHANNELS 16 // Aantal Kanalen
#define PPM_FrLen 22500 // Totale Signaaltijd PPM
#define PPM_PulseLen 250 // Bepaald de tijd dat het signaal hoog is.
int ppm[MAX_PPM_CHANNELS]; // Sla hier de stuur gegevens op voor het ppm signaal elke puls in een eigen integer.
int PPMmin = 400; // Bepaalde de basis sginaal tijd en het minimum signaaltijd (500 = 1ms)
byte PPM_cur_ch = 0;
unsigned int PPM_sum = 0;
void setup() {
Serial.begin(9600); // setup serial
pinMode(PPM_PIN, OUTPUT); //
analogWrite(PPM_PIN, 255); // sets up some other registers I haven't worked out yet
// timer is clocked at 42MHz, so 42 ticks per us
REG_PIOB_PDR = 1 << 25; // disable PIO, enable peripheral
REG_PIOB_ABSR = 1 << 25; // select peripheral B
REG_TC0_WPMR = 0x54494D00; // enable write to registers
REG_TC0_CMR0 = 0b00000000000010011100010000000000; // Negatief PPM Signaal
// REG_TC0_CMR0 = 0b00000000000001101100010000000000; // Positief PPM Signaal
REG_TC0_RC0 = 100000000; // counter period
REG_TC0_CCR0 = 0b101; // start counter
REG_TC0_IER0 = 0b00010000; // enable interrupt on counter = rc
REG_TC0_IDR0 = 0b11101111; // disable other interrupts
REG_TC0_RA0 = PPM_PulseLen * 42; // Pulse lenght
NVIC_EnableIRQ(TC0_IRQn); // enable TC0 interrupts
for (int i = 0; i < MAX_PPM_CHANNELS; i++) ppm[i] = PPMmin;
}
void TC0_Handler()
{
long dummy = REG_TC0_SR0; // vital - reading this clears some flag, otherwise you get infinite interrupts
if (PPM_cur_ch < MAX_PPM_CHANNELS)
{
REG_TC0_RC0 = ppm[PPM_cur_ch] * 42;
PPM_sum += ppm[PPM_cur_ch];
PPM_cur_ch++;
}
else
{
REG_TC0_RC0 = (PPM_FrLen - PPM_sum) * 42;
PPM_cur_ch = 0;
PPM_sum = 0;
}
}
void loop()
{
ppm[0] = PPMmin + analogRead(0) / 1.429;
ppm[1] = PPMmin + analogRead(1) / 1.429;
ppm[2] = PPMmin + analogRead(2) / 1.429;
ppm[3] = PPMmin + analogRead(3) / 1.429;
ppm[4] = PPMmin + analogRead(4) / 1.429;
ppm[5] = PPMmin + analogRead(5) / 1.429;
ppm[6] = PPMmin + analogRead(6) / 1.429;
ppm[7] = PPMmin + analogRead(7) / 1.429;
ppm[8] = PPMmin + analogRead(8) / 1.429;
ppm[9] = PPMmin + analogRead(9) / 1.429;
ppm[10] = PPMmin + analogRead(10) / 1.429;
ppm[11] = PPMmin + analogRead(11) / 1.429;
ppm[12] = PPMmin + 255;
ppm[13] = PPMmin + 20;
ppm[14] = PPMmin + 10;
ppm[15] = PPMmin + 0;
Serial.println(REG_TC0_RC0); // debug value
}