11 Aug 2012

Reading PPM Signal with arduino

I want to trigger additional logic in an UAV when I flip a 3 position switch on my R/C transmitter. This sketch will decode a PPM signal from an R/C receiver and will turn on two LEDs depending on switch position.

The code compiles for a Sparkfun Pro Micro 16MHz and also on an ATtiny85:


/**
 * Read PPM signal
 * 
 * Decode r/c receiver PPM servo signal and turn lights on 
 * according to servo position.
 *
 * $Id$
 */

// from which pin to read.
#define PIN_PPM   9
#define PIN_POS1 10
#define PIN_POS2 16

unsigned long duration, lastgood = 0;
int position = 0;

void setup() {
  pinMode(PIN_PPM, INPUT);
  pinMode(PIN_POS1, OUTPUT);
  pinMode(PIN_POS2, OUTPUT);
  digitalWrite(PIN_POS1, LOW);
  digitalWrite(PIN_POS2, LOW);
}

void loop() {
  // the length of the pulse (in microseconds) or 0 if no pulse 
  // started before the timeout (unsigned long)
  duration = pulseIn(PIN_PPM, HIGH, 20000); 
  if (duration == 0) {
    duration = lastgood;
  } else {
    lastgood = duration;
  }
  // map ppm values to 0, 1 and 2
  position = map(lastgood, 1000, 2000, 0, 2);
  // 0 == both off, 1 == LED1 on, LED2 off, 2 = both on 
  if (position > 0) {
    digitalWrite(PIN_POS1, HIGH);
  } else {
    digitalWrite(PIN_POS1, LOW);
  }
  if (position > 1) {
    digitalWrite(PIN_POS2, HIGH);
  } else {
    digitalWrite(PIN_POS2, LOW);
  }
}