First of all I would like to point out that that the Arduino code for Lepton on Github is wrong. To read a frame you must do the following:
- Lower Lepton CS
- Read 164 bytes into buffer - I found that reading using array indexing was too slow and instead a pointer had to be used
- Raise CS
The Github Arduino code seems to lower CS, read 2 Bytes and then raise CS. I don't think you can get past reading only the first two bytes of the first packet doing this. Everything else will then be garbage because the entire packet was not read out.
Using an Arduino Due I can read an entire frame from a Lepton into a buffer and then serially transmit this into Matlab. Below are some images I captured of my hand and face (no colour mapping yet). Serial transmission into Matlab (even at 115200 baud) takes a little while.

However, I am having two weird issues.
- Firstly, my Arduino code pulls one frame from Lepton and then randomly stops running. The SPI code being executed is in a while(1) statement which just seems to loop only one single time... The only way for me to get a new capture is to reset the Arduino and the code will execute once. Does anyone have any idea why the code is not constantly looping inside the while(1) statement?
- Occasionally the Lepton stops getting new frames and will only transmit the same frame which seems to be in its memory. The only way to fix this is to physically take the lepton out of the socket and pop in back it while everything is powered - similar to the red square issue with the Raspberry Pi Video. Anyone have any idea what's going on here?
My Arduino Due code is below (and attached). For clarity I have left out the code which serially sends the frame to Matlab. You can look at the frame values using the Arduino serial monitor.
Any help is greatly appreciated!
#include <SPI.h>
#include <stdio.h>
#include <string.h>
#define PACKET_SIZE (164)
#define PACKETS_PER_FRAME 60
byte frame_buffer[PACKET_SIZE * PACKETS_PER_FRAME] = {0};
byte *p;
int ledPin=13;
void setup()
{
Serial.begin(115200);
pinMode(2, OUTPUT); //I2C
pinMode(3, OUTPUT); //I2C
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
Serial.println("setup complete");
}
void loop()
{
p = frame_buffer;
openSPI();
while(1)
{
int resets = 0;
for(int j=0; j<PACKETS_PER_FRAME; j++)
{
//read 164 byte packet directly into frame buffer
for(int k=0; k<(PACKET_SIZE-1); k++)
{
// must dereference pointer...
*(p+j*PACKET_SIZE+k) = SPI.transfer(10, 0x00, SPI_CONTINUE); // use SPI_CONTINUE to keep CS low for entire 164 byte packet
// cannot store into buffer using array indexing - cannot pull complete frame fast enough without losing sync
// i.e. frame_buffer[j*PACKET_SIZE+k] = SPI.transfer(10, 0x00, SPI_CONTINUE);
}
*(p+j*PACKET_SIZE+PACKET_SIZE) = SPI.transfer(10, 0x00); // raise CS after last byte read
int packetID = *(p+j*PACKET_SIZE+1);
if(packetID != j) //if discard packet reset j, make j=-1 so 0 on next loop
{
if(packetID != 255)
{
Serial.print("Packet lost at ");
Serial.println(packetID);
}
j=-1;
resets += 1;
delayMicroseconds(1000);
//750 resets is an arbitrary limit, since there should never be 750 "null" packets between two valid transmissions at the current poll rate
//Polling faster may exceed this count, and the down period between frames may then be flagged as a loss of sync
if(resets == 750)
{
Serial.print("Sync lost at packet ");
Serial.println(packetID);
closeSPI();
delay(750);
openSPI();
}
}
}
Serial.println("Frame pulled");
//Serial.print("Resets = ");
//Serial.println(resets);
printFrame(); //print frame to serial monitor
}
closeSPI();
}
void openSPI(void)
{
SPI.begin(10);
SPI.setClockDivider(10,8); //Due 84MHz / 8 ~= 10MHz SPI clk
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE3);
}
void closeSPI(void)
{
SPI.end(10);
}
void printFrame(void)
{
// frame consists of 60 packets, each 164 bytes long
for(int row=0; row<PACKETS_PER_FRAME; row++)
{
for(int col=0; col<(PACKET_SIZE); col++)
{
Serial.print(*(p+row*PACKET_SIZE+col));
Serial.print(" ");
}
Serial.println("");
}
}