2025-07-02 11:09 AM
Hello everyone. I am writing to you because I am trying to capture a thermal image (frame of temperature values) using a Lepton 2.5 thermal camera with Break Out board 2.0 connected to a Nucleo U5A5ZJ-Q board. First I connected the following pins of the Break Out board 2.0 to the Nucleo board, as shown in the table below.
I have not inserted pull-up resistors or software pull-ups on SDA and SCL.
Then I created the project and wrote the first lines of code in order to:
-) Reset the Lepton thermal camera
-) Read the register =0x000E
-) Check that the thermal camera boot is finished (bit2 == 1 of 0x0002 register)
-) Check that the interface is not busy (bit0==0 of 0x0002 register)
-) Check that the system is ready (SYS FFC Status = 0x0000)
Below is the code I used to implement this first part.
// Lepton Reset (PC13 low -> high)
HAL_Delay(100); // 100 ms to give time for the activation
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); // Put Low for Reset
HAL_Delay(500); // 500ms di reset
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); // Put high to finish Reset
HAL_Delay(10000); // Wait the inizialization
// 0. READ 0x000E Register
HAL_I2C_Mem_Read(&hi2c1, LEPTON_I2C_ADDR << 1, 0x000E, I2C_MEMADD_SIZE_16BIT, rx_buf, 2, 100);
uint16_t cam_status = (rx_buf[0] << 8) | rx_buf[1];
volatile uint16_t lepton_cam_status = cam_status; // :backhand_index_pointing_left: Watch with debugger
// 1. Check that the boot process is finished (bit 2 == 1)
uint16_t timeout = 1000;
do {
status = HAL_I2C_Mem_Read(&hi2c1, LEPTON_I2C_ADDR << 1, 0x0002, I2C_MEMADD_SIZE_16BIT, status_buf, 2, 100);
HAL_Delay(10);
timeout--;
} while ((status == HAL_OK) && !(status_buf[1] & 0x04) && (timeout > 0)); // Bit 2
if (timeout == 0) // Timeout error: boot not finished
{
Error_Handler();
}
// 2. Check that the interface is not busy (bit 0 == 0)
timeout = 1000;
do {
status = HAL_I2C_Mem_Read(&hi2c1, LEPTON_I2C_ADDR << 1, 0x0002, I2C_MEMADD_SIZE_16BIT, status_buf, 2, 100);
HAL_Delay(10);
timeout--;
} while ((status == HAL_OK) && (status_buf[1] & 0x01) && (timeout > 0)); // Bit 0
if (timeout == 0) // Timeout errore: ancora busy
{
Error_Handler();
}
// 3. Check that the system is ready (SYS FFC Status = 0x0000)
timeout = 1000;
uint16_t ffc_status = 0;
do {
status = HAL_I2C_Mem_Read(&hi2c1, LEPTON_I2C_ADDR << 1, 0x0204, I2C_MEMADD_SIZE_16BIT, rx_buf, 2, 100);
HAL_Delay(10);
timeout--;
ffc_status = (rx_buf[0] << 8) | rx_buf[1];
} while ((status == HAL_OK) && (ffc_status != 0x0000) && (timeout > 0));
if (timeout == 0) // Errore: modulo non pronto
{
Error_Handler();
}
Up to this point everything works correctly and the communication on I2C works correctly. The SDA and SCL signals are coherent and correct and I checked them on oscilloscope.
Then I tried to read the temperature using the following lines of code.
// STEP 1: Write command ID (0x0010) in the 0x0008 register (COMMAND_ID)
tx_buf[0] = 0x00;
tx_buf[1] = 0x10;
status = HAL_I2C_Mem_Write(&hi2c1, LEPTON_I2C_ADDR << 1, 0x0008, I2C_MEMADD_SIZE_16BIT, tx_buf, 2, 100);
if (status != HAL_OK)
{
Error_Handler();
}
// STEP 2: Write GET (0x0000) in the 0x0006 register (COMMAND_TYPE)
tx_buf[0] = 0x00;
tx_buf[1] = 0x00;
status = HAL_I2C_Mem_Write(&hi2c1, LEPTON_I2C_ADDR << 1, 0x0006, I2C_MEMADD_SIZE_16BIT, tx_buf, 2, 100);
if (status != HAL_OK)
{
Error_Handler();
}
// STEP 3: Read the value from the 0x0210 register (0x0200 + 0x0010)
status = HAL_I2C_Mem_Read(&hi2c1, LEPTON_I2C_ADDR << 1, 0x0210, I2C_MEMADD_SIZE_16BIT, rx_buf, 2, 100);
if (status != HAL_OK)
{
Error_Handler();
}
temp_kelvin = (rx_buf[0] << 8) | rx_buf[1];
temp_celsius = (temp_kelvin / 100.0f) - 273.15f;
volatile float aux_temp_c = temp_celsius; // :backhand_index_pointing_left: watch with debugger
The communication on I2C works correctly, but the value read is zero. Zero is very strange. I checked all with oscilloscope. The communication works well, but the value read is zero.
Then I tried to read a frame of temperature values with the following function.
void Lepton_ReadFrame(void)
{
uint8_t line[LEPTON_LINE_SIZE];
uint16_t expected_line = 0;
uint16_t received_line = 0;
uint16_t retries = 0;
const uint16_t max_retries = 1000;
while (expected_line < LEPTON_FRAME_LINES && retries < max_retries)
{
// CS LOW
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
// Receive SPI line with 100ms timeout
if (HAL_SPI_Receive(&hspi1, line, LEPTON_LINE_SIZE, 200) != HAL_OK)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS HIGH
retries++;
HAL_Delay(1);
continue; // Check again
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS HIGH
// Take number of the line
received_line = ((line[0] & 0x0F) << 8) | line[1];
// Check valid header
if ((line[0] & 0xF0) != 0x00 || received_line >= LEPTON_FRAME_LINES)
{
retries++;
continue; // Conrupted packet
}
// Check sequential order
if (received_line != expected_line)
{
expected_line = 0; // restart the frame
retries++;
continue;
}
// Copy line in the frame
memcpy(lepton_frame[expected_line], line, LEPTON_LINE_SIZE);
expected_line++;
}
if (expected_line != LEPTON_FRAME_LINES)
{
// Error: incomplete frame
volatile int frame_error = 1; // useful for debug
}
else
{
volatile int frame_ok = 1; // frame complete and ready
}
}
But everything hangs on VSYNC, because before launch the function Lepton_ReadFrame in the While(1) of the main function I check the front on VSYNC.
while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET);
while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_SET);
Lepton_ReadFrame();
The front does not arrive on VSYNC and if I remove the check of the front of VSYNC I cannot read any values.
Finally, I would like to point out that approximately every minute the shutter of the LEPTON 2.5 closes and reopens. Do you have any advice on how to solve these problems and be able to read the temperature of the sensor case and the temperature frame with the thermal camera?
Thank you very much for the support.