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);
}

, 👍2

Обсуждение

Пожалуйста, дайте точную спецификацию используемых вами щитов. Возможно, есть какие-то скрытые подсказки., @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


6 ответов


0

Вы должны начать отлаживать свой код пошагово. То есть вставьте команды отладки вывода (печать через последовательный порт) в некоторые критические точки, чтобы найти блок кода, который сбрасывает ваше устройство. Затем сузьте его, пока не узнаете ту самую команду, которая ломает вашу настройку.

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

Тогда вам, вероятно, придется погрузиться в недра библиотек.

Если вы определили какую-то команду или вызов процедуры, ответственную за перезагрузку, это может быть все еще аппаратная проблема. Запись SD-карт потребляет значительное количество энергии. Если вы питаете свое устройство исключительно через USB, я рекомендую купить дополнительный блок питания и посмотреть, изменится ли поведение.

Следующее — проверить сигнал сброса на всех ваших шилдах и дочерних платах на наличие нежелательных соединений, таких как перемычки из пайки или отдельные жилы проводов, обрезанные в других местах. Еще одна забавная вещь — это укладка разъемов, не соответствующих материнской плате, и замыкание чего-либо на ней.

,

0

Вы используете коммутационные платы, как показано в ваших ссылках? Или шилды Arduino?

Многие щиты Uno почти, но не совсем, совместимы с платами Mega. Возможно, что один или несколько пинов несовместимы между ними.

Если вы используете коммутационные платы, дважды проверьте все соединения с Mega. Может ли что-то понижать ваш источник питания? Или фактически заземлять контакт сброса? Вероятно, это один из программируемых контактов ввода-вывода, поскольку сбой зависел только от того, использовали ли вы библиотеку SD, и, похоже, не зависел от простого наличия платы.

,

1

Распространенная проблема при использовании строк (символьных векторов) заключается в том, что размер вектора не обновляется при обновлении формата. Проверьте размер, требуемый для этих данных. Подходит ли он для операторов 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());
}

Какой размер необходим в худшем случае?

Ура!

,

1

Недавно я столкнулся с той же проблемой. У меня есть обходной путь, но нет четкого объяснения этой проблемы. Когда вы инициализируете различные модули в setup(), убедитесь, что сначала выполняется инициализация SD-карты, а затем RTC. Это полностью меня разобрало. Однако я еще не объяснил эти результаты.

Хотя уже поздно, на всякий случай, если кто-то еще столкнется с той же проблемой.

,

0

При использовании модуля карты памяти Catalex Micro SD возникает проблема с выходом MISO. Он не отключается на шине SPI из-за аппаратного сбоя. Для устранения проблемы вывод 13 на микросхеме необходимо снять с заземления и соединить с выводом 8, имеющим сигнал CS. Теперь карта отлично работает с другими модулями SPI. Будьте осторожны при пайке — выводы очень маленькие. С наилучшими пожеланиями OZ7LM Лейф

,

0

Уже поздно отвечать, но у меня была та же проблема, и я потратил неделю на ее решение. Это не будет точным решением. Это сработало, и я думаю, что это самый простой способ ее решить.

Сначала позвольте мне рассказать вам о моих компонентах:

  • 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(время_исключения); }
,