more G-Labs products

Author Topic: PCF8574  (Read 2249 times)

October 09, 2014, 09:36:02 PM
Read 2249 times

MikeS

  • *
  • Information
  • Newbie
  • Posts: 4
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:

Code: [Select]
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!

October 10, 2014, 11:14:10 PM
Reply #1

Gene

  • *****
  • Information
  • Administrator
  • Posts: 1472
  • Tangible is the future!
    • Yet Another Programmer
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.

October 11, 2014, 12:57:39 PM
Reply #2

Gene

  • *****
  • Information
  • Administrator
  • Posts: 1472
  • Tangible is the future!
    • Yet Another Programmer

October 12, 2014, 11:18:15 PM
Reply #3

MikeS

  • *
  • Information
  • Newbie
  • Posts: 4
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