From c7f1d1d65169482759d8e427b0f68c50f53ffdfc Mon Sep 17 00:00:00 2001 From: Cyril Danilevski <cyril.danilevski@xfel.eu> Date: Tue, 27 Aug 2024 18:16:26 +0200 Subject: [PATCH] Read pins from MCP23S08 port expander --- icbm.ino | 4 +++ panel.hpp | 38 +++++++++++------------ pins.cpp | 73 +++++++++++++++++++++++++++++++++++++++++++ pins.hpp | 31 +++++++++++++++++++ rest.cpp | 92 +++++++++++++++++++++++++++++++++---------------------- 5 files changed, 183 insertions(+), 55 deletions(-) create mode 100644 pins.cpp create mode 100644 pins.hpp diff --git a/icbm.ino b/icbm.ino index 885064f..1825fb0 100644 --- a/icbm.ino +++ b/icbm.ino @@ -1,6 +1,7 @@ #include "esp32_ethernet.hpp" #include "rest.hpp" #include "mpod.hpp" +#include "pins.hpp" unsigned long start; @@ -10,6 +11,7 @@ extern SNMP::Manager snmp; void setup() { Serial.begin(115200); + initializeMCP(); initializeNetwork(); initializeRoutes(); initializeSNMP(); @@ -33,7 +35,9 @@ void serial_loop() { } void loop() { + isr_check_loop(); snmp.loop(); restServer.handleClient(); + toggle_status_led(); serial_loop(); } diff --git a/panel.hpp b/panel.hpp index 16c296b..ae6e2e0 100644 --- a/panel.hpp +++ b/panel.hpp @@ -1,13 +1,14 @@ -String buildPanel(bool plc, bool iob, bool ups) { +String buildPanel(bool sib, bool plc, bool ups, unsigned long elapsed_secs) { + // Shows OK if not triggered (ie bool == false) String page = "<!DOCTYPE html><html lang=\"en\">\n"; - page += "<head><meta name=\"viewport\" page=\"width=device-width, initial-scale=1.0\">\n"; - page += "<meta http-equiv=\"refresh\" page=\"1\"/>\n"; + page += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n"; + page += "<meta http-equiv=\"refresh\" content=\"1\"/>\n"; page += "<title>ICBM</title>\n"; page += "<style>\n"; - page += "body {font-family: Arial, sans-serif; display: flex; justify-page: center; align-items: center; height: 100vh; margin: 0; background-color: #f0f0f0;}\n"; + page += "body {font-family: Arial, sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #f0f0f0;}\n"; page += ".container {background-color: white; padding: 20px; border-radius: 10px; box-shadow: 0 0 10px rgba(0,0,0,0.1);}\n"; page += "h1 {text-align: center; color: #333;}\n"; - page += ".status-item {margin: 15px 0; padding: 10px; border-radius: 5px; display: flex; justify-page: space-between; align-items: center;}\n"; + page += ".status-item {margin: 15px 0; padding: 10px; border-radius: 5px; display: flex; justify-content: space-between; align-items: center;}\n"; page += ".status-label {font-weight: bold; margin-right: 10px;}\n"; page += ".status-value {padding: 5px 10px; border-radius: 20px; color: white; font-weight: bold;}\n"; page += ".status-ok { background-color: #4CAF50; }\n"; @@ -16,28 +17,27 @@ String buildPanel(bool plc, bool iob, bool ups) { page += "</style>"; page += "</head><body>\n"; page += "<div class=\"container\"><h1>INPUTS:</h1>\n"; + page += "<div class=\"status-item\">\n"; - page += "<span class=\"status-label\">PLC:</span>"; - - if (plc) { page += "<span class=\"status-value status-error\">Triggered</span>\n"; } + page += "<span class=\"status-label\">SIB:</span>\n"; + if (!sib) { page += "<span class=\"status-value status-error\">Triggered</span>\n"; } else { page += "<span class=\"status-value status-ok\">OK</span>\n"; } + page += "</div>\n"; - page += "</div><div class=\"status-item\">\n"; - page += "<span class=\"status-label\">IOB:</span>\n"; - - if (iob) { page += "<span class=\"status-value status-error\">Triggered</span>\n"; } + page += "<div class=\"status-item\">\n"; + page += "<span class=\"status-label\">PLC:</span>"; + if (!plc) { page += "<span class=\"status-value status-error\">Triggered</span>\n"; } else { page += "<span class=\"status-value status-ok\">OK</span>\n"; } + page += "</div>\n"; - page += "</div><div class=\"status-item\">\n"; + page += "<div class=\"status-item\">\n"; page += "<span class=\"status-label\">UPS:</span>\n"; - - if (ups) { page += "<span class=\"status-value status-error\">Triggered</span>\n"; } + if (!ups) { page += "<span class=\"status-value status-error\">Triggered</span>\n"; } else { page += "<span class=\"status-value status-ok\">OK</span>\n"; } + page += "</div>\n"; - page += "</div><h3>Last INT: "; - - page += "5"; - + page += "<h3>Last INT: "; + page += elapsed_secs; page += "</h3></div></body></html>"; return page; diff --git a/pins.cpp b/pins.cpp new file mode 100644 index 0000000..d307577 --- /dev/null +++ b/pins.cpp @@ -0,0 +1,73 @@ +#include "pins.hpp" + +MCP23S08 MCP(SS, MISO, MOSI, SCK); +volatile byte ISR_FLAG = 0; +struct pins PINS; + +void IRAM_ATTR isr(){ + ISR_FLAG = 1; +} + +void initializeMCP() +{ + pinMode(ISR_PIN, INPUT_PULLUP); + //attachInterrupt(digitalPinToInterrupt(ISR_PIN), isr, CHANGE); + attachInterrupt(digitalPinToInterrupt(TRIGGER_SIGNAL), isr, CHANGE); + + SPI.begin(); + MCP.begin(); + + // Enable inputs and interrupts on pins 0-2 + MCP.pinMode8(0b00000111); + MCP.enableInterrupt(0, FALLING); + MCP.enableInterrupt(1, FALLING); + MCP.enableInterrupt(2, FALLING); + Serial.println("MCP23S08 Started"); + +} + + +void isr_check_loop() +{ + if (ISR_FLAG == 1){ + PINS.sib = false; + PINS.plc = false; + PINS.ups = false; + PINS.last_triggered = millis(); + + Serial.print("Interrupt: "); + uint8_t regval = MCP.getInterruptCaptureRegister(); //INTCAP + Serial.print(regval); + + uint8_t mask = 1 << 0; + if (!(regval & mask)) { + Serial.print("UPS"); + PINS.ups = true; + } + + mask = 1 << 1; + if (!(regval & mask)) { + Serial.print("PLC"); + PINS.plc = true; + } + + mask = 1 << 2; + if (!(regval & mask)) { + Serial.print("SIB"); + PINS.sib = true; + } + + Serial.println(); + ISR_FLAG = 0; + } +} + +bool on = true; +unsigned long toggle_start = 0; +void toggle_status_led() { + if (millis() - toggle_start >= 1000) { + toggle_start = millis(); + on = !on; + MCP.write1(STATUS_LED_PIN, on); + } +} diff --git a/pins.hpp b/pins.hpp new file mode 100644 index 0000000..a628949 --- /dev/null +++ b/pins.hpp @@ -0,0 +1,31 @@ +#pragma once +#include "MCP23S08.h" + +// Software SPI definitions +#define MOSI 13 +#define MISO 12 +#define SS 2 +#define SCK 4 + +// MCP23S08 interrupt +#define ISR_PIN 15 + +//AlCon Logic Board interrupt +#define TRIGGER_SIGNAL 14 + +// LED pin on MCP23S08 extender +#define STATUS_LED_PIN 6 + +struct pins { + bool sib; + bool plc; + bool ups; + int last_triggered; +}; +extern struct pins PINS; + +extern MCP23S08 MCP; +void IRAM_ATTR isr(); +void initializeMCP(); +void isr_check_loop(); +void toggle_status_led(); diff --git a/rest.cpp b/rest.cpp index 407d1d8..e990fad 100644 --- a/rest.cpp +++ b/rest.cpp @@ -1,6 +1,7 @@ #include "rest.hpp" #include "mpod.hpp" #include "panel.hpp" +#include "pins.hpp" #include <ETH.h> #ifndef ICBM_GIT_VERSION @@ -18,7 +19,7 @@ void initializeRoutes() { restServer.on("/restart", restart); restServer.onNotFound(notFound); restServer.on("/send", sendSNMP); - restServer.on("/poll", panel); + restServer.on("/", panel); restServer.begin(); Serial.println("REST Server Started"); @@ -26,51 +27,70 @@ void initializeRoutes() { void identify() { - int seconds = millis() / 1000; - int hours = seconds / 3600; - int minutes = (seconds / 60) % 60; - seconds = seconds % 60; - - String message = "{\n"; - - message += "\"mac\":\""; - message += ETH.macAddress(); - message += "\",\n"; - - message += "\"version\":\""; - message += ICBM_GIT_VERSION; - message += "\",\n"; - - message += "\"build date\":\""; - message += ICBM_GIT_TIMESTAMP; - message += "\",\n"; - - message += "\"uptime\": \""; - message += hours; - message += ":"; - message += minutes; - message += ":"; - message += seconds; - message += "\""; - - // TODO: Add here mcp23s08 info: - // Pin status; - // Interrupt status; - // seconds since last interrupt. - // + int seconds = millis() / 1000; + int hours = seconds / 3600; + int minutes = (seconds / 60) % 60; + seconds = seconds % 60; + + String message = "{\n"; + + message += "\"mac\":\""; + message += ETH.macAddress(); + message += "\",\n"; + + message += "\"version\":\""; + message += ICBM_GIT_VERSION; + message += "\",\n"; + + message += "\"build date\":\""; + message += ICBM_GIT_TIMESTAMP; + message += "\",\n"; + + message += "\"uptime\": \""; + message += hours; + message += ":"; + message += minutes; + message += ":"; + message += seconds; + message += "\",\n"; + + message += "\"inputs\":{\n"; + message += "\"sib\":"; + message += PINS.sib; + message += ",\n"; + + message += "\"plc\":"; + message += PINS.plc; + message += ",\n"; + + message += "\"ups\":"; + message += PINS.ups; + message += ",\n"; + + unsigned long elapsed_seconds = (millis() - PINS.last_triggered) / 1000; + message += "\"sec_since_interrupt\":"; + message += elapsed_seconds; + message += ",\n"; + message += "\n}"; + // TODO: Add here power sequence status // is_ramping_down // current step // percentage - message += "\n}"; + message += "\n}"; restServer.send(200, "text/json", message); } - void panel() { - String content = buildPanel(true, true, true); + unsigned long elapsed_seconds = (millis() - PINS.last_triggered) / 1000; + String content = buildPanel( + PINS.sib, + PINS.plc, + PINS.ups, + elapsed_seconds + ); restServer.send(200, "text/html", content); } -- GitLab