Вопрос или проблема
Я пытаюсь сделать небольшой осциллограф на плате 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, используемой в качестве осциллографа. Из вашего описания видно, что данные, отображаемые на экране, корректны, но в текстовом файле вместо ожидаемых значений данных записываются последовательные числа. Давайте проанализируем ваш код и выявим потенциальные проблемы.
Возможные причины проблемы
-
Форматирование данных в
fprintf
:
Убедитесь, чтоfprintf(file, "%u", value);
действительно корректно записывает значение и что вы не используете другие вызовыfprintf
, которые могут перезаписывать значения в файле. -
Синхронизация данных:
Проверка на синхронизированный байт может некорректно обрабатывать данные. Если данные не синхронизированы, это может привести к тому, что вы можете считывать старые, неверные значения. -
Правильное считывание данных:
Проверьте, правильно ли считываются и обрабатываются байты из буфера. Возможно, вы неверно интерпретируете синхронизацию и сдвигаете указатель не в том месте.
Рекомендации по коду
Вот несколько изменений и улучшений, которые можно внести в ваш код:
-
Проверка синхронизации:
Убедитесь, что синхронизация выполняется корректно. Когда вы не находите синхронизированный байт (0xAA
), вы должны пересчитывать положение вbuffer
. -
Корректное использование
fprintf
:
Поместитеfprintf
в условие, чтобы убедиться, что данные действительно записываются после успешного чтения. -
Очистка буфера:
Убедитесь, что в вашем буфере нет старых данных, когда вы перезаписываете значения.
Обновленный фрагмент кода может выглядеть следующим образом:
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.