I would like to share one of my projects, and ask for help at the same time.
I am building my own RC transmitter for long range flying with telemetry. This means that I need to
1 - generate a ppm output (transmitter)
2 - read a serial from xbee (telemetry) and
3 - generate serial (for touch screen)
4 - and maybe, read ppm input (like with a trainer port, or head tracker...) ALL at the same time!
My fisrt version was using a AVR (arduino) but it lacked power when you need to do all three tasks at the same time (plus serial library use cli() witch makes ppm stream buggy, I lost quite some time tracking this problem down). Then I found the Teensy! Lots of power and small size, perfect for my application! I immediately bought two Teensy 3.1, and everything worked immediately.
Here is what my transmitter looks like:
My problem is that I do not understand very well the structure of the interrupts (on ARM processors) to generate ppm output stream.
*** The easy solution is to use PulsePosition.h but i do not understand everything... So I can't modify it for my needs, for example i need to generate two types of ppm streams either positive or negative shift.
(Carrier is at 3V for both graphs)
*** Another solution would be to write my own ppm library (that I can understand, lol). I already did that, but for the AVR architecture. Off course, I can't port the code to the Teensy because I do not understand the timers on the ARM architecture. I read this: https://www.pjrc.com/teensy/interrupts.html#names , but i am not smart enough to apply it.
Here is my code works (actually it is not really mine, I copied big chunks of it):
1. Setup a timer on the due & Start a timer
2. Set a presacaler
3. Change the match register (trigger)
4. Run into a loop every time the trigger is reached and turn on (or off) the ppm pin and go back to step 3
Here is the actual code:
Any help, comments will be appreciated.
Thank you in advance for your help,
Francois
I am building my own RC transmitter for long range flying with telemetry. This means that I need to
1 - generate a ppm output (transmitter)
2 - read a serial from xbee (telemetry) and
3 - generate serial (for touch screen)
4 - and maybe, read ppm input (like with a trainer port, or head tracker...) ALL at the same time!
My fisrt version was using a AVR (arduino) but it lacked power when you need to do all three tasks at the same time (plus serial library use cli() witch makes ppm stream buggy, I lost quite some time tracking this problem down). Then I found the Teensy! Lots of power and small size, perfect for my application! I immediately bought two Teensy 3.1, and everything worked immediately.
Here is what my transmitter looks like:
My problem is that I do not understand very well the structure of the interrupts (on ARM processors) to generate ppm output stream.
*** The easy solution is to use PulsePosition.h but i do not understand everything... So I can't modify it for my needs, for example i need to generate two types of ppm streams either positive or negative shift.
(Carrier is at 3V for both graphs)
*** Another solution would be to write my own ppm library (that I can understand, lol). I already did that, but for the AVR architecture. Off course, I can't port the code to the Teensy because I do not understand the timers on the ARM architecture. I read this: https://www.pjrc.com/teensy/interrupts.html#names , but i am not smart enough to apply it.
Here is my code works (actually it is not really mine, I copied big chunks of it):
1. Setup a timer on the due & Start a timer
2. Set a presacaler
3. Change the match register (trigger)
4. Run into a loop every time the trigger is reached and turn on (or off) the ppm pin and go back to step 3
Here is the actual code:
Code:
//////////////////////CONFIGURATION///////////////////////////////
#define chanel_number 8 //set the number of chanels
#define default_servo_value 1500 //set the default servo value
#define PPM_FrLen 22500 //set the PPM frame length in microseconds (1ms = 1000µs)
#define PPM_PulseLen 300 //set the pulse length
#define onState 1 //set polarity of the pulses: 1 is positive, 0 is negative
#define sigPin 10 //set PPM signal output pin on the arduino
//////////////////////////////////////////////////////////////////
/*this array holds the servo values for the ppm signal
change theese values in your code (usually servo values move between 1000 and 2000)*/
int ppm[chanel_number];
void setup(){
//initiallize default ppm values
for(int i=0; i<chanel_number; i++){
ppm[i]= default_servo_value;
}
pinMode(sigPin, OUTPUT);
digitalWrite(sigPin, !onState); //set the PPM signal pin to the default state (off)
cli();
TCCR1A = 0; // set entire TCCR1 register to 0
TCCR1B = 0;
OCR1A = 100; // compare match register, change this
TCCR1B |= (1 << WGM12); // turn on CTC mode
TCCR1B |= (1 << CS11); // 8 prescaler: 0,5 microseconds at 16mhz
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
sei();
}
void loop(){
}
ISR(TIMER1_COMPA_vect){
static boolean state = true;
TCNT1 = 0;
if(state) { //start pulse
digitalWrite(sigPin, onState);
OCR1A = PPM_PulseLen * 2;
state = false;
}
else{ //end pulse and calculate when to start the next pulse
static byte cur_chan_numb;
static unsigned int calc_rest;
digitalWrite(sigPin, !onState);
state = true;
if(cur_chan_numb >= chanel_number){
cur_chan_numb = 0;
calc_rest = calc_rest + PPM_PulseLen;//
OCR1A = (PPM_FrLen - calc_rest) * 2;
calc_rest = 0;
}
else{
OCR1A = (ppm[cur_chan_numb] - PPM_PulseLen) * 2;
calc_rest = calc_rest + ppm[cur_chan_numb];
cur_chan_numb++;
}
}
}
Any help, comments will be appreciated.
Thank you in advance for your help,
Francois
Last edited: