Почему я не могу записать на SD, хотя пример ReadWrite работает?

Я создал датчик, измеряющий цвет наружного дренажа спинномозговой жидкости с помощью TCS3200. Я получаю показания, но не могу сохранить их на SD-карту, хотя с помощью ReadWrite это вполне возможно. Это навело меня на мысль, что проблема не связана с оборудованием. Возможно, я упускаю что-то очевидное (например, проглядел деление на ноль и потерял около 6 часов, пытаясь разобраться).

Я использую клон Arduino Micro. TCS3200 и модуль microSD.

Вот мой код:

    #include <SPI.h>
#include <SD.h>

// Определить контакты, подключенные к датчику TCS3200
#define S0 2
#define S1 3
#define S2 4
#define S3 5
#define sensorOut 6

// Значения калибровки для четких показаний СМЖ (ЗАДАЧА: Откалибровать их)
int baselineClearPeriodCount = 1; // Инициализируем значением 1, чтобы предотвратить деление на ноль (ой.)
int baselineRedPeriodCount = 1;   
int baselineGreenPeriodCount = 1; 
int baselineBluePeriodCount = 1; 

// Целевое количество, которое должно быть достигнуто в течение динамической корректировки времени
const int targetCount = 360; 

// Настройка тайм-аута для функции pulseIn() (микросекунды)
const int pulseTimeout = 2000; 

// Указывает контакт выбора микросхемы для модуля SD-карты
const int chipSelect = 10;  

// Переменные для взаимодействия с SD-картой
File sensorDataFile;
String dataString = ""; 

// Прототипы функций
void setupSensorPins();
void readColor(int &colorCount, int S2State, int S3State);

void setup() {
  // Инициализация последовательной связи
  Serial.begin(9600);
  // Дайте время последовательному монитору открыться
  while (!Serial) {
    ; // дождитесь подключения последовательного порта. Требуется только для собственного USB-порта.
  }
  Serial.println("Serial communication initialized.");

  // Настраиваем контакты датчика
  setupSensorPins();
  Serial.println("Sensor pins setup completed.");

  // Инициализируем SD-карту
  Serial.print("Initializing SD card...");
  if (!SD.begin(chipSelect)) {
    Serial.println("SD card initialization failed!");
    while (1);
  }
  Serial.println("Initialization done.");

  
}

void loop() {
  // Отладочный оператор для указания начала цикла
  Serial.println("Starting loop...");

  // Переменные для хранения счетчиков для каждого цвета и сброса показаний
  int redPeriodCount = 0;
  int greenPeriodCount = 0;
  int bluePeriodCount = 0;
  int clearPeriodCount = 0;

  // Считывание красного, зеленого, синего и прозрачного цветов
  readColor(redPeriodCount, LOW, LOW);
  readColor(greenPeriodCount, HIGH, HIGH);
  readColor(bluePeriodCount, LOW, HIGH);
  readColor(clearPeriodCount, HIGH, LOW);

  // Вычислить и зарегистрировать данные
  int turbidityReductionPercent = (baselineClearPeriodCount - clearPeriodCount) * 100 / baselineClearPeriodCount;
  int redChangePercent = (redPeriodCount - baselineRedPeriodCount) * 100 / baselineRedPeriodCount;
  int greenChangePercent = (greenPeriodCount - baselineGreenPeriodCount) * 100 / baselineGreenPeriodCount;
  int blueChangePercent = (bluePeriodCount - baselineBluePeriodCount) * 100 / baselineBluePeriodCount;

  // Создаем строку данных
  dataString  = String(redPeriodCount) + "," + String(greenPeriodCount) + "," + 
                String(bluePeriodCount) + "," + String(clearPeriodCount) + "," + 
                String(turbidityReductionPercent) + "," + 
                String(redChangePercent) + "," + String(greenChangePercent) + "," +
                String(blueChangePercent) + "%\n"; 

  // Отладочный оператор для печати строки данных
  Serial.println("Data String: " + dataString);

  // Запись данных на SD-карту
  sensorDataFile = SD.open("sensordata.txt", FILE_WRITE);
  
  if (sensorDataFile) {
    sensorDataFile.println(dataString);
    sensorDataFile.close();
    Serial.println("Text file write complete");
  }
  else {
    // если файл не открылся, вывести ошибку:
    Serial.println("Error opening text file.");
  }

  // Короткая задержка перед следующей итерацией цикла
  delay(1000);
}

void setupSensorPins() {
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT);
}

void readColor(int &colorCount, int S2State, int S3State) {
  // Устанавливаем масштабирование частоты на 20%
  digitalWrite(S0, HIGH);
  digitalWrite(S1, LOW);

  digitalWrite(S2, S2State);
  digitalWrite(S3, S3State);
  unsigned long startTime = millis();
  colorCount = 0;
  int dynamicMeasurementTime = 50;
  unsigned long currentTime = millis();

  while (currentTime - startTime < dynamicMeasurementTime) {
    int pulseWidth = pulseIn(sensorOut, LOW, pulseTimeout);
    if (pulseWidth > 0) {
      colorCount++;
      if (colorCount >= targetCount) {
        dynamicMeasurementTime = currentTime - startTime;
        break;
      }
    }
    currentTime = millis();
  }

  // Отладочный оператор для печати количества цветов
  //Serial.print("Количество цветов (S2: ");
  //Serial.print(S2State);
  //Serial.print(", S3: ");
  //Serial.println(S3State);
  //Serial.print("): ");
  //Serial.println(colorCount);
}

На мониторе написано:

Starting loop...
Data String: 0,0,0,1,0,-100,-100,-100%
Error opening text file.

Я также пробовал вручную добавить пустой текстовый файл, но это тоже не сработало.

, 👍0

Обсуждение

Попробуйте сократить имя файла до 8 или менее символов слева от точки., @Delta_G

Вот и всё... Полагаю, именно это и означает «короткие имена 8.3». Мне кажется, в документации к Arduino это должно быть указано более чётко. Спасибо!, @Bilal Bahadır Akbulut

можно ли сделать это более явным, чем есть? https://www.arduino.cc/reference/en/libraries/sd/#usage, @Juraj

@Juraj Если вы, конечно, понимаете, что такое «короткие имена 8.3». Но, учитывая, что многие пользователи Arduino — либо любители, либо сотрудники других отделов, это может остаться незамеченным. Я даже удивился, узнав, что возможности устройства настолько ограничены..., @Bilal Bahadır Akbulut


1 ответ


Лучший ответ:

0

Потому что «короткие имена в формате 8.3» означают, что имена файлов должны быть короче 8 символов, а длиннее 8 символов имена файлов создавать нельзя, чтобы соответствовать этому соглашению об именовании. Спасибо, @Delta_G.

,