initial commit
This commit is contained in:
BIN
dtoverlay/mcp23017_0x20_zeroplc.dtbo
Normal file
BIN
dtoverlay/mcp23017_0x20_zeroplc.dtbo
Normal file
Binary file not shown.
156
dtoverlay/mcp23017_0x20_zeroplc.dts
Normal file
156
dtoverlay/mcp23017_0x20_zeroplc.dts
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
/dts-v1/;
|
||||||
|
|
||||||
|
/ {
|
||||||
|
compatible = "brcm,bcm2835";
|
||||||
|
|
||||||
|
fragment@100 {
|
||||||
|
target = <0xffffffff>;
|
||||||
|
phandle = <0x01>;
|
||||||
|
|
||||||
|
__overlay__ {
|
||||||
|
status = "okay";
|
||||||
|
phandle = <0x05>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@101 {
|
||||||
|
target = <0xffffffff>;
|
||||||
|
|
||||||
|
__dormant__ {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@102 {
|
||||||
|
target = <0xffffffff>;
|
||||||
|
|
||||||
|
__dormant__ {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
__overrides__ {
|
||||||
|
i2c0 = [00 00 00 01 74 61 72 67 65 74 3a 30 3d 00 ff ff ff ff 00 00 00 01 74 61 72 67 65 74 2d 70 61 74 68 3f 3d 30 00 00 00 00 00 2b 31 30 31 2b 31 30 32 00];
|
||||||
|
i2c_csi_dsi = [00 00 00 01 74 61 72 67 65 74 3a 30 3d 00 ff ff ff ff 00 00 00 01 74 61 72 67 65 74 2d 70 61 74 68 3f 3d 30 00 00 00 00 00 2b 31 30 31 2b 31 30 32 00];
|
||||||
|
i2c_csi_dsi0 = [00 00 00 01 74 61 72 67 65 74 3a 30 3d 00 ff ff ff ff 00 00 00 01 74 61 72 67 65 74 2d 70 61 74 68 3f 3d 30 00 00 00 00 00 2b 31 30 31 2b 31 30 32 00];
|
||||||
|
i2c1 = [00 00 00 01 74 61 72 67 65 74 3a 30 3d 00 ff ff ff ff 00 00 00 01 74 61 72 67 65 74 2d 70 61 74 68 3f 3d 30 00 00 00 00 00 2d 31 30 31 2d 31 30 32 00];
|
||||||
|
i2c2 = <0x01 0x74617267 0x65743f3d 0x30000000 0x17461 0x72676574 0x2d706174 0x683d6932 0x63320000 0x2d 0x3130312d 0x31303200>;
|
||||||
|
i2c3 = <0x01 0x74617267 0x65743f3d 0x30000000 0x17461 0x72676574 0x2d706174 0x683d6932 0x63330000 0x2d 0x3130312d 0x31303200>;
|
||||||
|
i2c4 = <0x01 0x74617267 0x65743f3d 0x30000000 0x17461 0x72676574 0x2d706174 0x683d6932 0x63340000 0x2d 0x3130312d 0x31303200>;
|
||||||
|
i2c5 = <0x01 0x74617267 0x65743f3d 0x30000000 0x17461 0x72676574 0x2d706174 0x683d6932 0x63350000 0x2d 0x3130312d 0x31303200>;
|
||||||
|
i2c6 = <0x01 0x74617267 0x65743f3d 0x30000000 0x17461 0x72676574 0x2d706174 0x683d6932 0x63360000 0x2d 0x3130312d 0x31303200>;
|
||||||
|
i2c-path = [00 00 00 01 74 61 72 67 65 74 3f 3d 30 00 00 00 00 01 74 61 72 67 65 74 2d 70 61 74 68 00 00 00 00 00 2d 31 30 31 2d 31 30 32 00];
|
||||||
|
gpiopin = [00 00 00 02 62 72 63 6d 2c 70 69 6e 73 3a 30 00 00 00 00 03 69 6e 74 65 72 72 75 70 74 73 3a 30 00];
|
||||||
|
addr = <0x04 0x7265673a 0x30000000 0x27265 0x673a3000>;
|
||||||
|
mcp23008 = [00 00 00 00 3d 32 00];
|
||||||
|
noints = [00 00 00 00 21 31 21 33 00];
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@1 {
|
||||||
|
target = <0xffffffff>;
|
||||||
|
|
||||||
|
__overlay__ {
|
||||||
|
|
||||||
|
mcp23017_pins@20 {
|
||||||
|
brcm,pins = <0x04>;
|
||||||
|
brcm,function = <0x00>;
|
||||||
|
phandle = <0x02>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@2 {
|
||||||
|
target = <0x04>;
|
||||||
|
|
||||||
|
__dormant__ {
|
||||||
|
compatible = "microchip,mcp23008";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@3 {
|
||||||
|
target = <0x04>;
|
||||||
|
|
||||||
|
__overlay__ {
|
||||||
|
#interrupt-cells = <0x02>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <0x02>;
|
||||||
|
interrupt-parent = <0xffffffff>;
|
||||||
|
interrupts = <0x04 0x02>;
|
||||||
|
interrupt-controller;
|
||||||
|
microchip,irq-mirror;
|
||||||
|
phandle = <0x03>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@4 {
|
||||||
|
target = <0x05>;
|
||||||
|
|
||||||
|
__overlay__ {
|
||||||
|
#address-cells = <0x01>;
|
||||||
|
#size-cells = <0x00>;
|
||||||
|
|
||||||
|
mcp@20 {
|
||||||
|
compatible = "microchip,mcp23017";
|
||||||
|
reg = <0x20>;
|
||||||
|
gpio-line-names = "AIN1_SWITCH_I/V","AIN2_SWITCH_I/V","AIN3_SWITCH_I/V","AIN4_SWITCH_I/V","AIN5_SWITCH_I/V","AIN6_SWITCH_I/V","AIN7_SWITCH_I/V","AIN8_SWITCH_I/V","NC","IN7","IN8","DIS_24VOUT_POE","5V_EXT_FAULT","5V_EXT_EN","RS485_120R","DIS_24VOUTPUTS";
|
||||||
|
gpio-controller;
|
||||||
|
#gpio-cells = <0x02>;
|
||||||
|
status = "okay";
|
||||||
|
phandle = <0x04>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
__symbols__ {
|
||||||
|
busfrag = "/fragment@100";
|
||||||
|
i2cbus = "/fragment@100/__overlay__";
|
||||||
|
mcp23017_pins = "/fragment@1/__overlay__/mcp23017_pins@20";
|
||||||
|
mcp23017_irq = "/fragment@3/__overlay__";
|
||||||
|
mcp23017 = "/fragment@4/__overlay__/mcp@20";
|
||||||
|
};
|
||||||
|
|
||||||
|
__fixups__ {
|
||||||
|
i2c_arm = "/fragment@100:target:0";
|
||||||
|
i2c0if = "/fragment@101:target:0";
|
||||||
|
i2c0mux = "/fragment@102:target:0";
|
||||||
|
i2c0 = "/__overrides__:i2c0:14";
|
||||||
|
i2c_csi_dsi = "/__overrides__:i2c_csi_dsi:14";
|
||||||
|
i2c_csi_dsi0 = "/__overrides__:i2c_csi_dsi0:14";
|
||||||
|
i2c1 = "/__overrides__:i2c1:14";
|
||||||
|
gpio = "/fragment@1:target:0\0/fragment@3/__overlay__:interrupt-parent:0";
|
||||||
|
};
|
||||||
|
|
||||||
|
__local_fixups__ {
|
||||||
|
|
||||||
|
__overrides__ {
|
||||||
|
i2c0 = <0x00 0x12>;
|
||||||
|
i2c_csi_dsi = <0x00 0x12>;
|
||||||
|
i2c_csi_dsi0 = <0x00 0x12>;
|
||||||
|
i2c1 = <0x00 0x12>;
|
||||||
|
i2c2 = <0x00 0x0e>;
|
||||||
|
i2c3 = <0x00 0x0e>;
|
||||||
|
i2c4 = <0x00 0x0e>;
|
||||||
|
i2c5 = <0x00 0x0e>;
|
||||||
|
i2c6 = <0x00 0x0e>;
|
||||||
|
i2c-path = <0x00 0x0e>;
|
||||||
|
gpiopin = <0x00 0x10>;
|
||||||
|
addr = <0x00 0x0a>;
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@2 {
|
||||||
|
target = <0x00>;
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@3 {
|
||||||
|
target = <0x00>;
|
||||||
|
|
||||||
|
__overlay__ {
|
||||||
|
pinctrl-0 = <0x00>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@4 {
|
||||||
|
target = <0x00>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
BIN
dtoverlay/mcp23017_0x21_zeroplc.dtbo
Normal file
BIN
dtoverlay/mcp23017_0x21_zeroplc.dtbo
Normal file
Binary file not shown.
156
dtoverlay/mcp23017_0x21_zeroplc.dts
Normal file
156
dtoverlay/mcp23017_0x21_zeroplc.dts
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
/dts-v1/;
|
||||||
|
|
||||||
|
/ {
|
||||||
|
compatible = "brcm,bcm2835";
|
||||||
|
|
||||||
|
fragment@100 {
|
||||||
|
target = <0xffffffff>;
|
||||||
|
phandle = <0x01>;
|
||||||
|
|
||||||
|
__overlay__ {
|
||||||
|
status = "okay";
|
||||||
|
phandle = <0x05>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@101 {
|
||||||
|
target = <0xffffffff>;
|
||||||
|
|
||||||
|
__dormant__ {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@102 {
|
||||||
|
target = <0xffffffff>;
|
||||||
|
|
||||||
|
__dormant__ {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
__overrides__ {
|
||||||
|
i2c0 = [00 00 00 01 74 61 72 67 65 74 3a 30 3d 00 ff ff ff ff 00 00 00 01 74 61 72 67 65 74 2d 70 61 74 68 3f 3d 30 00 00 00 00 00 2b 31 30 31 2b 31 30 32 00];
|
||||||
|
i2c_csi_dsi = [00 00 00 01 74 61 72 67 65 74 3a 30 3d 00 ff ff ff ff 00 00 00 01 74 61 72 67 65 74 2d 70 61 74 68 3f 3d 30 00 00 00 00 00 2b 31 30 31 2b 31 30 32 00];
|
||||||
|
i2c_csi_dsi0 = [00 00 00 01 74 61 72 67 65 74 3a 30 3d 00 ff ff ff ff 00 00 00 01 74 61 72 67 65 74 2d 70 61 74 68 3f 3d 30 00 00 00 00 00 2b 31 30 31 2b 31 30 32 00];
|
||||||
|
i2c1 = [00 00 00 01 74 61 72 67 65 74 3a 30 3d 00 ff ff ff ff 00 00 00 01 74 61 72 67 65 74 2d 70 61 74 68 3f 3d 30 00 00 00 00 00 2d 31 30 31 2d 31 30 32 00];
|
||||||
|
i2c2 = <0x01 0x74617267 0x65743f3d 0x30000000 0x17461 0x72676574 0x2d706174 0x683d6932 0x63320000 0x2d 0x3130312d 0x31303200>;
|
||||||
|
i2c3 = <0x01 0x74617267 0x65743f3d 0x30000000 0x17461 0x72676574 0x2d706174 0x683d6932 0x63330000 0x2d 0x3130312d 0x31303200>;
|
||||||
|
i2c4 = <0x01 0x74617267 0x65743f3d 0x30000000 0x17461 0x72676574 0x2d706174 0x683d6932 0x63340000 0x2d 0x3130312d 0x31303200>;
|
||||||
|
i2c5 = <0x01 0x74617267 0x65743f3d 0x30000000 0x17461 0x72676574 0x2d706174 0x683d6932 0x63350000 0x2d 0x3130312d 0x31303200>;
|
||||||
|
i2c6 = <0x01 0x74617267 0x65743f3d 0x30000000 0x17461 0x72676574 0x2d706174 0x683d6932 0x63360000 0x2d 0x3130312d 0x31303200>;
|
||||||
|
i2c-path = [00 00 00 01 74 61 72 67 65 74 3f 3d 30 00 00 00 00 01 74 61 72 67 65 74 2d 70 61 74 68 00 00 00 00 00 2d 31 30 31 2d 31 30 32 00];
|
||||||
|
gpiopin = [00 00 00 02 62 72 63 6d 2c 70 69 6e 73 3a 30 00 00 00 00 03 69 6e 74 65 72 72 75 70 74 73 3a 30 00];
|
||||||
|
addr = <0x04 0x7265673a 0x30000000 0x27265 0x673a3000>;
|
||||||
|
mcp23008 = [00 00 00 00 3d 32 00];
|
||||||
|
noints = [00 00 00 00 21 31 21 33 00];
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@1 {
|
||||||
|
target = <0xffffffff>;
|
||||||
|
|
||||||
|
__overlay__ {
|
||||||
|
|
||||||
|
mcp23017_pins@20 {
|
||||||
|
brcm,pins = <0x04>;
|
||||||
|
brcm,function = <0x00>;
|
||||||
|
phandle = <0x02>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@2 {
|
||||||
|
target = <0x04>;
|
||||||
|
|
||||||
|
__dormant__ {
|
||||||
|
compatible = "microchip,mcp23008";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@3 {
|
||||||
|
target = <0x04>;
|
||||||
|
|
||||||
|
__overlay__ {
|
||||||
|
#interrupt-cells = <0x02>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <0x02>;
|
||||||
|
interrupt-parent = <0xffffffff>;
|
||||||
|
interrupts = <0x04 0x02>;
|
||||||
|
interrupt-controller;
|
||||||
|
microchip,irq-mirror;
|
||||||
|
phandle = <0x03>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@4 {
|
||||||
|
target = <0x05>;
|
||||||
|
|
||||||
|
__overlay__ {
|
||||||
|
#address-cells = <0x01>;
|
||||||
|
#size-cells = <0x00>;
|
||||||
|
|
||||||
|
mcp@20 {
|
||||||
|
compatible = "microchip,mcp23017";
|
||||||
|
reg = <0x21>;
|
||||||
|
gpio-line-names = "IN_FAULT","BUS_IO1","BUS_IO2","TFT_BACKLIGHT","NC","NC","NC","NC","NC","NC","NC","NC","OUT_DIAG","TFT_RST","TFT_RS","TOUCHT_RST";
|
||||||
|
gpio-controller;
|
||||||
|
#gpio-cells = <0x02>;
|
||||||
|
status = "okay";
|
||||||
|
phandle = <0x04>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
__symbols__ {
|
||||||
|
busfrag = "/fragment@100";
|
||||||
|
i2cbus = "/fragment@100/__overlay__";
|
||||||
|
mcp23017_pins = "/fragment@1/__overlay__/mcp23017_pins@20";
|
||||||
|
mcp23017_irq = "/fragment@3/__overlay__";
|
||||||
|
mcp23017 = "/fragment@4/__overlay__/mcp@20";
|
||||||
|
};
|
||||||
|
|
||||||
|
__fixups__ {
|
||||||
|
i2c_arm = "/fragment@100:target:0";
|
||||||
|
i2c0if = "/fragment@101:target:0";
|
||||||
|
i2c0mux = "/fragment@102:target:0";
|
||||||
|
i2c0 = "/__overrides__:i2c0:14";
|
||||||
|
i2c_csi_dsi = "/__overrides__:i2c_csi_dsi:14";
|
||||||
|
i2c_csi_dsi0 = "/__overrides__:i2c_csi_dsi0:14";
|
||||||
|
i2c1 = "/__overrides__:i2c1:14";
|
||||||
|
gpio = "/fragment@1:target:0\0/fragment@3/__overlay__:interrupt-parent:0";
|
||||||
|
};
|
||||||
|
|
||||||
|
__local_fixups__ {
|
||||||
|
|
||||||
|
__overrides__ {
|
||||||
|
i2c0 = <0x00 0x12>;
|
||||||
|
i2c_csi_dsi = <0x00 0x12>;
|
||||||
|
i2c_csi_dsi0 = <0x00 0x12>;
|
||||||
|
i2c1 = <0x00 0x12>;
|
||||||
|
i2c2 = <0x00 0x0e>;
|
||||||
|
i2c3 = <0x00 0x0e>;
|
||||||
|
i2c4 = <0x00 0x0e>;
|
||||||
|
i2c5 = <0x00 0x0e>;
|
||||||
|
i2c6 = <0x00 0x0e>;
|
||||||
|
i2c-path = <0x00 0x0e>;
|
||||||
|
gpiopin = <0x00 0x10>;
|
||||||
|
addr = <0x00 0x0a>;
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@2 {
|
||||||
|
target = <0x00>;
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@3 {
|
||||||
|
target = <0x00>;
|
||||||
|
|
||||||
|
__overlay__ {
|
||||||
|
pinctrl-0 = <0x00>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment@4 {
|
||||||
|
target = <0x00>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
139
install.sh
Normal file
139
install.sh
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
#/bin/bash
|
||||||
|
|
||||||
|
#test for root privilege
|
||||||
|
if [ $(id -u) -ne 0 ]
|
||||||
|
then echo "Please run this script using sudo!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "#################################################################"
|
||||||
|
echo "#### Welcome! ####"
|
||||||
|
echo "#### zeroPLC Installer v1.0 ####"
|
||||||
|
echo "#################################################################"
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
echo "#################################################################"
|
||||||
|
echo "#### Downloading files ####"
|
||||||
|
echo "#################################################################"
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
cd /home/$SUDO_USER
|
||||||
|
wget https://git.sqegmbh.de/zeroPLC/zeroPLC-installer/archive/master.zip
|
||||||
|
#check wget exit code
|
||||||
|
if [ $? -ne 0 ]
|
||||||
|
then echo "Error downloading files, exiting"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
unzip -q master.zip
|
||||||
|
cd zeroplc-installer
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo "#################################################################"
|
||||||
|
echo "#### Activating device tree overlays ####"
|
||||||
|
echo "#################################################################"
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
echo "Copying overlay files"
|
||||||
|
cp ./dtoverlay/mcp23017_0x20_zeroplc.dtbo /boot/overlays/
|
||||||
|
cp ./dtoverlay/mcp23017_0x21_zeroplc.dtbo /boot/overlays/
|
||||||
|
|
||||||
|
echo "Activating overlays in /boot/firmware/config.txt"
|
||||||
|
cat <<EOF >> /boot/firmware/config.txt
|
||||||
|
dtparam=i2c_arm=on
|
||||||
|
dtoverlay=i2c-gpio,bus=3,i2c_gpio_sda=23,i2c_gpio_scl=24
|
||||||
|
|
||||||
|
dtoverlay=w1-gpio
|
||||||
|
|
||||||
|
enable_uart=1
|
||||||
|
|
||||||
|
dtparam=spi=on
|
||||||
|
dtoverlay=spi0-0cs
|
||||||
|
|
||||||
|
dtoverlay=mcp23017_0x20_zeroplc,noints=1
|
||||||
|
dtoverlay=mcp23017_0x21_zeroplc,addr=0x21,noints=1
|
||||||
|
|
||||||
|
dtoverlay=i2c-rtc,pcf8523
|
||||||
|
|
||||||
|
dtoverlay=ads1015,addr=0x4b
|
||||||
|
dtparam=cha_enable=true,cha_cfg=4,cha_gain=0
|
||||||
|
dtparam=chb_enable=true,chb_cfg=5,chb_gain=0
|
||||||
|
dtparam=chc_enable=true,chc_cfg=6,chc_gain=0
|
||||||
|
dtparam=chd_enable=true,chd_cfg=7,chd_gain=0
|
||||||
|
|
||||||
|
dtoverlay=ads1015,addr=0x49
|
||||||
|
dtparam=cha_enable=true,cha_cfg=4,cha_gain=0
|
||||||
|
dtparam=chb_enable=true,chb_cfg=5,chb_gain=0
|
||||||
|
dtparam=chc_enable=true,chc_cfg=6,chc_gain=0
|
||||||
|
dtparam=chd_enable=true,chd_cfg=7,chd_gain=0
|
||||||
|
EOF
|
||||||
|
|
||||||
|
#load i2c-dev module, done by raspi-config when enabling i2c there
|
||||||
|
echo i2c-dev >> /etc/modules
|
||||||
|
#disable console on serial (will change /boot/firmware/cmdline.txt)
|
||||||
|
echo "Disabling console on serial"
|
||||||
|
raspi-config nonint do_serial_cons 1
|
||||||
|
|
||||||
|
echo "Done!"
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo "#################################################################"
|
||||||
|
echo "#### Activating RTC ####"
|
||||||
|
echo "#################################################################"
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
apt -y remove fake-hwclock
|
||||||
|
update-rc.d -f fake-hwclock remove
|
||||||
|
systemctl disable fake-hwclock
|
||||||
|
|
||||||
|
#GUI
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo "#################################################################"
|
||||||
|
echo "#### zeroPLC testing gui ####"
|
||||||
|
echo "#################################################################"
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read -p "Do you want to intall the zeroPLCgui for simple testing of hardware functions? (yes/no) " yn
|
||||||
|
case $yn in
|
||||||
|
yes ) echo Starting zeroPLCgui installation to zeroPLCgui folder in home directory;
|
||||||
|
break;;
|
||||||
|
no ) cd ..;
|
||||||
|
rm -r /home/$SUDO_USER/zeroplc-installer;
|
||||||
|
echo Exiting installer, please reboot the system;
|
||||||
|
exit;;
|
||||||
|
* ) echo invalid response;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
apt update
|
||||||
|
apt -y install python3-pip python3-picamera2
|
||||||
|
|
||||||
|
mv /home/$SUDO_USER/zeroplc-installer/zeroPLCgui /home/$SUDO_USER/
|
||||||
|
cd /home/$SUDO_USER/zeroPLCgui
|
||||||
|
|
||||||
|
chmod +x gui.py
|
||||||
|
|
||||||
|
echo "Creating python venv"
|
||||||
|
sleep 1
|
||||||
|
python3 -m venv --system-site-packages .venv
|
||||||
|
. /home/$SUDO_USER/zeroPLCgui/.venv/bin/activate
|
||||||
|
|
||||||
|
echo "Installing python packages"
|
||||||
|
sleep 1
|
||||||
|
pip3 install nicegui adafruit-circuitpython-tmp117 adafruit-circuitpython-sht4x adafruit-extended-bus
|
||||||
|
deactivate
|
||||||
|
|
||||||
|
chown -R $SUDO_USER:$SUDO_USER /home/$SUDO_USER/zeroPLCgui
|
||||||
|
rm -r /home/$SUDO_USER/zeroplc-installer
|
||||||
|
echo
|
||||||
|
echo "Installation finished, start gui with ./gui.py"
|
||||||
|
sleep 1
|
||||||
|
echo "Exiting installer"
|
||||||
388
zeroPLCgui/gui.py
Normal file
388
zeroPLCgui/gui.py
Normal file
@@ -0,0 +1,388 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
'''exec' "$HOME/zeroPLCgui/.venv/bin/python3" "$0" "$@"
|
||||||
|
' '''
|
||||||
|
|
||||||
|
from nicegui import ui,app
|
||||||
|
import os,sys
|
||||||
|
import gpiod
|
||||||
|
import atexit
|
||||||
|
import board
|
||||||
|
import adafruit_tmp117
|
||||||
|
import adafruit_sht4x
|
||||||
|
from adafruit_extended_bus import ExtendedI2C as I2C
|
||||||
|
|
||||||
|
from picamera2 import Picamera2
|
||||||
|
from fastapi.responses import StreamingResponse
|
||||||
|
import io
|
||||||
|
from PIL import Image
|
||||||
|
import time
|
||||||
|
|
||||||
|
picam2 = None
|
||||||
|
camera_connected = 0
|
||||||
|
|
||||||
|
def init_camera():
|
||||||
|
global picam2
|
||||||
|
picam2 = Picamera2()
|
||||||
|
picam2.configure(picam2.create_preview_configuration(main={"format": 'XRGB8888', "size": (640, 480)}))
|
||||||
|
picam2.start()
|
||||||
|
|
||||||
|
|
||||||
|
def generate_mjpeg():
|
||||||
|
while True:
|
||||||
|
img = picam2.capture_array()
|
||||||
|
pil_img = Image.fromarray(img)
|
||||||
|
if pil_img.mode == 'RGBA':
|
||||||
|
pil_img = pil_img.convert('RGB')
|
||||||
|
buf = io.BytesIO()
|
||||||
|
pil_img.save(buf, format='JPEG')
|
||||||
|
frame = buf.getvalue()
|
||||||
|
|
||||||
|
yield (
|
||||||
|
b'--frame\r\n'
|
||||||
|
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n'
|
||||||
|
)
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
@app.get('/video_feed')
|
||||||
|
def video_feed():
|
||||||
|
return StreamingResponse(generate_mjpeg(), media_type='multipart/x-mixed-replace; boundary=frame')
|
||||||
|
|
||||||
|
i2c = board.I2C() # uses board.SCL and board.SDA
|
||||||
|
tmp117 = adafruit_tmp117.TMP117(i2c)
|
||||||
|
|
||||||
|
i2c3=I2C(3)
|
||||||
|
try:
|
||||||
|
sht = adafruit_sht4x.SHT4x(i2c3,0x46)
|
||||||
|
except:
|
||||||
|
sht = 0
|
||||||
|
|
||||||
|
# Do not request the line upfront; request and release on demand
|
||||||
|
chip = gpiod.Chip('gpiochip0')
|
||||||
|
chip2 = gpiod.Chip('gpiochip2')
|
||||||
|
output1 = chip.get_line(12)
|
||||||
|
output2 = chip.get_line(13)
|
||||||
|
output3 = chip.get_line(18)
|
||||||
|
output4 = chip.get_line(19)
|
||||||
|
output5 = chip.get_line(20)
|
||||||
|
output6 = chip.get_line(21)
|
||||||
|
output7 = chip.get_line(22)
|
||||||
|
output8 = chip.get_line(26)
|
||||||
|
input1 = chip.get_line(5)
|
||||||
|
input2 = chip.get_line(6)
|
||||||
|
input3 = chip.get_line(7)
|
||||||
|
input4 = chip.get_line(8)
|
||||||
|
input5 = chip.get_line(27)
|
||||||
|
input6 = chip.get_line(25)
|
||||||
|
input7 = chip2.get_line(9)
|
||||||
|
input8 = chip2.get_line(10)
|
||||||
|
|
||||||
|
def set_output1():
|
||||||
|
try:
|
||||||
|
output1.request(consumer='nicegui', type=gpiod.LINE_REQ_DIR_OUT)
|
||||||
|
output1.set_value(switch_1.value)
|
||||||
|
output1.release()
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Output1 error: {e}")
|
||||||
|
|
||||||
|
def set_output2():
|
||||||
|
try:
|
||||||
|
output2.request(consumer='nicegui', type=gpiod.LINE_REQ_DIR_OUT)
|
||||||
|
output2.set_value(switch_2.value)
|
||||||
|
output2.release()
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Output2 error: {e}")
|
||||||
|
|
||||||
|
def set_output3():
|
||||||
|
try:
|
||||||
|
output3.request(consumer='nicegui', type=gpiod.LINE_REQ_DIR_OUT)
|
||||||
|
output3.set_value(switch_3.value)
|
||||||
|
output3.release()
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Output3 error: {e}")
|
||||||
|
|
||||||
|
def set_output4():
|
||||||
|
try:
|
||||||
|
output4.request(consumer='nicegui', type=gpiod.LINE_REQ_DIR_OUT)
|
||||||
|
output4.set_value(switch_4.value)
|
||||||
|
output4.release()
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Output4 error: {e}")
|
||||||
|
|
||||||
|
def set_output5():
|
||||||
|
try:
|
||||||
|
output5.request(consumer='nicegui', type=gpiod.LINE_REQ_DIR_OUT)
|
||||||
|
output5.set_value(switch_5.value)
|
||||||
|
output5.release()
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Output5 error: {e}")
|
||||||
|
|
||||||
|
def set_output6():
|
||||||
|
try:
|
||||||
|
output6.request(consumer='nicegui', type=gpiod.LINE_REQ_DIR_OUT)
|
||||||
|
output6.set_value(switch_6.value)
|
||||||
|
output6.release()
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Output6 error: {e}")
|
||||||
|
|
||||||
|
def set_output7():
|
||||||
|
try:
|
||||||
|
output7.request(consumer='nicegui', type=gpiod.LINE_REQ_DIR_OUT)
|
||||||
|
output7.set_value(switch_7.value)
|
||||||
|
output7.release()
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Output7 error: {e}")
|
||||||
|
|
||||||
|
def set_output8():
|
||||||
|
try:
|
||||||
|
output8.request(consumer='nicegui', type=gpiod.LINE_REQ_DIR_OUT)
|
||||||
|
output8.set_value(switch_8.value)
|
||||||
|
output8.release()
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Output8 error: {e}")
|
||||||
|
|
||||||
|
def get_input1():
|
||||||
|
try:
|
||||||
|
input1.request(consumer='nicegui', type=gpiod.LINE_REQ_DIR_IN)
|
||||||
|
if input1.get_value():
|
||||||
|
input1_indicator.classes('text-green', remove='text-red')
|
||||||
|
else:
|
||||||
|
input1_indicator.classes('text-red', remove='text-green')
|
||||||
|
input1.release()
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Input1 error: {e}")
|
||||||
|
|
||||||
|
def get_input2():
|
||||||
|
try:
|
||||||
|
input2.request(consumer='nicegui', type=gpiod.LINE_REQ_DIR_IN)
|
||||||
|
if input2.get_value():
|
||||||
|
input2_indicator.classes('text-green', remove='text-red')
|
||||||
|
else:
|
||||||
|
input2_indicator.classes('text-red', remove='text-green')
|
||||||
|
input2.release()
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Input2 error: {e}")
|
||||||
|
|
||||||
|
def get_input3():
|
||||||
|
try:
|
||||||
|
input3.request(consumer='nicegui', type=gpiod.LINE_REQ_DIR_IN)
|
||||||
|
if input3.get_value():
|
||||||
|
input3_indicator.classes('text-green', remove='text-red')
|
||||||
|
else:
|
||||||
|
input3_indicator.classes('text-red', remove='text-green')
|
||||||
|
input3.release()
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Input3 error: {e}")
|
||||||
|
|
||||||
|
def get_input4():
|
||||||
|
try:
|
||||||
|
input4.request(consumer='nicegui', type=gpiod.LINE_REQ_DIR_IN)
|
||||||
|
if input4.get_value():
|
||||||
|
input4_indicator.classes('text-green', remove='text-red')
|
||||||
|
else:
|
||||||
|
input4_indicator.classes('text-red', remove='text-green')
|
||||||
|
input4.release()
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Input4 error: {e}")
|
||||||
|
|
||||||
|
def get_input5():
|
||||||
|
try:
|
||||||
|
input5.request(consumer='nicegui', type=gpiod.LINE_REQ_DIR_IN)
|
||||||
|
if input5.get_value():
|
||||||
|
input5_indicator.classes('text-green', remove='text-red')
|
||||||
|
else:
|
||||||
|
input5_indicator.classes('text-red', remove='text-green')
|
||||||
|
input5.release()
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Input5 error: {e}")
|
||||||
|
|
||||||
|
def get_input6():
|
||||||
|
try:
|
||||||
|
input6.request(consumer='nicegui', type=gpiod.LINE_REQ_DIR_IN)
|
||||||
|
if input6.get_value():
|
||||||
|
input6_indicator.classes('text-green', remove='text-red')
|
||||||
|
else:
|
||||||
|
input6_indicator.classes('text-red', remove='text-green')
|
||||||
|
input6.release()
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Input6 error: {e}")
|
||||||
|
|
||||||
|
def get_input7():
|
||||||
|
try:
|
||||||
|
input7.request(consumer='nicegui', type=gpiod.LINE_REQ_DIR_IN)
|
||||||
|
if input7.get_value():
|
||||||
|
input7_indicator.classes('text-green', remove='text-red')
|
||||||
|
else:
|
||||||
|
input7_indicator.classes('text-red', remove='text-green')
|
||||||
|
input7.release()
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Input7 error: {e}")
|
||||||
|
|
||||||
|
def get_input8():
|
||||||
|
try:
|
||||||
|
input8.request(consumer='nicegui', type=gpiod.LINE_REQ_DIR_IN)
|
||||||
|
if input8.get_value():
|
||||||
|
input8_indicator.classes('text-green', remove='text-red')
|
||||||
|
else:
|
||||||
|
input8_indicator.classes('text-red', remove='text-green')
|
||||||
|
input8.release()
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Input8 error: {e}")
|
||||||
|
|
||||||
|
atexit.register(lambda: output1.release())
|
||||||
|
atexit.register(lambda: output2.release())
|
||||||
|
atexit.register(lambda: output3.release())
|
||||||
|
atexit.register(lambda: output4.release())
|
||||||
|
atexit.register(lambda: output5.release())
|
||||||
|
atexit.register(lambda: output6.release())
|
||||||
|
atexit.register(lambda: output7.release())
|
||||||
|
atexit.register(lambda: output8.release())
|
||||||
|
atexit.register(lambda: input1.release())
|
||||||
|
atexit.register(lambda: input2.release())
|
||||||
|
atexit.register(lambda: input3.release())
|
||||||
|
atexit.register(lambda: input4.release())
|
||||||
|
atexit.register(lambda: input5.release())
|
||||||
|
atexit.register(lambda: input6.release())
|
||||||
|
atexit.register(lambda: input7.release())
|
||||||
|
atexit.register(lambda: input8.release())
|
||||||
|
|
||||||
|
ui.markdown('#zeroPLC')
|
||||||
|
ui.markdown('##24V Outputs')
|
||||||
|
with ui.row():
|
||||||
|
switch_1 = ui.switch('Output 1', on_change=set_output1)
|
||||||
|
switch_2 = ui.switch('Output 2', on_change=set_output2)
|
||||||
|
switch_3 = ui.switch('Output 3', on_change=set_output3)
|
||||||
|
switch_4 = ui.switch('Output 4', on_change=set_output4)
|
||||||
|
switch_5 = ui.switch('Output 5', on_change=set_output5)
|
||||||
|
switch_6 = ui.switch('Output 6', on_change=set_output6)
|
||||||
|
switch_7 = ui.switch('Output 7', on_change=set_output7)
|
||||||
|
switch_8 = ui.switch('Output 8', on_change=set_output8)
|
||||||
|
|
||||||
|
ui.markdown('##24V Digital Inputs')
|
||||||
|
with ui.row():
|
||||||
|
input1_indicator = ui.icon('fiber_manual_record', size='2em').classes('drop-shadow text-red')
|
||||||
|
ui.label('Input 1')
|
||||||
|
input2_indicator = ui.icon('fiber_manual_record', size='2em').classes('drop-shadow text-red')
|
||||||
|
ui.label('Input 2')
|
||||||
|
input3_indicator = ui.icon('fiber_manual_record', size='2em').classes('drop-shadow text-red')
|
||||||
|
ui.label('Input 3')
|
||||||
|
input4_indicator = ui.icon('fiber_manual_record', size='2em').classes('drop-shadow text-red')
|
||||||
|
ui.label('Input 4')
|
||||||
|
input5_indicator = ui.icon('fiber_manual_record', size='2em').classes('drop-shadow text-red')
|
||||||
|
ui.label('Input 5')
|
||||||
|
input6_indicator = ui.icon('fiber_manual_record', size='2em').classes('drop-shadow text-red')
|
||||||
|
ui.label('Input 6')
|
||||||
|
input7_indicator = ui.icon('fiber_manual_record', size='2em').classes('drop-shadow text-red')
|
||||||
|
ui.label('Input 7')
|
||||||
|
input8_indicator = ui.icon('fiber_manual_record', size='2em').classes('drop-shadow text-red')
|
||||||
|
ui.label('Input 8')
|
||||||
|
ui.timer(0.5, get_input1)
|
||||||
|
ui.timer(0.5, get_input2)
|
||||||
|
ui.timer(0.5, get_input3)
|
||||||
|
ui.timer(0.5, get_input4)
|
||||||
|
ui.timer(0.5, get_input5)
|
||||||
|
ui.timer(0.5, get_input6)
|
||||||
|
ui.timer(0.5, get_input7)
|
||||||
|
ui.timer(0.5, get_input8)
|
||||||
|
|
||||||
|
table_rows = [
|
||||||
|
{'Input': str(i + 1), 'Voltage': 0.0} for i in range(8)
|
||||||
|
]
|
||||||
|
|
||||||
|
# Example function to update voltages
|
||||||
|
def get_analog_inputs():
|
||||||
|
value = [0] * 8
|
||||||
|
with open('/sys/bus/iio/devices/iio:device1/in_voltage0_raw', 'r') as f:
|
||||||
|
value[0]=int(f.read())*3/500
|
||||||
|
with open('/sys/bus/iio/devices/iio:device1/in_voltage1_raw', 'r') as f:
|
||||||
|
value[1]=int(f.read())*3/500
|
||||||
|
with open('/sys/bus/iio/devices/iio:device1/in_voltage2_raw', 'r') as f:
|
||||||
|
value[2]=int(f.read())*3/500
|
||||||
|
with open('/sys/bus/iio/devices/iio:device1/in_voltage3_raw', 'r') as f:
|
||||||
|
value[3]=int(f.read())*3/500
|
||||||
|
with open('/sys/bus/iio/devices/iio:device0/in_voltage0_raw', 'r') as f:
|
||||||
|
value[4]=int(f.read())*3/500
|
||||||
|
with open('/sys/bus/iio/devices/iio:device0/in_voltage1_raw', 'r') as f:
|
||||||
|
value[5]=int(f.read())*3/500
|
||||||
|
with open('/sys/bus/iio/devices/iio:device0/in_voltage2_raw', 'r') as f:
|
||||||
|
value[6]=int(f.read())*3/500
|
||||||
|
with open('/sys/bus/iio/devices/iio:device0/in_voltage3_raw', 'r') as f:
|
||||||
|
value[7]=int(f.read())*3/500
|
||||||
|
for i in range(8):
|
||||||
|
table_rows[i]['Voltage'] = value[i]
|
||||||
|
table.rows = table_rows
|
||||||
|
table.update()
|
||||||
|
|
||||||
|
ui.markdown('##10V Analog Inputs')
|
||||||
|
with ui.row():
|
||||||
|
# Create the table
|
||||||
|
table = ui.table(
|
||||||
|
columns=[
|
||||||
|
{'name': 'Input', 'label': 'Input', 'field': 'Input'},
|
||||||
|
{'name': 'Voltage', 'label': 'Voltage', 'field': 'Voltage'},
|
||||||
|
],
|
||||||
|
rows=table_rows,
|
||||||
|
)
|
||||||
|
ui.timer(0.5, get_analog_inputs)
|
||||||
|
|
||||||
|
ui.markdown('##Communication')
|
||||||
|
ui.markdown('####Onewire')
|
||||||
|
def get_onewire():
|
||||||
|
try:
|
||||||
|
with open('/sys/bus/w1/devices/28-ca795e1e64ff/temperature', 'r') as f:
|
||||||
|
value=int(f.read())/1000
|
||||||
|
onewirelabel.set_text("DS18B20 onewire sensor: %.2f °C"%value)
|
||||||
|
except:
|
||||||
|
onewirelabel.set_text("not connected")
|
||||||
|
|
||||||
|
with ui.row():
|
||||||
|
onewirelabel = ui.label()
|
||||||
|
ui.timer(1, get_onewire)
|
||||||
|
|
||||||
|
ui.markdown('####I2C')
|
||||||
|
with ui.row():
|
||||||
|
tmp117label = ui.label()
|
||||||
|
ui.timer(1, lambda: tmp117label.set_text("Onboard TMP117 temperature: %.2f °C"%tmp117.temperature))
|
||||||
|
|
||||||
|
ui.markdown('####Differential I2C')
|
||||||
|
def get_diffi2c():
|
||||||
|
if sht == 0:
|
||||||
|
sht40label.set_text("not connected")
|
||||||
|
else:
|
||||||
|
temperature, relative_humidity = sht.measurements
|
||||||
|
sht40label.set_text("SHT40 sensor: %.2f °C %0.1f %%"%(temperature, relative_humidity))
|
||||||
|
|
||||||
|
|
||||||
|
with ui.row():
|
||||||
|
sht40label = ui.label()
|
||||||
|
ui.timer(1, get_diffi2c)
|
||||||
|
|
||||||
|
app.add_static_files('/static', 'static')
|
||||||
|
|
||||||
|
ui.query("body").style(
|
||||||
|
"background-image: url('/static/zeroplc.jpg');"
|
||||||
|
"background-size: contain;"
|
||||||
|
"background-position: center;"
|
||||||
|
"background-repeat: no-repeat;"
|
||||||
|
)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
try:
|
||||||
|
init_camera()
|
||||||
|
camera_connected = 1
|
||||||
|
except:
|
||||||
|
camera_connected = 0
|
||||||
|
ui.markdown('####Camera')
|
||||||
|
with ui.row().classes('w-full justify-left'):
|
||||||
|
if camera_connected != 0:
|
||||||
|
ui.html('''
|
||||||
|
<div>
|
||||||
|
<img src="/video_feed" style="width: 100%; height: auto;" />
|
||||||
|
</div>
|
||||||
|
''')
|
||||||
|
else:
|
||||||
|
ui.html('<h3>No camera connected</h3>')
|
||||||
|
ui.run(reload=False)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
||||||
BIN
zeroPLCgui/static/zeroplc.jpg
Normal file
BIN
zeroPLCgui/static/zeroplc.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 97 KiB |
Reference in New Issue
Block a user