First fully working camera capture, transfer and receive!

This commit is contained in:
Adam Prochazka
2023-04-07 21:34:59 +02:00
parent 5132e015bd
commit 2007a5de10
11 changed files with 146 additions and 310 deletions

View File

@ -33,7 +33,6 @@ int Displayer::renderWindow(){
int Displayer::imageFromVector(std::vector<uint8_t>* img){
imageRwops = SDL_RWFromMem(img->data(), img->size());
return 0;
}

View File

@ -1,138 +0,0 @@
#include "ImageView.hpp"
int createWindow(SDL_Window** windowPtr){
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to initialize SDL: %s", SDL_GetError());
return 1;
}
// Create a window
SDL_Window* window = SDL_CreateWindow("Image Viewer", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1920, 1080, SDL_WINDOW_SHOWN);
if (!window) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create window: %s", SDL_GetError());
SDL_Quit();
return 1;
}
*windowPtr = window;
return 0;
}
int renderWindow(SDL_Renderer** rendererPtr, SDL_Window* window){
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);
if (!renderer) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create renderer: %s", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
*rendererPtr = renderer;
return 0;
}
int imageFromVector(SDL_RWops** imageRwopsPtr, std::vector<uint8_t>* img){
SDL_RWops* imageRwops = SDL_RWFromMem(img->data(), img->size());
*imageRwopsPtr = imageRwops;
return 0;
}
int createImageSurface(SDL_Surface** imageSurfacePtr, SDL_RWops* imageRwops){
SDL_Surface* imageSurface = IMG_Load_RW(imageRwops, 0);
if (!imageSurface) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to load image: %s", IMG_GetError());
//SDL_DestroyRenderer(renderer);
//SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
*imageSurfacePtr = imageSurface;
return 0;
}
int textureFromSurface(SDL_Texture** texturePtr, SDL_Renderer** renderer, SDL_Surface** imageSurface){
SDL_Texture* texture = SDL_CreateTextureFromSurface(*renderer, *imageSurface);
SDL_FreeSurface(*imageSurface);
if (!texture) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create texture: %s", SDL_GetError());
//SDL_DestroyRenderer(renderer);
//SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
*texturePtr = texture;
return 0;
}
int windowDestroy(SDL_Window** windowPtr, SDL_Texture** texturePtr, SDL_Renderer** rendererPtr){
SDL_DestroyTexture(*texturePtr);
SDL_DestroyRenderer(*rendererPtr);
SDL_DestroyWindow(*windowPtr);
SDL_Quit();
return 0;
}
int windowLoop(SDL_Renderer** rendererPtr,
int* currentBufferIndex,
std::mutex& currentBufferIndexMutex,
SDL_Texture** texturePtr1,
SDL_Texture** texturePtr2,
SDL_Texture** texturePtr3){
bool quit = false;
while (!quit) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
quit = true;
}
}
SDL_RenderClear(*rendererPtr);
currentBufferIndexMutex.lock();
switch(*currentBufferIndex) {
case 0:
SDL_RenderCopy(*rendererPtr, *texturePtr1, NULL, NULL);
break;
case 1:
SDL_RenderCopy(*rendererPtr, *texturePtr2, NULL, NULL);
break;
case 2:
SDL_RenderCopy(*rendererPtr, *texturePtr3, NULL, NULL);
break;
default:
std::cout << "error 18" << std::endl;
break;
}
currentBufferIndexMutex.unlock();
SDL_RenderPresent(*rendererPtr);
}
return 0;
}
int vectorToTexture(SDL_Renderer** rendererPtr,
SDL_RWops** imageRwopsPtr,
SDL_Surface** imageSurfacePtr,
SDL_Texture** texturePtr,
std::vector<uint8_t>* img){
imageFromVector(imageRwopsPtr, img);
createImageSurface(imageSurfacePtr, *imageRwopsPtr);
textureFromSurface(texturePtr, rendererPtr, imageSurfacePtr);
return 0;
}
int flipThroughTextures(int * currentTexture, std::mutex& currentTextureMutex){
while(1){
currentTextureMutex.lock();
*currentTexture = *currentTexture + 1;
*currentTexture %=3;
currentTextureMutex.unlock();
}
}

View File

@ -1,23 +0,0 @@
#include "main.hpp"
int createWindow(SDL_Window** windowPtr);
int renderWindow(SDL_Renderer** rendererPtr, SDL_Window* window);
int imageFromVector(SDL_RWops** imageRwopsPtr, std::vector<uint8_t>* img);
int createImageSurface(SDL_Surface** imageSurfacePtr, SDL_RWops* imageRwops);
int textureFromSurface(SDL_Texture** texturePtr, SDL_Renderer** renderer, SDL_Surface** imageSurface);
int windowDestroy(SDL_Window** windowPtr, SDL_Texture** texturePtr, SDL_Renderer** rendererPtr);
int windowLoop( SDL_Renderer** rendererPtr,
int* currentBufferIndex,
std::mutex& currentBufferIndexMutex,
SDL_Texture** texturePtr1,
SDL_Texture** texturePtr2,
SDL_Texture** texturePtr3);
int vectorToTexture(SDL_Renderer** rendererPtr,
SDL_RWops** imageRwopsPtr,
SDL_Surface** imageSurfacePtr,
SDL_Texture** texturePtr,
std::vector<uint8_t>* img);
int flipThroughTextures(int * currentTexture, std::mutex& currentTextureMutex);

View File

@ -11,7 +11,7 @@ void Receiver::printHex(unsigned char value) {
void Receiver::openStream(){
while(1){
// Open the CDC device file for reading
cdcFile = open("/dev/ttyACM0", O_RDWR | O_NOCTTY);
cdcFile = open("/dev/ttyACM1", O_RDWR | O_NOCTTY);
if(cdcFile == -1){
std::cerr << "Failed to open CDC device file" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
@ -50,13 +50,12 @@ int Receiver::initSerial(){
}
std::cout << "OPENED!" << std::endl;
//tcflush(cdcFile, TCIFLUSH);
return 1;
}
int Receiver::readCdcData(unsigned char (*character)[10]) {
memset(*character, 0x00, 10);
int bytesRead = read(cdcFile, character, 10);
int Receiver::readCdcData(uint8_t (*character)[50]) {
memset(*character, 0x00, 50);
int bytesRead = read(cdcFile, character, 50);
if (bytesRead == -1) {
std::cerr << "Error in read" << std::endl;
return -1;
@ -65,18 +64,22 @@ int Receiver::readCdcData(unsigned char (*character)[10]) {
std::cerr << "Error in read" << std::endl;
return -1;
}
for(int i = 0; i<10; i++)
/* PRINT WHAT IS RECEIVED
for(int i = 0; i<50; i++)
{
printHex((*character)[i]);
//std::cout << unsigned(character[i]);
//std::cout << " ";
std::cout << " ";
}
std::cout << std::endl;
std::cout << std::endl << std::endl;
*/
return 0;
}
int Receiver::simulateRead(unsigned char (*character)[10]){
memset(*character, 0x00, 10);
int Receiver::simulateRead(unsigned char (*character)[50]){
memset(*character, 0x00, 50);
int firstLen = (int)t1.size();
int secondLen = (int)t2.size();
@ -90,7 +93,7 @@ int Receiver::simulateRead(unsigned char (*character)[10]){
vecId = 2;
}
for(int i=0; i<10; i++){
for(int i=0; i<50; i++){
if(vecId == 1){
if(simulateIdx > firstLen){
(*character)[i] = 0x00;
@ -105,7 +108,6 @@ int Receiver::simulateRead(unsigned char (*character)[10]){
(*character)[i] = 0x00;
}
else{
//printHex(t1[simulateIdx-firstLen]);
(*character)[i] = t2[simulateIdx-firstLen-1];
simulateIdx++;
}
@ -116,30 +118,50 @@ int Receiver::simulateRead(unsigned char (*character)[10]){
}
int Receiver::fillBuffer(){
unsigned char character[10];
unsigned char character[50];
std::vector<uint8_t> tempVec{};
Receiver::readCdcData(&character);
//Receiver::simulateRead(&character);
int i = -1;
do {
Receiver::readCdcData(&character);
i = Receiver::findStart(&character);
}
while(i == -1);
while(Receiver::findStart(&character) == -1) Receiver::readCdcData(&character); //Receiver::simulateRead(&character);
tempVec.insert(tempVec.end(), character, character + sizeof(character));
tempVec.insert(tempVec.end(), &character[i], character + sizeof(character));
i = -1;
do{
Receiver::readCdcData(&character);
//Receiver::simulateRead(&character);
i = findEnd(&character);
if(i == -1)
tempVec.insert(tempVec.end(), character, character + sizeof(character));
}
while(findEnd(&character) == -1);
while(i == -1);
tempVec.insert(tempVec.end(), character, character + i + 2);
//////////// SAVE FRAMES TO FILES
/*
std::ofstream outfile(std::to_string(debugFileIdx) + ".jpg", std::ios::out | std::ios::binary);
if (!outfile.is_open()) {
std::cerr << "Failed to create file " << debugFileIdx << ".jpg" << std::endl;
return 1;
}
outfile.write(reinterpret_cast<const char*>(tempVec.data()), tempVec.size());
outfile.close();
debugFileIdx++;
*/
////////////
currentBufferIndexMutex.lock();
currentBufferIndex++;
currentBufferIndex %= 3;
currentBufferIndexMutex.unlock();
std::cout << "=" << currentBufferIndex;
switch(currentBufferIndex){
case 0:
buffer1 = tempVec;
@ -154,8 +176,6 @@ int Receiver::fillBuffer(){
std::cout << "error 25" << std::endl;
}
//for(int i=0; i<(int)tempVec.size(); i++) printHex(tempVec[i]);
//std::cout << std::endl;
return 1;
}
@ -178,36 +198,39 @@ void Receiver::bufferToDisplay(){
}
}
int Receiver::findSequence(unsigned char (*str)[10], unsigned char ch1, unsigned char ch2){
void Receiver::initTextures(){
dis->vectorToTexture(&buffer_initial);
dis->vectorToTexture(&buffer_initial);
dis->vectorToTexture(&buffer_initial);
dis->vectorToTexture(&buffer_initial);
}
int Receiver::findSequence(unsigned char (*str)[50], unsigned char ch1, unsigned char ch2){
if(sequenceEndedFF){
sequenceEndedFF = 0;
if((*str)[0] == ch2){
return 0;
}
}
for(int i=0; i<10; i++){
if((*str)[i] == ch1 && i < 10){
for(int i=0; i<50; i++){
if((*str)[i] == ch1 && i < 50){
if((*str)[i+1] == ch2){
return i;
}
}
}
if((*str)[9] == 0xFF) sequenceEndedFF = 1;
if((*str)[49] == 0xFF) sequenceEndedFF = 1;
return -1;
}
int Receiver::findStart(unsigned char (*str)[10]){
int Receiver::findStart(unsigned char (*str)[50]){
int res = findSequence(str, 0xFF, 0xD8);
//if(res != -1)std::cout << "s";
return res;
//return findSequence(str, 0xFF, 0xD8);
}
int Receiver::findEnd(unsigned char (*str)[10]){
int Receiver::findEnd(unsigned char (*str)[50]){
int res = findSequence(str, 0xFF, 0xD9);
//if(res != -1)std::cout << "f";
return res;
//return findSequence(str, 0xFF, 0xD9);
}

View File

@ -10,6 +10,40 @@ class Receiver{
struct termios tty;
int currentBufferIndex = 0;
std::mutex currentBufferIndexMutex;
std::vector<uint8_t> buffer_initial{
0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11,
0x08, 0x00, 0x60, 0x00, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff,
0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0x92, 0x8a, 0x00,
0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45,
0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89,
0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad,
0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25,
0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3,
0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1,
0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00,
0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45,
0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89,
0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad,
0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25,
0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3,
0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1,
0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00,
0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45,
0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89,
0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad,
0x4c, 0x84, 0xa2, 0xb3, 0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25,
0x15, 0x98, 0xc6, 0xd1, 0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3,
0x19, 0x62, 0x8a, 0x00, 0x4a, 0x2b, 0x31, 0x89, 0x45, 0x6a, 0x64, 0x25, 0x15, 0x98, 0xc6, 0xd1,
0x5b, 0x1b, 0x09, 0x45, 0x66, 0x31, 0x28, 0xad, 0x4c, 0x84, 0xa2, 0xb3, 0x19, 0xff, 0xd9
};
std::vector<uint8_t> buffer1;
std::vector<uint8_t> buffer2;
std::vector<uint8_t> buffer3;
@ -17,21 +51,23 @@ class Receiver{
int sequenceEndedFF = 0;
int simulateIdx = 0;
int debugFileIdx = 0;
public:
Receiver(Displayer *displayerPtr);
void openStream();
int initSerial();
int readCdcData(unsigned char (*character)[10]);
int readCdcData(unsigned char (*character)[50]);
void printHex(unsigned char value);
int fillBuffer();
void bufferToDisplay();
void initTextures();
int findSequence(unsigned char (*str)[10], unsigned char ch1, unsigned char ch2);
int findStart(unsigned char (*str)[10]);
int findEnd(unsigned char (*str)[10]);
int findSequence(unsigned char (*str)[50], unsigned char ch1, unsigned char ch2);
int findStart(unsigned char (*str)[50]);
int findEnd(unsigned char (*str)[50]);
int simulateRead(unsigned char (*character)[10]);
int simulateRead(unsigned char (*character)[50]);
};

View File

@ -1,70 +0,0 @@
#include "Transfer.hpp"
void printHex(unsigned char value) {
std::cout << "0x" << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(value);
}
void openStream(int *cdcFile){
while(1){
// Open the CDC device file for reading
*cdcFile = open("/dev/ttyACM1", O_RDWR | O_NOCTTY);
if (*cdcFile != -1) {
return;
}
std::cerr << "Failed to open CDC device file" << std::endl;
}
}
int initSerial(struct termios *tty, int *cdcFile){
memset(tty, 0, sizeof(*tty));
if (tcgetattr(*cdcFile, tty) != 0) {
std::cerr << "Error in tcgetattr" << std::endl;
return -1;
}
tcflush(*cdcFile, TCIFLUSH);
cfsetospeed(tty, B115200);
cfsetispeed(tty, B115200);
tty->c_cflag |= (CLOCAL | CREAD);
tty->c_cflag &= ~CSIZE;
tty->c_cflag |= CS8;
tty->c_cflag &= ~PARENB;
tty->c_cflag &= ~CSTOPB;
tty->c_cflag &= ~CRTSCTS;
tty->c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
tty->c_iflag &= ~(IXON | IXOFF | IXANY);
tty->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL);
tty->c_oflag &= ~OPOST;
tty->c_cc[VMIN] = 1;
tty->c_cc[VTIME] = 0;
if (tcsetattr(*cdcFile, TCSANOW, tty) != 0) {
std::cerr << "Error in tcsetattr" << std::endl;
return -1;
}
std::cout << "OPENED!" << std::endl;
tcflush(*cdcFile, TCIFLUSH);
return 1;
}
int readCdcData(int * cdcFile) {
unsigned char character[10];
memset(character, 0x00, 10);
// Read data from the CDC device file into the buffer
int bytesRead = read(*cdcFile, character, 10);
if (bytesRead == -1) {
std::cerr << "Error in read" << std::endl;
return -1;
}
for(int i = 0; i<10; i++)
{
printHex(character[i]);
//std::cout << unsigned(character[i]);
std::cout << " ";
}
std::cout << std::endl;
std::cout << std::endl;
return bytesRead;
}

View File

@ -1,6 +0,0 @@
#include "main.hpp"
void printHex(unsigned char value);
void openStream(int *cdcFile);
int initSerial(struct termios *tty, int *cdcFile);
int readCdcData(int * cdcFile);

View File

@ -5,29 +5,23 @@
#include "Displayer.hpp"
#endif
#include "Transfer.hpp"
int cdcFile;
struct termios tty;
int cdcFile;
void readLoop(Receiver ** receiverPtr){
std::cout << "1" << std::endl;
(*receiverPtr)->openStream();
std::cout << "2" << std::endl;
(*receiverPtr)->initSerial();
std::cout << "3" << std::endl;
while (true) {
unsigned char character[10];
unsigned char character[50];
(*receiverPtr)->readCdcData(&character);
if((*receiverPtr)->findStart(&character) != -1)
{std::cout << "start" << std::endl;}
else if((*receiverPtr)->findEnd(&character) != -1)
{std::cout << "stop" << std::endl;}
else{
std::cout << "-";
std::cout << "-";
}
std::this_thread::sleep_for(std::chrono::milliseconds(20));
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
close(cdcFile);
@ -42,7 +36,7 @@ void receiverLoop(Receiver ** receiverPtr){
while(1){
(*receiverPtr)->fillBuffer();
(*receiverPtr)->bufferToDisplay();
std::this_thread::sleep_for(std::chrono::milliseconds(20));
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
}
@ -51,12 +45,15 @@ int main()
Displayer dis;
Receiver *rec = new Receiver(&dis);
/*
dis.createWindow();
dis.renderWindow();
rec->openStream();
rec->initSerial();
rec->initTextures();
rec->fillBuffer();
rec->bufferToDisplay();
@ -65,7 +62,7 @@ int main()
dis.windowLoop();
t1.join();
*/
readLoop(&rec);
return 0;

View File

@ -12,4 +12,5 @@
#include <SDL2/SDL_image.h>
#include <thread>
#include <chrono>
#include <mutex>
#include <mutex>
#include <fstream>