HomeGenie Forum
Automation Program Plugins and Wizard Scripting => Raspberry Pi GPIO/SPI/I2C => Topic started by: MikeS on October 09, 2014, 09:36:02 PM
-
Hey @all!
First at all I wanna say Gene thanks for his great program.
This is really the best HomeAutomation software I've seen yet!
But I am a very beginner regarding Homegenie and still learning a lot.
I want to hook up a PCF8574 expander to HomeGenie to control small relais cards with 4 inputs and outputs. I saw in the source of raspberry-sharp-io that there is already a class for it.
I changed the MCP23017 sample in HomeGenie to the following code:
var moduleDomain = "Components.PCF8475x";
var pinConfiguration = new List<dynamic>(){
new { Address = "1", Pin = Raspberry.IO.Components.Expanders.Pcf8574.Pcf8574Pin.P0, Direction = "Out" },
new { Address = "2", Pin = Raspberry.IO.Components.Expanders.Pcf8574.Pcf8574Pin.P1, Direction = "Out" },
new { Address = "3", Pin = Raspberry.IO.Components.Expanders.Pcf8574.Pcf8574Pin.P2, Direction = "Out" },
new { Address = "4", Pin = Raspberry.IO.Components.Expanders.Pcf8574.Pcf8574Pin.P3, Direction = "Out" },
new { Address = "5", Pin = Raspberry.IO.Components.Expanders.Pcf8574.Pcf8574Pin.P4, Direction = "In" },
new { Address = "6", Pin = Raspberry.IO.Components.Expanders.Pcf8574.Pcf8574Pin.P5, Direction = "In" },
new { Address = "7", Pin = Raspberry.IO.Components.Expanders.Pcf8574.Pcf8574Pin.P6, Direction = "In" },
new { Address = "8", Pin = Raspberry.IO.Components.Expanders.Pcf8574.Pcf8574Pin.P7, Direction = "In" }
//
};
bool[] pinStatus = new bool[8];
var sdaPin = ConnectorPin.P1Pin03.ToProcessor();
var sclPin = ConnectorPin.P1Pin05.ToProcessor();
var I2CTreiber = new I2cDriver(sdaPin, sclPin);
var I2CConnection = new Raspberry.IO.Components.Expanders.Pcf8574.Pcf8574I2cConnection(I2CTreiber.Connect(0x38));
When.WebServiceCallReceived(moduleDomain, ( args ) =>
{
string[] reqs = ((string)args).Split('/');
var errormessage = "";
try
{
string pinid = reqs[1];
string command = reqs[2];
//
var module = Modules.InDomain(moduleDomain).WithAddress(pinid).Get();
var pinname = "";
var i = int.Parse(pinid);
pinname = "P" + (i - 1).ToString();
//
var mcppin = (Raspberry.IO.Components.Expanders.Pcf8574.Pcf8574Pin)Enum.Parse(typeof(Raspberry.IO.Components.Expanders.Pcf8574.Pcf8574Pin), pinname);
switch(command)
{
// eg. http://hg_address/api/Expanders.MCP23017/1/Control.On
case "Control.On":
I2CConnection.SetPinStatus(mcppin, true);
break;
// eg. http://hg_address/api/Expanders.MCP23017/3/Control.Off
case "Control.Off":
I2CConnection.SetPinStatus(mcppin, false);
break;
// eg. http://hg_address/api/Expanders.MCP23017/9/Control.Toggle
case "Control.Toggle":
I2CConnection.Toogle(mcppin);
break;
}
Program.RaiseEvent(module, "Status.Level",
I2CConnection.GetPinStatus(mcppin) ? "1" : "0",
"PCF8574 " + pinname);
//
return "{ 'ResponseValue' : 'OK' }";
}
catch (Exception ex)
{
errormessage = ex.Message + " " + ex.StackTrace;
}
// unable to process request
return "{ 'ResponseValue' : 'ERROR " + errormessage + "' }";
});
for (int p = 0; p < pinConfiguration.Count; p++)
{
var pincfg = pinConfiguration[p];
if(pincfg.Direction == "In")
{
Raspberry.IO.Components.Expanders.Pcf8574.Pcf8574PinExtensionMethods.In(I2CConnection, pincfg.Pin);
Program.AddVirtualModule(moduleDomain, pincfg.Address, "Sensor", "homegenie/generic/sensor");
}
else
{
Raspberry.IO.Components.Expanders.Pcf8574.Pcf8574PinExtensionMethods.Out(I2CConnection, pincfg.Pin);
Program.AddVirtualModule(moduleDomain, pincfg.Address, "Switch", "");
}
// get the module associated to the pin and store current status
var module = Modules.InDomain(moduleDomain).WithAddress(pincfg.Address).Get();
module.Parameter("Status.Level").Value = (pinStatus[p] ? "1" : "0");
}
// status polling loop
while (Program.IsEnabled)
{
Pause(0.5); // 500 ms poll resolution
//
for (int p = 0; p < pinConfiguration.Count; p++)
{
var pincfg = pinConfiguration[p];
if (p>3)
{
bool status = I2CConnection.GetPinStatus(pincfg.Pin);
// check if the pin status changed
if (pinStatus[p] != status)
{
// get the module associated to the pin
var module = Modules.InDomain(moduleDomain).WithAddress(pincfg.Address).Get();
// raise the event and update the current pin status
Program.RaiseEvent(module, "Status.Level",
status ? "1" : "0",
"PCF8574 " + pincfg.Pin.ToString());
pinStatus[p] = status;
Pause(0.1);
}
}
}
}
When I add now the items to HomeGenie the outputs work all fine.
But the inputs are always on false.
I checked the voltage at the IC directly. When I boot up the pi, all inputs are on "high", that means the current source is activated and I have an internal pull-up.
When HomeGenie started, all inputs are on "low". So I have no chance to get a high level.
I checked the communication to the IC with the i2c-tools and everything seems to work. With i2cget command I can see every change at the inputs.
I know that there have to be written a "0" to activate the internal pull-up on high for the outputs. But I cannot find my mistake in the code.
Does somebody have a working code example so I can get this thing running?
And why is the SetInputPin method in PCF8574 class in raspberry-sharp-io only accessible by internal? So I have to use the PinExtensions method to set a pin as an input.
Thanks a lot!
-
Hi Mike,
Internal pull-up resistor can be set for Pi GPIOs, but I don't see any reference to pull-up resistor parameter in PCF8574 classes so this might not be implemented.
I'll try to point the author of raspberry# to this forum post, pheraps he can help figuring this out.
Cheers,
g.
-
Hi MikeS,
see here:
https://github.com/raspberry-sharp/raspberry-sharp-io/issues/21#issuecomment-58743833
Cheers,
g.
-
Hey Gene,
I don't believe it, it worked like ebezine wrote at github forum!
I compiled the project with MS Visual Studio 2012 and MSBuild Version 12.0
There were no errors or warnings.
My program in HomeGenie is running fine but if I try to update it again it always pops up an error message: "Line -16, Column 0 (Code to Run): Input string was not in the correct format"
Something seems to have changed beside my little edit or it is not compiled correctly.
I tried to update the MCP23017 program but same there.
Should I post this in the github forum or do you know what I did wrong?
Thanks a lot!
MikeS