Skocz do zawartości

Biblioteka FTP_Client.h dla ESP8266 - invalid conversion


Wrona

Pomocna odpowiedź

Stosuje od jakiegoś czasu bibliotekę klienta FTP dla ESP32 i wszystko śmiga. Tym razem chciałem te same funkcje zastosować w ESP8266. W tym celu pobrałem bibliotekę: https://github.com/nimaltd/FTP_Client/blob/master/example.cpp i początkowo ciągle wywalało mi błędy. Pozmieniałem co umiałem według komunikatów o błędach ale utknąłem na tym: Invalid conversion froma 'unsigned char*'to'char*' [-fpermissive]

Poniżej kod funkcji w której mam błąd:

void FTP()
{
ftp.openConnection();
ftp.changeWorkDir("/Pomiary/");
String wyniki = "Zestaw wynikow: "+timeClient.getFormattedDate()+"\n";                  
unsigned int dlugosc = wyniki.length() + 1;                                                    
unsigned char dane[dlugosc];                                                                      
wyniki.toCharArray(dane, dlugosc);                                               

ftp.initFile(FTP_FileType_ASCII);
ftp.appendFile("WynikiPomiarow.txt");
ftp.write(dane);
ftp.closeFile();
ftp.closeConnection();
}

Jedyne co zaczaiłem to ze mam inaczej zrobić to: "wyniki.toCharArray(dane, dlugosc);" Pomoże ktoś to poprawić?

Link do komentarza
Share on other sites

15 minut temu, ethanak napisał:

Poczytaj o rzutowaniu typów.

 

Na to rozwiązanie to wpadłem sam i go realizuje. Czasami jednak od "poczytania o temacie" lepsze jest "wyjaśnienie na konkretnym przypadku". Na razie szukam sam, i pewnie w końcu znajdę rozwiązanie albo zrezygnuje (i wrócę do ESP32 gdzie nie mam tego problemu) ale jeśli ktoś ma ochotę wyjaśnić mi na tym konkretnym przypadku co robię źle, to będę zobowiązany. Jeśli ktoś ma ochotę wyjaśnić amatorowi to zagadnienie to zapraszam ... ale bez zbędnej spinki.

Link do komentarza
Share on other sites

No to w konkretnym przypadku:

  • Jakiego typu powinny być argumenty dla toCharArray?
  • Jakiego typu masz w programie?
  • Co zrobić żeby były takie same?

A poza tym nie lepiej tu użyć wyniki.c_str() zamiast kopiować zawartość String do jakiejś tablicy tylko po to, żeby sobie zajmowała pamięć? ESP8266 ma faktycznie nieco więcej pamięci niż np. Arduino UNO, ale to nie znaczy że trzeba ją marnować.

I bez spinek proszę 😉

 

 

 

 

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

(edytowany)

@ethanak Masz całkowitą racje z tymi typami w argumentach. Całkowicie się w tym wstrząsnąłem i zamieszałem bo ... w wersji na esp32 dla toCharArray były argumenty char i int i wszystko działało ale dla esp8266 zaczęło "wyć" bym pozamieniał na "unsigned" i chyba zrobiłem to za wcześnie. Dzięki za wskazówkę. Zacząłem też kombinować z tym c_str() tylko u mnie wszystko dłużej trwa bo już wiadomo że nie będę nigdy programistą.

EDIT:

Okazało się że problem jest innej natury. Czyli miałem raczej dobry kod, który popsułem i wszystko sobie w łepetynie pomieszałem. Rzeczywisty problem to chyba "pogryzienie" się bibliotek bo mam taki błąd:

C:\Users\Wrona\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h: In instantiation of 'size_t WiFiClient::write(T&, size_t) [with T = unsigned char [1024]; size_t = unsigned int]':
E:\Arduino\libraries\FTP_Client-master\FTP_Client.cpp:469:58:   required from here
C:\Users\Wrona\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h:123:36: error: request for member 'available' in 'source', which is of non-class type 'unsigned char [1024]'
     size_t left = source.available();
                                    ^
C:\Users\Wrona\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h:127:5: error: request for member 'read' in 'source', which is of non-class type 'unsigned char [1024]'
     source.read(buffer.get(), will_send);
     ^
exit status 1

Powiedzcie jak żyć? Wiem że uczciwie nie krzywdząc innych, .... ale co z tymi bibliotekami począć? O co właściwie chodzi?

Edytowano przez Wrona
Link do komentarza
Share on other sites

@ethanak Sorki, faktycznie nie wkleiłem całego. Poniżej całość.

Arduino:1.8.13 (Windows 10), Płytka:"NodeMCU 1.0 (ESP-12E Module), 80 MHz, 9600, 4M (3M SPIFFS)"
In file included from C:\Users\Wrona\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:39:0,
                 from E:\Instalowane Programy\Arduino\libraries\FTP_Client-master\FTP_Client.h:4,
                 from E:\Instalowane Programy\Arduino\libraries\FTP_Client-master\FTP_Client.cpp:1:
C:\Users\Wrona\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h: In instantiation of 'size_t WiFiClient::write(T&, size_t) [with T = unsigned char [1024]; size_t = unsigned int]':
E:\Instalowane Programy\Arduino\libraries\FTP_Client-master\FTP_Client.cpp:469:58:   required from here
C:\Users\Wrona\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h:123:36: error: request for member 'available' in 'source', which is of non-class type 'unsigned char [1024]'
     size_t left = source.available();
                                    ^
C:\Users\Wrona\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h:127:5: error: request for member 'read' in 'source', which is of non-class type 'unsigned char [1024]'
     source.read(buffer.get(), will_send);
     ^
exit status 1
Błąd kompilacji dla płytki NodeMCU 1.0 (ESP-12E Module).

 

Link do komentarza
Share on other sites

Tak sobie popatrzyłem w źródła... a co będzie jeśli zamienisz:

ftp.write(dane);

na

ftp.writeData((uint8_t *)dane, dlugosc -1);

ewentualnie żeby się pozbyć niepotrzebnej tablicy:

ftp.writeData ((uint8_t *) wyniki.c_str(), wyniki.length);

(czy jakoś tak)?

Edytowano przez ethanak
  • Pomogłeś! 1
Link do komentarza
Share on other sites

@ethanak Błędu to nie zlikwidowało ale nadało kierunek moim poszukiwaniom aż zrobiłem tak:

void FTP()
{
ftp.openConnection();
ftp.changeWorkDir("/Pomiary/");
String wyniki = "Zestaw wynikow: "+timeClient.getFormattedDate()+"\n";                  
int dlugosc = wyniki.length() + 1;                                                    
char dane[dlugosc];                                                                      
strcpy(dane, wyniki.c_str());                                              

ftp.initFile(FTP_FileType_ASCII);
ftp.appendFile("WynikiPomiarow.txt");
ftp.write((uint8_t *)dane);
ftp.closeFile();
ftp.closeConnection();
}

Ostatni błąd jaki mi się pojawia to

E:\Programy\Arduino\libraries\FTP_Client-master/FTP_Client.h:35:13: error:   initializing argument 1 of 'bool FTP_Client::write(const char*)' [-fpermissive]
     bool    write(const char * str);
             ^
exit status 1
invalid conversion from 'uint8_t* {aka unsigned char*}' to 'const char*' [-fpermissive]

Jako że ja osobiście kody jedynie kleje a nie pisze to mam spore braki. Zbliżyłem się do celu, czy to ślepa uliczka? 

Link do komentarza
Share on other sites

No to pomyśl:

  1. ftp.write wymaga typu const char *;
  2. Ty podajesz uint8_t *;
  3. Co trzeba zrobić?

Poza tym dlaczego nie spróbujesz tego writeData?

6 minut temu, Wrona napisał:

ja osobiście kody jedynie kleje

Wiesz - klejenia też trzeba się nauczyć, a nie wszystko się tak od razu znajdzie w góglu. Ja np. bardzo bym chciał wiedzieć, czym przykleić naturalne włosy do petg 😞

Przy okazji - jeśli użyłeś c_str(), to po jakiego grzyba tam tablica dane? Masz za dużo ramu w tym swoim ESP czy co?

 

Edytowano przez ethanak
Link do komentarza
Share on other sites

Przed chwilą, ethanak napisał:

Poza tym dlaczego nie spróbujesz tego writeData?

 

Jak najbardziej próbowałem zrobić zgodnie z Twoją radą ale tak jak pisałem to błędu nie likwidowało. Dlatego szukając różnych rozwiązań wróciłem do "write" bo w obecnej konfiguracji tamte błędy zniknęły i na razie został ten ostatni a niedozwolonej konwersji.

Dlatego mam już mętlik, bo wiem że "write" wymaga const char * ale wtedy pojawiają się niezrozumiałe dla mnie komunikaty o błędach a gdy podaje uint8_t * to pojawia się jedynie ten błąd i nieprawidłowej konwersji. Wiem że to kwestia rzutowania czegoś w coś i jeszcze w coś innego. Dlatego szukam w internetach o rzutowaniu na jakiś prostych przykładach ale w tym przypadku, to po prawdzie, pogubiłem się w tym co właściwe w którym miejscu mam rzutować na co. Jak już wszystko jest dobrze na etapie definiowania char-ów to ich nie przyjmuje ftp.write a jak ftp.write mam poprawione według tego co mi wskazują komunikaty o błędach to mi się nie zgadza z typem wcześniej zadeklarowanych zmiennych. W tym miejscu stoję ja we mgle ale w miarę swych możliwości, walczę dalej. 

 

Link do komentarza
Share on other sites

2 minuty temu, Wrona napisał:

Jak najbardziej próbowałem zrobić zgodnie z Twoją radą ale tak jak pisałem to błędu nie likwidowało.

Dobra... a możesz wrzucić tu jakiś większy kawałek programu (taki tworzący jakąś kompilowalna całość)? Wybacz, ale nie chce mi się pisać reszty do tej funkcji... a samej funkcji nie skompiluję.

Bo na razie mam tylko Twoje słowo na to że "nie wyszło", ale ani zmienionego kodu nie podałeś, ani opisu błędu.

Link do komentarza
Share on other sites

@ethanak Testujemy kolejno

void WyFTP()
{
ftp.openConnection();
ftp.changeWorkDir("/Pomiary/");
String wyniki = "Zestaw wynikow:\n";                  
unsigned int dlugosc = wyniki.length() + 1;                                                    
unsigned char dane[dlugosc];                                                                      
strcpy(dane, wyniki.c_str());                                           
ftp.initFile(FTP_FileType_ASCII);
ftp.appendFile("WynikiPomiarow.txt");
ftp.write(dane);
ftp.closeFile();
ftp.closeConnection();
}

Daje

TEST:207:28: error: invalid conversion from 'unsigned char*' to 'char*' [-fpermissive]
 strcpy(dane, wyniki.c_str());                                           
                           ^
In file included from c:\users\wrona\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\stdlib.h:11:0,
                 from C:\Users\Wrona\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Arduino.h:27,
                 from C:\Users\Wrona\Desktop\TEST\TEST.ino:1:
c:\users\Wrona\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\string.h:30:8: error:   initializing argument 1 of 'char* strcpy(char*, const char*)' [-fpermissive]
 char  *_EXFUN(strcpy,(char *, const char *));
        ^
TEST:211:15: error: invalid conversion from 'unsigned char*' to 'const char*' [-fpermissive]
 ftp.write(dane);
               ^
In file included from C:\Users\Wrona\Desktop\TEST\TEST.ino:6:0:
E:\Programy\Arduino\libraries\FTP_Client-master/FTP_Client.h:35:13: error:   initializing argument 1 of 'bool FTP_Client::write(const char*)' [-fpermissive]
     bool    write(const char * str);
             ^
exit status 1
invalid conversion from 'unsigned char*' to 'char*' [-fpermissive]

więc robimy inaczej

void WyFTP()
{
ftp.openConnection();
ftp.changeWorkDir("/Pomiary/");
String wyniki = "Zestaw wynikow:\n";                  
int dlugosc = wyniki.length() + 1;                                                    
char dane[dlugosc];                                                                      
strcpy(dane, wyniki.c_str());                                           
ftp.initFile(FTP_FileType_ASCII);
ftp.appendFile("WynikiPomiarow.txt");
ftp.writeData((uint8_t *)dane, dlugosc-1);
ftp.closeFile();
ftp.closeConnection();
}

i mamy komunikat

In file included from C:\Users\Wrona\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:39:0,
                 from E:\Programy\Arduino\libraries\FTP_Client-master\FTP_Client.h:4,
                 from E:\Programy\Arduino\libraries\FTP_Client-master\FTP_Client.cpp:1:
C:\Users\Wrona\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h: In instantiation of 'size_t WiFiClient::write(T&, size_t) [with T = unsigned char [1024]; size_t = unsigned int]':
E:\Programy\Arduino\libraries\FTP_Client-master\FTP_Client.cpp:469:58:   required from here
C:\Users\Wrona\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h:123:36: error: request for member 'available' in 'source', which is of non-class type 'unsigned char [1024]'
     size_t left = source.available();
                                    ^
C:\Users\Wrona\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h:127:5: error: request for member 'read' in 'source', which is of non-class type 'unsigned char [1024]'
     source.read(buffer.get(), will_send);
     ^
exit status 1

 

A teraz dodatkowy kod by było na czym sprawdzić kompilacje

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include "FTP_Client.h"
#include <DHT.h>
#include <NTPClient.h>         
#include <WiFiUdp.h>
#include "time.h"

const char* ssid = "**********";               
const char* password = "*******";             

const char* ftp_server = "*******";
const char* ftp_user = "******";
const char* ftp_pass = "******";

unsigned long aktualnyCzas = 0;
unsigned long zapamietanyCzas = 0;
unsigned long roznicaCzasu = 0;

ESP8266WebServer server(80);                                           
FTP_Client ftp;

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 7200, 60000);   

void setup()
{
WiFi.begin(ssid, password);                                                   
while (WiFi.status()!= WL_CONNECTED) {delay(500);}         
server.begin();
ftp.begin(ftp_server,ftp_user,ftp_pass,15000);
}

void loop()
{
aktualnyCzas = millis(); 
roznicaCzasu = aktualnyCzas - zapamietanyCzas; 
if (roznicaCzasu >= 100000UL) {zapamietanyCzas = aktualnyCzas; WyFTP();}
} 

void WyFTP()
{
ftp.openConnection();
ftp.changeWorkDir("/Pomiary/");
String wyniki = "Zestaw wynikow:\n";                  
int dlugosc = wyniki.length() + 1;                                                    
char dane[dlugosc];                                                                      
strcpy(dane, wyniki.c_str());                                           
ftp.initFile(FTP_FileType_ASCII);
ftp.appendFile("WynikiPomiarow.txt");
ftp.writeData((uint8_t *)dane, dlugosc-1);
ftp.closeFile();
ftp.closeConnection();
}

 

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.