I am working on a project to monitor battery status at a remote location using Blynk 2.0 and the above referenced module. I am no code expert, so this has been quite a ride. Lilygo does offer a somewhat functional Blynk example, so I started with this and a BME 280 just to test functionality and reliability prior to setting up in the field. This module is connected via GSM which has worked fine, but in an effort to reduce power consumption and battery usage, i have added a deep sleep function, as well as a function to power down the modem during deep sleep to reduce power consumption further.
So far all has been relatively reliable, but every two days or so, the unit loses connection to cellular and or Blynk and just hangs, leaving the unit powered up with no way to shut down the unit. This obviously leads to the eventual depletion of the single cell lithium battery.
I’ve posted my code below - is there a way to confirm connection to Blynk server prior to continuing on with the code so it does not get stuck in this frozen state? I’ve done some searching, but most examples focus on Wi-Fi and not GSM… I love to learn and am not looking for someone to give me instant gratification (hence my hobbled together code), but maybe point me in the right direction? Just getting deep sleep and modem power down to function correctly took me a couple of evenings… I’ve included most code in void setup() as it has been explained a number of times on the forum that this is required in order for deep sleep to function correctly on the ESP32…
Thank you in advance!
/* Fill-in your Template ID (only if using Blynk.Cloud) */
#define BLYNK_TEMPLATE_ID "TMPLwidl2O53"
#define BLYNK_DEVICE_NAME "T SIM 7000"
#define BLYNK_AUTH_TOKEN "xxxx";
// Select your modem:
#define TINY_GSM_MODEM_SIM7000
// Default heartbeat interval for GSM is 60
// If you want override this value, uncomment and set this option:
//#define BLYNK_HEARTBEAT 30
#include <TinyGsmClient.h>
#include <BlynkSimpleTinyGSM.h>
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <SD.h>
#include <SPI.h>
#define BMP_SCK 13
#define BMP_MISO 12
#define BMP_MOSI 11
#define BMP_CS 10
#define uS_TO_S_FACTOR 1000000ULL // Conversion factor for micro seconds to seconds
#define TIME_TO_SLEEP 300 // Time ESP32 will go to sleep (in seconds)
Adafruit_BME280 bme; // I2C
BlynkTimer timer;
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = BLYNK_AUTH_TOKEN;
// Your GPRS credentials
// Leave empty, if missing user or pass
char apn[] = "hologram";
char user[] = "";
char pass[] = "";
#define SerialAT Serial1
#define UART_BAUD 115200
#define PIN_DTR 25
#define PIN_TX 27
#define PIN_RX 26
#define PWR_PIN 4
#define LED_PIN 12
#define BAT_ADC 35
#define SOLAR_ADC 36
bool reply = false;
TinyGsm modem(SerialAT);
BLYNK_WRITE(V3) {
if(param.asInt()==1)
{
digitalWrite(LED_PIN, LOW);
Blynk.logEvent("led_off");//Sending Events
}
else{
digitalWrite(LED_PIN, HIGH);
Blynk.logEvent("led_on");//Sending Events
}
}
//Syncing the output state with the app at startup
BLYNK_CONNECTED()
{
Blynk.syncVirtual(V3); // will cause BLYNK_WRITE(V3) to be executed
}
float readBattery(uint8_t pin)
{
int vref = 1100;
uint16_t volt = analogRead(pin);
float battery_voltage = ((float)volt / 4095.0) * 2.0 * 3.3 * (vref);
return battery_voltage;
}
void setup() {
Serial.begin(115200); // Set console baud rate
delay(100);
// Set LED OFF
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
pinMode(PWR_PIN, OUTPUT);
digitalWrite(PWR_PIN, HIGH);
delay(300);
digitalWrite(PWR_PIN, LOW);
Serial.println("\nWait...");
SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX);
// Restart takes quite some time
// To skip it, call init() instead of restart()
Serial.println("Initializing modem...");
if (!modem.restart()) {
Serial.println("Failed to restart modem, attempting to continue without restarting");
}
String name = modem.getModemName();
delay(500);
Serial.println("Modem Name: " + name);
unsigned status;
// default settings
status = bme.begin(0x76);
// You can also pass in a Wire library object like &Wire2
// status = bme.begin(0x76, &Wire2)
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
while (1) delay(10);
}
Blynk.begin(auth, modem, apn, user, pass);
// Setup a function to be called every second
float p = bme.readPressure();
float t = bme.readTemperature(); // or bme.readTemperature(true) for Fahrenheit
float h = bme.readHumidity();
float mv = readBattery(BAT_ADC);
float mvs = readBattery(SOLAR_ADC);
float SLpressure_mB = (((p)/pow((1-((float)(1798.32))/44330), 5.255))/100.0);
float a = bme.readAltitude(SLpressure_mB);
int csq = modem.getSignalQuality();
Serial.print("mv :"); Serial.println(mv);
Serial.print("Pressure :"); Serial.println(h);
Serial.print("Temperature :"); Serial.println(t);
if (isnan(h) || isnan(t)|| isnan(mv)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
// You can send any value at any time.
// Please don't send more that 10 values per second.
Blynk.virtualWrite(V0, t*9/5+32);
Blynk.virtualWrite(V1, p/3389.39);
Blynk.virtualWrite(V2, ((mv/4200)*100));
Blynk.virtualWrite(V4, h);
Blynk.virtualWrite(V5, a*3.2808399);
Blynk.virtualWrite(V6, mvs/1000);
Blynk.virtualWrite(V7, csq);
modem.sendAT("+CPOWD=1");
if (modem.waitResponse(10000L) != 1) {
DBG("+CPOWD=1");
}
modem.poweroff();
Serial.println("Poweroff.");
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
delay(200);
esp_deep_sleep_start();
Blynk.run();
timer.run();
}
void loop() {
}