DIY Servo Signal (PWM) to PPM Converter - Page 11 - RC Groups
Thread Tools
Aug 07, 2011, 03:22 PM
Aircraft re-kitter
ergocentric's Avatar
Originally Posted by djdavies83
Hi sorry if this has been covered already, or is a little off-topic, this is the closet search I have found to what I am looking for.

Can this chip be programmed (or has someone done it) to do the reverse, take a PPM signal and output 4-8 channels?

The reason I ask is I've been very interested in the iPhly: Open-Source R/C on the iPhone thread and would like to use the PPM out from the phone and connecting it directly (though a chip of course) to the servos for any projects where a radio Tx/Rx set is not needed.

Many thanks Dave.
Like a Signetics NE4055? difficult to find now.
Sign up now
to remove ads between posts
Aug 08, 2011, 04:45 AM
Registered User
Sleurhutje's Avatar
Anybody any experience with this interface on a Spektrum AR7000 (or any other receiver with servo sync)?
Aug 09, 2011, 08:26 AM
Aircraft re-kitter
ergocentric's Avatar
They have source code available on the page too, nice.

Aug 12, 2011, 05:33 AM
We can rebuild it!
djdavies83's Avatar
Would this 8CH GWS-8M 35mhz FM receiver be hackable to take a direct PPM in put and give me the servo pwm outputs?

Aug 12, 2011, 11:23 AM
Aircraft re-kitter
ergocentric's Avatar
need to know the chip number

a bit pricey for a single conversion receiver
Last edited by ergocentric; Aug 12, 2011 at 11:33 AM.
Aug 12, 2011, 10:43 PM
We can rebuild it!
djdavies83's Avatar
Originally Posted by ergocentric
need to know the chip number

a bit pricey for a single conversion receiver
I've asked the seller but he didn't know the chip number, It's a used on on eBay I'm thinking of getting, I would never buy new for a conversion like this.

I think I know who to ask, I'll post my findings to help anyone who may look for this info.
Sep 12, 2011, 09:20 AM
Registered User
EDIT - Atmega8 does in fact have 8 pins in PORTB... I didn't look hard enough So ignore this

Thanks for the code! I've got an atmega8 lying around so I'd like to use this to sum 6 channels. I've not clue about assembly but have made the changes to the code to try to do this :

          ; Atmel Win32 AVR Disassembler V1.01 by SXPILOT450
          ; Byte Address & ASCII Column by WagnerLip - 2009
          ; Instruction         ADDR HEXA OPERANDS     BYTE#  ASCII NEXT 8 
          ; ------------------  ---- ---- --------     ----  ----------------

	  ; Modified by Druzara/Rex 09/22/2009
	  ; 6 Channel operation for Spektrum 6xxx receivers
	  ; PPM output on C0, inputs on PB0-PB5
          ; ATMEGA8 8MHz
          ; changes to original code are commented out but left in source

         ;.DEVICE AT90S2313
         .INCLUDE ""
         .org	0

          ldi    r23, 0x9F    ; 0000 E97F              0000   Setup stack pointer
          out    SPL, r23     ; 0001 BF7D              0002   
;         sbi    DDRB, 4      ; 0002 9ABC              0004   PB4 as ppm output
          sbi    DDRC, 0      ;                        0004   PC0 as ppm output

avr0003:  ldi    r22, 0x01    ; 0003 E061              0006   load r22 with bit to test
          rcall  avr0015      ; 0004 D010              0008   call avr0015 to set output
          ldi    r22, 0x02    ; 0005 E062              000A   repeat for all bits
          rcall  avr0015      ; 0006 D00E              000C   
          ldi    r22, 0x04    ; 0007 E064              000E   
          rcall  avr0015      ; 0008 D00C              0010   
          ldi    r22, 0x08    ; 0009 E068              0012  
          rcall  avr0015      ; 000A D00A              0014   
;         ldi    r22, 0x20    ; 000B E260              0016   
          ldi    r22, 0x10    ; 000B E260              0016   
          rcall  avr0015      ; 000C D008              0018   
;         ldi    r22, 0x40    ; 000D E460              001A   
          ldi    r22, 0x20    ; 000B E260              0016   
          rcall  avr0015      ; 000E D006              001C   
;         ldi    r22, 0x80    ; 000F E860              001E   
;         rcall  avr0015      ; 0010 D004              0020   
;         sbi    PORTB, 4     ; 0011 9AC4              0022
          sbi    PORTC, 0     ; 0011 9AC4              0022   ppm out high
          rcall  avr001F      ; 0012 D00C              0024   short delay
;         cbi    PORTB, 4     ; 0013 98C4              0026
          cbi    PORTC, 0     ; 0013 98C4              0026   ppm out low
          rjmp   avr0003      ; 0014 CFEE              0028   loop for next cycle

avr0015:  in     r23, PINB    ; 0015 B376              002A   test PB bit masked
          and    r23, r22     ; 0016 2376              002C   by r22
          breq   avr0015      ; 0017 F3E9              002E   
;         sbi    PORTB, 4     ; 0018 9AC4              0030   
          sbi    PORTC, 0     ; 0018 9AC4              0030   set ppm out high
          rcall  avr001F      ; 0019 D005              0032   short delay to inject gap
;         cbi    PORTB, 4     ; 001A 98C4              0034   
          cbi    PORTC, 0     ; 0013 98C4              0026   ppm out low

avr001B:  in     r23, PINB    ; 001B B376              0036   wait until current
          and    r23, r22     ; 001C 2376              0038   channel is done
          brne   avr001B      ; 001D F7E9              003A   
          ret                 ; 001E 9508              003C   

avr001F:  ldi    r25, 0x03    ; 001F E093              003E   delay for proper gap between pulses
avr0020:  sbiw   r24, 0x01    ; 0020 9701              0040   ie: "needle" glitch as generated
          brne   avr0020      ; 0021 F7F1              0042       by diode circuits
          ret                 ; 0022 9508              0044   

          ori    r18, 0x38    ; 0023 6328              0046   '(c) 2006 R.Smith'
          and    r2, r9       ; 0024 2029              0048   ') 2006 R.Smith..'
          cpi    r19, 0x02    ; 0025 3032              004A   '2006 R.Smith....'
          cpi    r19, 0x60    ; 0026 3630              004C   '06 R.Smith......'
          subi   r18, 0x20    ; 0027 5220              004E   ' R.Smith........'
          subi   r18, 0x3E    ; 0028 532E              0050   '.Smith..........'
          ori    r22, 0x9D    ; 0029 696D              0052   'mith............'
          ori    r23, 0x84    ; 002A 6874              0054   'th..............'
Basically channels 1-6 are B0-5, and as PORTB only has 6 pins on the Atmega8 I've tried to output the PPM Sum to C0. Will this work?


Last edited by ben123; Sep 13, 2011 at 05:28 PM.
Sep 12, 2011, 01:07 PM
Registered User
Also can anyone help me out with what fuses to use with an atmega8? I've looked at the fuse calculator and it's going right over my head

Sep 13, 2011, 08:27 AM
Registered User
I believe the code change should work, on the fuse bit , there are some calculators on the web. I don't have any links right now (at work).
Sep 13, 2011, 11:15 AM
Registered User
Thanks beer-man... I've looked through the code and with the help of Lord Google I've figured out what it's doing. Unfortunately though I think I've bricked my atmega8 as the programmer can't find it's signature now (it's all Fs). I was attempting to set the fuse bits but my lack of knowledge killed it

Sep 13, 2011, 01:18 PM
Registered User
I've done the same a couple times, sometimes you can revive them by connecting an external clock to the clock input. If that doesn't bring it back then it needs a high voltage programmer which is harder to find.
Sep 13, 2011, 03:02 PM
Registered User
Yep tried the external clock thing but no go. So I tried the code on a spare atmega48 dip I found and it worked like a charm. Lovely square PPM on the scope! Was able to use the original code (B7 ppm out) with the 48

Oct 30, 2011, 06:45 PM
Registered User
Xnaron's Avatar
Originally Posted by pipsqueak
Hi Rich,

I've been using your fantastic converter for a couple of months now - thanks again for posting the code.

I've been using your HEX on a Tiny13 (i.e. four channels only) - making an almost exact-looking replica of yours.

Btw, If there are any arduino users out there who'd want to decode the PPM that comes out of this, I'll post the modified sketch I use at the bottom:

However Rich, It would be really great to get a version to handle more channels - Ie. use the extra pins on the Tiny26 version. However, without the source I can't make the tweaks above that you mentioned.

So I was wondering, would you either possibly be up for (a) tweaking your code, and posting a HEX for a new version that could handle up to 8 inputs, or (b) posting the source so that I could have a go myself - If successful I'd post the version back to the thread

No matter what, I'm really grateful to have found such a neat 4 channel solution - So thanks again.



#define TXINPUTPIN 8 // Define TX PPM input signal - HARDCODED (so changing this won't make any difference)
unsigned int serinp[8]; // For the input PPM signal
#define TX_PITCH serinp[0]  // Related to the PPM order and wiring 
#define TX_ROLL serinp[1]
#define TX_THROTTLE serinp[2]
#define TX_YAW serinp[3]

void pmm_setup() 
  // Setup the TX PPM input
  pinMode(TXINPUTPIN, INPUT); // Ensure the TX PPM pin is input
  setup_timer1(); // Start the timer that does the PPM
                      Functions & Subroutines

void setup_timer1(){
//disable all interupts
TIMSK1 &= ~( _BV(TOIE1) | _BV(ICIE1) | _BV(OCIE1A) | _BV(OCIE1B));

//set timer mode
TCCR1A &= ~( _BV(WGM11) | _BV(WGM10) );
TCCR1B &= ~( _BV(WGM12) | _BV(WGM13) | _BV(ICNC1));

//capture raising edge
TCCR1B |= _BV(ICES1); //capture raising edge

//prescaler 1/8
TCCR1B |= _BV(CS11);
TCCR1B &= ~( _BV(CS12) | _BV(CS10) );

//disable outputs
TCCR1A &= ~( _BV(COM1A0) | _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1));

//enable capture interupt
TIMSK1 |= (1<<ICIE1);

static unsigned int lasticr; //icr at last caputre
static unsigned char cserinp; //current input servo

unsigned int licr;

//TCCR1B ^= _BV(ICES1);

if (licr<10000) { //pulse not super long - so Ok, otherwise totally ignore

if(licr>5000){ //pulse too long, means start of new frame
}else if(licr>500){ //pulse good, take reading, go to next channel
//too short, nothing to see here
//updateTXVals();  // So at the end lets update our calibrate vals  

I'm just looking for some simple interrupt driven code to read a channel from an rx. I don't want to use pulsein. I have tried so many sketches I've googled and haven't found anything that works the way I wanted. Anyone have an example? I am using arduino pro mini (328p).

Oct 31, 2011, 04:42 PM
Registered User

I made my own PWM2PPM converter based on ATtiny2313. Mine can handle up to 8 channels (it uses the entire port B of the ATtiny2313) and I have a power LED and a PWM signal indicator LED. I have also added 4 pull-down resistors for channels 4-8 to avoid any problems with floating inputs.

This can only handle PWM pulses which are not simultaneous - the pulses may not overlap; they have to occur one after another.

The source code is written in C. I used the 8 bit timer interrupt to generate the 300us PPM pulse, but I think a delay_us(300) could be used instead just as well. I also thought about using pin change interrupts instead of polling, but I think polling makes things a little simpler. As I said, the program can handle any number of channels (up to 8), but I don't recommend less than 4 because only channels 4-8 have the pull-downs.

I have attached the Eagle CAD schematic and PCB. I made the circuit and PCB so that I can plug my receiver directly into the converter.

I have tested it with a HK6DF TX/RX and I use it for controlling a simulator. It seems to work just fine.

Jan 23, 2012, 11:43 PM
Registered User
I don't mean to revive an old thread but I was wondering if anyone could maybe modify the code for three channels with a ATTiny13A. I am trying to include this as a method to transmit data over some distance via cable. Except I only need the three channels.

Thank you, any help is much appreciated. I will try and understand it as best i can in the meantime. I am more mechanically inclined, software is a foreign language to me.


Thread Tools

Similar Threads
Category Thread Thread Starter Forum Replies Last Post
Discussion how to convert PWM servo signal to DC voltage sahilkit DIY Electronics 15 Oct 05, 2008 10:23 PM
Mini-HowTo Motor PWM to PPM impulse converter quax DIY Electronics 27 Jun 17, 2008 12:38 AM
PWM to servo signal conversion? mcross DIY Electronics 13 Jul 05, 2005 09:48 PM
Futaba PCM receiver servo pulse other than PPM? risto Power Systems 14 Feb 14, 2002 01:18 PM