Skip to content

Instantly share code, notes, and snippets.

@Tech500
Last active June 13, 2024 05:46
Show Gist options
  • Save Tech500/149a9c0c123a99e220232b195ae296c8 to your computer and use it in GitHub Desktop.
Save Tech500/149a9c0c123a99e220232b195ae296c8 to your computer and use it in GitHub Desktop.
E220 remote switch operated by on demand web GET request.
//E220_Remote_Switch_Sender.ino
// 6/12/2024 @ 20:119 EST
// See library downloads for each library license.
// With FIXED SENDER configuration
#define DESTINATION_ADDL 3
#include <Arduino.h>
#include "WiFi.h"
#include <WiFiUdp.h>
#include <HTTPClient.h>
#include <time.h>
#include "LoRa_E220.h"
#include <AsyncTCP.h>
#include "ESPAsyncWebServer.h"
#include <Ticker.h>
#import "index7.h" //Video feed HTML; do not remove
#define FREQENCY_915
WiFiClient client;
///Are we currently connected?
boolean connected = false;
WiFiUDP udp;
// local port to listen for UDP packets
const int udpPort = 1337;
char incomingPacket[255];
char replyPacket[] = "Hi there! Got the message :-)";
//NTP Time Servers
const char * udpAddress1 = "pool.ntp.org";
const char * udpAddress2 = "time.nist.gov";
#define TZ "EST+5EDT,M3.2.0/2,M11.1.0/2"
int DOW, MONTH, DATE, YEAR, HOUR, MINUTE, SECOND;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
char strftime_buf[64];
// ---------- esp32 pins --------------
LoRa_E220 e220ttl(&Serial2, 15, 21, 19); // RX AUX M0 M1
//LoRa_E220 e220ttl(&Serial2, 22, 4, 33, 21, 19, UART_BPS_RATE_9600); // esp32 RX <-- e220 TX, esp32 TX --> e220 RX AUX_PIN M0 M1
// -------------------------------------
#define AUX_PIN GPIO_NUM_15
#define RXD1 16
#define TXD1 17
// Replace with your network details
const char *ssid = "R2D2";
const char *password = "sissy4357";
AsyncWebServer server(80);
int data = 2;
// Struct to hold date and time components
struct DateTime {
int year;
int month;
int day;
int hour;
int minute;
int second;
};
// Define the maximum length for the timestamp
const int MAX_TIMESTAMP_LENGTH = 30;
int switchState;
struct Message {
int switchState;
char timestamp[MAX_TIMESTAMP_LENGTH];
}message;
char dtStamp[MAX_TIMESTAMP_LENGTH];
Ticker oneTick;
Ticker onceTick;
String linkAddress = "xxx.xxx.xxx.xxx:80";
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
volatile int watchdogCounter;
int totalwatchdogCounter;
int cameraPowerOff = 0;
int watchDog;
void ISRwatchdog() {
portENTER_CRITICAL_ISR(&mux);
watchdogCounter++;
if (watchdogCounter >= 75) {
watchDog = 1;
}
portEXIT_CRITICAL_ISR(&mux);
}
int cameraFlag;
int needAnotherCountdown = 0;
void ISRcamera() {
batteryOff();
}
bool got_interrupt = false;
void interruptHandler() {
got_interrupt = true;
}
void setup() {
Serial.begin(9600);
delay(500);
Serial1.begin(9600, SERIAL_8N1, RXD1, TXD1);
Serial1.println("Hello, world?");
wifi_Start();
pinMode(AUX_PIN, INPUT);
attachInterrupt(GPIO_NUM_15, interruptHandler, FALLING);
// Startup all pins and UART
e220ttl.begin();
e220ttl.setMode(MODE_1_WOR_TRANSMITTER);
delay(1000);
Serial.println("\nHi, I'm going to send WOR message!");
// Send message
ResponseStatus rs = e220ttl.sendFixedMessage(0, DESTINATION_ADDL, 66, "\nHello, world? WOR!");
// Check If there is some problem of succesfully send
Serial.println(rs.getResponseDescription());
e220ttl.setMode(MODE_0_NORMAL);
delay(1000);
Serial.println("\n\n\nWebserver and");
Serial.println("E220-900T30D Remote Switch\n");
configTime(0, 0, "pool.ntp.org", "time.nist.gov");
// See https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv for Timezone codes for your region
setenv("TZ", "EST+5EDT,M3.2.0/2,M11.1.0/2", 3); // this sets TZ to Indianapolis, Indiana
server.on("/relay", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send_P(200, PSTR("text/html"), HTML7, processor7);
data = 1;
needAnotherCountdown = 1;
countdownTrigger();
});
server.begin();
oneTick.attach(1.0, ISRwatchdog); //watchdog ISR triggers every 1 second
}
void loop() {
DateTime currentDateTime = getCurrentDateTime();
if((currentDateTime.minute % 15 == 0) && (currentDateTime.second == 0)){
//webInterface(); //Sends URL Get request to wake up Radio and ESP32 at 1 minute interval
// URL = http://10.0.0.27/relay
//delay(1000);
}
//udp only send data when connected
if (connected)
{
//Send a packet
udp.beginPacket(udpAddress1, udpPort);
udp.printf("Seconds since boot: %u", millis() / 1000);
udp.endPacket();
}
// If something available
if (e220ttl.available() > 1) {
// read the String message
ResponseContainer rc = e220ttl.receiveMessage();
// Is something goes wrong print error
if (rc.status.code != 1) {
Serial.println(rc.status.getResponseDescription());
} else {
// Print the data received
Serial.println(rc.status.getResponseDescription());
Serial.println(rc.data);
}
}
if (Serial1.available()) {
Message message;
// Read switch state (assuming data is a single byte)
message.switchState = Serial1.read();
// Get timestamp (assuming a string format)
String timestamp = get_time(); // Replace with your timestamp function
timestamp.toCharArray(message.timestamp, MAX_TIMESTAMP_LENGTH);
message.timestamp[0] = Serial1.read();
// Send message
ResponseStatus rs = e220ttl.sendFixedMessage(0, DESTINATION_ADDL, 66, &message, sizeof(Message));
// Check for successful send
Serial.println(rs.getResponseDescription());
}
}
String processor7(const String &var) {
//index7.h
if (var == F("LINK"))
return linkAddress;
return String();
}
void batteryOff() {
int data = 2;
switchOne(data);
oneTick.detach();
}
void configTime()
{
configTime(0, 0, udpAddress1, udpAddress2);
setenv("TZ", "EST+5EDT,M3.2.0/2,M11.1.0/2", 3); // this sets TZ to Indianapolis, Indiana
tzset();
//udp only send data when connected
if (connected)
{
//Send a packet
udp.beginPacket(udpAddress1, udpPort);
udp.printf("Seconds since boot: %u", millis() / 1000);
udp.endPacket();
}
Serial.print("wait for first valid timestamp");
while (time(nullptr) < 100000ul)
{
Serial.print(".");
delay(5000);
}
Serial.println("\nSystem Time set\n");
get_time();
Serial.println(message.timestamp);
}
void countdownTrigger() {
// Perform countdown actions here
Serial.println("\nCountdown timer triggered!\n");
//getDateTime();
// Schedule the next countdown if needed
if (needAnotherCountdown == 1) {
onceTick.once(60, ISRcamera);
int data = 1;
switchOne(data);
needAnotherCountdown = 0;
}
}
// Function to get current date and time
DateTime getCurrentDateTime() {
DateTime currentDateTime;
time_t now = time(nullptr);
struct tm *ti = localtime(&now);
// Extract individual components
currentDateTime.year = ti->tm_year + 1900;
currentDateTime.month = ti->tm_mon + 1;
currentDateTime.day = ti->tm_mday;
currentDateTime.hour = ti->tm_hour;
currentDateTime.minute = ti->tm_min;
currentDateTime.second = ti->tm_sec;
return currentDateTime;
}
// Function to get the timestamp
String get_time() {
time_t now;
time(&now);
char time_output[MAX_TIMESTAMP_LENGTH];
strftime(time_output, MAX_TIMESTAMP_LENGTH, "%a %m/%d/%y %T", localtime(&now));
return String(time_output); // returns timestamp in the specified format
}
void switchOne(int data) {
if (data == 1) {
int data = 1;
Serial.println("\nBattery Switch is ON");
Serial.println("ESP32 waking from Deep Sleep\n");
}
if (data == 2) {
int data = 2;
Serial.println("\nBattery power switched OFF");
Serial.println("ESP32 going to Deep Sleep\n");
}
Serial.println("Hi, I'm going to send message!");
get_time();
Message message;
//initialize struct members
message.switchState = data;
// Initialize the timestamp
String timestamp = get_time();
timestamp.toCharArray(message.timestamp, MAX_TIMESTAMP_LENGTH);
Serial.print("TimeStamp: "); Serial.println(message.timestamp);
// Send message
ResponseStatus rs = e220ttl.sendFixedMessage(0, DESTINATION_ADDL, 66, &message, sizeof(Message));
// Check If there is some problem of succesfully send
Serial.println(rs.getResponseDescription());
}
void webInterface() {
//getTimeDate();
String data = "http://10.0.0.27/relay";
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http; // Declare object of class HTTPClient
http.begin(data); // Specify request destination
// No need to add content-type header for a simple GET request
int httpCode = http.GET(); // Send the GET request
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString(); // Get the response payload
Serial.print("HttpCode: ");
Serial.print(httpCode); // Print HTTP return code
Serial.println("\n");
//Serial.print(" Data echoed back from Hosted website: ");
//Serial.println(payload); // Print payload response
http.end(); // Close HTTPClient
} else {
Serial.print("HttpCode: ");
Serial.print(httpCode); // Print HTTP return code
Serial.println(" URL Request failed.");
http.end(); // Close HTTPClient
}
} else {
Serial.println("Error in WiFi connection");
}
}
void wifi_Start() {
//Server settings
#define ip { 10, 0, 0, 27}
#define subnet \
{ 255, 255, 255, 0 }
#define gateway \
{ 10, 0, 0, 1 }
#define dns \
{ 10, 0, 0, 1 }
WiFi.mode(WIFI_AP_STA);
Serial.println();
Serial.print("MAC: ");
Serial.println(WiFi.macAddress());
// We start by connecting to WiFi Station
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
delay(1000);
//setting the static addresses in function "wifi_Start
IPAddress ip;
IPAddress gateway;
IPAddress subnet;
IPAddress dns;
WiFi.config(ip, gateway, subnet, dns);
Serial.println("Web server running. Waiting for the ESP32 IP...");
// Printing the ESP IP address
Serial.print("Server IP: ");
Serial.println(WiFi.localIP());
Serial.print("Port: ");
Serial.println("80");
Serial.print("MAC: ");
Serial.println(WiFi.macAddress());
Serial.print("Wi-Fi Channel: ");
Serial.println(WiFi.channel());
Serial.println("\n");
delay(500);
WiFi.waitForConnectResult();
Serial.printf("Connection result: %d\n", WiFi.waitForConnectResult());
server.begin();
if (WiFi.waitForConnectResult() != 3) {
delay(3000);
wifi_Start();
}
}
void printParameters(struct Configuration configuration) {
DEBUG_PRINTLN("----------------------------------------");
DEBUG_PRINT(F("HEAD : ")); DEBUG_PRINT(configuration.COMMAND, HEX);DEBUG_PRINT(" ");DEBUG_PRINT(configuration.STARTING_ADDRESS, HEX);DEBUG_PRINT(" ");DEBUG_PRINTLN(configuration.LENGHT, HEX);
DEBUG_PRINTLN(F(" "));
DEBUG_PRINT(F("AddH : ")); DEBUG_PRINTLN(configuration.ADDH, HEX);
DEBUG_PRINT(F("AddL : ")); DEBUG_PRINTLN(configuration.ADDL, HEX);
DEBUG_PRINTLN(F(" "));
DEBUG_PRINT(F("Chan : ")); DEBUG_PRINT(configuration.CHAN, DEC); DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.getChannelDescription());
DEBUG_PRINTLN(F(" "));
DEBUG_PRINT(F("SpeedParityBit : ")); DEBUG_PRINT(configuration.SPED.uartParity, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.SPED.getUARTParityDescription());
DEBUG_PRINT(F("SpeedUARTDatte : ")); DEBUG_PRINT(configuration.SPED.uartBaudRate, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.SPED.getUARTBaudRateDescription());
DEBUG_PRINT(F("SpeedAirDataRate : ")); DEBUG_PRINT(configuration.SPED.airDataRate, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.SPED.getAirDataRateDescription());
DEBUG_PRINTLN(F(" "));
DEBUG_PRINT(F("OptionSubPacketSett: ")); DEBUG_PRINT(configuration.OPTION.subPacketSetting, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.OPTION.getSubPacketSetting());
DEBUG_PRINT(F("OptionTranPower : ")); DEBUG_PRINT(configuration.OPTION.transmissionPower, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.OPTION.getTransmissionPowerDescription());
DEBUG_PRINT(F("OptionRSSIAmbientNo: ")); DEBUG_PRINT(configuration.OPTION.RSSIAmbientNoise, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.OPTION.getRSSIAmbientNoiseEnable());
DEBUG_PRINTLN(F(" "));
DEBUG_PRINT(F("TransModeWORPeriod : ")); DEBUG_PRINT(configuration.TRANSMISSION_MODE.WORPeriod, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.TRANSMISSION_MODE.getWORPeriodByParamsDescription());
DEBUG_PRINT(F("TransModeEnableLBT : ")); DEBUG_PRINT(configuration.TRANSMISSION_MODE.enableLBT, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.TRANSMISSION_MODE.getLBTEnableByteDescription());
DEBUG_PRINT(F("TransModeEnableRSSI: ")); DEBUG_PRINT(configuration.TRANSMISSION_MODE.enableRSSI, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.TRANSMISSION_MODE.getRSSIEnableByteDescription());
DEBUG_PRINT(F("TransModeFixedTrans: ")); DEBUG_PRINT(configuration.TRANSMISSION_MODE.fixedTransmission, BIN);DEBUG_PRINT(" -> "); DEBUG_PRINTLN(configuration.TRANSMISSION_MODE.getFixedTransmissionDescription());
DEBUG_PRINTLN("----------------------------------------");
}
void printModuleInformation(struct ModuleInformation moduleInformation) {
Serial.println("----------------------------------------");
DEBUG_PRINT(F("HEAD: ")); DEBUG_PRINT(moduleInformation.COMMAND, HEX);DEBUG_PRINT(" ");DEBUG_PRINT(moduleInformation.STARTING_ADDRESS, HEX);DEBUG_PRINT(" ");DEBUG_PRINTLN(moduleInformation.LENGHT, DEC);
Serial.print(F("Model no.: ")); Serial.println(moduleInformation.model, HEX);
Serial.print(F("Version : ")); Serial.println(moduleInformation.version, HEX);
Serial.print(F("Features : ")); Serial.println(moduleInformation.features, HEX);
Serial.println("----------------------------------------");
}
//E220_Remote_Switch_Receiver.ino
// 6/12/2024 @ 2011 EST
// See library downloads for each library license.
//Project uses Ebyte E220-900T30D, KY002S Bi-stable MOSFET Switch, and INA226 Battery Monitor module.
/*
* EBYTE LoRa E220
* Stay in sleep mode and wait a wake up WOR message
*
* You must configure the address with 0 3 66 with WOR receiver enable
* and pay attention that WOR period must be the same of sender
*
*
* https://mischianti.org
*
* E220 ----- esp32
* M0 ----- 19 (or 3.3v)
* M1 ----- 21 (or GND)
* RX ----- TX2 (PullUP)
* TX ----- RX2 (PullUP)
* AUX ----- 15 (PullUP)
* VCC ----- 3.3v/5v
* GND ----- GND
*
*/
// with this DESTINATION_ADDL 2 you must set
// WOR SENDER configuration to the other device and
// WOR RECEIVER to this device
#define DESTINATION_ADDL 2
// If you want use RSSI uncomment //#define ENABLE_RSSI true
// and use relative configuration with RSSI enabled
//#define ENABLE_RSSI true
#include "Arduino.h"
#include "LoRa_E220.h"
#include <WiFi.h>
#include <time.h>
#include <FS.h>
#include <LittleFS.h>
#include "esp_sleep.h"
#include "driver/gpio.h"
#include "esp_system.h"
#include <rom/rtc.h>
#include "soc/rtc_cntl_reg.h"
#include "soc/rtc.h"
#include "driver/rtc_io.h"
#include <INA226_WE.h>
#include <Wire.h>
// Persisted RTC variable
RTC_DATA_ATTR bool isPowerUp = false;
RTC_DATA_ATTR int bootCount = 0;
RTC_DATA_ATTR bool switch_State = false; // Initially switch is off
const int pulseDuration = 100; // 100 milliseconds (adjust as needed)
#define FREQUENCY_915
#define AUX_PIN GPIO_NUM_15
#define TRIGGER 23 //KY002S MOSFET Bi-Stable Switch
#define ALERT 4 //INA226 Battery Monitor
#define SDA 13
#define SCL 22
#define RXD1 16
#define TXD1 17
#define I2C_ADDRESS 0x40
/* There are several ways to create your INA226 object:
* INA226_WE ina226 = INA226_WE(); -> uses I2C Address = 0x40 / Wire
* INA226_WE ina226 = INA226_WE(I2C_ADDRESS);
* INA226_WE ina226 = INA226_WE(&Wire); -> uses I2C_ADDRESS = 0x40, pass any Wire Object
* INA226_WE ina226 = INA226_WE(&Wire, I2C_ADDRESS);
*/
INA226_WE ina226 = INA226_WE(I2C_ADDRESS);
volatile bool event = false;
void alert() {
event = true;
detachInterrupt(ALERT);
}
// Struct to hold date and time components
struct DateTime {
int year;
int month;
int day;
int hour;
int minute;
int second;
};
// Define the maximum length for the timestamp
const int MAX_TIMESTAMP_LENGTH = 30;
struct Message {
int switchState;
char timestamp[MAX_TIMESTAMP_LENGTH];
};
Message message;
volatile int data = message.switchState;
char dtStamp[MAX_TIMESTAMP_LENGTH];
#define FPM_SLEEP_MAX_TIME 0xFFFFFFF
void callback() {
Serial.println("Callback");
Serial.flush();
}
bool interruptExecuted = false; // Ensure interruptExecuted is volatile
void IRAM_ATTR wakeUp() {
// Do not use Serial on interrupt callback
interruptExecuted = true;
//detachInterrupt(AUX_PIN);
}
void printParameters(struct Configuration configuration);
// ---------- esp8266 pins --------------
//LoRa_E32 e220ttl(RX, TX, AUX, M0, M1); // Arduino RX <-- e22 TX, Arduino TX --> e22 RX
//LoRa_E32 e220ttl(D3, D4, D5, D7, D6); // Arduino RX <-- e22 TX, Arduino TX --> e22 RX AUX M0 M1
//LoRa_E32 e220ttl(D2, D3); // Config without connect AUX and M0 M1
//#include <SoftwareSerial.h>
//SoftwareSerial mySerial(D2, D3); // Arduino RX <-- e22 TX, Arduino TX --> e22 RX
//LoRa_E32 e220ttl(&mySerial, D5, D7, D6); // AUX M0 M1
// -------------------------------------
// ---------- Arduino pins --------------
//LoRa_E32 e220ttl(4, 5, 3, 7, 6); // Arduino RX <-- e22 TX, Arduino TX --> e22 RX AUX M0 M1
//LoRa_E32 e220ttl(4, 5); // Config without connect AUX and M0 M1
//#include <SoftwareSerial.h>
//SoftwareSerial mySerial(4, 5); // Arduino RX <-- e22 TX, Arduino TX --> e22 RX
//LoRa_E32 e220ttl(&mySerial, 3, 7, 6); // AUX M0 M1
// -------------------------------------
// ---------- esp32 pins ----------------
LoRa_E220 e220ttl(&Serial2, 15, 21, 19); // RX AUX M0 M1
//LoRa_E220 e220(&Serial2, 16, 17); // TX, RX pins// esp32 RX <-- e22 TX, esp32 TX --> e22 RX AUX M0 M1
// -------------------------------------
void handleWakeupReason() {
esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();
switch (wakeup_reason) {
case ESP_SLEEP_WAKEUP_EXT0:
Serial.println("Wakeup caused by external signal using RTC_IO");
break;
case ESP_SLEEP_WAKEUP_EXT1:
Serial.println("Wakeup caused by external signal using RTC_CNTL");
break;
case ESP_SLEEP_WAKEUP_TIMER:
Serial.println("Wakeup caused by timer");
break;
case ESP_SLEEP_WAKEUP_TOUCHPAD:
Serial.println("Wakeup caused by touchpad");
break;
case ESP_SLEEP_WAKEUP_ULP:
Serial.println("Wakeup caused by ULP program");
break;
default:
Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason);
break;
}
}
void enterDeepSleep() {
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_ON);
gpio_hold_en(GPIO_NUM_19);
gpio_hold_en(GPIO_NUM_21);
gpio_deep_sleep_hold_en();
Serial.println("Going to sleep now");
esp_deep_sleep_start();
Serial.println("This will never be printed");
}
void setup() {
Serial.begin(9600);
delay(1000);
Serial.println("\n\nE220 Remote Switch Receiver\n");
attachInterrupt(GPIO_NUM_15, wakeUp, FALLING);
// Call the refactored function to handle the wakeup reason
handleWakeupReason();
pinMode(AUX_PIN, INPUT);
esp_sleep_enable_ext0_wakeup(GPIO_NUM_15, 0);
bool fsok = LittleFS.begin(true);
Serial.printf_P(PSTR("\nFS init: %s\n"), fsok ? PSTR("ok") : PSTR("fail!"));
Wire.begin(SDA, SCL);
pinMode(TRIGGER, OUTPUT); //ESP32, GPIO23
pinMode(ALERT, OUTPUT); //ESP32, GPIO4
if (!ina226.init()) {
Serial.println("\nFailed to init INA226. Check your wiring.");
//while(1){}
}
// INA226 configuration
ina226.enableAlertLatch();
ina226.setAlertType(BUS_UNDER, 5.0);
attachInterrupt(digitalPinToInterrupt(ALERT), alert, FALLING);
e220ttl.begin();
e220ttl.setMode(MODE_2_WOR_RECEIVER);
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
if (ESP_SLEEP_WAKEUP_EXT0 == wakeup_reason) {
Serial.println("Waked up from external GPIO!");
gpio_hold_dis(GPIO_NUM_21);
gpio_hold_dis(GPIO_NUM_19);
gpio_deep_sleep_hold_dis();
e220ttl.setMode(MODE_0_NORMAL);
delay(1000);
e220ttl.sendFixedMessage(0, DESTINATION_ADDL, 23, "We have waked up from message, but we can't read It!");
} else {
e220ttl.setMode(MODE_2_POWER_SAVING);
delay(1000);
Serial.println();
Serial.println("Start sleep!");
delay(100);
if (ESP_OK == gpio_hold_en(GPIO_NUM_21)) {
Serial.println("HOLD 21");
} else {
Serial.println("NO HOLD 21");
}
if (ESP_OK == gpio_hold_en(GPIO_NUM_19)) {
Serial.println("HOLD 19");
} else {
Serial.println("NO HOLD 19");
}
gpio_deep_sleep_hold_en();
//Go to sleep now
Serial.println("Going to sleep now");
//esp_deep_sleep_start();
delay(1);
}
// e220ttl.setMode(MODE_0_NORMAL);
// delay(1000);
Serial.println();
Serial.println("Wake and start listening!");
}
// The loop function is called in an endless loop
void loop() {
if (e220ttl.available() > 1) {
Serial.println("\nMessage arrived!");
ResponseStructContainer rsc = e220ttl.receiveMessage(sizeof(Message));
// Is something goes wrong print error
if (rsc.status.code != 1) {
Serial.println(rsc.status.getResponseDescription());
} else {
// Print the data received
Serial.println(rsc.status.getResponseDescription());
struct Message message = *(Message*)rsc.data;
Serial.println(message.switchState); //This prints to monitor
Serial.println(message.timestamp); //This prints to monitor
data = message.switchState;
rsc.close();
Serial.print("data: ");
Serial.println(data);
;
}
e220ttl.setMode(MODE_0_NORMAL);
delay(1000);
ResponseStatus rsSend = e220ttl.sendFixedMessage(0, 3, 66, "We have received the message!");
// Check If there is some problem of succesfully send
Serial.println(rsSend.getResponseDescription());
delay(10);
Serial.println("Gets here 2");
Serial.print("data before interrupt: ");
Serial.println(data);
}
if (interruptExecuted) {
interruptExecuted = false;
//detachInterrupt(AUX_PIN);
Serial.println("WakeUp Callback, AUX pin go LOW and start receive message!\n");
Serial.print("After Interrupt: ");
Serial.println(data);
//------------------------- Task execution ------------------------------
if (data != 1 || 2) {
enterDeepSleep();
}
if (data == 1) {
digitalWrite(TRIGGER, HIGH);
delay(pulseDuration);
digitalWrite(TRIGGER, LOW);
switch_State = digitalRead(TRIGGER); // Read current switch state
Serial.println("\nBattery power switched ON");
Serial.println("ESP32 wake from Deep Sleep\n");
getINA226(dtStamp);
char dtStamp[MAX_TIMESTAMP_LENGTH];
strncpy(dtStamp, message.timestamp, MAX_TIMESTAMP_LENGTH); // Copy timestamp
//logBattery(dtStamp); // Pass temporary copy
enterDeepSleep();
}
if (data == 2) {
digitalWrite(TRIGGER, HIGH);
delay(pulseDuration);
digitalWrite(TRIGGER, LOW);
switch_State = digitalRead(TRIGGER); // Read current switch state
Serial.println("\nBattery power switched OFF");
Serial.println("ESP32 going to Deep Sleep\n");
delay(1000);
enterDeepSleep();
}
if (event) {
digitalWrite(TRIGGER, HIGH);
delay(pulseDuration);
digitalWrite(TRIGGER, LOW);
ina226.readAndClearFlags(); // reads interrupt and overflow flags and deletes them
//getINA226(dtStamp); //displayResults();
attachInterrupt(digitalPinToInterrupt(ALERT), alert, FALLING);
event = false;
digitalWrite(TRIGGER, LOW);
ina226.readAndClearFlags();
enterDeepSleep();
}
//----------------------End Task Execution ------------------------
data = 0;
}
}
int main() {
// Create an instance of the Message struct
Message message;
// Get the timestamp using the get_time function and assign it to the struct member
String timestamp = get_time();
timestamp.toCharArray(message.timestamp, MAX_TIMESTAMP_LENGTH);
// Now you can use message.timestamp as needed...
return 0;
}
// Function to get the timestamp
String get_time() {
time_t now;
time(&now);
char time_output[MAX_TIMESTAMP_LENGTH];
strftime(time_output, MAX_TIMESTAMP_LENGTH, "%a %d-%m-%y %T", localtime(&now));
return String(time_output); // returns timestamp in the specified format
}
void getINA226(const char* dtStamp) {
float shuntVoltage_mV = 0.0;
float loadVoltage_V = 0.0;
float busVoltage_V = 0.0;
float current_mA = 0.0;
float power_mW = 0.0;
ina226.startSingleMeasurement();
ina226.readAndClearFlags();
shuntVoltage_mV = ina226.getShuntVoltage_mV();
busVoltage_V = ina226.getBusVoltage_V();
current_mA = ina226.getCurrent_mA();
power_mW = ina226.getBusPower();
loadVoltage_V = busVoltage_V + (shuntVoltage_mV / 1000);
checkForI2cErrors();
Serial.println(dtStamp);
Serial.print("Shunt Voltage [mV]: ");
Serial.println(shuntVoltage_mV);
Serial.print("Bus Voltage [V]: ");
Serial.println(busVoltage_V);
Serial.print("Load Voltage [V]: ");
Serial.println(loadVoltage_V);
Serial.print("Current[mA]: ");
Serial.println(current_mA);
Serial.print("Bus Power [mW]: ");
Serial.println(power_mW);
if (!ina226.overflow) {
Serial.println("Values OK - no overflow");
} else {
Serial.println("Overflow! Choose higher current range");
}
Serial.println();
// Open a "log.txt" for appended writing
File log = LittleFS.open("/log.txt", "a");
if (!log) {
Serial.println("file 'log.txt' open failed");
}
log.print(dtStamp);
log.print(" , ");
log.print(shuntVoltage_mV, 3);
log.print(" , ");
log.print(busVoltage_V, 3);
log.print(" , ");
log.print(loadVoltage_V, 3);
log.print(" , ");
log.print(current_mA, 3);
log.print(" , ");
log.print(power_mW, 3);
log.println("");
log.close();
}
void checkForI2cErrors() {
byte errorCode = ina226.getI2cErrorCode();
if (errorCode) {
Serial.print("I2C error: ");
Serial.println(errorCode);
switch (errorCode) {
case 1:
Serial.println("Data too long to fit in transmit buffer");
break;
case 2:
Serial.println("Received NACK on transmit of address");
break;
case 3:
Serial.println("Received NACK on transmit of data");
break;
case 4:
Serial.println("Other error");
break;
case 5:
Serial.println("Timeout");
break;
default:
Serial.println("Can't identify the error");
}
if (errorCode) {
while (1) {}
}
}
}
void printParameters(struct Configuration configuration) {
Serial.println("----------------------------------------");
Serial.print(F("HEAD : "));
Serial.print(configuration.COMMAND, HEX);
Serial.print(" ");
Serial.print(configuration.STARTING_ADDRESS, HEX);
Serial.print(" ");
Serial.println(configuration.LENGHT, HEX);
Serial.println(F(" "));
Serial.print(F("AddH : "));
Serial.println(configuration.ADDH, HEX);
Serial.print(F("AddL : "));
Serial.println(configuration.ADDL, HEX);
Serial.println(F(" "));
Serial.print(F("Chan : "));
Serial.print(configuration.CHAN, DEC);
Serial.print(" -> ");
Serial.println(configuration.getChannelDescription());
Serial.println(F(" "));
Serial.print(F("SpeedParityBit : "));
Serial.print(configuration.SPED.uartParity, BIN);
Serial.print(" -> ");
Serial.println(configuration.SPED.getUARTParityDescription());
Serial.print(F("SpeedUARTDatte : "));
Serial.print(configuration.SPED.uartBaudRate, BIN);
Serial.print(" -> ");
Serial.println(configuration.SPED.getUARTBaudRateDescription());
Serial.print(F("SpeedAirDataRate : "));
Serial.print(configuration.SPED.airDataRate, BIN);
Serial.print(" -> ");
Serial.println(configuration.SPED.getAirDataRateDescription());
Serial.println(F(" "));
Serial.print(F("OptionSubPacketSett: "));
Serial.print(configuration.OPTION.subPacketSetting, BIN);
Serial.print(" -> ");
Serial.println(configuration.OPTION.getSubPacketSetting());
Serial.print(F("OptionTranPower : "));
Serial.print(configuration.OPTION.transmissionPower, BIN);
Serial.print(" -> ");
Serial.println(configuration.OPTION.getTransmissionPowerDescription());
Serial.print(F("OptionRSSIAmbientNo: "));
Serial.print(configuration.OPTION.RSSIAmbientNoise, BIN);
Serial.print(" -> ");
Serial.println(configuration.OPTION.getRSSIAmbientNoiseEnable());
Serial.println(F(" "));
Serial.print(F("TransModeWORPeriod : "));
Serial.print(configuration.TRANSMISSION_MODE.WORPeriod, BIN);
Serial.print(" -> ");
Serial.println(configuration.TRANSMISSION_MODE.getWORPeriodByParamsDescription());
Serial.print(F("TransModeEnableLBT : "));
Serial.print(configuration.TRANSMISSION_MODE.enableLBT, BIN);
Serial.print(" -> ");
Serial.println(configuration.TRANSMISSION_MODE.getLBTEnableByteDescription());
Serial.print(F("TransModeEnableRSSI: "));
Serial.print(configuration.TRANSMISSION_MODE.enableRSSI, BIN);
Serial.print(" -> ");
Serial.println(configuration.TRANSMISSION_MODE.getRSSIEnableByteDescription());
Serial.print(F("TransModeFixedTrans: "));
Serial.print(configuration.TRANSMISSION_MODE.fixedTransmission, BIN);
Serial.print(" -> ");
Serial.println(configuration.TRANSMISSION_MODE.getFixedTransmissionDescription());
Serial.println("----------------------------------------");
}
void printModuleInformation(struct ModuleInformation moduleInformation) {
Serial.println("----------------------------------------");
Serial.print(F("HEAD: "));
Serial.print(moduleInformation.COMMAND, HEX);
Serial.print(" ");
Serial.print(moduleInformation.STARTING_ADDRESS, HEX);
Serial.print(" ");
Serial.println(moduleInformation.LENGHT, DEC);
Serial.print(F("Model no.: "));
Serial.println(moduleInformation.model, HEX);
Serial.print(F("Version : "));
Serial.println(moduleInformation.version, HEX);
Serial.print(F("Features : "));
Serial.println(moduleInformation.features, HEX);
Serial.println("----------------------------------------");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment