Simple Math Increment / Decrement Problem ~solved~

Ok this verifies but I'm not getting the expected results. I'm sure it's something simple but I'm just not seeing it. This is a EM Game I'm building and this is just a coin switch and a start button. I expect the coinCount to increment with the coin switch and decrement with the start button. My results are displayed on multi digit segment displays.

First coin press display reads SW1 Coin 0 (when I expect a 1 for 1 coin instead of 0)
then when I go to start button it adds 1 to the count then subsequent presses decrement as expected. Likewise if I add coins after a start(decrement), it decrements 1 first then starts adding them

example
coin press > displays: sw1 coin 0 (expecting 1)
coin press > displays: sw1 coin 1 (expecting 2)
coin press > displays: sw1 coin 2 (expecting 3)
start press > displays sw6 coin 3 (expecting 2)
start press > displays sw6 coin 2 (expecting 1)

#include <Wire.h>

#include <SparkFun_Alphanumeric_Display.h>  //Click here to get the library: http://librarymanager/All#Alphanumeric_Display by SparkFun
HT16K33 display;
int coinCount = 0;
int coinState = 0;
int lastCoinState = 0;
int startCount = 0;
int startState = 0;
int lastStartState = 0;
const int led1 = 13;
const int coin = 7;
const int start = 6;


void setup() {

  Serial.begin(115200);
  Serial.println("SparkFun Qwiic Alphanumeric");
  Wire.begin(); //Join I2C bus

  //check if displays will acknowledge
  if (display.begin(0x70, 0x71, 0x72) == false)
  {
    Serial.println("Device did not acknowledge! Freezing.");
    while (1);
  }
  Serial.println("Displays acknowledged.");

  pinMode(coin, INPUT_PULLUP);
  pinMode(start, INPUT_PULLUP);
  pinMode(led1, OUTPUT);

}

void loop() {
  String coins = String(coinCount);

  coinState = digitalRead(coin);
  if (coinState != lastCoinState) {
    if (coinState == LOW) {
      coinCount++;
      digitalWrite(led1, HIGH);
      display.print("SW1 COIN" + coins);
    }
  }
  lastCoinState = coinState;

  startState = digitalRead(start);
  if (startState != lastStartState) {
    if (startState == LOW && coinCount > 0) {
      coinCount--;
      digitalWrite(led1, HIGH);
      display.print("SW6 COIN" + coins);
    }
  }

  lastStartState = startState;



You set the value of the coins String to that of the coinCount variable. Later in the code you increment the value of coinCount but do not update the value of the coins String before you print it

void loop()
{
    String coins = String(coinCount);   //coins has a value of 0

    coinState = digitalRead(coin);
    if (coinState != lastCoinState)
    {
        if (coinState == LOW)
        {
            coinCount++;
            digitalWrite(led1, HIGH);
            display.print("SW1 COIN" + coins);  //the value of coins has no changed
        }
    }

So it prints the original value of coinCount

  • Suggest you sample the coin switch every 50ms rather than at wide open loop( ) speed.

Thanks Bob, I did think I needed to update the variable before printing. But I also just realized I needed to pre-increment (++coinCoint) vs. post Increment.

adding:
coins = ++coinCount
solved this.

corrected code for anyone interested. This is also based off the state change example.

#include <Wire.h>

#include <SparkFun_Alphanumeric_Display.h>  //Click here to get the library: http://librarymanager/All#Alphanumeric_Display by SparkFun
HT16K33 display;
int coinCount = 0;
int coinState = 0;
int lastCoinState = 0;
int startCount = 0;
int startState = 0;
int lastStartState = 0;
const int led1 = 13;
const int coin = 7;
const int start = 6;


void setup() {

  Serial.begin(115200);
  Serial.println("SparkFun Qwiic Alphanumeric");
  Wire.begin(); //Join I2C bus

  //check if displays will acknowledge
  if (display.begin(0x70, 0x71, 0x72) == false)
  {
    Serial.println("Device did not acknowledge! Freezing.");
    while (1);
  }
  Serial.println("Displays acknowledged.");

  pinMode(coin, INPUT_PULLUP);
  pinMode(start, INPUT_PULLUP);
  pinMode(led1, OUTPUT);

}

void loop() {
  String coins = String(coinCount);

  coinState = digitalRead(coin);
  if (coinState != lastCoinState) {
    if (coinState == LOW) {
      coins = ++coinCount;
      digitalWrite(led1, HIGH);
      display.print("SW1 COIN" + coins);
    }
    else {
      digitalWrite(led1, LOW);
    }
  }
  lastCoinState = coinState;

  startState = digitalRead(start);
  if (startState != lastStartState) {
    if (startState == LOW && coinCount > 0) {
      coins = --coinCount;
      digitalWrite(led1, HIGH);
      display.print("SW6 COIN" + coins);
    }
    else {
      digitalWrite(led1, LOW);
    }
  }

  lastStartState = startState;



}

I was going to add some delay for de-bounce anyway. But is there another reason to sample every 50ms? Always open to new ideas, I've got little experience with this coding.

I'm not going to use simple delay(), but the have been using the "blink without delay" example for my delays / debounce.

It wouldn't really matter except if the add coins while an active game is being played. Than a regular delay() may stall other code from executing is my understanding.

To mark the topic as Solved, tick the "Solution" box against whichever post for forum member gave you the most important advice or answer (this should not be yourself!).

1 Like
  • 10, 20, 30, 40, 50, you pick.
    I have found 50ms is a reasonable number for mechanical switch de-bounce.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.