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

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 6943|回复: 3

[项目] arduino制作简易文本文件服务器

[复制链接]
发表于 2017-8-26 12:36 | 显示全部楼层 |阅读模式
陆续更新
演示视频:
视频链接:http://v.youku.com/v_show/id_XMzEzMTYwNDUyOA==.html?spm=a2hzp.8244740.0.0

项目说明:
其实用arduino做类似的web server是不合适的,web server搭建更推荐使用linux开发板,本项目仅供学习研究。

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

因为我只有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中基本结构框架如下:
[mw_shl_code=arduino,true]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[index] = c;
          index++;
          if (index >= BUFSIZE)
            index = BUFSIZE - 1;
          continue;
        }

        clientline[index] = 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();
  }
}[/mw_shl_code]



各功能实现代码:

打开文件夹
[mw_shl_code=arduino,true]void OpenDir(char *dirname)
{
  file.open(&root, dirname, O_READ);
  ListFiles(file);
  file.close();
}
[/mw_shl_code]
输出文件名
[mw_shl_code=arduino,true]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('/');
        }
}[/mw_shl_code]


输出文件列表
[mw_shl_code=arduino,true]void ListFiles(SdFile dir)
{

        while (dir.readDir(p) > 0)
        {
                if (p.name[0] == DIR_NAME_FREE) break;
                if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.') 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>");
        }

}[/mw_shl_code]


打开文件
[mw_shl_code=arduino,true]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();

}[/mw_shl_code]

删除文件
[mw_shl_code=arduino,true]void DelFile(char *filename)
{
        file.remove(&root,filename);
}[/mw_shl_code]


完整程序如下:
[mw_shl_code=cpp,true]#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[20];
#define BUFSIZE 100
char clientline[BUFSIZE];

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[index] = c;
          index++;
          if (index >= BUFSIZE)
            index = BUFSIZE - 1;
          continue;
        }

        clientline[index] = 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] = 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] = 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] = 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[0] == DIR_NAME_FREE) break;
    if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.') 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");
}[/mw_shl_code]









发表于 2020-3-12 21:35 | 显示全部楼层
还可以搞到8266上
发表于 2020-3-12 22:54 | 显示全部楼层
大佬,如何实现SD卡文件的复制啊?
比如我的图片在SD卡里,我想把他复制到SPIFFS里面,进行下一步操作。麻烦大佬!!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-9-20 22:28 , Processed in 0.187080 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表