我一直在尝试扫描使用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;
//}
}
}
答案 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());