Map PWM to votage

Is there any way to map the 0-255 PWM values to a printed voltage? i'd like to see a serial.print with the voltage i should expect to see. based on the 0-255 scale.. i.e. if pwm is 127, i'd like to see a serial.print of 2.5V i realize this isn't going to be perfect, but at least get me close?

here's my current code.

#include "FreqPeriod.h"

long lfrq;
long int pp;
int freqpin = 6;
int sensorType = 12;
int aVout = 10;

int ffslowfreq;
int currentfreq;
int ffsmaxfreq;
int ethlowperc = 0;
int ethmaxperc = 100;
int selectedsensor;
int test;
void setup() {
  pinMode(sensorType, INPUT);
  digitalWrite(sensorType, LOW);
  selectedsensor = digitalRead(sensorType); 
  digitalWrite(freqpin, HIGH);
  Serial.println("Z0rr0's Ethanol ECA");

void loop() {
   if (selectedsensor == LOW)
    Serial.println("Ford Flex Sensor Connected");
    Serial.println("    ");
    ffslowfreq = 50;
    ffsmaxfreq = 125;
  else if (selectedsensor == HIGH)
    Serial.println("GM Flex Sensor Connected");
    Serial.println("    ");
    ffslowfreq = 50;
    ffsmaxfreq = 150;

  if (pp ){
    Serial.print("Frequency: ");
    lfrq= 16000400 / pp;
    Serial.println("  ");
    currentfreq = lfrq;
    currentfreq = constrain(currentfreq, 0, 150);
    if (currentfreq >= 50)
    int ethperc = map(currentfreq, ffslowfreq, ffsmaxfreq, ethlowperc, ethmaxperc);  
    ethperc = constrain(ethperc, 0, 100);
    Serial.print("Ethanol Percentage: ");
    int analogvoltagepwm = map(ethperc, 0, 100, 0, 255);
    Serial.print("Analog Voltage PWM: ");
    Serial.println(analogvoltagepwm) ;
    analogWrite(aVout, analogvoltagepwm);
    int analogvoltagereal = map(analogvoltagepwm, 0, 255, 0, 5.0);
    Serial.print("Analog Voltage Output: ");
    Serial.println(analogvoltagereal) ;

    Serial.println("No Ethanol Detected");
    analogWrite(aVout, 0);

any help and i would be grateful.

also, is there a way to measure the duty cycle of the same pin im reading frequency from? this sensor gives a frequency of 50-125Hz for Ethanol Content, and a 1-5ms duty cycle for fuel temperature. I'd really like to display that too.

thanks again!

Assuming PWM is linear, loop at the map() function.

PWM will only actually output a variable voltage once it is smoothed. There will be ripple associated with the voltage. The size of the ripple is dependent on the smoothing.

I was going to give a circuit, but he said "a serial.print". So I think he wants to take the reading he gets, divide by 1024 and multiply by 5, not necessarily in that order.

My code gives me this output:

Frequency: 82  
Ethanol Percentage: 42
Analog Voltage PWM: 107
Analog Voltage Output: 2.00
Ford Flex Sensor Connected

if the PWM is 107, analog voltage output should read like 2.17 for example. I am trying to output a 0-5V scale, based on that ehtanol percentage variable..

if the ethanol percentage is 50%, the PWM will be 127, so the analog output voltage should read: 2.5V +/-

i am going to put a low-pass filter on the PWM output to smooth the voltage ripple, but i just want to be able to quickly visualize what the output voltage should be.

I tried analogvoltagereal / 1024 * 5, and it gave me 0.052

Try (AnalogRead / 1024) * 5 Using floating point of course.

  int analogvoltagereal = map(analogvoltagepwm, 0, 255, 0, 5.0);

You have to think about what you are doing. You have already converted the reading to the range 0 to 5, so you hardly need to do it again. However map uses integers so you are throwing away decimal places. Maybe do your own maths and not use "map".

Nick, Grumpy_Mike had me in the right direction.

i got rid of the map()

but the calc is PWM / 255 * 5 not 1024.

[quote author=Nick Gammon link=topic=89618.msg672531#msg672531 date=1327988815] ... I think he wants to take the reading he gets, divide by 1024 and multiply by 5... [/quote]

Glad that's sorted out then.