2016-01-23 49 views
2

对于我的项目,我需要当前时间&日期。不幸的是,RP2在关闭时丢失了一切。接下来的事情是,我不会有互联网连接来使用NTP。 对于这种再生,我需要实现一个DS3231 RTC模块。 所有设备的通信都通过I2C运行(树莓< - > Arduino < - > DS3231)。 目前我的Arduino与模块进行通信并将日期和时间存储在char数组中。 RP2与Arduino通信以获取日期/时间。这实际上工作很好。但我想直接与模块沟通以节省Arduino上的资源(这只是一个Nano)。 因此,我想知道是否有人对模块和Windows IoT有经验。Windows IoT和DS3231 RTC时钟

下面你会发现我目前的解决方案:

的Arduino:

#include "Wire.h" 
#define DS3231_I2C_ADDRESS 0x68 
#define MyAddress 0x40 /* Define the i2c address */ 

char time_char[10]; 
char date_char[10]; 

byte ReceivedData; 

// Convert binary coded decimal to normal decimal numbers 
byte bcdToDec(byte val) 
{ 
    return((val/16*10) + (val%16)); 
} 

void setup() 
{ 
    Wire.begin(MyAddress); 
    Serial.begin(9600); 
    Wire.onReceive(I2CReceived); 
    Wire.onRequest(I2CRequest); 
} 

void readDS3231time(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year) 
{ 
    Wire.beginTransmission(DS3231_I2C_ADDRESS); 
    Wire.write(0); // set DS3231 register pointer to 00h 
    Wire.endTransmission(); 
    Wire.requestFrom(DS3231_I2C_ADDRESS, 7); 
    // request seven bytes of data from DS3231 starting from register 00h 

    *second = bcdToDec(Wire.read() & 0x7f); 
    *minute = bcdToDec(Wire.read()); 
    *hour = bcdToDec(Wire.read() & 0x3f); 
    *dayOfWeek = bcdToDec(Wire.read()); 
    *dayOfMonth = bcdToDec(Wire.read()); 
    *month = bcdToDec(Wire.read()); 
    *year = bcdToDec(Wire.read()); 
} 

void displayTime() 
{ 
    String hour_str, minute_str, second_str, day_str, month_str, year_str, hour_str_orig, minute_str_orig, second_str_orig, time_str, date_str; 
    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; 
    // retrieve data from DS3231 
    readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,&year); 

    if (hour<10) 
    { 
    hour_str_orig = (hour); 
    hour_str = ("0" + hour_str_orig); 
    } 
    else 
    { 
    hour_str = (hour); 
    } 

    if (minute<10) 
    { 
    minute_str_orig = (minute); 
    minute_str = ("0" + minute_str_orig); 
    } 
    else 
    { 
    minute_str = (minute); 
    } 

    if (second<10) 
    { 
    second_str_orig = (second); 
    second_str = ("0" + second_str_orig); 
    } 
    else 
    { 
    second_str = (second); 
    } 

    day_str = (dayOfMonth); 
    month_str = (month); 
    year_str = (year); 

    time_str = (hour_str + ":" + minute_str + ":" + second_str); 
    date_str = (day_str + "." + month_str + "." + "20" +year_str); 


    time_str.toCharArray(time_char, 10); 
    date_str.toCharArray(date_char, 10);  

} 
void loop() 
{ 
    displayTime(); // send the real-time clock data to IoT 
    delay(1000); // every second 
} 

void I2CReceived(int NumberOfBytes) 
{ 
    /* WinIoT have sent data byte; read it */ 
    ReceivedData = Wire.read(); 
} 

void I2CRequest() 
    { 

if (ReceivedData == 50)  
{ 
    Wire.write(time_char); 
} 

if (ReceivedData == 51) 
{ 
    Wire.write(date_char); 
} 

} 

物联网:

public async void TestFunction() 
{ 
    for (int i = 0; i < 50; i++) 
    { 
     for (byte DataToBeSend = 50; DataToBeSend < 52; DataToBeSend++) 
     { 
      if (DataToBeSend == 50) 
      { 
       byte ReceivedData; 

       ReceivedData = await Time.WriteRead_OneByte(DataToBeSend); 

       await Task.Delay(10); 
      } 

      if (DataToBeSend == 51) 
      { 
       byte ReceivedData; 

       ReceivedData = await Time.WriteRead_OneByte(DataToBeSend); 

       await Task.Delay(10); 
      } 
     } 

     await Task.Delay(1000); 

    } 
} 

类:

public class Time 
    { 
     private static string AQS; 
     private static DeviceInformationCollection DIS; 
     public static float result_fl; 


     public static async System.Threading.Tasks.Task<byte> WriteRead_OneByte(byte ByteToBeSend) 
     { 
      byte[] ReceivedData = new byte[10]; 


      /* Gateway's I2C SLAVE address */ 
      int SlaveAddress = 64;    // 0x40 

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

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


       using (I2cDevice Device = await I2cDevice.FromIdAsync(DIS[0].Id, Settings)) 
       { 
        /* Send byte to Arduino Nano */ 
        Device.Write(new byte[] { ByteToBeSend }); 

        /* Read byte from Arduino Nano */ 
        Device.Read(ReceivedData); 

        /* Rewrite Array to avoid empty space in source array */ 
        var i = ReceivedData.Length - 1; 
        while (ReceivedData[i] == 255) 
        { 
         --i; 
        } 

        var date_time_arr = new byte[i + 1]; 
        Array.Copy(ReceivedData, date_time_arr, i + 1); 

        /* Show date or time */ 
        string result = System.Text.Encoding.UTF8.GetString(date_time_arr); 
        Debug.WriteLine(result); 
       } 
      } 
      catch (Exception) 
      { 

      } 
      return ReceivedData[0]; 
     } 
    } 

告诉我,如果你需要更多的信息。 谢谢!

+0

你得到的IOT任何时钟信息? –

+0

@BlurrySterk对不起,我迟来的回复。是的,我得到了时钟信息,但只有通过Arduino的方式 – TRS

+0

我不能确定你的问题实际上是什么。我将直接在您的物联网中实施I2C通信。你在那里试过了吗? –

回答

0

对不起,对于迟到的回复! 我到目前为止的解决方案:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Windows.Devices.Enumeration; 
using Windows.Devices.I2c; 
using System.Diagnostics; 

namespace _015_Test15_I2C_Clock_RTC3231 
{ 
    public class I2C_Time 
    { 
     private static string AQS; 
     private static DeviceInformationCollection DIS; 

     public static async Task GetTimeFromDS3231() 
     { 

      /* DS3231 I2C SLAVE address */ 
      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 DeviceInformation.FindAllAsync(AQS); 
       } 


       using (I2cDevice Device = await I2cDevice.FromIdAsync(DIS[0].Id, Settings)) 
       { 
        byte[] writeBuf = { 0x00 }; 
        Device.Write(writeBuf); 
        byte[] readBuf = new byte[7]; 
        Device.Read(readBuf); 
        byte second = bcdToDec((byte)(readBuf[0] & 0x7f)); 
        byte minute = bcdToDec(readBuf[1]); 
        byte hour = bcdToDec((byte)(readBuf[2] & 0x3f)); 
        byte dayOfWeek = bcdToDec(readBuf[3]); 
        byte dayOfMonth = bcdToDec(readBuf[4]); 
        byte month = bcdToDec(readBuf[5]); 
        byte year = bcdToDec(readBuf[6]); 
       } 
      } 
      catch (Exception) 
      { 
       Debug.WriteLine("Error in I2C_Time Class"); 
      } 
     } 

     private static byte bcdToDec(byte val) 
      { 
       return (byte)(((int)val/16 * 10) + ((int)val % 16)); 
      } 
     } 
    } 

设置时钟:

using (I2cDevice Device = await I2cDevice.FromIdAsync(DIS[0].Id, Settings)) 
      { 
       byte write_seconds = decToBcd(set_Time_now_seconds); 
       byte write_minutes = decToBcd(set_Time_now_minutes); 
       byte write_hours = decToBcd(set_Time_now_hours); 
       byte write_dayofweek = decToBcd(set_Date_now_dayofweek); 
       byte write_day = decToBcd(set_Date_now_day); 
       byte write_month = decToBcd(set_Date_now_month); 
       byte write_year = decToBcd(set_Date_now_year); 

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

       Device.Write(write_time); 

      } 
     // Convert normal decimal numbers to binary coded decimal 
    private static byte decToBcd(byte val) 
    { 
     return (byte)(((int)val/10 * 16) + ((int)val % 10)); 
    }