// Aquire data from the RTC chip in BCD format void DS1307RTC::read( tmElements_t &tm) { Wire.beginTransmission(DS1307_CTRL_ID); #if ARDUINO >= 100 Wire.write((byte)0x00); #else Wire.send(0x00); #endif Wire.endTransmission(); // request the 7 data fields (secs, min, hr, dow, date, mth, yr) Wire.requestFrom(DS1307_CTRL_ID, tmNbrFields); #if ARDUINO >= 100 tm.Second = bcd2dec(Wire.read() & 0x7f); tm.Minute = bcd2dec(Wire.read() ); tm.Hour = bcd2dec(Wire.read() & 0x3f); // mask assumes 24hr clock tm.Wday = bcd2dec(Wire.read() ); tm.Day = bcd2dec(Wire.read() ); tm.Month = bcd2dec(Wire.read() ); tm.Year = y2kYearToTm((bcd2dec(Wire.read()))); #else tm.Second = bcd2dec(Wire.receive() & 0x7f); tm.Minute = bcd2dec(Wire.receive() ); tm.Hour = bcd2dec(Wire.receive() & 0x3f); // mask assumes 24hr clock tm.Wday = bcd2dec(Wire.receive() ); tm.Day = bcd2dec(Wire.receive() ); tm.Month = bcd2dec(Wire.receive() ); tm.Year = y2kYearToTm((bcd2dec(Wire.receive()))); #endif }
// Aquire data from the RTC chip in BCD format bool DS1307RTC::read(tmElements_t &tm) { uint8_t sec; Wire.beginTransmission(DS1307_CTRL_ID); Wire.write((uint8_t) 0x00); if (Wire.endTransmission() != 0) { exists = false; return false; } exists = true; // request the 7 data fields (secs, min, hr, dow, date, mth, yr) Wire.requestFrom(DS1307_CTRL_ID, tmNbrFields); if (Wire.available() < tmNbrFields) return false; sec = Wire.read(); tm.Second = bcd2dec(sec & 0x7f); tm.Minute = bcd2dec(Wire.read()); tm.Hour = bcd2dec(Wire.read() & 0x3f); // mask assumes 24hr clock tm.Wday = bcd2dec(Wire.read()); tm.Day = bcd2dec(Wire.read()); tm.Month = bcd2dec(Wire.read()); tm.Year = y2kYearToTm((bcd2dec(Wire.read()))); if (sec & 0x80) return false; // clock is halted return true; }
// -------------------------------------------------------- // Read the current time from the RTC and return it in a tmElements_t // structure. Returns the bus status (zero if successful). uint8_t DS1302RTC::read(tmElements_t &tm) { uint8_t buff[8]; readRTC(buff); tm.Second = bcd2dec(buff[0] & B01111111); // 7 bit (4L - sec, 3H - 10 sec), ignore CH bit tm.Minute = bcd2dec(buff[1] & B01111111); // 7 bit (4L - min, 3H - 10 min), ignore NULL bit tm.Hour = bcd2dec(buff[2] & B00111111); // 6 bit (4L - hrs, 2H - 10 hrs), ignore NULL & 12/24 bits tm.Day = bcd2dec(buff[3] & B00111111); // 6 bit (4L - dat, 2H - 10 dat), ignore 2 NULLs tm.Month = bcd2dec(buff[4] & B00011111); // 5 bit (4L - mth, 1H - 10 mth), ignore 3 NULLs tm.Wday = buff[5] & B00000111 ; // 3 bit, ignore 5 NULLs tm.Year = y2kYearToTm( bcd2dec(buff[6])); // 8 bit // Validation if(tm.Second >= 0 && tm.Second <= 59) if(tm.Minute >= 0 && tm.Minute <= 59) if(tm.Hour >= 0 && tm.Hour <= 23) if(tm.Day >= 1 && tm.Day <= 31) if(tm.Month >= 1 && tm.Month <= 12) if(tm.Wday >= 1 && tm.Wday <= 7) if(tm.Year >= 0 && tm.Year <= 99) return 0; // Success return 1; // Error }
// Aquire data from the RTC chip in BCD format void MCP7940RTC::read(tmElements_t &tm) { uint8_t d[8]; uint8_t dmask[] = { 0x7f, 0x7f, 0x3f, 0x07, 0x3f, 0x1f, 0xff }; memset(d,0,8); Wire.beginTransmission(MCP7940_CTRL_ID); #if ARDUINO >= 100 Wire.write((uint8_t)0x00); #else Wire.send(0x00); #endif Wire.endTransmission(); // request the 7 data fields (secs, min, hr, dow, date, mth, yr) Wire.requestFrom(MCP7940_CTRL_ID, tmNbrFields); #if ARDUINO >= 100 tm.Second = bcd2dec((Wire.read() & 0x7f)); tm.Minute = bcd2dec((Wire.read() & 0x7f)); byte b1 = Wire.read(); byte b2 = b1 & 0x1f; if((b1 & 0x40)>0) b2 |= 0x20; tm.Hour = bcd2dec(b1 & 0x3f); //tm.Hour = bcd2dec(Wire.read() & 0x3f); // mask assumes 24hr clock tm.Wday = bcd2dec((Wire.read() & 0x07)); tm.Day = bcd2dec(Wire.read() & 0x3f ); tm.Month = bcd2dec(Wire.read() & 0x1f); //tm.Year = bcd2dec(Wire.read()) + 30;// tm.Year = y2kYearToTm((bcd2dec(Wire.read()))); #else tm.Second = bcd2dec(Wire.receive() & 0x7f); tm.Minute = bcd2dec(Wire.receive() ); byte b1 = Wire.receive(); byte b2 = b1 & 0x1f; if((b1 & 0x40)>0) b2 |= 0x20; tm.Hour = bcd2dec(b1 & 0x3f); // mask assumes 24hr clock tm.Wday = bcd2dec(Wire.receive() ); tm.Day = bcd2dec(Wire.receive() & 0x07); tm.Month = bcd2dec(Wire.receive() & 0x1f ); tm.Year = y2kYearToTm((bcd2dec(Wire.receive()))); #endif }
/*----------------------------------------------------------------------* * Read the current time from the RTC and return it in a tmElements_t * * structure. Returns the I2C status (zero if successful). * *----------------------------------------------------------------------*/ byte DS3232RTC::read(tmElements_t &tm) { i2cBeginTransmission(RTC_ADDR); i2cWrite((uint8_t)RTC_SECONDS); if ( byte e = i2cEndTransmission() ) return e; //request 7 bytes (secs, min, hr, dow, date, mth, yr) i2cRequestFrom(RTC_ADDR, tmNbrFields); tm.Second = bcd2dec(i2cRead() & ~_BV(DS1307_CH)); tm.Minute = bcd2dec(i2cRead()); tm.Hour = bcd2dec(i2cRead() & ~_BV(HR1224)); //assumes 24hr clock tm.Wday = i2cRead(); tm.Day = bcd2dec(i2cRead()); tm.Month = bcd2dec(i2cRead() & ~_BV(CENTURY)); //don't use the Century bit tm.Year = y2kYearToTm(bcd2dec(i2cRead())); return 0; }
/* * getTime */ time_t DS1339::getTime() // Aquire data from buffer and convert to time_t { byte buffer[7]; tmElements_t tm; if(readBytes(buffer, 0, 7) == 7) { tm.Second = bcd2dec(buffer[0] & DS1339_SEC_MASK); tm.Minute = bcd2dec(buffer[1]); tm.Hour = bcd2dec(buffer[2] & DS1339_HR_MASK); // mask assumes 24hr clock tm.Wday = bcd2dec(buffer[3]); tm.Day = bcd2dec(buffer[4]); tm.Month = bcd2dec(buffer[5]); tm.Year = y2kYearToTm((bcd2dec(buffer[6]))); } return(makeTime(tm)); }
// Aquire data from the RTC chip in BCD format void DS3231RTC::read( tmElements_t &tm) { Wire.beginTransmission(DS3231_CTRL_ID); Wire.write((uint8_t)0); Wire.endTransmission(); // request the 7 data fields (secs, min, hr, dow, date, mth, yr) Wire.requestFrom(DS3231_CTRL_ID, tmNbrFields); tm.Second = bcd2dec(Wire.read() & 0x7f); tm.Minute = bcd2dec(Wire.read() ); tm.Hour = bcd2dec(Wire.read() & 0x3f); // mask assumes 24hr clock tm.Wday = bcd2dec(Wire.read() ); tm.Day = bcd2dec(Wire.read() ); tm.Month = bcd2dec(Wire.read() ); tm.Year = y2kYearToTm((bcd2dec(Wire.read()))); }
// Aquire data from the RTC chip in BCD format void DS1307RTC::read( tmElements_t &tm) { if (!ctrl_id) return; Wire.beginTransmission(ctrl_id); Wire.write((uint8_t)0x00); Wire.endTransmission(); // request the 7 data fields (secs, min, hr, dow, date, mth, yr) Wire.requestFrom(ctrl_id, tmNbrFields); tm.Second = bcd2dec(Wire.read() & 0x7f); tm.Minute = bcd2dec(Wire.read() ); tm.Hour = bcd2dec(Wire.read() & 0x3f); // mask assumes 24hr clock tm.Wday = bcd2dec(Wire.read() & 0x07); tm.Day = bcd2dec(Wire.read() ); tm.Month = bcd2dec(Wire.read() & 0x1f); // fix bug for MCP7940 tm.Year = y2kYearToTm((bcd2dec(Wire.read()))); }
// Aquire data from the RTC chip in BCD format bool DS1307RTC::read(tmElements_t &tm) { uint8_t sec; if (I2c.write(DS1307_CTRL_ID, 0x00) != 0) { exists = false; return false; } exists = true; // request the 7 data fields (secs, min, hr, dow, date, mth, yr) I2c.read(DS1307_CTRL_ID, tmNbrFields); if (I2c.available() < tmNbrFields) return false; sec = I2c.receive(); tm.Second = bcd2dec(sec & 0x7f); tm.Minute = bcd2dec(I2c.receive() ); tm.Hour = bcd2dec(I2c.receive() & 0x3f); // mask assumes 24hr clock tm.Wday = bcd2dec(I2c.receive() ); tm.Day = bcd2dec(I2c.receive() ); tm.Month = bcd2dec(I2c.receive() ); tm.Year = y2kYearToTm((bcd2dec(I2c.receive()))); if (sec & 0x80) return false; // clock is halted return true; }
//$GPRMC,225446.000,A,4916.45,N,12311.12,W,000.5,054.7,191194,020.3,E*68\r\n // 0 1 2 3 4 5 6 7 // 0123456789012345678901234567890123456789012345678901234567890123456789012 // 0 1 2 3 4 5 6 7 8 9 10 11 12 void parseGPSdata(char *gpsBuffer) { time_t tNow; tmElements_t tm; uint8_t gpsCheck1, gpsCheck2; // checksums // char gpsTime[10]; // time including fraction hhmmss.fff char gpsFixStat; // fix status // char gpsLat[7]; // ddmm.ff (with decimal point) // char gpsLatH; // hemisphere // char gpsLong[8]; // dddmm.ff (with decimal point) // char gpsLongH; // hemisphere // char gpsSpeed[5]; // speed over ground // char gpsCourse[5]; // Course // char gpsDate[6]; // Date // char gpsMagV[5]; // Magnetic variation // char gpsMagD; // Mag var E/W // char gpsCKS[2]; // Checksum without asterisk char *ptr; uint32_t tmp; if ( strncmp( gpsBuffer, "$GPRMC,", 7 ) == 0 ) { //Serial.println("parseGPSData"); //Serial.println(gpsBuffer); //beep(1000, 1); //Calculate checksum from the received data ptr = &gpsBuffer[1]; // start at the "G" gpsCheck1 = 0; // init collector /* Loop through entire string, XORing each character to the next */ while (*ptr != '*') // count all the bytes up to the asterisk { gpsCheck1 ^= *ptr; ptr++; if (ptr>(gpsBuffer+GPSBUFFERSIZE)) goto GPSerror1; // extra sanity check, can't hurt... } // now get the checksum from the string itself, which is in hex gpsCheck2 = atoh(*(ptr+1)) * 16 + atoh(*(ptr+2)); if (gpsCheck1 == gpsCheck2) { // if checksums match, process the data //beep(1000, 1); ptr = strtok(gpsBuffer, ",*\r"); // parse $GPRMC if (ptr == NULL) goto GPSerror1; ptr = strtok(NULL, ",*\r"); // Time including fraction hhmmss.fff if (ptr == NULL) goto GPSerror1; if ((strlen(ptr) < 6) || (strlen(ptr) > 10)) goto GPSerror1; // check time length // strncpy(gpsTime, ptr, 10); // copy time string hhmmss tmp = parsedecimal(ptr); // parse integer portion tm.Hour = tmp / 10000; tm.Minute = (tmp / 100) % 100; tm.Second = tmp % 100; ptr = strtok(NULL, ",*\r"); // Status if (ptr == NULL) goto GPSerror1; gpsFixStat = ptr[0]; if (gpsFixStat == 'A') { // if data valid, parse time & date gpsTimeout = 0; // reset gps timeout counter ptr = strtok(NULL, ",*\r"); // Latitude including fraction if (ptr == NULL) goto GPSerror1; // strncpy(gpsLat, ptr, 7); // copy Latitude ddmm.ff ptr = strtok(NULL, ",*\r"); // Latitude N/S if (ptr == NULL) goto GPSerror1; // gpsLatH = ptr[0]; ptr = strtok(NULL, ",*\r"); // Longitude including fraction hhmm.ff if (ptr == NULL) goto GPSerror1; // strncpy(gpsLong, ptr, 7); ptr = strtok(NULL, ",*\r"); // Longitude Hemisphere if (ptr == NULL) goto GPSerror1; // gpsLongH = ptr[0]; ptr = strtok(NULL, ",*\r"); // Ground speed 000.5 if (ptr == NULL) goto GPSerror1; // strncpy(gpsSpeed, ptr, 5); ptr = strtok(NULL, ",*\r"); // Track angle (course) 054.7 if (ptr == NULL) goto GPSerror1; // strncpy(gpsCourse, ptr, 5); ptr = strtok(NULL, ",*\r"); // Date ddmmyy if (ptr == NULL) goto GPSerror1; // strncpy(gpsDate, ptr, 6); if (strlen(ptr) != 6) goto GPSerror1; // check date length tmp = parsedecimal(ptr); tm.Day = tmp / 10000; tm.Month = (tmp / 100) % 100; tm.Year = tmp % 100; ptr = strtok(NULL, "*\r"); // magnetic variation & dir if (ptr == NULL) goto GPSerror1; if (ptr == NULL) goto GPSerror1; ptr = strtok(NULL, ",*\r"); // Checksum if (ptr == NULL) goto GPSerror1; // strncpy(gpsCKS, ptr, 2); // save checksum chars tm.Year = y2kYearToTm(tm.Year); // convert yy year to (yyyy-1970) (add 30) tNow = makeTime(&tm); // convert to time_t if ((tGPSupdate>0) && (abs(tNow-tGPSupdate)>SECS_PER_DAY)) goto GPSerror2; // GPS time jumped more than 1 day if ((tm.Second == 0) || ((tNow - tGPSupdate)>=60)) { // update RTC once/minute or if it's been 60 seconds //beep(1000, 1); // debugging g_gps_updating = true; tGPSupdate = tNow; // remember time of this update tNow = tNow + (long)(g_TZ_hour + g_DST_offset) * SECS_PER_HOUR; // add time zone hour offset & DST offset if (g_TZ_hour < 0) // add or subtract time zone minute offset tNow = tNow - (long)g_TZ_minute * SECS_PER_HOUR; else tNow = tNow + (long)g_TZ_minute * SECS_PER_HOUR; setRTCTime(tNow); // set RTC from adjusted GPS time & date } else g_gps_updating = false; } // if fix status is A } // if checksums match else // checksums do not match g_gps_cks_errors++; // increment error count return; GPSerror1: g_gps_parse_errors++; // increment error count goto GPSerror2a; GPSerror2: g_gps_time_errors++; // increment error count GPSerror2a: //beep(2093,1); // error signal - I'm leaving this in for now /wm //flash_display(200); // flash display to show GPS error strcpy(gpsBuffer, ""); // wipe GPS buffer } // if "$GPRMC" }