Hi people.
I'm building a weight scale using a HX711 load sensor and a Tinysine GSM Shield on an Arduino UNO.
I want to use it as a beehive scale for measuring the weight of the beehive two times a day and sending a SMS to my phone to inform me about the state of the beehive. I also have included a DHT11 and a DS18B20 sensor for measuring the temperature and humidity inside and outside of the beehive, and a DS1307 RTC for keeping time.
I have pretty much the whole project working as I have built both the metal frame for the load sensor and the Arduino circuit for the sensors.
The code is included below. It is working. The only problem is that it seems that the code or the Arduino kind of gets stuck and the feedback from the Serial monitor appears as below:
Ok, Time = 16:30:34, Date (D/
However, it only seems to be a problem only for the communication between the Arduino and the PC and it does not affect the weighing and SMS part of the code.
What I ask is if you would make any improvements on the code for it to run better.
As you see, I already stopped using the String function and used the dtostrf and strcpy/strcat to convert the several variables to a char array for sending the SMS.
/*
Load Cell
E+ -> RED
E- -> BLACK
A- -> WHITE
A+ -> GREEN
A1 -> HX711 CLK
A0 -> DOUT
5V -> VCC
GND -> GND
*/
#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 DOUT A0
#define CLK A1
#define DHTPIN 4
#define DHTTYPE DHT11
#define ONE_WIRE_BUS 5
HX711 scale(DOUT, CLK);
DHT dht(DHTPIN, DHTTYPE);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float calibration_factor = -42870; // ΕΜ: @29.999kg
//Global variables
float h; // humidity
float t1; // temperature
float t2; // temperature
float w; // weight
float dif; // difference
float lastWeight = 0;
int hour1 = 8; int min1 = 0;
int hour2 = 22; int min2 = 0;
int numdata;
boolean started = false;
char smsbuffer[160];
char n[20];
//debug begin
char sms_position;
char phone_number[20] = "xxxxxxxxxx";
char sms_text[160];
int i = 0;
void setup() {
Serial.begin(9600);
dht.begin();
sensors.begin();
// Serial.println(F("HX711 Calibration"));
// Serial.println(F("Remove all weight from scale"));
// Serial.println(F("After readings begin, place known weight on scale"));
// Serial.println(F("Press a,s,d,f to increase calibration factor by 10,100,1000,10000 respectively"));
// Serial.println(F("Press z,x,c,v to decrease calibration factor by 10,100,1000,10000 respectively"));
// Serial.println(F("Press t for tare"));
scale.set_scale();
scale.tare(); //Reset the scale to 0
long zero_factor = scale.read_average(); //Get a baseline reading
// Serial.print(F("Zero factor: ")); //This can be used to remove the need to tare the scale. Useful in permanent scale projects.
// Serial.println(zero_factor);
readSensors();
delay(500);
readSensors();
}
void loop() {
readTime();
if (((tm.Hour == hour1) & (tm.Minute == min1)) | ((tm.Hour == hour2) & (tm.Minute == min2))) {
startGSM();
readSensors();
sendSMSread();
}
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
}
scale.power_down();
for (int j = 0; j <= 54; j++) {
LowPower.idle(SLEEP_1S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF);
}
LowPower.idle(SLEEP_500MS, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF);
scale.power_up();
}
void readSensors() {
sensors.requestTemperatures(); // Send the command to get temperatures
h = dht.readHumidity();
// DHT11
t1 = dht.readTemperature();
// DS18B20
t2 = sensors.getTempCByIndex(0);
w = scale.get_units(10);
dif = w - lastWeight;
lastWeight = w;
scale.set_scale(calibration_factor);
//Serial.print(F("Reading: "));
//Serial.print(w, 3);
//Serial.print(F(" kg"));
//Serial.print(F(", calibration_factor: "));
//Serial.print(calibration_factor);
//Serial.print(F(", weight difference: "));
//Serial.print(dif, 3);
//Serial.print(F(" kg"));
//Serial.print(F(", T1 (*C): ")); // DHT11
//Serial.print(t1);
//Serial.print(F(", T2 (*C): ")); // DS18B20
//Serial.print(t2);
//Serial.print(F(", H (%): "));
//Serial.print(h);
//Serial.println();
}
void startGSM() {
if (!started)
{
Serial.println(F("GSM Shield testing."));
if (gsm.begin(4800))
{
Serial.println(F("\nstatus=READY"));
started = true;
}
else {
Serial.println(F("\nstatus=IDLE"));
}
}
}
void sendSMSread() {
if ((started) & (i == 0)) {
// convert floats w, dif, t1, t2, h to char arrays with 3 decimal points
char wbuffer[10];
dtostrf(w, 7, 3, wbuffer);
char dbuffer[10];
dtostrf(dif, 7, 3, dbuffer);
char t1buffer[10];
char t2buffer[10];
dtostrf(t1, 5, 2, t1buffer);
dtostrf(t2, 5, 2, t2buffer);
char hbuffer[10];
dtostrf(h, 5, 2, hbuffer);
//
// String msg = String("ZIGARIA 1, Reading: ") + wbuffer + String(" kg, difference: ") + dbuffer + String(" kg, T1 (*C): ") + String(t1) + String(", T2 (*C): ") + String(t2) + String(", H (%): ") + String(h);
// msg.toCharArray(sms_text, 160);
strcpy(sms_text, "ZIGARIA 1, Reading: ");
strcat(sms_text, wbuffer);
strcat(sms_text, " kg, difference: ");
strcat(sms_text, dbuffer);
strcat(sms_text, " kg, T1 (*C): ");
strcat(sms_text, t1buffer);
strcat(sms_text, ", T2 (*C): ");
strcat(sms_text, t2buffer);
strcat(sms_text, ", H (%): ");
strcat(sms_text, hbuffer);
Serial.println(sms_text);
delay(100);
if (sms.SendSMS(phone_number, sms_text)) {
Serial.println(F("\nSMS sent OK"));
i++;
}
}
}
void readTime() {
if (RTC.read(tm)) {
Serial.print(F("Ok, Time = "));
print2digits(tm.Hour);
Serial.write(':');
print2digits(tm.Minute);
Serial.write(':');
print2digits(tm.Second);
Serial.print(", Date (D/M/Y) = ");
Serial.print(tm.Day);
Serial.write('/');
Serial.print(tm.Month);
Serial.write('/');
Serial.print(tmYearToCalendar(tm.Year));
Serial.println();
}
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);
}
Any guidance and suggestions for improvements are welcome.
Thanks in advance.
Ektor