0

I hope someone can help me. I'm building a GSM water level meter that runs on solar power, using an Arduino pro mini, DS3231 RTC, JSN-SR04T - ULTRASONIC SENSOR, SIM800L along with a DFrobot DFR0535 solar power manager and 3.7V battery...my project worked fine before I added the RTC...it connects to blynk server, gets the readings from the ultrasonic sensor, and post them, before going to sleep. I added the RTC in order to use it to wake up the Arduino using the interrupt signal and save some power during the evenings and no sun. Even this works, but the interrupts stop after about 30 mins of firing. At the moment its configured to fire every 5 mins...my serial output looks like this

enter image description here

So at this point the sketch works 100% and does exactly what I need, but unfortunately stops after a few mins? Do i need a pull up resistor somewhere maybe?

Any ideas?

Below is my sketch...any help will be greatly appreciated.

#include <avr/sleep.h>//this AVR library contains the methods that controls the sleep modes
#define interruptPin 2 //Pin we are going to use to wake up the Arduino
#include <DS3232RTC.h>  //RTC Library https://github.com/JChristensen/DS3232RTC
#include <NewPing.h>
#define BLYNK_PRINT Serial
#define TINY_GSM_MODEM_SIM800
#include <TinyGsmClient.h>
#include <SoftwareSerial.h>
#include <BlynkSimpleSIM800.h>
#define SIM800_TX_PIN 9
#define SIM800_RX_PIN 8
#define uS_TO_m_FACTOR 60000000   // Conversion factor for micro seconds to minutes
char auth[] = "a892d375xxxxxx0d5c086d6b1";
char apn[]  = "";
char user[] = "";
char pass[] = "";
const int MAX_DISTANCE = 120;                       //max distance to measure
const int Diameter1 = 110;                                //internal Diameter of tank 1 in cm
const int Depth1 = 110;                                 //total depth of tank 1 in cm , from sensor to base inside
const unsigned int Period = 60000;    //period between pings, in milliseconds. i.e  1 munute = 60,000. max 65535. Want longer? use unsigned long
const int PingPin1 = 6;                          //     GPIO5,  D1
const int EchoPin1 = 7;                        //     GPIO4,  D2
const int Area1 = PI * ((Diameter1 / 2) * (Diameter1 / 2));          //area of base of tank 1
int Litres1, Distance1, WaterDepth1, Decimal, Persentage, battLevel, csq, kill;
String gsmTime, gsmTime1;
#include <SoftwareSerial.h>
SoftwareSerial SerialAT(SIM800_TX_PIN, SIM800_RX_PIN);
TinyGsm modem(SerialAT);
//BlynkTimer timer;
NewPing sonar = NewPing(PingPin1, EchoPin1, MAX_DISTANCE);
//RTC Module global variables
const int time_interval = 5; // Sets the wakeup intervall in minutes


void setup() {
  Serial.begin(115200);//Start Serial 
  delay(1000);

  pinMode(LED_BUILTIN,OUTPUT);//We use the led on pin 13 to indecate when Arduino is A sleep
  pinMode(interruptPin,INPUT_PULLUP);//Set pin d2 to input using the buildin pullup resistor
  digitalWrite(LED_BUILTIN,HIGH);//turning LED on

  // initialize the alarms to known values, clear the alarm flags, clear the alarm interrupt flags
    RTC.setAlarm(ALM1_MATCH_DATE, 0, 0, 0, 1);
    RTC.setAlarm(ALM2_MATCH_DATE, 0, 0, 0, 1);
    RTC.alarm(ALARM_1);
    RTC.alarm(ALARM_2);
    RTC.alarmInterrupt(ALARM_1, false);
    RTC.alarmInterrupt(ALARM_2, false);
    RTC.squareWave(SQWAVE_NONE);
     time_t t; //create a temporary time variable so we can set the time and read the time from the RTC
    t=RTC.get();//Gets the current time of the RTC
    RTC.setAlarm(ALM1_MATCH_MINUTES , 0, minute(t)+time_interval, 0, 0);// Setting alarm 1 to go off 5 minutes from now
    // clear the alarm flag
    RTC.alarm(ALARM_1);
    // configure the INT/SQW pin for "interrupt" operation (disable square wave output)
    RTC.squareWave(SQWAVE_NONE);
    // enable interrupt output for Alarm 1
    RTC.alarmInterrupt(ALARM_1, true);
}


void loop() {
 delay(5000);//wait 5 seconds before going to sleep. In real senairio keep this as small as posible
 Going_To_Sleep();
}

void Going_To_Sleep(){
    sleep_enable();//Enabling sleep mode
    attachInterrupt(0, wakeUp, LOW);//attaching a interrupt to pin d2
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);//Setting the sleep mode, in our case full sleep
    digitalWrite(LED_BUILTIN, LOW); //turning LED off
    time_t t;// creates temp time variable
    t=RTC.get(); //gets current time from rtc
    Serial.println("Sleep  Time: "+String(hour(t))+":"+String(minute(t))+":"+String(second(t)));//prints time stamp on serial monitor
    delay(1000); //wait a second to allow the led to be turned off before going to sleep
    sleep_cpu();//activating sleep mode
    Serial.println("just woke up!");//next line of code executed after the interrupt
    myFunction(); 
    t=RTC.get();
    Serial.println("WakeUp Time: "+String(hour(t))+":"+String(minute(t))+":"+String(second(t)));//Prints time stamp 
    //Set New Alarm
    RTC.setAlarm(ALM1_MATCH_MINUTES , 0, minute(t)+time_interval, 0, 0);

  // clear the alarm flag
  RTC.alarm(ALARM_1);
  }


void wakeUp(){
  Serial.println("Interrrupt Fired");//Print message to serial monitor
   sleep_disable();//Disable sleep mode
  detachInterrupt(0); //Removes the interrupt from pin 2;

}

void myFunction() {
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH); 
  SerialAT.begin(57600);
  delay(1000);// make GPIO8 output low
  Serial.println("Initializing modem...");
  modem.restart();
  Blynk.begin(auth, modem, apn, user, pass);
  delay(1000);
  Distance1 = sonar.ping_cm();                                       //get distance to the top of the water tank 1
  if (Distance1 >= Depth1 || Distance1 == 0 )  Distance1 = Depth1;                   //check it does not go negative
  WaterDepth1 = Depth1 - Distance1;                     //calculate the depth of the water
  Litres1 = ((Depth1 * (PI * (sq(Diameter1 / 2)))) - (Distance1 * (PI * (sq(Diameter1 / 2))))) / 1000;
  Persentage = (Litres1 / 1000.00) * 100;
  battLevel = modem.getBattPercent();
  csq = modem.getSignalQuality();
  Blynk.virtualWrite(V1, WaterDepth1);
  Blynk.virtualWrite(V2, Litres1);
  Blynk.virtualWrite(V3, Litres1 / 10);
  Blynk.virtualWrite(V4, Persentage);
  Blynk.virtualWrite(V5, battLevel);
  Blynk.virtualWrite(V6, csq);
  Serial.println();
  Serial.println();
  Serial.println("Water depth: " + String(WaterDepth1));
  Serial.println("Water distance: " + String(Distance1));
  Serial.println("Litres: " + String(Litres1));
  Serial.println("Percentage: " + String(Persentage));
  Serial.println("Battery: " + String(battLevel));
  Serial.println("Signal Qlty: " + String(csq));
  delay(100);
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
}
  • Do you have pullup resistors on SCL & SDA? – CrossRoads Feb 8 at 13:22
  • nope...directly from the RTC into the pro mini...I got a few 2N2222 & MPS2222A's? Or what would you suggest? – Roelof Loots Feb 8 at 13:36
  • 1
    don't use String class – Juraj Feb 8 at 13:38
  • 4.7K pullups on SCL, SDA are needed for I2C to work. Internal to Atmega328P are insufficient. – CrossRoads Feb 8 at 14:09
  • I think your code just hangs/crashes after some time. Try commenting out sleep_cpu(); and see if it hangs after half an hour. I don't think this has anything to do with sleeping. – Gerben Feb 8 at 16:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.