Skip to content

Instantly share code, notes, and snippets.

@Tech500
Last active March 13, 2024 22:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tech500/7e3ae16a998af52596c2e24dbd949937 to your computer and use it in GitHub Desktop.
Save Tech500/7e3ae16a998af52596c2e24dbd949937 to your computer and use it in GitHub Desktop.
E220_VideoFeed_Remote_Switch --Power switch for video camera to conserve battery
//E220_Transceiver_Videofeed_Receiver.ino
//William Lucid 3/11/2024 @ 17:17 EDT
/*
* EBYTE LoRa E32
* Stay in sleep mode and wait a wake up WOR message
*
* You must configure the address with 0 3 23 with WOR receiver enable
* and pay attention that WOR period must be the same of sender
*
*
* https://mischianti.org
*
* E32 ----- 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 "soc/rtc_cntl_reg.h"
#include "soc/rtc.h"
#include "driver/rtc_io.h"
#define AUX GPIO_NUM_15
#define relayPin 17
struct Message {
int switchState;
} message;
#define FPM_SLEEP_MAX_TIME 0xFFFFFFF
void callback() {
Serial.println("Callback");
Serial.flush();
}
void print_wakeup_reason() {
esp_sleep_wakeup_cause_t wakeup_reason;
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;
}
}
int data;
RTC_DATA_ATTR int bootCount = 0;
bool interruptExecuted = false;
void IRAM_ATTR wakeUp() {
// Do not use Serial on interrupt callback
interruptExecuted = true;
detachInterrupt(AUX);
}
void printParameters(struct Configuration configuration);
// ---------- esp32 pins --------------
LoRa_E220 e220ttl(&Serial2, 15, 21, 19); // RX AUX M0 M1
//LoRa_E32 e220ttl(&Serial2, 22, 4, 18, 21, 19, UART_BPS_RATE_9600); // esp32 RX <-- e22 TX, esp32 TX --> e22 RX AUX M0 M1
// -------------------------------------
//The setup function is called once at startup of the sketch
void setup()
{
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB
}
delay(100);
e220ttl.begin();
e220ttl.setMode(MODE_2_WOR_RECEIVER);
delay(1000);
Serial.println();
Serial.println("Start deep sleep!");
delay(100);
attachInterrupt(AUX, wakeUp, FALLING);
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);
}
}
// The loop function is called in an endless loop
void loop()
{
if (e220ttl.available() > 1) {
Serial.println("Message arrived!");
ResponseStructContainer rsc = e220ttl.receiveMessage(sizeof(Message));
struct Message message = *(Message*)rsc.data;
//Serial.println(*(int*)(message.switchState));
Serial.println(message.switchState);
free(rsc.data);
// Work only with full connection
e220ttl.setMode(MODE_0_NORMAL);
delay(1000);
ResponseStatus rsSend = e220ttl.sendFixedMessage(0, DESTINATION_ADDL, 23, "We have received the message!");
// Check If there is some problem of succesfully send
Serial.println(rsSend.getResponseDescription());
if(interruptExecuted){
Serial.println("WakeUp Callback, AUX pin go LOW and start receive message!");
if (message.switchState == 1) {
digitalWrite(relayPin, HIGH);
Serial.println("\nBattery power switched ON");
Serial.println("ESP32 wake from Deep Sleep\n");
}
if (message.switchState == 2) {
digitalWrite(relayPin, LOW);
Serial.println("\nBattery power switched OFF");
Serial.println("ESP32 going to Deep Sleep");
esp_sleep_enable_ext0_wakeup(GPIO_NUM_15,LOW);
gpio_deep_sleep_hold_en();
//Go to sleep now
Serial.println("Going to sleep now");
esp_deep_sleep_start();
delay(100);
Serial.println("This will never be printed");
}
}
}
}
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("----------------------------------------");
}
// See library downloads for each library license.
// With FIXED SENDER configuration
#define DESTINATION_ADDL 3
#include <Arduino.h>
#include "WiFi.h"
#include "LoRa_E220.h"
#include <AsyncTCP.h>
#include "ESPAsyncWebServer.h"
#include <esp_sleep.h>
#include <Ticker.h>
#import "index7.h" //Video feed HTML; do not remove
// ---------- esp32 pins --------------
LoRa_E220 e220ttl(&Serial2, 15, 21, 19); // RX AUX M0 M1
//LoRa_E220 e220ttl(&Serial2, 22, 4, 18, 21, 19, UART_BPS_RATE_9600); // esp32 RX <-- e220 TX, esp32 TX --> e220 RX AUX M0 M1
// -------------------------------------
#define AUX GPIO_NUM_15
// Replace with your network details
const char *ssid = "XXXX";
const char *password = "XXXXXXXX";
WiFiClient client;
AsyncWebServer server(80);
int data;
struct Message {
int switchState;
} message;
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;
} // interruptHandler
void setup() {
Serial.begin(9600);
delay(500);
// Startup all pins and UART
e220ttl.begin();
e220ttl.setMode(MODE_1_WOR_TRANSMITTER);
Serial.println("Hi, I'm going to send WOR message!");
// Send message
ResponseStatus rs = e220ttl.sendFixedMessage(0, DESTINATION_ADDL, 23, "Hello, world? WOR!");
// Check If there is some problem of succesfully send
Serial.println(rs.getResponseDescription());
// e220ttl.setMode(MODE_0_NORMAL);
// e220ttl.setMode(MODE_0_NORMAL);
Serial.println("\n\n\nWebserver and");
Serial.println("E220-900T30D Transceiver for turning ON Videofeed\n");
wifi_Start();
attachInterrupt(digitalPinToInterrupt(AUX), interruptHandler, FALLING);
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() {
// 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 (Serial.available()) {
message.switchState = data;
message.switchState = Serial.parseInt();
// Send message
ResponseStatus rs = e220ttl.sendFixedMessage(0, 2, 23, &message, sizeof(Message));
// Check If there is some problem of succesfully 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 countdownTrigger() {
// Perform countdown actions here
Serial.println("\nCountdown timer triggered!\n");
// Schedule the next countdown if needed
if (needAnotherCountdown == 1) {
onceTick.once(60, ISRcamera);
int data = 1;
switchOne(data);
needAnotherCountdown = 0;
}
}
void switchOne(int data) {
if (data == 1) {
int data = 1;
message.switchState = data;
Serial.println("Battery Switch is ON");
Serial.println("ESP32 waking from Deep Sleep\n");
}
if (data == 2) {
int data = 2;
message.switchState = data;
Serial.println("Battery power switched OFF");
Serial.println("ESP32 going to Deep Sleep\n");
}
Serial.println("Hi, I'm going to send message!");
// Send message
ResponseStatus rs = e220ttl.sendFixedMessage(0, DESTINATION_ADDL, 23, &message, sizeof(Message));
// Check If there is some problem of succesfully send
Serial.println(rs.getResponseDescription());
}
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("----------------------------------------");
}
//index7.h
const char HTML7[] PROGMEM = R"====(
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="container">
<header>
<br><br>This is original H264 video encoded by IP camera; server doesn't do any transcoding. Wyze Cam v3 video feeds
<br>Wyze-Bridge Docker, container; which provides webRTC video URL. Camera maybe offline; depending on battery discharge state.
<br><br>
</header>
<main>
<iframe class="iframe" width="1300" height="731"src="http://xxxxxx:port/cameraname/" frameborder="0"></iframe>
</main>
<footer>
<h2><a href="server return link goes here... " >ESP32 Server</a></h2>
</footer>
</div>
</body>
</html>
)====";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment