Файл создан, но не записаны данные
Я начинаю использовать Arduino и практически не имею опыта кодирования. Тем не менее, мне удалось закодировать и понять, как это работает.
Проблема, с которой я столкнулся, заключается в том, что я не могу регистрировать (записывать) данные с трех подключенных датчиков (анемометров Adafruit). Все они работают правильно; файл данных создан. Однако в файл не записываются данные (или привязка ко времени). Когда я проверяю код, он утверждается...Следовательно, это должно сработать, не так ли?.=/ Затем я загрузил код.
Я использую Arduino uno с SD Logger Shield (Data Logging Shield v1.0, от Deek-Robot (TM)), который использует DS1307 RTC.
Все комментарии более чем приветствуются!
Заранее спасибо
#include "SD.h"
#include <Wire.h>
#include "RTClib.h"
// Простой регистратор данных для аналоговых выводов Arduino
#define LOG_INTERVAL 60000 // мельницы между записями
#define ECHO_TO_SERIAL 0 // эхо-данные на последовательный порт
#define WAIT_TO_START 0 // Ждать последовательного ввода в setup()
// цифровые контакты, которые подключаются к светодиодам
#define redLEDpin 3
#define greenLEDpin 4
// Аналоговые контакты, которые подключаются к датчикам
#define Anemometer0 // аналоговый 0
#define Anemometer1 // аналоговый 1
#define Anemometer2 // аналоговый 2
RTC_DS1307 RTC; // определяет объект часов реального времени
//Параметры настройки анемометров
// Anemometer0
const int sensorPin0 = A0; // Определяет вывод, к которому подключен выход анемометра
int sensorValue0 = 0; // Переменная сохраняет значение непосредственно с аналогового вывода
float sensorVoltage0 = 0; // Переменная, которая сохраняет напряжение (в вольтах) от анемометра, отправляемого на аналоговый pin
float windSpeed0 = 0; // Скорость ветра в метрах в секунду (м/с)
// Anemometer1
const int sensorPin1 = A1; // Определяет вывод, к которому подключен выход анемометра
int sensorValue1 = 0; // Переменная сохраняет значение непосредственно с аналогового вывода
float sensorVoltage1 = 0; // Переменная, которая сохраняет напряжение (в вольтах) от анемометра, отправляемого на аналоговый
float windSpeed1 = 0; // Скорость ветра в метрах в секунду (м/с)
// Anemometer2
const int sensorPin2 = A2; // Определяет вывод, к которому подключен выход анемометра
int sensorValue2 = 0; // Переменная сохраняет значение непосредственно с аналогового вывода
float sensorVoltage2 = 0; // Переменная, которая сохраняет напряжение (в вольтах) от анемометра, отправляемого на аналоговый
float windSpeed2 = 0; // Скорость ветра в метрах в секунду (м/с)
float voltageConversionConstant = .004882814; // Эта константа отображает значение, полученное из функции аналогового считывания,
// которое находится в диапазоне от 0 до 1023, в фактическое напряжение, которое находится в диапазоне от 0 В до 5
int sensorDelay = 1000; // Задержка между показаниями датчика, измеряется в миллисекундах (мс)
//Технические параметры анемометра
// Следующие переменные соответствуют анемометру, продаваемому компанией Adafruit, но могут быть изменены для соответствия другим анемометрам.
float voltageMin = .4; // Минимальное выходное напряжение от анемометра в мВ.
float windSpeedMin = 0; // Скорость ветра в метрах/сек, соответствующая минимальному напряжению
float voltageMax = 2.0; // Максимальное выходное напряжение от анемометра в мВ.
float windSpeedMax = 32; // Скорость ветра в метрах/сек, соответствующая максимальному напряжению
// для экрана регистрации данных мы используем цифровой вывод 10 для линии SD cs
const int chipSelect = 10;
// файл журнала
File logfile;
void error(char *str)
{
Serial.print("error: ");
Serial.println(str);
// красный светодиод указывает на ошибку
digitalWrite(redLEDpin, HIGH);
while(1);
}
void setup() {
// поместите сюда свой установочный код, чтобы запустить его один раз:
Serial.begin(9600);
Serial.println();
#if WAIT_TO_START
Serial.println("Type any character to start");
while (!Serial.available());
#endif //ОЖИДАНИЕ НАЧАЛА
// инициализировать SD-карту
Serial.print("Initializing SD card...");
// убедитесь, что пин выбора чипа по умолчанию установлен на
// вывод, даже если вы его не используете:
pinMode(10, OUTPUT);
// посмотрите, присутствует ли карта и может ли она быть инициализирована:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// больше ничего не делай:
return;
}
Serial.println("card initialized.");
// создайте новый файл
char filename[] = "LOGGER00.CSV";
for (uint8_t i = 0; i < 100; i++) {
filename[6] = i/10 + '0';
filename[7] = i%10 + '0';
if (! SD.exists(filename)) {
// открывайте новый файл только в том случае, если он не существует
logfile = SD.open(filename, FILE_WRITE);
break; // выйти из цикла!
}
}
if (! logfile) {
error("couldnt create file");
}
Serial.print("Logging to: ");
Serial.println(filename);
Wire.begin();
if (!RTC.begin()) {
logfile.println("RTC failed");
#if ECHO_TO_SERIAL
Serial.println("RTC failed");
#endif //ECHO_TO_SERIAL
}
pinMode(redLEDpin, OUTPUT);
pinMode(greenLEDpin, OUTPUT);
// Если вы хотите установить aref на что-то другое, кроме 5 В
//Аналоговая ссылка (ВНЕШНЯЯ);
}
void loop() {
// поместите сюда свой основной код для повторного запуска:
DateTime now;
// задержка на нужное нам время между показаниями
delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
digitalWrite(greenLEDpin, HIGH);
// регистрировать миллисекунды с момента запуска
uint32_t m = millis();
logfile.print(m); // миллисекунды с момента запуска
logfile.print(", ");
#if ECHO_TO_SERIAL
Serial.print(m); // миллисекунды с момента запуска
Serial.print(", ");
#endif
// получить время
now = RTC.now();
// время регистрации
//logfile.print(); // секунды с 2000 года
logfile.print(", ");
logfile.print(now.year(), DEC);
logfile.print("/");
logfile.print(now.month(), DEC);
logfile.print("/");
logfile.print(now.day(), DEC);
logfile.print(" ");
logfile.print(now.hour(), DEC);
logfile.print(":");
logfile.print(now.minute(), DEC);
logfile.print(":");
logfile.print(now.second(), DEC);
#if ECHO_TO_SERIAL
Serial.print(now.get()); // секунды с 2000 года
Serial.print(", ");
Serial.print(now.year(), DEC);
Serial.print("/");
Serial.print(now.month(), DEC);
Serial.print("/");
Serial.print(now.day(), DEC);
Serial.print(" ");
Serial.print(now.hour(), DEC);
Serial.print(":");
Serial.print(now.minute(), DEC);
Serial.print(":");
Serial.print(now.second(), DEC);
#endif //ECHO_TO_SERIAL
// Anemometer0
const int sensorPin0 = A0; // Определяет вывод, к которому подключен выход анемометра
int sensorValue0 = 0; // Переменная сохраняет значение непосредственно с аналогового вывода
float sensorVoltage0 = 0; // Переменная, которая сохраняет напряжение (в вольтах) от анемометра, отправляемого на аналоговый pin
float windSpeed0 = 0; // Скорость ветра в метрах в секунду (м/с)
// Anemometer1
const int sensorPin1 = A1; // Определяет вывод, к которому подключен выход анемометра
int sensorValue1 = 0; // Переменная сохраняет значение непосредственно с аналогового вывода
float sensorVoltage1 = 0; // Переменная, которая сохраняет напряжение (в вольтах) от анемометра, отправляемого на аналоговый
float windSpeed1 = 0; // Скорость ветра в метрах в секунду (м/с)
// Anemometer2
const int sensorPin2 = A2; // Определяет вывод, к которому подключен выход анемометра
int sensorValue2 = 0; // Переменная сохраняет значение непосредственно с аналогового вывода
float sensorVoltage2 = 0; // Переменная, которая сохраняет напряжение (в вольтах) от анемометра, отправляемого на аналоговый
float windSpeed2 = 0; // Скорость ветра в метрах в секунду (м/с)
float voltageConversionConstant = .004882814; // Эта константа отображает значение, полученное из функции аналогового считывания,
// которое находится в диапазоне от 0 до 1023, в фактическое напряжение, которое находится в диапазоне от 0 В до 5
int sensorDelay = 1000; // Задержка между показаниями датчика, измеряется в миллисекундах (мс)
//Технические параметры анемометра
// Следующие переменные соответствуют анемометру, продаваемому компанией Adafruit, но могут быть изменены для соответствия другим анемометрам.
float voltageMin = .4; // Минимальное выходное напряжение от анемометра в мВ.
float windSpeedMin = 0; // Скорость ветра в метрах/сек, соответствующая минимальному напряжению
float voltageMax = 2.0; // Максимальное выходное напряжение от анемометра в мВ.
float windSpeedMax = 32; // Скорость ветра в метрах/сек, соответствующая максимальному напряжению
logfile.print(", ");
logfile.print(A0);
logfile.print(", ");
logfile.print(A1);
logfile.print(",");
logfile.println(A2);
#if ECHO_TO_SERIAL
Serial.print(", ");
Serial.print(Anemometer0);
Serial.print(", ");
Serial.print(Anemometer1);
Serial.print(",");
Serial.println(Anemometer2);
#endif //ECHO_TO_SERIAL
digitalWrite(greenLEDpin, LOW);
}
´´´
@PedroHerve, 👍2
Обсуждение1 ответ
Спасибо за всю вашу помощь. Мне удалось записать данные на SD-карту, включая дату и время. Новый код выглядит следующим образом:
#include <SPI.h>
#include <SD.h>
#include "RTClib.h"
RTC_DS1307 rtc; // создание локальных экземпляров объектов библиотечного класса
DateTime time;
File dataFile;
const int chipSelect = 10;
// Анемометр при 0,15 магл
const int sensorPinA0 = A0; // Определяет вывод, к которому подключен выход анемометра
int sensorValue0 = 0; // Переменная сохраняет значение непосредственно от аналогового
float sensorVoltage0 = 0; // Переменная, которая сохраняет напряжение (в вольтах) от анемометра, отправляемого на аналоговый вывод
float WindSpeed0 = 0; // Скорость ветра в метрах в секунду (м/с)
float voltageConversionConstant0 = .0048828125; // Эта константа отображает значение, полученное из функции аналогового считывания, которое находится в диапазоне от 0 до 1024, в фактическое напряжение, которое находится в диапазоне от 0 В до 5 В
// следовательно, это значение соответствует 5,00 В/1024. Проверить https://forum.allaboutcircuits.com/threads/why-adc-1024-is-correct-and-adc-1023-is-just-plain-wrong.80018/
int sensorDelay0 = 60000; //Задержка между показаниями датчика, измеряемая в миллисекундах (мс)
//Технические параметры анемометра
// Следующие переменные соответствуют анемометру, продаваемому компанией Adafruit, но могут быть изменены для соответствия другим анемометрам.
float voltageMin0 = .4; // Минимальное выходное напряжение от анемометра в мВ.
float windSpeedMin0 = 0; // Скорость ветра в метрах/сек, соответствующая минимальному напряжению
float voltageMax0 = 2.0; // Максимальное выходное напряжение от анемометра в мВ.
float windSpeedMax0 = 32; // Скорость ветра в метрах/сек, соответствующая максимальному напряжению
// Анемометр на 0,5 магл
const int sensorPinA1 = A1; // Определяет вывод, к которому подключен выход анемометра
int sensorValue1 = 0; // Переменная сохраняет значение непосредственно от аналогового
float sensorVoltage1 = 0; // Переменная, которая сохраняет напряжение (в вольтах) от анемометра, отправляемого на аналоговый вывод
float WindSpeed1 = 0; // Скорость ветра в метрах в секунду (м/с)
float voltageConversionConstant1 = .0048828125; // Эта константа отображает значение, полученное из функции аналогового считывания, которое находится в диапазоне от 0 до 1024, в фактическое напряжение, которое находится в диапазоне от 0 В до 5 В
// следовательно, это значение соответствует 5,00 В/1024. Проверить https://forum.allaboutcircuits.com/threads/why-adc-1024-is-correct-and-adc-1023-is-just-plain-wrong.80018/
int sensorDelay1 = 1000; //Задержка между показаниями датчика, измеряемая в миллисекундах (мс)
//Технические параметры анемометра
// Следующие переменные соответствуют анемометру, продаваемому компанией Adafruit, но могут быть изменены для соответствия другим анемометрам.
float voltageMin1 = .4; // Минимальное выходное напряжение от анемометра в мВ.
float windSpeedMin1 = 0; // Скорость ветра в метрах/сек, соответствующая минимальному напряжению
float voltageMax1 = 2.0; // Максимальное выходное напряжение от анемометра в мВ.
float windSpeedMax1 = 32; // Скорость ветра в метрах/сек, соответствующая максимальному напряжению
// Анемометр на 1,2 магл
const int sensorPinA2 = A2; // Определяет вывод, к которому подключен выход анемометра
int sensorValue2 = 0; // Переменная сохраняет значение непосредственно от аналогового вывода
float sensorVoltage2 = 0; // Переменная, которая сохраняет напряжение (в вольтах) от анемометра, отправляемого на аналоговый вывод
float WindSpeed2 = 0; // Скорость ветра в метрах в секунду (м/с)
float voltageConversionConstant2 = .0048828125; // Эта константа отображает значение, полученное из функции аналогового считывания, которое находится в диапазоне от 0 до 1024, в фактическое напряжение, которое находится в диапазоне от 0 В до 5 В
// следовательно, это значение соответствует 5,00 В/1024. Проверить https://forum.allaboutcircuits.com/threads/why-adc-1024-is-correct-and-adc-1023-is-just-plain-wrong.80018/
int sensorDelay2 = 60000; //Задержка между показаниями датчика, измеряемая в миллисекундах (мс)
//Технические параметры анемометра
// Следующие переменные соответствуют анемометру, продаваемому компанией Adafruit, но могут быть изменены для соответствия другим анемометрам.
float voltageMin2 = .4; // Минимальное выходное напряжение от анемометра в мВ.
float windSpeedMin2 = 0; // Скорость ветра в метрах/сек, соответствующая минимальному напряжению
float voltageMax2 = 2.0; // Максимальное выходное напряжение от анемометра в мВ.
float windSpeedMax2 = 32; // Скорость ветра в метрах/сек, соответствующая максимальному напряжению
void setup() {
Serial.begin(9600);
while (!Serial) {;} // дождитесь подключения последовательного порта.
Serial.print("Initializing SD card...");
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
while (1); // цикл навсегда
}
Serial.println("Have SD card");
rtc.begin();
}
void loop() {
sensorValue0 = analogRead(A0); // Получить значение от 0 до 1023 от аналогового вывода, подключенного к анемометру
sensorValue1 = analogRead(A1); // Получить значение от 0 до 1023 от аналогового вывода, подключенного к анемометру
sensorValue2 = analogRead(A2); // Получить значение между 0 и 1023 от аналогового вывода, подключенного к анемометру
sensorVoltage0 = sensorValue0 * voltageConversionConstant0; // Преобразовать значение датчика в фактическое напряжение
sensorVoltage1 = sensorValue1 * voltageConversionConstant1; // Преобразовать значение датчика в фактическое напряжение
sensorVoltage2 = sensorValue2 * voltageConversionConstant2; // Преобразовать значение датчика в фактическое напряжение
//Преобразуйте значение напряжения в скорость ветра, используя диапазон максимальных и минимальных напряжений и скорости ветра для анемометра
if (sensorVoltage0 <= voltageMin0){
WindSpeed0 = 0; //Проверьте, не ниже ли напряжение минимального значения. Если это так, установите скорость ветра равной нулю.
}
else {
WindSpeed0 = (sensorVoltage0 - voltageMin0)*windSpeedMax0/(voltageMax0 - voltageMin0); // Для напряжений выше минимального значения используйте линейную зависимость для вычисления скорости ветра на A0.
}
if (sensorVoltage1 <= voltageMin1){
WindSpeed1 = 0; //Проверьте, не ниже ли напряжение минимального значения. Если это так, установите скорость ветра равной нулю.
}
else {
WindSpeed1 = (sensorVoltage1 - voltageMin1)*windSpeedMax1/(voltageMax1 - voltageMin1); // Для напряжений выше минимального значения используйте линейную зависимость для вычисления скорости ветра на A1.
}
if (sensorVoltage2 <= voltageMin2){
WindSpeed2 = 0; //Проверьте, не ниже ли напряжение минимального значения. Если это так, установите скорость ветра равной нулю.
}
else {
WindSpeed2 = (sensorVoltage2 - voltageMin2)*windSpeedMax2/(voltageMax2 - voltageMin2); // Для напряжений выше минимального значения используйте линейную зависимость для вычисления скорости ветра на A2.
}
time = rtc.now(); // Читать RTC
String dataString = ""; // Собрать данные
log:
dataString = time.timestamp(DateTime::TIMESTAMP_DATE);
dataString += ", ";
dataString += time.timestamp(DateTime::TIMESTAMP_TIME);
dataString += ", ";
dataString += String(sensorVoltage0);
dataString += ", ";
dataString += String(WindSpeed0);
dataString += ", ";
dataString += String(sensorVoltage1);
dataString += ", ";
dataString += String(WindSpeed1);
dataString += ", ";
dataString += String(sensorVoltage2);
dataString += ", ";
dataString += String(WindSpeed2);
dataFile = SD.open("Speedlog.txt", FILE_WRITE);
if (dataFile) { // Запись в файл журнала
dataFile.println(dataString);
dataFile.close();
Serial.println(dataString);
delay(1000); // пауза в течение одной секунды между регистрациями датчиков
}
else {
Serial.println("error opening datalog.txt");
}
}
Вы не должны использовать строку, да вам это и не нужно, потому что вы можете просто записать все биты в файл, не объединяя их сначала. Если необходимо, вам следует удалить String dataString = ""; из цикла и добавить его в качестве глобального вверху; это может немного помочь сохранить вашу кучу нетронутой, но лучше вообще избегать String ., @ocrdu
- Данные DHT11 из Arduino UNO в Firebase через ESP8266
- Объяснение кода MPU6050
- Онлайн-проблема подключения Arduino к базе данных MySQL
- Как я могу прервать задержку() при нажатии кнопки?
- Проблема с открытием нескольких текстовых файлов одновременно/по порядку с использованием <SD.h>
- nRF24L01 + потеря пакетов, вызванная считыванием Arduino и связью с датчиками
- Как остановить серводвигатель в текущем положении при использовании последовательного порта? Я хочу, чтобы он оставался в одном положении при получении «0».
- Как установить управляющий регистр в модуле RTC DS3231 для Arduino UNO R3?
Вы "проверили", да. Но вы "загрузили"?, @Majenko
вы не открываете файл, если он существует, @Juraj
@Juraj Этот фрагмент кода предназначен для создания нового файла с последовательной нумерацией. Он найдет первый файл, который * не * существует в LOGGER00.CSV, в LOGGER99.CSV и откроет его., @Majenko
Да, @Majenko, код был правильно загружен на плату. Но я не упомянул об этом в письменном объяснении, спасибо, что указали на это. Должен ли файл содержать какие-либо данные и дату / время?, @PedroHerve
Я подозреваю, что вы не даете ему достаточно времени, чтобы сбросить данные на SD-карту, и они находятся только в буфере. Вы должны вызвать
logfile.flush();
после каждой итерации., @MajenkoДопустили ли вы ошибку копирования-вставки при вводе кода в вопрос? У вас есть часть в
loop ()
, где вы снова определяете глобальные переменные, такие какsensorPin0
, @chrislВаши заявления о задержке кажутся мне действительно странными. Зачем ты это делаешь? Если вы хотите читать с определенным интервалом, вам следует использовать
millis ()
, как в примере BlinkWithoutDelay, и полностью избегатьdelay ()
, @chrisl@chris|, да... Я допустил ошибку. Спасибо, что заметили!, @PedroHerve