Hello everyone,
I am developing a project to build a weather station with an Arduino MEGA 2560, with the following components: rain gauge, anenometer, windsock, BME280 and Sht20 sensors. In addition, it also sends data to a MYSQL database via the SIM808 module every 10 minutes. My code is running normally. The problem is that after around 15/20 hours running it just crashes and stops to send data to the database. If I reset the arduino mechanically it sends the data again, but this is not ideal, because the project is installed in a distant place and does not pay off to visit it every 15 hours to unlocked it. Do you guys know how to solve this problem? I'm new to the Arduino’s world, so I know my code isn't perfect but at least it's working. I was looking to make the code a little more dynamic or add something like a watchdog to restart every time the program crashes. Can you guy help me to do something like that?
The code:
#include <SoftwareSerial.h>
#include "DFRobot_SHT20.h"
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
#define TINY_GSM_MODEM_SIM808
#include <TinyGsmClient.h>
SoftwareSerial gprsSerial(10, 11);
Adafruit_BME280 bme; // I2C
// Constants definitions anem.
const float pi = 3.14159265; // Numero pi
int period = 5000; // Tempo de medida(miliseconds) 5000
int radius = 147; // Raio do anemometro(mm)
// Variable definitions ANENOMETRO
unsigned int counter = 0; // magnet counter for sensor
unsigned int RPM = 0; // Revolutions per minute
float speedwind = 0; // Wind speed (Km/h)
//Const def Pluviômetro
#define INTERRUPT_INPUT 3
volatile int pulse_counter_ISR;
int pulse_counter;
// Const def biruta
int pin=0; // A0 entrada do biruta *
float valor =0;
int Winddir =0;
DFRobot_SHT20 sht20;
void setup(){
Serial.begin(4800);
gprsSerial.begin(4800);
gprsSerial.flush();
Serial.flush();
// attach or detach from GPRS service
gprsSerial.println("AT+CGATT?");
delay(100);
toSerial();
// bearer settings
gprsSerial.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");
delay(2000);
toSerial();
// bearer settings
gprsSerial.println("AT+SAPBR=3,1,\"APN\",\"taif\"");
delay(2000);
toSerial();
// bearer settings
gprsSerial.println("AT+SAPBR=0,1");
delay(2000);
gprsSerial.println("AT+SAPBR=1,1");
delay(2000);
toSerial();
//pluviometro
digitalWrite(INTERRUPT_INPUT, HIGH); // activate internal pull-up, so normally input is HIGH
attachInterrupt(INTERRUPT_INPUT - 2, interrupt_handler, FALLING); // count on FALLING edge
//bme280
bool status;
status = bme.begin();
// Anemômetro
pinMode(2, INPUT); // Entrada anemometro *
digitalWrite(2, HIGH); //internall pull-up active
//sensorsolo
sht20.initSHT20(); // Init SHT20 Sensor
}
// Calculo da velocidade wind *************
void windvelocity(){
speedwind = 0;
counter = 0;
attachInterrupt(0, addcount, RISING);
unsigned long millis();
long startTime = millis();
while(millis() < startTime + period) {
}
}
void RPMcalc(){
RPM=((counter)*60)/(period/1000); // Calculate revolutions per minute (RPM)
}
void SpeedWind(){
speedwind = (((4 * pi * radius * RPM)/60) / 1000); // Calculate wind speed on khm/
}
void addcount(){
counter++;
}
// Fim calculo veloc wind
void loop()
{
// PLUVIOMETRO
noInterrupts(); // disable interrupts
pulse_counter=pulse_counter_ISR; // copy volatile variable into normal variable
pulse_counter_ISR=0; // reset ISR counter
interrupts(); // enable interrupts
// Ler anemometro
windvelocity();
RPMcalc();
SpeedWind();
// Ler biruta
String Direc;
valor = analogRead(pin)* (5.0 / 1023.0);
if (valor <= 0.58) {
Winddir = 315;
Direc= "SUDESTE ----> NOROESTE";
}
else if (valor <= 0.65) {
Winddir = 270;
Direc= "LESTE ----> OESTE";
}
else if (valor <= 0.75) {
Winddir = 225;
Direc ="NORDESTE ----> SUDOESTE";
}
else if (valor <= 0.9) {
Winddir = 180;
Direc= "NORTE ----> SUL";
}
else if (valor <= 1.1) {
Winddir = 135;
Direc= "NOROESTE ----> SUDESTE";
}
else if (valor <= 1.3) {
Winddir = 90;
Direc= "OESTE ----> LESTE";
}
else if (valor <= 1.7) {
Winddir = 45;
Direc= "SUDOESTE ----> NORDESTE";
}
else {
Winddir = 000;
Direc = "SUL ----> NORTE";
}
float humd = sht20.readHumidity(); // Read Humidity
float temp = sht20.readTemperature(); // Read Temperature
// initialize http service
gprsSerial.println("AT+HTTPINIT");
delay(2000);
toSerial();
// set http param value
gprsSerial.print("AT+HTTPPARA=\"URL\",\"MEUSERVIDOR//write_data.php?data1=");
gprsSerial.print(getBME('C'));
gprsSerial.print("&data2=");
gprsSerial.print(getBME('K'));
gprsSerial.print("&data3=");
gprsSerial.print(getBME('H'));
gprsSerial.print("&data4=");
gprsSerial.print(getBME('P'));
gprsSerial.print("&data5=");
gprsSerial.print(getBME('A'));
gprsSerial.print("&data6=");
gprsSerial.print(speedwind);
gprsSerial.print("&data7=");
gprsSerial.print(Direc);
gprsSerial.print("&data8=");
gprsSerial.print(temp);
gprsSerial.print("&data9=");
gprsSerial.print(humd);
gprsSerial.print("&data10=");
gprsSerial.print(pulse_counter*0.25);
gprsSerial.println("\"");
delay(2000);
toSerial();
// set http action type 0 = GET, 1 = POST, 2 = HEAD
gprsSerial.println("AT+HTTPACTION=0");
delay(6000);
toSerial();
// read server response
gprsSerial.println("AT+HTTPREAD");
delay(1000);
toSerial();
gprsSerial.println("");
gprsSerial.println("AT+HTTPTERM");
toSerial();
delay(300);
gprsSerial.println("");
delay(600000);
}
void toSerial()
{
while(gprsSerial.available()!=0)
{
Serial.write(gprsSerial.read());
}
}
float getBME(char type)
{
// Robojax.com BME280 Code
float value;
float temp = bme.readTemperature();// read temperature
float pressure = bme.readPressure() / 100.0F; // read pressure
float rel_hum = bme.readHumidity();// read humidity
float alt =bme.readAltitude(SEALEVELPRESSURE_HPA);// read altitude
if(type =='F')
{
value = temp *9/5 + 32;//convert to Fahrenheit
}else if(type =='K')
{
value = temp + 273.15;//convert to Kelvin
}else if(type =='H')
{
value = rel_hum;//return relative humidity
}else if(type =='P')
{
value = pressure;//return pressure
}else if(type =='A')
{
value = alt;//return approximate altitude
}else{
value = temp;// return Celsius
}
return value;
}//getBME
void interrupt_handler()
{
pulse_counter_ISR = pulse_counter_ISR + 1;
}
void printDegree()
{
// Robojax.com Code
Serial.print("\xC2");
Serial.print("\xB0");
}
PHP CODE ON SERVER
<?php
// Prepare variables for database connection
$servername = "myserver";
$database = "mydb";
$username = "myuser";
$password = "mypsw";
// Create connection
$conn = mysqli_connect($servername, $username, $password, $database);
// Check connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
// Prepare the SQL statement
$sql = "INSERT INTO Dados_Estacao(TempC,TempK,UR,Pressao,Altitude,VV,Direc,Temp_solo,Umidade_solo,Precip) VALUES ('".$_GET["data1"]."','".$_GET["data2"]."','".$_GET["data3"]."','".$_GET["data4"]."','".$_GET["data5"]."','".$_GET["data6"]."','".$_GET["data7"]."','".$_GET["data8"]."','".$_GET["data9"]."','".$_GET["data10"]."')";
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "
" . $conn->error;
}