I've been looking into libraries that read CPPM signals that I can use on my Arduino Pro Micro, and this one looked promising (github.com/jmparatte/CPPM) until I read that it only works on Atmega328P chips. Sure enough, I tried it, and it doesn't function on the Pro Micro as it does on my Arduino Uno. Why is this the case, i.e. what does it have that the Atmega32u4 doesn't?


This library works only on ATmega328 implementation of Arduino UNO, Duemillanove and similar, also Leonardo. It uses the 16bit Timer1. So PWM analogWrite() on pin 9 and 10 are unavailable. The library Servo is not compatible because it also uses Timer1.

I tried to do some research on my own, to no avail:

I'm new to this kind of thing and really stumped as to what could be the issue here.


That library relies mostly on Timer 1 and, as you already noticed, the Timer 1 of the ATmega32U4 is very similar, if not identical, to the one of the 328P. At least similar enough to expect the library to work identically.

I took a look at both datasheets and the only difference I can see that can possibly affect the library is the pinout. The pins relevant to the library are:

       328P  32U4
ICP1 =  PB0   PD4
OC1A =  PB1   PB5

The pinout of the 328P is hardcoded into the library. CPPM.h contains these lines:

#define CPPM_ICP1 8 // Input Capture Pin of Arduino UNO is pin 8 - ICP1 (Atmega328 PB0)
#define CPPM_OC1A 9 // Output Compare Pin of Arduino UNO is pin 9 - OC1A (Atmega328 PB1)

CPPM.cpp has two instances (here and here) of this:

if ((PINB & _BV(PINB1))) // rising edge ?

If you change the code in these three places to match the pinout of the 32U4, I would expect the library to work for you.

You could also change that conditionally as

#ifdef __AVR_ATmega32U4__
#else // assume ATmega328P

in order to make the library compatible with both MCUs, and then submit a pull request to the original author.

  • Excellent, when I get to it today, I'll try making that change. Thanks for the theory! – ifconfig Nov 7 '18 at 16:51
  • Hold on, what do I replace the PINB part with? – ifconfig Nov 7 '18 at 18:38
  • 1
    @ifconfig: PINB & _BV(PINB1) tests the state of the PB1 pin which, on the 328P, is the same as OC1A. On the 32U4 you would use OC1A = PB5 for the same purpose. The test then becomes PINB & _BV(PINB5). – Edgar Bonet Nov 7 '18 at 19:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.