Временные метки данных AnalogBinLogger

Я хотел бы поставить метку времени для данных, собранных с AnalogBinLogger.ino, на Arduino Uno. В скетче используются 512-байтовые буферы, и я читал, что запись данных фрагментами по 512 байт «лучше» с точки зрения задержки записи.

Скетч использует эту структуру для буферов:

// Блок данных для режима 10-битного АЦП.
const size_t DATA_DIM16 = 254;
struct block16_t {
  unsigned short count;    // количество значений данных
  unsigned short overrun;  // количество переполнений с момента последнего блока
  unsigned short data[DATA_DIM16];
};

Поскольку я хочу добавить временные метки типа unsigned long, мне придется изменить структуру следующим образом:

// Блок данных для режима 10-битного АЦП.
const size_t DATA_DIM16 = 254;
struct block16_t {
  unsigned short count;    // количество значений данных
  unsigned short overrun;  // количество переполнений с момента последнего блока
  unsigned short data[DATA_DIM16];
  unsigned long  milli[DATA_DIM16]; // время в миллисекундах
};

Теперь эта структура превышает 512 байт и составляет 1528 байт. Из-за отсутствия достаточного количества свободного стека моя программа не запускается (sketch сообщает, что размер FreeStack составляет 1135 байт). Как мне это сделать?

PS: Моя основная проблема заключается в том, чтобы добиться синхронизации времени между несколькими устройствами Arduino для сбора данных, которые осуществляют выборку с высокой частотой, например 8 кГц. Из-за дрейфа часов, даже если я синхронизирую время начала, временные метки, собранные впоследствии, не будут относиться друг к другу. Поэтому я планирую, чтобы мастер Arduino регулярно отправлял свое время остальным.

, 👍1


2 ответа


1

Простое решение:

const size_t DATA_DIM16 = 84;
struct block16_t {
  unsigned short count;    // количество значений данных
  unsigned short overrun;  // количество переполнений с момента последнего блока
  unsigned short data[DATA_DIM16];
  unsigned long  milli[DATA_DIM16]; // время в миллисекундах
  unsigned long padding;   // дополнить до 512 байт
};

Теперь предлагаю еще раз подумать о своих требованиях. Ты действительно нужна 32-битная метка времени для каждой точки данных? Если они близко расположены со временем должно быть достаточно 16-битной или даже 8-битной метки времени. Вы могли бы поставить полную 32-битную метку времени в начале каждого блока, тогда только 8-битные метки времени для каждой точки данных. Это позволит вам хранить 168 сэмплов на блок. Вы даже можете упаковать 6-битную метку времени с помощью образец данных в uint16_t и иметь 252 образца на блок.

,

1

Запись фрагментами по 512 байт выполняется библиотеками SD, поэтому вы можете положиться на этот слой и просто записывать и сохранять отдельные события

struct block_t {
  uint32_t  milli; // время в миллисекундах
  uint16_t data;
  uint8_t  overrun;  // состояние переполнения с момента последнего блока
};

Я не знаю ваш AnalogBinLogger.ino. В других обстоятельствах такого ограничения в 512 байт нет, но есть общее и строгое ограничение на ОЗУ. (Вы можете уменьшить DATA_DIM, чтобы сделать его безопасным)

,

Насколько я понимаю, 512-байтовый буфер был выбран из-за его эффективности, что является важным соображением, когда вы пытаетесь регистрировать данные с высокой скоростью., @Edgar Bonet

https://github.com/greiman/SdFat/blob/master/examples/AnalogBinLogger/AnalogBinLogger.ino — интересный пример. Спасибо @Эдгар и Харини, @DataFiddler