jeremylindsayni / Magellanic.Sensors.DS1307

C# code for the DS1307 real time clock module.
https://jeremylindsayni.wordpress.com/2016/06/18/how-to-use-the-ds1307-real-time-clock-with-c-and-the-raspberry-pi-3/
1 stars 1 forks source link

RTC 1307 Types and Modules #1

Closed D4rkF4ce closed 7 years ago

D4rkF4ce commented 7 years ago

Hey Jeremy!

First of all thanks for the code and your work on your blog. It was very informative and helpful. Now I would like to add an RTC to my Raspberry Pi 3 project.

Can I buy this RTC: https://www.sainsmart.com/sainsmart-arduino-i2c-rtc-ds1307-at24c32-real-time-clock-module-for-avr-arm-pic.html

There are so many different DS1307 RTC types to buy.

Thx!

D4rkF4ce commented 7 years ago

For info yes it works.

jeremylindsayni commented 7 years ago

Hey I just saw this, I saw you wrote to me on twitter also. Glad that this works for you! Do you still have a question?

D4rkF4ce commented 7 years ago

Hello

Thx, i think for this topic its better to write here.

I am currently building a Home-Automation system with the Pi3

My main components: 3 Relays 1 BME280 1 DS1307 RTC 1 Touchscreen

Single, I can already address everything.

But with the two I2C modules (RTC & BME280) I always get an exception alternately: "WinRT information: Slave address was not acknowledged."

I use this Nuget package and another classes of an Adafruit package also here from github. (https://github.com/BuildAzure/BuildAzure.IoT.Adafruit.BME280)

My thought: When my app is starting i init all modules and then call what i need but it is apparently not so easy.

after some search i think i have to set the I2cConnectionSettings to ShareMode for every iC2 object and Dispose every time after call. And init again by another call

what du you think?

jeremylindsayni commented 7 years ago

Hey - I found this link which kind of looks like what you are trying, in that there's multiple I2C devices connected to a Raspberry Pi https://www.hackster.io/AnuragVasanwala/home-automation-0dcefc

The author has some code on Github - an interesting file is here, particularly the CollectData method: https://github.com/AnuragVasanwala/Home-Automation--RPi2-WinIoT-/blob/master/Home%20Automation%20(RPi2%20WinIoT)/MainPage.xaml.cs

It obviously refers to other code in that project, the I2C_Helper class looks interesting too.

I hope this helps Jeremy

D4rkF4ce commented 7 years ago

Hey!

Thx for the hint and the links.

I think the error lies in my initialization of the I2C devices.

My Init Logic in Page_On_Loaded():

Init_BME280_Sensor()
Init_DS1307_RTC()

When I access the first I2C device (BME280_Sensor) after initialization I get an incorrect I2C_address and a "WinRT information: Slave address was not acknowledged." - Exception.

Based on your Logic, I now have the following idea:

I will add enums for my I2C Adresses:

    // Provides the Adress Numbers for our I2C-Modules according to the datasheets
    public enum I2CDevices
    {
        // The BME280 datasheet: http://www.adafruit.com/datasheets/BST-BME280-DS001-11.pdf
        Hygromether = 0x77,

        // The DS1307 RTC datasheet: http://www.netmftoolbox.com/documents/Hardware.DS1307.pdf
        RealTimeClock = 0x68
    }

I'm going to implement a FactoryPattern which provides me on the fly the right I2CDevice:

        public static async Task <I2cDevice> GetI2CDevice (I2CDevices i2cDevice)
        {
            switch (i2cDevice)
            {
                    case I2CDevices.Hygromether:
                    return await I2cSlave.Initialize (Convert.ToByte (I2CDevices.Hygromether));

                    case I2CDevices.RealTimeClock:
                    return await I2cSlave.Initialize (Convert.ToByte (I2CDevices.RealTimeClock));

                    default:
                    throw new ArgumentOutOfRangeException (nameof (i2cDevice), i2cDevice, null);
            }
        }

Implement a static Class "I2cSlave" which do the init for me by given I2C Adress and returning me the right I2CDevice:

    public static async Task<I2cDevice> Initialize(byte i2cDevice)
    {
        Debug.WriteLine("I2cSlave::Initialize on I2C_Address: " + i2cDevice);

        try
        {
            i2cAddress = i2cDevice;

            //Instantiate the I2CConnectionSettings using the device address 
            I2cConnectionSettings settings = new I2cConnectionSettings(i2cDevice);

            //Set the I2C bus speed of connection to fast mode
            settings.BusSpeed = I2cBusSpeed.FastMode;

            //Set I2C connection to shared mode
            settings.SharingMode = I2cSharingMode.Shared;

            //Use the I2CBus device selector to create an advanced query syntax string
            string aqs = I2cDevice.GetDeviceSelector(i2cControllerName);

            //Use the Windows.Devices.Enumeration.DeviceInformation class to create a collection using 
            the advanced query syntax string
            DeviceInformationCollection dis = await DeviceInformation.FindAllAsync(aqs);

            //Instantiate the I2C device using the device id of the I2CBus and the I2CConnectionSettings
            I2CModul = await I2cDevice.FromIdAsync(dis[0].Id, settings);

            //Check if device was found
            if (I2CModul == null)
            {
                Debug.WriteLine("Device not found");
            }
        }
        catch (Exception e)
        {
            Debug.WriteLine("Exception: " + e.Message + "\n" + e.StackTrace);
            throw;
        }

        return I2CModul;
    }

The individual sensor classes I pass Inherit from IDisposable so i can Dispose() it after using.

Call:

            var slave = await I2CDeviceFactory.GetI2CDevice (I2CDevices.RealTimeClock);
            using (AutoPlantSystem.Driver.RealTimeClock = new SainSmart_DS_1307_RTC (slave))
            {
                DateTime date = AutoPlantSystem.Driver.RealTimeClock.GetCurrentTime ();
                Debug.WriteLine ("The Time is:" + date);
                txtTime.Text = date.ToString ("dd.mm.yyyy - HH: mm: ss");
            }

I'll let you know if it works.

D4rkF4ce commented 7 years ago

Yes it works! :) So always take using for open, access & dispose. Now all the functions work, finally the protoytpe can go on. Thx for pointing me in the right direction.

jeremylindsayni commented 7 years ago

Brilliant! Glad to hear it, and happy to help.

Can I ask what touchscreen you're using with the Raspberry Pi? I'd be interested in doing some programming with that peripheral.

D4rkF4ce commented 7 years ago

I use the official Pi 7" Touchscreen: https://www.amazon.de/dp/B014WKCFR4/ref=cm_sw_r_sms_awd_xs_jA7-ybKJ29SC0

Screen and touch work out of the Box. i am also interested maybe i need a driver to control the brightness.

All parts of my Project are listed here: http://www.hightechnix.at/autoplant/?page_id=196#hardwareComponents

ProtoType: http://www.hightechnix.at/autoplant/?page_id=253