Main Site Documentation

Request help getting TimeSpan turn up a port


#1

MY DS1307 RTC is up and running on my Panda works like a champ. ;D My problem is I want to turn a port up during a set TimeSpan. I’m sure that I am just over looking something but as I’m fairly new to C# and FEZing I just can’t seam to make it work. Any feed back is welcome. :slight_smile:

My code is as follows, I know it is not the cleanest/smoothest but it is were I’m at at this time.

// ---References--- //
// FEZPanda_GHIElectronics.NETMF.FEZ
// GHIElectronics.NETMF.Hardware
// Microsoft.SPOT.Hardware
// Microsoft.SPOT.IO
// Microsoft.SPOT.Native
// mscorlib
// System
// System.IO

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Hardware;

namespace DS1307
{
    public class DS1307Interface : IDisposable
    {
        private I2CDevice I2C;
        I2CDevice.I2CTransaction[] xaction;
        ushort DS1307_Address = 0x68;

        public void Dispose()
        {
            I2C.Dispose();
            xaction = null;
        }

        public void RTC_DS1307()
        {
            // Create I2C object

            I2CDevice.Configuration conf = new I2CDevice.Configuration(DS1307_Address, 100);
            I2C = new I2CDevice(conf);
        }
        public DateTime GetDateTime()
        {
            xaction = new I2CDevice.I2CTransaction[2];
            xaction[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0x00 });
            byte[] ReturnedDateTime = new byte[7];
            xaction[1] = I2CDevice.CreateReadTransaction(ReturnedDateTime);
            if (I2C.Execute(xaction, 1000) == 0)
            {
                new Exception("Failed to send I2C data");
            }

            int sec = bcdToDec(ReturnedDateTime[0]) & 0x7f;
            int min = bcdToDec(ReturnedDateTime[1]);
            int hour = bcdToDec(ReturnedDateTime[2]) & 0x3f;
            int dayofweek = bcdToDec(ReturnedDateTime[3]);
            int dayofmonth = bcdToDec(ReturnedDateTime[4]);
            int month = bcdToDec(ReturnedDateTime[5]);
            int year = bcdToDec(ReturnedDateTime[6]) + 2000;

            DateTime dt = new DateTime(year, month, dayofmonth, hour, min, sec);
            return dt;
        }

        public void SetDateTime(DateTime datetime)
        {
            xaction = new I2CDevice.I2CWriteTransaction[1];
            byte[] sb = new byte[8] { 0x00, 
decToBcd(datetime.Second), 
decToBcd(datetime.Minute), 
decToBcd(datetime.Hour), 
decToBcd((int)datetime.DayOfWeek), 
decToBcd(datetime.Day), 
decToBcd(datetime.Month), 
decToBcd(datetime.Year - 2000)  
};

            xaction[0] = I2CDevice.CreateWriteTransaction(sb);
            if (I2C.Execute(xaction, 1000) == 0)
            {
                new Exception("Failed to send I2C data");
            }
        }

        public byte decToBcd(int val)
        {
            return (byte)((val / 10 * 16) + (val % 10));
        }

        public byte bcdToDec(byte val)
        {
            return (byte)((val / 16 * 10) + (val % 16));
        }
    }
    public class Program
    {
        public static void Main()
        {
            DS1307Interface connect = new DS1307Interface();
            connect.RTC_DS1307();

            /* >>>Start Set Date Time here<<< */
            /* >>>Date Time set formate (yyyy, MM, dd, HH, mm, ss)<<< */

            //DateTime setDate = new DateTime(2010, 12, 24, 15, 09, 00);
            //connect.SetDateTime(setDate);

            /* >>>End Date Time Set here<<< */
			
		   // Set Pin for Time_Range check
            OutputPort TimeCheck1;
            TimeCheck1 = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.IO21, false);

            while (true)
            {
                DateTime datetime = connect.GetDateTime();

                string thetime = datetime.ToString();
                string timeOnly24H = datetime.ToString("HH:mm:ss");  //24 Hour formate
                string timeOnly12H = datetime.ToString("h:mm:ss tt");  //12 Hour AM/PM formate
                string dateOnlyNum = datetime.ToString("yyyy/MM/dd");  // 2010/12/24 formate
                string dateOnlyTex = datetime.ToString("dd-MMM-yyyy");  // 24 Dec 2010 formate
                string dayOnlyLong = datetime.ToString("dddd");  //  Long Day of the week
                string dayOnlyShor = datetime.ToString("ddd");  //  Short Day of the week
				
				TimeSpan start = new TimeSpan(10, 00, 00); //10 o'clock 
				TimeSpan end = new TimeSpan(17, 35, 00); //12 o'clock 
				TimeSpan now = DateTime.Now.TimeOfDay; 
 
				if ((now > start) && (now < end)) 
{
    TimeCheck1.Write(true);			
} 
                Debug.Print("It is: " + timeOnly12H);
                Debug.Print("");
            }
        }
    }
}

#2

Can you please wrap your code using following tags "


".

You can use code button as well.

Just hit “Modify” button on your post, select all code and hit “code” button.


#3

Please “code tag” your code so it is readable. I modified your post

Now, I am not sure I understand your question. Can you explain more please?


#4

Gus / Architect
Thanks for the quick response.

Gus

I am trying to change the state of a port “IO21” during a given range of time. When it is 10:00:00 the port should turn on “go to a true state” and stay that way untill the end time span is reached in this case 17:35:00. The part of the code that is supposed to make it happen is.

				
TimeSpan start = new TimeSpan(10, 00, 00); //10 o'clock
TimeSpan end = new TimeSpan(17, 35, 00); //12 o'clock 
TimeSpan now = DateTime.Now.TimeOfDay; 
 
if ((now > start) && (now < end)) 
{
TimeCheck1.Write(true);			
} 

At least that is my undewrstanding of it.


#5

Got it! What you should do is setup a timer that fires at the time you want in which will change the pin…assuming this is some alarm you are making

as always, everything is in the free ebook :slight_smile: http://www.microframeworkprojects.com/index.php?title=Time_Services


#6

Gus

Actually my Panda will eventually be a controller for my reef tank. I need to turn the port on for an extended period of time hours. In fact I will need to turn on multiple ports at diffrent times for diffrent periods of time. This additionally will take place every day/night. The intent is to control solid state relays to turn high power lights on and off. I also have my Panda monitoring the temp via 1 wire and a DS18B20.


#7

Setup a different timer for each of those events. Just don’t block in the timer callback as it will block other timers.


#8

So for my future Reef Tank controller I have the timespan function working. :slight_smile: It seems that the timespan function is tied to the on chip clock and the on chip clock rests on every reboot to 01/01/2009 23:02:04 as reported by >>> Debug.Print(DateTime.Now.ToString()); <<<. This of course does not work with trying to turn on Multiple Metal Halide lights at a set time of day every day. By doing a manual sync of the on chip clock it works, the next step will be too periodically (daily) as well as on boot up in case of a power outage sync it with the DS1307.

Once I get the light management working will work on temperature management via a DS18B20 for monitoring and fans.


#9

Hey Terry, nice project.

I had a couple of suggestions.

In the first phase of your code, once you’ve set up the DS1307, set the system time from RTC. Then, periodically, I’d suggest you check for drift (more often than daily would be my suggestion, but I have no RTC to compare a running clock with - I personally am going to sync to a NTP server every 10 mins where time is important to the project, your resolution possibly won’t be that critical).

In your current MAIN you have a while (forever) loop, but you do some things in there that only need doing once - the start/end for instance. Move them to your initialisation section.

You need to modify your LED routine, since you never turn it off when outside the time window. There are many different ways to approach this, but at a minimum you need use an ELSE statement to turn the LED off.

hope that helps - good luck with the tank controller!


#10

Setting time under a job scheduler can have unexpected side-effects (i.e. jobs not running, jobs running twice, etc) as you probably know while playing with cron or the like. I would test all senerios in respect to jobs/callbacks (time going backward, time going forward). Can be difficult to test.


#11

Good point William, maybe that’s another reason to make the time drift checks more frequent (so the correction delta is less) and to have a maximum correction delta that you won’t adjust past (but flag an error).

For something as relatively simple as operating times for lights/fans etc (not in any way disparaging the concept from William, I have a similar simple need) maintaining a good history of state changes and figuring out if you’ve seen a transition within the max delta correction should cover off that.


#12

It seems to me that there is no critical or time consuming processing going on so I would make it as simple as possible.

[ulist]At boot up set your clock from RTC

In a never ending while loop
Check for on value A and turn it on, else turn it off (like your already do)
Check for on value B and turn it on, else turn it off.
Check for on value C…
Sleep for a minute

[/ulist]
This might not be the coolest programming approach but it’s easy to follow and debug.


#13

All
First thanks for the suggestions. As I continue working on this project Im learning more. I could have gone the Arduino route which has lots of examples available on the NET but what would have been the fun in that.

No timing isnt that critical can be easily be + or – a couple of minutes. The biggest reason for wanting the time sync is because of the reboot issue of the system clock defaulting to 01/01/2009 23:02:04.
Yes I did add an else statement to my if to ensure that the lights turn off as I did experience a hang. As for the interval of syncing I just went with a simple if not equal statement, took a little parsing but it works.
I am working on cleaning up the code now waiting on parts for the PH probe circuit.
Please keep the comments coming as that is how one learns.

				/* Sync the System Clock to the DS1307 */
                string SysClock = (DateTime.Now.ToString()); //System Clock to string for Sync
				
                if (SysClock != thetime) //Check to see if the clocks are in Sync if not preform Sync
                {
                    DateTime time = new DateTime(setYear, setMonth, setDay, setHour, setMin, setSec);
                    Utility.SetLocalTime(time);

#14

All
Just a quick update, the time synchronization seems to be working without any problems by having it set to run as the first item in the while loop. It checks to see if the system clock is equal to the DS1307 RTC and if not corrects the system clock. It has been running this way for about a week turning LEDs on and off with no issues. I even managed to figure out how to turn a port on true over night using the TimeSpan and if/else > & < statement, as I have a requirement for an overnight true.