查看: 17011|回复: 13

【328P+W5100】在web中读取SD卡的文件

[复制链接]
  • TA的每日心情
    奋斗
    2015-10-30 10:45
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2015-11-14 22:09 | 显示全部楼层 |阅读模式
    本帖最后由 某1o 于 2015-11-14 22:16 编辑

    磨磨唧唧写了一个礼拜,弄出来这个了,总之SD.h这个库是各种玄学。直接上代码!代码有点长 大家可以去github下载项目文件https://github.com/mo10/SDwebserver

    关于请求地址 表单 路径 后缀名截取方法 可以参考http://www.arduino.cn/thread-18012-1-1.html

    注意!访问不要太频繁,在上一个文件未完全关闭的情况下打开下一个文件可能会抽风!代码难免不出错,大家不要喷我~ Debug很累的

    kittenblock中小学创客名师推荐的图形化编程软件

    #include <SPI.h>
    #include <Ethernet.h>
    #include <SD.h>
    
    byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};//mac地址
    IPAddress ip(192, 168, 31, 177);//ip地址
    EthernetServer server(80);//访问端口
    String fakename = "Nginx/1.8.0 (ATmega328p/Ubuntu 12.04 LTS)"; //装逼参数(伪装服务器)
    String res = "", path = "";
    EthernetClient client;
    void setup() {
      Serial.begin(9600);
      while (!Serial) {
        ; // wait for serial port to connect. Needed for Leonardo only
      }
      //启动sd
      Serial.print("init sd:");
      if (!SD.begin(4)) {
        Serial.println("failed");
        return;
      }
      Serial.println("done");
      //启动eth
      Ethernet.begin(mac, ip);
      server.begin();
      Serial.print("ip:");
      Serial.println(Ethernet.localIP());
    
    }
    
    
    void loop() {
      client = server.available();
      if (client) {
        Serial.println("new client");
        
        delay(200);
        res = ""; path = ""; /*httpget = "", */
        int resend = 1;
        boolean currentLineIsBlank = true;
        while (client.connected()) {
          if (client.available()) {
            char c = client.read();
            //Serial.write(c);
            //只读取一行
            if (c != '\n' && resend) {
              res += c;
            } else {
              resend = 0;
            }
    
            if (c == '\n' && currentLineIsBlank) {
              //判断GET头完整性
              if ((res.indexOf("GET ") != -1) && (res.indexOf(" HTTP") != -1)) {
                //判断是否存在get参数
                if (res.indexOf('?') != -1) {
                  //httpget = res.substring(res.indexOf('?') + 1, res.indexOf(" HTTP"));
                  path = res.substring(res.indexOf("GET ") + 4, res.indexOf('?'));
                } else {
                  path = res.substring(res.indexOf("GET ") + 4, res.indexOf(" HTTP"));
                }
                Serial.println(res);
                //Serial.println("GET:" + httpget);
                Serial.println("path:" + path);
                //delay(100);
                File s = SD.open(path);
                if (s) {
                  webprintDirectory(s);
                } else {
                  client.println(s);
                  s.rewindDirectory();
                  s.close();
                }
                //client.println("<p>" + fakename + "</p></body></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(1);
        // close the connection:
        client.stop();
        Serial.println("client disconnected");
    
      }
    }
    
    void webprintDirectory(File dir) {
      //判断是否为文件
      if (!dir.isDirectory()) {
    
        if (path.indexOf('.') != -1) {
          //获取后缀名
          http_header("200 OK", path.substring(path.indexOf('.') + 1));
        } else {
          http_header("200 OK", "txt");//文件没有后缀名 默认显示文本格式
        }
        //读文件
        while (dir.available()) {
          char sc = dir.read();
          client.print(sc);
        }
        dir.close();
        dir.rewindDirectory();
        return;//退出
      }
      //判断不是文件
      http_header("200 OK", "htm");
      client.print("<!DOCTYPE HTML><html><body><h1>200 Success</h1><br />ATH:" + path + "<hr />");
      dir.rewindDirectory();//索引回到第一个位置
      while (true) {
        File entry =  dir.openNextFile();
        if (!entry) {
          //没有下一个索引了
          client.print("<br />No more files");
          dir.rewindDirectory();
          break;
        }
        if (path == "/") {
          client.print("<br /><a href=\"" + path);
        } else {
          client.print("<br /><a href=\"" + path + "/");
        }
        client.print(entry.name());
        client.print("\"target=\"_self\">");
        client.print(entry.name());
        client.print("</a>");
        if (!entry.isDirectory()) {
          // files have sizes, directories do not
          client.print("  ");
          client.println(entry.size(), DEC);
        }
    
        entry.close();
      }
      client.println("<p>" + fakename + "</p></body></html>");
      dir.close();
      delay(200);
    }
    
    void http_header(String statuscode, String filetype) {
      filetype.toLowerCase();//把后缀名变小写
      client.println("HTTP/1.1 " + statuscode);
      client.print("Content-Type: ");
      //判断文件mime类型
      if (filetype == "htm" || filetype == "html") {
        client.println("text/html");
      }
      if (filetype == "png" || filetype == "jpg" || filetype == "bmp" || filetype == "gif") {
        client.println("image/" + filetype);
      } else {
        client.println("text/plain");
      }
      client.println("Connection: close");
      client.println();
    }


    运行
    QQ截图20151114215516.png
    出现文件列表

    打开个图片看看
    QQ截图20151114215552.png
    加载速度有些坑爹了27KB文件要加载9秒多

    做个死 加载个大图片看看
    QQ截图20151114220126.png

    3MB用了17分钟,还是不要加载太大的图,慢死~~


    打开文本文件
    QQ截图20151114220330.png







  • TA的每日心情
    奋斗
    2020-4-7 14:48
  • 签到天数: 954 天

    [LV.10]以坛为家III

    发表于 2015-11-14 22:46 | 显示全部楼层
    膜拜一下高级东东
  • TA的每日心情
    奋斗
    2015-10-30 10:45
  • 签到天数: 2 天

    [LV.1]初来乍到

     楼主| 发表于 2015-11-15 00:27 | 显示全部楼层
    seesea 发表于 2015-11-14 22:46
    膜拜一下高级东东

    看海大大老是调侃我 给个精好不好啊~~?么么么
  • TA的每日心情
    郁闷
    2016-7-22 20:28
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2015-11-15 20:32 | 显示全部楼层
    某十大神威武
  • TA的每日心情
    奋斗
    2020-4-7 14:48
  • 签到天数: 954 天

    [LV.10]以坛为家III

    发表于 2015-11-15 21:52 | 显示全部楼层
    某1o 发表于 2015-11-15 00:27
    看海大大老是调侃我 给个精好不好啊~~?么么么

    某10大威武!
  • TA的每日心情
    奋斗
    2015-10-30 10:45
  • 签到天数: 2 天

    [LV.1]初来乍到

     楼主| 发表于 2015-11-17 07:19 | 显示全部楼层

    爱卓泰 爱生活!!
  • TA的每日心情
    奋斗
    2020-4-7 14:48
  • 签到天数: 954 天

    [LV.10]以坛为家III

    发表于 2015-11-17 22:06 | 显示全部楼层
    某1o 发表于 2015-11-17 07:19
    爱卓泰 爱生活!!

    哈哈,好基友,一辈子
  • TA的每日心情
    开心
    2017-1-22 10:14
  • 签到天数: 11 天

    [LV.3]偶尔看看II

    发表于 2015-11-25 13:50 | 显示全部楼层
    好基友,一被子
  • TA的每日心情
    开心
    2019-10-16 23:39
  • 签到天数: 407 天

    [LV.9]以坛为家II

    发表于 2016-2-13 12:09 | 显示全部楼层
    seesea 发表于 2015-11-17 22:06
    哈哈,好基友,一辈子

    都在啊
  • TA的每日心情
    奋斗
    2020-4-7 14:48
  • 签到天数: 954 天

    [LV.10]以坛为家III

    发表于 2016-2-14 21:21 | 显示全部楼层

    昨天不在
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    热门推荐

    《Color Unit免费申请试用》
    《Color Unit免费申请试用
    COLOR 是一款颜色识别 Unit,其内部集成TCS3472彩色光数字转换器,能够将其检测到颜色
    编译时空白行出现stray '\345' in program
    编译时空白行出现stray &#
    【原创】 drawbot平面关节scara机械臂写字机 画画机器人直播...
    【原创】 drawbot平面关节
    这个项目上个月就在做了,结构和代码反反复复改了多次,加上自己又太忙,一直没来得及
    siri+小爱+小度+天猫控制灯
    siri+小爱+小度+天猫控制
    以上是颜色代码 本程序控制的是8266的 io 0 默认上电LOW 有需求可以知己改写 siri
    siri控制8266
    siri控制8266
    //本程序是操作8266的GPIO 0 口// 程序如下 #include const char* ssid = "TP-11222";
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
    快速回复 返回顶部 返回列表