在Raspberry Pi 3上的Windows 10 IOT上扫描地址需要30秒

时间:2018-11-15 22:45:47

标签: c# i2c windows-10-iot-core

在I2C中扫描地址

我一直在尝试扫描使用I2C时存在的Raspberry Pi 3端口上的地址1-128。请注意,我们有1 GB的RAM,并且我们的软件总是将其最大化,尤其是在此过程中(实际上,它大约为900K)。

平台

我们的操作系统:Windows 10 Iot Core Build 17744。 Atlas Scientific具有用于pH,CO2,温度,电导率和氧化/还原电位(ORP)的传感器。 https://www.atlas-scientific.com/product_pages/circuits/ezo_orp.html 假设我们正在使用Whitebox的Labs触手3来托管3个电路和传感器及其关联的传感器。 https://www.atlas-scientific.com/product_pages/components/tentacle-t3.html

迭代1-128需要35秒,这是不允许的。此外,Raspian上的Python不需要那么长时间。 (我现在要对此进行验证)。

我们尝试过的事情

1)我注意到扫描循环在静态类中。我认为“使用”将确保垃圾收集将清除情况。没有。

1a)我改写了它,但没有“使用”,但要处理。结果相同;

2)接下来,我尝试了IOT Lightning DMAP驱动程序。 https://docs.microsoft.com/en-us/windows/iot-core/develop-your-app/lightningproviders 这对时间也没有影响。

帮我Obi-Wan Kenobi,你是我唯一的希望 我已经将其交叉发布到Windows 10 IOT支持委员会。 是时候尝试C ++了?

注意

我刚刚尝试过,但是似乎也不起作用 GetDeviceSelector()..

https://www.hackster.io/porrey/discover-i2c-devices-on-the-raspberry-pi-84bc8b

代码

FindDevicesAsync有两种版本(一种带有Lightning DMAP,一种没有Lightning DMAP)

 using IOT_Sensors;
 using MetroLog;
 using SQLite.Net;
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
 using System.Linq;
 using System.Threading.Tasks;
 using Windows.Devices.I2c;
 using Windows.Devices;
 using Microsoft.IoT.Lightning.Providers;
 using Windows.UI.Xaml;


 namespace atlas_iot
 {
public class SensorFinder 
{


    public async static Task<IEnumerable<byte>> StaticExample()
    {
        SensorFinder sf = new SensorFinder();
        return await sf.FindDevicesAsync();
    }

    //the process for searching for sensors could not be garbage collected in a static class
    // we are going to return a static List of addresses (bytes). ModuleStore.I2CsystemInit() will give them type






    public async Task<IEnumerable<byte>> FindDevicesAsync() //speed this up please!
    {

        if (LightningProvider.IsLightningEnabled)
        {
            // Set Lightning as the default provider
            LowLevelDevicesController.DefaultProvider = LightningProvider.GetAggregateProvider();
        }

        IList<byte> addresses = new List<byte>();

        I2cController controller = await I2cController.GetDefaultAsync();
        // const int minimumAddress = 97;
        const int minimumAddress =10;
        // The Min and Max may need to be adjusted depending on what ID #'s you haveon the EZO circuit.
        //const int maximumAddress = 104;
        const int maximumAddress = 105;
        //const int maximumAddress = 103;
        for (byte address = minimumAddress; address <= maximumAddress; address++)
        {
            // Debug.WriteLine("checking address " + address);
            var settings = new I2cConnectionSettings(address)
            {
                BusSpeed = I2cBusSpeed.FastMode,
                SharingMode = I2cSharingMode.Shared
            };


            I2cDevice device = controller.GetDevice(settings);
            if (device != null)
            {
                try
                {
                    byte[] writeBuffer = new byte[1] { 0 };
                    device.Write(writeBuffer);
                    addresses.Add(address);
                    Debug.WriteLine("Added Address: " + address);
                }
                catch (FileNotFoundException ex)
                {
                    //Do Nothing
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("Address {0} not found ", address);
                    string msg = ex.Message;
                    //swallow exception
                }
            }
            else
            {
                Debug.WriteLine("device DOES equal null!", address);
                //Do Nothing
            }
            device.Dispose();
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }

        //byte address2 = 105;
        //addresses.Add(address2);

        //addresses.Add(maximumAddress + 1); //Adding an extra for Config Button

        return addresses;
    }


    //Maybe use  a Hashtable or dictionary instead?ny
    //public async Task<IEnumerable<byte>> FindDevicesAsync() //speed this up please!
    //{
    //    IList<byte> addresses = new List<byte>();

    //    I2cController controller = await I2cController.GetDefaultAsync();
    //    // const int minimumAddress = 97;
    //    const int minimumAddress = 1;
    //    // The Min and Max may need to be adjusted depending on what ID #'s you haveon the EZO circuit.
    //    //const int maximumAddress = 104;
    //    const int maximumAddress = 105;
    //    //const int maximumAddress = 103;
    //    for (byte address = minimumAddress; address <= maximumAddress; address++)
    //    {
    //        // Debug.WriteLine("checking address " + address);
    //        var settings = new I2cConnectionSettings(address)
    //        {
    //            BusSpeed = I2cBusSpeed.FastMode,

    //            SharingMode = I2cSharingMode.Shared
    //        };

    //        using (I2cDevice device = controller.GetDevice(settings))
    //        {
    //            if (device != null)
    //            {
    //                try
    //                {
    //                    byte[] writeBuffer = new byte[1] { 0 };
    //                    device.Write(writeBuffer);
    //                    addresses.Add(address);
    //                    Debug.WriteLine("Added Address: " + address);
    //                }
    //                catch (FileNotFoundException ex)
    //                {
    //                    //    //This is the WatchDog Feature
    //                    //    //If it misses NumberOfTriesBeforeRestart sensors in a row, it can restart the i2c detection ring.
    //                    //    //This number is configurable in NumberOfTriesBeforeRestart

    //                    //    if (failures == NumberOfTriesBeforeRestart)
    //                    //    {   //You Can Reboot Here
    //                    //        //Reoot Code
    //                    //        //CoreApplication.RequestRestartAsync();
    //                    //    }
    //                    //    else
    //                    //    {
    //                    //        //Or You Can Shut Down
    //                    //        // CoreApplication.Exit();
    //                    //    }

    //                    //    failures++;

    //                    //    string MyEx = ex.Message;

    //                    //    //we decided that if 3 or more sensors in a row are caught (fail to be detected), Then
    //                    //    //the polling process restarts.
    //                }
    //                catch (Exception ex)
    //                {
    //                    Debug.WriteLine("Address {0} not found ", address);
    //                    string msg = ex.Message;
    //                    //swallow exception
    //                }
    //            }
    //            //else if ((device == null) && (address == 105))
    //            //{
    //            //    byte[] writeBuffer = new byte[1] { 0 };
    //            //    device.Write(writeBuffer);
    //            //    addresses.Add(address);
    //            //}
    //            else
    //            {
    //                Debug.WriteLine("device DOES equal null!", address);

    //                //restart by re-opening the MainPage.xaml file
    //                // Navigate to a page function like a page
    //            }
    //        }
    //    }

    //    //byte address2 = 105;
    //    //addresses.Add(address2);

    //    //addresses.Add(maximumAddress + 1); //Adding an extra for Config Button

    //    return addresses;
    //}


    }
}

1 个答案:

答案 0 :(得分:1)

由于抛出异常,然后导致地址“ SlaveAddressNotAcknowledged”,导致时间如此之长,时间成本取决于您扫描的地址数量。

要解决此问题,可以使用WritePartial代替Write。 WritePartial不会引发异常,但会在返回结果中报告状态代码:I2cTransferResult,I2cTransferStatus。因此节省时间。重复执行1-105大约需要1.2秒。

您可以尝试以下代码:

        const int minimumAddress = 1;
        const int maximumAddress = 105;

        var stopWatch = new Stopwatch();
        stopWatch.Start();

        for (byte address = minimumAddress; address <= maximumAddress; address++)
        {
            // Debug.WriteLine("checking address " + address);
            var settings = new I2cConnectionSettings(address)
            {
                BusSpeed = I2cBusSpeed.FastMode,

                SharingMode = I2cSharingMode.Shared
            };

            using (I2cDevice device = controller.GetDevice(settings))
            {
                if (device != null)
                {
                    try
                    {
                        byte[] writeBuffer = new byte[1] { 0 };
                        var result = device.WritePartial(writeBuffer);
                        if (result.Status == I2cTransferStatus.SlaveAddressNotAcknowledged)
                            continue;

                        addresses.Add(address);
                        Debug.WriteLine("Added Address: " + address);
                    }
                    catch (Exception ex)
                    {

                    }
                }
                else
                {
                    Debug.WriteLine("device DOES equal null!", address);
                }
            }
        }

        stopWatch.Start();            
        System.Diagnostics.Debug.WriteLine(stopWatch.ElapsedMilliseconds.ToString());