Потеря данных СОМ порта
- Войдите на сайт для отправки комментариев
Доброго времени суток!
Есть задача чтения потока данных, поступающих из СОМ-порта.
Данные сохраняются в файлы размером не более 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, чтобы выбрать все данные из порта и не тягать лишний раз код по формированию имени файла.