RTC и SD работают отдельно, а не вместе
Я работаю над небольшим проектом. Я хочу использовать Arduino Mega 2560 v3, PIR-датчик, модуль карты micro SD, модуль RTC 1307, несколько светодиодов, кнопок и зуммер. Для включения и выключения обнаружения движения, а при обнаружении обнаружения время сохраняется на SD-карте.
Я все соединил, закодировал и начал тестировать. Во время тестов Arduino при загрузке снова и снова перезапускался. Сначала я подумал, что проблема в макетной плате и подключении. Я проверил ее несколько раз и не заметил ничего неправильного. Поэтому я снова и снова проверял код. Все еще ничего.
Итак, я начал тестировать модули. И обнаружил проблему. Когда я не использую в скетче ни RTC, ни SD-карту (физически они все еще подключены, потому что мне лень), все работает нормально. Arduino не перезагружается. Я не использовал SD-модуль для записи данных , вместо этого я использовал последовательный порт для отображения данных. Все работает отлично: я могу видеть, в какое время обнаружено движение, и Arduino выводит это на терминал.
Во втором сценарии я не использовал RTC, только модуль SD. На этот раз все снова работает отлично. На SD-карте я смог прочитать, сколько раз было обнаружено движение. Это странно, потому что когда я смешиваю все вместе, это не работает.
Вот мой код:
// **************************************************
// ВКЛЮЧАТЬ
// **********************************************
#include <Wire.h>
#include <SD.h>
#include <SPI.h>
#include "RTClib.h"
// **********************************************
// ОПРЕДЕЛЯТЬ
// **********************************************
#define GREENLED 39
#define BTNON 11
#define REDLED 41
#define BTNOFF 9
#define BUZZ 3
#define PIR_PIN 10
//SD (на мега)
#define SD_CLK_SD 52
#define SD_MI 50
#define SD_MO 51
#define SD_CS 4
//РТК
#define RTC_SDA 20
#define RTC_SCL 21
#define RTC_DS 2
// **********************************************
// ПЕРЕМЕННЫЕ
// **********************************************
RTC_DS1307 rtc;
File myFile;
char godz[8];
char data[5];
int btnON;
int btnOFF;
int pirD;
bool stan_alarmu;
void wlAlarmu() {
digitalWrite(REDLED,LOW);
digitalWrite(GREENLED, HIGH);
stan_alarmu=true;
gettime();
myFile = SD.open("dane.txt", FILE_WRITE);
if (myFile) {
myFile.print("### Wlaczenie alarmu ### ");
myFile.print(" ");
myFile.print(godz);
myFile.print(data);
myFile.println("");
myFile.close();
}
}
void wylAlarmu(){
digitalWrite(GREENLED, LOW);
digitalWrite(REDLED,HIGH);
stan_alarmu=false;
gettime();
myFile = SD.open("dane.txt", FILE_WRITE);
if (myFile) {
myFile.print("### Wylaczenie alarmu ### ");
myFile.print(" ");
myFile.print(godz);
myFile.print(data);
myFile.println("");
myFile.close();
}
}
void alarm(){
digitalWrite(GREENLED,LOW);
digitalWrite(REDLED,HIGH);
digitalWrite(BUZZ,HIGH);
delay(500);
digitalWrite(BUZZ,LOW);
gettime();
myFile = SD.open("dane.txt", FILE_WRITE);
if (myFile) {
myFile.print("Alarm: ");
myFile.print(" ");
myFile.print(godz);
myFile.print(data);
myFile.println("");
myFile.close();
}
delay(5000);
digitalWrite(REDLED,LOW);
digitalWrite(GREENLED,HIGH);
}
void blad() {
while(1){
digitalWrite(REDLED,HIGH);
delay(500);
digitalWrite(REDLED,LOW);
delay(500);
}
}
void gettime() {
DateTime now = rtc.now();
sprintf(godz,"%02d:%02d:%02d ",now.hour(),now.minute(),now.second());
sprintf(data,"%d.%d",now.day(),now.month());
}
// **********************************************
// НАСТРАИВАТЬ
// **********************************************
void setup() {
//РТК
Wire.begin();
// Контакты I2C на плате Shield подключаются к альтернативной шине I2C на Arduino Due
rtc.begin();
if (!rtc.isrunning()) {
blad();
// следующая строка устанавливает RTC на дату и время компиляции этого скетча
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// Эта строка устанавливает RTC с явной датой и временем, например, чтобы установить
// 21 января 2014 года в 3 часа ночи вы позвоните:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
pinMode(BTNON,INPUT);
pinMode(GREENLED, OUTPUT);
pinMode(BTNOFF,INPUT);
pinMode(REDLED, OUTPUT);
pinMode(PIR_PIN,INPUT);
pinMode(BUZZ,OUTPUT);
//тестовая последовательность
digitalWrite(GREENLED,HIGH);
digitalWrite(REDLED,HIGH);
digitalWrite(BUZZ,HIGH);
delay(100);
digitalWrite(BUZZ,LOW);
digitalWrite(GREENLED,LOW);
digitalWrite(REDLED,LOW);
delay(500);
pinMode(SD_CS, OUTPUT);
if (!SD.begin(SD_CS)) {
blad();
}
digitalWrite(GREENLED,HIGH);
delay(1000);
digitalWrite(GREENLED,LOW);
gettime();
Serial.begin(9600);
myFile = SD.open("dane.txt", FILE_WRITE);
if (myFile) {
myFile.print("####START SYSTEMU: ");
myFile.print(godz);
myFile.print(data);
myFile.print(" ####");
myFile.println("");
myFile.close();
}
wylAlarmu();
}
void loop() {
btnON = digitalRead(BTNON);
btnOFF = digitalRead(BTNOFF);
pirD = digitalRead(PIR_PIN);
if(btnON == HIGH) {
wlAlarmu();
delay(2000);
}
if(btnOFF == HIGH) {
wylAlarmu();
delay(2000);
}
if(pirD==HIGH && stan_alarmu==true) {
alarm();
}
delay(1000);
}
@GarryMoveOut, 👍2
Обсуждение6 ответов
Вы должны начать отлаживать свой код пошагово. То есть вставьте команды отладки вывода (печать через последовательный порт) в некоторые критические точки, чтобы найти блок кода, который сбрасывает ваше устройство. Затем сузьте его, пока не узнаете ту самую команду, которая ломает вашу настройку.
Возможно, в вашем программном обеспечении будет не одна точка, которая ответственна за сбой. Тем не менее, вы будете мудрее после этого.
Тогда вам, вероятно, придется погрузиться в недра библиотек.
Если вы определили какую-то команду или вызов процедуры, ответственную за перезагрузку, это может быть все еще аппаратная проблема. Запись SD-карт потребляет значительное количество энергии. Если вы питаете свое устройство исключительно через USB, я рекомендую купить дополнительный блок питания и посмотреть, изменится ли поведение.
Следующее — проверить сигнал сброса на всех ваших шилдах и дочерних платах на наличие нежелательных соединений, таких как перемычки из пайки или отдельные жилы проводов, обрезанные в других местах. Еще одна забавная вещь — это укладка разъемов, не соответствующих материнской плате, и замыкание чего-либо на ней.
Вы используете коммутационные платы, как показано в ваших ссылках? Или шилды Arduino?
Многие щиты Uno почти, но не совсем, совместимы с платами Mega. Возможно, что один или несколько пинов несовместимы между ними.
Если вы используете коммутационные платы, дважды проверьте все соединения с Mega. Может ли что-то понижать ваш источник питания? Или фактически заземлять контакт сброса? Вероятно, это один из программируемых контактов ввода-вывода, поскольку сбой зависел только от того, использовали ли вы библиотеку SD, и, похоже, не зависел от простого наличия платы.
Распространенная проблема при использовании строк (символьных векторов) заключается в том, что размер вектора не обновляется при обновлении формата. Проверьте размер, требуемый для этих данных. Подходит ли он для операторов sprintf()?
char godz[8];
char data[5];
void gettime()
{
DateTime now = rtc.now();
sprintf(godz,"%02d:%02d:%02d ",now.hour(),now.minute(),now.second());
sprintf(data,"%d.%d",now.day(),now.month());
}
Какой размер необходим в худшем случае?
Ура!
Недавно я столкнулся с той же проблемой. У меня есть обходной путь, но нет четкого объяснения этой проблемы. Когда вы инициализируете различные модули в setup()
, убедитесь, что сначала выполняется инициализация SD-карты, а затем RTC. Это полностью меня разобрало. Однако я еще не объяснил эти результаты.
Хотя уже поздно, на всякий случай, если кто-то еще столкнется с той же проблемой.
При использовании модуля карты памяти Catalex Micro SD возникает проблема с выходом MISO. Он не отключается на шине SPI из-за аппаратного сбоя. Для устранения проблемы вывод 13 на микросхеме необходимо снять с заземления и соединить с выводом 8, имеющим сигнал CS. Теперь карта отлично работает с другими модулями SPI. Будьте осторожны при пайке — выводы очень маленькие. С наилучшими пожеланиями OZ7LM Лейф
Уже поздно отвечать, но у меня была та же проблема, и я потратил неделю на ее решение. Это не будет точным решением. Это сработало, и я думаю, что это самый простой способ ее решить.
Сначала позвольте мне рассказать вам о моих компонентах:
- WeMos D1 R2 (ESP8266)
- Адаптер для карты MicroSD
- DS3231 RTC (я пробовал с DS1302, но не получилось).
Как я решил, в части настройки, сначала я инициализировал RTC DS3231, затем я установил встроенные часы Arduino на значения DS3231 RTC. После этого я инициализировал SD-карту. В этом случае вы не можете получить данные RTC в цикле, но у вас они есть во встроенных часах Arduino, и SD-карта работает. Если ваш Arduino отключится от электричества, то он снова получит данные RTC в настройке.
Это решение в какой-то степени решает эту проблему.
Кроме того, нет руководства по подключению этих карт к WeMos D1 R2, поэтому я хочу поделиться своими подключениями.
SD Card WeMos D1 R2
------- -----------
SC -> D14/SDA/D5
SCK -> D13/SCK
MOSI -> D11/MOSI
MISO -> D12/MISO
VCC -> 5V
GND -> GND
RTC DS3231 WeMos
---------- -----
SCL -> SCL/D15
SDA -> SDA/D14
VCC -> 3.3V
GND -> GND
Также мой код:
< pre class="lang-c++ prettyprint-override">#include <Wire.h>
#включить "RTClib.h"
#include <SD.h> //Загрузить библиотеку SD
#include <SPI.h>
#include <время.h>
#include <TimeLib.h>
Файл файл;
int chipSelect = 5;
RTC_DS3231 ртц;
bool not1024prev;
неподписанный давно прошедший период;
беззнаковый длинный timecurr;
int cnt = 0;
целые об/мин;
char daysOfTheWeek[7][12] = { "Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота" };
недействительная настройка()
{
#ifndef ESP8266
в то время как (!Серийный)
; // для Леонардо/Микро/Зеро
#endif
Последовательный.начало(9600);
delay(3000); // ждем открытия консоли
если (!rtc.begin()) {
Serial.println("Не удалось найти RTC");
в то время как (1)
;
}
если (rtc.lostPower()) {
Serial.println("RTC потерял питание, давайте установим время!");
// следующая строка устанавливает RTC на дату и время компиляции этого скетча
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// Эта строка устанавливает RTC с явной датой и временем, например, чтобы установить
// 21 января 2014 года в 3 часа ночи вы позвоните:
//rtc.adjust(DateTime(2018, 3, 11, 16, 29, 30));
}
ДатаВремя сейчас = rtc.now();
setTime(сейчас.час(), сейчас.минута(), сейчас.секунда(), сейчас.день(), сейчас.месяц(), сейчас.год());
if (!SD.begin(chipSelect)) { // Инициализация SD-карты
Serial.println("Не удалось инициализировать SD-карту."); // если возвращаемое значение ложно, что-то пошло не так.
}
}
пустой цикл()
{
Строка curtime = Строка(год()) + "." + Строка(месяц()) + "." + Строка(день()) + "-" + Строка(час()) + ":" + Строка(минута()) + ":" + Строка(секунда());
Serial.println(время_исключения);
}
- Nextion Display не получает обновленных данных
- Создание файла на SD-карте
- SD-карта не инициализируется
- Печать содержимого файла SD - карты на ЖК-дисплее
- Возникла проблема с переобъявлением символа другого типа
- Записать массив на SD
- Использование Arduino wireless SD Shield для сохранения данных на SD-карту и отправки на ПК по беспроводной сети
- Файл не найден на SD-карте
Пожалуйста, дайте точную спецификацию используемых вами щитов. Возможно, есть какие-то скрытые подсказки., @Ariser
Мой модуль RTC выглядит примерно так: http://www.arduino-projekte.de/index.php?n=45 спецификация находится внизу страницы под
DS1307 Datenblatt PDF
(ENG). Считыватель SD microSD производится Catalex http://catalex.taobao.com/, но я не смог найти документацию на их сайте :), @GarryMoveOutПохоже, вы используете RTC-библиотеку от adafruit. То же самое и с библиотекой SD? Я предполагаю, что конфигурации I²C-Bus для обоих модулей конфликтуют. Скорее всего, это касается битрейта. Вам следует заглянуть внутрь обеих библиотек и проверить, какие параметры они применяют к Wire-Library., @Ariser
Я не нашел ничего в библиотеках. Я также нашел, что кто-то использует библиотеку rtc и sd, как и я, и это работает. http://www.michellechandra.com/physical-computing/activity-tracker-log-date-and-time-to-microsd-using-real-time-clock-and-arduino/, @GarryMoveOut
Я пробовал использовать 3 разные библиотеки. Все равно ничего удивительного., @GarryMoveOut
Хм, если у вас есть осциллограф, вам следует проверить стабильность всех напряжений в вашей системе. Повторные перезагрузки указывают на провалы напряжения., @Ariser
У меня нет осциллографа. Только мультиметр. Напряжение в пределах 4,86 - 4,90., @GarryMoveOut
Вы пробовали использовать аппаратный пин для SPI SS (это 53, я предположил, что вы используете Arduino Mega, глядя на директивы вашего препроцессора). Иногда происходят странные вещи, когда вы переназначаете этот пин., @Vassilis
После долгого времени я построил новую схему и новый скетч. Я использовал только rtc и sd, на этот раз все работало нормально. Сейчас проблем нет. Раньше что-то было не так., @GarryMoveOut