在I2C中扫描地址 [英] Scanning Addresses in I2C

查看:127
本文介绍了在I2C中扫描地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述






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


I've been trying to scan addresses 1-128 on the ports of Raspberry Pi 3 that exist when using I2C. Note that we have 1 GB RAM, and our software always maxes it out especially during this process (actually, it is about 900K, really).


我们的操作系统:Windows 10 物联网核心构建17744.Atlas Scientific具有pH值传感器,CO2,温度,电导率和氧化/还原电位(ORP)。假设我们使用Whitebox'Labs
触手3(我们)来托管3个电路和传感器及其相关传感器。 

Our Operating System: Windows 10 IOT Core Build 17744. Atlas Scientific has sensors for pH, CO2, Temperature, Conductivity and Oxidation/reduction potential (ORP). Let's assume we are using the Whitebox' Labs Tentacle 3 (we are) to host 3 circuits and sensors and their associated sensors. 


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

Iterating through 1-128 takes 35 seconds, which is impermissible. Also, Python on Raspian Doesn't take as long. (I'm going to validate that right now).


1)我注意到扫描循环是在一个静态类中。我认为"使用"会确保垃圾收集能够清除这种情况。它没有。

1)I noticed the scanning loop was in a static class. I thought "using" would ensure that garbage collection would clear the situation. It didn't.


1a)我在没有"使用"的情况下重写了它,但是Dispose。相同的结果;

1a) I rewrote it without "using", but Dispose. Same result;


2)接下来,我尝试了IOT Lightning DMAP驱动程序。 这对时间没有影响。

2) Next, I tried the IOT Lightning DMAP driver. This had no effect on the time either.


帮助我Obi-Wan Kenobi,你是我唯一的希望我已经将它交叉发布到StackOverflow。是时候尝试使用C ++了吗?

Help Me Obi-Wan Kenobi, you're my only hope I've cross-posted this to StackOverflow. Is it time to try C++?


有两个版本的FindDevicesAsync(一个有一个没有Lightning DMAP)

There are two versions of FindDevicesAsync (one with and one without 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;
        //}


    }
}









推荐答案

Hello Jon Steiner,

Hello Jon Steiner,


由于异常抛出然后地址"SlaveAddressNotAcknowledged"导致这么多时间,时间成本取决于您扫描的地址数。

This result in so much time due to the exception throw then the address "SlaveAddressNotAcknowledged", the time cost depends on the number of the addresses you scan.


要解决此问题,您可以使用WritePartial而不是Write。 WritePartial不会导致抛出异常,但会在返回结果中报告状态代码:I2cTransferResult,  I2cTransferStatus
所以节省时间。迭代1-105大约需要1.2秒。

To solve this issue you can use WritePartial instead of Write. WritePartial can't result in an exception thrown but report the status code in the return result: I2cTransferResult, I2cTransferStatus. So save the time. Iterating through 1-105 takes about 1.2 seconds.


您可以尝试以下代码:

You can try the following code:

        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());






如果有帮助,请告诉我。

Please let me know if it helps.

祝你好运,

Rita


这篇关于在I2C中扫描地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆