0

I am having some issues with a new DS3231 Precision RTC module. I have made connections as in the guide linked, and when used, the serial output from the Arduino is garbled, and the arduino apparently crashes, endlessly flowing garbled messages (which appear to be bits of the beginning of the first serial output).

Sometimes I can get better output, but only up until I try to set the datetime, where it then crashes, with endless garble.

Code used to set datetime (all vars given are ints):

rtc.adjust(DateTime(year, month, day, hour, minute, second));

The way I have things wired is the same as on the guide listed. I am basing my code off of the example on the guide (which is the same as on the guide), yet the example code functions well.

Relevant excerpt(s) from my code:

//includes
#include <Servo.h> //for running the servo
#include <Wire.h> //required for RTClib
#include "RTClib.h" //to run the real time clock functionality. https://github.com/adafruit/RTClib

boolean timingEnabled = true;
RTC_DS3231 rtc;
void setup(){
  Serial.begin(9600);
  if(timingEnabled){
    //clock
    boolean rtcOn = rtc.begin();
    Serial.print(String(rtcOn) + "\n");
    if(! rtcOn){
      Serial.print("Couldn't find RTC. Timing Disabled\n");
      timingEnabled = false;
    }else{
      if(rtc.lostPower()){
        Serial.println("Clock lost power.\n");
        setTime();//set the clock
      }
    }
  }
}

Since it was asked for, full code (minus loop()):

/* Sketch for Arduino to run the automatic cat feeder.
 *
 * 
 */

//includes
#include <Servo.h> //for running the servo
#include <Wire.h> //required for RTClib
#include "RTClib.h" //to run the real time clock functionality. https://github.com/adafruit/RTClib

//status indicator values
const int onboardLedPin = 13;

//buzzer values
const boolean buzz = true; //turns on and off the buzzer functionality
const int buzzerPin = 8;
const int buzzLength = 250;
const int buzzDefaultFreq = 1000;
const int buzzFeedStartFreq = 2000;
const int buzzFeedEndFreq = 500;
const int buzzBattWarnFreq = 2000;
const int buzzConfirmFreq = 100;

//Servo setup
Servo dispenserServo;
const int servoPin = 11;
const int feedServoSpinTime = 2000;
const int STOP = 90;
const int SPIN_CLOCKWISE = 180;
const int SPIN_COUNTER_CLOCKWISE = 0;

//clock
boolean timingEnabled = true;
RTC_DS3231 rtc;
String feedTimes[] = {"7:00"};

//button
const int buttonPin = 7;
int buttonVal = 0;

//other
const int mainWait = 5000;

/*
 * Does a buzz if it is set to.
 */
void doBuzz(int frequency, boolean wait){
  if(buzz){
    tone(buzzerPin, frequency, buzzLength);
    if(wait){
      delay(buzzLength);
    }
  }
}

/*
 * Default function to not wait for buzz to finish.
 */
void doBuzz(){
  doBuzz(buzzDefaultFreq, false);
}

void checkButton(){
  buttonVal = digitalRead(buttonPin);
}

/*
 * Determines if it is time to do the feeding.
 */
boolean isFoodTime(){
  if(!timingEnabled){
    return false;
  }
  DateTime curTime = rtc.now();

  String hr = String(curTime.hour());
  String mn = String(curTime.minute());

  String time = hr + ":" + mn;

  for(int i = 0; i < sizeof(feedTimes); i++){
    if(feedTimes[i] == time){
      return true;
    }
  }

  return false;
}

String formatDateTime(DateTime dtIn){
  return String(dtIn.month()) + "/" + String(dtIn.day()) + "/" + String(dtIn.year()) + " " + String(dtIn.hour()) + ":" + String(dtIn.minute()) + ":" + String(dtIn.second());
}

String formatDateTime(){
    formatDateTime(rtc.now());
}

int getNumFromButton(int startAt){
  doBuzz(buzzFeedEndFreq, true);
  int longPressLength = 500;
  int output = startAt;
  bool counting = true;
  do{
    checkButton();
    if(buttonVal == HIGH){
        delay(longPressLength);
        checkButton();
        if(buttonVal == HIGH){
          counting = false;
        }else{
          output++;
          doBuzz(buzzConfirmFreq, true);
          delay(longPressLength);
        }
    }
  }while(counting);
  doBuzz(buzzConfirmFreq, true);
  delay(buzzLength);
  doBuzz(buzzConfirmFreq, true);
  return output;
}

void setTime(){
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  //Serial.print("Setting the clock... ("+formatDateTime()+")\n");
  delay(buzzLength);
  delay(buzzLength);
  doBuzz(buzzConfirmFreq, true);
  delay(buzzLength);
  doBuzz(buzzConfirmFreq, true);
  delay(buzzLength);
  doBuzz(buzzConfirmFreq, true);
  Serial.print("Getting Year... (");
  int year = getNumFromButton(2000);
  Serial.print(String(year) + ")\nGetting Month... (");
  int month = getNumFromButton(1);
  Serial.print(String(month) + ")\nGetting Day... (");
  int day = getNumFromButton(1);
  Serial.print(String(day) + ")\nGetting Hour... (");
  int hour = getNumFromButton(0);
  Serial.print(String(hour) + ")\nGetting Minute... (");
  int minute = getNumFromButton(0);
  Serial.print(String(minute) + ")\nGetting Second... (");
  int second = getNumFromButton(0);
  Serial.print(String(second) + ")\n");
  delay(buzzLength);
  doBuzz(buzzConfirmFreq, true);

  Serial.print("Finished getting numbers.\n");
  rtc.adjust(DateTime(year, month, day, hour, minute, second));
  Serial.print("Clock set to: " + formatDateTime() + "\n");
}

/*
 * Setup of things:
 *  - status led
 *  - buzzer
 *  - servo
 */
void setup(){
  Serial.begin(9600);
  Serial.print("\nBeginning setup of the CatFeeder.\n");
  // status led
  pinMode(onboardLedPin, OUTPUT);
  // buzzer
  pinMode(buzzerPin, OUTPUT);
  doBuzz();
  //servo
  dispenserServo.attach(servoPin);
  pinMode(servoPin, OUTPUT);
  dispenserServo.write(STOP);

  if(timingEnabled){
    //clock
    boolean rtcOn = rtc.begin();
    Serial.print(String(rtcOn) + "\n");
    if(! rtcOn){
      Serial.print("Couldn't find RTC. Timing Disabled\n");
      timingEnabled = false;
      doBuzz(buzzConfirmFreq, true);
      delay(buzzLength);
      doBuzz(buzzConfirmFreq, true);
      delay(buzzLength);
      doBuzz(buzzConfirmFreq, true);
      delay(buzzLength);    
      doBuzz(buzzConfirmFreq, true);
    }else{
      if(rtc.lostPower()){
        Serial.println("Clock lost power.\n");
        setTime();
      }
    }
  }
  if(!timingEnabled){
    Serial.print("Timing disabled. Will only actuate on button press.\n");
  }else{
    Serial.print("Current time: " + formatDateTime());
  }

  //button    
  pinMode(buttonPin, INPUT);

  Serial.print("Finished setup.\n\n");
}

Full code size:

Binary sketch size: 12,416 bytes (of a 32,256 byte maximum)

  • I'm assuming you read the text below the picture "Oops i removed the Power wire from 5V to the Vin rail before taking this pic, don't forget it!", and corrected that issue. Are you able to set and read the date/time using the ds3231.ino sketch that came with the library? – VE7JRO Oct 5 '17 at 2:20
  • If you never see anything right then check to make sure you have the serial monitor set to the same baud rate as the sketch. Otherwise you'll have to show some complete code that exhibits the issue. The problem obviously isn't in the setup function. – Delta_G Oct 5 '17 at 2:21
  • @VE7JRO I did, originally had it on the 3.3v, as I thought I saw somewhere that it could run on it. I moved it to 5v as a debugging measure. As stated above, It seems to work properly with the example code. – Snappawapa Oct 5 '17 at 2:25
  • @Delta_G unfortunately I have alot of code in this build already, hence the cut back example I gave. Tomorrow I will see about providing more – Snappawapa Oct 5 '17 at 2:28
  • I don't see how anyone could possibly spot the problem without being able to see it. Look for the obvious suspects like a buffer overrun or something. – Delta_G Oct 5 '17 at 2:33
0

Memory is never allocated for the result of formatDateTime().

Or more exactly there is a local variable inside formatDateTime() which has memory allocated as the string is built, then formatDateTime() returns a pointer to this memory, but as soon as the formatDateTime() exits this memory is freed, hence when Serial.print() is called and passed this pointer the memory at this pointer that used to hold the string may have already been reused.

  • So how might I solve this then? How would you change it? – Snappawapa Oct 5 '17 at 11:07
  • Ah! You were close..... I forgot to return on the formatDateTime() overriding function, causing the issue. Weird how it compiled though. Used to more error checking here I guess. Since the issue was in the realm of your answer (and it led me to solving the issue) I will mark this as accepted. – Snappawapa Oct 6 '17 at 0:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.