@@ -1,5 +1,6 @@ | |||
#include "Gps.h" | |||
#include "Debug.h" | |||
#include "Hardware.h" | |||
#define LOGGER_NAME "Gps" | |||
@@ -8,13 +9,9 @@ namespace gps { | |||
char lastPosition[GPS_POSITION_SIZE]; | |||
SIM808_GPS_STATUS lastStatus; | |||
void powerOn() { | |||
/*inline */void powerOn() { hardware::sim808::gpsPowerOn(); } | |||
/*inline */void powerOff() { hardware::sim808::gpsPowerOff(); } | |||
} | |||
void powerOff() { | |||
} | |||
SIM808_GPS_STATUS acquireCurrentPosition() { | |||
SIM808_GPS_STATUS currentStatus = SIM808_GPS_STATUS::OFF; | |||
@@ -27,7 +24,7 @@ namespace gps { | |||
return currentStatus; | |||
} | |||
time_t getTime() { | |||
timestamp_t getTime() { | |||
} | |||
} |
@@ -1,9 +1,10 @@ | |||
#pragma once | |||
#include <TimeLib.h> | |||
#include <Time.h> | |||
#include <SIM808.h> | |||
#include "Hardware.h" | |||
#include "Time2.h" | |||
#define GPS_POSITION_SIZE 128 | |||
namespace gps { | |||
@@ -13,8 +14,8 @@ namespace gps { | |||
void powerOn(); | |||
void powerOff(); | |||
SIM808_GPS_STATUS acquireCurrentPosition(); | |||
time_t getTime(); | |||
timestamp_t getTime(); | |||
} |
@@ -3,15 +3,11 @@ | |||
#include <Arduino.h> | |||
#include <SoftwareSerial.h> | |||
#include <SIM808.h> | |||
#include <TimeLib.h> | |||
#include <Time.h> | |||
#include "Debug.h" | |||
#include "Core.h" | |||
#include "posmgr.h" | |||
#include "Gps.h" | |||
#include "posmgr.h" | |||
#include "MainUnit.h" | |||
#include "Network.h" | |||
#include "Rtc.h" | |||
@@ -21,7 +21,9 @@ void loop() { | |||
gps::powerOff(); | |||
if (gpsStatus > SIM808_GPS_STATUS::NO_FIX) { | |||
time_t time = gps::getTime(); | |||
timestamp_t time = gps::getTime(); | |||
tmElements_t t; | |||
breakTime(time, t); | |||
rtc::powerOn(); | |||
rtc::setTime(time); | |||
rtc::powerOff(); | |||
@@ -1,13 +1,15 @@ | |||
#include "Hardware.h" | |||
#include "Pins.h" | |||
#include <SoftwareSerial.h> | |||
#include <SIM808.h> | |||
#include <SIM808_Types.h> | |||
namespace hardware { | |||
namespace sim808 { | |||
SoftwareSerial simSerial = SoftwareSerial(SIM_TX, SIM_RX); | |||
SIM808 sim = SIM808(0, SIM_PWR, SIM_STATUS); | |||
SIM808 device = SIM808(SIM_RST, SIM_PWR, SIM_STATUS); | |||
//idea : int powered | |||
//gps::powerOn() => +1 | |||
//network::powerOn() => +1 | |||
@@ -18,11 +20,54 @@ namespace hardware { | |||
//gps/network::powerOff() => powered == 1 => sim808::powerOff() | |||
//idea : gps power on = +1, network power on = +1 => powerOff forces power off of all, powerOff one will lead to actual powerOff if | |||
void powerOn() { | |||
bool poweredOn = device.powerOnOff(true); | |||
if (!poweredOn) return; | |||
device.init(); | |||
} | |||
void powerOff() { | |||
bool poweredOff = device.powerOnOff(false); | |||
} | |||
void init() { | |||
device.powerOnOff(true); | |||
simSerial.begin(4800); | |||
device.begin(simSerial); | |||
device.init(); | |||
} | |||
void powerOffIfUnused() { | |||
bool gpsPowered = false; | |||
bool gprsPowered = false; | |||
if ((device.getGpsPowerState(&gpsPowered) && !gpsPowered) && | |||
(device.getGprsPowerState(&gprsPowered) && !gprsPowered)) { | |||
powerOff(); | |||
} | |||
} | |||
void gpsPowerOn() { | |||
powerOn(); | |||
device.enableGps(); | |||
} | |||
void gpsPowerOff() { | |||
device.disableGps(); | |||
powerOffIfUnused(); | |||
} | |||
void networkPowerOn() { | |||
powerOn(); | |||
device.setPhoneFunctionality(SIM808_PHONE_FUNCTIONALITY::FULL); | |||
device.enableGprs("Free"); //TODO : configure | |||
} | |||
void networkPowerOff() { | |||
device.setPhoneFunctionality(SIM808_PHONE_FUNCTIONALITY::MINIMUM); | |||
device.disableGprs(); | |||
powerOffIfUnused(); | |||
} | |||
} | |||
@@ -35,4 +80,4 @@ namespace hardware { | |||
void powerOn(); | |||
void powerOff(); | |||
} | |||
} | |||
} |
@@ -9,6 +9,14 @@ namespace hardware { | |||
void powerOn(); | |||
void powerOff(); | |||
void init(); | |||
void gpsPowerOn(); | |||
void gpsPowerOff(); | |||
void networkPowerOn(); | |||
void networkPowerOff(); | |||
} | |||
namespace rtc { | |||
@@ -1,9 +1,9 @@ | |||
#include "Network.h" | |||
#include "Hardware.h" | |||
#define LOGGER_NAME "Network" | |||
namespace network { | |||
void powerOn() {} | |||
void powerOff() {} | |||
/*inline */void powerOn() { hardware::sim808::networkPowerOn(); } | |||
/*inline */void powerOff() { hardware::sim808::networkPowerOff(); } | |||
} |
@@ -1,6 +1,9 @@ | |||
#pragma once | |||
#include "Hardware.h" | |||
namespace network { | |||
void powerOn(); | |||
void powerOff(); | |||
/*inline */void powerOn(); | |||
/*inline */void powerOff(); | |||
} |
@@ -1,7 +1,8 @@ | |||
#pragma once | |||
#define SIM_RX 5 | |||
#define SIM_TX 6 | |||
#define SIM_RST 5 | |||
#define SIM_RX 6 | |||
#define SIM_TX 7 | |||
#define SIM_PWR 9 | |||
#define SIM_STATUS 8 | |||
@@ -10,7 +10,7 @@ namespace rtc { | |||
namespace details { | |||
time_t readTimeFromRegisters() { | |||
timestamp_t readTimeFromRegisters() { | |||
tmElements_t tmElements = { | |||
RTC.s, | |||
RTC.m, | |||
@@ -24,7 +24,7 @@ namespace rtc { | |||
return makeTime(tmElements); | |||
} | |||
void writeTimeToRegisters(time_t &time) { | |||
void writeTimeToRegisters(timestamp_t &time) { | |||
tmElements_t tmElements; | |||
breakTime(time, tmElements); | |||
@@ -64,23 +64,23 @@ namespace rtc { | |||
RTC.control(DS3231_INT_ENABLE, DS3231_OFF); //INTCN OFF | |||
} | |||
time_t getTime() { | |||
timestamp_t getTime() { | |||
RTC.readTime(); | |||
return details::readTimeFromRegisters(); | |||
} | |||
void setTime(time_t &time) { | |||
void setTime(timestamp_t &time) { | |||
details::writeTimeToRegisters(time); | |||
RTC.writeTime(); | |||
} | |||
void setAlarm(uint16_t seconds) { | |||
time_t t = getTime(); | |||
timestamp_t t = getTime(); | |||
t = t + seconds; | |||
setAlarm(t); | |||
} | |||
void setAlarm(time_t &time) { | |||
void setAlarm(timestamp_t &time) { | |||
details::writeTimeToRegisters(time); | |||
RTC.writeAlarm1(DS3231_ALM_S); | |||
@@ -1,7 +1,6 @@ | |||
#pragma once | |||
#include <TimeLib.h> | |||
#include <Time.h> | |||
#include "Time2.h" | |||
namespace rtc { | |||
void powerOn(); | |||
@@ -9,9 +8,9 @@ namespace rtc { | |||
void setup(); | |||
time_t getTime(); | |||
void setTime(time_t &time); | |||
timestamp_t getTime(); | |||
void setTime(timestamp_t &time); | |||
void setAlarm(uint16_t seconds); | |||
void setAlarm(time_t &time); | |||
void setAlarm(timestamp_t &time); | |||
} |
@@ -0,0 +1,130 @@ | |||
#include "Time2.h" | |||
/*==============================================================================*/ | |||
/* Useful Constants */ | |||
#define SECS_PER_MIN (60UL) | |||
#define SECS_PER_HOUR (3600UL) | |||
#define SECS_PER_DAY (SECS_PER_HOUR * 24UL) | |||
#define DAYS_PER_WEEK (7UL) | |||
#define SECS_PER_WEEK (SECS_PER_DAY * DAYS_PER_WEEK) | |||
#define SECS_PER_YEAR (SECS_PER_WEEK * 52UL) | |||
#define SECS_YR_2000 (946684800UL) // the time at the start of y2k | |||
/* Useful Macros for getting elapsed time */ | |||
#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN) | |||
#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN) | |||
#define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR) | |||
#define dayOfWeek(_time_) ((( _time_ / SECS_PER_DAY + 4) % DAYS_PER_WEEK)+1) // 1 = Sunday | |||
#define elapsedDays(_time_) ( _time_ / SECS_PER_DAY) // this is number of days since Jan 1 1970 | |||
#define elapsedSecsToday(_time_) (_time_ % SECS_PER_DAY) // the number of seconds since last midnight | |||
// The following macros are used in calculating alarms and assume the clock is set to a date later than Jan 1 1971 | |||
// Always set the correct time before settting alarms | |||
#define previousMidnight(_time_) (( _time_ / SECS_PER_DAY) * SECS_PER_DAY) // time at the start of the given day | |||
#define nextMidnight(_time_) ( previousMidnight(_time_) + SECS_PER_DAY ) // time at the end of the given day | |||
#define elapsedSecsThisWeek(_time_) (elapsedSecsToday(_time_) + ((dayOfWeek(_time_)-1) * SECS_PER_DAY) ) // note that week starts on day 1 | |||
#define previousSunday(_time_) (_time_ - elapsedSecsThisWeek(_time_)) // time at the start of the week for the given time | |||
#define nextSunday(_time_) ( previousSunday(_time_)+SECS_PER_WEEK) // time at the end of the week for the given time | |||
/* Useful Macros for converting elapsed time to a timestamp_t */ | |||
#define minutesTotimestamp_t ((M)) ( (M) * SECS_PER_MIN) | |||
#define hoursTotimestamp_t ((H)) ( (H) * SECS_PER_HOUR) | |||
#define daysTotimestamp_t ((D)) ( (D) * SECS_PER_DAY) // fixed on Jul 22 2011 | |||
#define weeksTotimestamp_t ((W)) ( (W) * SECS_PER_WEEK) | |||
// leap year calulator expects year argument as years offset from 1970 | |||
#define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) ) | |||
static const uint8_t monthDays[] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; // API starts months from 1, this array starts from 0 | |||
__attribute__((__optimize__("O2"))) | |||
void breakTime(timestamp_t timeInput, tmElements_t &tm) { | |||
// break the given timestamp_t into time components | |||
// this is a more compact version of the C library localtime function | |||
// note that year is offset from 1970 !!! | |||
uint8_t year; | |||
uint8_t month, monthLength; | |||
uint32_t time; | |||
unsigned long days; | |||
time = (uint32_t)timeInput; | |||
tm.Second = time % 60; | |||
time /= 60; // now it is minutes | |||
tm.Minute = time % 60; | |||
time /= 60; // now it is hours | |||
tm.Hour = time % 24; | |||
time /= 24; // now it is days | |||
tm.Wday = ((time + 4) % 7) + 1; // Sunday is day 1 | |||
year = 0; | |||
days = 0; | |||
while ((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) { | |||
year++; | |||
} | |||
tm.Year = year; // year is offset from 1970 | |||
days -= LEAP_YEAR(year) ? 366 : 365; | |||
time -= days; // now it is days in this year, starting at 0 | |||
days = 0; | |||
month = 0; | |||
monthLength = 0; | |||
for (month = 0; month<12; month++) { | |||
if (month == 1) { // february | |||
if (LEAP_YEAR(year)) { | |||
monthLength = 29; | |||
} | |||
else { | |||
monthLength = 28; | |||
} | |||
} | |||
else { | |||
monthLength = monthDays[month]; | |||
} | |||
if (time >= monthLength) { | |||
time -= monthLength; | |||
} | |||
else { | |||
break; | |||
} | |||
} | |||
tm.Month = month + 1; // jan is month 1 | |||
tm.Day = time + 1; // day of month | |||
} | |||
__attribute__((__optimize__("O2"))) | |||
timestamp_t makeTime(tmElements_t &tm) { | |||
// assemble time elements into timestamp_t | |||
// note year argument is offset from 1970 (see macros in time.h to convert to other formats) | |||
// previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9 | |||
int i; | |||
uint32_t seconds; | |||
// seconds from 1970 till 1 jan 00:00:00 of the given year | |||
seconds = tm.Year*(SECS_PER_DAY * 365); | |||
for (i = 0; i < tm.Year; i++) { | |||
if (LEAP_YEAR(i)) { | |||
seconds += SECS_PER_DAY; // add extra days for leap years | |||
} | |||
} | |||
// add days for this year, months start from 1 | |||
for (i = 1; i < tm.Month; i++) { | |||
if ((i == 2) && LEAP_YEAR(tm.Year)) { | |||
seconds += SECS_PER_DAY * 29; | |||
} | |||
else { | |||
seconds += SECS_PER_DAY * monthDays[i - 1]; //monthDay array starts from 0 | |||
} | |||
} | |||
seconds += (tm.Day - 1) * SECS_PER_DAY; | |||
seconds += tm.Hour * SECS_PER_HOUR; | |||
seconds += tm.Minute * SECS_PER_MIN; | |||
seconds += tm.Second; | |||
return (timestamp_t)seconds; | |||
} | |||
/*=====================================================*/ | |||
/* Low level system time functions */ |
@@ -0,0 +1,27 @@ | |||
#pragma once | |||
#include <Arduino.h> | |||
//convenience macros to convert to and from tm years | |||
#define tmYearToCalendar(Y) ((Y) + 1970) // full four digit year | |||
#define CalendarYrToTm(Y) ((Y) - 1970) | |||
#define tmYearToY2k(Y) ((Y) - 30) // offset is from 2000 | |||
#define y2kYearToTm(Y) ((Y) + 30) | |||
/*============================================================================*/ | |||
typedef unsigned long timestamp_t; | |||
typedef struct { | |||
uint8_t Second; | |||
uint8_t Minute; | |||
uint8_t Hour; | |||
uint8_t Wday; // day of week, sunday is day 1 | |||
uint8_t Day; | |||
uint8_t Month; | |||
uint8_t Year; // offset from 1970; | |||
} tmElements_t, TimeElements, *tmElementsPtr_t; | |||
/* low level functions to convert to and from system time */ | |||
void breakTime(timestamp_t time, tmElements_t &tm); // break timestamp_t into elements | |||
timestamp_t makeTime(tmElements_t &tm); // convert time elements into timestamp_t |