Помогите пожалуйста разобраться с кодом записи на SD

Тема в разделе "Arduino & Shields", создана пользователем SDV, 13 май 2018.

  1. SDV

    SDV Нерд

    Код (C++):
    [code]
    #include <Wire.h>
    #include <TimeLib.h>
    #include <DS1307RTC.h>
    #include <SPI.h>
    #include <SD.h>
    File dataFile;
    int sensePin = 0;
    String dataString = "";
    unsigned long timing;

    void setup()
    {
    Serial.begin(9600);
    Serial.print("Initializing SD card...");
    pinMode(10, OUTPUT);
    if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    return;
    }
    Serial.println("initialization done.");
    }
    void loop()
    {
    dataString = "";
    int Hour;
    int Minute;
    int Second;
    int check;

    int val = analogRead(sensePin);
    val = constrain(val, 650, 975);
    int sdv = map(val,650,975,1,0);

    tmElements_t tm;

       switch (check) {
        RTC.read(tm);
        Hour = print2digits(tm.Hour);
        Minute = print2digits(tm.Minute);
        Second = print2digits(tm.Second);
        if (RTC.read(tm)) {
        dataString += String(tm.Day);
        dataString += ".";
        dataString += String(tm.Month);
        dataString += ".";
        dataString += String(tmYearToCalendar(tm.Year));
        dataString += "\t"; // ставим знак табуляции
        dataString += String (Hour);
        dataString += ":";
        dataString += String (Minute);
        dataString += ":";
        dataString += String (Second);
        dataString += ":";
        dataString += String(sdv);

        Serial.print(dataString);     // выводим результаты в serial-порт

        Serial.println();
       else {
        if (RTC.chipPresent()) {
          Serial.println("The DS1307 is stopped.  Please run the SetTime");
          Serial.println("example to initialize the time and begin running.");
          Serial.println();
        } else {
          Serial.println("DS1307 read error!  Please check the circuitry.");
          Serial.println();
        }
        delay(9000);
      }
      if (millis() - timing > 10000){ // Вместо 10000 можно подставить другую периодичность для сохранения
      timing = millis();
      saveSD();     // сохраняем на microSD
    }
          break;
        case DHT_ERROR_CHECKSUM:    // ошибка контрольной суммы
          Serial.println("Checksum error");
          break;
        default:     // неизвестная ошибка
          Serial.println("Unknown error");
          break;
       }
       delay(1000);
    }

    void print2digits(int number) {
      if (number >= 0 && number < 10) {
        Serial.write('0');
      }
      Serial.print(number);
    }

    void saveSD()
    {
      File dataFile = SD.open("sdv.txt", FILE_WRITE);  // создаём файл для записи
      if (dataFile) {   // если файл доступен для записи
        dataFile.println(dataString);     // сохраняем данные
        dataFile.close();    // закрываем файл
        Serial.println("Save OK");    // выводим сообщение об удачной записи
      } else {
        Serial.println("Error opening sdv.txt");    // если файл не доступен
      }
    }


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

    Подскажите пожалуйста, как и где нужно подправить код? Спасибо.
     
  2. Daniil

    Daniil Гуру

    Чему равна переменная check?
    У вас структура switch - case реализована без блоков case.
     
  3. SDV

    SDV Нерд

    Переделал скетч. Снова пишет ошибка компиляции...((
    Код (C++):
    [code]
    #include <SD.h> // библиотека для SD Card.
    #include <Wire.h>
    #include <TimeLib.h>
    #include <DS1307RTC.h>

    int sensePin = 0;

    File myFile; // SD card.
    unsigned long timing;

    //int Savesdv; // Для фиксации температуры.

    void setup()
    {
    Serial.begin(9600);
    Serial.print("Initializing SD card..."); // Тестируем SD card на работоспособность.
    if (!SD.begin(10)) // Здесь можно изменить № pin ** CS - pin 10.
    {
    Serial.println("initialization failed!");
    return;
    }
    Serial.println("initialization done.");


    SDcardWrite(); // Запускаем функцию записи на SD card.

    }


    void SDcardWrite() // Делаем функцию, для записи на SD card.
    {
      int val = analogRead(sensePin);
      val = constrain(val, 650, 975);
      int sdv = map(val,650,975,1,0);
    // open the file. note that only one file can be open at a time,
    // so you have to close this one before opening another.
    // Создаём новый, или открываем существующий файл на SD card,
    // например с именем sdv.txt
    // максимум "8" символов может иметь имя файла 12345678.123

    myFile = SD.open("sdv.txt", FILE_WRITE);

    // if the file opened okay, write to it:

    if (myFile) {

    Serial.print("Writing to dimasens.txt...");
    tmElements_t tm;
    // начинаем записывать на SD card, строку в файл sdv.txt
    // Текущую дату.
    if (RTC.read(tm)) {
    myFile.print(tm.Day);
    myFile.print(".");
    myFile.print(tm.Month);
    myFile.print(".");
    myFile.print(tmYearToCalendar(tm.Year));
    myFile.print("\t");
    // Текущее время.
    myFile.print(tm.Hour);
    myFile.print(":");
    myFile.print(tm.Minute);
    myFile.print(":");
    myFile.print(tm.Second);
    myFile.print("\t");
    // Текущее значение датчика.
    myFile.print(sdv);
    myFile.close(); // close the file:

    Serial.println("done.");

    }
    else {
    // if the file didn't open, print an error:
    Serial.println("error opening sdv.txt");
    }
    }
    }


    // Делаем функцию для чтения с SD card и вывода в Serial монитор.

    void SDcardRead(){
    // re-open the file for reading:
    myFile = SD.open("sdv.txt");
    if (myFile) {
    Serial.println("sdv.txt:");
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
    Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
    }
    else {
    // if the file didn't open, print an error:
    Serial.println("error opening dimasens.txt");
    }
    }
    void loop()
    {
     
    // Для того чтоб бессмысленно не записывать на SD card данные с датчиков,
    // сделаем проверку.
    // Только если прошлое значение температуры не равно текущему значению,
    // то есть произошло изменение температуры.

    //if (SaveTemperature != dht.readTemperature())

    // Можно и по-другому, увеличивая порог, обнаружения изменения температуры.
    // if (SaveTemperature >= (dht.readTemperature()+2) || SaveTemperature <= (dht.readTemperature()-2))

    {

    // Serial.println(rtc.getDateStr());
    // Serial.println(dht.readHumidity());
    // Serial.println(dht.readTemperature());

    //SDcardWrite(); // Запускаем функцию записи на SD card.

    if (millis() - timing > 10000){ // Вместо 10000 можно подставить другую периодичность для сохранения
      timing = millis();
      SDcardWrite();     // сохраняем на microSD
    }
    // Снова фиксируем текущее значение температуры.

    }

    // Для вывода в Serial монитор данных с SD card.

    if (Serial.available() > 0) {

    // Если отправляем через Serial монитор цифру 1
    // запускаем функцию SDcardRead.
    // То есть выводим в Serial монитор всё содержимое файла dimasens.txt

    if (Serial.read()-48 == 1)SDcardRead();
    }
    }
     
    [/code]
     
  4. Daniil

    Daniil Гуру

    У вас ничего про ошибку в первом посте не было. Задайте вопрос правильно.
     
  5. SDV

    SDV Нерд

    В общем, по железу у меня Arduino Mega + Ethernet Shield W5100 + RTCDS1307 + фоторезистор.

    Задача сделать регистратор значений с записью данных на сд накопитель с привязкой к дате и времени.

    В первом скетче, я сильно намудрил и решил поискать более понятный мне скетч. Написать полностью такой скетч самостоятельно, я пока не в состоянии. Нашел скетч под мои железяки, только за исключением моих часов реального времени. Собственно вот этот скетч, это моя попытка подружить все мои комплектующие. Помогите пожалуйста!
    Сейчас ID при компиляции выдает :
    C:\Users\user\Documents\Arduino\libraries\SD\src\utility\Sd2Card.cpp:31:17: fatal error: SPI.h: No such file or directory
    #include <SPI.h>
    compilation terminated.
    Multiple libraries were found for "SD.h"
    Used: C:\Users\user\Documents\Arduino\libraries\SD
    Not used: C:\Program Files (x86)\Arduino\libraries\SD
    Multiple libraries were found for "DS1307RTC.h"
    Used: C:\Users\user\Documents\Arduino\libraries\DS1307RTC
    Not used: C:\Program Files (x86)\Arduino\libraries\DS1307RTC
    Ошибка компиляции.

    Сам скетч:
    Код (C++):
    [code]
    #include <SD.h> // библиотека для SD Card.
    #include <Wire.h>
    #include <TimeLib.h>
    #include <DS1307RTC.h>

    int sensePin = 0;

    File myFile; // SD card.
    unsigned long timing;

    //int Savesdv; // Для фиксации температуры.

    void setup()
    {
    Serial.begin(9600);
    Serial.print("Initializing SD card..."); // Тестируем SD card на работоспособность.
    if (!SD.begin(10)) // Здесь можно изменить № pin ** CS - pin 10.
    {
    Serial.println("initialization failed!");
    return;
    }
    Serial.println("initialization done.");


    SDcardWrite(); // Запускаем функцию записи на SD card.

    }


    void SDcardWrite() // Делаем функцию, для записи на SD card.
    {
      int val = analogRead(sensePin);
      val = constrain(val, 650, 975);
      int sdv = map(val,650,975,1,0);
    // open the file. note that only one file can be open at a time,
    // so you have to close this one before opening another.
    // Создаём новый, или открываем существующий файл на SD card,
    // например с именем sdv.txt
    // максимум "8" символов может иметь имя файла 12345678.123

    myFile = SD.open("sdv.txt", FILE_WRITE);

    // if the file opened okay, write to it:

    if (myFile) {

    Serial.print("Writing to dimasens.txt...");
    tmElements_t tm;
    // начинаем записывать на SD card, строку в файл sdv.txt
    // Текущую дату.
    if (RTC.read(tm)) {
    myFile.print(tm.Day);
    myFile.print(".");
    myFile.print(tm.Month);
    myFile.print(".");
    myFile.print(tmYearToCalendar(tm.Year));
    myFile.print("\t");
    // Текущее время.
    myFile.print(tm.Hour);
    myFile.print(":");
    myFile.print(tm.Minute);
    myFile.print(":");
    myFile.print(tm.Second);
    myFile.print("\t");
    // Текущее значение датчика.
    myFile.print(sdv);
    myFile.close(); // close the file:

    Serial.println("done.");

    }
    else {
    // if the file didn't open, print an error:
    Serial.println("error opening sdv.txt");
    }
    }
    }


    // Делаем функцию для чтения с SD card и вывода в Serial монитор.

    void SDcardRead(){
    // re-open the file for reading:
    myFile = SD.open("sdv.txt");
    if (myFile) {
    Serial.println("sdv.txt:");
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
    Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
    }
    else {
    // if the file didn't open, print an error:
    Serial.println("error opening dimasens.txt");
    }
    }
    void loop()
    {

    // Для того чтоб бессмысленно не записывать на SD card данные с датчиков,
    // сделаем проверку.
    // Только если прошлое значение температуры не равно текущему значению,
    // то есть произошло изменение температуры.

    //if (SaveTemperature != dht.readTemperature())

    // Можно и по-другому, увеличивая порог, обнаружения изменения температуры.
    // if (SaveTemperature >= (dht.readTemperature()+2) || SaveTemperature <= (dht.readTemperature()-2))

    {

    // Serial.println(rtc.getDateStr());
    // Serial.println(dht.readHumidity());
    // Serial.println(dht.readTemperature());

    //SDcardWrite(); // Запускаем функцию записи на SD card.

    if (millis() - timing > 10000){ // Вместо 10000 можно подставить другую периодичность для сохранения
      timing = millis();
      SDcardWrite();     // сохраняем на microSD
    }
    // Снова фиксируем текущее значение температуры.

    }

    // Для вывода в Serial монитор данных с SD card.

    if (Serial.available() > 0) {

    // Если отправляем через Serial монитор цифру 1
    // запускаем функцию SDcardRead.
    // То есть выводим в Serial монитор всё содержимое файла dimasens.txt

    if (Serial.read()-48 == 1)SDcardRead();
    }
    }
     
    Как решить данную проблему?
     
    Последнее редактирование: 13 май 2018
  6. Daniil

    Daniil Гуру

    Проверьте библиотеки, судя по ошибкам они у вас дублированны, а spi.h (почему?) вообще отсутствует.
     
  7. SDV

    SDV Нерд

    Все! Заработал скетч. Спасибо!

    Вот рабочий скетч. Нужно было только подключить библиотеку SPI.

    Код (C++):

    #include <SPI.h>
    #include <SD.h> // библиотека для SD Card.
    #include <Wire.h>
    #include <TimeLib.h>
    #include <DS1307RTC.h>

    int sensePin = 0;

    File myFile; // SD card.
    unsigned long timing;

    //int Savesdv; // Для фиксации температуры.

    void setup()
    {
    Serial.begin(9600);
    Serial.print("Initializing SD card..."); // Тестируем SD card на работоспособность.
    if (!SD.begin(4)) // Здесь можно изменить № pin ** CS - pin 10.
    {
    Serial.println("initialization failed!");
    return;
    }
    Serial.println("initialization done.");


    SDcardWrite(); // Запускаем функцию записи на SD card.

    }


    void SDcardWrite() // Делаем функцию, для записи на SD card.
    {
      int val = analogRead(sensePin);
      val = constrain(val, 650, 975);
      int sdv = map(val,650,975,1,0);
    // open the file. note that only one file can be open at a time,
    // so you have to close this one before opening another.
    // Создаём новый, или открываем существующий файл на SD card,
    // например с именем sdv.txt
    // максимум "8" символов может иметь имя файла 12345678.123

    myFile = SD.open("sdv.txt", FILE_WRITE);

    // if the file opened okay, write to it:

    if (myFile) {

    Serial.print("Writing to sdv.txt...");
    tmElements_t tm;
    // начинаем записывать на SD card, строку в файл sdv.txt
    // Текущую дату.
    if (RTC.read(tm)) {
    myFile.print(tm.Day);
    myFile.print(".");
    myFile.print(tm.Month);
    myFile.print(".");
    myFile.print(tmYearToCalendar(tm.Year));
    myFile.print("\t");
    // Текущее время.
    myFile.print(tm.Hour);
    myFile.print(":");
    myFile.print(tm.Minute);
    myFile.print(":");
    myFile.print(tm.Second);
    myFile.print("\t");
    // Текущее значение датчика.
    myFile.print(sdv);
    myFile.println("\n");
    myFile.close(); // close the file:

    Serial.println("done.");

    }
    else {
    // if the file didn't open, print an error:
    Serial.println("error opening sdv.txt");
    }
    }
    }


    // Делаем функцию для чтения с SD card и вывода в Serial монитор.

    void SDcardRead(){
    // re-open the file for reading:
    myFile = SD.open("sdv.txt");
    if (myFile) {
    Serial.println("sdv.txt:");
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
    Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
    }
    else {
    // if the file didn't open, print an error:
    Serial.println("error opening sdv.txt");
    }
    }
    void loop()
    {

    // Для того чтоб бессмысленно не записывать на SD card данные с датчиков,
    // сделаем проверку.
    // Только если прошлое значение температуры не равно текущему значению,
    // то есть произошло изменение температуры.

    //if (SaveTemperature != dht.readTemperature())

    // Можно и по-другому, увеличивая порог, обнаружения изменения температуры.
    // if (SaveTemperature >= (dht.readTemperature()+2) || SaveTemperature <= (dht.readTemperature()-2))

    {

    // Serial.println(rtc.getDateStr());
    // Serial.println(dht.readHumidity());
    // Serial.println(dht.readTemperature());

    //SDcardWrite(); // Запускаем функцию записи на SD card.

    if (millis() - timing > 10000){ // Вместо 10000 можно подставить другую периодичность для сохранения
      timing = millis();
      SDcardWrite();     // сохраняем на microSD
    }
    // Снова фиксируем текущее значение температуры.

    }

    // Для вывода в Serial монитор данных с SD card.

    if (Serial.available() > 0) {

    // Если отправляем через Serial монитор цифру 1
    // запускаем функцию SDcardRead.
    // То есть выводим в Serial монитор всё содержимое файла dimasens.txt

    if (Serial.read()-48 == 1)SDcardRead();
    }
    }
     
    Последний вопрос… записывает данные на сд через строчку, как сделать так, чтобы записывал в каждую строчку?
     
    Daniil нравится это.
  8. Daniil

    Daniil Гуру

    Код (C++):
    myFile.println("\n");
    функция print выводит строку.
    функция println выводит строку и дополняет её символом конца строки.
    символ конца строки это "\n".
    Вызывая функцию println("\n") вы выводите сразу 2 символа конца строки, что даёт вам лишнюю пустую строку.
     
    arkadyf нравится это.