8266 sd卡 文件web服务器 dht11温度记录sd卡

//20240107改成使用sd卡来记录温湿度信息,因为腾讯的云服务器1年到,续费太贵。
//20220830路由器重启导致无法上传不知卡住何处,故在loop和upload之前都判断下wifi,不通就重连,之前if显然不合适,必须while,下一步如果不行,遇到网络不通的直接esp restart
/*
2024017 2332
实现了从dht11读取数据,并从网上取得网络时间,然后把两个温度湿度加时间写入到sd卡里面,
每隔三秒写一次基,基本已经实现了,下一步要实现的就是把8266做成一个服务器,
然后直接可以从服务器下载了这个文。
*/
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <Wire.h>
#include <DHT.h>

#include <SPI.h>
#include <SD.h>

// 引入 wifi 模块,并实例化,不同的芯片这里的依赖可能不同
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>
WiFiClient espClient; //新添加
HTTPClient http;
WiFiClient client; //新添加

// 设置 wifi 信息
#define WIFI_SSID "xxx"//(这里面连你自己家的WiFi,注意要是2.4G频段的,5G的不行)
#define WIFI_PASSWD "xxxx"//(你自己家的WiFi密码)
const char* host = "server";
#define DHTPIN 3     // Digital pin connected to the DHT sensor
//配置spi信息
#define MOSI  13
#define MISO  12
#define CLK  14
#define CS  15

static bool hasSD = false;
File myFile;
File uploadFile;
ESP8266WebServer server(80);
// Uncomment the type of sensor in use:
#define DHTTYPE    DHT11     // DHT 11
//#define DHTTYPE    DHT22     // DHT 22 (AM2302)
//#define DHTTYPE    DHT21     // DHT 21 (AM2301)


String GetUrl;
String Sdtime;
int sta;
String response;


DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
 if (!SD.begin(12)) {
    Serial.println("sd failed!");
    return;
  }
  Serial.println("sd done.");
  // 初始化 wifi
  wifiInit(WIFI_SSID, WIFI_PASSWD);


  //初始化 iot,需传入 wifi 的 client,和设备产品信息



  Serial.println(F("start"));
  dht.begin();

if (MDNS.begin(host)) {
    MDNS.addService("http", "tcp", 80);
    Serial.println("MDNS responder started");
    Serial.println("You can now connect to http://192.168.4.1");
  }
  
  server.on("/list", HTTP_GET, printDirectory);
  server.on("/edit", HTTP_DELETE, handleDelete);
  server.on("/edit", HTTP_PUT, handleCreate);
  server.on("/edit", HTTP_POST, []() {
    returnOK();
  }, handleFileUpload);
  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");
  // put your main code here, to run repeatedly:


}
void loop() {
  
  
  checkwifi();
  server.handleClient();
  MDNS.update();
      delay(10000);
      Serial.println(F("开始获取网络时间"));
      gettime();
      upload2();




}

// 初始化 wifi 连接
void wifiInit(const char *ssid, const char *passphrase)
{


        //静态地址、网关、子网掩码
    IPAddress local_IP(192, 168, 0, 200);
    IPAddress gateway(192, 168, 0, 1);
    IPAddress subnet(255, 255, 255, 0);
    IPAddress dns1(192,168,0,1);  //太恶心的,不设置dns能连接wifi不能上网。
    
    //设置
    WiFi.config(local_IP, gateway, subnet,dns1);//设置静态IP
   
    WiFi.mode(WIFI_STA);
    WiFi.begin(WIFI_SSID, WIFI_PASSWD);//路由器的WiFi名称和密码
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(1000);
        Serial.println("=init 0x01 WiFi not Connect led red ");

    }
    Serial.println("Connected to AP");
    Serial.println("WIFI SmartConfig Success");
    Serial.printf("SSID:%s", WiFi.SSID().c_str());
    Serial.printf(", PSW:%s\r\n", WiFi.psk().c_str());
    Serial.print("LocalIP:");
    Serial.print(WiFi.localIP());
    Serial.print(" ,GateIP:");
    Serial.println(WiFi.gatewayIP());



}
void checkwifi()
  {
   while (WiFi.status() != WL_CONNECTED) 
      {
        delay(1000);
        Serial.println("=0x02 WiFi not Connect led red ");  
        wifiInit(WIFI_SSID, WIFI_PASSWD);

        ++sta;
        if (sta>=60){
          sta=0;
         ESP.restart();
        } 
    }
  }


void  gettime(){
    String GetUrl = "http://quan.suning.com/getSysTime.do";
    //WiFiClient client; //新添加
     Serial.println(F("开始获取网络时间函数内部"));
    http.setTimeout(5000);
    http.begin(client,GetUrl);
    int httpCode = http.GET();
    if (httpCode > 0) {
      Serial.printf("[HTTP] GET... code: %d\n", httpCode);
      if (httpCode == HTTP_CODE_OK) {
        //读取响应内容
        String response = http.getString();
        Serial.println(response);
        Sdtime="";
        Sdtime=response.substring(13, 32);
        Serial.println(Sdtime);
            }
        }else {Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());}  http.end();
}  
//只是读取dht11 写入sd卡。
void upload2(){
  float h = dht.readHumidity();  
  float t = dht.readTemperature();
  //read temperature and humidity
  if (isnan(h) || isnan(t)) {
    Serial.println("upload2=Failed to read from DHT sensor!");
  }

    swritesd(String(t),String(h),Sdtime);
    Serial.println("sd=sd写入成功!");

}  
void upload(){
  float h = dht.readHumidity();  
  float t = dht.readTemperature();
  //read temperature and humidity
  if (isnan(h) || isnan(t)) {
    Serial.println("upload=Failed to read from DHT sensor!");
  }

    swritesd(String(t),String(h),"2024/01/07  22:22:22");
    Serial.println("sd=sd写入成功!");
    
//写入httpserser
WiFiClient client;
    const int httpPort = 8000;  

  if (!client.connect("49.234.33.166", httpPort)) {
    Serial.println("upload=connection failed");
    //ESP.reset();
    return;
  }


 //String data = "pst=temperature>" + String(random(0,100)) +"||humidity>" + String(random(0,100)) + "||data>text";
 String data="t1="+String(t)+"&t2="+String(h);
 //String data="t1="+String(t)+"&t2="+String(h)+"&t3="+String(WiFi.gatewayIP());
   //Serial.print("Requesting POST: ");
   // Send request to the server:
   client.println("POST / HTTP/1.1");
   client.println("Host:49.234.33.166");
   client.println("Accept: */*");
   client.println("Content-Type: application/x-www-form-urlencoded");
   client.print("Content-Length: ");
   client.println(data.length());
   client.println();
   client.print(data);

   delay(500); // Can be changed
   Serial.println("upload=send to httpserver success ");
 
   if (client.connected()) {
      
      client.stop(); // DISCONNECT FROM THE SERVER
      
      }
  }

void swritesd(String stt, String shh,String sdatetime)
{
  myFile = SD.open("wenshidu.txt", FILE_WRITE);
 
  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to wenshidu.txt...");
    myFile.println(stt+", "+shh+", "+sdatetime);
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
  /*读取sd卡信息。
  //* re-open the file for reading:
  myFile = SD.open("wenshidu.txt");
  if (myFile) {
    Serial.println("wenshidu.txt:");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  } 
  */
}


void returnOK() {
  server.send(200, "text/plain", "");
}

void returnFail(String msg) {
  server.send(500, "text/plain", msg + "\r\n");
}

bool loadFromSdCard(String path) {
  String dataType = "text/plain";
  if (path.endsWith("/")) {
    path += "index.html";
  }

  if (path.endsWith(".src")) {
    path = path.substring(0, path.lastIndexOf("."));
  } else if (path.endsWith(".htm") || path.endsWith(".html")) {
    dataType = "text/html";
  } else if (path.endsWith(".css")) {
    dataType = "text/css";
  } else if (path.endsWith(".js")) {
    dataType = "application/javascript";
  } else if (path.endsWith(".png")) {
    dataType = "image/png";
  } else if (path.endsWith(".gif")) {
    dataType = "image/gif";
  } else if (path.endsWith(".jpg")) {
    dataType = "image/jpeg";
  } else if (path.endsWith(".ico")) {
    dataType = "image/x-icon";
  } else if (path.endsWith(".xml")) {
    dataType = "text/xml";
  } else if (path.endsWith(".pdf")) {
    dataType = "application/pdf";
  } else if (path.endsWith(".zip")) {
    dataType = "application/zip";
  } else if (path.endsWith(".json")) {
    dataType = "application/json";
  }

  File dataFile = SD.open(path.c_str());
  if (dataFile.isDirectory()) {
    path += "/index.htm";
    dataType = "text/html";
    dataFile = SD.open(path.c_str());
  }

  if (!dataFile) {
    return false;
  }

  if (server.hasArg("download")) {
    dataType = "application/octet-stream";
  }

  if (server.streamFile(dataFile, dataType) != dataFile.size()) {
    Serial.println("Sent less data than expected!");
  }

  dataFile.close();
  return true;
}

void deleteRecursive(String path) {
  File file = SD.open((char *)path.c_str());
  if (!file.isDirectory()) {
    file.close();
    SD.remove((char *)path.c_str());
    return;
  }

  file.rewindDirectory();
  while (true) {
    File entry = file.openNextFile();
    if (!entry) {
      break;
    }
    String entryPath = path + "/" + entry.name();
    if (entry.isDirectory()) {
      entry.close();
      deleteRecursive(entryPath);
    } else {
      entry.close();
      SD.remove((char *)entryPath.c_str());
    }
    yield();
  }

  SD.rmdir((char *)path.c_str());
  file.close();
}

void handleCreate() {
  if (server.args() == 0) {
    return returnFail("BAD ARGS");
  }
  String path = server.arg(0);
  if (path == "/" || SD.exists((char *)path.c_str())) {
    returnFail("BAD PATH");
    return;
  }

  if (path.indexOf('.') > 0) {
    File file = SD.open((char *)path.c_str(), FILE_WRITE);
    if (file) {
      file.write((const char *)0);
      file.close();
    }
  } else {
    SD.mkdir((char *)path.c_str());
  }
  returnOK();
}

void handleDelete() {
  if (server.args() == 0) {
    return returnFail("BAD ARGS");
  }
  String path = server.arg(0);
  if (path == "/" || !SD.exists((char *)path.c_str())) {
    returnFail("BAD PATH");
    return;
  }
  deleteRecursive(path);
  returnOK();
}

void handleFileUpload() {
  if (server.uri() != "/edit") {
    return;
  }
  HTTPUpload& upload = server.upload();
  if (upload.status == UPLOAD_FILE_START) {
    if (SD.exists((char *)upload.filename.c_str())) {
      SD.remove((char *)upload.filename.c_str());
    }
    uploadFile = SD.open(upload.filename.c_str(), FILE_WRITE);
    Serial.print("Upload: START, filename: "); Serial.println(upload.filename);
  } else if (upload.status == UPLOAD_FILE_WRITE) {
    if (uploadFile) {
      uploadFile.write(upload.buf, upload.currentSize);
    }
    Serial.print("Upload: WRITE, Bytes: "); Serial.println(upload.currentSize);
  } else if (upload.status == UPLOAD_FILE_END) {
    if (uploadFile) {
      uploadFile.close();
    }
    Serial.print("Upload: END, Size: "); Serial.println(upload.totalSize);
  }
}

void printDirectory() {
  if (!server.hasArg("dir")) {
    return returnFail("BAD ARGS");
  }
  String path = server.arg("dir");
  if (path != "/" && !SD.exists((char *)path.c_str())) {
    return returnFail("BAD PATH");
  }
  File dir = SD.open((char *)path.c_str());
  path.clear();
  if (!dir.isDirectory()) {
    dir.close();
    return returnFail("NOT DIR");
  }
  dir.rewindDirectory();
  server.setContentLength(CONTENT_LENGTH_UNKNOWN);
  server.send(200, "text/json", "");
  WiFiClient client = server.client();

  server.sendContent("[");
  for (int cnt = 0; true; ++cnt) {
    File entry = dir.openNextFile();
    if (!entry) {
      break;
    }

    String output;
    if (cnt > 0) {
      output = ',';
    }

    output += "{\"type\":\"";
    output += (entry.isDirectory()) ? "dir" : "file";
    output += "\",\"name\":\"";
    output += entry.name();
    output += "\"";
    output += "}";
    server.sendContent(output);
    entry.close();
  }
  server.sendContent("]");
  server.sendContent(""); // Terminate the HTTP chunked transmission with a 0-length chunk
  dir.close();
}

void handleNotFound() {
  if (hasSD && loadFromSdCard(server.uri())) {
    return;
  }
  String message = "SDCARD Not Detected\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " NAME:" + server.argName(i) + "\n VALUE:" + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
  Serial.print(message);
}

  

http://192.168.0.200/list?dir=/

http://192.168.0.200/test.txt


 

通过以上路径访问文件夹,访问文件,文件一大就超时,没啥用。setup说好的只执行一次,好像也不是那么稳定,静态ip设置后能访问wifi无法访问ntp,需要指定dns。

=========以下函数有严重的问题。会导致8266 wdt reset,无法解决,=========

void myDelay(int milliseconds) {

  unsigned long startTime = millis(); // 记录函数开始时间

  while (millis() - startTime < milliseconds) {

    // 等待延时时间过去

  }}
//我们定义了一个`blinkLED`函数来实现LED灯的闪烁。该函数接受一个参数,表示延时的毫秒数。通过调用自定义的延时函数`myDelay`
//,我们可以实现不同的延时时间,从而实现LED灯的不同闪烁频率。
 void blinkLED(int milliseconds) {

  digitalWrite(LED_BUILTIN, HIGH); // 点亮LED灯
  

  myDelay(milliseconds); // 延时指定的时间

  digitalWrite(LED_BUILTIN, LOW); // 熄灭LED灯

  myDelay(milliseconds); // 延时指定的时间

}

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值