1. 오류 발생 : 파일을 전송하는데 처음에만 되고 그 이후로는 안되서 오류 분석 중. 추가로 파일 전송을 하고 난 후, 디렉토리가 없어짐.
2. 오류 원인 : 이름이 한글로된 파일이나 이름에 콤마가 2개 이상인 파일이 문제를 일으켜서 FTP 서버가 동작을 안하는 경우가 있었다.
3. 해결책 : 위의 종류의 파일을 취급하지 않거나, LFN(Long File Name)을 지원하거나 UNICODE(한글 지원)이 되도록 프로그램을 고쳐야 함. (디렉토리 해결책은 다음 글에 올려 놨음)


안녕하세요, 이번에는 Soft AP 를 이용한 8266 FTP Server를 만들어 봤습니다.


주변의 공유기에 붙여서 IP를 할당받아서 사용하는 방법이 아니라, 
8266 자체가 Ftp Server가 됩니다.

이것도 FTP Server가 공식적인 예제가 아니여서인지, 처음에는 Soft AP 는 잘 구현되어서 
SSID 와 Password를 치고 들어갔는데 Ftp Server 동작이 안됐었습니다.

많이 고생을 했는데, 알고 보니 SoftAPIP 주소가 아니라 localIP 주소에 의해 Ftp Server가 동작되도록 되어 있었습니다.
아직 Esp8266 과 네트웍 개념도 없고 c++ 문법도 잘 몰라서 SoftIP 주소에 의해 동작하도록 하는 방법으로 수정할 순 없겠고,
localIP 주소를 수정해서 동작하도록 만들었습니다.

예전의 SD 카드에 의해 동작하는 FTP 예제에서 아두이노 스케치 코드만 조금 고쳐주면 됩니다.

SoftAP 로 동작하는 데에는 독립적인 SSID 와 비밀번호가 필요하니 정의해 놓고,
1
2
3
const char* ssid = "FISI_Server";
const char* password = "0317358631";
 
cs

FTP 에서 사용할 IP 및 Gateway,subnetMask 주소를 정의했습니다.
1
2
3
4
5
// config static IP
IPAddress apIP(19216841);  
IPAddress gateway(19216841); // set gateway to match your network
IPAddress subnet(2552552550); // set subnet mask to match your network
 
cs

config 함수로 실제 local IP,Gateway,SubnetMask 주소를 세팅합니다.
그리고 아무 상관은 없지만 기분이 찝찝하니 SoftAP Ip,gateway,subnetmask 주소도 세팅해 주고,
WiFi.softAP 함수로 위에서 정의해 둔, SSID 와  비밀번호로 AP를 만듭니다.
1
2
3
4
5
6
7
8
9
10
  WiFi.config(apIP, gateway, subnet);
  Serial.println();
  Serial.print("Configuring access point...");
  /* You can remove the password parameter if you want the AP to be open. */
  WiFi.mode(WIFI_AP);
  WiFi.disconnect();
  delay(100);
  WiFi.softAPConfig(apIP, gateway, subnet);
  WiFi.softAP(ssid, password);
 
cs


위의 소스코드에서 쓸데없이 들어있는 것도 있을텐데, 또 할일들이 많아서 더 테스트는 못했습니다.

전체 아두이노 IDE의 스케치 파일의 소스 코드는 다음과 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266FtpServer.h>
 
const char* ssid = "FISI_Server";
const char* password = "0317358631";
 
// config static IP
IPAddress apIP(19216841);  
IPAddress gateway(19216841); // set gateway to match your network
IPAddress subnet(2552552550); // set subnet mask to match your network
 
 
ESP8266WebServer server(80);
FtpServer ftpSrv;   //set #define FTP_DEBUG in ESP8266FtpServer.h to see ftp verbose on serial
 
 
 
void handleRoot() {
  server.send(200"text/plain""hello from esp8266!");
 
}
 
void handleNotFound(){
  String message = "File Not Found\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 += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404"text/plain", message);
}
 
void setup(void){
  delay(1000);
  Serial.begin(115200);
 
  Serial.println("");
  Serial.println(WiFi.SSID());
  Serial.println(WiFi.psk());
  WiFi.config(apIP, gateway, subnet);
 
  Serial.println();
  Serial.print("Configuring access point...");
  /* You can remove the password parameter if you want the AP to be open. */
  WiFi.mode(WIFI_AP);
  WiFi.disconnect();
  delay(100);
  WiFi.softAPConfig(apIP, gateway, subnet);
  WiFi.softAP(ssid, password);
 
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
 
  Serial.println("");
  Serial.println("");
 
  WiFi.printDiag(Serial);
  
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(WiFi.SSID());
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  
  server.on("/", handleRoot);
  server.onNotFound(handleNotFound);
  server.begin();
  Serial.println("HTTP server started");
 
  /////FTP Setup, ensure SPIFFS is started before ftp;  /////////
  
  if (SD.begin(4)) {
      Serial.println("SD opened!");
      ftpSrv.begin("esp8266","esp8266");    //username, password for ftp.  set ports in ESP8266FtpServer.h  (default 21, 50009 for PASV)
  }    
      Serial.println("FTP server On!");
  /*
  if (SPIFFS.begin()) {
      Serial.println("SPIFFS opened!");
      ftpSrv.begin("esp8266","esp8266");    //username, password for ftp.  set ports in ESP8266FtpServer.h  (default 21, 50009 for PASV)
  }    */
}
 
void loop(void){
  ftpSrv.handleFTP();        //make sure in loop you call handleFTP()!!  
  server.handleClient();
 
}
cs

다 준비가 됐으니, Wifi 로 미리 설정해 둔 SSID 와 비번으로 Esp8266 에 접속합니다.



접속이 됐으면 이번에는 랜드폰 앱으로 FTP Client 앱을 받아서 설치합니다.
여러가지가 있는데 저는 터보 클라이언트라는 앱을 사용했습니다.


FTP 프로그램을 실행해서 설정을 다음과 같이 했습니다.



그리고 FTP 서버에 접속하니 SD 카드에 들어있는 내용이 나왔습니다. SOFT AP 도 완료. ~` ^^;




흐름제어 설정방법이 자세히 안 나와 있어서 직접 테스트를 해 봤습니다.


테스트를 진행한 프로젝트는 rfEasyLinkNp_cc1310 입니다.

설정방법은 간단합니다.


1. 만약 CTS,RTS 핀을 바꾸고 싶다면 CC1310_LAUNCHXL.h 파일에서 핀설정을 수정해 주시면 됩니다.
1
2
3
4
5
/* UART Board */
#define Board_UART_RX               IOID_2          /* RXD  */
#define Board_UART_TX               IOID_3          /* TXD  */
#define Board_UART_CTS              IOID_19         /* CTS  */
#define Board_UART_RTS              IOID_18         /* RTS */
cs

2. 그런 다음, CC1310_LAUNCHXL.c 의 BoardGpioInitTable[] 설정을
다음과 같이 수정하고..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const PIN_Config BoardGpioInitTable[] = {
 
    Board_RLED   | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,         /* LED initially off             */
    Board_GLED   | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,         /* LED initially off             */
    Board_BTN1   | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS,            /* Button is active low          */
    Board_BTN2   | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS,            /* Button is active low          */
    Board_SPI_FLASH_CS | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN,  /* External flash chip select    */
    Board_UART_RX | PIN_INPUT_EN | PIN_PULLDOWN,                                              /* UART RX via debugger back channel */
    Board_UART_TX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL,                        /* UART TX via debugger back channel */
    Board_UART_CTS | PIN_INPUT_EN | PIN_PULLUP,
    Board_UART_RTS | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
    //Board_SPI0_MOSI | PIN_INPUT_EN | PIN_PULLDOWN,                                            /* SPI master out - slave in */
    //Board_SPI0_MISO | PIN_INPUT_EN | PIN_PULLDOWN,                                            /* SPI master in - slave out */
    //Board_SPI0_CLK | PIN_INPUT_EN | PIN_PULLDOWN,                                             /* SPI clock */
 
    PIN_TERMINATE
};
cs


3. CC1310_LAUNCHXL.c 의 uartCC26XXHWAttrs[CC1310_LAUNCHXL_UARTCOUNT] 의 내용 중,
.ctsPin 과 .rtsPin 설정을 수정합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* UART hardware parameter structure, also used to assign UART pins */
const UARTCC26XX_HWAttrsV1 uartCC26XXHWAttrs[CC1310_LAUNCHXL_UARTCOUNT] = {
    {
        .baseAddr       = UART0_BASE,
        .powerMngrId    = PowerCC26XX_PERIPH_UART0,
        .intNum         = INT_UART0_COMB,
        .intPriority    = ~0,
        .swiPriority    = 0,
        .txPin          = Board_UART_TX,
        .rxPin          = Board_UART_RX,
        .ctsPin         = Board_UART_CTS,    // PIN_UNASSIGNED -> Board_UART_CTS
        .rtsPin         = Board_UART_RTS    // PIN_UNASSIGNED -> Board_UART_RTS    
    }
};
cs

4. 빌드하고 다운로드하면 흐름제어 동작이 됩니다.


Necleo 보드에 달려있는 STLINK를 사용하는 방법을 알아보겠습니다.

저는 일단 STLINK 부분을 잘라버렸는데, 괜히 잘랐네요.
CN2 의 점퍼만 빼면 STLINK로 사용하고, 끼우면 NUCLEO 보드하고 같이 사용하도록 되어 있던것을 .. 에휴..

이 보드를 잘라 버리면 8MHz 클럭이 끊어지고 UART-to-USB 연결이 끊어져 버려서 Nucleo 보드를 못쓰게 되었습니다.
아깝네요.


잘라낸 쪽보드를 STLINK 로 사용하는 방법은 CN2의 점퍼를 모두 OPEN하고 
CN4 의 6핀 중, 5핀을 사용하면 됩니다.

그림 1장에 사용법이 다 나와있는데 다음과 같습니다.




다음은 실제로 잘라낸 STLINK 보드입니다.



다음은 회사에서 만든 Target 보드에 STLINK 핀을 뽑아 놓은 사진이고 , 위의 STLINK와 연결해서 다운로드 했는데 잘 동작됐습니다. 위에서 3.3V 라고 써 놓은 CN4의 1번핀은 VDD_TARGET 으로서 타겥보드에서 전원을 감지하는(DETECT) 역할을 한다. (전원을 공급하는 용도는 아님)



이정도 설명이면 다들 알아 들으시겠죠? ^^

+ Recent posts