If you want more ports, you can create more files based on this, for i2c address 0x20,0x21,0x22 etc
This example uses the first 8 ports (GPA0-GPA7) as low inputs, so the chip is set to pull up internal, the last 8 ports (GPB0-GPB7) are for the PIR in my case, they send HIGH when active, so I have 10K resistors between GND and each GPB0-GPB7 (chip has no internal pull down), some PIR don't need them, and don't react if placed, some PIR need them because the generate false positive (or being in flooting state). You can change easy mcp23017.input.c and mcp23017.setup.sh to you're own config. Place in this example the 10K resistors between GND and each GPB0-GPB7 when noting is connected or you will get false warning about port state, and switch with +3.3V
Beware every time a PIR send a signal the script will run, or a switch that stays open, will run a script every 50ms, I created a lock dir example, so you're create a dir, and sleep for some time, every time another same script is running it will exit, because there is a "lock" dir.
I included a zip file with all the example's
Filename : mcp23017.input.c
Code: Select all
/*
* mcp23017.input.c:
* This script provide 16 channel input with the MCP23017 with Orange-PI with the interupt port, so only when a button is pressed, the PI will check status all ports
* This take much less cpu time then when waiting for the interrupt on all 16 ports.
*
* 1. Connect the mcp23017 as usual with i2c, in this example on address 0x20 (3x GND)
* 2. Connect MCP23017 port 20 (INTA) to port (Physical) 37 on the PI (Number off the Physical pin 37 - Broadcom pin 20 - GPIO.25 - wPi 25)
* 3. Connect push buttons with GND on MCP23017 port 1-16
*
* This example uses the first 8 ports (GPA0-GPA7) as low inputs, so the chip is set to pull up internal,
* the last 8 ports (GPB0-GPB7) are for the PIR in my case, they send HIGH when active,
* so I have 10K resistors between GND and each GPB0-GPB7 (chip has no internal pull down),
* some PIR don't need them, and don't react if placed, some PIR need them because the generate false positive (or being in flooting state).
* You can change easy mcp23017.input.c and mcp23017.setup.sh to you're own config.
*
* When pushed or detection, it will start a script /root/scripts/mcp23017/mcp23017.GPA0, mcp23017.GPA1, mcp23017.GPB0 etc
*
*
* Created by ILoveIOT 2019
***********************************************************************************
* For compiling use : cd /root/scripts/mcp23017 ; gcc -Wall -o mcp23017.input mcp23017.input.c -lwiringPi
* For console use : /root/scripts/mcp23017/mcp23017.input
* For background use : /root/scripts/mcp23017/mcp23017.input &
***********************************************************************************
*/
#include <stdio.h> // Used for printf() statements
#include <wiringPi.h> // Include WiringPi library!
#include <stdlib.h> // Standard Library
#include <mcp23017.h> // I2C mcp23017 communication
#define Q2W_BASE 100
// We're using the Physical pin number, for the INTA/INTB, Orange-PI GPIO.25 to MCP23017 INTA
const int butPin = 37; // Number off the Physical pin 37 - Broadcom pin 20 - GPIO.25 - wPi 25
int main(void)
{
//printf("MCP23017 input script is running! Press CTRL+C to quit.\n");
// Add in the mcp23017 on the q2w board
mcp23017Setup (Q2W_BASE, 0x20) ;
// Enable the on-goard GPIO
wiringPiSetup () ;
// Setup stuff:
wiringPiSetupPhys(); // Initialize wiringPi -- Physical pin numbers
pinMode(butPin, INPUT); // Set button as INPUT on the PI
pullUpDnControl(butPin, PUD_UP); // Enable pull-up resistor on button
// Setup the MCP23017
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.setup.sh");
// Reset the INTA and INTB
system("/bin/bash -c /usr/sbin/i2cget -y 0 0x20 0x12 > /dev/null 2>&1");
system("/bin/bash -c /usr/sbin/i2cget -y 0 0x20 0x13 > /dev/null 2>&1");
delay(250);
// Loop (while(1)):
while(1)
{
if (digitalRead(butPin)) // Button is released if this returns 1
{
delay(50); // Wait 50ms again
}
else // If digitalRead returns 0, button is pressed
{
if (digitalRead (Q2W_BASE + 15) == HIGH) // While Pushed
{
//printf ("GPB7 is ON\n") ;
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.GPB7.sh &");
}
if (digitalRead (Q2W_BASE + 14) == HIGH) // While Pushed
{
//printf ("GPB6 is ON\n") ;
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.GPB6.sh &");
}
if (digitalRead (Q2W_BASE + 13) == HIGH) // While Pushed
{
//printf ("GPB5 is ON\n") ;
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.GPB5.sh &");
}
if (digitalRead (Q2W_BASE + 12) == HIGH) // While Pushed
{
//printf ("GPB4 is ON\n") ;
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.GPB4.sh &");
}
if (digitalRead (Q2W_BASE + 11) == HIGH) // While Pushed
{
//printf ("GPB3 is ON\n") ;
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.GPB3.sh &");
}
if (digitalRead (Q2W_BASE + 10) == HIGH) // While Pushed
{
//printf ("GPB2 is ON\n") ;
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.GPB2.sh &");
}
if (digitalRead (Q2W_BASE + 9) == HIGH) // While Pushed
{
//printf ("GPB1 is ON\n") ;
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.GPB1.sh &");
}
if (digitalRead (Q2W_BASE + 8) == HIGH) // While Pushed
{
//printf ("GPB0 is ON\n") ;
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.GPB0.sh &");
}
if (digitalRead (Q2W_BASE + 7) == LOW) // While Pushed
{
//printf ("GPA7 is ON\n") ;
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.GPA7.sh &");
}
if (digitalRead (Q2W_BASE + 6) == LOW) // While Pushed
{
//printf ("GPA6 is ON\n") ;
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.GPA6.sh &");
}
if (digitalRead (Q2W_BASE + 5) == LOW) // While Pushed
{
//printf ("GPA5 is ON\n") ;
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.GPA5.sh &");
}
if (digitalRead (Q2W_BASE + 4) == LOW) // While Pushed
{
//printf ("GPA4 is ON\n") ;
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.GPA4.sh &");
}
if (digitalRead (Q2W_BASE + 3) == LOW) // While Pushed
{
//printf ("GPA3 is ON\n") ;
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.GPA3.sh &");
}
if (digitalRead (Q2W_BASE + 2) == LOW) // While Pushed
{
//printf ("GPA2 is ON\n") ;
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.GPA2.sh &");
}
if (digitalRead (Q2W_BASE + 1) == LOW) // While Pushed
{
//printf ("GPA1 is ON\n") ;
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.GPA1.sh &");
}
if (digitalRead (Q2W_BASE + 0) == LOW) // While Pushed
{
//printf ("GPA0 is ON\n") ;
system("/bin/bash -c /root/scripts/mcp23017/mcp23017.GPA0.sh &");
}
// Reset the INTA and INTB
system("/bin/bash -c /usr/sbin/i2cget -y 0 0x20 0x12 > /dev/null 2>&1");
system("/bin/bash -c /usr/sbin/i2cget -y 0 0x20 0x13 > /dev/null 2>&1");
delay(50); // Wait 150ms again
}
}
return 0;
}
Code: Select all
#/bin/bash
# Change in /boot/armbianEnv.txt overlays=i2c0 i2c1 i2c2
# apt-get install i2c-tools
# i2cdetect -y 0 of i2cdetect -y 1
#$ i2cdetect -y 0
# 0 1 2 3 4 5 6 7 8 9 a b c d e f
#00: -- -- -- -- -- -- -- -- -- -- -- -- --
#10: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- --
#20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
#30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
#40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
#50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
#60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
#70: -- -- -- -- -- -- -- --
# Define complete bank A as IN-Port:
/usr/sbin/i2cset -y 0 0x20 0x00 0xFF
# Define complete bank B as IN-Port:
/usr/sbin/i2cset -y 0 0x20 0x01 0xFF
# Activate all internal pullup resistors at bank A:
/usr/sbin/i2cset -y 0 0x20 0x0C 0xFF
# Activate all internal pullup resistors at bank B:
#/usr/sbin/i2cset -y 0 0x20 0x0D 0xFF
# Activate Interrupt OnChange for Port INTA:
/usr/sbin/i2cset -y 0 0x20 0x04 0xFF
# Activate Interrupt OnChange for Port INTB:
/usr/sbin/i2cset -y 0 0x20 0x05 0xFF
# Connect Interrupt-Pin A with the one of B (MIRROR = 1):
/usr/sbin/i2cset -y 0 0x20 0x0A 0x40
# Connect Interrupt-Pin B with the one of A (MIRROR = 1):
/usr/sbin/i2cset -y 0 0x20 0x0B 0x40
exit
### EOF
