SD+LAN+DHT11

KickStarter
Offline
Зарегистрирован: 08.12.2012

Надо собрать SD+LAN+DHT11. набросал отдельно себе коды, работают нормально, начинаю объединять, и появилась проблема (SD+DHT11)

1 - В serial монитор почему то писало 2 раза о чтении датчика DHT11, потом что то наковырял, перестало, но такое ощущение, что функция myTempDataDHT11 выполняется 2 раза внутри loop, и если не ставить делей между выводом в файл и монитор, то датчик показывает ошибку таймаута.

 

#include <dht11.h>
#include <SdFat.h>

  SdFat sd;
  SdFile myFile;

  dht11 DHT11;

const int selectEthernet = 10;          // выбор ведомого на шилде - Ethernet
const int selectSd = 4;                 // выбор ведомого на шилде - SD

#define DHT11PIN 2
// включим Ethernet
#define SWITCH_TO_W5100 digitalWrite(selectSd,HIGH); digitalWrite(selectEthernet,LOW);
// включим SD
#define SWITCH_TO_SD digitalWrite(selectEthernet,HIGH); digitalWrite(selectSd,LOW);
// выключим и SD и Ethernet
#define ALL_OFF digitalWrite(selectEthernet,HIGH); digitalWrite(selectSd,HIGH);

void setup()
{
   Serial.begin(9600);
  // Initialize SdFat or print a detailed error message and halt
  // Use half speed like the native library.
  // change to SPI_FULL_SPEED for more performance.
  delay(400);  // catch Due reset problem
  SWITCH_TO_SD;
  if (!sd.begin(selectSd, SPI_HALF_SPEED)) sd.initErrorHalt();
}

void loop()
{
   delay(2000);

   uint32_t t = millis()/1000;
   String MyStrTemperature=myTempDataDHT11(DHT11PIN);
   String MyStr;

   delay(500);

   mySDLogString("fer.txt",MyStrTemperature,t);
   delay(500);
   Serial.print(MyStrTemperature);
   Serial.print(";");
   Serial.println(t);
}

String myTempDataDHT11(int mDHT11Pin){
  String result;

   Serial.println("\nTemp-DHT11 Reading...");
   int chk = DHT11.read(DHT11PIN);

   Serial.print("DHT11 Sensor: ");
   switch (chk)
   {
     case DHTLIB_OK: 
                 result = "OK;Sensor:";result = result + mDHT11Pin;result = result + ";Temp:";result = result + DHT11.temperature;
                 result = result + ";Humid%:";result = result + DHT11.humidity;break;
     case DHTLIB_ERROR_CHECKSUM: 
                 Serial.println("Checksum error");
                 result = "ErrCS;Sensor:";result = result + mDHT11Pin;result = result + ";0;0";break;
     case DHTLIB_ERROR_TIMEOUT: 
                 Serial.println("Time out error"); 
                 result = "ErrTO;Sensor:";result = result + mDHT11Pin;result = result + ";0;0";break;
     default: 
                 Serial.println("Unknown error"); 
                 result = "ErrUNK;Sensor:"; result = result + mDHT11Pin; result = result + ";0;0"; break;
   }
  return result;
}

void mySDLogString(String MFileName, String DataStr, uint32_t TimeFromStart){

  // выберем ведомого SPI = включим SD        
  SWITCH_TO_SD;
  // open the file for write at end like the Native SD library
  if (!myFile.open("fer.csv", O_RDWR | O_CREAT | O_AT_END)) {
    sd.errorHalt("opening %file% for write failed");
    Serial.print("ERROR file Open!");
    Serial.print(MFileName);
    //return "FAIL";
  }
  // if the file opened okay, write to it:
  Serial.print("Writing to file...");
  Serial.println(TimeFromStart);
  myFile.print(DataStr);
  myFile.println(";");
  myFile.println(TimeFromStart);
  myFile.println(";");
  myFile.close();
  ALL_OFF;
  //return "OK";
}

 

Life23
Offline
Зарегистрирован: 10.08.2013

Я сам не "шарю" в програмировании, но интересно. Меня че-то смущает строчка 48. Разве функцию можно "обзывать" String а не void?

P.S. И нажмите в IDE Ctrl+T - не возможно же код читать..

maksim
Offline
Зарегистрирован: 12.02.2012

Life23 пишет:

Разве функцию можно "обзывать" String а не void?

Можно.

TevatroN
Offline
Зарегистрирован: 17.11.2013

Этот DHT11 тот еще геморой, ошибки часто выдавал, стандартные либы к нему тоже, была у меня одна нестандартная либа которая работала с этим датчиком без проблем, уже затерялась, так как уже имею DHT22 и не имею проблем.

KickStarter
Offline
Зарегистрирован: 08.12.2012

После перехода на новую версию 1.0.4 данная проблема исчезла, но по ходу добавления NTP клиента, снова стал проявляться какой то глюк, в сериал и в файл не выводится часть инфа от датчика, хотя вэб сервер нормально отображает.

TevatroN
Offline
Зарегистрирован: 17.11.2013

Могу повторить ваш вариант если код скините, может смогу помоч. UNO+W5100_SD+DHT11?

   

 

KickStarter
Offline
Зарегистрирован: 08.12.2012

Конечно, был бы благодарен. Может памяти не хватает, я ещё мало работаю с ардуино, не опытен. Если в моём коде что ниже, что то добавить в loop, то часть данных от датчика не выводятся (например добавить ещё обработку по другому интервалу millis)

 

#include <Time.h>
#include <SPI.h>
#include <Ethernet.h>
#include <dht11.h>
#include <SdFat.h>
#include <EthernetUdp.h>


/*-----( Declare Constants and Pin Numbers )-----*/
SdFat sd;
SdFile myFile;
dht11 DHT11;  //The Sensor Object

const int selectEthernet = 10;          // выбор ведомого на шилде - Ethernet
const int selectSd = 4;                 // выбор ведомого на шилде - SD

const int NTP_PACKET_SIZE= 48;            // NTP time stamp is in the first 48 bytes of the message  
byte packetBuffer[NTP_PACKET_SIZE];       // buffer to hold incoming and outgoing packets  
EthernetUDP Udp;
IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov NTP server
const unsigned long seventyYears = 2208988800UL;     
unsigned long epoch = seventyYears;
// const unsigned long UTCcorrection = 7200; // CET = UTC + 1 (+2 in summer):  (HOW to properly calculate DST?)
const unsigned long UTCcorrection = 7200*3;    // keep UTC
unsigned int localPort = 8989;            // local port to listen for UDP packets


#define DHT11PIN 2  // The Temperature/Humidity sensor
// включим Ethernet
#define SWITCH_TO_W5100 digitalWrite(selectSd,HIGH); digitalWrite(selectEthernet,LOW);
// включим SD
#define SWITCH_TO_SD digitalWrite(selectEthernet,HIGH); digitalWrite(selectSd,LOW);
// выключим и SD и Ethernet
#define ALL_OFF digitalWrite(selectEthernet,HIGH); digitalWrite(selectSd,HIGH);


// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {  
  0x74,0x69,0x69,0x2D,0x35,0x31 };
byte ip[] = { 
  192, 168, 1, 11 };
byte dnS[] = { 
  192, 168, 1, 1 };
byte gateway[] = { 
  192, 168, 1, 1 };

long prevmicros = 0;//переменная для хранения значений таймера
long prevmicros2 = 0;//переменная для хранения значений таймера2


// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);

/*-----( Declare Variables )-----*/



void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  delay(400);  // catch Due reset problem

  // Задаем режим работы портов  
  pinMode(selectEthernet, OUTPUT);
  pinMode(selectSd, OUTPUT);
  // высокий уровень на обоих - не выбран ведомый на SPI
  digitalWrite(selectEthernet, HIGH);
  digitalWrite(selectSd, HIGH);

  SWITCH_TO_SD;
  if (!sd.begin(selectSd, SPI_HALF_SPEED)) sd.initErrorHalt();

  SWITCH_TO_W5100;
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, dnS, gateway);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

    //000UDPNTP
    ntpTimeSync();

  //Serial.print("Free RAM=");  Serial.println(freeRam(), DEC); 
}


void loop()
{

  if (micros() - prevmicros >(499210*2*3*1))
  {    
    prevmicros = micros();  //принимает значение каждые полсекунды
    String MyStrTemperature=myTempDataDHT11(DHT11PIN);
    mySDLogString("ferm0.csv",MyStrTemperature);
    Serial.print(MyStrTemperature);
    Serial.println(";");

    Serial.print("\nTIME:");
    Serial.print(getDateString());
    Serial.print(" ");
    Serial.println(getTimeString());
  }

/*  if (micros() - prevmicros2 >(499210*2*30*1))
  {    
    prevmicros2 = micros();  //принимает значение каждые полсекунды
    //000UDPNTP
    Serial.print("\nTIMEOLD:");
    Serial.print(getDateString());
    Serial.print(" ");
    Serial.println(getTimeString());
    ntpTimeSync();
    Serial.print("\nTIMENew:");
    Serial.print(getDateString());
    Serial.print(" ");
    Serial.println(getTimeString());
  }
*/

  WebSRVM();

}



String myTempDataDHT11(int mDHT11Pin){
  String result;

  Serial.println("\nTemp-DHT11 Reading...");
  int chk = DHT11.read(DHT11PIN);
  delay(50);

  Serial.print("DHT11 Sensor: ");
  switch (chk)
  {
  case DHTLIB_OK: 
    result = "OK;Sens:";
    result = result + mDHT11Pin;
    result = result + ";T:";
    result = result + DHT11.temperature;
    result = result + ";H:";
    result = result + DHT11.humidity;
    break;
  case DHTLIB_ERROR_CHECKSUM: 
    Serial.println("Checksum error");
    result = "ErrCS;Sensor:";
    result = result + mDHT11Pin;
    result = result + ";0;0"; 
    break;
  case DHTLIB_ERROR_TIMEOUT: 
    Serial.println("Time out error"); 
    result = "ErrTO;Sensor:";
    result = result + mDHT11Pin;
    result = result + ";0;0"; 
    break;
  default: 
    Serial.println("Unknown error"); 
    result = "ErrUNK;Sensor:"; 
    result = result + mDHT11Pin; 
    result = result + ";0;0"; 
    break;
  }
  return result;
}

void mySDLogString(char* MFileName, String DataStr){

  // выберем ведомого SPI = включим SD        
  SWITCH_TO_SD;
  // open the file for write at end like the Native SD library
  if (!myFile.open(MFileName, O_RDWR | O_CREAT | O_AT_END)) {
    sd.errorHalt("opening %file% for write failed");
    Serial.print("ERROR file Open!");
    Serial.print(MFileName);
    //return "FAIL";
  }
  // if the file opened okay, write to it:
  Serial.print("Writing to file...");
  Serial.println(millis()/1000);
  myFile.print(DataStr);
  myFile.print(";");
  myFile.print(millis()/1000);
  myFile.print(";");
  myFile.print(getDateString());
  myFile.print(";");
  myFile.println(getTimeString());
  myFile.close();

  ALL_OFF;
  //return "OK";
}

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
} 


void WebSRVM() {
  // listen for incoming clients
  SWITCH_TO_W5100;
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          // add a meta refresh tag, so the browser pulls again every 5 seconds:
          client.println("<meta http-equiv=\"refresh\" content=\"5\">");
          client.print("Hi!");   
          client.println("<br />");    

          /*----(Get sensor reading, calculate and print results )-----------------*/

          int chk = DHT11.read(DHT11PIN);

          client.print("Time: ");
          client.print(getDateString());
          client.print(" ");
          client.println(getTimeString());
          client.println("<br />");  


          client.print("Temperature (C): ");
          client.println((float)DHT11.temperature, 1);  
          client.println("<br />");  


          client.print("Humidity (%): ");
          client.println((float)DHT11.humidity, 0);  
          client.println("<br />");   


          /*--------( End Sensor Read )--------------------------------*/
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(10);
    // close the connection:
    client.stop();

    Serial.println("client disonnected");
  }
  //ALL_OFF;
}  

unsigned long 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(); 
}



void ntpTimeSync() {
  //000UDP
  Udp.begin(localPort);

  sendNTPpacket(timeServer); // send an NTP packet to a time server

    // wait to see if a reply is available
  delay(1000);  
  if ( Udp.parsePacket() ) {  
    // We've received a packet, read the data from it
    Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract the two words:
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
    // combine the four bytes (two words) into a long integer this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;  
    const unsigned long seventyYears = 2208988800UL;     
    // subtract seventy years:
    unsigned long epoch = secsSince1900 - seventyYears;  
    //0000SET TIME 
    time_t t = epoch + UTCcorrection;
    setTime(t);    // sets arduino internal clock
    //****SET TIME 
  }

  Udp.stop();
}


String getDateString() {  
  // gives back dd/mm/yyyy  
  time_t t = now();  
  String ss = "";  
  if (day(t) <10) ss = "0";  
  ss = ss + day(t) + "/";  
  if (month(t) <10) ss = ss + "0";  
  ss = ss + month(t) + "/";  
  ss = ss + year(t);  

  return(ss);    
} 

String getTimeString() {
  // gives back hh:mm:ss
  time_t t = now();
  String s = "";
  if (hour(t) <10) s = s + "0";
  s = s + hour(t) + ":";
  if (minute(t) <10) s = s + "0";
  s = s + minute(t) + ":";
  if (second(t) <10) s = s + "0";
  s = s + second(t);
  return(s);
}

 

KickStarter
Offline
Зарегистрирован: 08.12.2012

нет мыслей ни у кого?