Linear PWM output for Analog meter

I am working on a tank level display using an analog meter. I have an ESP8266 that measures my water tank and reports a percentage full value in HA. I’d like to have that percentage displayed using an analog meter. I have a few 100mV meters, convenient as the display is already marked from 0-100.

The way I’d do this on an Arduino (which I am more familiar with) is output a PWM signal, and, if needed, use a capacitor and resistor as a low pass filter to smooth out the PWM output into a DC signal, and a voltage divider to bring the full range of the output into a 0-100mV level.

I am trying to do this within ESPHome, but the PWM output I started with is a logarithmic output (verified by the meters action, and oscilloscope measurements), as it’s part of the “light” class. A linear meter needs a linear output to be useful.

Is there a way to get a linear PWM output? Searching on both log and linear I can’t find anything documented. I can’t find any example of anyone using ESPHome to drive an analog meter as an output device either.

Thanks!
Steve

How about an R-2R DAC instead of PWM?

https://www.electronics-tutorials.ws/combination/r-2r-dac.html

You would need 4 spare GPIOs for a 4 bit version (16 levels).

4 ports and 8 resistors to get 4 bit resolution… meh. All I need is normal, linear PWM to make this work.

I can publish the tank level to my mqtt server and just use an Arduino, but I am trying to leverage ESPHome if I can. Hopefully there’s a way to do this - should be easy I would think, but I don’t see an option for “linear”.

Thanks for your reply and input!

Maybe I am misunderstanding but I don’t think that a pwm can ever be linear. Sounds like you are looking for a converter. I use something like this to go from a pwm signal to a linear 0-10v output.

I might have not been clear with my description. The PWM duty cycle is not linear with the slider (1-100%) in HA. Setting the slider to “50” results in a duty cycle of about 13%. I am looking for the slider to act linear with respect to the duty cycle, i.e., 25% = 25%, 75% = 75%.

I think this maybe because you are using an 8266 and only software pwm is available. Possibly try the default frequency 1000 Hz as it deviates more if it’s higher.

I use the fan component and use the above to control a light. I never noticed log scaling. So I just measured, I’m using an esp32 though, 25% = .9, 50% = 1.7, 75% = 2.5, 100% = 3.3. So not exact but close, I’d expect the light component to be the same.

Huh, I wonder if the fan component is a better choice. I’ll have to plot what I am seeing with the light component, definitely appears to be a log response. This is with the ledc hardware PWM functionally. Thanks!

I’ve used the light component and never seen any log scaling. Double check that you are using LEDC, I don’t think you are. LEDC is only available for esp32’s not 8266’s. Software is the only option for 8266’s.

I’m only using the fan component by chance. I had a esp already configured for pwm fans and I borrowed an output to see if it worked with my light. I just havent gotten around to making it, it’s own board.

Just to follow up, the fan component worked for me, I was able to drive an analog meter to display a tank level using the FAN component. FAN appears to be linear, and the pwm duty cycle matches what is requested - from 0-100. Light components appear to be logarmithic. It would be nice if this action was documented, or selectable.

I can confirm that esp8266_pwm do not have a linear relation IF the duty cycle is controlled through a monochromatic light using its brightness:
image
That is, the responsibility of the logarithmic behaviour is of the light component!
But if we actuate directly in the output using the set_level action it is possible to have a linear relation between that level (in %) and the duty cycle (also in %).
To avoid actuating the output directly we can use the Fan Component.

Just for the sake of completeness, but I believe using
gamma_correct: 1.0
also creates a linear output when using a monochromatic light using its brightness.
At least it does for me…

1 Like