Version 1.1

master v1.1
sfeakes 2020-09-26 17:16:36 -05:00
parent 9648433ef8
commit 5c3f29e773
16 changed files with 1868 additions and 52 deletions

1473
GPIO_Pi.c Normal file

File diff suppressed because it is too large Load Diff

162
GPIO_Pi.h Normal file
View File

@ -0,0 +1,162 @@
/*
* Copyright (c) 2017 Shaun Feakes - All rights reserved
*
* You may use redistribute and/or modify this code under the terms of
* the GNU General Public License version 2 as published by the
* Free Software Foundation. For the terms of this license,
* see <http://www.gnu.org/licenses/>.
*
* You are free to use this software under the terms of the GNU General
* Public License, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* https://github.com/sfeakes/GPIO_pi
*/
/********************-> GPIO Pi v1.2 <-********************/
#define _GPIO_pi_NAME_ "GPIO Pi"
#define _GPIO_pi_VERSION_ "1.2"
#ifndef _GPIO_pi_H_
#define _GPIO_pi_H_
/* Use sysfs for ALL gpio activity?
comment out to use memory where we can
*/
//#define GPIO_SYSFS_MODE
#include <syslog.h>
#include <stdbool.h>
// check number is between 2 and 27
#ifndef USE_WIRINGPI
#define GPIO_MIN 2
#define GPIO_MAX 27
#else // WiringPI valid numbers
#define GPIO_MIN 0
#define GPIO_MAX 30
#endif
#define validGPIO(X) ((X) <= (GPIO_MAX) ? ( ((X) >= (GPIO_MIN) ? (1) : (0)) ) : (0))
#ifndef USE_WIRINGPI // Don't include anything below this line if using wiringpi.
#define INPUT 0
#define OUTPUT 1
#define IO_ALT5 2 // PWM Circuit
#define IO_ALT4 3 // SPI Circuit
#define IO_ALT0 4 // PCM Audio Circuit (Also I2C)
#define IO_ALT1 5 // SMI (Secondary Memory Interface)
#define IO_ALT2 6 // Nothing
#define IO_ALT3 7 // BSC - SPI Circuit
#define LOW 0
#define HIGH 1
#define INT_EDGE_SETUP 0
#define INT_EDGE_FALLING 1
#define INT_EDGE_RISING 2
#define INT_EDGE_BOTH 3
#define PUD_OFF 0
#define PUD_DOWN 1
#define PUD_UP 2
#define SYSFS_PATH_MAX 35
#define SYSFS_READ_MAX 3
#ifndef GPIO_SYSFS_MODE
#define GPIO_BASE_P4 0xFE000000 // Pi 4
#define GPIO_BASE_P2 0x3F000000 // Pi 2 & 3
#define GPIO_BASE_P1 0x20000000 // Pi 1 & Zero
#define GPIO_OFFSET 0x200000
//#define GPIO_BASE 0x20200000
#define GPIO_LEN 0xB4
#define GPIO_LEN_P4 0xF1 // Pi 4 has more registers BCM2711
#define GPSET0 7
#define GPSET1 8
#define GPCLR0 10
#define GPCLR1 11
#define GPLEV0 13
#define GPLEV1 14
#define GPPUD 37
#define GPPUDCLK0 38
#define GPPUDCLK1 39
/* Pi4 BCM2711 has different pulls */
#define GPPUPPDN0 57
#define GPPUPPDN1 58
#define GPPUPPDN2 59
#define GPPUPPDN3 60
#define PI_MODEL_UNKNOWN -1
#define PI_MODEL_A 0
#define PI_MODEL_B 1
#define PI_MODEL_AP 2
#define PI_MODEL_BP 3
#define PI_MODEL_2 4
#define PI_ALPHA 5
#define PI_MODEL_CM 6
#define PI_MODEL_07 7
#define PI_MODEL_3 8
#define PI_MODEL_ZERO 9
#define PI_MODEL_CM3 10
#define PI_MODEL_ZERO_W 12
#define PI_MODEL_3P 13
#define PI_MODEL_3AP 14
#define PI_MODEL_CM3P 16
#define PI_MODEL_4B 17
#endif
#define GPIO_ERR_GENERAL -7
#define GPIO_NOT_IO_MODE -6
#define GPIO_NOT_OUTPUT -5
#define GPIO_NOT_EXPORTED -4
#define GPIO_ERR_IO -3
#define GPIO_ERR_NOT_SETUP -2
#define GPIO_ERR_BAD_PIN -1
#define GPIO_OK 0
//#ifndef SYSFS_MODE
int pinExport(unsigned int gpio);
int pinUnexport(unsigned int gpio);
bool isExported(unsigned int gpio);
int pinMode(unsigned int gpio, unsigned int mode);
int getPinMode(unsigned int gpio);
int digitalRead(unsigned int gpio);
int digitalWrite(unsigned int gpio, unsigned int level);
int setPullUpDown(unsigned int gpio, unsigned int pud);
int edgeSetup (unsigned int pin, unsigned int value);
bool gpioSetup();
void gpioShutdown();
int registerGPIOinterrupt(unsigned int gpio, unsigned int mode, void (*function)(void *args), void *args );
#ifndef GPIO_SYSFS_INTERRUPT
int unregisterGPIOinterrupt(unsigned int gpio);
#endif
/*
#else
bool pinExport(int pin);
bool pinUnexport(int pin);
bool pinMode (int pin, int mode);
int digitalRead (int pin);
bool digitalWrite (int pin, int value);
#endif
*/
#endif /* WiringPI */
#endif /* _GPIO_pi_H_ */

View File

@ -4,7 +4,7 @@ CC = gcc
#USE_WIRINGPI := 1
ifeq ($(USE_WIRINGPI),)
sd_GPIO_C := sd_GPIO.c
sd_GPIO_C := GPIO_Pi.c
else
#WPI_LIB := -D USE_WIRINGPI -lwiringPi -lwiringPiDev
WPI_LIB := -D USE_WIRINGPI -lwiringPi
@ -58,8 +58,8 @@ $(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)
gpio_tools:
$(CC) -o $(GMON) sd_GPIO.c -lm -lpthread -D GPIO_MONITOR
$(CC) -o $(GPIO) sd_GPIO.c -lm -lpthread -D GPIO_RW
$(CC) -o $(GMON) GPIO_Pi.c -lm -lpthread -D GPIO_MONITOR
$(CC) -o $(GPIO) GPIO_Pi.c -lm -lpthread -D GPIO_TOOL
# this is a suffix replacement rule for building .o's from .c's
# it uses automatic variables $<: the name of the prerequisite of

View File

@ -13,7 +13,7 @@
#define PIN_CFG_NAME "GPIO_PIN"
#endif
#include "sd_GPIO.h"
#include "GPIO_Pi.h"
#include "minIni.h"
#include "utils.h"
#include "config.h"

View File

@ -6,7 +6,7 @@
#ifdef USE_WIRINGPI
#include <wiringPi.h>
#else
#include "sd_GPIO.h"
#include "GPIO_Pi.h"
#endif
#include "json_messages.h"

View File

@ -9,7 +9,7 @@
#ifdef USE_WIRINGPI
#include <wiringPi.h>
#else
#include "sd_GPIO.h"
#include "GPIO_Pi.h"
#endif
#include "mongoose.h"

Binary file not shown.

Binary file not shown.

162
release/install-new.sh Executable file
View File

@ -0,0 +1,162 @@
#!/bin/bash
#
# ROOT=/nas/data/Development/Raspberry/gpiocrtl/test-install
#
BUILD="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
SERVICE="sprinklerd"
BIN="sprinklerd"
CFG="sprinklerd.conf"
SRV="sprinklerd.service"
DEF="sprinklerd"
MDNS="sprinklerd.service"
BINLocation="/usr/local/bin"
CFGLocation="/etc"
SRVLocation="/etc/systemd/system"
DEFLocation="/etc/default"
WEBLocation="/var/www/sprinklerd/"
MDNSLocation="/etc/avahi/services/"
function check_cron() {
# Look for cron running with LSB name support
if [[ ! $(pgrep -af cron | grep '\-l') ]]; then
# look for cron running
if [[ ! $(pgrep -af cron) ]]; then
# look for cron installed
if [[ ! $(command -v cron) ]]; then
echo "Can't find cron, please install"
else
echo "cron is not running, please start cron"
fi
else
# Cron is running, but not with LSB name support
if [ ! -d "/etc/cron.d" ] || [ ! -f "/etc/default/cron" ]; then
echo "The version of Cron may not support chron.d, if so the calendar schedule will not work"
echo "Please check cron for LSB name support before using calendar schedule feature of $SERVICE"
else
# Check and see if we can add LSB support
#if [ -f "/etc/default/cron" ]; then
echo ...
fi
fi
fi
}
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root"
exit 1
fi
if [[ $(mount | grep " / " | grep "(ro,") ]]; then
echo "Root filesystem is readonly, can't install"
exit 1
fi
check_cron
exit 0
if [ ! -d "/etc/cron.d" ]; then
echo "The version of Cron may not support chron.d, if so the calendar schedule will not work"
echo "Please check before starting"
else
if [ -f "/etc/default/cron" ]; then
CD=$(cat /etc/default/cron | grep -v ^# | grep "\-l")
if [ -z "$CD" ]; then
echo "Please enabled cron.d support, if not the calendar will not work"
echo "Edit /etc/default/cron and look for the -l option"
fi
else
echo "Please make sure the version if Cron supports chron.d, if not the calendar schedule will not work"
fi
fi
exit 0
if [ "$1" == "uninstall" ] || [ "$1" == "-u" ] || [ "$1" == "remove" ]; then
systemctl stop $SERVICE > /dev/null 2>&1
systemctl disable $SERVICE > /dev/null 2>&1
rm -f $BINLocation/$BIN
rm -f $SRVLocation/$SRV
rm -f $DEFLocation/$DEF
rm -f $MDNSLocation/$MDNS
rm -rf $WEBLocation
if [ -f $CFGLocation/$CFG ]; then
cache=$(cat $CFGLocation/$CFG | grep CACHE | cut -d= -f2 | sed -e 's/^[ \t]*//' | sed -e 's/ *$//')
rm -f $cache
rm -f $CFGLocation/$CFG
fi
rm -f "/etc/cron.d/sprinklerd"
echo "SprinklerD & configuration removed from system"
exit
fi
# Check cron.d options
if [ ! -d "/etc/cron.d" ]; then
echo "The version of Cron may not support chron.d, if so the calendar will not work"
echo "Please check before starting"
else
if [ -f "/etc/default/cron" ]; then
CD=$(cat /etc/default/cron | grep -v ^# | grep "\-l")
if [ -z "$CD" ]; then
echo "Please enabled cron.d support, if not the calendar will not work"
echo "Edit /etc/default/cron and look for the -l option"
fi
else
echo "Please make sure the version if Cron supports chron.d, if not the calendar will not work"
fi
fi
# Exit if we can't find systemctl
command -v systemctl >/dev/null 2>&1 || { echo "This script needs systemd's systemctl manager, Please check path or install manually" >&2; exit 1; }
# stop service, hide any error, as the service may not be installed yet
systemctl stop $SERVICE > /dev/null 2>&1
SERVICE_EXISTS=$(echo $?)
# copy files to locations, but only copy cfg if it doesn;t already exist
cp $BUILD/$BIN $BINLocation/$BIN
cp $BUILD/$SRV $SRVLocation/$SRV
if [ -f $CFGLocation/$CFG ]; then
echo "Config exists, did not copy new config, you may need to edit existing! $CFGLocation/$CFG"
else
cp $BUILD/$CFG $CFGLocation/$CFG
fi
if [ -f $DEFLocation/$DEF ]; then
echo "Defaults exists, did not copy new defaults to $DEFLocation/$DEF"
else
cp $BUILD/$DEF.defaults $DEFLocation/$DEF
fi
if [ -f $MDNSLocation/$MDNS ]; then
echo "Avahi/mDNS defaults exists, did not copy new defaults to $MDNSLocation/$MDNS"
else
if [ -d "$MDNSLocation" ]; then
cp $BUILD/$MDNS.avahi $MDNSLocation/$MDNS
else
echo "Avahi/mDNS may not be installed, not copying $MDNSLocation/$MDNS"
fi
fi
if [ ! -d "$WEBLocation" ]; then
mkdir -p $WEBLocation
fi
cp -r $BUILD/../web/* $WEBLocation
systemctl enable $SERVICE
systemctl daemon-reload
if [ $SERVICE_EXISTS -eq 0 ]; then
echo "Starting daemon $SERVICE"
systemctl start $SERVICE
fi

Binary file not shown.

View File

@ -4,22 +4,22 @@ NAME=My Sprinklers
DOCUMENTROOT = /nas/data/Development/Raspberry/SprinklerD/web/
CACHE = /var/cache/sprinklerd.cache
# The log level. [DEBUG, INFO, NOTICE, WARNING, ERROR]
#LOG_LEVEL = DEBUG
LOG_LEVEL = DEBUG
#LOG_LEVEL = NOTICE
LOG_LEVEL = INFO
#LOG_LEVEL = INFO
# mqtt stuff
MQTT_ADDRESS = trident:1883
#MQTT_ADDRESS = trident:1883
#MQTT_USER = someusername
#MQTT_PASSWD = somepassword
MQT_TOPIC = sd_test
MQTT_DZ_PUB_TOPIC = domoticz/in
MQTT_DZ_SUB_TOPIC = domoticz/out
#MQT_TOPIC = sd_test
#MQTT_DZ_PUB_TOPIC = domoticz/in
#MQTT_DZ_SUB_TOPIC = domoticz/out
DZIDX_CALENDAR = 197
DZIDX_24HDELAY = 198
DZIDX_ALL_ZONES = 199
DZIDX_RAINSENSOR = 48
DZIDX_CALENDAR = 2197
DZIDX_24HDELAY = 2198
DZIDX_ALL_ZONES = 2199
DZIDX_RAINSENSOR = 2248
# Options for the below ZONE and GPIO configuration
#
@ -31,12 +31,11 @@ DZIDX_RAINSENSOR = 48
# PUD_UP 2
#NAME = name of zone
#GPIO_PIN = GPIO Pin # This is WiringPi Pin#, not Raspberry Pi board pin#.
#WPI_PIN = use instead of GPIO_PIN if compiled with USE_WIRINGPI flag
#GPIO_PIN = GPIO # This is the GPIO# not the pin#, so (17 = GPIO17 = Pin 11) or another example (5 = GPIO5 = Pin 29)
#WPI_PIN = use instead of GPIO_PIN if compiled with USE_WIRINGPI flag, This is WiringPi Pin#, not Raspberry Pi board pin#
#GPIO_PULL_UPDN = setup pull up pull down resistor PUD_OFF|PUD_DOWN|PUD_UP
#GPIO_ON_STATE = State GPIO reads when relay for zone is on. HIGH or LOW 1 or 0
#DOMOTICZ_IDX = Domoticz IDX 0 or remove entry if you don;t use Domoticz (only if you use domoticz)
#MASTER_VALVE = YES=1 NO=0 // turn on with any zone
# Don't use ZONE:0 for anything other than master valve, if you don't have a master valve simply delete it and start from ZONE:1
[ZONE]
@ -44,7 +43,7 @@ DZIDX_RAINSENSOR = 48
NAME=Master Valve
MASTER_VALVE=1
GPIO_PIN=2
WPI_PIN=0
#WPI_PIN=0
GPIO_PULL_UPDN=1
GPIO_ON_STATE=0
@ -53,7 +52,7 @@ NAME=Island
DEFAULT_RUNTIME=10
#GPIO_PIN=18
GPIO_PIN=3
WPI_PIN=1
#WPI_PIN=1
GPIO_PULL_UPDN=1
GPIO_ON_STATE=0
DOMOTICZ_IDX=2000
@ -61,9 +60,9 @@ DOMOTICZ_IDX=2000
[ZONE:2]
NAME=Driveway
DEFAULT_RUNTIME=10
#GPIO_PIN=27
GPIO_PIN=40
WPI_PIN=2
GPIO_PIN=27
#GPIO_PIN=40
#WPI_PIN=2
GPIO_PULL_UPDN=1
GPIO_ON_STATE=0
DOMOTICZ_IDX=2010
@ -72,20 +71,20 @@ DOMOTICZ_IDX=2010
NAME=Diningroom Flowerbeds
DEFAULT_RUNTIME=10
GPIO_PIN=5
WPI_PIN=3
#WPI_PIN=3
GPIO_PULL_UPDN=1
GPIO_ON_STATE=0
DOMOTICZ_IDX=2020
[INPUT]
[INPUT:1]
NAME=Test Switch
GPIO_PIN=6
WPI_PIN=3
GPIO_PULL_UPDN=1
GPIO_ON_STATE=0
COMMAND_ON=/usr/bin/curl -s -o /dev/null 'http://localhost?type=option&option=24hdelay&state=on'
COMMAND_OFF=/usr/bin/curl -s -o /dev/null 'http://localhost?type=option&option=24hdelay&state=off'
#[INPUT]
#[INPUT:1]
#NAME=Test Switch
#GPIO_PIN=6
#WPI_PIN=3
#GPIO_PULL_UPDN=1
#GPIO_ON_STATE=0
#COMMAND_ON=/usr/bin/curl -s -o /dev/null 'http://localhost?type=option&option=24hdelay&state=on'
#COMMAND_OFF=/usr/bin/curl -s -o /dev/null 'http://localhost?type=option&option=24hdelay&state=off'
#[ZONE:4]
#NAME=Diningroom error
@ -153,13 +152,13 @@ COMMAND_OFF=/usr/bin/curl -s -o /dev/null 'http://localhost?type=option&option=2
#COMMAND triggered_event_runcmd = external command to run
#DOMOTICZ_IDX Domoticz IDX
[GPIO]
[GPIO:1]
NAME=Rain Sensor
GPIO_PIN=4
WPI_PIN=7
PIN_MODE=0
#[GPIO]
#[GPIO:1]
#NAME=Rain Sensor
#GPIO_PIN=4
#WPI_PIN=7
#PIN_MODE=0
#PULL_UPDN=0
TRIGGER_EVENT_ON=3
COMMAND_HIGH=/usr/bin/curl -s -o /dev/null 'http://localhost?type=option&option=24hdelay&state=on'
COMMAND_LOW=/usr/bin/curl -s -o /dev/null 'http://localhost?type=option&option=24hdelay&state=off'
#TRIGGER_EVENT_ON=3
#COMMAND_HIGH=/usr/bin/curl -s -o /dev/null 'http://localhost?type=option&option=24hdelay&state=on'
#COMMAND_LOW=/usr/bin/curl -s -o /dev/null 'http://localhost?type=option&option=24hdelay&state=off'

View File

@ -14,7 +14,7 @@
// #include "sd_GPIO.h"
#endif
#include "sd_GPIO.h"
#include "GPIO_Pi.h"
#include "mongoose.h"
@ -252,6 +252,10 @@ void main_loop ()
logMessage(LOG_DEBUG, "Setting up GPIO\n");
gpioSetup();
if (! gpioSetup()) {
logMessage(LOG_ERR, "Failed to setup GPIO\n");
exit (EXIT_FAILURE);
}
for (i=(_sdconfig_.master_valve?0:1); i <= _sdconfig_.zones ; i++)
{

View File

@ -1,6 +1,6 @@
#ifndef SD_VERSION_H
#define SD_VERSION_H
#define SD_VERSION "1.0g"
#define SD_VERSION "1.1"
#endif

View File

@ -1,7 +1,7 @@
#ifdef USE_WIRINGPI
#include <wiringPi.h>
#else
#include "sd_GPIO.h"
#include "GPIO_Pi.h"
#endif
#include "zone_ctrl.h"
@ -218,6 +218,7 @@ bool zc_zone(zcRunType type, int zone, zcState state, int length) {
}
bool zc_start(/*zcRunType type,*/ int zone) {
int rtn = false;
// Check if zone is already on
if ( _sdconfig_.zonecfg[zone].on_state == digitalRead (_sdconfig_.zonecfg[zone].pin)) {
logMessage (LOG_DEBUG, "Request to turn zone %d on. Zone %d is already on, ignoring!\n",zone,zone);
@ -225,20 +226,28 @@ bool zc_start(/*zcRunType type,*/ int zone) {
}
logMessage (LOG_NOTICE, "Turning on Zone %d\n",zone);
#ifndef USE_WIRINGPI
int rtn = digitalWrite(_sdconfig_.zonecfg[zone].pin, _sdconfig_.zonecfg[zone].on_state );
//int rtn = digitalWrite(_sdconfig_.zonecfg[zone].pin, _sdconfig_.zonecfg[zone].on_state );
//logMessage (LOG_NOTICE, "digitalWrite return %d\n",rtn);
if (digitalWrite(_sdconfig_.zonecfg[zone].pin, _sdconfig_.zonecfg[zone].on_state ) == GPIO_OK )
rtn = true;
else
rtn = false;
#else
digitalWrite(_sdconfig_.zonecfg[zone].pin, _sdconfig_.zonecfg[zone].on_state );
int rtn = true;
#endif
_sdconfig_.eventToUpdateHappened = true;
return rtn;
// store what's running
if (rtn == true)
return true;
else
return false;
//if (rtn == true)
// return true;
//else
// return false;
}
bool zc_stop(/*zcRunType type,*/ int zone) {
int rtn = false;
// Check if zone is alreay off
if ( _sdconfig_.zonecfg[zone].on_state != digitalRead (_sdconfig_.zonecfg[zone].pin)) {
logMessage (LOG_DEBUG, "Request to turn zone %d off. Zone %d is already off, ignoring!\n",zone,zone);
@ -246,15 +255,22 @@ bool zc_stop(/*zcRunType type,*/ int zone) {
}
logMessage (LOG_NOTICE, "Turning off Zone %d\n",zone);
#ifndef USE_WIRINGPI
int rtn = digitalWrite(_sdconfig_.zonecfg[zone].pin, !_sdconfig_.zonecfg[zone].on_state );
//int rtn = digitalWrite(_sdconfig_.zonecfg[zone].pin, !_sdconfig_.zonecfg[zone].on_state );
if (digitalWrite(_sdconfig_.zonecfg[zone].pin, !_sdconfig_.zonecfg[zone].on_state ) == GPIO_OK )
rtn = true;
else
rtn = false;
#else
digitalWrite(_sdconfig_.zonecfg[zone].pin, !_sdconfig_.zonecfg[zone].on_state );
int rtn = true;
#endif
_sdconfig_.eventToUpdateHappened = true;
return rtn;
/*
if (rtn == true)
return true;
else
return false;
*/
}