Electronic – Increment value and display in C

cmbedmicrocontroller

as my primary thing with electronics is hardware, I am having some difficulties learning programming. Unfortunately, my college where I study offers no such course so for my project this year I decided to incorporate some, to force myself to learn it, however, I am struggling to understand some of it! I have been building up separate parts of my code and most of it is working, however, I am trying to display a count on an LCD, and each time a button is pressed, I want it to increment by 1.

I managed to do this successfully on an Arduino (as there are many example sketches out there) but I want to do my project using an STM Nucleo (F103RB). I tried to transfer the example code over, and edit it using commands the online mbed IDE would understand, but it would not work. I then found a few different examples and each gave me different results. I eventually came up with my own code following a guide in adding/subracting in the book 'C Programming: A mordern approach'. The code I have come up with is here:

#include "mbed.h"
#include "TextLCD.h"

DigitalIn ip(D7);
TextLCD lcd(A0, A1, A2, A3, A4, A5);

int i =0;

int main() {
    lcd.cls();
    lcd.locate(0,0);
    lcd.printf("COUNT:");
    lcd.locate(0,1);
    lcd.printf("%d",i);
    while(1) {
    if (ip ==1) {
    lcd.locate(0,1);
    lcd.printf("%d", ++i);
        }
    }

And finally, the count started responding when I pushed the button. However, the issue I am having, is that the count increments all the time I have the button pressed, so even a small press will increase the count by 50-80 (depending how quickly you press it) and I want it to increment by 1 each press.

I have tried structuring it differently, having the 'while' statement at the beginning etc, but that just caused the LCD to oscillate strangely.

I've been stuck on this for about 6 hours now before getting to this point! Would really appreciate if someone could give me some pointers in the right direction!

In case anyone is needing it, my (simplified) schematic is here:

schematic

simulate this circuit – Schematic created using CircuitLab

So you can see it really is very simple. But I have just zero knowledge of C programming and have never been taught how to do it properly, so any solutions will need to be explained!

Best Answer

The main reason your counter increases so quickly is that you probably hold it down for about 1 second and the while loop is executed about 100 times during that time. So it will increase the counter by about 100.

What you really want is to only increase the counter once each time it's pressed down. A solution is shown below. The while loop remembers the last state of the button. The if clause is then only executed if the state goes from 0 to 1. It will no longer be executed when the previous value is 1, i.e. the button state hasn't changed but was just kept pressed down.

#include "mbed.h"
#include "TextLCD.h"

DigitalIn ip(D7);
TextLCD lcd(A0, A1, A2, A3, A4, A5);

int i = 0;
int lastButtonValue = 0;

int main() {
    lcd.cls();
    lcd.locate(0,0);
    lcd.printf("COUNT:");
    lcd.locate(0,1);
    lcd.printf("%d",i);

    while(1) {
        if (lastButtonValue == 0 && ip == 1) {
            lcd.locate(0,1);
            lcd.printf("%d", ++i);
        }
        lastButtonValue = ip;
    }
}