Происходит торможение процесса
- Войдите на сайт для отправки комментариев
Сб, 05/06/2021 - 21:39
Господа, доброго времени суток! У меня имеется 3 акселерометра, ардуино МЕГА и Шилд. Необходимо записывать на SD карту показания с датчиков, обычно скорость у меня составляет 4-5 показаний в секунду, но потом, после полудня или целого дня работы он начинает затормаживать, как будто чем-то переполняется, и показания 1-2 в секунду. Подскажите пожалуйста что можно подправить?
//Импорт библиотек #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(); }Несколько ошибок я вижу, но они не должны так влиять.
Давайте Вы
Только не забудьте, заодно, выложить получившийся код - надо видеть актуальный код а не держать в уме кто и что там менял.
Благодарю за совет, начинаю делать так, но результат смогу сказать только через 12 часов - день. Ощущение, что хранящиеся на SD данные начинают замедлять все.
А строка 137 закомментирована, так как ошибки нет и чтобы не нагружать лишним отключил
Упростить вычисления, очевидно. Отказаться файловой системы. Перейти на более мощное железо.
Вообще конечная задумка состоит в отправке данных на сервер, а на SD карту записывается резервная копия, но уже сейчас начали торможения... Кто-то писал тоже, что РаспБери Пай будет лучше для такого
Для такого будет лучше программист получше.
Ну вот и я не понимаю почему замедляется)
Ощущение, что хранящиеся на SD данные начинают замедлять все.
Это ощущение легко проверить.
Запустить с изначально большим размером файла. Если сразу будет медленно, то ощущения верные.
Да, Вы правы, спасибо! Попробую
Это ощущение легко проверить.
Запустить с изначально большим размером файла. Если сразу будет медленно, то ощущения верные.
А вот очень правильный совет. Согласен с ним. Попробуйте каждый час писать в новый файл. Скорее всего - поможет.
Вообще реализовано 15-минутоное сохранение, и вот это наблюдается у первого и последнего файла из списка. В начале 5-6, потом 1-2(
Я заполню половину памяти SD карты и проведу эксперимент еще раз
Есть небольшие продвижения. Эксперимент показал, что тормозит процесс количество файлов на SD карте. То есть чем их больше, тем медленнее работает все. Возможно надо как-то библиотеку изменить, если это поможет...но не уверен пока что. Вообще они создаются каждые 15 минут с именем текущего времени, так что за день их уже получается нормально. И тормозит именно не вес, а количество файлов
Как уже rkit писал выше рассмотрите отказ от файловой системы если вы эту карточку больше нигде не читаете. Переписывать библиотеку файловой системы... ну скажем так весь остальной ваш проект куда проще этого действа.
Эксперимент показал, что тормозит процесс количество файлов на SD карте. То есть чем их больше, тем медленнее работает все. Возможно надо как-то библиотеку изменить, если это поможет...
Сэр что-нибудь слышал о том, как устроена ФС FAT32?
И может догадаться, как при заданных в Ардуино ограничениях выглядит реальная работа с SD?
Библиотеку переписать, конечно, можно (хотя, скажу честно - большой геморрой даже для программиста высокой квалификации. А со средней квалификацией там вообще делать нечего), но оптимизировать по скорости можно одним единственным способом - выделить под библиотеку хотя бы десяток кбайт оперативной памяти. На большинстве моделей Арлуино столько просто нет. Другими словами, существенная зависимость скорости работы от количества файлов вытекает из двух обстоятельств:
1. Файловая система FAT32.
2. Серьезные ограничения на объем памяти.
Так что для моделей Ардуино с 2.0-2.5 кбайтами оперативной памяти единственный вариант как-то ускорить работу - это применить нестандартную ФС. О чем, кстати, rkit уже упоминал.
Так что для моделей Ардуино с 2.0-2.5 кбайтами оперативной памяти единственный вариант как-то ускорить работу - это применить нестандартную ФС. О чем, кстати, rkit уже упоминал.
или оставить один единственный файл структурировав формат (до)записи в него, кластер сделать 512 байт
Или рассматривай всю SD карту как один блок памяти с flat-адресацией с окном 512 байт.
Так что для моделей Ардуино с 2.0-2.5 кбайтами оперативной памяти единственный вариант как-то ускорить работу - это применить нестандартную ФС. О чем, кстати, rkit уже упоминал.
или оставить один единственный файл структурировав формат (до)записи в него, кластер сделать 512 байт
Если это будет надстройкой над FAT, то никак не снизит ее ресурсоемкость.
Другими словами, библиотека исходит из того, что файл может быть фрагментированным. А это требует даже при последовательной записи одного непрерывного файла периодически читать-записывать несколько секторов на границе каждых 512 байтов файла. Другими словами, переход через каждую границу в 512 байт требует не единственной операции записи одного сектора, как это было бы в оптимальном случае, а чтения-записи множества секторов.
Я использую Arduino Mega 2560, чтобы памяти хватало
Я использую Arduino Mega 2560, чтобы памяти хватало
Вы всерьез думаете, что библиотека анализирует, сколько памяти доступно, и пытается ее оптимально использовать?
Прошу прощение за опечатку, не 4-5 показаний потом 2-3, 40-50 в начале и 20-30 далее.
Я думал с помощью ардуино осуществить процесс записи данных с акселерометров, но для этого минимальная скорость нужна 40, а у меня понижается и выходит, что на ардуино это реализовать не так и просто
Ну так ты ж не в скаску попал. Надо на SD писАть, крофьизносу, возьми STM с аппаратной поддержкой SD-протокола.
Если уж речь про скорость - убирай float, String, и всю арифметику. Пиши что получилось с датчиков прямо в том формате, т.е. в
unsignedint. Данные собери в структуру и записывай одним блоком, 18 байт проще записать. А арифметику и пр. оставь на потом, пусть тот кто считает данные тот и обработает. Там проц мощней. Если для этого нужны будут константы - ну запиши и их на карту в начале файла или отдельным файлом.Организуй работу с ФС так. Сразу после форматирования карты запиши большой файл, с запасом, на вырост. Данные не добавляй в конец, а пиши поверху файла. Этим сэкономишь время на выделение блоков на карте.
Перебери SD карты, они не все одинаковы и в том режиме работы, что либа поддерживает их скорость тяжело прогнозируема. 50*18=900 Б/сек - не должно быть проблемой.
Если не поможет. Кешируй перед записью много блоков (штук 20-50, кол-во опытным путем подобрать) и записуй их за один раз. Тут правда ожидают сюрпризы в получении неравномерных интервалов между замерами (пока кэш запишется замеров не будет). Решается прерываниями и правильной архитектурой.
Если не поможет - нахер ФС, изучай работу с картой по SPI. Если осилишь - сможешь и FAT сохранить и писать быстро на прямую. Но тогда уже советы ты нам давать будешь.
Смена платформы - вариант тоже. Но ресурсоемкий.
Организуй работу с ФС так. Сразу после форматирования карты запиши большой файл, с запасом, на вырост. Данные не добавляй в конец, а пиши поверху файла. Этим сэкономишь время на выделение блоков на карте.
Издалека видно знатока флеш-памяти.
Издалека видно знатока флеш-памяти.
Сразу видно, что rkit издалека бежал, в штанах еле донес.