Pushbutton Help

Hi! I am trying to work with a LCD screen, a pushbutton, and a TTL (GT-521F32) fingerprint scanner. The board I am using is an Arduino Mega 2560. What I want my code to do is when the you scan your print and it detects that you are a good print, then you will be able to hit the pushbutton "buttonAdd" to add a new print to the system. Right now what happens is when a good print is detected it just jumps straight into the Enroll function without having to hit the pushbutton. Any help would be greatly appreciated. Thank you for your time as well!

I also intend to add a delete print option as well.

#include <FPS_GT511C3.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>

#define GREEN 13
#define RED 12
#define RELAY 3
#define buttonAdd 48
#define buttonDel 46


FPS_GT511C3 fps(51, 53);


LiquidCrystal lcd(8, 9, 4, 5, 6, 7);


void setup() {
  // put your setup code here, to run once:

  lcd.begin(16, 2);
  lcd.clear();

  pinMode(GREEN, OUTPUT);
  pinMode(RED, OUTPUT);
  pinMode(RELAY, OUTPUT);
  pinMode(buttonAdd, INPUT);
  digitalWrite(RELAY, LOW);
  digitalWrite(GREEN, LOW);
  digitalWrite(RED, LOW);

  Serial.begin(9600);
  delay(1000);
  fps.Open();
  fps.SetLED(true);
  
}

void loop() {
  // put your main code here, to run repeatedly:
  lcd.clear();
  lcd.print("Waiting for");
  lcd.setCursor(0, 1);
  lcd.print("scan!");

  if (fps.IsPressFinger()){
    fps.CaptureFinger(false);
    int id = fps.Identify1_N();
    

    if (id < 4) {
      lcd.clear();
      lcd.print("Welcome user");
      lcd.setCursor(0, 1);
      lcd.print("ID: ");
      lcd.print(id);
      digitalWrite(GREEN, HIGH);
      if(digitalRead(buttonAdd) == HIGH){
        Enroll();
      }
      
      
      delay(5000);
      digitalWrite(GREEN, LOW);
      lcd.clear(); 
    }
    else{
      lcd.clear();
      lcd.print("Finger not");
      lcd.setCursor(0, 1);
      lcd.print("Found in system");
      digitalWrite(RED, HIGH);
      delay(5000);
      digitalWrite(RED, LOW);
      lcd.clear();
    }
    
  }
}


void Enroll() {

  int enrollId = 0;
  bool usedid = true;

  while (usedid == true) {
    usedid = fps.CheckEnrolled(enrollId);
    if (usedid == true) enrollId++;
  }
  fps.EnrollStart(enrollId);

  lcd.print("Place finger on");
  lcd.setCursor(0, 1);
  lcd.print("on scanner");
  while (fps.IsPressFinger() == false) delay(500);
  bool bret = fps.CaptureFinger(true);
  int iret = 0;

  if (bret != false) {
    lcd.clear();
    lcd.print("Remove Finger");
    fps.Enroll1();
    delay(1000);
    lcd.clear();

    while (fps.IsPressFinger() == true) delay(500);
    lcd.print("Reapply Finger");
    while (fps.IsPressFinger() == false) delay(500);
    bret = fps.CaptureFinger(true);

    if (bret != false) {
      lcd.clear();
      lcd.print("Remove Finger");
      fps.Enroll2();
      delay(1000);
      lcd.clear();

      while (fps.IsPressFinger() == true) delay(500);
      lcd.print("Reapply Finger");
      while (fps.IsPressFinger() == false) delay(500);
      bret = fps.CaptureFinger(true);

      if (bret != false) {
        lcd.print("Remove Finger");
        iret = fps.Enroll3();
        delay(1000);
        lcd.clear();
        if (iret == 0) {
          lcd.print("Finger has been");
          lcd.setCursor(0, 1);
          lcd.print("Added");
          delay(1000);
          lcd.clear();
        } else {
          lcd.print("Enroll failed");
          lcd.setCursor(0, 1);
          lcd.print("Error code: iret");
          
        }
      } else {
        lcd.print("Failed to");
        lcd.setCursor(0, 1);
        lcd.print("capture print");
      }

    } else {
      lcd.print("Failed to");
      lcd.setCursor(0, 1);
      lcd.print("capture print");
    }
  } else {
    lcd.print("Failed to");
    lcd.setCursor(0, 1);
    lcd.print("capture print");
  }
}

Can you post a schematic please

I do not have a schematic for this circuit. Where could I make one if that will make the question easier?

Pencil and paper showing all connections would be fine. :wink:

Hi Joey

I'd suggest you rewrite your code as a state machine. Why? because your description of the process you want clearly has different states.

There is an example here

How would I use those case statements in this scenario? I sorta understand what you are doing with LEDs. I am mostly confused on how the cases are changing. What effect is happening to move to the next case or does it all just run through?

I cannot get you a good enough schematic I am sorry. I can explain it as best as I can on what you need to see or send a photo of the circuit itself. I warn you it is a giant mess or wires at the moment.

Could that be why your push button is acting up? :wink:

No the push button is working properly. What happens is the code just bypasses the if statement and goes straight into the enroll function.

How did you test/verify this? If the wiring is incorrect you can have random values on the pin.

I tested with a test software where I would just turn on an LED with it

That depends on how you define the states. Can you define the states of your program and give each a number - eg
state 0 - waiting for fingerprint

and the actions that bring about a change from one state to another?

Then draw the state transition diagram.

As others have said, without seeing your schematic it's difficult but I'll make the assumption that your push button is a normally open button that switches 5v to pin 48 when pressed.

You have defined pin 48 as INPUT (fine) and you are testing for a HIGH condition (also fine) but you shouldn't assume that pin 48 will be low when the button is not pressed. A normally open button on an input will actually be floating unless you pull it one way or the other, so it could be literally anywhere. This is especially true if adjacent pins are in use.

So, if my assumption is correct, you have 2 options.

  1. Add a pull down resistor (10k will be fine) between pin 48 and ground to 'force' the input low unless the button is pressed.

  2. Change the way the button is wired and switch to ground instead of 5v, then change the definition to INPUT_PULLUP, then test for input LOW instead of HIGH in your 'if' statement. (Arduino's have built in pull up resistors but not built in pull down resistors.)

Just a general comment ... switching to ground is kind of an industry standard as it prevents unexpected or accidental high voltages being applied to a pin and damaging the processor.

Hope this helps,

Gareth

So I kind of took your advice. I assumed that the button would be low and that is where the problem was. I coded the button to be LOW and tried it again. The function sort of works now, but the button has to be already being pressed before the scan. Any tips on how I could reverse that and make it so when the good print is scanned the user can then hit the button to add the print. I also appreciate all of the help this forum has given me. I am working with the switch cases as well to see if that can change anything.

I think because you are only checking the input status once, followed by a 5 second delay.

in place of ...

digitalWrite(GREEN, HIGH);
if(digitalRead(buttonAdd) == HIGH){
  Enroll();
}
delay(5000);
digitalWrite(GREEN, LOW);

try something like ...

digitalWrite(GREEN, HIGH);
scantime = millis();
while ((millis()-scantime) < 5000)
{
 if (digitalRead(buttonAdd) == HIGH) Enroll();
}
digitalWrite(GREEN, LOW);

This will give the user 5 seconds to press the button before timing out. (scantime should be declared as long)

There are other ways of doing it but this should point you in the right direction :slight_smile:

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