Trying to read button presses

efftek
Sun Mar 19, 2017 8:28 pm
Hi,

I have two buttons connected to my blue pill on PB10 and PB11. Ultimately, I need six buttons, I’m just messing around with code to get two working. So, I initialise both pins with INPUT_PULLUP so it will detect when the pin is pulled low by a button press and it was working well with just one button. Now I have added a second button, it only detects one press at a time, ie I cant press the same button twice. If a press is detected, I have a debounce delay of 100mS then a while loop waits until the button is released so holding the button down doesn’t give multiple detects. One butto turns the board LED on, the other turns it off so I have a visual representation that it is working. Theres also a serial output to show which button was pressed for when I have more than two buttons connected. I cannot for the life of me see why it wont detect the same button pressed repeated times. Any ideas?

#define DEBOUNCE 100

void setup()
{
pinMode(PC13, OUTPUT);
digitalWrite(PC13, LOW);

pinMode(PB10, INPUT_PULLUP);
pinMode(PB11, INPUT_PULLUP);
Serial.begin(115200);
}

int isButtonPressed(int pin)
{
if (digitalRead(pin))
{
delay(DEBOUNCE);
while (digitalRead(pin));
return true;
}
else
return false;
}

void loop()
{
if (isButtonPressed(PB10))
{
Serial.println("You pressed UP");
digitalWrite(PC13, HIGH);
delay(500);
}

if (isButtonPressed(PB11))
{
Serial.println("You pressed DOWN");
digitalWrite(PC13, LOW);
delay(500);
}
}


BennehBoy
Sun Mar 19, 2017 8:50 pm
I use a little library to read them inside a state machine, it works nicely.

probably best to look at the code -> https://github.com/BennehBoy/LRDuinoTD5


efftek
Sun Mar 19, 2017 9:06 pm
Thankyou. I have downloaded the files but will look at them later, my head is getting heavy and my eyes grow dim, I need to stop for tonight!

Sorry thats what happens when your designing a board using Eagle all day!

Steve.


enif
Mon Mar 20, 2017 8:55 am
Aren’t your buttons are pressed when digitalRead(pin) is false? But your code seems to test it for true. So as long as button PB11 is not pressed, it does not return from isButtonPressed(PB11).

But anyway, I doubt that the way you try to debounce is working well, so indeed you will probably be better off using the library…


efftek
Mon Mar 20, 2017 2:09 pm
enif wrote:But anyway, I doubt that the way you try to debounce is working well, so indeed you will probably be better off using the library…

Nutsy
Tue Mar 21, 2017 10:49 am
What about using interrupts?

BennehBoy
Tue Mar 21, 2017 11:05 am
Nutsy wrote:What about using interrupts?

Nutsy
Tue Mar 21, 2017 4:04 pm
fair enough… Might sound superfluous but in my project, to get button presses to work properly im using the built in nextion library button interrupts. (on screen buttons) Well a mixture of that and some of my own serial checking stuff… the library really is a total mess… Bearly functions as its designed too.

but in any case, what im doing is having the interrupts flag a boolean thats checked in due course of the loop run then takes action to what it needs to do…

A hardware interrupt can run in the same way. A small function to set a boolean thats later checked.

Or depending on ease of coding… the interrupt call can do everything thats required later… Though Im not 100% sure if a function called by an interrupt call blocks other interrupts…


BennehBoy
Tue Mar 21, 2017 6:37 pm
Yeah best to spend as little time in an interrupt as possible.

efftek
Tue Mar 21, 2017 8:27 pm
Nutsy wrote:What about using interrupts?

efftek
Tue Mar 21, 2017 8:32 pm
Nutsy wrote:Bearly functions as its designed too.

efftek
Tue Mar 21, 2017 8:34 pm
efftek wrote:One butto turns the board LED on

david.prentice
Tue Mar 21, 2017 10:43 pm
You normally read button presses in a regular Timer interrupt. XOR the new reading with the previous reading to determine a change. Increment counter for a steady state. A button is effectively debounced when it has had a steady value for 20ms. A “long press” can be detected by a large count.

The button scan takes very few processing cycles. Most apps have a regular Timer interrupt anyway e.g. SYSCLOCK.

Your ADC will work in the background. An interrupt flag is set when the ADC completes.

David.


Nutsy
Wed Mar 22, 2017 11:14 am
I think if the nextion Rarred it would be an improvement :p

efftek
Wed Mar 22, 2017 9:29 pm
david.prentice wrote:Your ADC will work in the background.

Nutsy
Sun Mar 26, 2017 12:46 pm
efftek wrote:david.prentice wrote:Your ADC will work in the background.

efftek
Mon Mar 27, 2017 9:45 am
Nutsy wrote:
I dont know if its because im so tired… but i can barely understand what that line does :p

Pito
Mon Mar 27, 2017 11:51 am
What is the reason for multiplying the reala(b) by 16??
xa[a] = (((uint16_t)(reala*16)) | ((uint32_t)(imag<<16)));

Is it not this you want?
xa[a] = (((uint32_t)(reala)) | ((uint32_t)(imag<<16)));


efftek
Mon Mar 27, 2017 7:14 pm
[quote=”Pito”]What is the reason for multiplying the reala(b) by 16??
quote]

The adc is 12 bits, maximum value 4096. The FFT uses 16 bit int, maximum value 65536 which divided by 4096 is 16 hence the real value is multiplied by 16 for ‘proper scaling’.

It seems to be a point people are divided abaout Pito. I know you said you didn’t think scaling mattered when doing an FFT and you definitely know a lot more about FFT’s than me so I accepted it. Thank you for pointing out that I forgot to remove the *16

Steve.


Leave a Reply

Your email address will not be published. Required fields are marked *