Datalogger + Datum + Tijd + EthernetW5100 + SD

Arduino specifieke Software
Berichten: 68
Geregistreerd: 10 Apr 2013, 11:51

Datalogger + Datum + Tijd + EthernetW5100 + SD

Berichtdoor Enschot » 28 Mei 2013, 15:29

Hallo,

ik ben al enige weken bezig met een datalogger die gedurende elke minuut de datum, tijd, en data op een SD card schrijft.
Deze SD card bevind zich op de Arduino Ethernet card W5100.
Op zich werkt het programma, en doet het wat het moet doen, maar wanneer ik vervolgens de seriele monitor uitschakel, en vervolgens weer inschakel zodat het programma opnieuw opstart gebeurt er niets meer.
Dit heeft blijkbaar iets te maken met het gecombineerde gebruik van de SPI interface die d.m.v. de CS van de ethernet card en de SD card wordt toegewezen aan of het Ethernet gedeelte of het SD card gedeelte.
Natuurlijk heb ik al van alles geprobeert op dit gebied, maar ik krijg dit probleem niet opgelost.
Kan iemand me hierbij helpen?
Hieronder het betreffende programma.

    /*

    The circuit:
    * DHT11 Humidity & Temperature Sensor pin 8
    * SD card attached to SPI bus as follows:
    ** Default CS - pin 10
    ** MOSI - pin 11
    ** MISO - pin 12
    ** CLK - pin 13
    ** CS - pin 4

    created 14 Mei 2013
    modified 21 Mei 2013
    by Frans van Enschot

    This example code is in the public domain.

    */

    #include <SD.h>
    #include <Time.h>
    #include <SPI.h>
    #include <Ethernet.h>
    #include <EthernetUdp.h>

    // On the Ethernet Shield, CS is pin 4. Note that even if it's not
    // used as the CS pin, the hardware CS pin (10 on most Arduino boards,
    // 53 on the Mega) must be left as an output or the SD library
    // functions will not work.

    const int chipSelect = 4;
    const int TM_Living = 2;
    const int TM_Bedroom = 3;
    const int TM_Bathroom = 5;
    const int TM_Hall = 6;
    const int TM_Storage = 7;

    const int timeZone = 1; // Central European Time
    //const int timeZone = -5; // Eastern Standard Time (USA)
    //Const int timeZone = -4; // Eastern Daylight Time (USA)
    //const int timeZone = -8; // Pacific Standard Time (USA)
    //Const int timeZone = -7; // pacific Daylight Time (USA)

    int InputState;
    byte mac[] = {0x00, 0x60, 0xB0, 0xD6, 0xA1, 0xD6};//MAC address for controller
    IPAddress timeServer(132, 163, 4, 101);//time-a.timefreq.bldrdoc.gov NTP server

    EthernetUDP Udp;

    unsigned int localPort = 8888; //local port to listen for UDP packets
    String timedateString = "";

    void setup(){
    // Open serial communications and wait for port to open:
    Serial.begin(9600);

    while (!Serial) {
    ; // wait for serial port to connect.
    }

    // Start Ethernet and UDP
    if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    for (;;);
    }

    Udp.begin(localPort);
    Serial.println("waiting for sync");
    setSyncProvider(getNtpTime);

    Serial.println("Initializing Input/Output");
    pinMode(2, INPUT);//Living
    pinMode(3, INPUT);//Bedroom
    pinMode(5, INPUT);//Bathroom
    pinMode(6, INPUT);//Hall
    pinMode(7, INPUT);//Storage

    Serial.println("Initializing SD card...");
    // make sure that the default chip select pin is set to
    // output, even if you don't use it:
    pinMode(10, OUTPUT);

    // see if the card is present and can be initialized:
    if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
    }
    Serial.println("card initialized.");
    }

    time_t prevDisplay = 0;//when the digital clock was displayed

    void loop()
    {
    // make a string for assembling the data to log:
    String dataString = "";

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

    // read the status of the 5 thermomotors
    InputState = digitalRead(TM_Living);
    if (InputState == HIGH) {dataString += "1";} else {dataString += "0";};
    dataString += ",";
    InputState = digitalRead(TM_Bedroom);
    if (InputState == HIGH) {dataString += "1";} else {dataString += "0";};
    dataString += ",";
    InputState = digitalRead(TM_Bathroom);
    if (InputState == HIGH) {dataString += "1";} else {dataString += "0";};
    dataString += ",";
    InputState = digitalRead(TM_Hall);
    if (InputState == HIGH) {dataString += "1";} else {dataString += "0";};
    dataString += ",";
    InputState = digitalRead(TM_Storage);
    if (InputState == HIGH) {dataString += "1";} else {dataString += "0";};

    // open the file. note that only one file can be open at a time,
    // so you have to close this one before opening another.
    File dataFile = SD.open("datalog.txt", FILE_WRITE);

    // if the file is available, write to it:
    if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
    delay(1000);
    }
    // if the file isn't open, pop up an error:
    else {
    Serial.println("error opening datalog.txt");
    delay(1000);
    }
    }


    void Get_And_Convert_TimeStamp() {
    // digital clock display of the time
    timedateString = "";
    timedateString += hour();
    printDigits(minute());
    printDigits(second());
    timedateString += " ";
    timedateString += day();
    timedateString += "/";
    timedateString += month();
    timedateString += "/";
    timedateString += year();
    timedateString += ' ';
    }

    void printDigits(int digits){
    // utility for digital clock display: prints preceding colon and leading 0
    timedateString += ':';
    if(digits < 10)
    timedateString += '0';
    timedateString += 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();
    }

met vriendelijke groet,
Frans

Advertisement

Berichten: 68
Geregistreerd: 10 Apr 2013, 11:51

Re: Datalogger + Datum + Tijd + EthernetW5100 + SD

Berichtdoor Enschot » 28 Mei 2013, 15:34

Extra informatie.

Wat ik nog ben vergeten te vertelen.
Als ik het SD kaartje er uit haal, en het er vervolgens weer in steek, en daarna het programma weer start door de Seriele monitor op te staarten werkt het programma weer perfect.

grtz frans

Berichten: 68
Geregistreerd: 10 Apr 2013, 11:51

Re: Datalogger + Datum + Tijd + EthernetW5100 + SD

Berichtdoor Enschot » 31 Mei 2013, 11:38

Hoi,

Uiteindelijk heb ik het probleem zelf op kunnen lossen.
Na toevoeging van onderstaande regels aan het begin van de setup() was het probleem opgelost.

pinMode(chipSelect, OUTPUT);
digitalWrite(chipSelect, HIGH);

achteraf erg simpel :oops: :oops: :oops: :oops: :oops: :oops:

Berichten: 68
Geregistreerd: 10 Apr 2013, 11:51

Re: Datalogger + Datum + Tijd + EthernetW5100 + SD

Berichtdoor Enschot » 10 Jul 2013, 10:12

Hoi

Ik ben al weken bezig met onderstaand programma.
In mijn vorige reactie heb ik gemeld dat ik het probleem met de SD kaart op had gelost, en dat was ook zo, maar nu heb ik mijn Arduino Uno uitgewisseld met een Arduino MEGA2560 omdat ik meer geheugen en in/uitgangen nodig heb in de toekomst.
Ik zit nu weer met hetzelfde probleem, maar kan het deze keer niet oplossen.
De eerste keer wordt mijn SD kaart niet herkend, en als ik er vervolgens de kaart uit, en dan weer opnieuw erin steek, en daarna het programma opnieuw start werkt het allemaal wel.
Ik ben nu helemaal aan het einde van mijn latijn. Hopelijk kan iemand mij uit mijn lijden verlossen, en dit probleem oplossen


Code: Alles selecteren
/*
 The circuit:
 * DHT11 Humidity & Temperature Sensor pin 8
 * SD card attached to SPI bus as follows:
 ** Default CS - pin 10
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4
 
 Created  14 Mei 2013
 Modified 09 Jul 2013
 by Frans van Enschot
 
 This example code is in the public domain.
 */

#include <SD.h>
#include <Time.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

//DIO pin used to control the modules CS pin
#define SD_CARD_CD_DIO 4

File dataFile;

// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.

const int TM_Living = 2;
const int TM_Bedroom = 3;
const int TM_Bathroom = 5;
const int TM_Hall = 6;
const int TM_Storage = 7;

// make a string for assembling the data to log:
String dataString = "";

const int timeZone = 1;     // Central European Time
//const int timeZone = -5;  // Eastern Standard Time (USA)
//Const int timeZone = -4;  // Eastern Daylight Time (USA)
//const int timeZone = -8;  // Pacific Standard Time (USA)
//Const int timeZone = -7;  // pacific Daylight Time (USA)

int InputState;
byte mac[] = {0x00, 0x60, 0xB0, 0xD6, 0xA1, 0xD6};//MAC address for controller
IPAddress timeServer(132, 163, 4, 101);//time-a.timefreq.bldrdoc.gov NTP server

EthernetUDP Udp;
time_t prevDisplay = 0;//when the digital clock was displayed 

unsigned int localPort = 8888; //local port to listen for UDP packets
String timedateString = "";

void setup(){
  pinMode(53,OUTPUT);
  digitalWrite(53,HIGH);
 
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
 
  Serial.println("Initializing Input/Output");
  pinMode(TM_Living, INPUT);
  pinMode(TM_Bedroom, INPUT);
  pinMode(TM_Bathroom, INPUT);
  pinMode(TM_Hall, INPUT);
  pinMode(TM_Storage, INPUT);

  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    for (;;);
  }

  Udp.begin(localPort);
  Serial.println("waiting for sync");
  setSyncProvider(getNtpTime);
 
  // see if the card is present and can be initialized:
  if (!SD.begin(SD_CARD_CD_DIO)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
}

void loop(){
  if (timeStatus() != timeNotSet) {
    if (now() != prevDisplay) {//update the display only if time has changed
      prevDisplay = now();
      Get_And_Convert_TimeStamp();
      dataString = timedateString;
      AddDataToDateString();
      WriteDataToSD();
    }
  }
}

void Get_And_Convert_TimeStamp() {
  // digital clock display of the time
  timedateString = "";
  timedateString += hour();
  printDigits(minute());
  printDigits(second());
  timedateString += " ";
  timedateString += day();
  timedateString += "/";
  timedateString += month();
  timedateString += "/";
  timedateString += year();
  timedateString += ' ';
}

void printDigits(int digits){
  // utility for digital clock display: prints preceding colon and leading 0
  timedateString += ':';
  if(digits < 10)
    timedateString += '0';
  timedateString += digits;
}

void AddDataToDateString() {
  // read the status of the 5 thermomotors
  InputState = digitalRead(TM_Living);
  if (InputState == HIGH) {dataString += "1";} else {dataString += "0";};
  dataString += ",";
  InputState = digitalRead(TM_Bedroom);
  if (InputState == HIGH) {dataString += "1";} else {dataString += "0";};
  dataString += ","; 
  InputState = digitalRead(TM_Bathroom);
  if (InputState == HIGH) {dataString += "1";} else {dataString += "0";};
  dataString += ","; 
  InputState = digitalRead(TM_Hall);
  if (InputState == HIGH) {dataString += "1";} else {dataString += "0";};
  dataString += ","; 
  InputState = digitalRead(TM_Storage);
  if (InputState == HIGH) {dataString += "1";} else {dataString += "0";}; 
}

void WriteDataToSD() {
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
    delay(60000);//Wait 1 minute
  } 
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
    delay(1000);
  }
}

/*-------- 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();
}



Met vriendelijke groet,
Frans

Gebruikers-avatar
Berichten: 700
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Datalogger + Datum + Tijd + EthernetW5100 + SD

Berichtdoor pjh » 10 Jul 2013, 12:28

SPI zit bij de MEGA op andere pinnetjes:

MOSI = 51 (niet 11)
MISO = 50 (niet pin 12)
SCK = 52 (niet 13)
SS is altijd vrij om te kiezen.

Misschien dat dat meespeelt?

Berichten: 68
Geregistreerd: 10 Apr 2013, 11:51

Re: Datalogger + Datum + Tijd + EthernetW5100 + SD

Berichtdoor Enschot » 10 Jul 2013, 12:42

Hallo pjh,

Bedankt voor de snelle reactie.
ik denk niet dat de pinning het probleem veroorzaakt.
Wanneer ik de SD kaart er uit haal, en hem er dan weer in stop, en vervolgens het programma weer opstart werkt alles zoals het moet werken.
Start ik daarna het programma weer opnieuw dan ziet hij de SD kaart weer niet.

grtz frans

Gebruikers-avatar
Berichten: 700
Geregistreerd: 05 Mrt 2012, 21:56
Woonplaats: Appingedam

Re: Datalogger + Datum + Tijd + EthernetW5100 + SD

Berichtdoor pjh » 10 Jul 2013, 15:52

Is die delay(60000);//Wait 1 minute
nodig in de writeToSD routine?
Komt raar over, maar geen tijd om alles goed langs te lopen.
Later misschien

Berichten: 68
Geregistreerd: 10 Apr 2013, 11:51

Re: Datalogger + Datum + Tijd + EthernetW5100 + SD

Berichtdoor Enschot » 10 Jul 2013, 18:16

Hallo pjh

Ik schrijf een keer per minuut mijn data naar de SD kaart.

grtz frans

Berichten: 2
Geregistreerd: 13 Jul 2013, 22:50

Re: Datalogger + Datum + Tijd + EthernetW5100 + SD

Berichtdoor pajbootsma » 13 Jul 2013, 23:12

Dag Frans,

SD-card en MEGA ging hier ook niet vanzelf. Op http://arduino.cc/en/Tutorial/CardInfo de volgende code gevonden:

Code: Alles selecteren
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("FAILED.");
    return;
  } else {
    Serial.println("OK.");
  }


Groet!
Peter

Berichten: 68
Geregistreerd: 10 Apr 2013, 11:51

Re: Datalogger + Datum + Tijd + EthernetW5100 + SD

Berichtdoor Enschot » 14 Jul 2013, 10:09

Hallo Peter,

bedankt voor de reactie.
De SD card samen met de Mega is geen probleem.
Het probleem ontstaat pas als je de combinatie SD Mega en de ethenet kaart gaat gebruiken.
Het beste kan je het zelf even uitproberen, en het bijgevoegde programma laten draaien, zodat je kan zien wat ik bedoeld.
De eerste keer werkt het programma zoals bedoeld, maar als ik het daarna nog een keer opstart gaat het fout bij het initialiserenvan de SD card.
Als ik vervolgens de SD card eruit haal, en er daarna weer instop werkt het programma weer zoals het hoort.

grtz frans

Volgende

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 27 gasten