I'm using a Nano. A0 and A5 can take digital and analog input/output, but found that A6 and A7 only takes analog input/output. I was trying to find how to convert from analogRead() to digitalRead() for pins A6 and A7. I didn't find any answers in the forums but did find a solution on YouTube. So I'm posting it here for anyone who doesn't look at YouTube videos.
I don't see this as a replacement for digitalRead, without some thresholding (which should be expressed in raw readings, not "voltages") - all you've posted is how to convert an analogue reading to a voltage*
You really ought to add the caveat that it's around 25 times slower than a real digitalRead; you don't want to raise unattainable expectations.
(readPin and readPin2 ought to be of type "const byte", and "readVal", "readVal2", "V1" nor "V2" require global scope.
As was pointed out, much easier to just check the value read from the analog pin. You could use any value between 0 and 1023, depending on how you want to define the threshold between LOW and HIGH.
int digitalReadAnalog(const int pin) {
if (analogRead(pin) < 512)
return LOW;
else
return HIGH;
}
Thought it was obvious, you only going to get 5 when you multiply 5 by 1, and you only going to get 1 when you divide 1023 by 1023. you never going to get 1 if you divide 1023 by 1024. Any more questions?
// Threshold values taken from the 328 datasheet, section
// 30.2 DC Characteristics, for the typical range of Vcc in the
// range 2.4 - 5.5V
// other processors / families may need different values.
// Note: This is an awfully slow substitute for digitalRead,
// and makes no check to see if the pin provided
// is a legitimate analogue pin.
int digitalReadAnalog(const uint8_t pin)
{
int pinVal = analogRead (pin);
if (pinVal <= (0.3 * 1023))
return 0;
if (pinVal >= (0.6 * 1023))
return 1;
return pinVal & 1; // tongue-in-cheek indeterminate value.
}
The electrical spefications/characteristics of the IO pins of ATmega328P MCU and it is for the information of @killzone_kid who has mentioned that VIH = 2V (Post-11) instead of 3V at Vcc = 5V.
The ADC can't ever measure the range 5.0V*(1024/1024) to 5.0V*(1025/1024). That may seem irrelevant, but in fact that is what a reading of 1024 would represent. Consider, that the range 5.0V*(0/1024) to 5.0V*(1/1024) is what is represented by a reading of 0.
The ADC partitions the input range into n partitions where n is the resolution of the ADC. By definition it can not represent either n, or zero.
When you scale an ADC range by a scalar voltage using n, it is correct because it scales a reading of (n-1) to the range Vs*(n-1) to Vs(n). That is because 0 is the 1st, and (n-1) is the nth partition.
For example, an input reading of 1023 is the 1024th partition, and if you calculate the input voltage with 5.0V1023/1024, the result corresponds to any input voltage between 5.0(1023/1024) and 5.0*(1024/1024) which is the specified behaviour of the ADC. Using any other divisor will not.