void Lepton::captureFrame() { //read data packets from lepton over SPI int resets = 0; for (int j = 0; j < PACKETS_PER_FRAME; j++) { //if it's a drop packet, reset j to 0, set to -1 so he'll be at 0 again loop read(spi_cs0_fd, _result + sizeof(uint8_t) * PACKET_SIZE * j, sizeof(uint8_t) * PACKET_SIZE); int packetNumber = _result[j * PACKET_SIZE + 1]; if (packetNumber != j) { j = -1; resets += 1; usleep(1000); if (resets == 750) { SpiClosePort(0); usleep(750000); SpiOpenPort(0); } } } if (resets >= 30) { std::cout << "Done reading, resets: " << resets << std::endl; } _frameBuffer = (uint16_t *) _result; int row, column; for (int i = 0; i < FRAME_SIZE_UINT16; i++) { //skip the first 2 uint16_t's of every packet, they're 4 header bytes if (i % PACKET_SIZE_UINT16 < 2) { continue; } //flip the MSB and LSB at the last second uint8_t temp = _result[i * 2]; _result[i * 2] = _result[i * 2 + 1]; _result[i * 2 + 1] = temp; } /* Obtain the lock to check if allowed to overwrite the latest frame. * If so, keep the lock until done overwriting it. */ _mtx.lock(); if (_canOverwriteLatestFrame) { for (int i = 0; i < FRAME_SIZE_UINT16; i++) { if (i % PACKET_SIZE_UINT16 < 2) { continue; } column = (i % PACKET_SIZE_UINT16) - 2; row = i / PACKET_SIZE_UINT16; _latestFrame[row * VIEWPORT_WIDTH_PIX + column] = _frameBuffer[i]; } _cv.notify_one(); } _mtx.unlock(); }
Lepton::Lepton() { SpiOpenPort(0); int ret = 0; int fd; fd = open(device, O_RDWR); if (fd < 0) { pabort("can't open device"); } ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); if (ret == -1) { pabort("can't set spi mode"); } ret = ioctl(fd, SPI_IOC_RD_MODE, &mode); if (ret == -1) { pabort("can't get spi mode"); } ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); if (ret == -1) { pabort("can't set bits per word"); } ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits); if (ret == -1) { pabort("can't get bits per word"); } ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); if (ret == -1) { pabort("can't set max speed hz"); } ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); if (ret == -1) { pabort("can't get max speed hz"); } _latestFrame = (uint16_t*) malloc(VIEWPORT_WIDTH_PIX * VIEWPORT_HEIGHT_PIX * sizeof(uint16_t)); _newFrameAvailable = false; _canOverwriteLatestFrame = true; std::thread tempThread(&Lepton::startCapture, this); std::swap(tempThread, _leptonThread); }
void LeptonThread::run() { QString outString; int count = 0; int minValueFlameThreshold = 18200; int maxValueFlameThreshold = 9000; //create the initial image myImage = QImage(80, 60, QImage::Format_RGB888); //open spi port SpiOpenPort(0); while(count < 1) { //while(true){ //read data packets from lepton over SPI int resets = 0; for(int j=0;j<PACKETS_PER_FRAME;j++) { //if it's a drop packet, reset j to 0, set to -1 so he'll be at 0 again loop read(spi_cs0_fd, result+sizeof(uint8_t)*PACKET_SIZE*j, sizeof(uint8_t)*PACKET_SIZE); int packetNumber = result[j*PACKET_SIZE+1]; if(packetNumber != j) { j = -1; resets += 1; usleep(1000); //Note: we've selected 750 resets as an arbitrary limit, since there should never be 750 "null" packets between two valid transmissions at the current poll rate //By polling faster, developers may easily exceed this count, and the down period between frames may then be flagged as a loss of sync if(resets == 750) { SpiClosePort(0); usleep(750000); SpiOpenPort(0); } } } if(resets >= 30) { qDebug() << "done reading, resets: " << resets; } frameBuffer = (uint16_t *)result; int row, column; uint16_t value; uint16_t minValue = 16000; uint16_t maxValue = 0; for(int i=0;i<FRAME_SIZE_UINT16;i++) { //skip the first 2 uint16_t's of every packet, they're 4 header bytes if(i % PACKET_SIZE_UINT16 < 2) { continue; } //flip the MSB and LSB at the last second int temp = result[i*2]; result[i*2] = result[i*2+1]; result[i*2+1] = temp; value = frameBuffer[i]; if(value > maxValue) { maxValue = value; //count = value; } if(value < minValue) { minValue = value; //count = value; } column = i % PACKET_SIZE_UINT16 - 2; row = i / PACKET_SIZE_UINT16 ; } //std::cout<<minValue<<","<<maxValue<<"\n"<<endl; float diff = maxValueFlameThreshold - minValueFlameThreshold; float scale = 255/diff; QRgb color; for(int i=0;i<FRAME_SIZE_UINT16;i++) { if(i % PACKET_SIZE_UINT16 < 2) { continue; } value = (frameBuffer[i] - minValueFlameThreshold) * scale; //valueOut=value; const int *colormap = colormap_ironblack; //const int *colormap = colormap_rainbow; /* if(maxValue > 9000) { color = qRgb(colormap[(3*value)], colormap[(3*value+1)], colormap[(3*value+2)]); } else { color = qRgb(255, 255, 255); } */ color = qRgb(colormap[(3*value)], colormap[(3*value+1)], colormap[(3*value+2)]); column = (i % PACKET_SIZE_UINT16 ) - 2; row = i / PACKET_SIZE_UINT16; myImage.setPixel(column, row, color); } //lets emit the signal for update emit updateImage(myImage); outString=QString("test%1.png").arg(count); //outString+= std::to_string(count); //outString+=".png"; myImage.save(outString); count++; } //finally, close SPI port just bcuz SpiClosePort(0); std::exit(0); }
void SPIReader::Open(int spiPort) { _spiPort = spiPort; SpiOpenPort(_spiPort); }