Потеря данных СОМ порта
- Войдите на сайт для отправки комментариев
Доброго времени суток!
Есть задача чтения потока данных, поступающих из СОМ-порта.
Данные сохраняются в файлы размером не более 1 МБ. При этом, чтобы имена файлов не повторялись, при формировании их имени осуществляется привязка к внутреннему времени, формируемому платой с микросхемой DS1302.
Имя файла ММДДЧЧММ.dat (месяц-дата-часы-минуты).
Программа нормально компилируется. Файлы с данными пишутся.
Но это прелюдия.
Основная проблема состоит в том, что при чтении потока происходит потеря байт.
Дело в том, что в поток внедрены метки, повторяющиеся через 6 байт (6 байт - длина кадра, информационной последовательности). По ним можно отследить пропуски кадров.
Я вижу, что записываются 16-17 кадров (96-112 байт), потом идет пропуск до 32-34 кадров (192-204 байт).
Потом данные опять записываются. Потом опять пропуск.
Кодприведен ниже:
#include <WProgram.h>
#include <Wire.h>
#include <SD.h>
#include <stdio.h>
#include <DS1302.h>
const int chipSelect = 4; // On the Ethernet Shield, CS is pin 4
long volume=0; // Размер файла с данными
boolean flag = true; // Разрешение формирования нового имени файла
int incomingByte = 0; // переменная для хранения байта данных,
//принятых по последовательному интерфейсу
File dataFile;
char * szNewFileName;
char data[100];
char massive[100];
int i=0;
//Исходные данные времени для имени файла
String HR; //Часы
String MIN; //Минуты
String DATE; //День (число)
String MTH; //Месяц
// Предустановка микросхемы DS1302 chip
// Init the DS1302 (2->5, 3->6, 4->7)
DS1302 rtc(5, 6, 7);
// Init a Time-data structure
Time t;
void setup() {
Serial.begin(9600); // открываем последовательный порт
// задаем скорость передачи данных 9600 бод
Serial.print("Initializing SD card..."); // ВЫВОД ИНФОРМАЦИИ ОБ ИНИЦИАЛИЗАЦИИ КАРТЫ ПАМЯТИ
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect))
{
Serial.println("Card failed, or not present"); // ВЫВОД ИНФОРМАЦИИ ОБ ИНИЦИАЛИЗАЦИИ КАРТЫ ПАМЯТИ
// don't do anything more:
return;
}
Serial.println("card initialized."); // ВЫВОД ИНФОРМАЦИИ ОБ ИНИЦИАЛИЗАЦИИ КАРТЫ ПАМЯТИ
}
void loop() {
if (flag==true)
{
// Get data from the DS1302
t = rtc.getTime();
//ФОРМИРУЕМ ИМЯ ФАЙЛА
if (t.min < 10)
MIN = "0" + String(t.min, DEC);
else
MIN = String(t.min, DEC);
if (t.hour < 10)
HR = "0" + String(t.hour, DEC);
else
HR = String(t.hour, DEC);
if (t.date < 10)
DATE = "0" + String(t.date, DEC);
else
DATE = String(t.date, DEC);
if (t.mon < 10)
MTH = "0" + String(t.mon, DEC);
else
MTH = String(t.mon, DEC);
String stroke = MTH+DATE+HR+MIN+".wg";
char charVar[12];
stroke.toCharArray(charVar, 12);
char new_data[12];
strcpy(new_data,charVar);
szNewFileName = new_data;
flag=false;
}
// отправляем данные только после их получения:
if (Serial.available() > 0)
{
dataFile = SD.open(szNewFileName, FILE_WRITE);
volume = dataFile.size();
if (volume<1000000)
{
// считываем принятый байт:
Serial.readBytes((char*)data,100);
//Записываем данные в файл
dataFile.write(data,sizeof(data));
}
else
{flag=true;}
dataFile.close();
}
}
Использую Arduino UNO. Скорость входного потока - 9600 кб/с.
Подключал источник данных к компу, там проблем нет.
Не могу понять: то ли идет переполнение буфера, то ли нужно выставлять правильно таймеры.
Может кто подскажет: это затык по железу (что, на мой взгляд, маловероятно) либо корявый код?
P.S.: Размер буфера варьировал. Не помогло.
С какой частотой твои "кадры" идут. Чую, что ардуина тупо не успевает всё записать.
Попробуй вместо if (Serial.available() > 0) сделать while, чтобы выбрать все данные из порта и не тягать лишний раз код по формированию имени файла.