ntp and sd card write, incompatible? (probably solved)

Hi!
i am doing a project that needs ntp and logging on a sd, i taken the demo timentp and integrated in my program.
The problem is that i had to put a delay of several seconds between the getNtpTime and the SD.begin, otherwise the ntp fails.
But now the file on the sd gets created but it can't write on it.
for the project i am using a lot of libraries and the pins 2,5,6,7,8 that i think are free to be used
i am not using pins 4,10,11,12,13 that are reserved.
i am also at limits of the program memory (31.347 of 32.256) on the arduino uno (i think i'll have to switch to a mega)

any idea?

any idea?

Where is your code? My crystal ball is not available at the moment.

Here it is

i'm sorry if it's messy but i'm quite new at programming, and had no time to clean it...
here is the first part, since it won't fit in the 9500 chars limit of the forum

here is a detailed description

this project takes the readings from 2 1wire sensors (for now, but it will be 3 or 4) and logs it in the sd with timestamp (timestamp not implemented now)
it also displays it graphically on a servo used as a gauge, with a button to switch between sensors, (a led change color based on first or second sensor)
the readings are presented also via http server
a fan automatically turns on when a certain sensor raises in temperature and turns off if the temperature goes down (that part is present but actually disabled)
the final project is meant for a small server room, other arduino pins would be wired on the air conditioner ir command to control it and some fans would spin up based on general temperature or specifically for temperatures of some equipment that will have sensors attached.

Thank you!

#include <OneWire.h>
#include <DallasTemperature.h>
#include <Servo.h>
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Time.h>
#define ONE_WIRE_BUS 2


OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

//-------------------------ETHERNET-----------------//
byte mac[] = { 
  0x90, 0xA2, 0xDA, 0x0D, 0xD5, 0xB6 }; //physical mac address proto shield
byte ip[] = { 
  192, 168, 5, 235 }; // ip in lan
byte gateway[] = {
  192, 168, 5, 3 }; // internet access via router
byte subnet[] = { 
  255, 255, 255, 0 }; //subnet mask
byte mydns[] = {
  192, 168, 5, 3 };
EthernetServer server(80); //server port

IPAddress timeServer(132, 163, 4, 101);
EthernetUDP Udp;
unsigned int localPort = 8888;
const int timeZone = 1;




String readString;
File MioFile;
Servo myServo;  // create a servo object  
double angle=0;   // variable to hold the angle for the servo motor
double tempind=14;
int selectsens=0;
double temp[]={
  0,0};
int sensnum=0;
double diff=0;
int time=450;

int servopin=8;
int fanpin=3;
int redled=7;
int greenled=6;
int led[]={
  greenled,redled};
int button=5;
time_t prevDisplay = 0;



//------------------------------SETUP----------------------------//
void setup(void)
{

  int x=14;
  //pinMode(fanpin,OUTPUT);
  pinMode(redled,OUTPUT);
  pinMode(greenled,OUTPUT);
  pinMode(button,INPUT);

  Serial.begin(9600);
  Serial.println("INIZIALIZZO");
  myServo.attach(servopin); // attaches the servo on pin 9 to the servo object

  Ethernet.begin(mac, ip, mydns, gateway);
  Udp.begin(localPort);
  setSyncProvider(getNtpTime);
  Serial.println("done");
  server.begin();
  sensors.begin();
  delay(5500);
  SD.begin(4);


  myServo.write(angle);

  //  analogWrite(fanpin,100);
  //  while(x<45)
  //  {
  //
  //    angle = map_double(x, 15, 45, 0, 179);
  //    myServo.write(angle);
  //    x=x+5;
  //    delay(time);
  //
  //}
  digitalWrite(led[selectsens],HIGH);
  //  analogWrite(fanpin,0);

}





//----------------------------------LOOP----------------------//

void loop(void)
{ 

  
  if (timeStatus() != timeNotSet) {
    if (now() != prevDisplay) { //update the display only if time has changed
      prevDisplay = now();
      digitalClockDisplay();
    }
  }




  if(sensnum==0)
  {
    temp[sensnum]=tempTest(sensnum);

    //    Serial.print("sensore ");
    //    Serial.print(sensnum);
    //    Serial.print(" - ");
    //    Serial.print(temp[sensnum]);
    //    Serial.println("C");
    delay(500);
    sensnum=1;
  }

  if(sensnum==1)
  {
    temp[sensnum]=tempTest(sensnum);

    //    Serial.print("sensore ");
    //    Serial.print(sensnum);
    //    Serial.print(" - ");
    //    Serial.print(temp[sensnum]);
    //    Serial.println("C");
    delay(500);
    sensnum=0;
  }

  if (digitalRead(button)==1)
  {
    switch (selectsens) {
    case 0:    // your hand is on the sensor
      digitalWrite(led[selectsens],LOW);
      selectsens=1;
      digitalWrite(led[selectsens],HIGH);
      delay(150);
      break;
    case 1:    // your hand is close to the sensor
      digitalWrite(led[selectsens],LOW);
      selectsens=0;
      digitalWrite(led[selectsens],HIGH);
      delay(150);
    }
  }

  servo(temp[selectsens]);



  writeLog();
  //servePage();


}



//--------------------WRITELOG-----------------------//

void writeLog(void)
{


  MioFile = SD.open("log.txt", FILE_WRITE);

  if (MioFile) 
  {
  while (MioFile.available())
  {
    Serial.write(MioFile.read());
  }
 
  Serial.println("writing");
  MioFile.print(temp[0]);
  MioFile.print(",");
  MioFile.println(temp[1]);
  MioFile.close();
  }
  else {
    Serial.println("error opening datalog.txt");
  } 

}


//-------------------------TEMPTEST------------------------//

double tempTest(int x)
{
  double y=0;
  sensors.requestTemperatures(); // Send the command to get temperatures
  y=sensors.getTempCByIndex(x);
  return y;

}





//---------------------------FANACT----------------------------//
void fanAct(void)
{

  if(temp[sensnum]>tempind){
    tempind=temp[sensnum];
    //    analogWrite(fanpin,200);
    Serial.println("maggiore");
  }


  if(temp[sensnum]<tempind){
    tempind=temp[sensnum];
    analogWrite(fanpin,0);
    Serial.println("minore");
  }


  if(temp[sensnum]==tempind){
    //    tempind=temp[sensnum];
    Serial.println("uguale");
  }



}



//----------------------------------SERVO-------------------------//
void servo(int x)
{
  double angle;
  angle = map_double(x, 15, 45, 0, 179);
  myServo.write(angle);

}


float map_double(double x, double in_min, double in_max, double out_min, double out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

last part

//--------------------------------SERVEPAGE----------------------------//





void servePage(void)
{
  // Create a client connection
  EthernetClient client = server.available();

  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string
          readString += c;
          //Serial.print(c);
        }


        //if HTTP request has ended
        if (c == '\n') {

          Serial.print("il client e'");
          Serial.print(client);


          Serial.println("sending html to client");

          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");

          //client.print("<meta http-equiv=\"refresh\" content=\"4;url=http://home.saglio.net:82\">");

          client.println("<TITLE>Arduino online</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");
          client.println("<H1>Arduino temp</H1>");
          client.println("<hr />");
          client.println("
");

          client.print("Sensore1 ");
          client.print(temp[0]);
          client.println("C");
          client.print("Sensore2 ");
          client.print(temp[1]);
          client.println("C");



          client.println();

          client.println("</H1>");


          client.println("</body>");
          client.println("</html>");

          //stopping client
          client.stop();
          Serial.println("sent html to client, connectiion closed");
          //clearing string for next read
          readString="";
          delay(100);


        }
      }
    }
  } 

}




//--------------------------NTP TIME----------------------//






void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year()); 
  Serial.println(); 
}

void printDigits(int digits){
  // utility for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

/*-------- NTP code ----------*/

const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets

time_t getNtpTime()
{
  while (Udp.parsePacket() > 0) ; // discard any previously received packets
  Serial.println("Transmit NTP Request");
  sendNTPpacket(timeServer);
  uint32_t beginWait = millis();
  while (millis() - beginWait < 1500) {
    int size = Udp.parsePacket();
    if (size >= NTP_PACKET_SIZE) {
      Serial.println("Receive NTP Response");
      Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
      unsigned long secsSince1900;
      // convert four bytes starting at location 40 to a long integer
      secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
    }
  }
  Serial.println("No NTP Response :-(");
  return 0; // return 0 if unable to get the time
}

// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
  
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;
  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:                 
  
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
  
}

If you are using an Uno, the setup() should work better in this order. Initialize the SD first, then the w5100. The SD.begin() call will set D10 to OUTPUT and HIGH, disabling the w5100 by accident, before running the rest of the SD init. It does not do that for the Mega.

  if(!SD.begin(4)) Serial.println(F("SD failed"));
  Ethernet.begin(mac, ip, mydns, gateway);
  Udp.begin(localPort);
  setSyncProvider(getNtpTime);
  Serial.println(F("done"));
  server.begin();

Does that work any better?

Also, use that F() macro on all your static strings like I did in the two Serial.println() calls above. That will save SRAM in the event you are running out, which you should be close to doing.

no, it gives me the same error, nothing changed...

what is the f() in the Serial.println? it's the first time i see it...
yes i'm quite at the limit of SRAM on my uno...

here is the modified setup cleaned up

void setup(void)
{
  int x=14;
  pinMode(redled,OUTPUT);
  pinMode(greenled,OUTPUT);
  pinMode(button,INPUT);

  Serial.begin(9600);
  Serial.println("INIZIALIZZO");
  myServo.attach(servopin);


if(!SD.begin(4)) Serial.println(F("SD failed"));
  Ethernet.begin(mac, ip, mydns, gateway);
  Udp.begin(localPort);
  setSyncProvider(getNtpTime);
  Serial.println(F("done"));
  server.begin();
  sensors.begin();

  myServo.write(angle);
  digitalWrite(led[selectsens],HIGH);
  
}

is there a function to unload udp after i had the correct time? like an inverse of udp.begin()
or close all the ethernet functions and reopen it without udp...

tnx

Here is the basic NTP code I use. It disables the SD so it works ok.
http://forum.arduino.cc/index.php?topic=137789.msg1038071#msg1038071

The only time those are really incompatible is when you run out of SRAM.

The F() macro keeps those static strings in program memory. If you do not use that, the sketch will transfer those to SRAM before using them. That can eat up your SRAM in a hurry.

Thank you, but the ntp code i have actually is ok...
as you say, your code disables the sd card, that is what i really need to log to.

Thank you, but the ntp code i have actually is ok...

Good to hear all is working together now. :slight_smile:

I use them together with NTP and DNS. I use them with the web server code and the FTP code I have in the playground. They are incompatible if not initialized correctly or the device runs out of SRAM.

Ok, it's probably a memory issue, i deactivated the servo and commented the relative code and now the sketch is 29.832 bytes and i can write to the sd while having ntp.
I'll do some more testings bit i think i need an arduino mega for this.

I have the same problem, but I don't know how to solve it. Trying to get NTP and process to have date and time for adding to my variable to a file in SD card. The NTP is got, the file is created on SD card, but nothing inside. If I don't use internet connection everything is fine.
What could be the problem?
Below is size of sketch after compilation, could be this a problem? What the strategy for optimization.
31.072 bytes (din maxim 32.256 bytes)

thank you,

antonio1:
Below is size of sketch after compilation, could be this a problem? What the strategy for optimization.
31.072 bytes (din maxim 32.256 bytes)

Are you using an Uno? If so, you may be running out of SRAM. If you are close to using all the program memory, it is probable that you are running low on SRAM.

Post the sketch code.

edit: If this is a post with your code, stay on that thread.
http://forum.arduino.cc/index.php?topic=175889.0