Button Press Debounce Problem, when used Serial

Hi everyone.

I have a slight issue with button press.

Basically I am using an OLED LCD, which works serially.

The LCD needs to be initialised first before it is sent anything serially. So I use this to initialise it:


// Initialise OLED display. You must first activate a serial comunication!
void OLED_Init()
{
// First reset display
OLED_ResetDisplay();

delay(OLED_INITDELAYMS); // Wait for init
// Autodetect baudrate
printByte(OLED_DETECT_BAUDRATE);
OLED_GetResponse();
}

void OLED_ResetDisplay()
{
digitalWrite(OLED_RESETPIN, LOW);
delay(20);
digitalWrite(OLED_RESETPIN, HIGH);
delay(20);
}

char OLED_GetResponse()
{
byte incomingByte = OLED_ACK;
// Wait for data avaliable
while (!Serial.available()) { delay(1); }

// Read incoming byte
incomingByte = Serial.read();

return incomingByte;
}

The OLED_Init() gets called in Setup().

Problem is that; when I wanna detect a button press in my loop() it never gets detected. However if I get rid of the OLED_Init() method in Setup() the button press gets detected!

Any ideas?

Thanks.

Hi,
from the code you posted I'd say OLED_GetResponse waits forever in the

// Wait for data avaliable
 while (!Serial.available()) { delay(1); }

loop.

Did you call Serial.begin() before OLED_init()?
Does your OLED work at all?

Eberhard

Yes I called the Serial.Begin() in my Setup before the OLED_init()

so:

void Setup()
{
Serial.Begin(9600);
OLED_init();
}

Yes my OLED works absolutely fine! I just can't detect push button on any digital input pins!!

Thanks.

So the error is not in the code you posted.
Does the OLED_init(); code ever return?
Otherwise loop() will never be called, so your code never reaches the buttonpress part
Eberhard

But void loop() is always running! That's why I can put whatever code in the void loop() and draw things on the OLED LCD! so of course it's called!

What do you mean by "OLED_init(); code ever return?" ???

M.

But void loop() is always running!

No! When a arduino sketch is started it first runs the setup() method, and then it calls loop().

If in the line I pointed out

// Wait for data avaliable
 while (!Serial.available()) { delay(1); }

Serial.available() always return 0, the while-loop will never terminate, OLED_init() will never return;loop() will never be called.

Eberhard

Ok,

I know void loop() gets called because my code within void loop(), which draws a line on the LCD, works!!! But not the button press detection! That was the whole problem to start with.

Why is it that the button press never gets detected?

M.

How could we say anything about that, without seeing the relevant code section????

All you posted was code for the display-initialization. Please post the code-section with the button-code (and its sourrounding) .

Eberhard

int buttonPin = 2;
int buttonState = 0;

void Setup()
{
Serial.begin(9600);

pinMode(buttonPin, INPUT);

OLED_Init();
}

void loop()
{
DRAW_LINE_TO_LCD();

if (buttonState == HIGH)
{
//Do Something
} else {
//Do Something Else
}
}

/ Initialise OLED display. You must first activate a serial comunication!
void OLED_Init()
{
// First reset display
OLED_ResetDisplay();

delay(OLED_INITDELAYMS); // Wait for init
// Autodetect baudrate
printByte(OLED_DETECT_BAUDRATE);
OLED_GetResponse();
}

void OLED_ResetDisplay()
{
digitalWrite(OLED_RESETPIN, LOW);
delay(20);
digitalWrite(OLED_RESETPIN, HIGH);
delay(20);
}

char OLED_GetResponse()
{
byte incomingByte = OLED_ACK;
// Wait for data avaliable
while (!Serial.available()) { delay(1); }

// Read incoming byte
incomingByte = Serial.read();

return incomingByte;
}

You set

buttonstate=0;

at the top of the code.

The value of this variable is never changed in the rest of the code.
So the test

if (buttonState  == HIGH)
{    
   //Do Something
  } else {
   //Do Something Else
}

will always go to the Else clause

I think you forgot a

buttonState=digitalRead(buttonPin)

Eberhard

Yes I forgot to put it in the above code as I was typing everything quickly for this forum. But I have it in my actual code in the compiler!

Any ideas?!

M.

Copy and paste your code. The digitalRead() call is the most important one for tracking down the problem.

Is you button connected to the right pin?
http://www.arduino.cc/en/Tutorial/Button

Light up an led right before you call digitalRead() to see if your code actually gets there.

However if I get rid of the OLED_Init() method in Setup() the button press gets detected!

I don't see anything that would connect the OLED_Init() method to the button problem.

Eberhard

I still haven't solved this and I've tried everything!!!
:frowning:

Any ideas?

M.

Please do what other posters suggested; post your exact sketch copy-and-pasted. Don't type it in!

By only posting hand-copied material from where you think that the problem is, you are forcing us to essentially look at your conclusions and not at the source material. It is unlikely that we will find the issue by looking at your conclusions since you cannot find it.

Worse, you are wasting all these people's time which is why people have stopped trying to help you.

But here's a wild guess: press the button and HOLD IT DOWN for many seconds and tell us if that works. AND COPY_PASTE YOUR SKETCH!!!

#define OLED_DETECT_BAUDRATE 0x55
#define OLED_ACK 0x06 // Ok
#define OLED_NAK 0x15 // Error

#define OLED_CLEAR 0x45

int OLED_RESETPIN = 53;
int OLED_INITDELAYMS = 3000;

const int buttonPin = 2; // the pin that the pushbutton is attached to
const int ledPin = 12; // the pin that the LED is attached to
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button
int ledState = 0; // remember current led state

void setup() {

Serial.begin(19200);

pinMode(buttonPin, INPUT); // initialize the button pin as a input
pinMode(ledPin, OUTPUT);

pinMode(OLED_RESETPIN, OUTPUT); // sets the digital pin as output

//Using pin53 to control reset of the OLED
OLED_Init();

//clear screen
OLED_Clear();

}

void loop()
{

// read the pushbutton input pin
buttonState = digitalRead(buttonPin);

if (buttonState == HIGH)
{
digitalWrite(ledPin,HIGH);
} else {
digitalWrite(ledPin,LOW);
}

}

/ Initialise OLED display. You must first activate a serial comunication!
void OLED_Init()
{
// First reset display
OLED_ResetDisplay();

delay(OLED_INITDELAYMS); // Wait for init
// Autodetect baudrate
printByte(OLED_DETECT_BAUDRATE);
OLED_GetResponse();
}

void OLED_ResetDisplay()
{
digitalWrite(OLED_RESETPIN, LOW);
delay(20);
digitalWrite(OLED_RESETPIN, HIGH);
delay(20);
}

char OLED_GetResponse()
{
byte incomingByte = OLED_ACK;
// Wait for data avaliable
while (!Serial.available()) { delay(1); }

// Read incoming byte
incomingByte = Serial.read();

return incomingByte;
}

There we go.

Thanks,
M.

Hi,
did you verify that the Led connected to pin 12 works. ?

Put this into your setup() function

digitalWrite(ledPin,HIGH);
delay(1000);
digitalWrite(ledPin,LOW);
delay(1000);

You have the onboard led on pin 13. Use it to verify that your loop() function is called by blinking it, the same way i did it with the led on pin 12.
put this into your loop() function

pinMode(13,OUTPUT);

Put this at the top of your loop() function

digitalWrite(13,HIGH);
delay(1000);
digitalWrite(13,LOW);
delay(1000);

Tell us what you see..

Eberhard

Yeah, Eberhard is smart to take a divide and conquer approach.

We cannot guarantee that the code is getting past the while loop that is waiting to recv data. His comments will prove or disprove that and therefore point us to a problem in the OLED code or a problem with the button.

I'm going to jump ahead tho and ask you to describe how the button is connected... did you connect pin 2 to one side of the button and the other side to ground? (That will not work erratically...)

This works in Setup()

Both set on pin12 and pin13 for the LED. If I put before the "OLED_Init();"

digitalWrite(ledPin,HIGH);
delay(1000);
digitalWrite(ledPin,LOW);
delay(1000);

When I do the above in loop(); it works if I get rid of the "OLED_Init();" but doesn't if "OLED_Init();" stays there.

The button is conneted the correct way. Reason why I am 100% sure is that when I so a very simple button push program it works perfectly. When I mix it with OLED code it doesn't work! This is what the problem has been from the begining.

M.

And this is what I sugessted from the beginning:
OLED_init() does never returns therefore setup() never returns and in the end loop() is never called, so the button is never checked.

My last suggestion to this topic is to remove the call to
OLED_GetResponse(); in setup() and see what happens.

Eberhard

@matinzk

"The button is conneted the correct way. Reason why I am 100% sure is that when I so a very simple button push program it works perfectly"

I'd recommend that you learn how to present data not your opinion. That you are 100% sure is not relevant. You are asking for help. If you can't be bothered to take the time to state what you think the correct way is, why should we be spending all this time thinking abt your proglem. In this case, if the pin is "floating" proximity to a driven pin could affect the float level. Inclusion of the serial drives pins and could influence proximal pins. This is why I asked the question.

Regardless, there's no point chasing this unlikely case when in fact this bug is pretty obviously what Eberhard 1st suggested. I just got fooled by your obstinacy. Loop() is never being run.

Good luck...