brianrho / FPM

Arduino library for the R30x/ZFMxx/FPMxx optical fingerprint sensors
105 stars 41 forks source link

Occasionally triggers when nobody touched sensor #6

Closed swilson86 closed 6 years ago

swilson86 commented 6 years ago

I am using a DY50 3.3V sensor from eBay. The FPM software works very well, but occasionally triggers when nobody touched the sensor. It happens randomly thus does not seem to be when sun, sundown, sunrise, or any specific atmospheric event occurs.

Is it a bug somewhere in FPM or the sensor itself?

brianrho commented 6 years ago

Could you describe what you mean by "triggers"? Also post the relevant part of your application code

swilson86 commented 6 years ago

By "triggers" I mean the fingerprint sensor would frequently act as though someone had placed their finger on the glass... even though nobody did. Your code was giving me a "no match".

I found the problem! Power supply was only rated for 800ma. The fingerprint sensor takes about 140ma and I have an Arduino and ESP-8266 chip on the same power supply. Upped it to a 1.6A power supply and now no false triggers.

Good thing about this is that your software works perfectly with the DY50 fingerprint sensor. Also if anyone reports this error we now know it is likely insufficient power.

Thanks for the excellent software! Well done.

swilson86 commented 6 years ago

Sorry. It worked ok after upgrading power supply and no error for several hours. Now it is doing it again. I am running some debug code to narrow down the problem. Here is the section of code so far:

int getFingerprintID() {
  int p = -1;
  Serial.println("Scanning...");
  while (p != FINGERPRINT_OK){
    p = finger.getImage();
    switch (p) {
      case FINGERPRINT_OK:
        #ifdef USETIME
          PrintTime();
        #endif
        Serial.println("441 Image taken");
        break;

Without a finger on the sensor it gets to that line containing a 441. I will continue by having a look at getImage to see why it returns FINGERPRINT_OK.

brianrho commented 6 years ago

Could you post the entire getFingerprintID() function, as well as the definition of PrintTime()? Pls try to format the code properly with the '<>' button. How often do you call getFingerprintID() and what's the current baud rate? I'd also like the product link and a sketch of how you connected the module to your MCU

swilson86 commented 6 years ago
int getFingerprintID() {
  int p = -1;
  Serial.println("Scanning...");
  while (p != FINGERPRINT_OK){
    p = finger.getImage();
    switch (p) {
      case FINGERPRINT_OK:
        #ifdef USETIME
          PrintTime();
        #endif
        Serial.println("441 Image taken");
        break;
      case FINGERPRINT_NOFINGER:
        //Serial.print(".");
        break;
      case FINGERPRINT_PACKETRECIEVEERR:
        Serial.println("Comm error");
        break;
      case FINGERPRINT_IMAGEFAIL:
        Serial.println("Imaging error");
        break;
      default:
        Serial.print("Unknown error: ");
        Serial.println(p);
        break;
    }
    yield();
  }

  // OK success!

  p = finger.image2Tz();
  switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image converted");
      break;
    case FINGERPRINT_IMAGEMESS:
      Serial.println("Image too messy");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Comm error");
      return p;
    case FINGERPRINT_FEATUREFAIL:
      Serial.println("No fingerprint features");
      return p;
    case FINGERPRINT_INVALIDIMAGE:
      Serial.println("No fingerprint features");
      return p;
    default:
      Serial.println("Unknown error");
      return p;
  }

  Serial.println("Remove finger...");
  while (p != FINGERPRINT_NOFINGER){
    p = finger.getImage();
    yield();
  }
  Serial.println();
  // OK converted!
  p = finger.fingerFastSearch();
  if (p == FINGERPRINT_OK) {
    Serial.println("Prints matched!");
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    Serial.println("Comm error");
    return p;
  } else if (p == FINGERPRINT_NOTFOUND) {
    Serial.println("No match");
    #ifdef USETIME
      PrintTime();
    #endif
    // Send MQTT with 999 (no match number)
    mqtt.publish(pubPrintMatch,"999",3,0,0);
    return p;
  } else {
    Serial.println("Unknown error");
    return p;
  }   

  // found a match!
  Serial.print("Found ID #"); Serial.print(finger.fingerID); 
  Serial.print(" confidence "); Serial.println(finger.confidence);
  #ifdef USETIME
    PrintTime();
  #endif
  // Send MQTT with match number
  char buf[8] = "";
  mqtt.publish(pubPrintMatch,itoa(finger.fingerID,buf,10),7,0,0); 
}`

`#ifdef USETIME
  void PrintTime() {
    time_t t = cmd.GetTime(); // store the current time in time variable t
    Serial.print("Time: ");
    if (hour(t) < 10)
      Serial.print("0"); 
    Serial.print(hour(t));
    Serial.print(":");
    if (minute(t) < 10)
      Serial.print("0");
    Serial.print(minute(t));
    Serial.print(":");
    if (second(t) < 10)
      Serial.print("0");
    Serial.print(second(t));
    Serial.print(" ");
    if (month(t) < 10)
      Serial.print("0");
    Serial.print(month(t));
    Serial.print("/");
    if (day(t) < 10)
      Serial.print("0");
    Serial.print(day(t));
    Serial.print("/");
    Serial.println(year(t));  
  }
#endif
swilson86 commented 6 years ago

Baud rate is 57,600

I am using software serial connected to Arduino pins 10 and11. Power is 3.3V DC @1.6A from a pair of AM1117 chips thus very stable. Running an Arduino Pro Mini jumpered to 3.3V

PrintTime() was added as a debug so I could see if there was a pattern in the false triggering. It seems to be random. Makes no difference whether I am using PrintTime or not, so it can be ruled out.

Arduino: Sketch uses 13594 bytes (44%) of program storage space. Maximum is 30720 bytes. Global variables use 1326 bytes (64%) of dynamic memory, leaving 722 bytes for local variables. Maximum is 2048 bytes.

Product link: https://www.ebay.com/itm/Optical-Fingerprint-reader-Sensor-Module-sensors-All-in-one-For-Arduino-Lock/401156605672?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2057872.m2749.l2649

I am calling getFingerprintID() in the main loop of the Arduino sketch. There is very little other overhead in the loop, thus it is getting called a few milliseconds after it just ran.

brianrho commented 6 years ago

In my experience, these fingerprint modules are intended to be powered by 5V not 3.3V. I've never used them with 3.3V before and I suspect that's the cause of the unreliability here. The datasheet weirdly gives Vcc range as 3.6 - 6 V / 3.3 V direct supply, what that means I'm not sure. I noticed your module has a pad labelled 3V3 on the PCB, which I think means it can be powered by applying 3.3V to that pad directly. However between the Vcc pin on your 6-pin header and that 3V3 pad, I suspect there's an LDO. So to be sure, I'd like you to test a few things:

swilson86 commented 6 years ago

I am running the 1117's in parallel to give me 800ma x 2. Externally a wall wart provides 5V DC @2A to provide power to the 1117 pair.

I have not altered the security settings. The 3V3 pad is connected directly to the Vcc header pin according to my Ohmmeter. The only LDO's on the entire board reside inside the AS608 fingerprint chip. The spec sheet from the manufacturer (synochip.com) of the AS608 says the chip is 4.0V to 5.4V BUT they imply it can run on 3.3V supply if connected to pin 29. Sure enough... the DY50 has it's pad marked 3.3V connected to pin 29 and thus also from the Vcc header pin! For sure the DY50 is intended to be run at 3.3V

I originally connected another DY50 sensor on a completely different 5V Arduino Nano and ran everything including the DY50 at 5V. The circuit board of the DY50 unit got fairly warm (as opposed to completely cool on 3.3V). The unit burned up in a few hours and software always said "Did not find fingerprint sensor :("

Side note: There is a 2238 capacitive touch ic inside the DY50 which knows when a finger is on the sensor. It's the same one that most eBay people are selling as an Arduino touch sensor which operates from 2.2 to 5.5V.

I just ordered a 3rd DY50 from eBay and a better power supply that provides up to 3A at 3.3VDC. I will eliminate all the variables by completely building a new system and will check again. This probably will take a couple of months :(

swilson86 commented 6 years ago

Interesting development... The 5th wire on the DY50 is connected directly to the signal output of the 2238 internal touch sensor chip. It should toggle high (or low) when a finger touches the sensor. I will check that out tomorrow.

brianrho commented 6 years ago

Ah, there goes that theory. Why are you ordering more DY50s though? If its possible that the module isnt entirely compatible with my code, then you should try ordering the R305 or FPM10. I assume you have the latest version of FPM too.

Also what MQTT library are you using? Pubsubclient? Adafruit's? Just noticed some of your calls look strange. Namely, what are the other arguments you passed to publish()? I imagine '7' is the length, and '0' is the retained or qos parameter, but what's the last '0' for? I've seen a fingerprint module behave unreliably before while based on code that contained buffer overruns etc. So one test it would be sensible to run is, to use only the example code from the library and see if the false triggering occurs, this way I can narrow the problem down to just my software.

swilson86 commented 6 years ago

Thanks. I have just ordered an FPM10A by express. Should be here in a couple of weeks.

I am using JeeLabs excellent esp-link software running on an ESP-01s, and Mosquitto running on Raspberry Pi 3. The DY50 is my new doorbell which publishes a message. Subscribing stations around the house then announce who is at my front door. Except at 3am... the false triggers keep me up all night :) The MQTT is JeeLabs version. The 0's are my latest attempt to terminate strings to make sure they are not character arrays. Another battle I am fighting with to avoid buffer overruns. Interesting you mention that.

brianrho commented 6 years ago

That means you're using the ELClient library. Could you post your entire sketch here, so I can see if there's any chance of overruns already occurring? Also to be clear, you're not using an old version of FPM, right?

swilson86 commented 6 years ago

Fingerprint_V6.zip

swilson86 commented 6 years ago

I am using the current version of FPM

brianrho commented 6 years ago

I've looked through the code and while there are a few things to be corrected, nothing jumps out at me as a possible cause for the module's behaviour. The most I can suggest now is that you run the fingerprint example for a while and see if that too has this problem, so we can narrow down the cause.

swilson86 commented 6 years ago

Good idea! Thanks for looking at the code. I will narrow things down further (and faster) by trying the DY50 on a very simple non esp-link connection and just your examples with absolutely zero changes to your code. That will isolate any problems with your code.

Meanwhile the new FPM10A sensor should arrive by express and I will try it. As far as I know the FPM10A and others are 5V devices which means additional power supplies and level shifting to use the ESP-01s.

In any case I will have answers in a couple of weeks. Thanks for your outstanding patience and support!