Alarm uitgang DS3231 problemen

blackdog

Golden Member

Hi,

Voor ondermeer de reis referentie wil ik één van de uitgangen van een DS3231 klok moduul gebruiken.
Het gaat om pin-3 welke als INT/SQW omscheven wordt van het DS3231 IC.

De bedoeling is dat deze pin, wat een open Drain is, laag getrokken wordt als er wordt voldaan aan een door mij ingestelde alarm tijd.
Een van de functies wordt natuurlijk een Arduino of andere Micro controler wakker te maken om wat metingen te doen.
Maar ik heb nog wat meer toepassingen voor deze functie.

Weet iemand een library of andere code waarmee dit voor mij simpel is in te stellen?
Ik heb al zeker 5 verschillende library's uitgeplozen en gezocht op youtube, maar bijna niemand laat duidelijke voorbeelden zien met de INT/SQW aansluiting...

Ondertussen denk ik dat het sneller is een klokje met wekker functie te gaan gebruiken...
En voor de gene die het nog niet begrepen hebben, de DS3231 moduul moet ook los staand gebruik kunnen worden met deze alarm functie.
Dus met b.v. een Arduino de alarm tijden er in programmeren en dan de DS3231 moduul los gebruiken voor een toepassing naar keuze.

Mijn dank is alvast groot!

Groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"

Hallo Blackdog,

De code hieronder zou moeten werken (heb het in ieder geval getest op een een arduino nano). Als de open drain van de RTC pin 2 laag trekt wordt de arduino uit zijn slaap modus gehaald. In dit geval knippert het ledje een paar keer en wordt de slaap modus geïnitieerd. Een belangrijke sidenote hierbij is:

  • Verwijder het "power on" LEDje
  • Neem een arduino pro oid waar geen serieel<-> usb chip op zit. Anders gaat je winst als nog verloren
  • Zit er een LDO op voor 3.3v die je niet gebruikt? Dan die er ook beter maar afhalen.

Doordat op de nano wel een serieel<-> usb chip opzit is het slaap verbruik als nog 3 mA. Je moet sub µA kunnen komen met de slaap modus

c code:


#include <avr/sleep.h>

// --------CONSTANTS (won't change)---------------
const int wakePin = 2;                 // pin used for waking up
const int LEDPin  = 13;                 // pin used for led blinking

//------------ VARIABLES (will change)---------------------
unsigned int cutoffTime = 0;           // variable used for time keeping
unsigned int BlinkTime  = 4000;        // variable which sets blinking period in ms
//====================================================


void wakeUpNow()//here the code will start after the interrupt. re initialise
{ cutoffTime = millis();                 //initialize the counter
}

void setup()
{
  pinMode(LEDPin, OUTPUT);
  pinMode(wakePin,INPUT);
  digitalWrite(LEDPin, HIGH);         //Defines that LED is certainly off
  digitalWrite(wakePin,HIGH);         //pull up enabled
  
  cutoffTime = millis();              //initialize the counter
}

void sleepNow() //interrupt
{ // shut off everything not used
  //MCUCR |= (1 << PUD); // disable port pullups, can be used if external pull ups are used
  //ADCSRA = 0x00; // disable ADC, could be used when ADC is not needed
  sleep_bod_disable(); // turn off brown-out detector
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  attachInterrupt(0,wakeUpNow,HIGH);//Interrupt when wakePin gets high, ie button is pushed (0== pin 2
  sleep_mode();
  sleep_disable();
  detachInterrupt(0);
}

void loop()
{ while (millis() - cutoffTime < BlinkTime)
  { digitalWrite(LEDPin, HIGH);
    delay(250);
    digitalWrite(LEDPin, LOW);
    delay(250);
  }
  sleepNow();//Going in sleep modi
}

ps je zal wel code moeten toevoegen om de RTC in te stellen denk ik

Op 29 mei 2019 00:01:16 schreef blackdog:
Weet iemand een library of andere code waarmee dit voor mij simpel is in te stellen?
Ik heb al zeker 5 verschillende library's uitgeplozen en gezocht op youtube, maar bijna niemand laat duidelijke voorbeelden zien met de INT/SQW aansluiting...

Misschien begrijp ik je vraag niet... maar het is toch een kwestie van de juiste bitjes aan- of uitzetten in de controleregisters van de DS3231? Dus op een vergelijkbare manier als waarmee je het alarm instelt, maar dan op een ander adres.

Het staat helemaal gedocumenteerd in de datasheet.

Zelf heb ik ooit zoiets gemaakt met een 12F629 Pic in assembly.

instellen I2C RTC (is wel een iets andere) wordt hier beschreven:
http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock De eerste 7 bytes van jouw RTC zijn in iedergeval gelijk aan die van de RTC1307.

blackdog

Golden Member

Hi Heren,

Dank voor de input, maar dit is toch niet helemaal waar ik hulp mee vraag. :-)
Wat betreft de slaap modi van de processor, daar ben ik mee bekend,
ook wat betreft het uitschakelen van allerlij onderdelen om het stroomverbruik nog lager te krijgen.
Titatommeke, ik sla in ieder geval je stukje code op voor de slaap modus om te kijken of ik dit later kan toepassen.

Het laagste verbruik is voor mijn reisreferentie niet super belangrijk,
dit omdat het stroomverbruik van het oventje dat daarin zit, dominant is wat energieverbruik betreft.

Maar het gaat om het programmeren van de DS3231, daar kom/kwam ik niet uit.(ik ben geen software schrijver) :-)

Wat ik wel al weet is dit.
Er is "standaard" een 1HZ signaal op die uitgang aanwezig, en dit moet worden uitgezet.
In de setup moeten de twee alarm functie worden gereset, voor dat deze weer worden ingesteld.

Ondertussen het ik nog een Library gevonden waar de functies die ik nodig heb in zijn verwerkt.
Dus ik ga daar in de loop van de dag eens mee testen.

Het gaat om deze: https://github.com/JChristensen/DS3232RTC

Je kan de uitgang als alarm gebruiken, maar als je hem wilt gebruiken als Interrupt voor een microcontroler
dan zit naar een speciale functie voor in de library.

Dit is een van de voorbeelden die bij de Library zit en waar ik mee ga testen.

c code:

// Arduino DS3232RTC Library
// https://github.com/JChristensen/DS3232RTC
// Copyright (C) 2018 by Jack Christensen and licensed under
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
//
// DS3231/DS3232 Alarm Example Sketch #2
//
// Set Alarm 1 to occur once a minute at 5 seconds after the minute.
// Configure the RTC INT/SQW pin to be asserted when alarm match occurs.
// Detect the alarm by polling the INT/SQW pin.
//
// Hardware:
// Arduino Uno, DS3231 RTC.
// Connect RTC SDA to Arduino pin A4.
// Connect RTC SCL to Arduino pin A5.
// Connect RTC INT/SQW to Arduino pin 2.
//
// Jack Christensen 16Sep2017

#include <DS3232RTC.h>        // https://github.com/JChristensen/DS3232RTC
#include <Streaming.h>        // http://arduiniana.org/libraries/streaming/

// pin definitions
const uint8_t alarmInput(2);

void setup()
{
    Serial.begin(115200);
    pinMode(2, INPUT_PULLUP);

    // initialize the alarms to known values, clear the alarm flags, clear the alarm interrupt flags
    RTC.setAlarm(ALM1_MATCH_DATE, 0, 0, 0, 1);
    RTC.setAlarm(ALM2_MATCH_DATE, 0, 0, 0, 1);
    RTC.alarm(ALARM_1);
    RTC.alarm(ALARM_2);
    RTC.alarmInterrupt(ALARM_1, false);
    RTC.alarmInterrupt(ALARM_2, false);
    RTC.squareWave(SQWAVE_NONE);

    tmElements_t tm;
    tm.Hour = 00;               // set the RTC to an arbitrary time
    tm.Minute = 00;
    tm.Second = 00;
    tm.Day = 16;
    tm.Month = 9;
    tm.Year = 2017 - 1970;      // tmElements_t.Year is the offset from 1970
    RTC.write(tm);              // set the RTC from the tm structure

    // set Alarm 1 to occur at 5 seconds after every minute
    RTC.setAlarm(ALM1_MATCH_SECONDS, 5, 0, 0, 0);
    // clear the alarm flag
    RTC.alarm(ALARM_1);
    // configure the INT/SQW pin for "interrupt" operation (disable square wave output)
    RTC.squareWave(SQWAVE_NONE);
    // enable interrupt output for Alarm 1
    RTC.alarmInterrupt(ALARM_1, true);

    Serial << millis() << " Start ";
    printDateTime(RTC.get());
    Serial << endl;
}

void loop()
{
    // check to see if the INT/SQW pin is low, i.e. an alarm has occurred
    if ( !digitalRead(alarmInput) )
    {
        RTC.alarm(ALARM_1);    // reset the alarm flag
        Serial << millis() << " ALARM_1 ";
        printDateTime(RTC.get());
        Serial << endl;
    }
}

void printDateTime(time_t t)
{
    Serial << ((day(t)<10) ? "0" : "") << _DEC(day(t));
    Serial << monthShortStr(month(t)) << _DEC(year(t)) << ' ';
    Serial << ((hour(t)<10) ? "0" : "") << _DEC(hour(t)) << ':';
    Serial << ((minute(t)<10) ? "0" : "") << _DEC(minute(t)) << ':';
    Serial << ((second(t)<10) ? "0" : "") << _DEC(second(t));
}

In ieder geval bedankt voor de input en ik zal laten zien wat ik ga gebruiken als ik de code zo krijg ingesteld
zoals voor mijn projecten nodig is.
Of als ik vastloop vraag ik weer wat...

Groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"
blackdog

Golden Member

Hi,

Ik ben de documentatie aan het lezen die bij de DS323x Library zit van JChristensen.
Een stukje uit de documentatie vond ik zeer raak en dat geld niet alleen voor de alarm functie van de DS323X klok IC's.
Zie het stukje hieronder van JChristensen:

It's probably natural that when we think about an "alarm" we think of the clock radio that we might have on our nightstand. Pretty much everyone is familiar with how these devices work but the first thing we need to do is forget that paradigm because the DS323x alarms aren't necessarily a lot like clock radio alarms. My advice is: Don't have any preconceived notions as to how an "alarm" works. First understand how the RTC alarms work, and only then, consider how to apply them to your particular application.

Vervang "alarm" voor allerlij zaken die je wilt leren of toepassen :-)

Nu weer verder studeren!

Groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"