Осциллограф Arduino Mega 2560

Вопрос или проблема

Я пытаюсь сделать небольшой осциллограф на плате Arduino Mega 2560. В следующем фрагменте кода клиента для ПК есть функция, которая обрабатывает полученные байты данных с образцов платы. Когда они отображаются, они правильные, но записываются в текстовый файл неправильно. Вместо этого в текстовом файле находятся последовательные числа от 1 до огромного значения. Где проблема в fprintf?

void receive_data(int fd, const char *filename, int num_channels, int mode) {
    FILE *file = fopen(filename, "w");
    if (!file) {
        perror("Ошибка при открытии файла");
        return;
    }
    uint8_t buffer[MAX_BUFFER_SIZE];
    int bytes_per_sample = num_channels * 3; // 1 байт синхронизации + 2 байта на канал
    int buffer_offset = 0;
    time_t start_time = time(NULL);
    //unsigned int sample_count = 0; // Счетчик образцов

    printf("Сэмплирование в течение 10 секунд...\n");

    while (time(NULL) - start_time < 10) {
        int bytes_read = read(fd, buffer + buffer_offset, sizeof(buffer) - buffer_offset);
        if (bytes_read > 0) {
            bytes_read += buffer_offset;
            int i = 0;
         while (i <= bytes_read - bytes_per_sample) {
            // Для каждого канала ищем байт синхронизации
            int sync_found = 1;
            for (int ch = 0; ch < num_channels; ch++) {
                if (buffer[i++] != 0xAA) {
                    sync_found = 0;
                    break;
                }
                // Читаем старший и младший байты для канала
                if (bytes_read - i < 2) {
                    // Недостаточно данных, обрабатываем смещение буфера
                    break;
                }
                uint8_t high_byte = buffer[i++];
                uint8_t low_byte = buffer[i++];
                uint16_t value = ((uint16_t)high_byte << 8) | low_byte;
                printf("%u ", value);
                fprintf(file, "%u", value);
                if (ch < num_channels - 1) {
                    fprintf(file, " ");
                }
            }
            if (!sync_found) {
                // Выравниваем буфер, если байт синхронизации не найден
                while (i < bytes_read && buffer[i] != 0xAA) {
                    i++;
                }
                buffer_offset = bytes_read - i;
                memmove(buffer, &buffer[i], buffer_offset);
                break;
            }
            printf("\n");
            fprintf(file, "\n");
            fflush(file);
         }
            // Обрабатываем оставшиеся байты в буфере
            if (i < bytes_read) {
                buffer_offset = bytes_read - i;
                memmove(buffer, &buffer[i], buffer_offset);
            } else {
                buffer_offset = 0;
            }
        } else if (bytes_read == 0) {
            usleep(1000); // Ждем 1мс
        } else {
            perror("Ошибка при чтении с последовательного порта");
            break;
        }
    }
    fclose(file);
}

Если необходимо, я могу показать другие части кода

Ответ или решение

Ваш вопрос связан с проблемой записи данных в текстовый файл из кода клиента, который получает данные от Arduino Mega 2560, используемой в качестве осциллографа. Из вашего описания видно, что данные, отображаемые на экране, корректны, но в текстовом файле вместо ожидаемых значений данных записываются последовательные числа. Давайте проанализируем ваш код и выявим потенциальные проблемы.

Возможные причины проблемы

  1. Форматирование данных в fprintf:
    Убедитесь, что fprintf(file, "%u", value); действительно корректно записывает значение и что вы не используете другие вызовы fprintf, которые могут перезаписывать значения в файле.

  2. Синхронизация данных:
    Проверка на синхронизированный байт может некорректно обрабатывать данные. Если данные не синхронизированы, это может привести к тому, что вы можете считывать старые, неверные значения.

  3. Правильное считывание данных:
    Проверьте, правильно ли считываются и обрабатываются байты из буфера. Возможно, вы неверно интерпретируете синхронизацию и сдвигаете указатель не в том месте.

Рекомендации по коду

Вот несколько изменений и улучшений, которые можно внести в ваш код:

  1. Проверка синхронизации:
    Убедитесь, что синхронизация выполняется корректно. Когда вы не находите синхронизированный байт (0xAA), вы должны пересчитывать положение в buffer.

  2. Корректное использование fprintf:
    Поместите fprintf в условие, чтобы убедиться, что данные действительно записываются после успешного чтения.

  3. Очистка буфера:
    Убедитесь, что в вашем буфере нет старых данных, когда вы перезаписываете значения.

Обновленный фрагмент кода может выглядеть следующим образом:

while (time(NULL) - start_time < 10) {
    int bytes_read = read(fd, buffer + buffer_offset, sizeof(buffer) - buffer_offset);
    if (bytes_read > 0) {
        bytes_read += buffer_offset;
        int i = 0;
        while (i <= bytes_read - bytes_per_sample) {
            int sync_found = 1;
            for (int ch = 0; ch < num_channels; ch++) {
                if (buffer[i++] != 0xAA) {
                    sync_found = 0;
                    break;
                }
                if (bytes_read - i < 2) {
                    break;
                }
                uint8_t high_byte = buffer[i++];
                uint8_t low_byte = buffer[i++];
                uint16_t value = ((uint16_t)high_byte << 8) | low_byte;
                printf("%u ", value);
                fprintf(file, "%u", value);
                if (ch < num_channels - 1) {
                    fprintf(file, " ");
                }
            }
            if (sync_found) {
                fprintf(file, "\n");
                printf("\n");
            } else {
                // Обработка несинхронизированных байтов
                while (i < bytes_read && buffer[i] != 0xAA) {
                    i++;
                }
                buffer_offset = bytes_read - i;
                memmove(buffer, &buffer[i], buffer_offset);
                break;
            }
        }
        if (i < bytes_read) {
            buffer_offset = bytes_read - i;
            memmove(buffer, &buffer[i], buffer_offset);
        } else {
            buffer_offset = 0;
        }
    } else if (bytes_read == 0) {
        usleep(1000);
    } else {
        perror("Ошибка при чтении с последовательного порта");
        break;
    }
}

Заключение

Попробуйте внести предложенные изменения и проверьте снова, записываются ли данные корректно в ваш текстовый файл. Убедитесь, что синхронизация функционирует правильно, и fprintf действительно выводит ожидаемые значения. Если проблема продолжает существовать, возможно, будет полезно отладить данные, чтобы убедиться, что они корректно отправляются с вашей Arduino.

Оцените материал
Добавить комментарий

Капча загружается...