Происходит торможение процесса

Altik
Offline
Зарегистрирован: 28.01.2021

Господа, доброго времени суток! У меня имеется 3 акселерометра, ардуино МЕГА и Шилд. Необходимо записывать на SD карту показания с датчиков, обычно скорость у меня составляет 4-5 показаний в секунду, но потом, после полудня или целого дня работы он начинает затормаживать, как будто чем-то переполняется, и показания 1-2 в секунду. Подскажите пожалуйста что можно подправить?

Altik
Offline
Зарегистрирован: 28.01.2021
//Импорт библиотек
#include "DHT.h"
#include <Wire.h>
#include <string.h>
#include <SPI.h>
#include <SD.h>



#define SDCARD_CS 4
unsigned long timing_welcome;

//1 accel
unsigned int xPin = A0;
unsigned int yPin = A1;
unsigned int zPin = A2;
//2 accel
unsigned int x1Pin = A3;
unsigned int y1Pin = A4;
unsigned int z1Pin = A5;
//3 accel
unsigned int x2Pin = A6;
unsigned int y2Pin = A7;
unsigned int z2Pin = A8;

float Vmax = 5.0;

float Vmax1 = 5.0;

float Vmax2 = 5.0;


float x0 = 1.71;
float y0 = 1.69;
float z0 = 1.68;

float x01 = 1.71;
float y01 = 1.69;
float z01 = 1.68;

float x02 = 1.71;
float y02 = 1.69;
float z02 = 1.68;

float sens_x = 0.35;
float sens_y = 0.35;
float sens_z = 0.35;

float sens_x1 = 0.35;
float sens_y1 = 0.35;
float sens_z1 = 0.35;

float sens_x2 = 0.35;
float sens_y2 = 0.35;
float sens_z2 = 0.35;


RTC_DS1307 RTC;

char fileName[] = "00000000.CSV"; //Название файла
File webFile;




void setup()
{


  delay(300);
  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);
  // Serial.begin(115200);
  Wire.begin(); //Important for RTClib.h



  // initialize SD card
  if (!SD.begin(4)) {
    return;
  }



  webFile = SD.open(fileName, FILE_WRITE);

  if (webFile)
  {
    //Создание колонок
    String Name0 = (fileName);
    String header0 = ("Time Gx Gy Gz Gx1 Gy1 Gz1 Gx2 Gy2 Gz2 t,C");
    webFile.println(Name0);
    webFile.println(header0);
    webFile.close();
  }
}


void my_func() {

  //Считывания аналога
  unsigned int value_x = analogRead(xPin);
  unsigned int value_y = analogRead(yPin);
  unsigned int value_z = analogRead(zPin);
  unsigned int value_x1 = analogRead(x1Pin);
  unsigned int value_y1 = analogRead(y1Pin);
  unsigned int value_z1 = analogRead(z1Pin);
  unsigned int value_x2 = analogRead(x2Pin);
  unsigned int value_y2 = analogRead(y2Pin);
  unsigned int value_z2 = analogRead(z2Pin);

  //Формула для расчета
  float Gx = (value_x * Vmax / 1024.0 - x0) / sens_x;
  float Gy = (value_y * Vmax / 1024.0 - y0) / sens_y;
  float Gz = (value_z * Vmax / 1024.0 - z0) / sens_z;
  float Gx1 = (value_x1 * Vmax1 / 1024.0 - x01) / sens_x1;
  float Gy1 = (value_y1 * Vmax1 / 1024.0 - y01) / sens_y1;
  float Gz1 = (value_z1 * Vmax1 / 1024.0 - z01) / sens_z1;
  float Gx2 = (value_x2 * Vmax2 / 1024.0 - x02) / sens_x2;
  float Gy2 = (value_y2 * Vmax2 / 1024.0 - y02) / sens_y2;
  float Gz2 = (value_z2 * Vmax2 / 1024.0 - z02) / sens_z2;
  int time = millis() / 1000;
  unsigned int time1 = millis();



  webFile = SD.open(fileName, FILE_WRITE);
  webFile.print (time1);
  if (webFile)
  {
    //Выводим строку со значениями акселерометра и емпературы
    webFile.println(' ' + String(Gx) + ' ' + String(Gy) + ' ' + String(Gz) + ' ' + String(Gx1) + ' ' + String(Gy1) + ' ' + String(Gz1) + ' ' + String(Gx2) + ' ' + String(Gy2) + ' ' + String(Gz2) + ' ' + String(t));
    webFile.close();
  }
  else
  {
    //  Serial.println("EROR222");
    return;
  }
}


void loop()
{
  webFile = SD.open(fileName, FILE_WRITE);

  if (webFile)
  {
    String Name = (fileName); // Имя файла
    String header = ("Time Gx Gy Gz Gx1 Gy1 Gz1 Gx2 Gy2 Gz2 t,C");  //Заголовок
    webFile.println(Name);
    webFile.println(header);
    webFile.close();
  }
  my_func();
}


void createFileName() {
  webFile = SD.open(fileName, FILE_WRITE);
  webFile.close();
}

 

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

Несколько ошибок я вижу, но они не должны так влиять.

Давайте Вы

  1. поменяете местами строки №№ 128 и 129
  2. раскомментируете строку №137.
  3. запустите и расскажете нам, что получилось.

Только не забудьте, заодно, выложить получившийся код - надо видеть актуальный код а не держать в уме кто и что там менял.

Altik
Offline
Зарегистрирован: 28.01.2021

Благодарю за совет, начинаю делать так, но результат смогу сказать только через 12 часов - день. Ощущение, что хранящиеся на SD данные начинают замедлять все.

Altik
Offline
Зарегистрирован: 28.01.2021

А строка 137 закомментирована, так как ошибки нет и чтобы не нагружать лишним отключил

rkit
Offline
Зарегистрирован: 23.11.2016

Упростить вычисления, очевидно. Отказаться файловой системы. Перейти на более мощное железо.

Altik
Offline
Зарегистрирован: 28.01.2021

Вообще конечная задумка состоит в отправке данных на сервер, а на SD карту записывается резервная копия, но уже сейчас начали торможения... Кто-то писал тоже, что РаспБери Пай будет лучше для такого

rkit
Offline
Зарегистрирован: 23.11.2016

Для такого будет лучше программист получше.

Altik
Offline
Зарегистрирован: 28.01.2021

Ну вот и я не понимаю почему замедляется)

Upper
Offline
Зарегистрирован: 23.06.2020

Altik пишет:

Ощущение, что хранящиеся на SD данные начинают замедлять все.

Это ощущение легко проверить.

Запустить с изначально большим размером файла. Если сразу будет медленно, то ощущения верные.

Altik
Offline
Зарегистрирован: 28.01.2021

Да, Вы правы, спасибо! Попробую

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Upper пишет:

Это ощущение легко проверить.

Запустить с изначально большим размером файла. Если сразу будет медленно, то ощущения верные.

А вот очень правильный совет. Согласен с ним. Попробуйте каждый час писать в новый файл. Скорее всего - поможет.

Altik
Offline
Зарегистрирован: 28.01.2021

Вообще реализовано 15-минутоное сохранение, и вот это наблюдается у первого и последнего файла из списка. В начале 5-6, потом 1-2(

Altik
Offline
Зарегистрирован: 28.01.2021

Я заполню половину памяти SD карты и проведу эксперимент еще раз

Altik
Offline
Зарегистрирован: 28.01.2021

Есть небольшие продвижения. Эксперимент показал, что тормозит процесс количество файлов на SD карте. То есть чем их больше, тем медленнее работает все. Возможно надо как-то библиотеку изменить, если это поможет...но не уверен пока что. Вообще они создаются каждые 15 минут с именем текущего времени, так что за день их уже получается нормально. И тормозит именно не вес, а количество файлов

Morroc
Offline
Зарегистрирован: 24.10.2016

Как уже rkit писал выше рассмотрите отказ от файловой системы если вы эту карточку больше нигде не читаете. Переписывать библиотеку файловой системы... ну скажем так весь остальной ваш проект куда проще этого действа.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Altik пишет:

Эксперимент показал, что тормозит процесс количество файлов на SD карте. То есть чем их больше, тем медленнее работает все. Возможно надо как-то библиотеку изменить, если это поможет...

Сэр что-нибудь слышал о том, как устроена ФС FAT32?

И может догадаться, как при заданных в Ардуино ограничениях выглядит реальная работа с SD?

Библиотеку переписать, конечно, можно (хотя, скажу честно - большой геморрой даже для программиста высокой квалификации. А со средней квалификацией там вообще делать нечего), но оптимизировать по скорости можно одним единственным способом - выделить под библиотеку хотя бы десяток кбайт оперативной памяти. На большинстве моделей Арлуино столько просто нет. Другими словами, существенная зависимость скорости работы от количества файлов вытекает из двух обстоятельств: 

1. Файловая система FAT32.

2. Серьезные ограничения на объем памяти.

Так что для моделей Ардуино с 2.0-2.5 кбайтами оперативной памяти единственный вариант как-то ускорить работу - это применить нестандартную ФС. О чем, кстати, rkit уже упоминал.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

andriano пишет:

Так что для моделей Ардуино с 2.0-2.5 кбайтами оперативной памяти единственный вариант как-то ускорить работу - это применить нестандартную ФС. О чем, кстати, rkit уже упоминал.

или оставить один единственный файл структурировав формат (до)записи в него, кластер сделать 512 байт

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Или рассматривай всю SD карту как один блок памяти с flat-адресацией с окном 512 байт. 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ua6em пишет:

andriano пишет:

Так что для моделей Ардуино с 2.0-2.5 кбайтами оперативной памяти единственный вариант как-то ускорить работу - это применить нестандартную ФС. О чем, кстати, rkit уже упоминал.

или оставить один единственный файл структурировав формат (до)записи в него, кластер сделать 512 байт

 

Если это будет надстройкой над FAT, то никак не снизит ее ресурсоемкость. 

Другими словами, библиотека исходит из того, что файл может быть фрагментированным. А это требует даже при последовательной записи одного непрерывного файла периодически читать-записывать несколько секторов на границе каждых 512 байтов файла. Другими словами, переход через каждую границу в 512 байт требует не единственной операции записи одного сектора, как это было бы в оптимальном случае, а чтения-записи множества секторов.

Altik
Offline
Зарегистрирован: 28.01.2021

Я использую Arduino Mega 2560, чтобы памяти хватало

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Altik пишет:

Я использую Arduino Mega 2560, чтобы памяти хватало

Вы всерьез думаете, что библиотека анализирует, сколько памяти доступно, и пытается ее оптимально использовать?

Altik
Offline
Зарегистрирован: 28.01.2021

Прошу прощение за опечатку, не 4-5 показаний  потом 2-3, 40-50 в начале и 20-30 далее.

 

Я думал с помощью ардуино осуществить процесс записи данных с акселерометров, но для этого минимальная скорость нужна 40, а  у меня понижается и выходит, что на ардуино это реализовать не так и просто

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Ну так ты ж не в скаску попал.  Надо на SD писАть, крофьизносу, возьми STM с аппаратной поддержкой SD-протокола.  

Logik
Offline
Зарегистрирован: 05.08.2014

Если уж речь про скорость - убирай floatString, и всю арифметику. Пиши что получилось с датчиков прямо в том формате, т.е. в unsigned int. Данные собери в структуру и записывай одним блоком, 18 байт проще записать. А арифметику и пр. оставь на потом, пусть тот кто считает данные тот и обработает. Там проц мощней. Если для этого нужны будут константы - ну запиши и их на карту в начале файла или отдельным файлом.

Организуй работу с ФС так. Сразу после форматирования карты запиши большой файл, с запасом, на вырост. Данные не добавляй в конец, а пиши поверху файла. Этим  сэкономишь время на выделение блоков на карте.

Перебери SD карты, они не все одинаковы и в том режиме работы, что либа поддерживает их скорость тяжело прогнозируема. 50*18=900 Б/сек - не должно быть проблемой.

Если не поможет. Кешируй перед записью много блоков (штук 20-50, кол-во опытным путем подобрать) и записуй их за один раз. Тут правда ожидают сюрпризы в получении неравномерных интервалов между замерами (пока кэш запишется замеров не будет). Решается прерываниями и правильной архитектурой.

Если не поможет - нахер ФС, изучай работу с картой по SPI. Если осилишь - сможешь и FAT сохранить и писать быстро на прямую. Но тогда уже советы ты нам давать будешь.

Смена платформы - вариант тоже. Но ресурсоемкий.

 

 

rkit
Offline
Зарегистрирован: 23.11.2016

Logik пишет:

Организуй работу с ФС так. Сразу после форматирования карты запиши большой файл, с запасом, на вырост. Данные не добавляй в конец, а пиши поверху файла. Этим  сэкономишь время на выделение блоков на карте.

Издалека видно знатока флеш-памяти.

Logik
Offline
Зарегистрирован: 05.08.2014

rkit пишет:

Издалека видно знатока флеш-памяти.

Сразу видно, что rkit издалека бежал, в штанах еле донес.