Arduino UNO for a Fingerprint-based attendance system with GPS location

Hi
I am working on a project with Arduino UNO for a Fingerprint-based attendance system with GPS location. I have used, R307 optical fingerprint scanner + Ublox Neo 6M GPS module + 128x64 OLED display connected to Arduino UNO
Following are the pin connections on my Arduino UNO
R307 optical fingerprint scanner UART connected to SoftwareSerial mySerial(3, 2)
Ublox Neo 6M GPS module UART connected to AltSoftSerial gpsSerial(8, 9)
128x64 OLED display connected to A4,A5 I2C pins

When I flash the attached code to Arduino, the display does not come up and everything is like stuck
But if I disable/comment the GPS section of the code then the display and fingerprint sensor works fine. Especially if I comment "TinyGPSPlus GPS" line then everything works.
Please suggest what is the problem? what is wrong with my code attached here? can I use 2 UART interface and an i2c interface all at once on Arduino UNO? is that causing the problem?

Thanks
Santosh

Finger_with_GPS_and_OLED_v2.ino (5.94 KB)

Check what resources those 3 devices need, interrupts, timers.... I think You will find the answer there.

I think you just proved to yourself that you can only use ONE software type serial at a time.

Paul

Maybe using a Mega having 3 serial channels would be better?

I thought of this but....when I tried only the Fingerprint sensor and GPS module code(commenting the OLED section) it works fine.
R307 optical fingerprint scanner UART connected to SoftwareSerial mySerial(3, 2)
Ublox Neo 6M GPS module UART connected to AltSoftSerial gpsSerial(8, 9)
with these two software UARTS simultaneously I and hardware serial(0,1) for debug/com port it works fine

Attached here that code and com port output
Adafruit finger detect test
Found fingerprint sensor!
Reading sensor parameters
Status: 0x0
Sys ID: 0x0
Capacity: 1000
Security level: 3
Device address: FFFFFFFF
Packet len: 128
Baud rate: 57600
Waiting for valid finger...
Sensor contains 2 templates

Place finger
Found a match with ID No:1
Lat,Lng: Not Available
Date: 00/00/2000
Time: 05:30:00

Place finger

Finger_with_GPS_v3_final.ino (6.08 KB)

santoshgurral:
But if I disable/comment the GPS section of the code then the display and fingerprint sensor works fine. Especially if I comment "TinyGPSPlus GPS" line then everything works.

Does the reading of the GPS really work then? What does the compiler say at GPS.encode?

Mixing softwareserial and heaps of Serial.print() stuff to the serial monitor can cause the softwareserial (running in the background) to miss the odd character from the GPS, maybe the fingerprint sensor too. Miss the odd character and you might never get a GPS position.

You may be able to workaround the problems eventually, and NeoSWserial is a lot better behaved in this respect, but using two software serials at the same time is not the best of ideas, especially as one of the instances runs at 57600 baud, close to the performance limit.

If you want the project to be reliable running the GPS and fingerprint sensors on an Arduino that has enough hardware serial ports is the way to go.

Like reply #3 or other controllers?

date, time, year, lat, lng, not showing here bcz i was indoor while testing this...if i go outdoor under clear sky GPS updates properly..i have verified that

Maybe I misunderstand things but Your project is fully working now?
Get a proper antenna to the GPS and it will work indoors too.

santoshgurral:
if i go outdoor under clear sky GPS updates properly..i have verified that

Thats normal.

If this 'attendance' system if for indoor use, then you need to appreciate that depending on the 'indoors' the GPS might not get a location fix at all, might take tens of minutes to get a fix or the location may be 10s of metres out.

I have changed my Arduino UNO to Arduino Mega board now and the pinouts are as below

Fingerprint sensor connected to Serial1 (18, 19)pins of Arduino Mega
Ublox 6m GPS module connected to Serial3 (14, 15)pins of Arduino Mega
and 128x64 OLED is connected to I2C pins (20, 21) of Arduino Mega

With this board change now all three modules Fingerprint sensor, GPS module, and OLED work fine without getting hanging...I think as you pointed it was about having separate hardware serial interfaces for each.
But now the problem I am seeing is that GPS module output is not reliable. GPS coordinates, date, and time are not getting updated consistently. sometimes its does, and sometimes it does not.
What could be the issue? I am guessing is it something related to the timing issue or baud rate settings for GPS and optical sensor may be causing the problem? or the delays I have in my code may be causing the problem? how do I adjust these? please suggest

my latest code attached here

#include <Adafruit_Fingerprint.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SPI.h>
#include <Wire.h>
#include <TinyGPS++.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET 4

int BUZZER = 7;
int ISThour = 0;
int ISTmin = 0;
int GMTmin = 0;
float latitude = 0;
float longitude = 0;

TinyGPSPlus gps;

Adafruit_Fingerprint finger = Adafruit_Fingerprint(&Serial1);
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup()
{
Serial3.begin(9600);
Serial1.begin(57600);
pinMode(BUZZER, OUTPUT);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //Address 0x3C for 128x64
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(("Booting..."));
display.display();
delay(1500);
display.clearDisplay();

if (finger.verifyPassword())
{
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(25, 0);
display.println(("Sensors"));
display.setCursor(5, 20);
display.println("Connected");
display.display();
delay(1000);
display.clearDisplay();
}

else
{
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(25, 0);
display.println(("Sensors"));
display.setCursor(5, 20);
display.println("Not Found");
display.display();
delay(2000);
while (1)
{
delay(1);
}
}
display.clearDisplay();
}

void loop()
{
getFingerprintIDez();
delay(1500);
}

void displayInfo()
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(("Date:"));
display.setCursor(33, 0);
display.println((gps.date.day()));
display.setCursor(47, 0);
display.println(("/"));
display.setCursor(57, 0);
display.println((gps.date.month()));
display.setCursor(67, 0);
display.println(("/"));
display.setCursor(77, 0);
display.println((gps.date.year()));

display.setCursor(0, 20);
display.println(("Time:"));
GMTmin = gps.time.minute();
ISThour = gps.time.hour() + 5;
if (GMTmin >= 30) ISThour = ISThour + 1;
if (ISThour > 24) ISThour = gps.time.hour() - 24;
ISTmin = gps.time.minute() + 30;
if (ISTmin >= 60) ISTmin = ISTmin - 60;
display.setCursor(35, 20);
display.println(ISThour);
display.setCursor(47, 20);
display.println(":");
display.setCursor(53, 20);
display.println(ISTmin);
display.setCursor(65, 20);
display.println(":");
display.setCursor(71, 20);
display.println((gps.time.second()));

latitude = gps.location.lat();
longitude = gps.location.lng();
display.setCursor(0, 35);
display.println(("Lat: "));
display.setCursor(30, 35);
display.println(latitude, 6);
display.setCursor(0, 45);
display.println(("Lng: "));
display.setCursor(30, 45);
display.println(longitude, 6);
display.display();
delay(2000);
display.clearDisplay();

/else
{
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(20, 0);
display.println(("GPS Not"));
display.setCursor(10, 20);
display.println(("Available"));
display.display();
delay(1000);
display.clearDisplay();
}
/
}

// returns -1 if failed, otherwise returns ID #
int getFingerprintIDez()
{
uint8_t p = finger.getImage();
if (p != FINGERPRINT_OK)
{
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(35, 0);
display.println(("PLACE"));
display.setCursor(30, 20);
display.println(("FINGER"));
display.display();
return -1;
}

p = finger.image2Tz();
if (p != FINGERPRINT_OK)
{
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(("Messy Image"));
display.setCursor(0, 20);
display.println("Try Again");
display.display();
delay(2000);
display.clearDisplay();
return -1;
}

p = finger.fingerFastSearch();
if (p != FINGERPRINT_OK) {

display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(20, 0);
display.println(("Invalid"));
display.setCursor(30, 20);
display.println("Finger");
display.display();
digitalWrite(BUZZER, HIGH);
delay(200);
digitalWrite(BUZZER, LOW);
delay(200);
digitalWrite(BUZZER, HIGH);
delay(200);
digitalWrite(BUZZER, LOW);
delay(200);
digitalWrite(BUZZER, HIGH);
delay(200);
digitalWrite(BUZZER, LOW);
delay(800);
display.clearDisplay();
return -1;
}

// found a match!
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(35, 0);
display.println(("Match"));
display.setCursor(2, 20);
display.println(("Found with"));
display.setCursor(15, 40);
display.println("ID No:");
display.setCursor(90, 40);
display.println((finger.fingerID));
display.display();
digitalWrite(BUZZER, HIGH);
delay(500);
digitalWrite(BUZZER, LOW);
delay(2000);

while (Serial3.available() > 0)
if (gps.encode(Serial3.read()))
delay(1000);
displayInfo();

return finger.fingerID;
}

thanks
santosh

Two comments:

  1. You posted code without code tags, as indicated in the forum guidelines
  2. Your comments suggest that you didn't read the post that immediately preceded it.

No surprise that You loose data. You just can' t hang up the execution in delays " here and there", for seconds.
Even in loop You use delay. Brrr...

This bit of code is not at all good, assuming a default Neo6 setup;

while (Serial3.available() > 0)
  if (gps.encode(Serial3.read()))
  delay(1000);
  displayInfo();

Depending on how long the display takes to update, you can get in a situation where you never get to decode a fix, and the delay(1000); makes the problem worse, maybe.

Only about one in four of the sentences decoded will have updated fix information, so there not a lot of point in displaying the updated information, since there wont be anything to update. Then after all the delays and updating when you eventually get back to reading the GPS again, the sentences containing the updated position data etc, might have gone past.