Using micro switch on analog pin

Hi!

I have run out of digital pins and am now forced to use the analog pins on my Uno clone. I would like to use a micro switch (like the one in the image) without an external resistor (cause I would have to order some and can't wait). So can I do it like this:

and this (pseudo) code:

void setup(){
pinMode (A0,INPUT_PULLUP)}

void loop(){
if(analogRead(A0)) 'do nothing'
else 'do something'
}

as fas as I understand it the pin is HIGH when the switch is not pressed. It's low when it's pressed. Therefore I have written the If clause as it is. When I use the pin as just INPUT I would have swapped 'do nothing' and 'do something'. If anyone wonders why I haven't querried a specific value with anologRead, well this way it works with my capacitive switch TP224, so I figured it should work here as well. If not please let me know.

btw - if this works - is there any chance that if I push the switch during upload/ initialization by accident that it would damage the board?

Why mess around with analogRead() ?

Wire the switch to take the pin to GND when closed, use INPUT_PULLUP and digitalRead()

You know analog pins can also be used as digital pins.

A0 = 14
A1 = 15
A2 = 16
A3 = 17
A4 = 18
A5 = 19

UKHeliBob:
Why mess around with analogRead() ?

Wire the switch to take the pin to GND when closed, use INPUT_PULLUP and digitalRead()

I use analogRead() because I found out that it works much faster on an analog pin than digitalRead(). And I need the speed for stepper motor control.

sorry to ask, but I don't understand how to "wire the switch to take pin to GND" (I am German, perhaps the language barrier :D), I thought that this is what I had already done in the image?

step1

larryd:
You know analog pins can also be used as digital pins.

A0 = 14
A1 = 15
A2 = 16
A3 = 17
A4 = 18
A5 = 19

thanks for the info, I read that but I didn't know that those numbers can be assigned to them to use them as digital pins.

step1

step1:
I use analogRead() because I found out that it works much faster on an analog pin than digitalRead().

That seems very unlikely. Please post the program that you used to measure the times.

...R

I don't understand how to "wire the switch to take pin to GND"

When using INPUT_PULLUP the pin will be held HIGH when connected to the switch if the switch is open. To detect whether the switch is closed, wire the other side of the switch to GND and test for the pin being LOW

I didn't know that those numbers can be assigned to them to use them as digital pins.

It does not matter whether you use the A* names or the actual pin numbers, they both work the same and at the same speed. Try printing A0, for instance. It is just defined as a number

Robin2:
That seems very unlikely. Please post the program that you used to measure the times.

...R

that was a few weeks ago, I only used the testing code temporarily. I think I used micros() to measure the time both for analogRead() and digitalRead(). I am not 100% sure but I think it took about 200µs for digitalRead() to read the analog pin. For analogRead() it was much less. At the time I used a rather long sin function which consumed a lot of time as well and so the code wouldn't keep up with the required 600µs for each microstep of my stepper motor.

UKHeliBob:
When using INPUT_PULLUP the pin will be held HIGH when connected to the switch if the switch is open. To detect whether the switch is closed, wire the other side of the switch to GND and test for the pin being LOW

still don't get what you mean :frowning: could you show in an image (preferably change the one I uploaded)? In my code I think I was testing by "if analogRead(A0)" if the switch is open so that when it's closed the else statement will execute some code (in my case stop the stepper motor).

It does not matter whether you use the A* names or the actual pin numbers, they both work the same and at the same speed. Try printing A0, for instance. It is just defined as a number

ah, I see, that is useful info, thank you :slight_smile:


Courtesy of LarryD

S3 is the one that I am suggesting

S3 is wired to a digital pin D3 and to GND. My switch is wired to A0 and GND. So I suppose (except for the use of the digital pin) it's the same way of testing the switch? If you look at my image, when the switch is open A0 is HIGH, so if I execute

IF anologRead(A0) do nothing

it tests if A0 is HIGH, i.e. if the switch is open. I guess IF analogRead(A0) and IF analogRead(A0) == HIGH are the same.

in your case I would execute:

IF digitalRead(D3)==LOW do something

of course, I just noticed I could just as well execute

IF analogRead(A0)==LOW do something and thereby omit the ELSE statement which makes the code faster. So I think I get your point now :slight_smile:

just one other thing (see my first post): is there any chance that if I push the switch during upload/ initialization by accident that it would damage the board? (since the pullup resistor has not yet been activated?)

step1

step1:
that was a few weeks ago, I only used the testing code temporarily. I think I used micros() to measure the time both for analogRead() and digitalRead().

The following program shows that there is almost no difference in the time for reading D7 or A0. And the average time for a read is about 3.5 microsecs

// python-build-start
// action, upload
// board, arduino:avr:uno
// port, /dev/ttyACM0
// ide, 1.8.6
// python-build-end

byte digitalPin = 7;
byte analogPin = A0;

volatile byte digitalPinVal = 0;
volatile byte analogPinVal = 0;

unsigned long startMicros = 0;
unsigned long midMicros = 0;
unsigned long endMicros = 0;

void setup() {
    Serial.begin(115200);
    Serial.println("Starting R2-readTime.ino");
    pinMode(7, INPUT_PULLUP);
    pinMode(A0, INPUT_PULLUP);

    startMicros = micros();
    for (int n = 0; n < 10000; n++) {
        digitalPinVal = digitalRead(digitalPin);
    }
    midMicros = micros();
    for (int m = 0; m < 10000; m++) {
        analogPinVal = digitalRead(analogPin);
    }
    endMicros = micros();
    Serial.print("10,000 digitalPin reads  ");
    Serial.println(midMicros - startMicros);
    Serial.print("10,000 analogPin reads  ");
    Serial.println(endMicros - midMicros);

}

void loop() {

}

...R

if(digitalRead(A0)) // switch is open, pin HIGH
if(! digitalRead(A0)) // switch is closed, pin pulled LOW

Hi Robin2,

I was comparing digitalRead(analogPin) and analogRead(analogPin), not digitalRead(digitalPin) and digitalRead(analogPin). However, I can't tell for sure which values I got and if there was'nt a possible other cause for the difference. I think back then I had read somewhere that digitalRead(analogPin) would first have to do a conversion from analog to digital and therefore would take longer than analogRead(analogPin). I'm pretty sure the latter was faster. But in case I will reproduce this some time in the future I will save the code and post it here.

step1

EDIT: maybe it had to do with querrieng input of a capacitive touch switch (TP224)?, also in pinMode I used INPUT instead of INPUT_PULLUP

JCA34F:
if(digitalRead(A0)) // switch is open, pin HIGH
if(! digitalRead(A0)) // switch is closed, pin pulled LOW

yep, exactly, that was my guess :slight_smile:

Stop messing around. Just use A0 as if it were a digital pin

Job done

If you want to read the pin faster then look at reading the port that it is on
See port manipulation

step1:
I was comparing digitalRead(analogPin) and analogRead(analogPin),

The following program is updated to include analogRead() and (as expected) they take about 112 µsecs each

// python-build-start
// action, upload
// board, arduino:avr:uno
// port, /dev/ttyACM0
// ide, 1.8.6
// python-build-end

byte digitalPin = 7;
byte analogPin = A0;

volatile byte digitalPinVal = 0;
volatile byte digitalPinValB = 0;
volatile byte analogPinVal = 0;
volatile int adcVal = 0;

unsigned long startMicros = 0;
unsigned long midMicros = 0;
unsigned long midMicros2 = 0;
unsigned long endMicros = 0;

void setup() {
    Serial.begin(115200);
    Serial.println("Starting R2-readTime.ino");
    pinMode(digitalPin, INPUT_PULLUP);
    pinMode(analogPin, INPUT_PULLUP);

    startMicros = micros();
    for (int n = 0; n < 10000; n++) {
        digitalPinVal = digitalRead(digitalPin);
        //~ digitalPinValB = digitalRead(digitalPin);
    }
    midMicros = micros();
    for (int m = 0; m < 10000; m++) {
        analogPinVal = digitalRead(analogPin);
    }
    midMicros2 = micros();
    for (int m = 0; m < 10000; m++) {
        adcVal = analogRead(analogPin);
    }
    endMicros = micros();
    Serial.print("10,000 digitalPin reads  ");
    Serial.println(midMicros - startMicros);
    Serial.print("10,000 analogPin reads  ");
    Serial.println(midMicros2 - midMicros);
    Serial.print("10,000 adc reads  ");
    Serial.println(endMicros - midMicros2);

}

void loop() {

}

...R

Robin2:
The following program is updated to include analogRead() and (as expected) they take about 112 µsecs each

// python-build-start

// action, upload
// board, arduino:avr:uno
// port, /dev/ttyACM0
// ide, 1.8.6
// python-build-end

byte digitalPin = 7;
byte analogPin = A0;

volatile byte digitalPinVal = 0;
volatile byte digitalPinValB = 0;
volatile byte analogPinVal = 0;
volatile int adcVal = 0;

unsigned long startMicros = 0;
unsigned long midMicros = 0;
unsigned long midMicros2 = 0;
unsigned long endMicros = 0;

void setup() {
    Serial.begin(115200);
    Serial.println("Starting R2-readTime.ino");
    pinMode(digitalPin, INPUT_PULLUP);
    pinMode(analogPin, INPUT_PULLUP);

startMicros = micros();
    for (int n = 0; n < 10000; n++) {
        digitalPinVal = digitalRead(digitalPin);
        //~ digitalPinValB = digitalRead(digitalPin);
    }
    midMicros = micros();
    for (int m = 0; m < 10000; m++) {
        analogPinVal = digitalRead(analogPin);
    }
    midMicros2 = micros();
    for (int m = 0; m < 10000; m++) {
        adcVal = analogRead(analogPin);
    }
    endMicros = micros();
    Serial.print("10,000 digitalPin reads  ");
    Serial.println(midMicros - startMicros);
    Serial.print("10,000 analogPin reads  ");
    Serial.println(midMicros2 - midMicros);
    Serial.print("10,000 adc reads  ");
    Serial.println(endMicros - midMicros2);

}

void loop() {

}




...R

did you read my EDIT Robin, maybe it's because of the TP224 I used and for some reason reading it as analog takes less time. And in pinMode I used INPUT instead of INPUT_PULLUP. Also, have you connected something to the pins you tested or just the loose ends?

step1

UKHeliBob:
Stop messing around. Just use A0 as if it were a digital pin

Job done

If you want to read the pin faster then look at reading the port that it is on
See port manipulation

if that works better I will do that :slight_smile:

step1

step1:
did you read my EDIT Robin, maybe it's because of the TP224 I used and for some reason reading it as analog takes less time. And in pinMode I used INPUT instead of INPUT_PULLUP. Also, have you connected something to the pins you tested or just the loose ends?

Those things won't make any difference. The time for a digitalRead() or analogRead() is entirely determined within the Atmel microchip. How the pin is connected will probably affect the result - but not the time taken to do the read.

The reason I posted the program is so you can try it yourself.

...R