analogRead() to digitalRead() Solution

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.

Huge credit to Paul McWhorter: https://www.youtube.com/watch?v=5TitZmA66bI

Edit: this doesn't really work like digitalRead() instead 1 being LOW, and 3 being HIGH

1 Analog Pin

  int readPin = A6;
  int readVal;
  int V1 = 0;

void setup() {
  
  pinMode(readPin, INPUT); 
  Serial.begin(115200);
}

void loop() {
  readVal = analogRead(readPin);
  V1 = (5./1023.)*readVal; // Do not remove points
  Serial.print("A6: "); Serial.print(V1);
}

2 Analog Pins

  int readPin = A6;
  int readPin2 = A7;
  int readVal;
  int readVal2;
  int V1 = 0;
  int V2 = 0;

void setup() {
  
  pinMode(readPin, INPUT);
  pinMode(readPin2, INPUT); 
  Serial.begin(115200);
}

void loop() {
  // Delay needed if there's no resistor for A6 and A7
  readVal = analogRead(readPin);
  V1 = (5./1023.)*readVal; // Do not remove points
  Serial.print("A6: "); Serial.print(V1);

  //delay(1000);

  readVal2 = analogRead(readPin2);
  V2 = (5./1023.)*readVal2;
  Serial.print("  A7: "); Serial.println(V2);

  //delay(1000);
}

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.

*

(5./1023.)*readVal;

really should be 1024. (Hard-hat time!)

This is incorrect. digitalRead returns LOW on logical 0 and HIGH on logical 1. TTL levels in terms of Voltage are:
LOW: 0V-0.8V
HIGH: 2V-5V

Your method returns 0 when 0V-0.9999999V and 1 when 1V-5V

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;
}

Does 10bit ADC ever return 1024? It can’t can it? 1024 is not a value 10bit int variable can support, no?

No, it can't.
What's your point?

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?

But you can never get 5, because 1023 doesn't represent the reference voltage, it represents the reference voltage, minus 1 LSB.

For the full story, see the 328's datasheet, page 256, section 24.7.
They even give a formula.

You're welcome

How about:
(Uncompiled, untested)

// 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.
}

It should return previous value until the threshold triggered. better save prev value in static var

The specifications are:
spec

You have a different datasheet than I have :smiley:

Mine's probably more up-to-date than yours; mine says "Microchip" at the bottom of the page, not "Atmel" :wink:
(Same formula, different section number)

The specifications of what?
Why the discussion about TTL?

spec

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.

For what input voltage, a 10-bit ADC will assume 1010100010 when the Full Scale of the ADC is 5V?

ADC do not measure voltages. They measure voltage ranges.

You mean that there is no answer to the question of Post-17 when the ADC's value is (theoretically) stable.

Only if you rephrase the question, "For what input voltage range..."