Windows IoT Raspberry Pi 3 C# RTC DS3231

этот пост может показаться дублирующимся как часы Windows IoT и DS3231 RTC , но это не так. Кажется, это работает для меня. у меня нет опыта использования i2c в этой среде.

Моя предполагаемая функциональность,

  1. при запуске проверьте, есть ли сетевое подключение для обновления системных часов
  2. в автономном режиме система будет читать datetime из DS3231 и обновлять систему datetime
  3. любые изменения datetime с datepicker или timepicker будут обновлены DS3231

моя проблема

  1. Как проверить доступность сети для обновления системных часов.
  2. для чтения из DS3231 с помощью i1cdevice.writeread требуется write read address отдельно? i2c автоматически считывает все данные до тех пор, пока не будет получен stop бит, или мне нужно настроить счетчик?

    private const byte DS3231_I2C_WADDR = 0xD0;
    private const byte DS3231_I2C_RADDR = 0xD1;
    private I2cDevice DS3231_RTC; 
    
    byte[] i2CWriteBuffer;
    byte[] i2CReadBuffer;
    
    private async void Read_DS3231_RTC()
    {
        var settings = new I2cConnectionSettings(DS3231_I2C_RADDR);
        settings.BusSpeed = I2cBusSpeed.StandardMode;
        var controller = await I2cController.GetDefaultAsync();
        DS3231_RTC = controller.GetDevice(settings);
    
        try
        {
            DS3231_RTC.WriteRead(new byte[] { DS3231_I2C_RADDR }, i2CReadBuffer);
            }
        catch (Exception e)
        {
            StatusMessage.Text = "Fail to Init I2C:" + e.Message;
            return;
        }
    }
    
  3. для записи в DS3231 есть dateicker и timepicker для настройки времени при установке datetime как я могу обновить до DS3231

    private void DatePicker_DateChanged(object sender, DatePickerValueChangedEventArgs e)
    {
        DateTimeSettings.SetSystemDateTime(e.NewDate.UtcDateTime);
        SetTime_DS3231();
    }
    
    private void TimePicker_TimeChanged(object sender, TimePickerValueChangedEventArgs e)
    {
        var currentDate = DateTime.Now.ToUniversalTime();
    
        var newDateTime = new DateTime(currentDate.Year,
                                       currentDate.Month,
                                       currentDate.Day,
                                       e.NewTime.Hours,
                                       e.NewTime.Minutes,
                                       e.NewTime.Seconds);
    
        DateTimeSettings.SetSystemDateTime(newDateTime);
    }
    

Спасибо.


person mylim    schedule 15.03.2018    source источник


Ответы (1)


1.Как проверить доступность сети для обновления системных часов.

Вы можете использовать метод GetIsNetworkAvailable класса NetworkInterface, чтобы проверить, подключен ли Интернет или нет. Вы можете получить больше информации о том, как проверить тип подключения к Интернету на универсальной платформе Windows, из этого тема.

bool isInternetConnected = NetworkInterface.GetIsNetworkAvailable();

2. для чтения с DS3231 с помощью i1cdevice.writeread требуется отдельно писать адрес чтения? i2c автоматически считывает все данные до тех пор, пока не будет получен стоп-бит, или мне нужно настроить счетчик?

Не надо разделять запись на чтение. Метод WriteRead Выполняет атомарную операцию для записи данных, а затем для чтения данных из шины интеринтегральной схемы (I2 C), к которой подключено устройство, и отправляет условие перезапуска между операциями записи и чтения. Второй параметр — это буфер, в который вы хотите считывать данные с шины I2 C. Длина буфера определяет, сколько данных требуется от устройства. Он не останавливается автоматически, пока не будет получен стоп-бит. Если устройство I2 C отрицательно подтвердит передачу данных до того, как весь буфер будет прочитан, возникнет ошибка (код ошибки 0x8007045D).

3. для записи в DS3231 есть dateicker и timepicker для настройки времени при установке даты и времени, как я могу обновить до DS3231

Как TRS ответил в теме Windows IoT и часы RTC DS3231 , он/она предоставил метод для установки часов.

Новое обновление:

    private async void SetTime_DS3231(DateTime dt)
    {
        int SlaveAddress = 0x68;

        try
        {
            // Initialize I2C
            var Settings = new I2cConnectionSettings(SlaveAddress);
            Settings.BusSpeed = I2cBusSpeed.StandardMode;

            if (AQS == null || DIS == null)
            {
                AQS = I2cDevice.GetDeviceSelector("I2C1");
                DIS = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(AQS);
            }

            using (I2cDevice Device = await I2cDevice.FromIdAsync(DIS[0].Id, Settings))
            {
                byte write_seconds = decToBcd((byte)dt.Second);
                byte write_minutes = decToBcd((byte)dt.Minute);
                byte write_hours = decToBcd((byte)dt.Hour);
                byte write_dayofweek = decToBcd((byte)dt.DayOfWeek);
                byte write_day = decToBcd((byte)dt.Day);
                byte write_month = decToBcd((byte)dt.Month);
                byte write_year = decToBcd((byte)(dt.Year%100));

                byte[] write_time = { 0x00, write_seconds, write_minutes, write_hours, write_dayofweek, write_day, write_month, write_year };

                Device.Write(write_time);

            }
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.Write(ex.Message);
        }
    }

    private static byte decToBcd(byte val)
    {
        return (byte)(((int)val / 10 * 16) + ((int)val % 10));
    }
person Michael Xu - MSFT    schedule 16.03.2018
comment
Спасибо. для Write как применить метод, так как он using (I2cDevice Device = await I2cDevice.FromIdAsync(DIS[0].Id, Settings)) - person mylim; 16.03.2018
comment
У меня есть дополнительная проблема: когда я вставляю SetTime_DS3231(newDateTime) в конце TimePicker_TimeChanged и SetTime_DS3231(e.NewDate.UtcDateTime) в конце DatePicker_DateChanged, я столкнулся с System.UnauthorizedAccessException: 'Access is denied. (Excep_FromHResult 0x80070005)' - person mylim; 16.03.2018
comment
Вам нужно добавить возможность управления системой в ваш Package.appxmanifest, поскольку DateTimeSettings.SetSystemDateTime требует разрешения. - person Michael Xu - MSFT; 16.03.2018
comment
Если `if( isInternetConnected == true)` и системные часы будут обновляться через IoT, как я узнаю, что когда time будет обновлено, чтобы я мог обновить DS3231 после обновления системного времени по сети. - person mylim; 17.03.2018
comment
По умолчанию устройства IoT Core настроены на синхронизацию времени с time.windows.com при загрузке. Вам необходимо использовать службу NTP для синхронизации даты/времени вручную. - person Michael Xu - MSFT; 19.03.2018
comment
О.. в таком случае.. Я проверяю подключение к Интернету перед чтением из RTC? Если есть подключение к Интернету.. Я пропущу чтение из RTC.. Я также понимаю, что есть какой-либо класс для уведомления о том, что дата и время были синхронизированы с time.windows.com.. - person mylim; 19.03.2018
comment
Кажется, что нет никакого класса, чтобы уведомить, что дата и время были синхронизированы с NTP. - person Michael Xu - MSFT; 19.03.2018
comment
во время преобразования decToBcd для Year я заметил, что (byte)dt.Year = 226, где dt.Year = 2018 .. после преобразования write_year = 51 и записывается в DS3231 ... когда я читаю это обратно, я получаю 66 для year ... я что-то сделал не так? Я передаю DateTime.Now в TimePicker_TimeChanged до SetTime_DS3231(DateTime.Now); - person mylim; 19.03.2018
comment
Я обновил код, пожалуйста, обратитесь к новому обновленному коду. Я думаю, это связано с тем, что максимальное значение байта равно 255. Поскольку у меня нет ни одной части DS3231, я не могу проверить код. Работает он или нет, пожалуйста, дайте мне знать. - person Michael Xu - MSFT; 20.03.2018
comment
Привет .. это не сработало .. но мне удалось заставить его работать .. следующий код; byte write_year = decToBcd(dt.Year % 100); return (byte)((val % 10) | (val / 10) << 0x4); ... - person mylim; 21.03.2018
comment
Спасибо, что поделились кодом. Я обновил свой ответ в соответствии с вашим кодом, чтобы он был полезен для кого-то еще. - person Michael Xu - MSFT; 21.03.2018