fingerprint_fps_GT511C3

Yes, here it is: LINK

Here is the datasheet:

SYSTEM_THREAD(ENABLED) wasn't meant to cure the blocking of the library and the D7 blinking does not get affected by the library blocking since it runs in a seperate thread.
The D7 blink test was meant to illustrate that in fact your code got flashed even when you assumed it didn't due to the missing publish event.

SYSTEM_THREAD(ENABLED) was meant to cure this

with it your code will still stall, but you should still be able to flash OTA.

So are you using the GT-511C1R or the GT511C3?

My fingerprint scanner is the “economy version”: GT-511C1R
It worked about 2 years with the library you ported…

Thanks for looking into it!

:sleeping:

For a strange reason, my Photon could not be reflashed in case a sketch with any of the three FPS libraries was running. I had to bring it first into safe mode before it accepted to be flashed again.
:bow:

@FiDel, can you give more details on how you have things hooked up. If it worked for two years then stopped working, what changed needs to be identified.

  1. Did you change any hardware connections?
  2. Did you change the power source for your project?
  3. How is the scanner powered?
  4. Did you change any of the code?
  5. Which version of firmware are you targeting?

Can you post a picture of your setup?

Indeed, it always helps to spend some time to check the basics:

Did you change any hardware connections?
No.

Did you change the power source for your project?
No.

How is the scanner powered?
Directly from my home’s 5V DC power line.

Did you change any of the code?
No. Actually, I test with just the FPS_Blink.ino example.
Even that sketch does not work anymore with the on-line libraries, but it does with your old (off-line) library.

Which version of firmware are you targeting?
System firmware target: : 0.6.3
On the device: 0.6.3


Confusing things happened in the previous days when suddenly also your “old” library stopped working… That was weird!
Today, I tried my FPS module again with the Windows demo program and my FPS module came back to life. I was glad to see it’s blue light working. :sweat:
When I then tried my FPS module again with your (old) library and with Particle Dev, all my previous sketches worked again!!!

I suppose the frequent trouble with the on-line libraries had confused my FPS module… :imp:
When I try any sketch in the Web IDE, nothing works and the RGB LED consistently turns green every time again after about 10-15"…

I can still continue to use my FPS and update my sketches off-line, but probably others who try with the available on-line libraries can’t anymore…

It would be nice if you could make your library available again in the Web IDE.
Thanks on beforehand!

I wish i would have known there was a lib out there before I wrote my own :wink:

Congratulations @seulater if you wrote the necessary library yourself!
Q:
Which FPS scanner are you using?
Can you share your library and sketch with the community?

:older_man:

I used the GT-511C3.
I cannot share the sketch because its tied into allot of other source files, which I am not willing to share at this time.

Since this forum does not allot you to upload files other than images I tried putting it here but the forum only allows 32k.
So i’ll have to do it in 2 steps.

GT-511C3.cpp

#include "application.h"
#include "headers.h"
#include "MI0283QT-9A.h"
#include "sx8654.h"
#include "SST25VF016B.h"
#include "SX1509.h"
#include "GT-511C3.h"

int fds=0;
SB_OEM_PKT* Command_Packet;
uint16_t total_downloaded;
//uint8_t FingerImg[240*320/4];
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int CheckPacket(uint8_t *ucData, uint8_t rtn)
{

	uint8_t x;


	if(rtn == SB_OEM_PKT_SIZE)
	{
		Serial.println("OK Packet");

		if(Command_Packet->wCmd0 == ACK)
		{
			Serial.println("OK ACK");

			if(CheckChkSumOfRpsAckPkt(Command_Packet) == OK)
			{
				Serial.println("OK Packet");
			}
			else
			{
				Serial.println("Bad Packet");
			}

		}
		else
		{
			Serial.println("Bad ACK");
		}

	}

}




//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int GT_511C3_Init( void )
{
	int rt;


	Command_Packet =(SB_OEM_PKT*) malloc(sizeof(SB_OEM_PKT));

//	Serial1.begin(9600);   // open serial over USB
	GT_511C3_PurgeRX();

	rt = GT_511C3_Terminate();

	sprintf(lcdstring,"Terminate=%d",rt);
	Serial.println(lcdstring);

	rt = GT_511C3_ChangeBaudRate(115200);

	sprintf(lcdstring,"Change Baud=%d",rt);
	Serial.println(lcdstring);

	Serial1.begin(115200);   // open serial over USB
//	Serial1.write("\r");
//	Serial1.write("\n");

	GT_511C3_PurgeRX();

	rt = GT_511C3_Open(115200);

	sprintf(lcdstring,"Init GT_511C3=%d",rt);
	Serial.println(lcdstring);

	return rt;
}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int GT_511C3_Terminate(void)
{

	/*********Open Command***********/
	Command_Packet->Head1 = COMMAND_START_CODE1;
	Command_Packet->Head2 = COMMAND_START_CODE2;
	Command_Packet->wDevId0 = DEVICE_ID;
	Command_Packet->wDevId1 = DEVICE_ID>>8;
	Command_Packet->nParam0 = ZERO;
	Command_Packet->nParam1 = ZERO;
	Command_Packet->nParam2 = ZERO;
	Command_Packet->nParam3 = ZERO;
	Command_Packet->wCmd0 = CLOSE;
	Command_Packet->wCmd1 = ZERO;
	uint16_t tmp = CalcChkSumOfCmdAckPkt(Command_Packet);
	Command_Packet->wChkSum0 = tmp % 256;
	Command_Packet->wChkSum1 = tmp >> 8;
	/*********Open Command***********/

	GT_511C3_SendCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	int rtn = GT_511C3_ReceiveCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

//	CheckPacket((uint8_t *)Command_Packet, rtn);

	if( (rtn == SB_OEM_PKT_SIZE) && (Command_Packet->wCmd0 == ACK) && (CheckChkSumOfRpsAckPkt(Command_Packet) == OK) )
	{
		return OK;
	}


	return FAIL;
}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
void GT_511C3_SendCommand(uint8_t *ucData, uint8_t length)
{
	uint8_t x;
	uint8_t *uc;

	if(0)
	{
		uc = ucData;

		Serial.print("Sending Packet:");
		for(x=0;x<length;x++)
		{
			Serial.print(*uc);
			Serial.print(",");
			uc++;
		}

		Serial.println("");

	}


	// If we are sending something, then we will be receiving something So make sure
	// the rx is clean before we start. Just to be safe.
	GT_511C3_PurgeRX();

	for(x=0;x<length;x++)
	{
		Serial1.write(*ucData);
		ucData++;
	}

//	Serial1.write(0);
}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int GT_511C3_ReceiveCommand(uint8_t *ucData, uint16_t length)
{
	uint8_t total=0;
	uint8_t x;
	uint8_t *uc;
	uint32_t t=0;
	uc = ucData;

	do
	{

		while(Serial1.available())
		{
			*ucData = Serial1.read();
			ucData++;
			total++;
		}

	}while( (total < length) && (++t < 2000000) );


	if(0)
	{
		Serial.print("Received Packet:");
		for(x=0;x<length;x++)
		{
			Serial.print(*uc);
			Serial.print(",");
			uc++;
		}

		Serial.println("");

	}



	return total;
}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
void GT_511C3_PurgeRX(void)
{
	while(Serial1.available())
    {
        Serial1.read();
    }
}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int CalcChkSumOfCmdAckPkt( SB_OEM_PKT* pPkt )
{
	uint16_t wChkSum = 0;
	uint8_t * pBuf = (uint8_t*)pPkt;
	uint16_t i;

	for(i=0;i<(sizeof(SB_OEM_PKT) - SB_OEM_CHK_SUM_SIZE);i++)
	{
		wChkSum += pBuf[i];
	}

	return wChkSum;
}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int CheckChkSumOfRpsAckPkt( SB_OEM_PKT* pPkt )
{
	unsigned short wChkSum = 0;
	uint8_t * pBuf = (uint8_t*)pPkt;
	uint16_t i;

	if(pPkt->Head1 != RESPONSE_START_CODE1 || pPkt->Head2 != RESPONSE_START_CODE2)
	{
		return PKT_HDR_ERR;
	}

	if(pPkt->wDevId0 != DEVICE_ID || pPkt->wDevId1 != ZERO)
	{
		return PKT_DEV_ID_ERR;
	}


	for(i=0;i<(sizeof(SB_OEM_PKT) - SB_OEM_CHK_SUM_SIZE);i++)
		wChkSum += pBuf[i];

	if(pPkt->wChkSum0 != (wChkSum & 0xFF) || pPkt->wChkSum1 != (wChkSum & 0xFF00)>>8)
	{
		return PKT_CHK_SUM_ERR;
	}


	return OK;
}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int CalcChkSumOfDataPkt( unsigned char* pDataPkt, int nSize )
{
	int i;
	unsigned short wChkSum = 0;
	unsigned char* pBuf = (unsigned char*)pDataPkt;

	if(*pBuf != DATA_START_CODE1 || *(pBuf + 1) != DATA_START_CODE2)
		return PKT_HDR_ERR;

	if(*(pBuf + 2) != DEVICE_ID || *(pBuf + 3) != ZERO)
		return PKT_DEV_ID_ERR;

	for(i=0;i< nSize - SB_OEM_CHK_SUM_SIZE;i++)
		wChkSum += pBuf[i];

	if(*(pBuf + nSize - SB_OEM_CHK_SUM_SIZE) != (wChkSum & 0xFF) || *(pBuf + nSize - SB_OEM_CHK_SUM_SIZE + 1) != (wChkSum & 0xFF00)>>8)
		return PKT_CHK_SUM_ERR;
	return OK;
}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int GT_511C3_Open(unsigned long BAUDRATE)
{

	/*********Open Command***********/
	Command_Packet->Head1 = COMMAND_START_CODE1;
	Command_Packet->Head2 = COMMAND_START_CODE2;
	Command_Packet->wDevId0 = DEVICE_ID;
	Command_Packet->wDevId1 = DEVICE_ID>>8;
	Command_Packet->nParam0 = ZERO;
	Command_Packet->nParam1 = ZERO;
	Command_Packet->nParam2 = ZERO;
	Command_Packet->nParam3 = ZERO;
	Command_Packet->wCmd0 = OPEN;
	Command_Packet->wCmd1 = ZERO;
	uint16_t tmp = CalcChkSumOfCmdAckPkt(Command_Packet);
	Command_Packet->wChkSum0 = tmp % 256;
	Command_Packet->wChkSum1 = tmp >> 8;
	/*********Open Command***********/

	GT_511C3_SendCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	int rtn = GT_511C3_ReceiveCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

//	CheckPacket((uint8_t *)Command_Packet, rtn);

	if( (rtn == SB_OEM_PKT_SIZE) && (Command_Packet->wCmd0 == ACK) && (CheckChkSumOfRpsAckPkt(Command_Packet) == OK) )
	{
		return OK;
	}


	return FAIL;
}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int GT_511C3_ChangeBaudRate(unsigned long BAUDRATE)
{

	/*********Change Baudrate Command***********/
	Command_Packet->Head1 = COMMAND_START_CODE1;
	Command_Packet->Head2 = COMMAND_START_CODE2;
	Command_Packet->wDevId0 = DEVICE_ID;
	Command_Packet->wDevId1 = DEVICE_ID>>8;
	Command_Packet->nParam0 = BAUDRATE & 0xFF;
	Command_Packet->nParam1 = (BAUDRATE & 0xFF00) >> 8 ;
	Command_Packet->nParam2 = (BAUDRATE & 0xFF0000) >> 16;
	Command_Packet->nParam3 = (BAUDRATE & 0xFF000000) >> 24;
	Command_Packet->wCmd0 = CHANGBAUDRATE;
	Command_Packet->wCmd1 = ZERO;
	uint16_t tmp = CalcChkSumOfCmdAckPkt(Command_Packet);
	Command_Packet->wChkSum0 = tmp % 256;
	Command_Packet->wChkSum1 = tmp >> 8;
	/*********Change Baudrate Command***********/

	GT_511C3_SendCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	int rtn = GT_511C3_ReceiveCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);


//	CheckPacket((uint8_t *)Command_Packet, rtn);


	if( (rtn == SB_OEM_PKT_SIZE) && (Command_Packet->wCmd0 == ACK) && (CheckChkSumOfRpsAckPkt(Command_Packet) == OK) )
	{
		return OK;
	}


	return FAIL;

}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int GT_511C3_LED(boolean State)
{

	/*********Change Baudrate Command***********/
	Command_Packet->Head1 = COMMAND_START_CODE1;
	Command_Packet->Head2 = COMMAND_START_CODE2;
	Command_Packet->wDevId0 = DEVICE_ID;
	Command_Packet->wDevId1 = DEVICE_ID>>8;
	Command_Packet->nParam0 = State & 0xFF;
	Command_Packet->nParam1 = 0x00;		//(State & 0xFF00) >> 8 ;
	Command_Packet->nParam2 = 0x00;		//(State & 0xFF0000) >> 16;
	Command_Packet->nParam3 = 0x00;		//(State & 0xFF000000) >> 24;
	Command_Packet->wCmd0 = CMOSLED;
	Command_Packet->wCmd1 = ZERO;
	uint16_t tmp = CalcChkSumOfCmdAckPkt(Command_Packet);
	Command_Packet->wChkSum0 = tmp % 256;
	Command_Packet->wChkSum1 = tmp >> 8;
	/*********Change Baudrate Command***********/


	GT_511C3_SendCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);


	int rtn = GT_511C3_ReceiveCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	if( (rtn == SB_OEM_PKT_SIZE) && (Command_Packet->wCmd0 == ACK) && (CheckChkSumOfRpsAckPkt(Command_Packet) == OK) )
	{
		return OK;
	}


//	iprintf("Led Fail\r\n");
	return FAIL;
}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int GT_511C3_IsFingerPressed(void)
{

	/*********Change Baudrate Command***********/
	Command_Packet->Head1 = COMMAND_START_CODE1;
	Command_Packet->Head2 = COMMAND_START_CODE2;
	Command_Packet->wDevId0 = DEVICE_ID;
	Command_Packet->wDevId1 = DEVICE_ID>>8;
	Command_Packet->nParam0 = ZERO;
	Command_Packet->nParam1 = ZERO;
	Command_Packet->nParam2 = ZERO;
	Command_Packet->nParam3 = ZERO;
	Command_Packet->wCmd0 = ISPRESSFINGER;
	Command_Packet->wCmd1 = ZERO;
	uint16_t tmp = CalcChkSumOfCmdAckPkt(Command_Packet);
	Command_Packet->wChkSum0 = tmp % 256;
	Command_Packet->wChkSum1 = tmp >> 8;
	/*********Change Baudrate Command***********/

	GT_511C3_SendCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	int rtn = GT_511C3_ReceiveCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	if( (rtn == SB_OEM_PKT_SIZE) && (Command_Packet->wCmd0 == ACK) && (CheckChkSumOfRpsAckPkt(Command_Packet) == OK) )
	{
		if(Command_Packet->nParam0 == 0)
		{
			return FINGER_PRESSED;
		}
		else
		{
			return FINGER_NOT_PRESSED;
		}
	}

//	iprintf("IsFingerPressed Fail\r\n");
	return FAIL;
}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int GT_511C3_GetEnrollment(void)
{

	/*********Change Baudrate Command***********/
	Command_Packet->Head1 = COMMAND_START_CODE1;
	Command_Packet->Head2 = COMMAND_START_CODE2;
	Command_Packet->wDevId0 = DEVICE_ID;
	Command_Packet->wDevId1 = DEVICE_ID>>8;
	Command_Packet->nParam0 = ZERO;
	Command_Packet->nParam1 = ZERO;
	Command_Packet->nParam2 = ZERO;
	Command_Packet->nParam3 = ZERO;
	Command_Packet->wCmd0 = GETENROLLCOUNT;
	Command_Packet->wCmd1 = ZERO;
	uint16_t tmp = CalcChkSumOfCmdAckPkt(Command_Packet);
	Command_Packet->wChkSum0 = tmp % 256;
	Command_Packet->wChkSum1 = tmp >> 8;
	/*********Change Baudrate Command***********/

	GT_511C3_SendCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	int rtn = GT_511C3_ReceiveCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	if( (rtn == SB_OEM_PKT_SIZE) && (Command_Packet->wCmd0 == ACK) && (CheckChkSumOfRpsAckPkt(Command_Packet) == OK) )
	{
		return Command_Packet->nParam0;
	}

//	iprintf("GetEnrollment Fail\r\n");
	return FAIL;

}
/*********************************************************************
 *
 * Function:	Identify( Param 1 )
 * Description:	Identify
 *
 * Copyright:	Versamodule
 * Author:		JP
 * Creation Date:	4.13.2013
 *
 *
 * Function Passers: 	Param 1: data to send to the Command Register
 *
 *
 * NOTE: CaptureFinger must be called first before this for it to be valid
 *
 *
 *
 * Returns: Identity good, -1 if not
 *
**********************************************************************/
int GT_511C3_Identify(void)
{


	/*********Change Baudrate Command***********/
	Command_Packet->Head1 = COMMAND_START_CODE1;
	Command_Packet->Head2 = COMMAND_START_CODE2;
	Command_Packet->wDevId0 = DEVICE_ID;
	Command_Packet->wDevId1 = DEVICE_ID>>8;
	Command_Packet->nParam0 = ZERO;
	Command_Packet->nParam1 = ZERO;
	Command_Packet->nParam2 = ZERO;
	Command_Packet->nParam3 = ZERO;
	Command_Packet->wCmd0 = IDENTIFY;
	Command_Packet->wCmd1 = ZERO;
	uint16_t tmp = CalcChkSumOfCmdAckPkt(Command_Packet);
	Command_Packet->wChkSum0 = tmp % 256;
	Command_Packet->wChkSum1 = tmp >> 8;
	/*********Change Baudrate Command***********/

	GT_511C3_SendCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	int rtn = GT_511C3_ReceiveCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	if( (rtn == SB_OEM_PKT_SIZE) && (Command_Packet->wCmd0 == ACK) && (CheckChkSumOfRpsAckPkt(Command_Packet) == OK) )
	{
		return (Command_Packet->nParam1<<8) + Command_Packet->nParam0;
	}

//	iprintf("Identify Fail\r\n");
	return FAIL;

}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int GT_511C3_CaptureFinger(uint8_t cFlag)
{

	/*********Change Baudrate Command***********/
	Command_Packet->Head1 = COMMAND_START_CODE1;
	Command_Packet->Head2 = COMMAND_START_CODE2;
	Command_Packet->wDevId0 = DEVICE_ID;
	Command_Packet->wDevId1 = DEVICE_ID>>8;
	Command_Packet->nParam0 = cFlag & 0xFF;
	Command_Packet->nParam1 = 0x00;		//(cFlag & 0xFF00) >> 8 ;
	Command_Packet->nParam2 = 0x00;		//(cFlag & 0xFF0000) >> 16;
	Command_Packet->nParam3 = 0x00;		//(cFlag & 0xFF000000) >> 24;
	Command_Packet->wCmd0 = CAPTURE_FINGER;
	Command_Packet->wCmd1 = ZERO;
	uint16_t tmp = CalcChkSumOfCmdAckPkt(Command_Packet);
	Command_Packet->wChkSum0 = tmp % 256;
	Command_Packet->wChkSum1 = tmp >> 8;
	/*********Change Baudrate Command***********/

	GT_511C3_SendCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	int rtn = GT_511C3_ReceiveCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	if( (rtn == SB_OEM_PKT_SIZE) && (Command_Packet->wCmd0 == ACK) && (CheckChkSumOfRpsAckPkt(Command_Packet) == OK) )
	{
		return OK;
	}

	return FAIL;
}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int GT_511C3_DeleteAll(void)
{

	/*********Change Baudrate Command***********/
	Command_Packet->Head1 = COMMAND_START_CODE1;
	Command_Packet->Head2 = COMMAND_START_CODE2;
	Command_Packet->wDevId0 = DEVICE_ID;
	Command_Packet->wDevId1 = DEVICE_ID>>8;
	Command_Packet->nParam0 = ZERO;
	Command_Packet->nParam1 = ZERO;
	Command_Packet->nParam2 = ZERO;
	Command_Packet->nParam3 = ZERO;
	Command_Packet->wCmd0 = DELETEALL;
	Command_Packet->wCmd1 = ZERO;
	uint16_t tmp = CalcChkSumOfCmdAckPkt(Command_Packet);
	Command_Packet->wChkSum0 = tmp % 256;
	Command_Packet->wChkSum1 = tmp >> 8;
	/*********Change Baudrate Command***********/

	GT_511C3_SendCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	int rtn = GT_511C3_ReceiveCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);


	if( (rtn == SB_OEM_PKT_SIZE) && (Command_Packet->wCmd0 == NACK) && (CheckChkSumOfRpsAckPkt(Command_Packet) == OK) )
	{
		return OK;
	}

//	iprintf("DeleteAll Fail\r\n");
	return FAIL;
}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int GT_511C3_Delete_ID(uint16_t id)
{

	/*********Change Baudrate Command***********/
	Command_Packet->Head1 = COMMAND_START_CODE1;
	Command_Packet->Head2 = COMMAND_START_CODE2;
	Command_Packet->wDevId0 = DEVICE_ID;
	Command_Packet->wDevId1 = DEVICE_ID>>8;
	Command_Packet->nParam0 = id & 0xFF;
	Command_Packet->nParam1 = (id & 0xFF00) >> 8 ;
	Command_Packet->nParam2 = 0x00;		//(id & 0xFF0000) >> 16;
	Command_Packet->nParam3 = 0x00;		//(id & 0xFF000000) >> 24;
	Command_Packet->wCmd0 = DELETEID;
	Command_Packet->wCmd1 = ZERO;
	uint16_t tmp = CalcChkSumOfCmdAckPkt(Command_Packet);
	Command_Packet->wChkSum0 = tmp % 256;
	Command_Packet->wChkSum1 = tmp >> 8;
	/*********Change Baudrate Command***********/

	GT_511C3_SendCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	int rtn = GT_511C3_ReceiveCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	if( (rtn == SB_OEM_PKT_SIZE) && (Command_Packet->wCmd0 == ACK) && (CheckChkSumOfRpsAckPkt(Command_Packet) == OK) )
	{
		return OK;
	}

//	iprintf("Delete_ID Fail\r\n");
	return FAIL;
}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int GT_511C3_GetRawImage(int valid)
{

//	uint8_t gbyImgRaw[240*320/4];
	uint8_t pixel;
//	uint8_t gbyImgRaw[240];
	int x, y;
	int j=0;

	//*********Change Baudrate Command***********
	Command_Packet->Head1 = COMMAND_START_CODE1;
	Command_Packet->Head2 = COMMAND_START_CODE2;
	Command_Packet->wDevId0 = DEVICE_ID;
	Command_Packet->wDevId1 = DEVICE_ID>>8;
	Command_Packet->nParam0 = ZERO;
	Command_Packet->nParam1 = ZERO;
	Command_Packet->nParam2 = ZERO;
	Command_Packet->nParam3 = ZERO;
	Command_Packet->wCmd0 = GETRAWIMAGE;
	Command_Packet->wCmd1 = ZERO;
	uint16_t tmp = CalcChkSumOfCmdAckPkt(Command_Packet);
	Command_Packet->wChkSum0 = tmp % 256;
	Command_Packet->wChkSum1 = tmp >> 8;
	//*********Change Baudrate Command***********



	GT_511C3_SendCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	int rtn = GT_511C3_ReceiveCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	if( (rtn == SB_OEM_PKT_SIZE) && (Command_Packet->wCmd0 == ACK) && (CheckChkSumOfRpsAckPkt(Command_Packet) == OK) )
	{
		Serial.print("Downloading Image\r\n");

		for( x=0; x<120; x++)
		{
			for( y=0; y<160; y++)
			{

				while(!Serial1.available());

				pixel = Serial1.read();

				if(valid == VALID)
				{
					LCD_PixelPut(x + 5, y + 45 , pixel << 5 );		//Shift up 4 or 5
				}
				else
				{
					LCD_PixelPut(x + 5, y + 45 , (pixel << 5) | 0xf800 );		//Shift up 4 or 5
				}

			}
		}

		GT_511C3_PurgeRX();

		return OK;
	}

	Serial.print("GetRawImage Fail\r\n");


	// Wipe Bargraph Off screen
//	LCD_Fill(1,41,129,220,0x0000);

//	sprintf(lcdstring,"Image Error");
//	LCD_String(lcdstring,Comic_Sans_MS20x27,5,120,4,0x07e0,0x0000);


	return FAIL;

}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int GT_511C3_EnrollStart(uint16_t id)
{



	/*********Change Baudrate Command***********/
	Command_Packet->Head1 = COMMAND_START_CODE1;
	Command_Packet->Head2 = COMMAND_START_CODE2;
	Command_Packet->wDevId0 = DEVICE_ID;
	Command_Packet->wDevId1 = DEVICE_ID>>8;
	Command_Packet->nParam0 = id & 0xFF;
	Command_Packet->nParam1 = (id & 0xFF00) >> 8 ;
	Command_Packet->nParam2 = 0x00;		//(id & 0xFF0000) >> 16;
	Command_Packet->nParam3 = 0x00;		//(id & 0xFF000000) >> 24;
	Command_Packet->wCmd0 = ENROLLSTART;
	Command_Packet->wCmd1 = ZERO;
	uint16_t tmp = CalcChkSumOfCmdAckPkt(Command_Packet);
	Command_Packet->wChkSum0 = tmp % 256;
	Command_Packet->wChkSum1 = tmp >> 8;
	/*********Change Baudrate Command***********/

	GT_511C3_SendCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	int rtn = GT_511C3_ReceiveCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	if( (rtn == SB_OEM_PKT_SIZE) && (Command_Packet->wCmd0 == ACK) && (CheckChkSumOfRpsAckPkt(Command_Packet) == OK) )
	{
		return Command_Packet->nParam0;
	}

//	iprintf("GetEnrollment Fail\r\n");
	return FAIL;

}
//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int GT_511C3_Enrollnth(uint8_t count)
{

	/*********Change Baudrate Command***********/
	Command_Packet->Head1 = COMMAND_START_CODE1;
	Command_Packet->Head2 = COMMAND_START_CODE2;
	Command_Packet->wDevId0 = DEVICE_ID;
	Command_Packet->wDevId1 = DEVICE_ID>>8;
	Command_Packet->nParam0 = ZERO;
	Command_Packet->nParam1 = ZERO;
	Command_Packet->nParam2 = ZERO;
	Command_Packet->nParam3 = ZERO;
	Command_Packet->wCmd0 = ENROLLSTART + count;
	Command_Packet->wCmd1 = ZERO;
	uint16_t tmp = CalcChkSumOfCmdAckPkt(Command_Packet);
	Command_Packet->wChkSum0 = tmp % 256;
	Command_Packet->wChkSum1 = tmp >> 8;
	/*********Change Baudrate Command***********/

	GT_511C3_SendCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	int rtn = GT_511C3_ReceiveCommand((uint8_t *)Command_Packet,SB_OEM_PKT_SIZE);

	if( (rtn == SB_OEM_PKT_SIZE) && (Command_Packet->wCmd0 == ACK) && (CheckChkSumOfRpsAckPkt(Command_Packet) == OK) )
	{
		return Command_Packet->nParam0;
	}

//	iprintf("Enroll nth Fail\r\n");
	return FAIL;

}

//*********************************************************************
//****************************  TASK 1  *******************************
//*********************************************************************
int GT_511C3_PerformEnrollment(uint16_t id)
{

	uint8_t  x;

	if(GT_511C3_EnrollStart(id) == OK)
	{
//		iprintf("Start Enrollment for ID:%d\r\n",id);

		// Turn LCD on so module can see finger
		GT_511C3_LED(1);


		for(x=1;x<4;x++)
		{
//			iprintf("Enrollment #%u of 3, Press Finger\r\n",x);

			// Wait for finger press
			while(GT_511C3_IsFingerPressed() != FINGER_PRESSED)
			{
				//OSTimeDly( 1 );
			}

			// while finger pressed and capture not ready
			while( (GT_511C3_IsFingerPressed() == FINGER_PRESSED)  && (GT_511C3_CaptureFinger(1)!=OK) )
			{
				//OSTimeDly( 5 );
			}

			if(GT_511C3_Enrollnth(x)==OK)
			{
//				iprintf("Enroll Complete, Remove Finger\r\n");

				while(GT_511C3_IsFingerPressed() == FINGER_PRESSED)
				{
					//OSTimeDly( 1 );
				}
			}
			else
			{
//				iprintf("Enroll %u Failed\r\n",x);

				return FAIL;
			}
		}


		GT_511C3_LED(0);

//		iprintf("Enrollment of ID[%d] Successful\r\n",id);


		return OK;
	}
	else
	{
//		iprintf("!!! Start Enrollment Fail for ID:%d !!!\r\n",id);
	}

	return FAIL;

}

GT-511C3.h

/*
 * GT-511C3.h
 *
 *  Created on: Apr 12, 2013
 *      Author: Jim
 */

#ifndef GT_511C3_H_
#define GT_511C3_H_

#define ERROR	0
#define VALID	1

#define FINGER_PRESSED			1
#define FINGER_NOT_PRESSED		0

#define OK 				0
#define FAIL (char)			-1
#define MAX_ENTRY_LEN 			64
#define VSIZE 				224
#define HSIZE 				216
#define CAP_OK 				1
#define GET_USB_MESSAGE 		2
#define PROCESSING 			3
#define QUILITY_BAD		 	4
#define LOGIN_PASS 			5
#define LOGIN_FAIL			6
#define RECOVER				7
#define ID_EMPTY			8
#define ENROLLING			0x30
#define GET_IMAGE_DATA			0x33
#define IMAGE_PROTOCOLl_START 		0x33
#define NO_PUT_FINGER			9
#define REMOVE_FINGER			10
#define	REMOVE_OK			11
#define UNDETECT_AGAIN			12
#define ENROLL_FAIL			13
#define ENROLL_OK			14
#define ERASEID_OK			15
#define ERASE_PROTECT			0xFB
#define FLASH_FAIL			0xFC
#define CAP_FAIL			0xFF
#define EVEN_BREAK			0xFF



#define INFO_EXISTED 			-1000
#define PROCESSING_FAIL			-1001
#define COMMAND_FAIL			-1002


#define COMMAND_START_CODE1 		0x55
#define COMMAND_START_CODE2 		0xAA
#define DEVICE_ID			0x0001

#define RESPONSE_START_CODE1 		0x55
#define RESPONSE_START_CODE2 		0xAA

#define DATA_START_CODE1		0x5A
#define DATA_START_CODE2		0xA5

#define OPEN				0x01
#define CLOSE				0x02
#define USBINTERNALCHECK		0x03
#define CHANGBAUDRATE			0x04
#define IAPMODE				0x05
#define CMOSLED				0x12
#define GETENROLLCOUNT			0x20
#define CHECKENROLLED			0x21
#define	ENROLLSTART			0x22
#define ENROLL1				0x23
#define ENROLL2				0x24
#define ENROLL3				0x25
#define ISPRESSFINGER			0x26
#define DELETEID			0x40
#define DELETEALL			0x41
#define VERIFY				0x50
#define IDENTIFY			0x51
#define VERIFY_TEMPLATE			0x52
#define IDENTIFY_TEMPLATE		0x53
#define CAPTURE_FINGER			0x60
#define GETIMAGE			0x62
#define GETRAWIMAGE			0x63
#define GETTEMPLATE			0x70
#define SETTEMPLATE			0x71
#define GETDATABASESTART		0x72
#define GETDATABASEEND			0x73
#define UPGRADEFIRMWARE			0x80
#define ACK				0x30
#define NACK				0x31

#define NACK_NONE			0x1000
#define NACK_TIMEOUT			0x1001
#define NACK_INVALID_BAUDRATE		0x1002
#define NACK_INVALID_POS		0x1003
#define NACK_IS_NOT_USED		0x1004
#define NACK_IS_ALREADY_USED		0x1005
#define NACK_COMM_ERR			0x1006
#define NACK_VERIFY_FAILED		0x1007
#define NACK_IDENTIFY_FAILED		0x1008
#define NACK_DB_IS_FULL			0x1009
#define NACK_DB_IS_EMPTY		0x100A
#define NACK_TURN_ERR			0x100B
#define NACK_BAD_FINGER			0x100C
#define NACK_ENROLL_FAILED		0x100D
#define NACK_IS_NOT_SUPPORTED		0x100E
#define NACK_DEV_ERR			0x100F
#define NACK_CAPTURE_CANCELED		0x1010
#define NACK_INVALID_PARAM		0x1011
#define NACK_FINGER_IS_NOT_PRESSED	0x1012

#define COMMAND_PACKET			0x00
#define RESPONSE_PACKET			0x01
#define	DATA_PACKET			0x02

#define SB_OEM_PKT_SIZE			12
#define SB_OEM_HEADER_SIZE		2
#define SB_OEM_DEV_ID_SIZE		2
#define SB_OEM_CHK_SUM_SIZE		2

#define NONZERO				0x01
#define ZERO				0x00
#define DEVUCE_SERIAL_NUMBER_ERROR	0xFF

#define PKT_ERR_START			-500
#define PKT_COMM_ERR			PKT_ERR_START+1
#define PKT_HDR_ERR			PKT_ERR_START+2
#define PKT_DEV_ID_ERR			PKT_ERR_START+3
#define PKT_CHK_SUM_ERR			PKT_ERR_START+4
#define PKT_PARAM_ERR			PKT_ERR_START+5

#define FP_MAX_USERS			20


typedef struct _devinfo
{
	long FirmwareVersion;
	unsigned char DeviceSerialNumber[16];
} devinfo;


typedef struct {
	unsigned char 	Head1;
	unsigned char 	Head2;
	unsigned char	wDevId0;
	unsigned char	wDevId1;
	unsigned char	nParam0;
	unsigned char	nParam1;
	unsigned char	nParam2;
	unsigned char	nParam3;
	unsigned char	wCmd0;// or nAck
	unsigned char	wCmd1;
	unsigned char 	wChkSum0;
	unsigned char 	wChkSum1;
} SB_OEM_PKT;


extern uint16_t total_downloaded;
//extern uint8_t FingerImg[240*320/4];



int GT_511C3_Init( void );
int GT_511C3_Terminate(void);
void GT_511C3_SendCommand(uint8_t * ucData, uint8_t length);
int GT_511C3_ReceiveCommand(uint8_t *ucData, uint16_t length);
int GT_511C3_ReceiveCommandLCD(char *ucData, uint16_t length);
void GT_511C3_PurgeRX(void);
int CalcChkSumOfCmdAckPkt( SB_OEM_PKT* pPkt );
int CheckChkSumOfRpsAckPkt( SB_OEM_PKT* pPkt );
int CalcChkSumOfDataPkt( unsigned char* pDataPkt, int nSize );
int GT_511C3_Open(unsigned long BAUDRATE);
int GT_511C3_ChangeBaudRate(unsigned long BAUDRATE);
int GT_511C3_LED(boolean State);
int GT_511C3_IsFingerPressed(void);
int GT_511C3_GetEnrollment(void);
int GT_511C3_Identify(void);
int GT_511C3_CaptureFinger(uint8_t cFlag);
int GT_511C3_DeleteAll(void);
int GT_511C3_Delete_ID(uint16_t id);
int GT_511C3_GetImage(void);
int GT_511C3_GetRawImage(int valid);
int GT_511C3_EnrollStart(uint16_t id);
int GT_511C3_Enrollnth(uint8_t count);
int GT_511C3_PerformEnrollment(uint16_t id);



#endif /* GT_511C3_H_ */

main.ino

#include "application.h"
#include "headers.h"
#include "MI0283QT-9A.h"
#include "sx8654.h"
#include "SST25VF016B.h"
#include "SX1509.h"
#include "GT-511C3.h"
#include "menus.h"


// SX1509 Pin definition:
#define SX1509_LED_PIN  15 // LED to SX1509's pin 15
#define SX1509_PWM_PIN  14 // LED PWM Breathe output



//https://docs.particle.io/reference/firmware/photon/#semi-automatic-mode
// This is done so we initialize the LCD quickly so user does not think its
// dead while it waiting to register, or it it has not been registered yet.
SYSTEM_MODE(SEMI_AUTOMATIC);

//*********************************************************************
//******************  INITALIZE THE CHIP SELECT PIN  ******************
//*********************************************************************
void setup()
{

    pinMode(FLASH_CS_PIN, OUTPUT);
    digitalWrite(FLASH_CS_PIN, HIGH);

    pinMode(LCD_CS_PIN, OUTPUT);
    digitalWrite(LCD_CS_PIN, HIGH);

    pinMode(LCD_DC_PIN, OUTPUT);
    digitalWrite(LCD_DC_PIN, HIGH);

    pinMode(LCD_IRQ_PIN, INPUT_PULLUP);

    Serial1.begin(9600);   // open serial over USB
    Serial1.write("\r");
    Serial1.write("\n");

    Serial.begin(115200);   // open serial over USB

    // Initialize the I2C bus if not already enabled
    if ( !Wire.isEnabled() )
    {
      Wire.setSpeed(CLOCK_SPEED_100KHZ);
      Wire.begin();
    }

    SPI1.begin();
    SPI1.setBitOrder(MSBFIRST);
    SPI1.setClockDivider(SPI_CLOCK_DIV2);
    SPI1.setDataMode(SPI_MODE0);

    // Init LCD
    LCD_InitLandscape();

    // Verify the sFLASH, Touch Screen, GPIO Expander
    if( (sFLASH_Init() == true) && (SX8654_Init() == true) && (io.begin(SX1509_ADDRESS)==true) )
    {
        LCD_Fill(0,0,320,81,0xF800);
        LCD_Fill(0,81,320,81,0x07e0);
        LCD_Fill(0,160,320,80,0x001f);

        // Set up the SX1509's clock to use the internal 2MHz
        // oscillator. The second parameter divides the oscillator
        // clock to generate a slower LED clock. 4 divides the 2MHz
        // clock by 2 ^ (4-1) (8, ie. 250kHz). The divider parameter
        // can be anywhere between 1-7.
        io.clock(INTERNAL_CLOCK_2MHZ, 4);

        io.pinMode(SX1509_LED_PIN, OUTPUT); // Set LED pin to OUTPUT

        // Blink the LED pin -- ~1000 ms LOW, ~500 ms HIGH:
        io.blink(SX1509_LED_PIN, 1000, 500);

        // To breathe an LED, make sure you set it as an
		// ANALOG_OUTPUT, so we can PWM the pin:
		io.pinMode(SX1509_PWM_PIN, ANALOG_OUTPUT);

		// Breathe an LED: 1000ms LOW, 500ms HIGH,
		// 500ms to rise from low to high
		// 250ms to fall from high to low
		io.breathe(SX1509_PWM_PIN, 1000, 500, 500, 250);

    }
    else
    {
        LCD_CLS(0xF800);
    }

    // Wi-Fi connect...
    Particle.connect();

//    delay(1000);
    LCD_CLS(0x0000);


    sprintf(lcdstring,"Open Terminal");
    LCD_StringFram(lcdstring,Comic_Sans_20x27,100,100,3,0xF81f,0x0000);

    // Now open your Serial Terminal, and hit any key to continue!
//    while(!Serial.available()) Particle.process();

    LCD_CLS(0x0000);

    GT_511C3_Init();

    GT_511C3_LED(true);

    sprintf(lcdstring,"Biometric Scanner");
	LCD_StringFram(lcdstring,Comic_Sans_20x27,25,0,4,0xffe0,0x0000);

    LCD_Box(0,40,130,210,0xffe0);

    DisplayFRAMImage(PressYellow,190,60);

    CreateTouchContainer(190,60,PressYellow,HAND_ICON);
    CreateTouchBox(0,40,130,210,SETTINGS_ICON,0);


    CreateTouchContainer(10,20,UserAdd,USER_ADD_ICON);
	CreateTouchContainer(115,20,UserDelete,USER_DELETE_ICON);
	CreateTouchContainer(220,20,RecycleBin,RECYCLEBIN_ICON);
	CreateTouchContainer(10,125,UserProfile,USER_PROFILE_ICON);
	CreateTouchContainer(220,125,Previous,PREVIOUS_ICON);




    GT_511C3_LED(false);

    //Show how many fingers are enrolled
	int enroll = GT_511C3_GetEnrollment();

	Serial.print("Total Enrolled:");
    Serial.println(enroll);

}
//*********************************************************************
//******************  INITALIZE THE CHIP SELECT PIN  ******************
//*********************************************************************
void loop()
{

//    WaitForFingerScan();

    if(IsScreenPressed() == true)
    {
        if( GetPenLocation() == true)
        {
            Crosshairs(sx8654_touch.pen_x, sx8654_touch.pen_y,5, 0x07e0);

            // See if the area we touched was within the "Touch Me" location container
            if(CheckTouchBox(sx8654_touch.pen_x,sx8654_touch.pen_y,HAND_ICON) == true)
            {
                // Wipe fingerprint Off screen
                LCD_Fill(1,51,129,154,0x0000);

                DisplayFRAMImage(PressGreen,190,60);
                WaitForFingerScan();
            }
            else if(CheckContainer(sx8654_touch.pen_x,sx8654_touch.pen_y,SETTINGS_ICON) == true)
            {
                SetupMenu();

                LCD_CLS(0x0000);

                sprintf(lcdstring,"Biometric Scanner");
            	LCD_StringFram(lcdstring,Comic_Sans_20x27,25,0,4,0xffe0,0x0000);

                LCD_Box(0,40,130,210,0xffe0);

                DisplayFRAMImage(PressYellow,190,60);

                WaitForTouchRelease(2000);
            }

        }
    }

    delay(5);

}

Is there an update to this that doesn’t require application.h? application.h has 40 other header files.

Yes, application.h was superseded by Particle.h but what’s the issue with the nested header files?
If the respective modules are not used in your code they won’t be linked into the binary but chances are that you will need at least a dozen of them anyway.

The alternative would be that everybody else would potentially have to include dozends of headers manually :wink:

Oh sweet, I will include Particle.h thanks.