JeeLabs Precision RTC Module

Posted on
Page
of 2
Prev
/ 2
  • Thanks Gordon, I think I have made the appropriate changes correctly.

    There are no errors at least when I drop the code into the Espruino.

    When I type rtc into the console it returns
    ={"i2c":I2C1 }

    What is the syntax to call one of the public functions now? i.e. DS3231.prototype.readDateTime = function ()

  • I'd hope it's just rtc.readDateTime()...

  • Yes that works, got some errors to work though now but its at least calling it okay.

    It appears some of my old function code doesn't work. I have tried reflashing the board but still errors.
    Stepping all the way back to the code I posted in #19, I get the following error.

    ERROR: Got '}' expected EOF at line 1 col 286
    {I2C1.writeTo(104,0);var data=I2C1.readFrom(104,3);var seconds=("0"+data[0].toString(16)).subst­r(-2);var minutes=("0"+data[1].toString(16)).subst­r(-2);var hours=("0"+data[2].toString(16)).substr(­-2);var rtcTime=hours+":"+minutes+":"+seconds;pr­int(text,data);print(text,rtcTime);retur­n}
                                                                                                                                                                                                                                                                                                  ^
    at line 1 col 285
    {I2C1.writeTo(104,0);var data=I2C1.readFrom(104,3);var seconds=("0"+data[0].toString(16)).subst­r(-2);var minutes=("0"+data[1].toString(16)).subst­r(-2);var hours=("0"+data[2].toString(16)).substr(­-2);var rtcTime=hours+":"+minutes+":"+seconds;pr­int(text,data);print(text,rtcTime);retur­n}
                                                                                                                                                                                                                                                                                                 ^
    in function called from system
    ERROR: Error processing interval - removing it.
    Execution Interrupted during event processing.
    
  • Fixed! For some reason it didn't like the return statement on the end.

  • Ahh. Thanks for letting me know - I've just put a fix in for that, it'll be in 1v63.

  • Out of interest, did you turn on minification, or was that on by default?

  • Minification was set to 'Whitespace Only' in the IDE.
    Pretty sure that wasn't the default as I do remember messing around with it at some point to see what differences it made on the amount of free space.

  • How does this look?

    exports = {};
    
    var dstStatus = true;
    
    function DS3231(_i2c) { this.i2c = _i2c; }
    
    //private
    var C = {
      i2c_address: 0x68,
      dateReg : 0x04,
      monthReg : 0x05,
      yearReg : 0x06,
      secsReg : 0x00,
      minsReg : 0x01,
      hourReg : 0x02,
      dowReg : 0x03
    };
    
    //private functions
    // Convert Decimal value to BCD
    function dec2bcd(val) {
      return parseInt(val, 16);
    }
    
    // Convert BCD value to decimal
    function bcd2dec(val) {
      return ((val >> 4)*10+(val & 0x0F));
    }
    
    // Formatting
    function format(val) {
      return ("0"+val).substr(-2);
    }
    
    //DST
    function isDST(day,month,dow) {
      if ((month === 3) && (dow === 7) && (day > 23)) {
        return true;
      }
      if ((month === 10) && (dow === 7) && (day > 23)) {
        return false;
      }
      if ((month > 3) && (month < 11)) {
        return true;
      }
      else {
        return false;
      }
    }
    
    //public
    
    
    //public functions
    /* Put most of my comments outside the functions... */
    DS3231.prototype.setDow = function(day) {
      var days = ["Monday","Tuesday","Wednesday","Thursda­y","Friday","Saturday","Sunday"];
      var idx = days.indexOf(day);
      if (idx<0) {
        print("Not a valid day");
      }
      else {
        this.i2c.writeTo(C.i2c_address,[C.dowReg­, (dec2bcd(1+idx))]);
     }
    };
    
    DS3231.prototype.setDate = function(date,month,year) {
      this.i2c.writeTo(C.i2c_address,[C.dateRe­g, (dec2bcd(date))]);
      this.i2c.writeTo(C.i2c_address,[C.monthR­eg, (dec2bcd(month))]);
      this.i2c.writeTo(C.i2c_address,[C.yearRe­g, (dec2bcd(year))]);
      dstStatus = isDST(date,month,year);
    };
    
    DS3231.prototype.setTime = function(hour,minute) {
      this.i2c.writeTo(C.i2c_address,[C.secsRe­g, 0]);
      this.i2c.writeTo(C.i2c_address,[C.minsRe­g, (dec2bcd(minute))]);
      this.i2c.writeTo(C.i2c_address,[C.hourRe­g, (dec2bcd(hour))]);
    };
    
    DS3231.prototype.readDateTime = function () {
      this.i2c.writeTo(C.i2c_address, C.secsReg/* address*/);
      var data = this.i2c.readFrom(C.i2c_address, 7/* bytes */); //read number of bytes from address
      var seconds = bcd2dec(data[0]);
      var minutes = bcd2dec(data[1]);
      var hours = bcd2dec(data[2]);
      var dow = bcd2dec(data[3]);
      var date = bcd2dec(data[4]);
      var month = bcd2dec(data[5]);
      var year = bcd2dec(data[6]);
      
      //print(hours+" "+minutes+" "+seconds+" "+(isDST(date,month,dow))+" "+dstStatus);
      
      if (hours === 1 && minutes === 0 && seconds === 0 && isDST(date,month,dow) === true && dstStatus === false) { // clocks go forward
        this.i2c.writeTo(C.i2c_address,[C.hourRe­g, (dec2bcd(2))]);
        hours = 2;
        dstStatus = true;
      }
      
      if (hours === 2 && minutes === 0 && seconds === 0 && isDST(date,month,dow) === false && dstStatus === true) { // clocks go back
        this.i2c.writeTo(C.i2c_address,[C.hourRe­g, (dec2bcd(1))]);
        hours = 1;
        dstStatus = false;
      }
      
      var rtcDate = format(date)+"/"+format(month)+"/"+forma­t(year);
      var rtcTime = format(hours)+":"+format(minutes)+":"+fo­rmat(seconds);
      var rtcDateTime = rtcDate+" "+rtcTime;
      return rtcDateTime;
    };
    
    exports.connect = function(i2c) { return new DS3231(i2c); };
    
    I2C1.setup({scl:B6,sda:B7});
    var rtc = exports.connect(I2C1);
    
  • Looks great! Do you want to send a git pull request with a documentation page for it ( info ) or should I knock something up?

  • No problem Gordon I will follow the tutorial and put something together.

    There is one thing I didn't quite understand. Can you explain when you might use a public constant rather than a private constant?

  • Thanks!

    It's if you want someone using the module to be able to use that constant. For example:

    rtc = require(...)
    rtc.foo(rtc.C.WHATEVER);
    

    If you don't need them to be able to use it then you can make it private, and when the code is minified the minifier can then take that constant, remove it, and put the numeric value right into the I2C.writeTo statement (which will be faster and will use a bit less memory).

  • Thanks for all your help Gordon!

    If anyone has been following this the code has been merged into the main branch and is now available as a module.
    http://www.espruino.com/DS3231

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

JeeLabs Precision RTC Module

Posted by Avatar for StuntMonkeh @StuntMonkeh

Actions