Эхологгер. Ошибка записи на флешку.

hans-zemmer
Offline
Зарегистрирован: 30.06.2021

Добрый день. Довольно долгое время пробую довести до безотказной работы устройство "эхологгер". Суть простая: есть импульс с эхолота с хаотичной периодичностью, как правило, несколько раз в секунду. В устройстве gps-модуль и модуль SD. По импульсу с эхолота (по прерываниям) начинается отсчет времени до следующей посылки. В этот промежуток регистрируется максимальное напряжение на аналоговом входе (это есть дно), делается расчет глубины по скорости звука в воде. Координаты скрещиваются с глубиной и записываются на SD каждые 2м либо раз в секунду.

Если не подключать эхолот, устройство работает как gps-логгер, ошибок практически нет, все успевает записаться. Тестировал в машине, путь 180 км - ни одной ошибки. Формат данных такой: 54.659339,20.387359,0.00

Если подключаю эхолот, какое-то время все записывается нормально. Потом начинаются ошибки вплоть до глюка флешки и невозможности ее открытия.

Сегодня катался на лодке. Трек примерно 16 км. В теории должно было записаться около 8000 точек, но живых только 600.

Вот выдержки из файлов:

54.659946,20.388492,2.24
54.659942,20.388519,2.24
54.69О
MEЖ†AЎ
 
54.659355,20.387304,3.92
9351,20.387283,3.81
20.387266,3.81
.659366,20.387279,4.76
54.659374,20.387296,4.76

Лампочки сигнализируют об успешной работе устройства, но по факту файлы фаршмачные. Скетч ниже. Не судите строго. Нужна помощь. 

 

#include <AltSoftSerial.h>
#include <SPI.h>
#include <SD.h>
#include <TinyGPS.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Устанавливаем дисплей


AltSoftSerial gpsport;  //(8, 9) RX, TX по умолчанию
TinyGPS gps;

#define humbaud 4800
#define gpsbaud 9600
#define chipSelect 10
#define red 5
#define green 6
#define blue 7
#define water A1
#define button A3

#define dV 50 // разница между истинной скоростью и скоростью по спутнику
#define Vv 1500
#define timeout 1500
#define Ustart 185 // 0.9 v

bool newdata = false;
boolean flag = true, waterflag = false, lcdstate = false;
unsigned long start, redst, greenst, bluest, date, time, fix_age, lcdtimer, buttontimer;
long lat, lon, oldlat = 54500000, oldlon = 20500000;
float oldhdop;
int filescore = 1;
char filename[] = "01.TXT"; // Первоначальное название
File dataFile;


void setup() {

  pinMode(10, OUTPUT);
  pinMode(water, OUTPUT);
  pinMode(blue, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(red, OUTPUT);
  pinMode(A0, INPUT);
  pinMode (button, INPUT_PULLUP);

  lcd.init();
  lcd.backlight();

  Serial.begin(gpsbaud);
  while (!Serial) {}
  delay(100);

  gpsport.begin(gpsbaud);
  digitalWrite(water, HIGH);
  digitalWrite(blue, HIGH);
  digitalWrite(green, HIGH);
  digitalWrite(red, HIGH);
  delay(2000);

  lcd.clear();
  digitalWrite(water, LOW);
  digitalWrite(blue, LOW);
  digitalWrite(green, LOW);
  digitalWrite(red, LOW);

  lcd.setCursor(0, 1);
  lcd.print(F("Card ini..."));

  if (!SD.begin(chipSelect)) {
    lcd.setCursor(0, 1);
    lcd.print(F("Card ini fail"));

    lcd.noBacklight();

    while (1) {
      digitalWrite(green, HIGH);
      digitalWrite(red, HIGH);
      delay(150);
      digitalWrite(green, LOW);
      digitalWrite(red, LOW);
      delay(150);
    }

  } else {

    for (uint8_t i = 1; i < 100; i++) {
      filename[0] = i / 10 + '0';
      filename[1] = i % 10 + '0';

      if (!SD.exists(filename)) { // Проверяем наличие
        dataFile = SD.open(filename, FILE_WRITE);
        break;  // Дальше продолжать смысла нет
      }
    }

    lcd.setCursor(0, 0);
    lcd.print(filename);
    delay(1000);

    if (dataFile) {
      dataFile.println("-----");

      lcd.setCursor(0, 1);
      lcd.print(F("Card Ok. File Ok"));

      digitalWrite(green, HIGH);
      delay(2000);
      digitalWrite(green, LOW);
      delay(1000);
      lcd.clear();
      lcd.noBacklight();
    } else {
      lcd.setCursor(0, 1);
      lcd.print(F("Cant open file!"));
      delay(1000);
      lcd.noBacklight();

      while (1) {
        digitalWrite(green, HIGH);
        digitalWrite(red, HIGH);
        delay(700);
        digitalWrite(green, LOW);
        digitalWrite(red, LOW);
        delay(700);
      }

    }
  }
  attachInterrupt(0, glubinomer, RISING);

}

volatile unsigned long sonarTimer = 0, pikTimer = 0, dt;
volatile boolean sonarPik = false;
volatile int Uref, tik = 1;
volatile float depth = 0.0, lastdepth = 0.0;
void glubinomer() {
  if (micros() < sonarTimer) {
    dt = 4294967295 - sonarTimer + micros();
  } else {
    dt = micros() - sonarTimer;
  }
  if (dt > timeout) {
    if (pikTimer > sonarTimer) {
      long dif = pikTimer - sonarTimer;
      if (abs(dif) > 1000) {
        //depth = filter((dif - 500) * 0.00075);
        depth = (dif - 500) * 0.00075;
      }
    }
    sonarTimer = micros();
    pikTimer = sonarTimer;
    sonarPik = true;
  }
}




void loop() { // run over and over

  if (millis() - lcdtimer > 1000) {
    lcdtimer = millis();
    // вывод глубины на экран
    if (depth < 250) {
      lcd.setCursor(0, 1);
      lcd.print(F("h "));
      lcd.print(depth, 1);
      if (depth < 10) {
        lcd.print(F("   "));
      } else if (depth < 100) {
        lcd.print(F("  "));
      } else {
        lcd.print(F(" "));
      }
    }

  }


  // обработка кнопки
  if (millis() - buttontimer > 300) {
    int but = analogRead(button);
    if (but < 50) {
      buttontimer = millis();
      lcdstate = !lcdstate;
      if (lcdstate) {
        lcd.backlight();
      } else {
        lcd.noBacklight();
      }
    }
  }



  // =============== считывание отраженных сигналов с эхолота ====================
  if (sonarTimer > 0) {
    if (sonarPik) {
      sonarPik = false;
      Uref = Ustart;
 
      delayMicroseconds(1000);

    } else {
      int U = analogRead(A0);
      if (U > Uref) {
        Uref = U;
        //Serial.println(Uref);
        pikTimer = micros();
        waterflag = !waterflag;
        digitalWrite(water, waterflag); // мигнули лампочкой
      }
    }
  }



  if (millis() - redst > 250) {
    digitalWrite(red, LOW);
  }
  if (millis() - greenst > 250) {
    digitalWrite(green, LOW);
  }
  if (millis() - bluest > 250) {
    digitalWrite(blue, LOW);
  }

  newdata = readgps();

  if (newdata) {

    noInterrupts();

    start = millis();
     digitalWrite(blue, HIGH);
    bluest = millis();
    gps.get_position(&lat, &lon, &fix_age);
    float skor = gps.f_speed_kmph();
    float myhdop = gps.hdop() / 100.0;
    float dist = (sqrt(sq((lat - oldlat) * 11.11) + sq((lon - oldlon) * 11.11))) / 100.0;
    flag = true;
 

    // ------------------------  фильтр координат -----------------------------------
    if (fix_age == TinyGPS::GPS_INVALID_AGE) {
      //Serial.println("No fix");
      digitalWrite(red, HIGH);
      redst = millis();
    } else if (fix_age > 1000) {
      //Serial.println("Old fix");
      digitalWrite(red, HIGH);
      redst = millis();
    } else if (myhdop > 5.0) {
      //Serial.print("BIG HDOP: ");
      digitalWrite(red, HIGH);
      redst = millis();
    } else if (dist < oldhdop) {
      //Serial.println("Moving in HDOP");
    } else if (dist < 2.0) {
      //Serial.print("Low moving: ");
    } else {



      // ------------------- запись на флешку -----------
      oldlat = lat;
      oldlon = lon;
      oldhdop = myhdop;

      float lattitude = lat / 1000000.0;
      float longitude = lon / 1000000.0;

      if (dataFile) {
        dataFile.print(lattitude, 6);
        dataFile.print(",");
        dataFile.print(longitude, 6);
        dataFile.print(",");
        dataFile.print(depth);
        dataFile.println();
        dataFile.flush();
        digitalWrite(green, HIGH);
        greenst = millis();
      } else {
        interrupts();
        lcd.setCursor(0, 1);
        lcd.print(F("error open File"));
        digitalWrite(red, HIGH);
        redst = millis();
        digitalWrite(green, HIGH);
        greenst = millis();
      }
      depth = 0.00;
      interrupts();

      lcd.setCursor(7, 1);
      lcd.print(F(" V "));
      lcd.print(skor, 1);
      if (skor < 10) {
        lcd.print(F("   "));
      } else if (skor < 100) {
        lcd.print(F("  "));
      } else {
        lcd.print(F(" "));
      }

      lcd.setCursor(0, 0);
      lcd.print(lattitude, 4);
      lcd.setCursor(8, 0);
      lcd.print(longitude, 4);
      // ------------------- конец записи на флешку -----------

    } // ----- конец фильтра координат


    interrupts();

  } else {
    if (flag) {
      Serial.println(F("No GPS data yet..."));
      flag = false;
    }
  }
} // конец лупа




bool readgps() {
  while (gpsport.available())
  {
    int b = gpsport.read();
    //в библиотеке TinyGPS имеется ошибка: не обрабатываются данные с \r и \n
    if ('\r' != b)
    {
      if (gps.encode(b))
        return true;
    }
  }
  return false;
}

 

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

первое что вижу - зачем вы запрещаете прерывание аж на 2 трети длины программы? Чего вы этим хотите добится? боитесь. чтобы прерывание от эхолота не испортило данные? - это не так делается...

И что это такое в строке 139 - защита от переполнения микрос? :))))

hans-zemmer
Offline
Зарегистрирован: 30.06.2021

Да, все верно :))
И тем не менее, что исправить/добавить, чтобы гарантированно каждую секунду данные писались на флешку без всякой лабуды?

Ощущение, что данные не успевают записаться, а потом и указатель на открытый файл "ломается". 
Читал про скорость записи на флешку и буфер в 512 байт, якобы что 1 байт и 512 байт пишутся одинаковое время, но, боюсь, будет коряво записывать сразу пачку точек. 
Склеивать String? 
Закрывать/переоткрывать файл через какое-то время? 
Прошу помочь. Без надежно работающего устройства вхолостую жгу бензин и время.  :))

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

в первую очередь я бы изменил работу с прерываниями. Если их и надо запрещать - то на самое короткое время, буквально на одну строчку кода. Заведите в ЛУП отдельную переменную для времени, полученного с эхолота. Когда надо ее скопировать - запретили прерывание, скопировали значение, разрешили прерывания обратно. А все остальные действия, в том числе запись на карту - должны происходить при разрешенных прерываниях

И да, еще - следующая запись на карту должна начинатся не ранее, чем закончилась предыдущая. Пока идет запись - данные с эхолота можно не обновлять.

 

hans-zemmer
Offline
Зарегистрирован: 30.06.2021

Ясно. Теперь надо понять, как запрет прерываний влияет на запись на флешку, так, для себя. Думал даже прилепить вторую нано или тини чисто на расчет времени и по запросу отдавать глубину, но уверен, что можно без них как-то сделать. 
А как определить, когда закончилась предыдущая запись? Мне казалось, что в кардридере есть свой буфер и туда все складывается по порядку, а flush() уже дает команду на запись. 
Правильно ли сделана запись построчно? Быть может, лучше склеить все данные в одну строку и уже ее писать?

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

hans-zemmer пишет:

Ясно. Теперь надо понять, как запрет прерываний влияет на запись на флешку

если у вас флешка SPI, то без прерываний оно не работает.

Да и вообще, выключать прерывания более чем на доли микросекунды - в любом случае плохая идея, у вас все перестает работать - миллис, сериал, i2c и spi...

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

hans-zemmer пишет:

Правильно ли сделана запись построчно? Быть может, лучше склеить все данные в одну строку и уже ее писать?

днйствуйте последовательно, переделать прерывания - дело 5 минут, сначала попробуйте. может с файлами все ОК и так

hans-zemmer
Offline
Зарегистрирован: 30.06.2021

b707 пишет:

hans-zemmer пишет:

Правильно ли сделана запись построчно? Быть может, лучше склеить все данные в одну строку и уже ее писать?

днйствуйте последовательно, переделать прерывания - дело 5 минут, сначала попробуйте. может с файлами все ОК и так

Ну так а может вообще не нужно их запрещать? 

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

hans-zemmer пишет:

Ну так а может вообще не нужно их запрещать? 

насколько я вижу, единственная величина, которую нужно копировать из прерывания эхолота в ЛУП - это dif, разница между двумя значениями таймера (поскольку расчет глубины лучше вынести из прерывания).

Величина dif имеет тип лонг, сл-но, теоретически, прерывание может случится в середине ее копирования - поэтому лучше в этот момент прерывания запретить. Но только на эту одну единственную строчку.

ELECTROS
Offline
Зарегистрирован: 28.05.2021

А флешка вообще живая после этих манипуляций?

hans-zemmer
Offline
Зарегистрирован: 30.06.2021

ELECTROS пишет:

А флешка вообще живая после этих манипуляций?

Да.
Однажды видел такую странность: в корне было несколько файлов с именами что-то типа T.XT и вообще без расширения объемом около 3,5 Гб, хотя флешка была на 2 Гб. Эти файлы не удаляются, не открываются и не копируются. Помогает только форматирование. Флешка после форматирования живая. 
 

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

hans-zemmer пишет:

Добрый день. Довольно долгое время пробую довести до безотказной работы устройство "эхологгер". Суть простая: есть импульс с эхолота с хаотичной периодичностью, как правило, несколько раз в секунду. В устройстве gps-модуль и модуль SD. По импульсу с эхолота (по прерываниям) начинается отсчет времени до следующей посылки. В этот промежуток регистрируется максимальное напряжение на аналоговом входе (это есть дно), делается расчет глубины по скорости звука в воде. Координаты скрещиваются с глубиной и записываются на SD каждые 2м либо раз в секунду.

Если не подключать эхолот, устройство работает как gps-логгер, ошибок практически нет, все успевает записаться. Тестировал в машине, путь 180 км - ни одной ошибки.

Я так понял, что если скорость больше примерно 4 узлов, то темп записи на SD выше 1 записи в секунду, а при 30 узлах достигает примерно 8 записей в секунду.

Опять же, чем отличается "на машине"? Как вообще "путь 180 км" соотносится с темпом записи?

hans-zemmer пишет:

Читал про скорость записи на флешку и буфер в 512 байт, якобы что 1 байт и 512 байт пишутся одинаковое время

Ну это немного не так. Правильнее будет примерно так: запись одного байта в файл может потребовать последовательного чтения и записи более десятка секторов (по 512 байт каждый).

В общем, при неблагоприятных условиях 120 мс может оказаться недостаточно, чтобы завершился процесс записи.

И еще ответьте на два вопроса:

1. Зачем Вы вообще используете прерывания?

2. Каков допустимый процент пропусков данных, пришедших с эхолота?

hans-zemmer
Offline
Зарегистрирован: 30.06.2021

andriano пишет:

Я так понял, что если скорость больше примерно 4 узлов, то темп записи на SD выше 1 записи в секунду, а при 30 узлах достигает примерно 8 записей в секунду.

В общем, при неблагоприятных условиях 120 мс может оказаться недостаточно, чтобы завершился процесс записи.

И еще ответьте на два вопроса:

1. Зачем Вы вообще используете прерывания?

2. Каков допустимый процент пропусков данных, пришедших с эхолота?

Запись производится тогда, когда координаты со спутника успешно прошли через фильтр координат. Учитывая то, что gps-модуль отдает координаты 1 раз в секунду, то и запись на флешку происходит не чаще 1 раза в секунду. К этому моменту должна быть подготовлена глубина.

1. Думал, что прерывания помогут гарантированно записать данные. Чтобы в процесс записи не вмешивался сигнал с эхолота. Перечитал немного про прерывания и понял, что смысла их запрещать вообще никакого, да и оказывается их запрет влияет практически на весь процесс работы платы. Я даже использовал не ту функцию для запрета. Нужно было detachinterrupt() использовать. Уже убрал.

2. Процент пропусков, думаю, роли не играет. Как я уже сказал, мне нужно к моменту записи на флешку иметь глубину. Очевидно, чем ближе к этому моменту рассчитается глубина, тем точнее будет  местоположение отснятой точки. Съемка, как правило, ведется на малых скоростях, примерно до 2 м/с, то полноправно можно вообще этим пренебречь. 

Сейчас пробовал подключать все на балконе, программа без прерываний: точки пишутся. Но это опять всего несколько точек, потом фильтр не пропускает координаты из-за малого перемещения, чтобы не писать одну и ту же точку по 100 раз. Чтобы оценить в полной мере, нужно снова снарядить лодку, поехать на водоем и пройтись час-два. Я так уже год катаюсь с переменным успехом. :)) Вот варианты закончились и тогда  написал сюда. Думаю, вы все грамотные ребята и вместе мы решим проблему. ;)

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Проще и по быстродействию точно хватит поставить внешнюю eeprom

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

hans-zemmer пишет:

Как я уже сказал, мне нужно к моменту записи на флешку иметь глубину. Очевидно, чем ближе к этому моменту рассчитается глубина, тем точнее будет  местоположение отснятой точки.

Вы напрасно пытаетесь ввести связь между отметкой глубины и моментом записи. Каждую точку глубины нужно снабжать меткой времени, каждую координату с GPS - тоже. И можно будет сбрасывать на флешку не каждую секунду, а хоть раз в полчаса. Более того, в таком случае можно ввести постобработку, чтобы точнее привязать отметки глубины к географическим координатам.

И, возможно, лучше вести постоянную запись не на SD, а в какую-нибудь память с произвольным доступом: в EEPROM (распространенные корпуса на 32 или 64 кбайта, можно использовать до 8 штук одновременно) либо в PSRAM64 (8 Мбайт), а сбрасывать на SD (возможно, с постобработкой) уже по окончании цикла измерений.

hans-zemmer
Offline
Зарегистрирован: 30.06.2021

andriano пишет:

Вы напрасно пытаетесь ввести связь между отметкой глубины и моментом записи. 

Зря вы проигнорировали вторую часть той мысли: "..Съемка, как правило, ведется на малых скоростях, примерно до 2 м/с, то полноправно можно вообще этим пренебречь.". Погрешность в пределах одного цикла измерений для меня не очень существенна, поэтому метки времени - это лишнее для данной ситуации. 

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

Заплатить на 500 рублей больше за нормальное оборудование, и не мучить маню софтсериалами и прочей порнографией - не вариант, конечно. Год поездок того стоит.

hans-zemmer
Offline
Зарегистрирован: 30.06.2021

Все понятно.
Спасибо, друзья. 

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

hans-zemmer пишет:

Перечитал немного про прерывания и понял, что смысла их запрещать вообще никакого, да и оказывается их запрет влияет практически на весь процесс работы платы. Я даже использовал не ту функцию для запрета. Нужно было detachinterrupt() использовать. Уже убрал.

похоже, что вы мало что поняли из того, что читали. Во-первых, смысл запрещать прерывания есть, но только на момент копирования данных. И во-вторых, команда detachinterrupt() не для этого

.Я вам выше четко расписал, что именно нужно поправить в коде. Вы так пробовали?

Если вы не слушаете советов, то я не стану тратить на вас время, разбирайтесь сами.

hans-zemmer
Offline
Зарегистрирован: 30.06.2021

andycat пишет:
Проще и по быстродействию точно хватит поставить внешнюю eeprom

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

Наткнулся тут на интересный пост про скорость записи на sd-карту: https://sprosi.pro/questions/6471/kak-uvelichit-skorost-zapisi-sd-kartyi-v-arduino и https://forum.arduino.cc/t/why-is-the-sd-library-slow/49791. И еще смущает тот факт, что флешки имеют ограниченный ресурс по перезаписи. А не накрываются ли все флешки в моем устройстве медным тазом именно ввиду ограниченности своего ресурса? 
Вопросов в плане быстродействия нет. Главный вопрос, который и был изначально: почему ломается структура флешки и находящихся на ней фалов через довольно продолжительное время работы кода? Откуда берутся неудаляемые файлы и пр. хрень? Может ли переменная-указатель на открытый файл в setup изменить свое значение во время выполнения Loop и из-за этого начинается вся эта билиберда с файлами? Что, если просто указать название файла как const char[] = "TEXT.TXT"; и потом уже открывать и закрывать этот файл при записи? Что тогда будет с ресурсом флешки? 

И главный вопрос: как перекидывать данные на флешку из внешней подключенной памяти в конце цикла измерений, чтобы таки не растратить снова этот ресурс флешки? 

 

hans-zemmer
Offline
Зарегистрирован: 30.06.2021

b707 пишет:

Вы так пробовали?

Да, пробовал, работает. Спасибо. Я выше там еще изложил свои идеи по поводу флешки. И вот еще момент: может ли двигатель давать какие-либо фатальные наводки на плату? И про питание sd-модуля тоже не совсем ясно, сколько он потребляет тока и какое должно быть напряжение. Питаю вместе с ардуино от 5В поуэрбанка. Может, в этом дело?

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

hans-zemmer пишет:

Я выше там еще изложил свои идеи по поводу флешки.

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

hans-zemmer
Offline
Зарегистрирован: 30.06.2021

b707 пишет:

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


Я пытаюсь найти причину, а не свалить проблемы. В ответ получаю: кривой код. Разве я попросил бы помощи, если бы знал, где именно "кривизна"? 

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

hans-zemmer пишет:

Разве я попросил бы помощи, если бы знал, где именно "кривизна"? 

вы должны понять, что вы со своими проблемами один на один. Никакой форум вам не поможет, ибо никто на форуме не станет вникать во все нюансы вашего кода.

Вам подсказывают общие идеи, как например про прерывания - а у ж дальше вы их разрабатываете сами, пишете 300 вариантов кода, штудируете книжки... Ну или не штудируете, а просто бросаете это дело...

 

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

hans-zemmer пишет:

Разве я попросил бы помощи, если бы знал, где именно "кривизна"? 

Везде. Начиная с выбора оборудования. О чем, вроде бы, вполне неоднозначно было сказано. Ну и кода 80% нужно причесывать с беглого взгляда. И это не считая того, что не дано ни вводных в полной мере, ни элементарно схемы.

Feofan
Offline
Зарегистрирован: 28.05.2017

Был один модуль SD с чудным поведением. Вёл себя непредсказуемо - иногда писал белиберду, иногда не признавал карты. "Вылечилось" использованием конвертера уровня на MOSI, SCK, CS.

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

Feofan пишет:

Был один модуль SD с чудным поведением. Вёл себя непредсказуемо - иногда писал белиберду, иногда не признавал карты. "Вылечилось" использованием конвертера уровня на MOSI, SCK, CS.

Модули SD бывают как с конвертерами уровней (предназначенные для сопряжения с 5-вольтовой логикой), так и без оных (предназначенные для сопряжения с 3.3-вольтовой логикой).

Со стороны карты должно быть исключительно 3.3В.

Если кому-то вздумалось подключать модуль без конвертеров к 5-вольтовой логике напрямую, то "чудное поведение" здесь не со стороны модуля, а со стороны того, кто пытался так подключить. Так что лечить надо было не модуль, а "подключателя". А модуль вполне здоров. Просто предназначен для Mini 8MHz, Due, stm32...

Если болт М4 не входит в резьбу М3, то это не значит, что он нездоров и нуждается в лечении. Хотя можно, конечно, опилить болт напильником, а затем поверх нарезать резьбу М3.

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

hans-zemmer пишет:

Наткнулся тут на интересный пост про скорость записи на sd-карту: ... и https://forum.arduino.cc/t/why-is-the-sd-library-slow/49791

Вас не смутило, что этой теме 10 лет?

Сегодня библиотека SD точно не ведет себя так, как описано в этом источнике. Да и было ли оно так раньше - тоже сомнительно. Иначе получается, что ресурса флешки (до полного износа) хватит только на то, чтобы записать один файл длиной 10к.

hans-zemmer
Offline
Зарегистрирован: 30.06.2021

andriano пишет:

Вас не смутило, что этой теме 10 лет?

А чего смущаться? Не каждый занимается этой темой более 10 лет и я в том числе. 

hans-zemmer
Offline
Зарегистрирован: 30.06.2021

 

Остался единственный неясный момент:
 

// автосохранение 1 раз в 15 минут либо каждые 500 точек (при скорости 5 км/ч)
  if (koltoch > 500 || millis() - savetime > 900000) {
    savetime = millis();
    koltoch = 0;
    dataFile.println(F("--autosave--"));
    dataFile.close();
    delay(1000); // для успешного сохранения на SD
    dataFile = SD.open(filename, FILE_WRITE);
  }

Иногда происходит ошибка открытия файла. Что это - глючная флешка или все-таки программа+железо?