Go Down

Topic: Digital inputs for MAME credit use (Read 1 time) previous topic - next topic

Karl_H

I'm trying to write a sketch to handle the credits process for a MAME cabinet I am building.
I want to use 1 coin mechanism which will be monitored by the Arduino to record the number of credits inserted. Each player will have a "Use Credit" button, which will tell the Arduino to deduct 1 from the number of credits, and then pass that on to the keyboard encoder. I also want to have an LED on when there are unused credits available in the Arduino (that is, credits that haven't been passed on to the encoder yet).

I am doing this because I don't want to have to use 4 coin mechanisms for the cabinet, to save money, and space and to make the finished cabinet look nicer.

For my testing I am just using push buttons rather than a coin mechanism, and using Serial.print rather than connecting to the encoder.

I think I'm having trouble because of the "if" conditions. It's likely that I'm not using them properly, because I don't have the experience with programming yet.

The Sketch I have so far is:

Code: [Select]
/*
*  Counting Coins Entered, Subtracting Coins Used
*    Set up for coin mechanisim with pull DOWN resistor, so HIGH on coin insert
*    Player use credit buttons also with pull DOWN resistor, HIGH on press
*    LED to indicate available credits
*/

int P1_Pin = 6;              // Player 1 credit button
int P2_Pin = 2;              // Player 2 credit button
int P3_Pin = 3;              // Player 3 credit button
int P4_Pin = 4;              // Player 4 credit button
int Coin_Pin = 5;            // Coin mechanism switch

int Pn_LED_Pin = 13;          // LED to indicate available credits

int Coin_Val;                   // variable for reading the pin status
int P1_Val;
int P2_Val;
int P3_Val;
int P4_Val;

int P1_State;                   // variable to hold the Player 1 credit state
int P2_State;                   // variable to hold the Player 2 credit state
int P3_State;                   // variable to hold the Player 3 credit state
int P4_State;                   // variable to hold the Player 4 credit state
int Coin_State;                 // variable to hold the Coin Mechanisim state

int Credits = 0;                // Initial credit count



void setup() {
  pinMode(P1_Pin, INPUT);        // Set input/output pins
  pinMode(P2_Pin, INPUT);
  pinMode(P3_Pin, INPUT);
  pinMode(P4_Pin, INPUT);
  pinMode(Coin_Pin, INPUT);
  pinMode(Pn_LED_Pin, OUTPUT);

  Serial.begin(9600);                   // Set up serial communication at 9600bps
 
  Coin_State = digitalRead(Coin_Pin);   // read the initial state
  P1_State = digitalRead(P1_Pin);       // read the initial state
  P2_State = digitalRead(P2_Pin);       // read the initial state
  P3_State = digitalRead(P3_Pin);       // read the initial state
  P4_State = digitalRead(P4_Pin);       // read the initial state
}


void loop(){
  Coin_Val = digitalRead(Coin_Pin);      // read input value and store it as *_Val
  P1_Val = digitalRead(P1_Pin);
  P2_Val = digitalRead(P2_Pin);
  P3_Val = digitalRead(P3_Pin);
  P4_Val = digitalRead(P4_Pin);

      // When coin is inserted +1 to Credits
  if (Coin_Val != Coin_State) {            // button used
    if (Coin_Val == HIGH) {                // check if the button is pressed
      Credits++;                           // increment the credits variable
      Serial.print(Credits);
      Serial.println(" Credits Remaining");
    }
  }
 
      // When Player 1 button is pressed, check available credits, if 1 or more, use 1
  if (P1_Val != P1_State){            // button used
    if (P1_Pin == HIGH) {             // check if pressed
      if (Credits >= 1) {             // check available credits
        Credits--;                    // use 1 credit
        Serial.println("Player 1 Used a Credit. ");
        Serial.print(Credits);
        Serial.println(" Credits Remaining");
      }
    }
  }

      // When Player 2 button is pressed, check available credits, if 1 or more, use 1
  if (P2_Val != P2_State){            // button used
    if (P2_Pin == HIGH) {             // check if pressed
      if (Credits >= 1) {             // check available credits
        Credits--;                    // use 1 credit
        Serial.println("Player 2 Used a Credit. ");
        Serial.print(Credits);
        Serial.println(" Credits Remaining");
      }
    }
  }

      // When Player 3 button is pressed, check available credits, if 1 or more, use 1
  if (P3_Val != P3_State){            // button used
    if (P3_Pin == HIGH) {             // check if pressed
      if (Credits >= 1) {             // check available credits
        Credits--;                    // use 1 credit
        Serial.println("Player 3 Used a Credit. ");
        Serial.print(Credits);
        Serial.println(" Credits Remaining");
      }
    }
  }
   
       // When Player 4 button is pressed, check available credits, if 1 or more, use 1
  if (P4_Val != P4_State){            // button used
    if (P4_Pin == HIGH) {             // check if pressed
      if (Credits >= 1) {             // check available credits
        Credits--;                    // use 1 credit
        Serial.println("Player 4 Used a Credit. ");
        Serial.print(Credits);
        Serial.println(" Credits Remaining");
      }
    }
  }
 
  Coin_State = Coin_Val;    // save number of credits
 
        // Check number of Credits, if 1 or more LED on, if 0 LED off. If less than 0 set to 0
  if (Coin_State >= 1) {
      digitalWrite(Pn_LED_Pin, HIGH);
  } else {
      digitalWrite(Pn_LED_Pin, LOW);
      Coin_State = 0;
  }
 
}


This is working for adding credits (when pressing the button connected to pin 5 the serial monitor outputs an incrementing number of credits remaining), but it's not responding to the other buttons (pins 2, 3, 4 and 6, representing the player use credit buttons, which should reduce the number of credits by one, and output "player [number] used a credit" on the serial monitor). I suspect that the code is only being read as far as the first "if" condition, and not moving on to the others.

I am using an Arduino Uno.

I only have a limited experience in coding, and have always had issues with using conditions.
Any help would be greatly appreciated!

Osgeld

Quote
I suspect that the code is only being read as far as the first "if" condition, and not moving on to the others.


so toss a Serial.println("entered if # 2 or whatever"); after the first if to see if its stopping there or not
http://arduino.cc/forum/index.php?action=unread;boards=2,3,4,5,67,6,7,8,9,10,11,66,12,13,15,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,86,87,89,1;ALL

Karl_H

I didn't think of that. Thanks Osgeld.

It is reading past the "if" conditions, just not working. Back to the drawing board I guess, check the wiring and so on.

Riva

A quick look at your code and I think
Code: [Select]
if (P1_Pin == HIGH) {             // check if pressed
is a problem. P1_Pin is defined as the pin number (in this case 6) maybe you need
Code: [Select]
if (digitalRead(P1_Pin) == HIGH) {             // check if pressed
I'm not sure why you read the initial state of the buttons in setup() and then only act on them changing from this state
Code: [Select]
if (P1_Val != P1_State){            // button used but then check again later against a known state
Code: [Select]
if (P1_Pin == HIGH) { of HIGH to determine if button is pressed. Your code readability would benefit from using a function to check button presses. Maybe checkout the Arduino Debounce example and convert it to a function that takes the button to read as a parameter and returns the button state.
http://forum.arduino.cc/index.php?action=unread;boards=5,67,10,11,66,12,15,17,21,22,23,24,25,29;ALL

Karl_H

Thanks for the advice Riva.

I have been working for a tutorial script, which I did get to work as written, but then have taken it apart and changed bits around and put bits in. Being fairly new to coding I'm not exactly sure what is required and what isn't.

I'll try your suggestion when I get the chance and post back with my results.

Karl_H

Many thanks Riva!

The checking of state in setup() seems to have been largely where I have gone wrong. With your suggestions it is working nearly perfectly. I just need to write in a debounce to it so it only issues 1 credit per press of the coin button, and only uses one per press of the use credit button.

I'm not entirely sure about what you mean by
Quote
using a function to check button presses

But I'm sure a quick Google search will point me in the right direction.

Again thank you very much!

Riva


The checking of state in setup() seems to have been largely where I have gone wrong. With your suggestions it is working nearly perfectly. I just need to write in a debounce to it so it only issues 1 credit per press of the coin button, and only uses one per press of the use credit button.

I'm not entirely sure about what you mean by
Quote
using a function to check button presses


Something like the below code will debounce button presses and it's a function to check buttons just call it with something like 'if (checkButton(3) == HIGH){'
You may need to reverse the logic (replace HIGH with LOW and vice-versa) if you use pull up switches as this is for pull down version.

Code: [Select]

const long debounceDelay = 40;          // Button debounce time

// Button = pin number to read
int checkButton(int Button){
    int buttonState = digitalRead(Button);              // Read button
    if (buttonState == HIGH){                           // If button pressed then wait a bit to allow for debounce
        long Time = millis();
        while ((millis() - Time) < debounceDelay){   
        }
        buttonState = digitalRead(Button);              // Read button again
        return buttonState;                             // Return button state
    }
    else {                                              // Button not pressed so no need to wait for bebounce
        return LOW;
    }
}
http://forum.arduino.cc/index.php?action=unread;boards=5,67,10,11,66,12,15,17,21,22,23,24,25,29;ALL

Go Up