Proper Timing

Hello there,

I have a problem with timing og Arduino mega2560, first of all i would like to tell You about my project, so lets begin. I have Raspberry pi B+ running apache2, MySQL with HDD and some other stuff and i have 2 arduinos MEGA 2560 one is controlling my terrarium and serving html and also imputing data to MySQL all is controlled by DS3231 with that config i have no issues. the problem is with my other arduino witch is picking data from two ds18B20, two DHT22 and one BMP180 it is showing the data on I2C 4x20 HD44780 display and also it is putting data to MySQL. this arduino is also using DS3231 to controll the time in order to not make the data input in the same time. So for MEGA controlling terrarium the data is inputted every 5th second of minute and as for the other one its 00 second of Minute. I am also syncing both of the DS3231 with NTP server. Both of Arduinos are using WizNET w5100 ethernet shield to comunicate over LAN network.

here is the code of the "faulty" arduino :

#include <SPI.h>
#include <Ethernet.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <DHT.h>
#include <EthernetUdp.h>
#include <Time.h>
#include <DS3231.h>
#include <LiquidCrystal_I2C.h>

// MAC address of ethernet shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xFE, 0xEF, 0xEE }; //physical mac address
IPAddress ip(192,168,0,17); // ip in lan
IPAddress gateway(192,168,0,1); // internet access via router
IPAddress subnet(255,255,255,0); //subnet mask
IPAddress myserver(192,168,0,15); // Servers IP

EthernetClient client;

IPAddress timeServer(194, 146, 251, 100);
const long timeZoneOffset = 3600L;
unsigned int localPort = 8888;
const int NTP_PACKET_SIZE = 48;
byte packetBuffer[NTP_PACKET_SIZE];
EthernetUDP Udp;
unsigned long ntpLastUpdate = 0;
time_t prevDisplay = 0;

DS3231 clock;
RTCDateTime dt;

DHT dht(2, DHT22);
DHT dht_2(5, DHT22);

float tF;
float dP;
float dPF;

unsigned long previousMillis = 0;
const long interval = 3000;

LiquidCrystal_I2C lcd(0x27, 20, 4);  

uint8_t InsideLBitmap[]= { 0x4,0x5,0x7,0x7,0xf,0x19,0x9,0xf };
uint8_t InsidePBitmap[]= { 0x0,0x10,0x18,0x1c,0x1e,0x13,0x12,0x12 };
uint8_t DegreeBitmap[]= { 0x18,0x18,0x3,0x4,0x4,0x4,0x3,0x0 };
uint8_t OutsideLBitmap[]= { 0x0,0x6,0x8,0x8,0x6,0x0,0x1,0x7 };
uint8_t OutsidePBitmap[]= { 0x0,0x0,0x0,0x0,0xe,0x1f,0x1e,0x1c };
uint8_t HumidityBitmap[]= { 0x4,0x4,0xe,0xe,0x1f,0x1f,0x1f,0xe };
uint8_t PressureBitmap[]= { 0x4,0x4,0x4,0x1f,0xe,0x4,0x1f,0x0 };
uint8_t DewPointBitmap[]= { 0x0,0xa,0x15,0x0,0xa,0x15,0x0,0x0 };


Adafruit_BMP085 bmp;


#define ONE_WIRE_BUS 3
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress TempIN = { 0x28, 0x09, 0xDC, 0x76, 0x08, 0x00, 0x00, 0x73 };      
DeviceAddress TempOUT = { 0x28, 0xA1, 0x78, 0x76, 0x08, 0x00, 0x00, 0xA2 };

void setup()
{


 if (!bmp.begin())
 {
    while (1) {}
 }

 lcd.clear();
 lcd.init();
 lcd.backlight();
 lcd.setCursor(0, 0);
   lcd.createChar(1, InsideLBitmap);
 lcd.createChar(2, InsidePBitmap);
        lcd.createChar(3, DegreeBitmap);
        lcd.createChar(4, OutsideLBitmap);
   lcd.createChar(5, OutsidePBitmap);
   lcd.createChar(6, HumidityBitmap);
   lcd.createChar(7, PressureBitmap);

 sensors.begin();
 sensors.setResolution(TempIN, 12);
 sensors.setResolution(TempOUT, 12);

    dht.begin();


    Ethernet.begin(mac, ip, subnet, gateway);  

    clock.begin();
    
    dt = clock.getDateTime();
 int trys = 0;
 while(!getTimeAndDate() && trys < 10 )
 {
 trys++;
 }
}

void(* resetFunc) (void) = 0; //declare reset function @ address 0

void loop(void)
{
 dt = clock.getDateTime();
 if(dt.hour == 04 && dt.minute == 30 && dt.second == 30)
 {
 int trys = 0;
 while(!getTimeAndDate() && trys < 10)
 {
 trys++;
 }
 }
 sensors.requestTemperatures();
 sendWebData();
 LCD();

 delay(100);

}

void sendWebData()
{
 if(dt.second == 00)
 {
 if (client.connect(myserver, 80))
 {
 client.print("GET /write_data.php?");
 client.print("TempIN=");
 client.print(sensors.getTempC(TempIN), 2);
 client.print("&TempOUT=");
 client.print(sensors.getTempC(TempOUT), 2);
 client.print("&Press=");
 client.print(bmp.readPressure() / 100.0, 2);
 client.print("&HumIN=");
 client.print(dht.readHumidity(), 2);
 client.print("&DewIN=");
 client.print(dewPointFast(dht.readTemperature(), dht.readHumidity()));
 client.print("&HumOUT=");
 client.print(dht_2.readHumidity());
 client.print("&DewOUT=");
 client.print(dewPointFast(dht_2.readTemperature(), dht_2.readHumidity()));
 client.println(" HTTP/1.1"); // Part of the GET request
 client.println("Host: 192.168.0.15");
 client.println("Connection: close");
 client.println(); 
 client.println(); 
 client.stop();    
 delay(1000);
 }
 }
}

void LCD()
{
 lcd.setCursor(0, 0);
 lcd.print(F("\001\002")); // Home Icon
 lcd.print(F(":"));   
 lcd.print(sensors.getTempC(TempIN), 1);
 lcd.print(F("\003"));
 
 lcd.setCursor(12, 0);
 lcd.print(F("\004\005")); // Outside Icon
 lcd.print(F(":"));   
 lcd.print(sensors.getTempC(TempOUT), 1);
 lcd.print(F("\003"));
 


 
 if (bmp.readPressure() / 100.0 < 1000)
 {
 lcd.setCursor(12, 3);
 lcd.print(F("\007"));
 lcd.print(F(":"));
 lcd.print(bmp.readPressure() / 100.0, 1); //lcd.print("hPa");
 lcd.setCursor(19, 3);
 lcd.print(F(" "));
 }
 else
 {
 lcd.setCursor(12, 3);
 lcd.print(F("\007"));
 lcd.print(F(":"));
 lcd.print(bmp.readPressure() / 100.0, 1);
 }
 
  unsigned long currentMillis = millis();

            if (currentMillis - previousMillis >= interval) {
            previousMillis = currentMillis;
            

 
 lcd.setCursor(0, 1);
 lcd.print(F("\006\006"));
 lcd.print(F(":"));
 lcd.print(dht.readHumidity(), 1);
 lcd.print(F("% "));
 
 
 lcd.setCursor(0, 2);
 lcd.print(F("Pr"));
 lcd.print(F(":"));
 lcd.print(dewPointFast(dht.readTemperature(), dht.readHumidity()), 1);
 lcd.print(F("\003"));
 
 
 lcd.setCursor(12, 1);
 lcd.print(F("\006\006"));
 lcd.print(F(":"));
 lcd.print(dht_2.readHumidity(), 1);
 lcd.print(F("% "));
 
 
 lcd.setCursor(12, 2);
 lcd.print(F("Pr"));
 lcd.print(F(":"));
 lcd.print(dewPointFast(dht_2.readTemperature(), dht_2.readHumidity()), 1);
 lcd.print(F("\003"));
 
}


int getTimeAndDate()
{
 int flag = 0;
 Udp.begin(localPort);
 sendNTPpacket(timeServer);
 delay(1000);
 if (Udp.parsePacket())
 {
 Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
 unsigned long highWord, lowWord, epoch;
 highWord = word(packetBuffer[40], packetBuffer[41]);
 lowWord = word(packetBuffer[42], packetBuffer[43]);
 epoch = highWord << 16 | lowWord;
 epoch = epoch - 2208988800 + timeZoneOffset;
 flag = 1;
 setTime(epoch);
 ntpLastUpdate = now();
 clock.setDateTime(year(), month(), day(), hour(), minute(), second());
 }
 return flag;
}

unsigned long sendNTPpacket(IPAddress& address)
{
 memset(packetBuffer, 0, NTP_PACKET_SIZE);
 packetBuffer[0] = 0b11100011;
 packetBuffer[1] = 0;
 packetBuffer[2] = 6;
 packetBuffer[3] = 0xEC;
 packetBuffer[12]  = 49;
 packetBuffer[13]  = 0x4E;
 packetBuffer[14]  = 49;
 packetBuffer[15]  = 52;
 Udp.beginPacket(address, 123);
 Udp.write(packetBuffer, NTP_PACKET_SIZE);
 Udp.endPacket();
}

double dewPointFast(double celsius, double humidity)
{
 double a = 17.271;
 double b = 237.7;
 double temp = (a * celsius) / (b + celsius) + log(humidity*0.01);
 double Td = (b * temp) / (a - temp);
 return Td;
}

There are few problems with the code:

  1. sometimes the code is skipping Sending data to MySQL, some times its ok and the data are sended every 1 min and some times after 2 min, 3min.

  2. Sometimes the values of Dew Point or Humidity are represented on LCD as NAN also (but not in the same time ) sometimes those values are represented as 0 in MySQL table

Sorry for my english, hope it is understeandable and i hope somebody here can help me with those issues.
I am also sorry because I've needed to delete nearly all of the comments in the code to keep 9000 character restriction.

There are few problems with the code:

Piss-poor formatting is one of them. Use Tools + Auto Format if you can't keep the indenting straight while typing.

Another problem is functions do things that their names do not suggest that they should be doing. Why in heavens name is LCD() reading the pressure sensor?

void sendWebData()
{
 if(dt.second == 00)

If the first attempt to sync the clock with the NTP server failed, more than one second is wasted before this function is called, so the second value will no longer be 0, so data will not be sent.

But the NTP server sync is only called in setup and then only on 4:30 am

But the NTP server sync is only called in setup and then only on 4:30 am

You are misunderstanding the point being made.

void sendWebData()
{
 if(dt.second == 00)

What are the chances that dt.second == 0 when you are reading the clock each pass through a busy loop with sensor readings and displays?

Why don't you allow the web send to be called in a 5 second window between 30 and 35 seconds. It will be farther away from the other sends on the 5th second and won't need to match the time so precisely.

Shalvan:
But the NTP server sync is only called in setup and then only on 4:30 am

Bullshit.

void loop(void)
{
 dt = clock.getDateTime();
 if(dt.hour == 04 && dt.minute == 30 && dt.second == 30)
 {
 int trys = 0;
 while(!getTimeAndDate() && trys < 10)

What is the name of that function that this code is in?

It's a good thing that you don't want the sync to happen at 8:30 or 9:30.