【问题标题】:Turning One Raspberry Pi I2C Connected Relay On Turns the Other Relay Off打开一个 Raspberry Pi I2C 连接的继电器会关闭另一个继电器
【发布时间】:2019-11-26 17:53:08
【问题描述】:

目前,我有两个 2 通道 1 Amp SPDT 信号继电器控制器通过 I2C 连接到我的 Raspberry Pi 3,当我当前运行打开一个继电器的功能时,另一个将同时关闭(一个或另一个打开)。此外,我关闭继电器 1 的按钮和关闭继电器 2 的按钮将关闭两个继电器。

我的程序是用 Windows 窗体 (visual studio) 编写的,我正在通过 Dll Import 访问 C 共享库,但我知道事实上我的问题出在我的 C 库中。我对 C 和 shift 如何工作非常陌生,所以我的问题的根源在于我的代码的逻辑和结构。坦率地说,我对如何正确编码感到困惑。

这是目前打开继电器 1 的方法。它会正确打开继电器,但这也会同时关闭继电器 2。

void Relay1On() ***CURRENTLY TURNS OTHER OFF WHEN ACTIVATED***
{
    // Create I2C bus
    int file;
    char *bus = "/dev/i2c-1";
    if ((file = open(bus, O_RDWR)) < 0) 
    {
        printf("Failed to open the bus. \n");
        exit(1);
    }
    // Get I2C device, MCP23008 I2C address is 0x20(32)
    ioctl(file, I2C_SLAVE, 0x20);

    // Configure all pins of port as output (0x00)
    char config[2] = {0};
    config[0] = 0x00;
    config[1] = 0x00;
    write(file, config, 2);

    //Turn the first relay on
    char data = 0x01;
    config[0] = 0x09;
    config[1] = data;
    write(file, config, 2);

}

这里是 Relay 1 Off 的代码,我不会发布 Relay 2 On/Off 因为它基本相同,Relay2On 只是在char data = 0x01; 之后添加了data += 1;。两种“关闭”方法都会导致两个继电器都关闭。

void Relay1Off()
{
    // Create I2C bus
    int file;
    char *bus = "/dev/i2c-1";
    if ((file = open(bus, O_RDWR)) < 0) 
    {
        printf("Failed to open the bus. \n");
        exit(1);
    }
    // Get I2C device, MCP23008 I2C address is 0x20(32)
    ioctl(file, I2C_SLAVE, 0x20);

    // Configure all pins of port as output (0x00)
    char config[2] = {0};
    config[0] = 0x00;
    config[1] = 0x00;
    write(file, config, 2);

    //Turn the first relay off *****Turns all off at the moment******
    char data = 0xFE;
    data = (data << 1);
    config[0] = 0x09;
    config[1] = data;
    write(file, config, 2);
}

我想要的只是所描述的方法,在调用该方法时打开 Relay 1。当调用 Relay1Off 时,仅关闭 Relay 1。我确信这很简单,但正如我在上面所说的,C 对我来说很新。

提前感谢您的任何贡献。

【问题讨论】:

  • 如果您尝试打开和关闭继电器 2,是否也会影响继电器 1,只做继电器 2,还是什么都不做?
  • @ThomasJager 打开继电器 2 将关闭继电器 1,是的。关闭继电器 2 的结果与关闭继电器 1 的结果相同 - 两者都关闭。如果有更好的帮助,我可以发布 Relay 2 功能的代码
  • 愚蠢的问题,他们有相同的I2C地址吗?
  • @yhyrcanus 是的,两个继电器在一块板上。单板地址为0x20
  • 等等,MCP23008 是一个 IO 扩展器。继电器本身不是 I2C 设备。您可能希望对数据使用按位数学,而不是仅仅等于它。每次,您都将这些位设置为 10 或 01 或 00。如果您保持激活了哪些继电器的状态,您可以使用它或它/它带有一个掩码来打开/只打开您想要关闭的那个。

标签: c raspberry-pi hardware i2c smbus


【解决方案1】:

我不知道花哨的ioctl 是如何工作的,但我会尝试在此函数之外进行所有初始化,包括将所有 GPIO 设置为输出。

您可能应该只调用一个函数来设置/清除继电器。我会做这样的事情开始:

void RelayOnOff(unsigned char relay, unsigned char enable)
{
    //Init to all off
    static unsigned char data = 0x00;
    ...  
    if (enable){
        data |= ( 1 << relay );
    }
    else{
        data &= ~( 1 << relay );
    }
    config[0] = 0x09;
    config[1] = data;
    write(file, config, 2);
}

您传入要控制的继电器,以及启用/禁用的布尔值。如果您将数据变量设为静态,它会从函数调用到函数调用“记住”该值。启用/禁用设置/清除您传入的任何继电器的位 (0-7)。

【讨论】:

  • 根据我的理解(这是最小的),基本上 ioctl 只是一种查找设备并将其配置为输出或输入的方法。不过还是谢谢你的回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-29
  • 1970-01-01
  • 2020-07-30
  • 1970-01-01
  • 1970-01-01
  • 2017-10-28
  • 1970-01-01
相关资源
最近更新 更多