Merge pull request #1 from TrochtaOndrej/chata--test

Chata  test
This commit is contained in:
Ondrej Trochta
2024-10-01 20:31:44 +02:00
committed by GitHub
34 changed files with 879 additions and 338 deletions
+4
View File
@@ -3,3 +3,7 @@
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
.vscode/
.vs/
+13
View File
@@ -0,0 +1,13 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/contentModel.xml
/modules.xml
/projectSettingsUpdater.xml
/.idea.GSM-Chata.iml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
+8
View File
@@ -0,0 +1,8 @@
{
"files.associations": {
"pinsdefinitions": "c",
"new": "cpp"
}
}
+14
View File
@@ -0,0 +1,14 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "PlatformIO",
"task": "Build (uno)",
"problemMatcher": [
"$platformio"
],
"group": "build",
"label": "PlatformIO: Build (uno)"
}
]
}
+14
View File
@@ -0,0 +1,14 @@
{
"folders": [
{
"name": "Arduino-GSM-Chata",
"path": "."
}
],
"settings": {
"files.associations": {
"pinsdefinitions": "c",
"new": "cpp"
}
}
}
+3
View File
@@ -0,0 +1,3 @@
#include "DeviceBase.h"
DeviceBase::DeviceBase(const String id): Id(id) {};
+14
View File
@@ -0,0 +1,14 @@
#ifndef _DeviceBase_h
#define _DeviceBase_h
#include <Arduino.h>
class DeviceBase
{
public:
String Id;
DeviceBase(const String id);
};
#endif
+47
View File
@@ -0,0 +1,47 @@
#include <Arduino.h>
#include "GSMMobileData.h"
#include "EEPROMUtils.h"
#include "DeviceBase.h"
GSMMobileData::GSMMobileData(String id) : DeviceBase(id)
{
readAllData(id);
}
void GSMMobileData::readAllData(String id)
{
EEPROMUtils eepromUtils = EEPROMUtils();
MobileNumber = eepromUtils.readString(1, 20);
Sms = eepromUtils.readString(21, 100);
}
void GSMMobileData::updateMobileNumber(const String &newMobileNumber)
{
if (newMobileNumber.length() <= 0)
{
return;
}
if (newMobileNumber != MobileNumber)
{
EEPROMUtils eepromUtils = EEPROMUtils();
MobileNumber = newMobileNumber;
eepromUtils.writeString(1, newMobileNumber, 20);
}
}
void GSMMobileData::updateSMS(const String &newSMS)
{
if (newSMS.length() <= 0)
{
return;
}
if (newSMS != Sms)
{
EEPROMUtils eepromUtils = EEPROMUtils();
Sms = newSMS;
eepromUtils.writeString(21, newSMS, 100);
}
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef GSMMobileData_H
#define GSMMobileData_H
#include <Arduino.h>
#include "DeviceBase.h" // Include the missing header file
class GSMMobileData : public DeviceBase
{
private:
void readAllData(String id);
public:
String MobileNumber;
String Sms;
GSMMobileData(String id);
void updateMobileNumber(const String &newMobileNumber);
void updateSMS(const String &newSMS);
};
#endif // GSMMobileData_H
+9
View File
@@ -0,0 +1,9 @@
#include <Arduino.h>
#include "PinTypeIn.h"
bool PinTypeIn::IsPinHigh()
{
return digitalRead(_pin) == HIGH ? true : false;
}
+31
View File
@@ -0,0 +1,31 @@
#ifndef PinTypeIn_H
#define PinTypeIn_H
#include <Arduino.h>
#include "DeviceBase.h"
class PinTypeIn : public DeviceBase
{
private:
uint8_t _pin;
unsigned long _debounceDelay;
unsigned long _lastDebounceTime;
int _lastButtonState;
int _buttonState;
public:
const char *description;
PinTypeIn(String id, uint8_t pin, unsigned long debounceDelay, const char *description): DeviceBase(id), _pin(pin), _debounceDelay(debounceDelay)
{
this->description = description;
pinMode(pin, INPUT);
}
/// @brief Get Actual Pin Value if is SET = True, if is NOT SET = False
/// @return
bool IsPinHigh();
};
#endif
+20
View File
@@ -0,0 +1,20 @@
#include "PinTypeOut.h"
#include <Arduino.h>
void PinTypeOut::setOutputSignalToHigh()
{
digitalWrite(_pinNumber, HIGH);
}
void PinTypeOut::setOutputSignalToLow()
{
digitalWrite(_pinNumber, LOW);
}
bool PinTypeOut::IsPinOn()
{
return digitalRead(_pinNumber) == HIGH;
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef PINTYPEOUT_H
#define PINTYPEOUT_H
#include <Arduino.h>
#include "DeviceBase.h"
class PinTypeOut : public DeviceBase
{
private:
uint8_t _pinNumber;
unsigned long _debounceTime;
unsigned long lastStateChangeTime;
public:
const char *description;
PinTypeOut(String id, uint8_t pinNumber, unsigned long debounceTime, const char *description)
: DeviceBase(id), _pinNumber(pinNumber), _debounceTime(debounceTime), lastStateChangeTime(0), description(description)
{
pinMode(pinNumber, OUTPUT);
}
PinTypeOut(String id, uint8_t pinNumber, const char *description)
: DeviceBase(id), _pinNumber(pinNumber),_debounceTime(0), lastStateChangeTime(0), description(description)
{
pinMode(pinNumber, OUTPUT);
}
void setOutputSignalToHigh();
void setOutputSignalToLow();
bool IsPinOn();
};
#endif // PinTypeOut_H
+49
View File
@@ -0,0 +1,49 @@
/*#include <WebServerData.h>
#include <Ethernet.h>
#include <Arduino.h>
String WebServerData::getValue(const String &data, const String &key)
{
return getValue(data, key, '&');
}
/// @brief Separe data PIN1=ON to PIN1 and ON
/// @param data PIN1=ON
/// @param key =
/// @param endchar end of string & or space or any other character
/// @return
String WebServerData::getValue(const String &data, const String &key, char endchar)
{
int keyIndex = data.indexOf(key);
if (keyIndex == -1)
{
return ""; // return empty string if key is not found
}
int separatorIndex = data.indexOf(endchar, keyIndex);
String value = data.substring(keyIndex + key.length(), separatorIndex != -1 ? separatorIndex : data.length());
return removeAllCharactersAfterEmptySpace(value);
}
String WebServerData::getVariableName(const String &data, const String &key)
{
int keyIndex = data.indexOf(key);
String value = data.substring(0, keyIndex != -1 ? keyIndex : keyIndex);
return removeAllCharactersAfterEmptySpace(value);
}
String WebServerData::removeAllCharactersAfterEmptySpace(String &data)
{
int keyIndex = data.indexOf(' ');
if (keyIndex == -1)
{
return data; // return empty string if key is not found
}
data.remove(keyIndex);
data.replace("_", " ");
return data;
}
*/
+23
View File
@@ -0,0 +1,23 @@
/*ifndef WebServerData_H
#define WebServerData_H
#include <Ethernet.h>
#include <Arduino.h>
class WebServerData
{
public:
String Request;
bool IsEmpty;
WebServerData() : IsEmpty(true){};
WebServerData(String request) : Request(request), IsEmpty(false){};
String getValue(const String &data, const String &key, char endchar);
String getValue(const String &data, const String &key);
String removeAllCharactersAfterEmptySpace(String &data);
String getVariableName(const String &data, const String &key);
};
#endif // WebServerData_H
*/
+32
View File
@@ -0,0 +1,32 @@
#include "EEPROMUtils.h"
#include <EEPROM.h>
#include <Arduino.h>
// Statická metoda pro čtení řetězce z EEPROM
String EEPROMUtils::readString(int addr, int length)
{
String data;
for (int i = 0; i < length; i++)
{
char onedata = char(EEPROM.read(addr + i)); // read one byte at a time
if (onedata == '\n')
return data;
data += onedata;
}
return data;
}
// Statická metoda pro zápis řetězce do EEPROM
void EEPROMUtils::writeString(int addr, String data, int limit)
{
int numBytes = data.length(); // get length of the string
for (int i = 0; i < numBytes && i < limit; i++)
{
EEPROM.write(addr + i, data[i]); // write one byte at a time
}
if (numBytes < limit)
{
EEPROM.write(addr + numBytes, '\n'); // add newline character at the end
}
}
+13
View File
@@ -0,0 +1,13 @@
#ifndef EEPROMUtils_h
#define EEPROMUtils_h
#include <Arduino.h> // Include the missing header file for the String class
class EEPROMUtils
{
public:
static String readString(int addr, int length);
static void writeString(int addr, const String data, int limit); // Fix the function signature
};
#endif
+112
View File
@@ -0,0 +1,112 @@
#include "GSMMobileData.h"
#include <SoftwareSerial.h>
#include "GSMMobileDevice.h"
#include "DebugLog.h"
#include "Helper.h"
//#define DEBUG
void GSMMobileDevice::init()
{
// init software serial
_gsmSerial.begin(_baudRate);
delay(5000); // initialization GSM module (give it some time to boot up)
}
void GSMMobileDevice::end()
{
_gsmSerial.end();
#ifdef DEBUG
DebugLog::log("GSM End ..");
#endif
}
void GSMMobileDevice::executeAtCommand(const String &atCommand)
{
#ifdef DEBUG
DebugLog::log(atCommand);
#endif
_gsmSerial.print(atCommand + "\r");
delay(500);
#ifdef DEBUG
DebugLog::log("read fromGMS:" + readStringSerialPort());
delay(100);
#endif
}
String GSMMobileDevice::readStringSerialPort()
{
return _gsmSerial.readString();
}
void GSMMobileDevice::sendSMSToGSM(GSMMobileData gsmData)
{
#ifdef DEBUG
DebugLog::log("SMS Start SEND SMS Id:" + gsmData.Id + " M:" + gsmData.MobileNumber + " with message " + gsmData.Sms);
#endif
executeAtCommand("AT+CMGF=1");
executeAtCommand("AT + CMGS =\"" + gsmData.MobileNumber + "\"");
executeAtCommand("ID:" + gsmData.Id + " Msg:" + gsmData.Sms);
delay(1000);
// Send a Ctrl+Z / ASCII SUB
_gsmSerial.print((char)26);
delay(500);
// Close the connection
_gsmSerial.print((char)27);
delay(500);
}
bool GSMMobileDevice::checkSMSError()
{
return true;
String response = readStringSerialPort();
if (response.indexOf("ERROR") != -1)
{
// If there was an error, try to reconnect and resend
_gsmSerial.println("AT+CFUN=1,1"); // Restart the module
delay(15000); // Wait for the module to restart
return true;
}
return false;
}
unsigned long _lastSMSTime = 0;
void GSMMobileDevice::sendSMS(GSMMobileData gsmData)
{
// Check if enough time has passed since the last SMS was sent
if (millis() - _lastSMSTime >= 60000)
{
// Send the SMS
init();
sendSMSToGSM(gsmData);
if (checkSMSError())
{
// Log that the SMS was sent
DebugLog::log("SMS sent successfully.");
}
else
{
// Log that the SMS was not sent
DebugLog::log("SMS not sent. Error occurred.");
}
// Update the last SMS time
_lastSMSTime = millis();
end();
}
else
{
// Log that the SMS was not sent
DebugLog::log("SMS not sent. Not enough time has passed since the last SMS was sent.");
}
}
// GSMMobileDevice::~GSMMobileDevice()
// {
// // // close gsmSerial
// // // close gsmSerial
// _gsmSerial.end();
// }
+31
View File
@@ -0,0 +1,31 @@
#ifndef GSMMobileDevice_H
#define GSMMobileDevice_H
#include "GSMMobileData.h"
#include "SoftwareSerial.h"
class GSMMobileDevice
{
private:
SoftwareSerial _gsmSerial;
// Methods
void executeAtCommand(const String &atCommand);
String readStringSerialPort();
void sendSMSToGSM(GSMMobileData gsmData);
long _baudRate;
bool checkSMSError();
public:
// Constructor with no parameters
GSMMobileDevice(uint8_t pinRx, uint8_t pinTx, long baudRate) : _gsmSerial(pinRx, pinTx), _baudRate(baudRate)
{
}
// Methods
void init();
void sendSMS(GSMMobileData gsmData);
void end();
};
#endif // GSMDevice_H
+137
View File
@@ -0,0 +1,137 @@
/*#include <Arduino.h>
#include <Ethernet.h>
#include "WebServer.h"
#include "WebServerData.h"
#include "DebugLog.h"
// Constructor
WebServer::WebServer() : _server(80) {}
WebServer::WebServer(byte mac[6], IPAddress ip, uint16_t port) : _ip(ip), _server(port)
{
memcpy(_mac, mac, 6);
}
// Initialize the Ethernet and start the server
void WebServer::init()
{
Ethernet.begin(_mac, _ip);
#ifdef DEBUG
DebugLog::log("Ethernet IP: " + Ethernet.localIP());
#endif
_server.begin();
#ifdef DEBUG
DebugLog::log("Server Start");
#endif
}
// Move the declaration of EthernetClient inside the WebServer class
EthernetClient client;
// Handle client requests
WebServerData WebServer::getWebServerData()
{
// Check if a client has connected
client = _server.available();
if (client)
{
if (client.connected())
{
#ifdef DEBUG
DebugLog::log("Client connected");
#endif
unsigned long startTime = millis();
while (client.available() == 0)
{
if (millis() - startTime >= 10000)
{
break;
}
delay(10);
}
client.println(F("HTTP/1.1 200 OK")); // Respond together with the Web page in the HTML
client.println(F("Content-Type: text/html"));
client.println(F("Connection: close"));
client.println();
String request = client.readStringUntil('\r');
if (request.startsWith("GET / HTTP/1.1"))
{
#ifdef DEBUG
DebugLog::log("EMPTY DATA: " + request);
#endif
return WebServerData();
}
// client.flush(); // Clear the incoming buffer after reading the GET request
// If you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (request.startsWith("GET /"))
{
#ifdef DEBUG
DebugLog::log("GET WEB SERVER DATA: " + request);
#endif
WebServerData webServerData = WebServerData(request);
return webServerData;
}
}
}
return WebServerData();
// Give the web browser time to receive the data
}
// Return a default-constructed WebServerData object if no client is available
void WebServer::endServer()
{
if (_server.available())
{
delay(10);
// Close the connection
client.stop();
}
}
void WebServer::SendToBrowser(const String &dataString)
{
const byte chunkSize = 50;
// Send data in chunks
unsigned int stringIndex = 0;
unsigned long startTime = millis();
while (stringIndex < dataString.length())
{
if (client.availableForWrite() > 0)
{
int chunkLength = min(chunkSize, dataString.length() - stringIndex);
const String chunk = dataString.substring(stringIndex, stringIndex + chunkLength);
// Send the chunk (consider error handling)
#ifdef DEBUG
DebugLog::log("StBC: " + chunk);
#endif
client.print(chunk);
stringIndex += chunkLength;
delay(5); // Optional delay between chunks
}
else if (millis() - startTime >= 10000)
{
return; // Timeout
}
delay(5); // Optional delay between chunks
}
client.println("");
}
*/
+27
View File
@@ -0,0 +1,27 @@
/*#ifndef WebServer_H
#define WebServer_H
#include <WebServerData.h>
#include <Arduino.h>
#include <Ethernet.h>
class WebServer
{
private:
byte _mac[6];
IPAddress _ip;
EthernetServer _server;
public:
EthernetClient client;
WebServer();
WebServer(byte mac[6], IPAddress ip, uint16_t port);
WebServerData getWebServerData();
void init();
void endServer();
void SendToBrowser(const String &dataString);
};
#endif // WebServer_H
*/
+31
View File
@@ -0,0 +1,31 @@
#include <Arduino.h>
#include "DebugLog.h"
void DebugLog::log(const String &log)
{
// WriteToSerial(log);
}
void DebugLog::init(const long &bound)
{
Serial.begin(bound);
Serial.println("Serial Port Initialized");
}
void DebugLog::WriteToSerial(const String &dataString)
{
const byte chunkSize = 60;
unsigned int stringIndex = 0;
while (stringIndex < dataString.length())
{
int chunkLength = min(chunkSize, dataString.length() - stringIndex);
String chunk = dataString.substring(stringIndex, stringIndex + chunkLength);
Serial.print(chunk);
stringIndex += chunkLength;
delay(4); // Optional delay between chunks
}
Serial.println("");
}
+18
View File
@@ -0,0 +1,18 @@
#ifndef DebugLog_H
#define DebugLog_H
#include <Arduino.h>
class DebugLog
{
private:
static void WriteToSerial(const String &dataString);
public:
static void init(const long &bound);
static void log(const String &log);
};
#endif
+21
View File
@@ -0,0 +1,21 @@
#include <Arduino.h>
#include "HTMLGenerator.h"
#include "DebugLog.h"
const String HTMLGenerator::GetElement(const String &tag, const String &content)
{
return "<" + tag + ">" + content + "</" + tag + ">";
}
const String HTMLGenerator::DisplayOuputPinStatus(const String &pinName, const bool &isOn, const String &description)
{
const String pinvariable = pinName + (isOn ? "=OFF" : "=ON");
String content = pinName + " is " + (isOn ? "ON" : "OFF") + " | <a href=\"" + pinvariable + "\">" + pinvariable + "</a> ";
return GetElement("p", content);
}
const String HTMLGenerator::DisplayInputPinStatus(const String &pinName, const bool &isOn, const String &description)
{
const String content = pinName + " is " + (isOn ? "ON" : "OFF");
return GetElement("H4", content);
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef HTMLGENERATOR_H
#define HTMLGENERATOR_H
#include <Arduino.h>
class HTMLGenerator
{
public:
static const String GetElement(const String &tag,const String &content );
static const String DisplayOuputPinStatus( const String &pinName,const bool &isOn, const String &description);
static const String DisplayInputPinStatus( const String &pinName,const bool &isOn,const String &description);
};
#endif // HTMLGENERATOR_H
+30
View File
@@ -0,0 +1,30 @@
#include <limits.h>
#include <Arduino.h>
#include "Helper.h"
unsigned long currentTime = millis();
unsigned long lastOverflowTime = 0; // Add missing declaration and initialization
// Function to check for overflow and update lastOverflowTime
bool Helper::hasOverflowed()
{
if (currentTime < lastOverflowTime)
{
lastOverflowTime = currentTime;
return true;
}
return false;
}
// Calculate elapsed time considering overflow
unsigned long Helper::getElapsedTime(bool resetTime)
{
unsigned long elapsedTime = currentTime - lastOverflowTime;
if (hasOverflowed())
{
elapsedTime += (ULONG_MAX - lastOverflowTime); // Add the time since last overflow
}
return elapsedTime;
}
+18
View File
@@ -0,0 +1,18 @@
#ifndef HELPER_H
#define HELPER_H
#include <limits.h>
#include <Arduino.h>
class Helper
{
private:
public:
Helper();
bool hasOverflowed();
unsigned long getElapsedTime(bool reset);
};
#endif
+6 -1
View File
@@ -12,4 +12,9 @@
platform = atmelavr
board = uno
framework = arduino
lib_deps = arduino-libraries/Ethernet@^2.0.2
debug_tool = avr-stub
debug_port = COM8
monitor_port = COM8
monitor_speed = 115200
lib_deps =
jdolinay/avr-debugger@^1.5
-337
View File
@@ -1,337 +0,0 @@
#include <SoftwareSerial.h>
#include <EEPROM.h>
#include <Arduino.h>
#include <Ethernet.h>
#define DEBUG
// MAC address and IP address for the Ethernet module
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
// Initialize the Ethernet server (port 80 is default for HTTP)
EthernetServer server(80);
// Initialize software serial for RS232 communication (RX, TX)
SoftwareSerial gsmSerial(5, 6); // RX, TX (this is using for communicate with GSM module as AT commands)
uint8_t PIN_OUT_2 = 2;
uint8_t PIN_OUT_3 = 3;
String ElmP = "p";
String ElmH2 = "H2";
EthernetClient client;
struct BaseTypeScript {
String id;
};
// Definice struktury pro ukládání parametrů GET požadavku
struct GsmPostParams : public BaseTypeScript {
String mobileNumber;
String sms;
};
//Pin (Vstupni piny)
struct pinState {
uint8_t pinNumber;
volatile bool lastState;
unsigned long debounceTime;
unsigned long lastStateChangeTime;
const char *description;
};
const uint8_t numInputPins = 2; // Replace with the actual number of input pins
// definice ignorace vstupnich pinu
pinState inputStates[numInputPins] = {
// { 4, LOW, 60000, 0, "Enter Door" }, // Pin 4, debounce time 1 minute
{ 7, LOW, 30000, 0, "Alarm Alert" }, // Pin 8, debounce time 30 seconds
{ 8, LOW, 10000, 0, "Electric Alarm" } // Pin 9, debounce time 10 seconds
};
GsmPostParams gsmPostParams;
String readStringFromEEPROM(int addr, int length) {
String data;
for (int i = 0; i < length; i++) {
char onedata = char(EEPROM.read(addr + i)); // read one byte at a time
if (onedata == '\n') return data;
data += onedata;
}
return data;
}
void logDebug(const String &log) {
// Serial.println(log);
}
void setup() {
// if (Serial.available() > 0) {
// Serial.begin(115200);
// }
gsmSerial.begin(115200);
// Start the Ethernet connection and the server
Ethernet.begin(mac, ip);
server.begin();
gsmPostParams.mobileNumber = readStringFromEEPROM(1, 20);
gsmPostParams.sms = readStringFromEEPROM(21, 200);
gsmPostParams.id = "GSM";
logDebug("Init ..");
// Set all input pins as inputs
for (int i = 0; i < numInputPins; i++) {
pinMode(inputStates[i].pinNumber, INPUT);
}
// Set pin 2 and 3 as OUTPUT
pinMode(PIN_OUT_2, OUTPUT);
pinMode(PIN_OUT_3, OUTPUT);
logDebug("Init I/O is OK");
// Open serial communications
}
String removeAllCharactesrAfterEmpty(String& data) {
int keyIndex = data.indexOf(' ');
if (keyIndex == -1) {
return data; // return empty string if key is not found
}
data.remove(keyIndex);
data.replace("+", " ");
return data;
}
// Metoda pro parsování parametrů
String getValue(String &data, const String &key) {
int keyIndex = data.indexOf(key);
if (keyIndex == -1) {
return ""; // return empty string if key is not found
}
int separatorIndex = data.indexOf('&', keyIndex);
String value = data.substring(keyIndex + key.length(), separatorIndex != -1 ? separatorIndex : data.length());
logDebug("Only value:" + value);
return removeAllCharactesrAfterEmpty(value);
}
void writeToLogAndIntoWebAsP(const String &msg, const String &element) {
String lineElement = "<" + element + ">" + msg + "</" + element + ">";
// logDebug(msg);
//gsmlogDebug("GSM:" + msg);
client.println(lineElement);
}
// pin = definice pinu Arduino, string je post hodnota, ktera se porovnava
void checkValue(String &request, uint8_t pin, const String &postValue) {
if (request.indexOf("/PIN") == -1) return;
if (request.indexOf("/" + postValue + "=ON") != -1) {
digitalWrite(pin, HIGH);
String msgOn = "PIN ON: " + String(pin) + " PostVale: " + postValue;
writeToLogAndIntoWebAsP(msgOn, ElmH2); // Send state to debug console
}
if (request.indexOf("/" + postValue + "=OFF") != -1) {
digitalWrite(pin, LOW);
String msgOff = "PIN OFF: " + String(pin) + " PostVale: " + postValue;
writeToLogAndIntoWebAsP(msgOff, ElmH2); // Send state to debug console
}
}
String ConvertStatusToString(uint8_t &pin, bool showLink) {
String pinAsStr = String(pin);
String elm = "";
if (digitalRead(pin) == HIGH) {
elm = "PIN" + pinAsStr + " is ON ";
if (showLink) elm += "<a href=\"PIN" + pinAsStr + "=OFF\">OFF</a>";
return elm;
}
elm = "PIN" + pinAsStr + " is OFF ";
if (showLink) elm += "<a href=\"PIN" + pinAsStr + "=ON\">ON</a>";
return elm;
}
void changeDataIfNotNull(String &variable, String &data) {
if (data == "") return;
variable = data;
}
void SednAtCommandWithLog(String msg) {
logDebug(msg);
gsmSerial.print(msg + "\r");
delay(400);
logDebug(gsmSerial.readString());
}
void SendSMS(String pin) {
// Set the SIM900A to text mode
SednAtCommandWithLog("AT+CMGF=1");
delay(400);
SednAtCommandWithLog("AT + CMGS =\"" + gsmPostParams.mobileNumber + "\"");
delay(400);
// Specify the SMS message
SednAtCommandWithLog(pin + " " + gsmPostParams.sms);
delay(1000);
// Send a Ctrl+Z / ASCII SUB
gsmSerial.print((char)26);
delay(1000);
// Close the connection
gsmSerial.print((char)27);
delay(1000);
logDebug("Close communication GSM");
// String msg = gsmSerial.readStringUntil("/n");
// gsmlogDebug("Msg:"+msg);
}
void writeStringToEEPROM(int addr, const String &data, int limit) {
uint8_t endIndex =0;
int numBytes = data.length(); // get length of the string
for (uint8_t i = 0; i < numBytes && i < limit; i++) {
EEPROM.write(addr + i, data[i]); // write one byte at a time
endIndex = i;
}
if (endIndex < limit) {
EEPROM.write(addr + endIndex + 1, '\n');
}
}
void SetPin(uint8_t pin, const char *description) {
SendSMS("PIN:" + String(pin) + "|" + description);
}
void checkInputPins() {
unsigned long currentTime = millis();
for (int i = 0; i < numInputPins; i++) {
pinState *currentState = &inputStates[i]; // Pointer to current pin state
bool currentInputState = digitalRead(currentState->pinNumber);
if (currentInputState != currentState->lastState && currentTime - currentState->lastStateChangeTime >= currentState->debounceTime) {
// Input state change confirmed after debounce time
currentState->lastState = currentInputState;
if (currentInputState) {
// Call SetPin function (modify for specific pin control)
SetPin(currentState->pinNumber, currentState->description); // Example usage with pin number passed
}
currentState->lastStateChangeTime = currentTime;
}
}
}
int iterationCounter = 0; // Counter for loop iterations
void loop() {
// Listen for incoming clients
String msg = "";
client = server.available();
if (client) {
String request = client.readStringUntil('\r');
logDebug("request:" + request);
if (request.indexOf("GET /?id=GSM") != -1) {
logDebug("it is GSM");
//int start = request.indexOf("/?id=") + 2;
String data = request.substring(6);
logDebug("data:" + data);
String id = getValue(data, "id=");
logDebug("id data:" + id);
String value = getValue(data, "mobileNumber=");
changeDataIfNotNull(gsmPostParams.mobileNumber, value);
value = getValue(data, "sms=");
changeDataIfNotNull(gsmPostParams.sms, value);
msg += "PARSING GMS DATA SUCESSFULLY";
}
logDebug("struc GSM:" + gsmPostParams.mobileNumber + " sms:" + gsmPostParams.sms);
if (request.indexOf("GET /SEND-SMS") != -1) {
msg += "SEND SMS TROUGHT GSM. ";
}
if (request.indexOf("GET /SAVE-EEPROM") != -1) {
writeStringToEEPROM(1, gsmPostParams.mobileNumber, 20);
writeStringToEEPROM(21, gsmPostParams.sms, 200);
msg += "Update to EEPROM is sucessfully. ";
}
logDebug("Request:" + request);
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
client.println("<html><head><style>");
client.println(" body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0;}");
client.println(".content {text-align: center;}");
client.println("</style>");
client.println("</head><body><div class=\"content\">");
client.println("<H2> Trochta.net:</H2>");
writeToLogAndIntoWebAsP(msg, "H3");
//nastav jestli je post
checkValue(request, PIN_OUT_2, "PIN2");
checkValue(request, PIN_OUT_3, "PIN3");
// Vypis aktualni hodnoty
writeToLogAndIntoWebAsP("Input:", ElmP);
for (int i = 0; i < numInputPins; i++) {
pinState *currentState = &inputStates[i];
writeToLogAndIntoWebAsP(ConvertStatusToString(currentState->pinNumber, false), ElmP);
}
writeToLogAndIntoWebAsP("Output:", ElmP);
writeToLogAndIntoWebAsP(ConvertStatusToString(PIN_OUT_2, true), ElmP);
writeToLogAndIntoWebAsP(ConvertStatusToString(PIN_OUT_3, true), ElmP);
writeToLogAndIntoWebAsP("GSM Number:" + gsmPostParams.mobileNumber, ElmP);
writeToLogAndIntoWebAsP("SMS:" + gsmPostParams.sms, ElmP);
writeToLogAndIntoWebAsP("<a href=\"SEND-SMS\">Send SMS</a>", "H4");
writeToLogAndIntoWebAsP("<a href=\"SAVE-EEPROM\">Save to EEPROM</a>", ElmP);
writeToLogAndIntoWebAsP("<a href=\"/\">Refresh</a>", ElmP);
// Send the time and the message that the page is loaded
client.println("</div></body></html>");
// Give the web browser time to receive the data
client.stop();
logDebug("Time: " + String(millis() / 1000));
if (request.indexOf("GET /SEND-SMS") != -1) {
SendSMS("Web Link (Test)");
}
// Zjkontroluje vstupni piny
delay(5);
}
iterationCounter++;
if (iterationCounter == INT_FAST16_MAX) iterationCounter = 0;
if (iterationCounter % 5 == 0) { // Check if 10 iterations have passed
checkInputPins(); // Call checkInputPins() every 10 iterations
}
delay(100);
}
+61
View File
@@ -0,0 +1,61 @@
#include "GSMMobileDevice.h"
//#include "WebServer.h"
#include "PinTypeIn.h"
#include "PinTypeOut.h"
#include <Arduino.h>
//#include <IPAddress.h>
// #include <Ethernet.h>
// #include "WebServer.h"
// #include "WebServerData.h"
//#include "HTMLGenerator.h"
#include "avr8-stub.h"
//#define DEBUG
// PIN INPUT Initialization as OUTPUT
static const int COUNT_OUTPUTS_PIN_OUT = 2;
static PinTypeOut PinOutAlarm8 = PinTypeOut("PIN8", 8, "Electric Alarm");
static PinTypeOut PinOutCase7 = PinTypeOut("PIN7", 7, "Default Description");
static const PinTypeOut OUPUTS_PINS_ARRAY[COUNT_OUTPUTS_PIN_OUT] = {PinOutAlarm8, PinOutCase7};
// PIN INPUT Initialization as INPUT
static const int COUNT_INPUTS_PIN_IN = 2;
static PinTypeIn PinInEZSAlarm2 = PinTypeIn("PIN4", 4, 100, "Input EZS ALARM"); // 100ms debounce;
static PinTypeIn PinInCaseOpen3 = PinTypeIn("PIN3", 3, 100, "Input Contact Box");
static const PinTypeIn INPUTS_PINS_ARRAY[COUNT_INPUTS_PIN_IN] = {PinInEZSAlarm2, PinInCaseOpen3};
// // GSM Serial Port
//https://arduino.stackexchange.com/questions/44599/sim900a-mini-modem-imei-0-help-with-tx-rx-pins
static const uint8_t GSM_PIN_RX = 5;
static const uint8_t GSM_PIN_TX = 6;
static const long GSM_BAUD_RATE = 115200;
GSMMobileDevice gsmDevice = GSMMobileDevice(GSM_PIN_RX, GSM_PIN_TX, GSM_BAUD_RATE);
// // Pin Input
GSMMobileData gsmData = GSMMobileData("GSM");
void setup()
{
debug_init();
gsmData.MobileNumber = "+420608126674";
gsmData.Sms = "Alarm EZS CHATA";
}
void loop()
{
;
if (PinInEZSAlarm2.IsPinHigh())
{
PinOutAlarm8.setOutputSignalToHigh();
gsmDevice.sendSMS(gsmData);
}
else
{
PinOutAlarm8.setOutputSignalToLow();
}
delay(1000);
}