-1

I am checking for pressing of a switch(negative logic) inside the condition of a while loop. But the variable in which I store the input button press does not change state if I press the button. If I keep pressing the switch and reset the Arduino board, the press is recognized.

I tried making the variable volatile but I don't understand why it still don't work? I also tried to read from register instead of digitalRead but in vain.

volatile char ok_btn;
ok_btn= digitalRead(10);        

while(ok_btn!=0)
{
Serial.println("ok button not pressed/n");
delay(200);
}

Serial.println("ok button pressed/n");

It seems the variable ok_btn is just reading once and storing it for ever!

Bhuvnesh
  • 101
  • 4
  • The language you're using is C++. – Antti Haapala -- Слава Україні Aug 09 '19 at 10:25
  • 4
    `volatile` does not mean that it would automatically change value in the future. It just means that the compiler cannot assume that it would not change without compiler knowing. – Antti Haapala -- Слава Україні Aug 09 '19 at 10:26
  • C++ (which is the language used on Arduino) doesn't to things automatically. If you want to get the value of `digitalRead(10)` continuously then you explicitly have to call it continuously. That is, you need to do it inside the loop. And `volatile` have nothing to do with this. – Some programmer dude Aug 09 '19 at 10:29
  • So isn't there a way to get fresh values of the input without using digitalRead. I have seen on many websites that if a variable is volatile, the compiler re-reads its value wherever it is used. – Bhuvnesh Aug 09 '19 at 10:37
  • 2
    `volatile` does not say `ok_btn` gets set from `digitalRead(10)`, so update `ok_btn` whenever `digitalRead(10)` changes. `volatile` says “I have made special arrangements so that `ok_btn` is at an address that is physically connected to some device that changes its value in hardware, so, every time I use `ok_btn` in my code, read it again.” (That is a simplification for this situataion; `volatile` has further meaning.) You have not done that; you have not made arrangements so that `ok_btn` is directly mapped to a special address. – Eric Postpischil Aug 09 '19 at 10:38
  • If `digitalRead(10)` is reading data from some address that is updated by hardware, not a regular memory address, then there is a possibility you could define `ok_btn` to be a pointer to a volatile type, then initialize `ok_btn` to that address, then use `*ok_btn` in your code. This might not be much faster than calling `digitalRead(10)`, depending on how it is implemented. (If `digitalRead` is a macro that just expands to a reference to a volatile location, then doing it yourself will not be any faster.) – Eric Postpischil Aug 09 '19 at 10:40
  • @Eric Postpischil As I mentioned, I tried using an internal register too to read from; but that too did not 'make the arrangement' – Bhuvnesh Aug 09 '19 at 10:42
  • @EricPostpischil Thanks! I'll try your method – Bhuvnesh Aug 09 '19 at 10:43

2 Answers2

2
  1. You need to move the digitalread function inside the while loop.

  2. If you are using a physical switch, you need to have some sort of debounce mechanism for the switch. Look at Simple Debounce Routine for some ideas.

Rishikesh Raje
  • 8,556
  • 2
  • 16
  • 31
  • I have used debounce mechanism in actual code though. And I don't want to read every time from the digitalRead because I have to use this variableat many places. Why volatile is not working here? It should! – Bhuvnesh Aug 09 '19 at 10:35
  • 1
    You are reading the `digitalread` only once. After that you enter the while loop and do not read it again, so the value of `ok_btn` does not change. `volatile` only indicates to the compiler that there is a *possibility* that `ok_btn` can change (from some external source e.g.interrupt ) The actual change needs to be done somewhere in the code. – Rishikesh Raje Aug 09 '19 at 10:40
  • @Bhuvnesh: What is the problem with reading every time from `digitalRead`? If it is too much code to write, use a macro. (Hint: It is not too much code to write. Just write it.) If it is slow, why do you think it is slow? Did you time it? – Eric Postpischil Aug 09 '19 at 10:41
  • @Bhuvnesh If you've used for example timer ISR to update that variable every few milliseconds, it'd work (and it wouldn't work without volatile). But now you set some value to the variable (volatile or not) and never ever changed it again. – KIIV Aug 09 '19 at 10:43
  • @Bhuvnesh - If you have implemented debounce, then you would anyway need to read the input periodically every `X` milliseconds, You can then have other functions take the input from the debounced value. – Rishikesh Raje Aug 09 '19 at 10:47
0

as long as ok_btn isn´t 0 it won´t leave your while loop so it doesn´t read the button, it´s better to check the value of ok_btn in a if/else

8bit
  • 528
  • 2
  • 6
  • 25