Mengirim file di SDCard ke PC melalui ESP8266 dengan Arduino

Mengunduh file (download) dari web server melaui web browser biasa kita lakukan. protokol yang umum digunakan adalah FTP atau HTTP. Perancangan kali ini menggunakan Arduino sebagai file server. File-filenya disimpan dalam SDCard, dan untuk berkomunikasi dengan jaringan menggunakan modul wifi ESP8266.

Perancangan sistem file server arduino ini mampu menampilkan File SDCard ke web browser, daftar file file ini merupakan isi dari root direktori kartu memori.

Untuk mendownload file dari arduino, buka browser di halaman sesuai alamat IP Wifi ESP8266 kemudian klik file yang akan didownload, atau jika ingin mendownload secara langsung bisa melalui link http://(alamat ip ESP8266)/namafile.ext.

Komponen yang digunakan :

  1. Arduino Mega
  2. Modul MicroSD
  3. Modul ESP8266 ESP12E

skema download file dari kartu memori melalui ESP8266 :

Sebelum digunakan edit dulu bagian ini :

char ssid[] = "Twim";
char pass[] = "12345678";

Program/sketch File server ESP8266 dengan arduino:

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

char ssid[] = "Twim";
char pass[] = "12345678";
int status = WL_IDLE_STATUS;

WiFiEspServer server(80);
File FileSDCard;

void setup() {
  Serial.begin(115200);
  Serial.println("Mengirim file di SDCard ke PC melalui ESP8266 dengan Arduino");
  Serial.println("https://www.semesin.com/project");

  Serial1.begin(115200);
  WiFi.init(&Serial1);

  if (!SD.begin(53)) 
  {
    Serial.println("Gagal memulai kartu memori!");
    while (true);
  }
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("Modul ESP8266 tidak ditemukan");
    while (true);
  }

  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, pass);
  }

  Serial.println("You're connected to the network");
  printWifiStatus();
  server.begin();
}

void loop() {
  WiFiEspClient client = server.available();
  if (client) {
    boolean currentLineIsBlank = true;
    String request = "";

    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        request += c;
        if (c == '\n' && currentLineIsBlank) {
          break;
        }
        if (c == '\n') {
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          currentLineIsBlank = false;
        }
      }
    }
    client.println("HTTP/1.1 200 OK");
    client.println("Connection: close");

    Serial.println(request);
    Serial.println();
    Serial.println("Mengirim respon");

    int startFilename = request.indexOf('/') + 1;
    int endFilename = request.indexOf("HTTP/1.1") - 1;

    String fileRquest = request.substring(startFilename, endFilename);
    Serial.print("Permintaan file : ");
    Serial.println(fileRquest);

    if(fileRquest == "")
    {
      File root = SD.open("/");
      client.println("Content-Type: text/html");
      client.println();
      client.print("<!DOCTYPE HTML>");
      client.print("<html>");
      client.print("Daftar file:<br>");

      while (true) 
      {
        File entry =  root.openNextFile();
        if (! entry) {
          break;
        }
        client.print("<a href=\"");
        client.print(entry.name());
        client.print("\">");
        client.print(entry.name());
        client.print("</a><br>");
        entry.close();
      }
      client.print("</html>\r\n");
    }
    else if (!SD.exists(fileRquest)) 
    {
      client.println("Content-Type: text/html");
      client.println();
      client.print("<!DOCTYPE HTML>");
      client.print("<html>");
      client.print("Maaf file tidak ditemukan");
      client.print("</html>");
    } 
    else 
    {
      Serial.print("Mengirim file : ");
      Serial.println(fileRquest);
      FileSDCard = SD.open(fileRquest, FILE_READ);

      client.print("Content-Length:");
      client.println((String)FileSDCard.size());
      client.println("Content-Type: text/plain");
      client.print("Content-Disposition: attachment; filename=\"");
      client.print(fileRquest);
      client.println("\"");
      client.println("Content-Transfer-Encoding: binary");
      client.println();

      for(uint16_t i=0;i<FileSDCard.size();i++)
      {
        client.write(FileSDCard.read());
      }
      FileSDCard.close();
    }
    delay(10);
    client.stop();
    Serial.println("Client disconnected");
  }
}
void printWifiStatus()
{
  IPAddress ip = WiFi.localIP();
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  Serial.print("IP Address: ");
  Serial.println(ip);
  Serial.println();
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
  Serial.println();
}

keluaran serial monitor:

Membaca file txt dari SDCard/kartu memori kedalam struct menggunakan Arduino (Aplikasi Bel Sekolah)

SDCard/microSD/kartu memori merupakan media penyimpanan yang banyak digunakan pada perangkat-perangkat elektronik untuk menyimpan foto, video, data dll. Dalam aplikasi arduino SDCard bisa dibaca/ditulis dalam protokol SPI, format yang didukung adalah FAT.

Dalam perancangan ini saya menggunakan file .txt yang tersusun sebagai database (contoh database jadwal bel sekolah), dan dibaca dengan arduino untuk kemudian dimasukkan kedalam tabel “jadwalBelajar”.

format yang digunakan adalah

Aktif | Waktu | Hari aktif | Minggu aktif | Kegiatan

Aktif
Sebagai status item/baris jadwal diaktifkan atau tidak(diabaikan)
isiannya Aktif, Tidak Aktif

Waktu
Format waktu jam:menit

Hari aktif
hari dimana item jadwal diaktifkan
isiannya: Senin, Selasa, Rabu, Kamis, Jum’at, Sabtu, Minggu atau kombinasinya dalam bentuk array didalam tanda ‘{‘ dan ‘}’

minggu aktif
isiannya kombinasi minggu bentuk array didalam tanda ‘{‘ dan ‘}’

Kegiatan
text Kegiatan

Skema:

sketch/program:

#include <avr/pgmspace.h>
#include <SPI.h>
#include <SD.h>

struct Waktu
{ 
  byte jam; 
  byte menit; 
};

struct TabelMataPelajaran
{
  byte aktif;
  Waktu waktu;
  byte hariAktif;
  byte mingguAktif;
  byte kegiatan;
};

const PROGMEM char kegiatan[][21] = 
{
  "Jam Pelajaran 1\0    ",
  "Jam Pelajaran 2\0    ",
  "Jam Pelajaran 3\0    ",
  "Jam Pelajaran 4\0    ",
  "Jam Pelajaran 5\0    ",
  "Jam Pelajaran 6\0    ",
  "Jam Pelajaran 7\0    ",
  "Jam Pelajaran 8\0    ",
  "Jam Pelajaran 9\0    ",
  "Jam Pelajaran 10\0   ",
  "Jam Pelajaran 11\0   ",
  "Jam Pelajaran 12\0   ",
  "Jam Pelajaran 13\0   ",
  "Jam Pelajaran 14\0   ",
  "Jam Pelajaran 15\0   ",
  "Masuk\0              ",
  "Upacara\0            ",
  "Istirahat\0          ",
  "Selesai Istirahat\0  ",
  "Kepramukaan\0        ",
  "Khusus\0             ",
  "Pulang\0             ",
  "Pulang Jumat\0       ",
  "Pulang Sabtu\0       "
};

const char namaHari[][7] PROGMEM = 
{
  "Minggu",
  "Senin\0",
  "Selasa",
  "Rabu\0 ",
  "Kamis\0",
  "Jum'at",
  "Sabtu\0"
};

const char Aktifasi[][12] PROGMEM = 
{
  "Aktif\0     ",
  "Tidak aktif"
};

#define hariAktifSenin 1<<6
#define hariAktifSelasa 1<<5
#define hariAktifRabu 1<<4
#define hariAktifKamis 1<<3
#define hariAktifJumat 1<<2
#define hariAktifSabtu 1<<1
#define hariAktifMinggu 1<<7


#define _hariAktif(Sen,Sel,Rab,Kam,Jum,Sab,Mgu) (Mgu<<7)|(Sen<<6)|(Sel<<5)|(Rab<<4)|(Kam<<3)|(Jum<<2)|(Sab<<1)
#define _mingguAktif(Mgu1,Mgu2,Mgu3,Mgu4,Mgu5) (Mgu1<<7)|(Mgu2<<6)|(Mgu3<<5)|(Mgu4<<4)|(Mgu5<<3)
#define _waktu(Jam, Menit) {Jam, Menit}
#define Aktif 1
#define TidakAktif 0

TabelMataPelajaran jadwalBelajar[150];
Waktu waktu;
File fileJadwal;
char buffer[21];

void setup() {
  Serial.begin(9600);
  Serial.println("Membaca file txt dari SDCard/kartu memori kedalam struct menggunakan Arduino");
  Serial.println("(Aplikasi Bel Sekolah)");
  Serial.println("https://www.semesin.com/project");
}

void loop() {
  if (!SD.begin(53)) 
  {
    Serial.println("Gagal memulai kartu memori!");
  }
  else
  {  
    if (!SD.exists("Jadwal.txt")) 
    {
      Serial.println("file Jadwal.txt tidak ditemukan");
    } 
    else 
    {
      char c;
      byte index;
      String str;
      fileJadwal = SD.open("Jadwal.txt", FILE_READ);
      while(1)
      {
        c = fileJadwal.peek();
        if(c == -1)
        {
          break;
        }
        else if(c == '/')
        {
          while(fileJadwal.read() != '\n');
          continue;
        }
        else if((c == '\r') || (c == '\n') || (c == '\t') || (c == ' '))
        {
          fileJadwal.read();
          continue;
        }
        jadwalBelajar[index].aktif = ambilCSVAktif(fileJadwal);
        ambilCSVWaktu(&jadwalBelajar[index].waktu.jam,&jadwalBelajar[index].waktu.menit, fileJadwal);
        jadwalBelajar[index].hariAktif = ambilCSVHari(fileJadwal);
        jadwalBelajar[index].mingguAktif = ambilCSVMinggu(fileJadwal);
        jadwalBelajar[index].kegiatan = ambilCSVKegiatan(fileJadwal);

        copyFlashString(buffer, &Aktifasi[jadwalBelajar[index].aktif][0]);
        Serial.print(buffer);
        Serial.print('\t');
        if(jadwalBelajar[index].waktu.jam < 10) Serial.print('0');
        Serial.print(jadwalBelajar[index].waktu.jam);
        Serial.print(':');
        if(jadwalBelajar[index].waktu.menit < 10) Serial.print('0');
        Serial.print(jadwalBelajar[index].waktu.menit);
        Serial.print('\t');
        Serial.print(jadwalBelajar[index].hariAktif,HEX);
        Serial.print('\t');
        Serial.print(jadwalBelajar[index].mingguAktif,HEX);
        Serial.print('\t');
        copyFlashString(buffer, &kegiatan[jadwalBelajar[index].kegiatan][0]);
        Serial.println(buffer);
      }
      fileJadwal.close();
    }
  }

  while(1);//***
}
byte ambilCSVAktif(File file)
{
  String str = ambilCSVDariFile(file);

  for(byte i=0;i<sizeof(Aktifasi)/sizeof(Aktifasi[0]);i++)
  {
    copyFlashString(buffer, &Aktifasi[i][0]);
    if(str.equalsIgnoreCase((String)buffer))
    {
      return i;
    }
  }
}
void ambilCSVWaktu(byte* jam, byte* menit, File file)
{
  String str = ambilCSVDariFile(file);
  byte pos1 = str.indexOf(':');
  *jam = str.substring(0,pos1).toInt();
  *menit = str.substring(pos1+1).toInt();
}
byte ambilCSVHari(File file)
{
  String str = ambilCSVDariFile(file);
  for(byte i=0;i<sizeof(namaHari)/sizeof(namaHari[0]);i++)
  {
    copyFlashString(buffer, &namaHari[i][0]);
    if(str.equalsIgnoreCase((String)buffer))
    {
      return 1<<(7-i);
    }
  }
  byte dataHari = 0;
  byte shift = 0x80;
  byte hari[7];

  ambilCSVDariString(hari, str);
  for(byte i=0;i<sizeof(hari);i++)
  {
    if(hari[i])
    {
      dataHari += shift;
    }
    shift >>= 1;
    
  }
  return dataHari;
}

byte ambilCSVMinggu(File file)
{
  byte dataMinggu = 0;
  byte shift = 0x80;
  byte minggu[5];
  String str = ambilCSVDariFile(file);

  ambilCSVDariString(minggu, str);
  for(byte i=0;i<sizeof(minggu);i++)
  {
    if(minggu[i])
    {
      dataMinggu += shift;
    }
    shift >>= 1;
  }
  return dataMinggu;
}

byte ambilCSVKegiatan(File file)
{
  String str = ambilCSVDariFile(file);
  for(byte i=0;i<sizeof(kegiatan)/sizeof(kegiatan[0]);i++)
  {
    copyFlashString(buffer, &kegiatan[i][0]);
    if(str.equalsIgnoreCase((String)buffer))
    {
      return i;
    }
  }
}
String ambilCSVDariFile(File file)
{
  String str = "";
  char terminator = ',';

  while(1)
  {
    char c = file.peek();
    if(c == '{')
    {
      terminator = '}';
      file.read();
    }
    else if(((c != terminator) && (c != '\r')))
    {
      str += (char)file.read();
    }
    else
    {
      file.read();
      if(terminator == '}')
      {
        terminator = ',';
      }
      else if((terminator == ',') || (c == '\r'))
      {
        break;
      }
    }
  }
  str.trim();
  return str;
}
void copyFlashString(char* buf, const char* alamat)
{
  char c;
  while(c = pgm_read_byte(alamat++))
  {
    *buf++ = c;
  }
  *buf = 0;
}
void ambilCSVDariString(byte *minggu, String str)
{
  while(1)
  {
    int pos = str.indexOf(',');
    *minggu++ = str.substring(0,pos).toInt();
    if(pos == -1)
    {
      break;
    }
    str = str.substring(pos+1);
  }
}

contok keluaran serial monitor:

Contoh file jadwal.txt:
Jadwal.txt

Bel sekolah bluetooth dengan kontrol android : disini