I'm outputting an analog voltage by setting an 8-bit duty cycle using analogWrite
. Once set, I'd like a way to read back this duty cycle. I've managed to read the duty cycle back from the OCR4D
register, which matches the value set, e.g.:
pinMode(6, OUTPUT);
analogWrite(6, 123);
Serial.print(OCR4D); // 123
However, when setting the duty cycle to 0
or 255
, OCR4D
is not actually set at all; instead analogWrite
calls digitalWrite
behind the scenes and the pin is digitally set to LOW
or HIGH
. This is seen in the source for analogWrite
:
if (val == 0)
{
digitalWrite(pin, LOW);
}
else if (val == 255)
{
digitalWrite(pin, HIGH);
}
else
{
// set PWM duty cycle as normal...
The problem with this is that OCR4D
is simply left at its previous value, so it's not always possible to tell the actual output by reading OCR4D
alone. In other words there is no way to tell the difference between:
- PWM is active and OCR4D
reflects the duty cycle
- PWM is disabled and OCR4D
reflects a previous duty cycle (which is not useful)
Which register(s) can I read to crosscheck the PWM is active?
I'm also aware of the pulseIn
function, but would rather read the PWM register directly.
digitalRead(pin)
will tell you if it's 0 or 1if (timer != NOT_ON_TIMER) turnOffPWM(timer);
. I want to read the value without changing it @dandavis.OCR4D
is "wrong" as it always returns a valid duty cycle (it just keeps the old value). What I'm after is a way to tell if the PWM is active and that value is being applied.analogWrite2(pin, val)
, which sets an external array of values by the pin number, then calls the realanalogWrite()
with the passed values. You can refer to the array from anywhere for a fast reliable read. Just run a replaceAll w/analogWrite2
...