I'm using PWM to control LED brightness using MOSFET, using analogWrite(pwmPin,val), while val is a 12 bit bit value.

pwmPin is defined as- pinMode(pwmPin, OUTPUT);

Since val changes in time due to external lightning, I wish to measure PWM value, for later use in code. Using analogRead(pwnPin) yielded a changing value ranges 7-14.

Is there a way to measure PWM value defined as an output ?


Saving val's value won't save the problem I'm looking for, since code reaches a deepSeleep phase, which val can be stored, but I want an actual incidication of its value, and if it actually on.

  • Why not storing val and calculate what you need depending on that? That seems better than measuring something you already know (or knew) as it is/was in the variable val. – Michel Keijzers Feb 7 at 9:05
  • @MichelKeijzers - see EDIT1 in my Q – Guy . D Feb 7 at 9:14
  • @Guy.D "I want an actual indication of its value" When you are measuring the output, you are actually only writing code to test your code. In most cases this does not really make sense. If your code is written correctly, you can trust the output to do, what you want. Any event, that might change that (like some kind of hardware failure), is high likely to also effect your testing code, which you then also cannot trust. Why do you really need this indication? If for safety, then you should think about the scenarios, that you want to cover, and then build a seperate device for this purpose. – chrisl Feb 7 at 9:36
  • 2
    The fact that you sleep doesn't matter. If you keep in a variable the value that you used to analogWrite(), it will still be there when you wake up. – Edgar Bonet Feb 7 at 10:48
  • Doesn't analogRead from analog pins but analogWrite write to digital pins? And don't the analog and digital pins have their own numbers (digital 0 is a different pin to analog 0)? – user253751 Feb 7 at 16:49

First: Why would you need to measure the PWM value. You already know it; it's saved in the val variable. Why not just use this variable for later use in code?

Second: Doing the analogRead on the same pin as the PWM output is not going to work. Internally there are 2 different hardware peripherals, that are responsible for these functions: The ADC is responsible for measuring analog voltages, while one of the Timers is responsible for generating the PWM output. Only one of them can connect to the pin at any time. Thus you are not measuring the PWM signal, when you do an analogRead(pwmPin). This function set's the pin for measuring analog voltages (means it connect it to the ADC and configures the ADC) and thus disconnects the Timer hardware.

Third: Doing an analogRead() directly on a PWM signal is not going to work. PWM is still a digital signal, so measuring it's analog voltage would yield only values around 0 and 1023. This signal is transformed to a real analog voltage through a low pass filter, either electrically or mechanically (here I mean because mechanical elements often cannot follow the relatively fast PWM signal - like a motor or a speaker - which results effectively in a low pass filter).

How to measure a PWM signal then? First you definitely need to use a different pin, than the PWM output pin. Then you have 2 ways of measuring the current PWM value:

  1. You can connect the PWM output to a low pass filter (combination of resistor and capacitor; you can google this and get very detailed descriptions), and the output of the low pass filter to an analog input pin of the Arduino. Then you can do analogRead()s to measure the current value.

  2. You can measure the PWM signal directly, meaning measuring the actual pulse width of the signal. There are multiple ways of doing this, one being the pulseIn() function, which wait's for a pulse to complete and returns the length of the pulse.

| improve this answer | |

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.