void loop() { unsigned long currentTime = Time.now(); //TODO: if targets -1, don't do any control //Request time synchronization from the Particle Cloud every 24 hours if (millis() - lastTimeSync > ONE_DAY_MILLIS) { Particle.syncTime(); lastTimeSync = millis(); } //Update time zone at DSTJumpHour incase DST is now in effect if(Time.hour(currentTime) == DSTJumpHour && Time.minute(currentTime) == 0) { Time.zone(isDST(Time.day(currentTime), Time.month(currentTime), Time.weekday(currentTime), preferences.DSTRule) ? preferences.timeZone + 1 : preferences.timeZone); } //Record data from sensors every minute if(millis() - lastDataSync > dataSyncFrequency) { temperature = tempHumidSensor.readTemperature(); humidity = tempHumidSensor.readHumidity(); light = lightSensor.getFullLuminosity(); fullLight = light & 0xFFFF; irLight = light >> 16; visibleLight = fullLight - irLight; lux = lightSensor.calculateLux(fullLight, irLight); //TODO: soil moisture sensor if(postToPhant() == 0) { //Success } else { //failed //TODO: Handle failure } }
/******************************************************************************* * Function Name : adjustDST * Description : adjusts time to DST if needed * Input : non DST time-struct, must be fully populated including weekday * Output : time-stuct gets modified * Return : false: no DST ("winter"), true: in DST ("summer") * DST according to German standard * Based on code from Peter Dannegger found in the mikrocontroller.net forum. *******************************************************************************/ static bool adjustDST( RTC_t *t ) { uint8_t hour, day, wday, month; // locals for faster access hour = t->hour; day = t->mday; wday = t->wday; month = t->month; if ( isDST(t) ) { t->dst = 1; hour++; // add one hour if( hour == 24 ){ // next day hour = 0; wday++; // next weekday if( wday == 7 ) { wday = 0; } if( day == DaysInMonth[month-1] ) { // next month day = 0; month++; } day++; } t->month = month; t->hour = hour; t->mday = day; t->wday = wday; return true; } else { t->dst = 0; return false; } }
/******************************************************************************* * Function Name : rtc_settime * Description : sets HW-RTC with values from time-struct, takes DST into * account, HW-RTC always running in non-DST time * Input : None * Output : None * Return : not used *******************************************************************************/ bool rtc_settime (const RTC_t *rtc) { uint32_t cnt; RTC_t ts; cnt = struct_to_counter( rtc ); // non-DST counter-value counter_to_struct( cnt, &ts ); // normalize struct (for weekday) if ( isDST( &ts ) ) { cnt -= 60*60; // Subtract one hour } RTC_SetCounter( cnt ); return true; }
/******************************************************************************* * Function Name : rtc_settime * Description : sets HW-RTC with values from time-struct, takes DST into * account, HW-RTC always running in non-DST time * Input : None * Output : None * Return : not used *******************************************************************************/ void rtc_settime (const RTC_t *rtc) { uint32_t cnt; volatile uint16_t i; RTC_t ts; cnt = struct_to_counter( rtc ); // non-DST counter-value counter_to_struct( cnt, &ts ); // normalize struct (for weekday) if ( isDST( &ts ) ) { cnt -= 60*60; // Subtract one hour } PWR_BackupAccessCmd(ENABLE); my_RTC_SetCounter( cnt ); PWR_BackupAccessCmd(DISABLE); }
void setup() { //Check for current EEPROM data if(EEPROM.read(0) == 117) { EEPROM.get(1, preferences); } else { preferences = {-8, 1000, -1, -1, -1, -1, -1.0, -1.0, -1.0, "US"}; EEPROM.put(1, preferences); EEPROM.put(0, 117); } //Update settings according to EEPROM data if(preferences.DSTRule == "US") { DSTJumpHour = 2; } else if(preferences.DSTRule == "EU") { DSTJumpHour = 1 + preferences.timeZone; } else { DSTJumpHour = 0; } dataSyncFrequency = preferences.dataSyncFrequency; lightCycleLength = preferences.lightCycleLength; waterCycleLength = preferences.waterCycleLength; targetTemperature = preferences.targetTemperature; targetHumidity = preferences.targetHumidity; targetSoilMoisture = preferences.targetSoilMoisture; //Set the proper time zone according to DST status Time.zone(isDST(Time.day(), Time.month(), Time.weekday(), preferences.DSTRule) ? preferences.timeZone + 1 : preferences.timeZone); //Setup sensors tempHumidSensor.begin(); lightSensor.begin(); lightSensor.setGain(TSL2591_GAIN_MED); lightSensor.setTiming(TSL2591_INTEGRATIONTIME_100MS); pinMode(pumpPWMPin, OUTPUT); pinMode(pumpIn1Pin, OUTPUT); pinMode(pumpIn2Pin, OUTPUT); pinMode(growLEDPin, OUTPUT); pinMode(socketPin, OUTPUT); pinMode(fanPin, OUTPUT); //TEST ONLY lightCycleStartHour = Time.hour(); lightCycleStartMinute = Time.minute()+1; lightCycleLength = 1 * 60 * 1000; }
void loop() { unsigned long currentTime = Time.now(); //Request time synchronization from the Particle Cloud every 24 hours if (millis() - lastSync > ONE_DAY_MILLIS) { Particle.syncTime(); lastSync = millis(); } //Update time zone at DSTJumpHour incase DST is now in effect if(Time.hour(currentTime) == DSTJumpHour && Time.minute(currentTime) == 0) { Time.zone(isDST(Time.day(currentTime), Time.month(currentTime), Time.weekday(currentTime), preferences.dstRule) ? preferences.timeZone + 1 : preferences.timeZone); } //Update the 7-segment display refreshDisplayTime(); //Record data from sensors every 5 minutes if(Time.minute(currentTime) % 5) { temp = tempSensor.getTemperature(); //TODO: Send and/or record data } //Testing if(Time.minute(currentTime) % 1) { temp = tempSensor.getTemperature(); //TODO: Send and/or record data } //Sound alarm check if(soundAlarm) { if(millis() - lastBeep > 600) { lastBeep = millis(); tone(piezoPin, preferences.piezoHertz, 300); } } //Light alarm check if(lightAlarm) { analogWrite(LEDPin, min(maxBrightness, ((currentTime - lightS) / (lightF - lightS)) * maxBrightness)); } //Delay for checking alarms/timers Alarm.delay(1); }
void setup() { //EEPROM.clear(); testString = "zo345566"; EEPROM.get(0, preferences); testString += "get"; if(preferences.version != 0) { preferences.version = 0; preferences.timeZone = -8; preferences.hourFormat = 12; preferences.piezoHertz = 2000; preferences.LEDCurrent = 700; preferences.LEDBrightness = 100; preferences.dstRule = DST_US; for(int i=0; i<32; ++i) { preferences.alarmTimes[i][0] = -1; } EEPROM.put(0, preferences); testString += "put"; } //Converts preferences.alarmTimes to vectorAlarmTimes for(int i=0; i<32; ++i) { if(preferences.alarmTimes[i][0] != -1) { std::vector<int> temp; temp.push_back(preferences.alarmTimes[i][0]); temp.push_back(preferences.alarmTimes[i][1]); temp.push_back(preferences.alarmTimes[i][2]); temp.push_back(preferences.alarmTimes[i][3]); temp.push_back(preferences.alarmTimes[i][4]); temp.push_back(preferences.alarmTimes[i][5]); temp.push_back(preferences.alarmTimes[i][6]); temp.push_back(preferences.alarmTimes[i][7]); vectorAlarmTimes.push_back(temp); } } testString += preferences.timeZone; testString += preferences.hourFormat; testString += preferences.piezoHertz; testString += preferences.LEDCurrent; testString += preferences.LEDBrightness; testString += preferences.dstRule; if(preferences.dstRule == DST_US) { DSTJumpHour = 2; } else if(preferences.dstRule == DST_EU) { DSTJumpHour = 1 + preferences.timeZone; } else { DSTJumpHour = 0; } //Set the proper time zone according to DST status Time.zone(isDST(Time.day(), Time.month(), Time.weekday(), preferences.dstRule) ? preferences.timeZone + 1 : preferences.timeZone); //testString += isDST(Time.day(), Time.month(), Time.weekday(), preferences.dstRule); //Setup the 7-segment display, temperature sensor, and audio amp display.begin(0x70); display.setBrightness(15); //TODO: adjust brightness to optimize for veneer/time tempSensor.begin(); tempSensor.setResolution(MCP9808_SLOWEST); audioAmp.begin(); //Pin setup pinMode(LEDPin, OUTPUT); //Add alarms stored in eeprom addAlarms(); //Cloud functions and variables Particle.function("CreateAlarm", createAlarm); Particle.function("DeleteAlarm", deleteAlarm); Particle.variable("Temperature", temp); Particle.variable("alarmString", alarmString); Particle.variable("testString", testString); }