Can't get GT-NUCL1633K1 fingerprint reader to work

I’m trying to interface an ATmega328P with a GT-NUCL1633K1 sensor over UART. When I send commands to the sensor, it responds just by echoing the command, instead of actually doing anything.

For example, I’m trying to execute the 0xA0 command with Flag set to 1 (page 8 in the sensor’s programming guide) using the following code.

cmd: F5 A0 00 00 01 00 A1 F5   (open and send dev info)
res: F5 A0 00 00 01 00 A1 F5

According to the programming guide, the 01 in the fifth position means ACK_FAIL (execute failed). So, I tried the following command sequence:

cmd: F5 A0 00 00 00 00 A1 F5   (open)
res: F5 A0 00 00 00 00 A1 F5

cmd: F5 B4 00 00 00 00 B4 F5   (LED on)
res: F5 B4 00 00 00 00 B4 F5

cmd: F5 0D 00 00 00 00 0D F5   (Get an unused ID between 1 and N)
res: F5 0D 00 00 00 00 0D F5

As you can see, the response from the sensor just echoes my command. My driver code for the sensor:

#include <stdio.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <util/setbaud.h>

#include "nrfm.h"
#include "finprint.h"

#define FINPRINT_PIN    PC5
#define FINPRINT_DDR    DDRC
#define FINPRINT_PORT   PORTC

#define LEN(a)  (sizeof(a) / sizeof(a[0]))

static uint8_t txaddr[] = { 194, 178, 83 };

static inline void send(uint8_t c)
{
	while (!(UCSR0A & (1 << UDRE0)))
		;
	UDR0 = c;
}

static inline void enable(void)
{
	FINPRINT_PORT |= (1 << FINPRINT_PIN);
	_delay_ms(100);
}

static inline void disable(void)
{
	FINPRINT_PORT &= ~(1 << FINPRINT_PIN);
}

static inline void sendcmd(uint8_t cm, uint8_t p1, 
	uint8_t p2, uint8_t p3, uint8_t p4)
{
	uint8_t cs;

	cs = cm ^ p1 ^ p2 ^ p3 ^ p4;

	send(0xF5);
	send(cm);
	send(p1);
	send(p2);
	send(p3);
	send(p4);
	send(cs);
	send(0xF5);
}

void finprint_init(void)
{
	UBRR0H = UBRRH_VALUE;
	UBRR0L = UBRRL_VALUE;
#if USE_2X
	UCSR0A |= (1 << U2X0);
#else
	UCSR0A &= ~(1 << U2X0);
#endif
	UCSR0B = (1 << TXEN0) | (1 << RXEN0) | (1 << RXCIE0);
	UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);

	FINPRINT_DDR |= (1 << FINPRINT_PIN);
	FINPRINT_PORT &= ~(1 << FINPRINT_PIN);
}

void finprint_info(uint8_t buf[8]) 
{
	PORTC &= ~(1 << PC4);
	enable();

	sendcmd(0xA0, 0, 0, 0, 0);
	_delay_ms(500);
	sendcmd(0xB4, 0, 0, 0, 0);
	_delay_ms(500);
	sendcmd(0x0D, 0, 0, 0, 0);
	
	//disable();
}

ISR(USART_RX_vect) 
{
	char s[5];

	PORTC |= (1 << PC4);
	snprintf(s, 5, "0x%02X", UDR0);
	radio_sendto(txaddr, s, 4);
	PORTC &= ~(1 << PC4);
}

Calling from main.c:

#include <avr/interrupt.h>
#include <util/delay.h>

#include "nrfm.h"
#include "finprint.h"

int main(void)
{
	char buf[8];
	uint8_t rxaddr[] = { 194, 178, 82 };
	uint8_t txaddr[] = { 194, 178, 83 };

	finprint_init();
	radio_init(rxaddr);
	
	sei();

	finprint_info((uint8_t *) buf);

	for (;;) {
		_delay_ms(2000);
	}

	return 0;
}

According to the programming guide, the expected response for the last command is

cmd: F5 0D 00 00 00 00 0D F5   (Get unused ID)
res: F5 0D 00 01 00 09 0F F5

The sensor operates at 3.3V. So, I’m connecting the VCC, GND, TXD and RXD of the sensor to PC5, GND, RXD, and TXD of the ATmega328P respectively via a bi-directional logic level converter. I’m using the default baudrate, which is supposed to be 115200, with 1 start and stop bit.

I verified the TXD and RXD signals using an oscilloscope. The signals on the oscilloscope match the ones I get from the RX interrupt.

Has anyone gotten one of these things to work successfully? What am I doing wrong :frowning:

I pitched this to an LLM and it had some suggestions, I’d run through those to start

Chatgpt mostly has the same ideas, here’s its link

Thanks for your reply. Pretty much tried all of them except lowering the baudrate. I believe the issue is with the LLC and the 3.3V-5V interface. There’s a good answer to my question at SO: avr - Can't get GT-NUCL1633K1 fingerprint reader to work - Electrical Engineering Stack Exchange. But wasn’t enough to resolve the problem.

I’ll test it with a 3.3V MCU like an ESP32 at some point and report back. But for now, I need to get this project done. So, I ordered a 5V fingerprint sensor.

1 Like

Sounds pragmatic! Wishing you luck with both :smiley: