Reading a PWM Signal

Hi Everyone,

I'm very new to Arduino and hopefully someone here can help.

I'm working on a project with some students where they would like to read a PWM signal and turn it in to a green, amber or red LED depending on the length of the high-side signal.

For example if the duty cycle is high for <85% the green LED will be lit, 85% - 90% amber and >90% red.

I can find lots of info online of Arduino generating a PWM signal but there's not much about reading PWM.

Does anyone know if what i'm trying to achieve is possible and if so which Arduino product would be best?

Thanks in advance for the help.

The easiest way is low-pass filter to get a variable DC voltage, then read the analog input.

Or, you can try [u]pulseIn()[/u].

The first question that pop's into my head, what frequency are we talking about?

Sounds like a job for some resistors, capacitors, and an LM3914. (If they are still available!)

I would use pulseIn() with a short timeout.

Syntax: pulseIn(pin, value, timeout)

value: type of pulse to read: HIGH or LOW

timeout (optional): the number of microseconds to wait for the pulse to start; default is one second. Allowed data types: unsigned long.

const byte PWMPin = 2;
const byte GreenLEDPin = 3;
const byte AmberLEDPin = 4;
const byte RedLEDPin = 5;

void setup()
{
  pinMode(PWMPin, INPUT);

  pinMode(GreenLEDPin, OUTPUT);
  pinMode(AmberLEDPin, OUTPUT);
  pinMode(RedLEDPin, OUTPUT);
}

void loop()
{
  byte PWM = GetPWM(PWMPin);
  digitalWrite(GreenLEDPin, PWM < 85);
  digitalWrite(AmberLEDPin, PWM >= 85 && PWM <= 90);
  digitalWrite(RedLEDPin, PWM > 90);
}

byte GetPWM(byte pin)
{
  unsigned long highTime = pulseIn(pin, HIGH, 50000UL);  // 50 millisecond timeout
  unsigned long lowTime = pulseIn(pin, LOW, 50000UL);  // 50 millisecond timeout

  // pulseIn() returns zero on timeout
  if (highTime == 0 || lowTime == 0)
    return digitalRead(pin) ? 100 : 0;  // HIGH == 100%,  LOW = 0%

  return (100 * highTime) / (highTime + lowTime);  // highTime as percentage of total cycle time
}
1 Like