Read the digital value of a pin configured as a Timer PWM

I successfully configured a PWM using Timer1 of my Arduino Uno R3 Smd Edition. The period of the PWM is quite long, from 1s to 4s. So I can avoid to use an HW timer, I can do the same very easily with a software PWM, but this is not the issue. What I am interestd in is: it is possible to read the value of the PWM pin (pin 9 in this example)? If I use the 'digitalRead(9)' the pwm is switched off. I think I need to read the image of the pin in output of the waveform generator.
PS: For sure I can put a physical wire from the PWN output pin to an input and read the input, but again this is not the issue.

Have you tried direct port manipulation? Arduino Reference - Arduino Reference
AFAIK it should be possible to read the input register without messing with the Timer1 configuration. Haven't tried it, but I don't see why it wouldn't work.

If the pin outputs PWM, Arduino's digitalRead() releases it before fetching the register value.
If you want to read the value when keep the pin connected to the timer, you should read port register direct instead of digitalRead().

Yes, thanks.
But if the 'Guru' made that check in the digital read, I suppose there is a VERY good reason to avoid to read the register value if the PWM is active. Any ideas? I do not want to have troubles due to made this shortcut.

Neither digitalRead nor digitalWrite should affect the data direction register (but setting pinMode to INPUT_PULLUP necessarily writes the pin HIGH), so one does wonder why a digitalRead would affect PWM in any manner?

May be a bug in the coding; it would certainly be interesting to learn what the problem is. :face_with_raised_eyebrow:

(OK, I should go inspect the datasheet, shouldn't I? :roll_eyes:)

Did you see my link at post #3?
It's a behavior "intentionally" implemented by the Arduino team.

DDRx register is not manipulated.
But, it disconnects the PWM output of the timer from the pin.
In other words, it manipulates the TCCRnx register.

But I don't know why such a decision was made. :expressionless:

Yes Chrisknightley I read your post.
Due to that, I wonder to remove the test at line 175.
Someone, an expert, put this test into an API execute billions of times. As I am not an expert, can I modify this API without inserting a bug? This upsets me a little.

If you need it, I think it's better to create the peculiar digitalRead() without that one line.

const int TEST_PIN_PWM = 10;
void setup() {
  analogWrite(TEST_PIN_PWM, 127);
void loop() {
int myDigitalRead(uint8_t pin)
  uint8_t timer = digitalPinToTimer(pin);
  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  if (port == NOT_A_PIN) return LOW;
  if (*portInputRegister(port) & bit) return HIGH;
  return LOW;

Ah, sorry, it looked like some code so I glossed over it! :grin:

For no obvious reason at all. Fair enough! :crazy_face:

Thanks to all Guys for your help.
I am still thinking to this digitalRead() API
and I wish to comment its behaviour not from a technical point of view but from my personal point of view of a user.
In the development of my project I first made the setting of the PWM and I made a very preliminary
release of my application with some calls to the digitalRead().
I spent two working days trying to understand why the PWM didn't work as expected. I look at some examples
and I read the manual, but I didn't find a reason why the pwm didn't work.
Only after a deep analisys of this API I realized which was the reason of the fault.
From my point of view, I setup a PWM and then I read some digital input and silently someone take the decision
of switching off the PWM.
From a user point of view, do you think that is reasonable?
This solution is not consistent with the user case when the pin is NOT a pin where the read API returns with a beautiful 'false'. Why do not do the same upon a 'timer pin' and leave the PWM setting as it is?
As a user, if I discover that the input image is always 'false', my attention is on the read of the PIN because my oscilloscope or la led on the PIN is saying that the PWM is working properly.
This is just my personal comment, it has not so much value.

I get your point - and you do indeed have a point. I think it's a compromise by the people who wrote this function this way. They wanted to make something fool-proof, so they had to imagine what a fool would expect. Apparently they decide that a fool would forget to disable PWM before they wanted to use the same pin as an input, and not that they would want to read the same input they had PWM running on.

The difficulty with something like this is that you never do it right for everybody. Sooner or later someone comes around who complains :wink:

Which in the event, is an extremely stupid proposition and should never have been implemented.

The code should do exactly what it is supposed to do and no more. This needs fixing, it is a serious bug. Nothing will break by removing the bad code.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.