Send files over UART

66 Views Asked by At

I am transferring 6 different files from my Windows PC to BeagleBone over UART communication. I have written receiving (BeagleBone) side C code to receive and store 6 files at the "/home/debian/NEW" location.

Also, I have written a script to send 6 files from PC to BeagleBone.

  1. BeagleBone side C code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>

#define UART_PORT "/dev/ttyS1"
#define BAUD_RATE B9600
#define UART_BUFFER_SIZE 8192

enum State {
    IDLE,
    FILENAME,
    DATA
};

char readByte(int uart_fd) {
    char byte;
    ssize_t bytesRead = read(uart_fd, &byte, 1);

    if (bytesRead < 0) {
        perror("Error reading from UART");
        exit(EXIT_FAILURE);
    }

    return byte;
}

void receiveAndStoreFilesOverUART(const char *folderPath) {
    int uart_fd = open(UART_PORT, O_RDWR | O_NOCTTY);
    struct termios uart_config;

    if (uart_fd < 0) {
        perror("Error opening UART port");
        exit(EXIT_FAILURE);
    }

    // Configure UART settings
    if (tcgetattr(uart_fd, &uart_config) < 0) {
        perror("Error getting UART configuration");
        close(uart_fd);
        exit(EXIT_FAILURE);
    }

    cfsetispeed(&uart_config, BAUD_RATE);
    cfsetospeed(&uart_config, BAUD_RATE);
    uart_config.c_cflag &= ~PARENB;
    uart_config.c_cflag &= ~CSTOPB;
    uart_config.c_cflag &= ~CSIZE;
    uart_config.c_cflag |= CS8;
    uart_config.c_cflag &= ~CRTSCTS;
    uart_config.c_cflag |= CREAD | CLOCAL;
    uart_config.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    uart_config.c_cc[VMIN] = 1;
    uart_config.c_cc[VTIME] = 0;

    if (tcsetattr(uart_fd, TCSANOW, &uart_config) < 0) {
        perror("Error setting UART configuration");
        close(uart_fd);
        exit(EXIT_FAILURE);
    }

    enum State state = IDLE;
    int finished = 0;
    char filenameBuffer[256];
    FILE *file = NULL;

    while (!finished) {
        char byte = readByte(uart_fd);

        switch (state) {
            case IDLE:
                if (byte == 0x01) {
                    state = FILENAME;
                    filenameBuffer[0] = '\0'; // Reset the filename buffer
                    printf("Entering FILENAME state\n");
                } else if (byte == 0x04) {
                    finished = 1;
                    printf("Entering IDLE state\n");
                }
                break;

            case FILENAME:
                if (byte == 0x02) {
                    state = DATA;
                    printf("Entering DATA state\n");
                } else if (byte == 0x04) {
                    finished = 1;
                    printf("Entering IDLE state\n");
                } else {
                    strncat(filenameBuffer, &byte, 1);
                }
                break;

            case DATA:
                if (byte == 0x03) {
                    if (file != NULL) {
                        fclose(file);
                        printf("File closed\n");
                        state = IDLE;
                    }
                } else if (byte == 0x04) {
                    if (file != NULL) {
                        fclose(file);
                        printf("File closed\n");
                    }
                    finished = 1;
                } else {
                    if (file == NULL) {
                        // Open the file for writing if not already open
                        snprintf(filenameBuffer, sizeof(filenameBuffer), "%s/%s", folderPath, filenameBuffer);
                        file = fopen(filenameBuffer, "wb");
                        if (file == NULL) {
                            perror("Error opening file");
                            finished = 1;
                        }
                    }
                    if (file != NULL) {
                        fwrite(&byte, 1, 1, file);
                    }
                }
                break;
        }
    }

    close(uart_fd);
}

int main(void) {
    const char *storageFolderPath = "/home/debian/NEW";
    receiveAndStoreFilesOverUART(storageFolderPath);
    printf("Finished receiving\n");
    return 0;
}
  1. Windows (Transmitting) side Python code
import serial
import time

def send_file(serial_port, file_name):
    try:
        # Send start marker (0x01)
        serial_port.write(bytes([0x01]))

        # Send filename
        serial_port.write(file_name.encode())

        # Send filename marker (0x02)
        serial_port.write(bytes([0x02]))

        # Open the file for reading
        with open(f"C:/Users/HP/OneDrive/Desktop/DRS_Database/{file_name}", "rb") as file:
            # Send file data marker (0x03)
            serial_port.write(bytes([0x03]))

            # Send file data
            file_data = file.read()
            serial_port.write(file_data)

        print(f"{file_name} sent successfully.")
    except FileNotFoundError:
        print(f"File {file_name} not found.")

def send_files(serial_port, filenames):
    for file_name in filenames:
        send_file(serial_port, file_name)
        time.sleep(1)  # Add a delay to allow time for the BeagleBone to process the data

    # Send finish marker (0x04) after all files are sent
    serial_port.write(bytes([0x04]))

# Open the serial port for communication
ser = serial.Serial('COM11', 9600)  # COM port and baud rate

# List of file names to send
file_names = ["DIA_ID.TXT", "OP_REC.TXT", "DIA_REC.TXT", "PAT_REC.TXT", "JAR_REC.TXT", "PRO_REC.TXT"]

# Send files
send_files(ser, file_names)

# Close the serial port
ser.close()`

All file data is stored in one folder: /home/debian/NEW. No separate files are stored.

The content of files that I send from my Windows PC using a Python script is stored in a folder. It does not generate separate files.

0

There are 0 best solutions below