Вывод данных

Katbert
Offline
Зарегистрирован: 04.06.2018

Есть задача выводить данные с датчика акселерометра ADXL345 в файл на ПК. Вывожу через Serial.print и замеряю время. Получается, что при скорости 115200 бод выводится около 400 значений в секунду. Этого для моих задач мало. Интересуют частоты 1000-1200 Hz, поэтому нужно получать больше 2500 измерений в секунду.  Характеристики ADXL345 и Arduino позволяют это сделать. Ограничением, как я понял, является Serial.print. 

Существует ли еще какой то способ ускорить вывод данных по последовательному порту? 

Буду рад любой помощи!

    

ToRcH2565
Offline
Зарегистрирован: 16.05.2015

Семейство алгоритмов LZ вам может помоч.... =)

b707
Offline
Зарегистрирован: 26.05.2017

Katbert, выводите командой Serial.write в бинарном виде. На скорости 115200 вы теоретически сможете вывести порядка 5000 значений типа int в секунду

Katbert
Offline
Зарегистрирован: 04.06.2018

Спасибо! Готовых библиотек по сжатию данных сходу не нашел. Попробую сам разобраться. 

В принципе у меня нет необходимости получать данные в режиме реального времени. Может ли ускорить процесс запись данных на sd карту?

 

Katbert
Offline
Зарегистрирован: 04.06.2018

b707 пишет:

Katbert, выводите командой Serial.write в бинарном виде. На скорости 115200 вы теоретически сможете вывести порядка 5000 значений типа int в секунду

С датчика получаю значения float. Попробую преобразовать и прогнать через Serial.write. Отпишусь, что получится. Спасибо!

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

И скетч не забывайте выкладывать, когда вопросы задаёте.

Мне вот, например, интересно Вы чем ситаете данные с датчика. Если I2C, так узкое горо именно он, а вовсе не uart.

Ну, и вообще, обсуждать что-то без скетча - занятие бессмысленное.

А тот все уже свои хрустальные шары порасчехляли - расслабились, пока Великого и Ужасного нет.

SLKH
Offline
Зарегистрирован: 17.08.2015

Katbert пишет:

Спасибо! Готовых библиотек по сжатию данных сходу не нашел.

у вас не текст, а куча числовых данных. не особо-то они жмутся.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

SLKH пишет:

Katbert пишет:

Спасибо! Готовых библиотек по сжатию данных сходу не нашел.

у вас не текст, а куча числовых данных. не особо-то они жмутся.

Это зависит от, что называется. "Сжать" - возможно можно, при анализе входного числового ряда вполне может оказаться, что есть некая закономерность, позволяющая отбросить какие-то части потока байт, заменив их битами (или вовсе обойдясь без замены - просто отбросить). Вон, в SMS есть семибитная кодировка - с 8 байт по байтику экономят ;)

Katbert
Offline
Зарегистрирован: 04.06.2018

ЕвгенийП пишет:

И скетч не забывайте выкладывать, когда вопросы задаёте.

Мне вот, например, интересно Вы чем ситаете данные с датчика. Если I2C, так узкое горо именно он, а вовсе не uart.

 

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);


void displaySensorDetails(void)
{
  sensor_t sensor;
  accel.getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" m/s^2");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" m/s^2");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" m/s^2");  
  Serial.println("------------------------------------");
  Serial.println("");
  delay(500);
}

void displayDataRate(void)
{
  Serial.print  ("Data Rate:    "); 
  
  switch(accel.getDataRate())
  {
    case ADXL345_DATARATE_3200_HZ:
      Serial.print  ("3200 "); 
      break;
    case ADXL345_DATARATE_1600_HZ:
      Serial.print  ("1600 "); 
      break;
    case ADXL345_DATARATE_800_HZ:
      Serial.print  ("800 "); 
      break;
    case ADXL345_DATARATE_400_HZ:
      Serial.print  ("400 "); 
      break;
    case ADXL345_DATARATE_200_HZ:
      Serial.print  ("200 "); 
      break;
    case ADXL345_DATARATE_100_HZ:
      Serial.print  ("100 "); 
      break;
    case ADXL345_DATARATE_50_HZ:
      Serial.print  ("50 "); 
      break;
    case ADXL345_DATARATE_25_HZ:
      Serial.print  ("25 "); 
      break;
    case ADXL345_DATARATE_12_5_HZ:
      Serial.print  ("12.5 "); 
      break;
    case ADXL345_DATARATE_6_25HZ:
      Serial.print  ("6.25 "); 
      break;
    case ADXL345_DATARATE_3_13_HZ:
      Serial.print  ("3.13 "); 
      break;
    case ADXL345_DATARATE_1_56_HZ:
      Serial.print  ("1.56 "); 
      break;
    case ADXL345_DATARATE_0_78_HZ:
      Serial.print  ("0.78 "); 
      break;
    case ADXL345_DATARATE_0_39_HZ:
      Serial.print  ("0.39 "); 
      break;
    case ADXL345_DATARATE_0_20_HZ:
      Serial.print  ("0.20 "); 
      break;
    case ADXL345_DATARATE_0_10_HZ:
      Serial.print  ("0.10 "); 
      break;
    default:
      Serial.print  ("???? "); 
      break;
  }  
  Serial.println(" Hz");  
}

void displayRange(void)
{
  Serial.print  ("Range:         +/- "); 
  
  switch(accel.getRange())
  {
    case ADXL345_RANGE_16_G:
      Serial.print  ("16 "); 
      break;
    case ADXL345_RANGE_8_G:
      Serial.print  ("8 "); 
      break;
    case ADXL345_RANGE_4_G:
      Serial.print  ("4 "); 
      break;
    case ADXL345_RANGE_2_G:
      Serial.print  ("2 "); 
      break;
    default:
      Serial.print  ("?? "); 
      break;
  }  
  Serial.println(" g");  
}

void setup(void) 
{
#ifndef ESP8266
  while (!Serial); // for Leonardo/Micro/Zero
#endif


int count;

  Serial.begin(115200);
  Serial.println("Accelerometer Test"); Serial.println("");
  
  /* Initialise the sensor */
  if(!accel.begin())
  {
    /* There was a problem detecting the ADXL345 ... check your connections */
    Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
    while(1);
  }

  /* Set the range to whatever is appropriate for your project */
  accel.setRange(ADXL345_RANGE_16_G);

  accel.setDataRate(ADXL345_DATARATE_800_HZ);
  
  /* Display some basic information on this sensor */
  displaySensorDetails();
  
  /* Display additional settings (outside the scope of sensor_t) */
  displayDataRate();
  displayRange();
  Serial.println("");
}

void loop(void) 
{
  /* Get a new sensor event */ 
  
  sensors_event_t event; 
  accel.getEvent(&event);
 
  /* Display the results (acceleration is measured in m/s^2) */
 
  Serial.print(event.acceleration.x);
  Serial.print("  ");
  Serial.println(millis());
 
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, так я  и думал. Вы читаете датчик через I2C - забудьте о нужных Вам скоростях. Просто забудьте. Ищите другое решение. Например, этот датчик умеет отдавать свои данные по SPI. Это ближе к делу.

sadman41
Offline
Зарегистрирован: 19.10.2016

Я i2c на бешенных скоростях не работаю, но там, разве, не считается нормой 100kHz на шине? 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sadman41 пишет:

Я i2c на бешенных скоростях не работаю, но там, разве, не считается нормой 100kHz на шине? 

Да, мало ли, что где считается. Мы же работаем с конкретным датчиком и его реализацией I2C, а не c абстракцией. А по конкретному датчику см. даташит, стр 18, правый столбец, первый абзац сверху. Не попёрло ТС с 2500 измерений :(

sadman41
Offline
Зарегистрирован: 19.10.2016

А, ну тогда понятно, что не сама I2C виновата, а датчик на ней. Вижу на стр.15, что полторы тыщи сэмплов надо на SPI читать.

Katbert
Offline
Зарегистрирован: 04.06.2018

ЕвгенийП пишет:

Ну, так я  и думал. Вы читаете датчик через I2C - забудьте о нужных Вам скоростях. Просто забудьте. Ищите другое решение. Например, этот датчик умеет отдавать свои данные по SPI. Это ближе к делу.

 

Спасибо за помощь!

Буду разбираться с SPI. Код нашел. Понял также, что поскольку использую ардуино уно, для правильного подключения нужно еще будет согласовать логические уровни.