Closed D4rkF4ce closed 7 years ago
For info yes it works.
Hey I just saw this, I saw you wrote to me on twitter also. Glad that this works for you! Do you still have a question?
Hello
Thx, i think for this topic its better to write here.
I am currently building a Home-Automation system with the Pi3
My main components: 3 Relays 1 BME280 1 DS1307 RTC 1 Touchscreen
Single, I can already address everything.
But with the two I2C modules (RTC & BME280) I always get an exception alternately: "WinRT information: Slave address was not acknowledged."
I use this Nuget package and another classes of an Adafruit package also here from github. (https://github.com/BuildAzure/BuildAzure.IoT.Adafruit.BME280)
My thought: When my app is starting i init all modules and then call what i need but it is apparently not so easy.
after some search i think i have to set the I2cConnectionSettings to ShareMode for every iC2 object and Dispose every time after call. And init again by another call
what du you think?
Hey - I found this link which kind of looks like what you are trying, in that there's multiple I2C devices connected to a Raspberry Pi https://www.hackster.io/AnuragVasanwala/home-automation-0dcefc
The author has some code on Github - an interesting file is here, particularly the CollectData method: https://github.com/AnuragVasanwala/Home-Automation--RPi2-WinIoT-/blob/master/Home%20Automation%20(RPi2%20WinIoT)/MainPage.xaml.cs
It obviously refers to other code in that project, the I2C_Helper class looks interesting too.
I hope this helps Jeremy
Hey!
Thx for the hint and the links.
I think the error lies in my initialization of the I2C devices.
My Init Logic in Page_On_Loaded():
Init_BME280_Sensor()
Init_DS1307_RTC()
When I access the first I2C device (BME280_Sensor) after initialization I get an incorrect I2C_address and a "WinRT information: Slave address was not acknowledged." - Exception.
Based on your Logic, I now have the following idea:
I will add enums for my I2C Adresses:
// Provides the Adress Numbers for our I2C-Modules according to the datasheets
public enum I2CDevices
{
// The BME280 datasheet: http://www.adafruit.com/datasheets/BST-BME280-DS001-11.pdf
Hygromether = 0x77,
// The DS1307 RTC datasheet: http://www.netmftoolbox.com/documents/Hardware.DS1307.pdf
RealTimeClock = 0x68
}
I'm going to implement a FactoryPattern which provides me on the fly the right I2CDevice:
public static async Task <I2cDevice> GetI2CDevice (I2CDevices i2cDevice)
{
switch (i2cDevice)
{
case I2CDevices.Hygromether:
return await I2cSlave.Initialize (Convert.ToByte (I2CDevices.Hygromether));
case I2CDevices.RealTimeClock:
return await I2cSlave.Initialize (Convert.ToByte (I2CDevices.RealTimeClock));
default:
throw new ArgumentOutOfRangeException (nameof (i2cDevice), i2cDevice, null);
}
}
Implement a static Class "I2cSlave" which do the init for me by given I2C Adress and returning me the right I2CDevice:
public static async Task<I2cDevice> Initialize(byte i2cDevice)
{
Debug.WriteLine("I2cSlave::Initialize on I2C_Address: " + i2cDevice);
try
{
i2cAddress = i2cDevice;
//Instantiate the I2CConnectionSettings using the device address
I2cConnectionSettings settings = new I2cConnectionSettings(i2cDevice);
//Set the I2C bus speed of connection to fast mode
settings.BusSpeed = I2cBusSpeed.FastMode;
//Set I2C connection to shared mode
settings.SharingMode = I2cSharingMode.Shared;
//Use the I2CBus device selector to create an advanced query syntax string
string aqs = I2cDevice.GetDeviceSelector(i2cControllerName);
//Use the Windows.Devices.Enumeration.DeviceInformation class to create a collection using
the advanced query syntax string
DeviceInformationCollection dis = await DeviceInformation.FindAllAsync(aqs);
//Instantiate the I2C device using the device id of the I2CBus and the I2CConnectionSettings
I2CModul = await I2cDevice.FromIdAsync(dis[0].Id, settings);
//Check if device was found
if (I2CModul == null)
{
Debug.WriteLine("Device not found");
}
}
catch (Exception e)
{
Debug.WriteLine("Exception: " + e.Message + "\n" + e.StackTrace);
throw;
}
return I2CModul;
}
The individual sensor classes I pass Inherit from IDisposable so i can Dispose() it after using.
Call:
var slave = await I2CDeviceFactory.GetI2CDevice (I2CDevices.RealTimeClock);
using (AutoPlantSystem.Driver.RealTimeClock = new SainSmart_DS_1307_RTC (slave))
{
DateTime date = AutoPlantSystem.Driver.RealTimeClock.GetCurrentTime ();
Debug.WriteLine ("The Time is:" + date);
txtTime.Text = date.ToString ("dd.mm.yyyy - HH: mm: ss");
}
I'll let you know if it works.
Yes it works! :) So always take using for open, access & dispose. Now all the functions work, finally the protoytpe can go on. Thx for pointing me in the right direction.
Brilliant! Glad to hear it, and happy to help.
Can I ask what touchscreen you're using with the Raspberry Pi? I'd be interested in doing some programming with that peripheral.
I use the official Pi 7" Touchscreen: https://www.amazon.de/dp/B014WKCFR4/ref=cm_sw_r_sms_awd_xs_jA7-ybKJ29SC0
Screen and touch work out of the Box. i am also interested maybe i need a driver to control the brightness.
All parts of my Project are listed here: http://www.hightechnix.at/autoplant/?page_id=196#hardwareComponents
Hey Jeremy!
First of all thanks for the code and your work on your blog. It was very informative and helpful. Now I would like to add an RTC to my Raspberry Pi 3 project.
Can I buy this RTC: https://www.sainsmart.com/sainsmart-arduino-i2c-rtc-ds1307-at24c32-real-time-clock-module-for-avr-arm-pic.html
There are so many different DS1307 RTC types to buy.
Thx!