Hi there.
I am working on building a weight scale which can send messages on preset timestamps, using an Arduino Uno and SIM900 board.
It was running well on previous versions of the code, in which every weight reading was sent right away in a message. But I wanted to send one message with 3 readings, and then the Arduino started crashing and rebooting as I observed in the Serial monitor.
I searched on the web for Arduinos crashing and rebooting, and it seems like a memory issue.
However, the memory used is on ~60% of both the program storage space and the dynamic memory.
I would be greatful to hear any solutions or guidance on how to correct/improve my code.
Thank you in advance.
Ektor
#include "LowPower.h"
#include "HX711.h" //You must have this library in your arduino library folder
#include "DHT.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include "SIM900.h"
#include <SoftwareSerial.h>
#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
#include "sms.h"
SMSGSM sms;
tmElements_t tm;
#define BUZZER 13
#define DOUT A1
#define CLK A0
#define DHTPIN 4
#define DHTTYPE DHT11
#define ONE_WIRE_BUS 5
#define GSM_ON 8
HX711 scale(DOUT, CLK);
DHT dht(DHTPIN, DHTTYPE);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float calibration_factor = 42870;
//Global variables
float h; // humidity
float t; // temperature
float w; // weight
float dif; // difference
float lastWeight = 0;
char scaleName[20] = "ZYGARIA 2";
char rTime[5];
int hour1 = 5; int min1 = 31; //09.00
int hour2 = 5; int min2 = 32; //16.00
int hour3 = 5; int min3 = 33; //22.00
boolean started = false;
char n[20];
//debug begin
char sms_position;
char phone_number[20] = "xxxxxxxxxx";
char sms_text[160];
void setup() {
Serial.begin(9600);
pinMode(GSM_ON, OUTPUT);
pinMode(BUZZER, OUTPUT);
// Save Power by writing all digital IO LOW
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
pinMode(A2, OUTPUT);
pinMode(A3, OUTPUT);
pinMode(A4, OUTPUT);
pinMode(A5, OUTPUT);
dht.begin();
sensors.begin();
scale.set_scale();
scale.tare();
long zero_factor = scale.read_average();
readSensors();
LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF);
readSensors();
}
void loop() {
readTime();
if ((tm.Day == 7) && (tm.Month == 5) && (tm.Hour == 0) && (tm.Minute == 0)) {
refillSMS();
}
if ((tm.Hour == hour1) && (tm.Minute == min1)) {
readSensors();
smsTextNew();
}
if ((tm.Hour == hour2) && (tm.Minute == min2)) {
readSensors();
smsTextConcat();
}
if ((tm.Hour == hour3) && (tm.Minute == min3)) {
startGSM();
scale.power_up();
readSensors();
smsTextConcat();
sendSMSread();
GSMpowerDown();
scale.power_down();
}
if (Serial.available()) {
char temp = Serial.read();
if (temp == '+' || temp == 'a')
calibration_factor += 10;
else if (temp == '-' || temp == 'z')
calibration_factor -= 10;
else if (temp == 's')
calibration_factor += 100;
else if (temp == 'x')
calibration_factor -= 100;
else if (temp == 'd')
calibration_factor += 1000;
else if (temp == 'c')
calibration_factor -= 1000;
else if (temp == 'f')
calibration_factor += 10000;
else if (temp == 'v')
calibration_factor -= 10000;
else if (temp == 't')
scale.tare(); //Reset the scale to zero
}
for (int j = 0; j <= 5; j++) {
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF);
LowPower.powerDown(SLEEP_250MS, ADC_OFF, BOD_OFF);
}
}
void readSensors() {
sensors.requestTemperatures();
scale.set_scale(calibration_factor);
h = dht.readHumidity();
t = sensors.getTempCByIndex(0);
w = scale.get_units(10);
dif = w - lastWeight;
lastWeight = w;
}
void startGSM() {
if (!started)
{
Serial.println(F("GSM Shield testing."));
if (gsm.begin(4800))
{
Serial.println(F("\nstatus=READY"));
started = true;
for (int j = 0; j < 2; j++) {
digitalWrite(BUZZER, HIGH);
LowPower.powerDown(SLEEP_120MS, ADC_OFF, BOD_OFF);
digitalWrite(BUZZER, LOW);
LowPower.powerDown(SLEEP_120MS, ADC_OFF, BOD_OFF);
}
}
else {
Serial.println(F("\nstatus=IDLE"));
}
}
}
void sendSMSread() {
if (started) {
Serial.println(sms_text);
delay(100);
if (sms.SendSMS(phone_number, sms_text)) {
Serial.println(F("\nSMS sent OK"));
for (int j = 0; j < 2; j++) {
digitalWrite(BUZZER, HIGH);
LowPower.powerDown(SLEEP_500MS, ADC_OFF, BOD_OFF);
digitalWrite(BUZZER, LOW);
LowPower.powerDown(SLEEP_500MS, ADC_OFF, BOD_OFF);
}
}
}
}
void smsTextNew() {
char wbuffer[7];
dtostrf(w, 7, 3, wbuffer);
char dbuffer[7];
dtostrf(dif, 7, 3, dbuffer);
char tbuffer[5];
dtostrf(t, 5, 2, tbuffer);
char hbuffer[5];
dtostrf(h, 5, 2, hbuffer);
strcpy(sms_text, scaleName);
strcat(sms_text, ",");
strcat(sms_text, rTime);
strcat(sms_text, ",R:");
strcat(sms_text, wbuffer);
strcat(sms_text, "kg,D:");
strcat(sms_text, dbuffer);
strcat(sms_text, "kg,T:");
strcat(sms_text, tbuffer);
strcat(sms_text, ",H:");
strcat(sms_text, hbuffer);
Serial.println(sms_text);
}
void smsTextConcat() {
char wbuffer[7];
dtostrf(w, 7, 3, wbuffer);
char dbuffer[7];
dtostrf(dif, 7, 3, dbuffer);
char tbuffer[5];
dtostrf(t, 5, 2, tbuffer);
char hbuffer[5];
dtostrf(h, 5, 2, hbuffer);
strcat(sms_text, ",");
strcat(sms_text, rTime);
strcat(sms_text, ",R:");
strcat(sms_text, wbuffer);
strcat(sms_text, "kg,D:");
strcat(sms_text, dbuffer);
strcat(sms_text, "kg,T:");
strcat(sms_text, tbuffer);
strcat(sms_text, ",H:");
strcat(sms_text, hbuffer);
Serial.println(sms_text);
}
void GSMpowerDown() {
digitalWrite(GSM_ON, HIGH);
delay(2000);
digitalWrite(GSM_ON, LOW);
delay(2000);
started = false;
Serial.println("GSM Power Down");
delay(100);
}
void refillSMS() {
if (sms.SendSMS("1252", "91")) {
Serial.println(F("\nRefill SMS sent OK"));
}
}
void readTime() {
if (RTC.read(tm)) {
char timeText[100];
strcpy(timeText, "Ok, Time = ");
char timeTemp[2];
sprintf(timeTemp, "%02d", tm.Hour);
strcat(timeText, timeTemp);
strcpy(rTime, timeTemp);
strcat(timeText, ":");
strcat(rTime, ":");
sprintf(timeTemp, "%02d", tm.Minute);
strcat(timeText, timeTemp);
strcat(rTime, timeTemp);
strcat(timeText, ":");
sprintf(timeTemp, "%02d", tm.Second);
strcat(timeText, timeTemp);
strcat(timeText, ", Date (D/M/Y) = ");
sprintf(timeTemp, "%02d", tm.Day);
strcat(timeText, timeTemp);
strcat(timeText, "/");
sprintf(timeTemp, "%02d", tm.Month);
strcat(timeText, timeTemp);
strcat(timeText, "/");
char yearTemp[4];
sprintf(yearTemp, "%04d", tmYearToCalendar(tm.Year));
strcat(timeText, yearTemp);
Serial.println(timeText);
delay(100);
}
else {
if (RTC.chipPresent()) {
Serial.println(F("The DS1307 is stopped. Please run the SetTime"));
Serial.println(F("example to initialize the time and begin running."));
Serial.println();
}
else {
Serial.println(F("DS1307 read error! Please check the circuitry."));
Serial.println();
}
}
}
void print2digits(int number) {
if (number >= 0 && number < 10) {
Serial.write('0');
}
Serial.print(number);
}
Sketch uses 20402 bytes (63%) of program storage space. Maximum is 32256 bytes.
Global variables use 1245 bytes (60%) of dynamic memory, leaving 803 bytes for local variables. Maximum is 2048 bytes.