arduino制作简易文本文件服务器-Arduino中文社区 - Powered by Discuz! Archiver

奈何col 发表于 2017-8-26 12:36

arduino制作简易文本文件服务器

陆续更新
演示视频:
视频链接:http://v.youku.com/v_show/id_XMzEzMTYwNDUyOA==.html?spm=a2hzp.8244740.0.0
http://v.youku.com/v_show/id_XMzEzMTYwNDUyOA==.html
项目说明:
其实用arduino做类似的web server是不合适的,web server搭建更推荐使用linux开发板,本项目仅供学习研究。

使用到的硬件:
Arduino UNO、Wiznet W5500扩展板、TF卡一张、网线


因为我只有5500,5500的ethernet库需要使用https://github.com/Wiznet/WIZ_Ethernet_Library
使用5100也是可以的,IDE自带的ethernet库即可。

可实现的功能:
通过浏览器查看、删除TF卡中的文件。
(暂时没有在线编写文件的功能,实际上很多应用中文件都是Arduino采集传感器数据自动生成的)

参考了以下项目:
https://github.com/greiman/SdFat
https://github.com/adafruit/SDWebBrowse

实现思路:
1.仿照REST,通过get实现指定路径的访问、文件查看、文件删除操作
2.在loop中获取请求,并分析判断是哪种操作,并执行相应的操作

因此loop中基本结构框架如下:
void loop()
{
int index = 0;
client = server.available();
if (client)
{
    boolean current_line_is_blank = true;
    index = 0;

    while (client.connected())
    {
      if (client.available())
      {
      //SdFile root;
      char c = client.read();
      if (c != '\n' && c != '\r')
      {
          clientline = c;
          index++;
          if (index >= BUFSIZE)
            index = BUFSIZE - 1;
          continue;
      }

      clientline = 0;
      Serial.println(clientline);
      //访问根目录
      if (strstr(clientline, "GET / ") != 0)
      {
      }
      //删除文件
      else if (strstr(clientline, "/del/") != 0)
      {
      }
      //打开子目录
      else if ((strstr(clientline, "GET /") != 0) && (strstr(clientline, "/ HTTP") != 0))
      {
      }
      //打开文件
      else if (strstr(clientline, "GET /") != 0)
      {
      }
      //没有找到文件
      else
      {
      }
      break;
      }
    }
    delay(1);
    client.stop();
}
}



各功能实现代码:

打开文件夹
void OpenDir(char *dirname)
{
file.open(&root, dirname, O_READ);
ListFiles(file);
file.close();
}

输出文件名
void PrintFileName()
{
      for (uint8_t i = 0; i < 11; i++) {
                if (p.name == ' ') continue;
                if (i == 8) {
                        client.print('.');
                }
                client.print((char)p.name);
      }
      if (DIR_IS_SUBDIR(&p)) {
                client.print('/');
      }
}


输出文件列表
void ListFiles(SdFile dir)
{

      while (dir.readDir(p) > 0)
      {
                if (p.name == DIR_NAME_FREE) break;
                if (p.name == DIR_NAME_DELETED || p.name == '.') continue;
                if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;

                client.print("<p><a href=\"");
                PrintFileName();
                client.print("\">");
                PrintFileName();
                client.print("</a>");

    // 大小信息
                client.print("   ");
                client.print(p.fileSize);

                client.print("      ");
                client.print("<a href=\"del/");
                PrintFileName();
                client.print("\">");
                client.print("del");
                client.print("</a>");

                client.println("</p>");
      }

}


打开文件
void OpenFile(char *filename)
{
    Serial.println("send file data");
    Serial.println(filename);
    char *path=strtok(filename, "/");
    filename=strtok(NULL, "/");
    Serial.println(path);
    Serial.println(filename);
    file.open(&root, path, O_READ);
    SdFile file2;
    file2.open(&file, filename, O_READ);
    client.println("HTTP/1.1 200 OK");
    client.println("Content-Type: text/plain");
    client.println();

    int16_t c;
    while ((c = file2.read()) > 0) {
      client.print((char)c);
    }

file2.close();
file.close();

}

删除文件
void DelFile(char *filename)
{
      file.remove(&root,filename);
}


完整程序如下:
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
Sd2Card card;
SdVolume volume;
SdFile root;
// SdFile file;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 0, 177);
EthernetServer server(80);
EthernetClient client;
dir_t p;
String readString;
String filelist;
#define BUFSIZE 100
char clientline;

void initSD()
{
card.init(SPI_HALF_SPEED, 4);
volume.init(&card);
root.openRoot(&volume);
}

void setup()
{
Serial.begin(9600);
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
initSD();
Ethernet.begin(mac, ip);
server.begin();
Serial.print("Server is at ");
Serial.println(Ethernet.localIP());
}

void loop()
{
int index = 0;
client = server.available();
if (client)
{
    boolean current_line_is_blank = true;
    index = 0;

    while (client.connected())
    {
      if (client.available())
      {
      //SdFile root;
      char c = client.read();
      if (c != '\n' && c != '\r')
      {
          clientline = c;
          index++;
          if (index >= BUFSIZE)
            index = BUFSIZE - 1;
          continue;
      }

      clientline = 0;
      Serial.println(clientline);
      //访问根目录
      if (strstr(clientline, "GET / ") != 0)
      {
          Sendheader(200);
          client.println("<h2>File List:</h2>");
          root.rewind();
          ListFiles(root);
      }
      //删除文件
      else if (strstr(clientline, "/del/") != 0)
      {
          char *filename;
          filename = clientline + 5;
          (strstr(clientline, "/del/ HTTP")) = 0;
          Serial.println(filename);
          DelFile(filename);
      }
      //打开子目录
      else if ((strstr(clientline, "GET /") != 0) && (strstr(clientline, "/ HTTP") != 0))
      {
          Serial.println("open dir");
          Sendheader(200);
          char *dirname;
          dirname = clientline + 5;
          (strstr(clientline, " HTTP")) = 0;
          client.print("<h2>");
          client.print(dirname);
          client.println(" List:</h2>");
          OpenDir(dirname);
      }
      //打开文件
      else if (strstr(clientline, "GET /") != 0)
      {
          char *filename;
          filename = clientline + 5;
          (strstr(clientline, " HTTP")) = 0;
          OpenFile(filename);
      }
      //没有找到文件
      else
      {
          Sendheader(404);
          client.println("<h2>File Not Found!</h2>");
      }
      break;
      }
    }
    delay(1);
    client.stop();
}
}

void PrintFileName()
{
for (uint8_t i = 0; i < 11; i++) {
    if (p.name == ' ') continue;
    if (i == 8) {
      client.print('.');
    }
    client.print((char)p.name);
}
if (DIR_IS_SUBDIR(&p)) {
    client.print('/');
}
}

void ListFiles(SdFile dir)
{

while (dir.readDir(p) > 0)
{
    if (p.name == DIR_NAME_FREE) break;
    if (p.name == DIR_NAME_DELETED || p.name == '.') continue;
    if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;

    client.print("<p><a href=\"");
    PrintFileName();
    client.print("\">");
    PrintFileName();
    client.print("</a>");

    if (!(DIR_IS_SUBDIR(&p)))
    {
      client.print("   ");
      client.print(p.fileSize);

      client.print("      ");
      client.print("<a href=\"");
      PrintFileName();
      client.print("/del/\">");
      client.print("del");
      client.print("</a>");
    }

    client.println("</p>");
}

}

void Sendheader(int x)
{
if (x == 200)
{
    client.println("HTTP/1.1 200 OK");
}
if (x == 404)
{
    client.println("HTTP/1.1 404 Not Found");
    return;
}
client.println("Content-Type: text/html");
client.println();
}

void OpenDir(char *dirname)
{
//dirname: DATA/2016/05/
SdFile file, file2, file3;

char *path1 = strtok(dirname, "/"); //DATA
char *path2 = strtok(NULL, "/"); //201X
char *path3 = strtok(NULL, "/"); //XX

if (path2 == NULL)
{
    file.open(&root, path1, O_READ);
    ListFiles(file);
    file.close();
}
else if (path3 == NULL)
{
    file.open(&root, path1, O_READ);
    file2.open(&file, path2, O_READ);
    ListFiles(file2);
    file2.close();
    file.close();
}
else
{
    file.open(&root, path1, O_READ);
    file2.open(&file, path2, O_READ);
    file3.open(&file2, path3, O_READ);
    ListFiles(file3);
    file3.close();
    file2.close();
    file.close();
}

}

void OpenFile(char *filename)
{
//DATA/01/XXX.TXT
char *path1 = strtok(filename, "/"); //DATA
char *path2 = strtok(NULL, "/"); //201X
char *path3 = strtok(NULL, "/"); //XX
filename = strtok(NULL, "/"); //XXX.TXT
SdFile file;
file.open(&root, path1, O_READ);
SdFile file2;
file2.open(&file, path2, O_READ);
SdFile file3;
file3.open(&file2, path3, O_READ);
SdFile file4;
file4.open(&file3, filename, O_READ);
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/plain");
client.println();

int16_t c;
while ((c = file4.read()) > 0) {
    client.print((char)c);
}

file4.close();
file3.close();
file2.close();
file.close();

}
void DelFile(char *filename)
{
char *path1 = strtok(filename, "/"); //DATA
char *path2 = strtok(NULL, "/"); //201X
char *path3 = strtok(NULL, "/"); //XX
filename = strtok(NULL, "/"); //XXX.TXT

SdFile file;
file.open(&root, path1, O_READ);
SdFile file2;
file2.open(&file, path2, O_READ);
SdFile file3;
file3.open(&file2, path3, O_READ);
SdFile file4;
file4.remove(&file3, filename);

file4.close();
file3.close();
file2.close();
file.close();

Sendheader(200);

client.print("Delete ");
client.print(filename);
client.println(" success");
}









hongzailalala 发表于 2017-8-26 12:56

有点意思!

a7178636965 发表于 2020-3-12 21:35

还可以搞到8266上

a7178636965 发表于 2020-3-12 22:54

大佬,如何实现SD卡文件的复制啊?
比如我的图片在SD卡里,我想把他复制到SPIFFS里面,进行下一步操作。麻烦大佬!!
页: [1]
查看完整版本: arduino制作简易文本文件服务器