diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..eabc537 --- /dev/null +++ b/.clang-format @@ -0,0 +1,9 @@ +BasedOnStyle: LLVM +UseTab: Never +IndentWidth: 2 +BreakBeforeBraces: Attach +AllowShortIfStatementsOnASingleLine: Always +AlignConsecutiveMacros: true +IndentPPDirectives: BeforeHash +IndentCaseLabels: true +ColumnLimit: 120 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0ae98dc --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/extensions.json +.vscode/ipch +platformio.ini +secrets.h diff --git a/README.md b/README.md index 64bfeb3..be952bb 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,13 @@ If all build flags are enabled, to include as much libraries as possible, the fo V3.2 + - added Email on (re-)start (at the moment this only works for ESP32). Although by a call to Restart_Email (as shown in the main program) also a (re-)start email for the ESP8266 can be send - added warning MQTT message on (re-)start - added username/password to MQTTconnection (may be left empty) V3.1 of RFLink-ESP has the following new or improved features + - complete rebuild on the base of Sensors/Receivers-concept (more features with less effort) - program can be completely build and controlled by WebSettings - simultanuous support of serial and telnet debug and control @@ -22,21 +24,108 @@ V3.1 of RFLink-ESP has the following new or improved features - received and transmitted messages are stored in a file - build flags extended, so the program can be used with a minimal set of libraries - flag Home_Automation removed -- command added: 19;PRINT; //lists the known devices +- command added: 19;PRINT; //lists the known devices - Learning_Mode=9 is made asynchronuous, so you can do other things including stopping LM-9 -- command added: 13; and 14; // shows/sets 2 commands for Learning_Mode 8/9 +- command added: 13; and 14; // shows/sets 2 commands for Learning_Mode 8/9 - programs added to upload files to the ESP by FTP -# Schmurtz +## Secrets + +To change settings and store private keys, create a `secrets.h` file under `src/`. Below is a sample of basic required secrets. + +```cpp +// *********************************************************************** +// PRIVATE GLOBALS +// *********************************************************************** +#define __SECRET_Wifi_Name "Home Network SSID" +#define __SECRET_Wifi_PWD "Password" +#define __SECRET_Broker_IP "192.168.22.23" + +#define __SECRET_SMTP_Server "smtp.gmail.com" +#ifdef ESP32 +#define __SECRET_SMTP_Port 587 +#else +#define __SECRET_SMTP_Port 465 +#endif +#define __SECRET_SMTP_User "someone@gmail.com" +#define __SECRET_SMTP_PWD "someones password" +#define __SECRET_SMTP_MailTo "someone@gmail.com" +``` + +## Inclusion + +By commenting/uncommenting build parameters you can reduce RAM size requirement. +To include for example the FTP server, uncomment in your main ino file: + +```cpp +#define INCLUDE_FTPSERVER +``` + +### Common + +These build parameters are often used in most programs. + +| Name | Included by default | +| ------------------- | ---------------------- | +| SENSOR_ADS1115 | :x: no | +| SENSOR_ADS1115_DIFF | :x: no | +| SENSOR_BME280 | :x: no | +| SENSOR_DHT22 | :x: no | +| SENSOR_DS18B20 | :x: no | +| SENSOR_MHZ14 | :x: no | +| SENSOR_MPU9250 | :x: no | +| SENSOR_PIR | :x: no | +| SENSOR_SDS011 | :x: no | +| RECEIVER_MQTT | :heavy_check_mark: yes | +| RECEIVER_EMAIL | :heavy_check_mark: yes | +| RECEIVER_SCRATCHPAD | :x: no | +| RECEIVER_SDFAT | :x: no | +| RECEIVER_SSD1306 | :x: no | +| RECEIVER_TM1638 | :x: no | + +### Special Case + +These build parameters only used in special programs. + +| Name | Included by default | +| ----------------------- | ---------------------- | +| FTPSERVER | :x: no | +| BLAUWE_ENGEL | :x: no | +| FIJNSTOF_CONDITIONERING | :x: no | +| SENSOR_RFLINK | :heavy_check_mark: yes | +| SENSOR_BMP280 | :x: no | +| SENSOR_MLX90614 | :x: no | +| SENSOR_MLX90640 | :x: no | +| SENSOR_MQTTBroker | :x: no | +| SENSOR_NTP | :x: no | +| SENSOR_OKE4 | :x: no | +| SENSOR_RTC | :x: no | +| RECEIVER_OTA | :heavy_check_mark: yes | +| RECEIVER_TELNET | :heavy_check_mark: yes | +| RECEIVER_WEBSERVER | :heavy_check_mark: yes | +| RECEIVER_LUFTDATEN | :x: no | + +## Building + +Useful flags while building are + +``` +-Wno-deprecated-declarations -Wno-sign-compare -Wno-unused-variable +``` + +## Schmurtz + forked V2.1 and made it more compatible with other Bridge-libraries. https://github.com/schmurtzm/RFLink-ESP -# RFLink-ESP V2.1 +## RFLink-ESP V2.1 + Home Assistant / Domoticz tested with a RFLink, modified for ESP8266 and ESP32 This is a fork of RFLink, and because we couldn't get it working reliable, we ended up in a complete rewrite of RFLink. Problem is that the latest version of RFLink is R48. We couldn't only find sources of version R29 and R35. Both sources didn't work correctly, R29 was the best. We tried to contact "the stuntteam" which owns the orginal sources but no response. This version of RFLink-ESP has the following features + - just a few protocols are translated and tested - Protocols are more generic, so you need less protocols - Protocols are written as classes and all derived from a common class @@ -45,13 +134,14 @@ This version of RFLink-ESP has the following features - Removed a lot of redundancies - Device must be registered before they will be recognized ( (almost) no more false postives) - Dynamically determine long/short puls, by measuring Min,Max,Mean -- Runs on ESP32 and even on a ESP8266 +- Runs on ESP32 and even on a ESP8266 - Fully open source - Codesize is strongly reduced - Can communicate over USB/RS232 or MQTT Some ideas for the future + - Implementing rolling code SomFy / Own - Cleanup global constants and variables - Using SI4432 as Receiver / Transmitter (Transmitter can be used for all frequencies, Receiver might be able to fetch a complete sequence, so listening at more frequencies at the same time might even be possible) -- Logging of false positives, including time (Neighbours ??) NTP: https://www.instructables.com/id/Arduino-Internet-Time-Client/ +- Logging of false positives, including time (Neighbours ??) NTP: https://www.instructables.com/id/Arduino-Internet-Time-Client/ diff --git a/RFLink_ESP/Email_Support.h b/RFLink_ESP/Email_Support.h deleted file mode 100644 index ce600f8..0000000 --- a/RFLink_ESP/Email_Support.h +++ /dev/null @@ -1,249 +0,0 @@ - - -// Version 0.1 25-04-2020 -// - special for ESP8266, gmail works on port = 465 - - -#ifndef Email_Support_h -#define Email_Support_h 0.1 - - -// *********************************************************************************** -// Encode64 is based on the code from AlertMe -// *********************************************************************************** -const char PROGMEM b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - - -// *********************************************************************************** -inline void a3_to_a4(unsigned char * a4, unsigned char * a3) { - a4[0] = (a3[0] & 0xfc) >> 2; - a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4); - a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6); - a4[3] = (a3[2] & 0x3f); -} - -// *********************************************************************************** -int base64_encode(char *output, char *input, int inputLen) { - int i = 0, j = 0; - int encLen = 0; - unsigned char a3[3]; - unsigned char a4[4]; - - while (inputLen--) { - a3[i++] = *(input++); - if (i == 3) { - a3_to_a4(a4, a3); - - for (i = 0; i < 4; i++) { - output[encLen++] = pgm_read_byte(&b64_alphabet[a4[i]]); - } - - i = 0; - } - } - - if (i) { - for (j = i; j < 3; j++) { - a3[j] = '\0'; - } - - a3_to_a4(a4, a3); - - for (j = 0; j < i + 1; j++) { - output[encLen++] = pgm_read_byte(&b64_alphabet[a4[j]]); - } - - while ((i++ < 3)) { - output[encLen++] = '='; - } - } - output[encLen] = '\0'; - return encLen; -} - -// *********************************************************************************** -int base64_enc_length(int plainLen) { - int n = plainLen; - return (n + 2 - ((n + 2) % 3)) / 3 * 4; -} - -// *********************************************************************************** -const char* encode64_f ( char* Line , uint8_t len ) { - int encodedLen = base64_enc_length(len); - static char encoded[256]; - // note input is consumed in this step: it will be empty afterwards - base64_encode ( encoded, Line, len ); - return encoded; -} - -// **************************************************************************** -// **************************************************************************** -String Encode64 ( String Line ) { - const int MaxLen = 100 ; - - char Copy[MaxLen] ; - Line.toCharArray ( Copy, MaxLen ); - - String Result = encode64_f ( Copy, Line.length() ) ; - return Result ; -} - - -#ifndef ESP32 -#include - -// *********************************************************************************** -bool Email_Wait ( WiFiClientSecure &Mail_Client, String Response = "", uint16_t timeOut = 10000 ) { - uint32_t ts = millis(); - while ( !Mail_Client.available () ) { - if ( millis() > ( ts + timeOut ) ) { - Serial.println ( "ERROR: Email_Wait timed out" ) ; - return false; - } -yield(); - } - String Server_Response = Mail_Client.readStringUntil ( '\n' ) ; -Serial.println ( "Waiting for: "+ Response + " Received: " + Server_Response ) ; - if ( ( Response.length() > 0 ) && Server_Response.indexOf ( Response ) == -1 ) return false; - return true; -} - - -// *********************************************************************************** -// *********************************************************************************** -class _Email_Client_Class { - public: - - // _Email_Client_Class ************************************************** - // *********************************************************************** - _Email_Client_Class ( String xSMTP_Server, int xSMTP_Port, - String xSMTP_User, String xSMTP_PWD, String xSMTP_MailTo ) { - this->_SMTP_Server = xSMTP_Server ; - this->_SMTP_Port = xSMTP_Port ; - this->_SMTP_User = xSMTP_User ; - this->_SMTP_PWD = xSMTP_PWD ; - this->_SMTP_MailTo = xSMTP_MailTo ; - } - _Email_Client_Class ( String xSMTP_Server, int xSMTP_Port, - String xSMTP_User, String xSMTP_PWD ) { - this->_SMTP_Server = xSMTP_Server ; - this->_SMTP_Port = xSMTP_Port ; - this->_SMTP_User = xSMTP_User ; - this->_SMTP_PWD = xSMTP_PWD ; - this->_SMTP_MailTo = xSMTP_User ; - - } - - - // _Email_Client_Class ************************************************** - // *********************************************************************** - bool Send_Mail ( String MailTo, String Subject, String Message, bool HTML_Format = false ) { - - if ( WiFi.status () != WL_CONNECTED ) { - WiFi.mode ( WIFI_STA ) ; - WiFi.begin ( __SECRET_Wifi_Name, __SECRET_Wifi_PWD ) ; - Serial.println ( "..... Trying to connect to " + String ( __SECRET_Wifi_Name ) ) ; - while ( WiFi.status () != WL_CONNECTED ) { - delay ( 500 ) ; - Serial.print ( "." ) ; - } - Serial.println () ; - } - - Serial.println ( "Connecting to mailserver:" + this->_SMTP_Server + " Port:" + String (this->_SMTP_Port )); - - WiFiClientSecure Email_Client ; - Email_Client.setInsecure () ; - delay(1000); - - if ( !Email_Client.connect( this->_SMTP_Server, this->_SMTP_Port )) { - Serial.println ( "Could not connect to mail server:" + this->_SMTP_Server +" Port:" + String(this->_SMTP_Port) ) ; - return false; - } - - if ( !Email_Wait ( Email_Client, "220" ) ) { - Serial.println( "Connection Error"); - return false; - } - - Email_Client.println ( "HELO friend" ) ; - if ( !Email_Wait ( Email_Client, "250" ) ) { - Serial.println( "identification error"); - return false; - } - - Email_Client.println ( "AUTH LOGIN" ) ; - Email_Wait ( Email_Client, "" ) ; - - Email_Client.println ( Encode64 ( this->_SMTP_User ) ) ; - Email_Wait ( Email_Client, "" ) ; - - Email_Client.println ( Encode64 ( this->_SMTP_PWD ) ) ; - if ( !Email_Wait ( Email_Client, "235" ) ) { - Serial.println( "SMTP AUTH error"); - return false; - } - - String mailFrom = "MAIL FROM: " ; - Email_Client.println ( mailFrom ) ; - Email_Wait ( Email_Client, "" ) ; - - String Recipient = "RCPT TO: <" + MailTo + ">" ; - Email_Client.println ( Recipient ) ; - Email_Wait ( Email_Client, "" ) ; - - Email_Client.println ( "DATA" ) ; - if ( !Email_Wait ( Email_Client, "354" ) ) { - Serial.println( "SMTP DATA error"); - return false; - } - - String From = "From: <" + this->_SMTP_User + ">" ; - Email_Client.println ( From ) ; - String To = "To: <" + MailTo + ">" ; - Email_Client.println( To ); - - Email_Client.print ( "Subject: " ); - Email_Client.println ( Subject ) ; - - Email_Client.println ( "Mime-Version: 1.0" ) ; - Email_Client.println ( "Content-Type: text/html; charset=\"UTF-8\"" ) ; - Email_Client.println ( "Content-Transfer-Encoding: 7bit" ) ; - Email_Client.println () ; - String Body = Message ; - if ( HTML_Format ) Body = "" + Message + "" ; - Email_Client.println ( Body ) ; - Email_Client.println ("." ) ; - if (!Email_Wait ( Email_Client, "250" ) ) { - Serial.println( "Sending message error"); - return false; - } - - Email_Client.println ( "QUIT" ) ; - if ( !Email_Wait ( Email_Client, "221" ) ) { - Serial.println( "SMTP QUIT error" ) ; - return false ; - } - return true ; - } - - bool Send_Mail ( String Subject, String Message ) { - return this-> Send_Mail ( this->_SMTP_MailTo, Subject, Message ) ; - } - - - // _Email_Client_Class ************************************************** - // *********************************************************************** - private : - String _SMTP_Server ; - int _SMTP_Port ; - String _SMTP_User ; - String _SMTP_PWD ; - String _SMTP_MailTo ; - -} ; - -#endif -#endif diff --git a/RFLink_ESP/FS_support.h b/RFLink_ESP/FS_support.h deleted file mode 100644 index 0476cf5..0000000 --- a/RFLink_ESP/FS_support.h +++ /dev/null @@ -1,833 +0,0 @@ -// Version 1.1, 14-04-2020, SM -// - nu ook voor ESP32 filelist ordering removed (not tesed!!) -// -// Version 1.0, 27-02-2020, SM -// - Ordering van filelist removed, vraagt teveel RAM (tzt oplossen in HTML) -// - SPIFFS wordt reeds geopend in de class constructor -// - method Read_File toegeveogd (allen geschilt voor kleine bestanden ) -// -// Version 0.9, 18-02-2020, SM -// - bij restart wordt aantal seconden in de file opgezocht, zodat dit een monotoon stijgende reeks is -// -// Version 0.8, 20-12-2019, SM -// - Get_File_Nr added -// -// Version 0.7, 29-08-2019, SM -// - poging tot toevoeging SDMMC -// -// Version 0.6, 02-08-2019, SM -// - Dir_CheckList added -// -// Version 0.5, 28-07-2019, SM -// - Exists added -// -// Version 0.4 -// - Get_Time_In_File hanged if file ended incorrect -// - _FS_class.Begin ESP32 support added -// -// Version 0.3 -// - starting new file on size or time -// remove oldest file -// -// Version 0.2 -// - automatic formatting ESP32 if no filesystem yet -// -// Version 0.1 -// -// https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html - -#ifndef FS_support_h -#define FS_support_h 1.1 - - -#define FS_NO_GLOBALS -#include "FS.h" -#include "My_File_Support.h" - -#ifdef ESP32 - #include "SPIFFS.h" -#endif - -#include "My_StringSplitter.h" - - - - -// *********************************************************************************** -// typical usage: -// -//_FS_class FileSystem () ; -// -//void setup(){ -// Serial.begin(115200); -// delay ( 500 ) ; -// -// FileSystem.Begin () ; -// *********************************************************************************** -class _FS_class { - public: - int _Offset_Seconds = 0 ; - - // ************************************************** - // ************************************************** - _FS_class () { - // ********************************************************************** - // Bewust naar constructor verplaatst, zodat filesysteem direct bruikbaar - // ********************************************************************** -//_DEBUG_Global_String += "\r\n+ _FS_Class.creator" ; - #ifdef ESP32 -//fff this->_Opened = SPIFFS.begin ( true ) ; // format if no filesystem yet -//SPIFFS.format () ; -//delay(1000); - #else - if ( ! SPIFFS.begin ( ) ) { - SPIFFS.format () ; - } - this->_Opened = SPIFFS.begin ( ) ; - #endif -//SPIFFS.format () ; - if ( this->_Opened ) Serial.println ( "SPIFFS succesfull opened" ) ; - else Serial.println ( "ERROR: SPIFFS could not be opened !!!! " ) ; - } - - // ************************************************** - // ************************************************** - bool Begin ( String Filename="", long Max_File_Time = 24*60*60, int Max_NFile = 10 ) { -//_DEBUG_Global_String += "\r\n+ _FS_Class.Begin" ; - #ifdef ESP32 - if ( !this->_Opened ) { - this->_Opened = SPIFFS.begin ( true ) ; // format if no filesystem yet - } -//Serial.println ( "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" ) ; -//Serial.println ( this->_Opened ) ; - if ( this->_Opened ) { - if ( _Parse_Filename ( Filename ) ) { - String Last_File_Pre = _Temp_Last_File_Pre ; - String Last_File_Post = _Temp_Last_File_Post ; - int Last_File_Nr = 0 ; - String FileFound ; - fs::File dir = SPIFFS.open ( "/" ) ; - fs::File file = dir.openNextFile () ; - while ( file ) { - FileFound = file.name() ; - if ( _Parse_Filename ( FileFound ) ) { - if ( _Temp_Last_File_Nr > Last_File_Nr ) { - Last_File_Nr = _Temp_Last_File_Nr ; - } - } - file = dir.openNextFile () ; - } - _Last_Filename = Last_File_Pre + String ( Last_File_Nr ) + Last_File_Post ; - _Last_File_Pre = Last_File_Pre ; - _Last_File_Post = Last_File_Post ; - _Last_File_Nr = Last_File_Nr ; - Serial.println ( "Last File (SPIFFS) = " + _Last_Filename ) ; - } - } - #else - if ( this->_Opened ) { - if ( _Parse_Filename ( Filename ) ) { - String Last_File_Pre = _Temp_Last_File_Pre ; - String Last_File_Post = _Temp_Last_File_Post ; - int Last_File_Nr = 0 ; - String FileFound ; - - fs::Dir dir = SPIFFS.openDir ( Last_File_Pre ) ; - while ( dir.next() ) { - FileFound = dir.fileName() ; - if ( _Parse_Filename ( FileFound ) ) { - if ( _Temp_Last_File_Nr > Last_File_Nr ) { - Last_File_Nr = _Temp_Last_File_Nr ; - } - } - } - _Last_Filename = Last_File_Pre + String ( Last_File_Nr ) + Last_File_Post ; - _Last_File_Pre = Last_File_Pre ; - _Last_File_Post = Last_File_Post ; - _Last_File_Nr = Last_File_Nr ; - Serial.println ( "Last File (SPIFFS) = " + _Last_Filename ) ; - } - } - #endif - - - // >0 aantal seconden (eerste kolom) dat een file maximaal mag bevatten - // <0 maximaal filesize (in bytes) - _Max_FileSize = 0 ; - _Max_FileTime = 0 ; - if ( Max_File_Time > 0 ) { - _Max_FileTime = Max_File_Time ; - } - else { - _Max_FileSize = -Max_File_Time ; - } - _Max_NFile = Max_NFile - 2 ; - if ( _Max_NFile < 0 ) { - _Max_NFile = 0 ; - } - return this->_Opened ; - } - - // ************************************************** - // ************************************************** - String DirList ( String Path = "/" ) { - String Result = "" ; - // ************************************************** - // ESP32 - // ************************************************** - #ifdef ESP32 - fs::File dir = SPIFFS.open ( "/" ) ; - fs::File file = dir.openNextFile () ; - Serial.println ( ">>>>>"); - while ( file ) { - Serial.println ( file.name()); - Result += String ( file.name() ).substring(1) + "\n" ; - file = dir.openNextFile () ; - } - - // ************************************************** - // ESP8266 - // ************************************************** - #else - fs::Dir dir = SPIFFS.openDir ( "/" ) ; - Serial.println ( ">>>>>"); - while ( dir.next() ) { - Serial.println ( dir.fileName()); - Result += dir.fileName().substring(1) + "\n" ; - } - #endif - return Result ; - } - - void DirList_Print ( String Path = "/" ) { -// void DirList_Print ( fs::FS &Drive, String Path = "/" ) { - //if ( Drive == SD_MMC ) { -//Serial.println ( "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& FS_SUPPOYU" ) ; - - Serial.println ( "===== Files in SPIFFS ===== " + Path ) ; - int Count = 0 ; - - // ************************************************** - // ESP32 - // ************************************************** - #ifdef ESP32 - fs::File dir = SPIFFS.open ( "/" ) ; - fs::File file = dir.openNextFile () ; - while ( file ) { - Serial.print ( " " ) ; - Serial.print ( file.name() ) ; - Serial.print ( "\t[" ); - Serial.print ( file.size() ) ; - Serial.println ( "]" ) ; - file = dir.openNextFile () ; - Count += 1 ; - } - - Serial.printf ( "Files=%i Total=%i Used=%i Free=%i MaxOpen=%i\n", - Count, SPIFFS.totalBytes(), SPIFFS.usedBytes(), SPIFFS.totalBytes() - SPIFFS.usedBytes(), 10 ) ; - // ************************************************** - // ESP8266 - // ************************************************** - #else - fs::Dir dir = SPIFFS.openDir ( Path ) ; - while ( dir.next() ) { - Serial.print ( " " + dir.fileName() + "\t[" ); - fs::File file = dir.openFile ( "r" ) ; - Serial.print ( file.size() ) ; - Serial.println ( "]" ) ; - Count += 1 ; - } - - fs::FSInfo fs_info ; - SPIFFS.info ( fs_info ) ; - Serial.printf ( "Files=%i Total=%i Used=%i Free=%i MaxOpen=%i MaxPathLength=%i BlockSize=%i PageSize=%i\n", - Count, fs_info.totalBytes, fs_info.usedBytes, fs_info.totalBytes - fs_info.usedBytes, - fs_info.maxOpenFiles, fs_info.maxPathLength, - fs_info.blockSize, fs_info.pageSize ) ; -Print_Heap () ; - #endif - } - - // ************************************************** - // ************************************************** - void HTML_File_CheckList ( String Path = "/", String Ends = "" ) { - String Filename ; - String FileExt ; - String Line ; - String Result ; - - My_Webserver.sendContent ( "

Data Files (unordered) on ESP-chip

\n" ) ; - My_Webserver.sendContent ( "
\n" ) ; - My_Webserver.sendContent ( "\n" ) ; - My_Webserver.sendContent ( "\n" ) ; - - // ************************************************** - // ESP32 - // ************************************************** - #ifdef ESP32 - fs::File dir = SPIFFS.open ( Path ) ; - fs::File file = dir.openNextFile () ; - while ( file ) { - String Filename = String ( file.name() ).substring(1) ; - if ( Ends.length() == 0 || Filename.endsWith ( Ends ) ) { - Result = "" ; - int x1 = Filename.indexOf ( '.' ) ; - FileExt = Filename.substring ( x1+1 ); - FileExt.toLowerCase() ; - Result = "\n") ; - - My_Webserver.sendContent ( Result.c_str() ) ; - delay(40); - yield() ; - } - file = dir.openNextFile () ; - } - - // ************************************************** - // ESP8266 - // ************************************************** - #else - fs::Dir dir = SPIFFS.openDir ( Path ) ; - while ( dir.next() ) { - String Filename = String(dir.fileName()).substring(1) ; - if ( Ends.length() == 0 || Filename.endsWith ( Ends ) ) { - Result = "" ; - fs::File file = dir.openFile ( "r" ) ; - Filename = String(dir.fileName()).substring(1) ; - //Line = Filename + " [" + String ( file.size() ) + "]" ; - //Line = Filename + "\n") ; - - My_Webserver.sendContent ( Result.c_str() ) ; - delay(40); - yield() ; - - } - } - #endif - My_Webserver.sendContent ( "
GraphFilenameSizeDownload
" ; - //if ( FileExt.endsWith ( "csv" ) ) { - if ( FileExt == "csv" ) { - Result += F("" ; - } - Result += "" + Filename + "" + String ( file.size() ) ; - - Result += "Download
" + String ( file.size() ) + "" ; - - int x1 = Filename.indexOf ( '.' ) ; - FileExt = Filename.substring ( x1+1 ); - FileExt.toLowerCase() ; -//Serial.println ( x1 ) ; -//Serial.println ( FileExt ); - Result = "
" ; - //if ( FileExt.endsWith ( "csv" ) ) { - if ( FileExt == "csv" ) { - Result += F("" ; - } - Result += "" + Filename + "" + String ( file.size() ) ; - - Result += "Download
\n
\n") ; - } - - // ************************************************** - // ************************************************** - int Get_File_Nr ( ) { - return _Last_File_Nr ; - } - - // ************************************************** - // ************************************************** - String Get_Next_Filename () { - if ( _Last_Filename.length() == 0 ) { - _Get_Last_Filename () ; - } - - _Last_File_Nr += 1 ; - if ( _Last_File_Pre.length() == 0 ) { - _Last_File_Pre = "/MLX_" ; - _Last_File_Post= ".bin" ; - } - - //if ( _Last_File_Nr < 10 ) _Last_Filename = _Last_File_Pre + "0" + String ( _Last_File_Nr ) + _Last_File_Post ; - //else _Last_Filename = _Last_File_Pre + String ( _Last_File_Nr ) + _Last_File_Post ; - _Last_Filename = _Last_File_Pre + String ( _Last_File_Nr ) + _Last_File_Post ; - - return _Last_Filename ; - } - - - - - // ************************************************** - // ene variant om de laatste MLX_xxx.bin file te bepalen - // ************************************************** - int Get_Last_File_Number () { - - int Last_FileNr = 0 ; - // ************************************************** - // ESP32 - // ************************************************** - #ifdef ESP32 - fs::File dir = SPIFFS.open ( "/" ) ; - fs::File file = dir.openNextFile () ; - while ( file ) { - String Filename = file.name() ; - int FileNr = Parse_FileNr ( Filename ) ; - if ( FileNr > Last_FileNr ) Last_FileNr = FileNr ; - file = dir.openNextFile () ; - } - // ************************************************** - // ESP8266 - // ************************************************** - #else - fs::Dir dir = SPIFFS.openDir ( "/" ) ; - while ( dir.next() ) { - String Filename = dir.fileName() ; - int FileNr = Parse_FileNr ( Filename ) ; - if ( FileNr > Last_FileNr ) Last_FileNr = FileNr ; - } - #endif - return Last_FileNr ; - } - - // ************************************************** - // ************************************************** - String _Get_Last_Filename () { - if ( _Last_Filename.length() > 0 ) { - return _Last_Filename ; - } - - // ************************************************** - // ESP32 - // ************************************************** - #ifdef ESP32 - fs::File dir = SPIFFS.open ( "/" ) ; - fs::File file = dir.openNextFile () ; - while ( file ) { - _Last_Filename = file.name() ; - file = dir.openNextFile () ; - } - // ************************************************** - // ESP8266 - // ************************************************** - #else - fs::Dir dir = SPIFFS.openDir ( "/" ) ; - while ( dir.next() ) { - //_Last_Filename = dir.Filename() ; - _Last_Filename = dir.fileName() ; - } - #endif - - // ************************************************** - // Parse the filename and store the parts - // ************************************************** - int x1 = _Last_Filename.indexOf ( '_' ) ; - int x2 = _Last_Filename.indexOf ( '.' ) ; - if ( x1 > 0 ) { - _Last_File_Pre = _Last_Filename.substring ( 0 , x1+1 ) ; - _Last_File_Nr = ( _Last_Filename.substring ( x1+1, x2 ) ).toInt () ; - _Last_File_Post = _Last_Filename.substring ( x2 ) ; - } - else { - _Last_File_Pre = _Last_Filename.substring ( 0 , x2 ) + "_" ; - _Last_File_Nr = 0 ; - _Last_File_Post = _Last_Filename.substring ( x2 ) ; - - } - return _Last_Filename ; - } - - - // ************************************************** - // ************************************************** - void Dump ( String Filename ) { - Serial.println ( "===== Dump " + Filename ) ; - fs::File file = SPIFFS.open ( Filename, "r" ) ; - if ( file ) { - while ( file.available() ){ - Serial.print ( file.readString() ) ; - } - file.close () ; - Serial.println ( "\n===============" ) ; - } - else { - Serial.println ( "ERROR: file not found" ) ; - } - } - // ************************************************** - // ************************************************** - String Read_File ( String Filename ) { - String Line ; - fs::File file = SPIFFS.open ( Filename, "r" ) ; - if ( file ) { - while ( file.available() ){ - Line += file.readString() ; - } - file.close () ; - } - return Line ; - } - - // ************************************************** - // ************************************************** - int Get_Time_In_File ( String Filename ) { - int Delta_T = 0 ; - fs::File file = SPIFFS.open ( Filename, "r" ) ; - String Line_0 ; - String Line_1 ; - String Line_2 ; - String Line_x ; - if ( !file ) { - return 0 ; - } - if ( ! file.available() ) { - return 0 ; - } - - Line_0 = file.readStringUntil ( '\n' ) ; - My_StringSplitter *Splitter = new My_StringSplitter ( Line_0, '\t' ) ; - int ItemCount = Splitter -> getItemCount () ; - int DT_i ; - for ( DT_i = 0; DT_i < ItemCount; DT_i++ ) { - String Item = Splitter -> getItemAtIndex ( DT_i ) ; - if ( Item == "Seconds" ) { - break ; - } - } - if ( DT_i >= ItemCount ) { - return 0 ; - } - if ( !file.available() ) { - return 0 ; - } - - Line_1 = file.readStringUntil ( '\n' ) ; - Splitter -> newString ( Line_1, '\t' ) ; - String Date1 = Splitter -> getItemAtIndex ( DT_i ) ; - int DT1 = Date1.toInt () ; - if ( !file.available() ) { - return 0 ; - } - - Line_2 = file.readStringUntil ( '\n' ) ; - Splitter -> newString ( Line_2, '\t' ) ; - String Date2 = Splitter -> getItemAtIndex ( DT_i ) ; - int DT2 = Date2.toInt () ; - if ( !file.available() ) { - return 0 ; - } - - Line_x = "###" ; - while ( file.available() && ( Line_x.length() > 1 ) ){ - Line_x = file.readStringUntil ( '\n' ) ; -//Serial.println ( Line_x ) ; - Splitter -> newString ( Line_x, '\t' ) ; - String Datex = Splitter -> getItemAtIndex ( DT_i ) ; - int DTx = Datex.toInt () ; - - - if ( DTx > DT2 ) { - Delta_T += DTx - DT2 ; - } - DT2 = DTx ; - } - file.close () ; - return Delta_T ; - } - - // ************************************************** - // ************************************************** -/* - int Get_Time_In_File_HANGT_TEVEEL_AF_VAN_NTP_SERVER ( String Filename ) { - File file = SPIFFS.open ( Filename, "r" ) ; - String Line_0 ; - String Line_1 ; - String Line_x ; - if ( file ) { - if ( file.available() ) { - Line_0 = file.readStringUntil ( '\n' ) ; - } - if ( file.available() ) { - Line_1 = file.readStringUntil ( '\n' ) ; - } - while ( file.available() ){ - Line_x = file.readStringUntil ( '\n' ) ; - } - file.close () ; - - My_StringSplitter *Splitter = new My_StringSplitter ( Line_0, '\t' ) ; - int ItemCount = Splitter -> getItemCount () ; - int DT_i ; - for ( DT_i = 0; DT_i < ItemCount; DT_i++ ) { - String Item = Splitter -> getItemAtIndex ( DT_i ) ; - if ( Item == "DateTime" ) { - break ; - } - } - - if ( DT_i < ItemCount ) { - Splitter -> newString ( Line_1, '\t' ) ; - String Date1 = Splitter -> getItemAtIndex ( DT_i ) ; - time_t DT1 = String_2_UnixTime ( Date1 ) ; - - Splitter -> newString ( Line_x, '\t' ) ; - String Date2 = Splitter -> getItemAtIndex ( DT_i ) ; - time_t DT2 = String_2_UnixTime ( Date2 ) ; - - Serial.print ( "Delta T in file = ") ; - Serial.println ( DT2-DT1 ) ; - return (int) (DT2-DT1) ; - } - else { - return 0 ; - } - } - else { - return 0 ; - } - } -*/ - // ************************************************** - // ************************************************** - bool Exists ( String Filename ) { - fs::File file = SPIFFS.open ( Filename, "r" ) ; - if ( file ) { - file.close () ; - return true ; - } - return false ; - } - - // ************************************************** - // ************************************************** - void DumpAll () { - // ************************************************** - // ESP32 - // ************************************************** - #ifdef ESP32 - fs::File dir = SPIFFS.open ( "" ) ; - fs::File file = dir.openNextFile () ; - while ( file ) { - String Filename = file.name () ; - Serial.println ( Filename ) ; - Serial.println ( file.size() ) ; - if ( file ) { - while ( file.available() ){ - Serial.print ( file.readString() ) ; - } - file.close () ; - //if ( Delete_Files ) { - // Delete ( Filename ) ; - //} - } - file = dir.openNextFile () ; - } - - // ************************************************** - // ESP8266 - // ************************************************** - #else - //String Result ; - fs::Dir dir = SPIFFS.openDir ( "" ) ; - while ( dir.next() ) { - //Result += dir.fileName() + "\n" ; - fs::File file = dir.openFile ( "r" ) ; - if ( file ) { - Serial.print ( "===== Contents of " ) ; - Serial.print ( dir.fileName() ) ; - Serial.print ( " " ) ; - Serial.println ( file.size() ) ; - while ( file.available() ){ - Serial.print ( file.readString() ) ; - } - file.close () ; - Serial.println ( "\n===============" ) ; - } - } - #endif - return ; - } - - // ************************************************** - // ************************************************** - bool Delete ( String Filename ) { - Serial.println ( "===== Delete " + Filename ) ; - bool Result = SPIFFS.remove ( Filename ) ; - if ( Result ) { - Serial.println ( "\n===============" ) ; - } - else { - Serial.println ( "ERROR: file not found" ) ; - } - } - - // ************************************************** - // ************************************************** - void Delete_All () { - Serial.println ( "===== Delete All Files" ) ; - String Filename ; - - #ifdef ESP32 - Serial.println ( "!!!!!!!! ToDo _FS_class.Delete_All" ) ; - #else - fs::Dir dir = SPIFFS.openDir ( "" ) ; - while ( dir.next() ) { - Filename = dir.fileName() ; - Serial.println ( "Delete : " + Filename ) ; - SPIFFS.remove ( Filename ) ; - } - #endif - } - - // ************************************************** - // ************************************************** - bool Store_File ( String Filename, String Line ) { - fs::File file = SPIFFS.open ( Filename, "w" ) ; - file.print ( Line ) ; - file.close () ; - return true; - } - - // ************************************************** - // ************************************************** - bool Append_File ( String Filename, String Line ) { - fs::File file = SPIFFS.open ( Filename, "a" ) ; - file.print ( Line ) ; - file.close () ; - return true; - } - - // ************************************************** - // ************************************************** - bool Create_CSV_File ( String Filename, String Header ) { - if ( not SPIFFS.exists ( Filename ) ) { - Append_File ( Filename, Header ) ; - } - } - - // ************************************************** - // ************************************************** - bool Create_CSV_File_Nr ( String Filename, String Header ) { - // ************************************************************ - // als ongeveer een dag opgenomen, ga over naar een nieuwe file - // ************************************************************ - bool NewFile = false ; - if ( _Max_FileSize > 0 ) { - fs::File file = SPIFFS.open ( Filename, "r" ) ; - if ( file.size() > _Max_FileSize ) { - NewFile = true ; - } - file.close() ; - } - else if ( _Max_FileTime > 0 ) { - // ************************************************************ - // After a reset check how many seconds are already in the file - // ************************************************************ - if ( !_Initialized ) { -//Serial.println ( "Before gettime" ) ; - _Offset_Seconds = millis()/1000 + 10 + Get_Time_In_File ( Filename ); -//Serial.println ( "Agter gettime" ) ; - if ( _Offset_Seconds > _Max_FileTime ) { - NewFile = true ; - } - _Initialized = true ; - } -/* -Serial.print ( "millis / Delta / maxfileTIME / Offset = "); -Serial.print ( millis() ) ; -Serial.print ( " / " ); -Serial.print ( _Max_FileTime - _Offset_Seconds ) ; -Serial.print ( " / " ) ; -Serial.print ( _Max_FileTime ) ; -Serial.print ( " / " ); -Serial.println ( _Offset_Seconds ) ; -//*/ - //if ( ( millis() - _File_Millis ) > ( _Max_FileTime - _Offset_Seconds ) ) { - if ( ( millis()/1000 + _Offset_Seconds ) > _Max_FileTime ) { - NewFile = true ; - } - } - - - - - //if ( ( millis() - _File_Millis ) > _Max_FileTime ) { - if ( NewFile ) { - //_File_Millis = millis() ; - if ( _Last_File_Nr > _Max_NFile ) { - String File_To_Remove = _Last_File_Pre + String ( _Last_File_Nr - _Max_NFile ) + _Last_File_Post ; - SPIFFS.remove ( File_To_Remove ) ; - Serial.println ( "rrrrrrrrrrrrrrrrrr " + File_To_Remove ) ; - } - SPIFFS.rename ( Filename, Get_Next_Filename() ) ; - Serial.println ( "???????????????????" + _Get_Last_Filename() ) ; - } - - //_Get_Last_Filename () ; - if ( not SPIFFS.exists ( Filename ) ) { - Append_File ( Filename, Header ) ; - _Offset_Seconds = - ( millis()/1000 ) ; - } - } - - // ************************************************* - private: - // ************************************************* - bool _Opened = false ; - String _Last_Filename = "" ; - String _Last_File_Pre = "" ; - String _Last_File_Post = "" ; - int _Last_File_Nr = 0 ; - - String _Temp_Last_File_Pre = "" ; - String _Temp_Last_File_Post = "" ; - int _Temp_Last_File_Nr = 0 ; - - //unsigned long _File_Millis = 0 ; - bool _Initialized = false ; - //int _Offset_Millis = 0 ; - - unsigned long _Max_FileTime ; - long _Max_FileSize ; - int _Max_NFile ; - - - // ************************************************** - // Parse the filename and store the parts - // ************************************************** - bool _Parse_Filename ( String Filename ) { - if ( Filename.length() == 0 ) { - return false ; - } - int x1 = Filename.indexOf ( '_' ) ; - int x2 = Filename.indexOf ( '.' ) ; - if ( x1 > 0 ) { - _Temp_Last_File_Pre = Filename.substring ( 0 , x1+1 ) ; - _Temp_Last_File_Nr = ( Filename.substring ( x1+1, x2 ) ).toInt () ; - _Temp_Last_File_Post = Filename.substring ( x2 ) ; - } - else { - _Temp_Last_File_Pre = Filename.substring ( 0 , x2 ) + "_" ; - _Temp_Last_File_Nr = 0 ; - _Temp_Last_File_Post = Filename.substring ( x2 ) ; - } - return true ; - } - - -}; - - -// *********************************************************************************** -// *********************************************************************************** -_FS_class File_System ; - - -#endif diff --git a/RFLink_ESP/LuftDaten.h b/RFLink_ESP/LuftDaten.h deleted file mode 100644 index 6745fb3..0000000 --- a/RFLink_ESP/LuftDaten.h +++ /dev/null @@ -1,240 +0,0 @@ - -// Version 0.2 - -#ifndef LuftDaten_h -#define LuftDaten_h 0.2 - -#define SOFTWARE_VERSION "NRZ-2017-100" - -#define SDS_API_PIN 1 - -String LuftDaten_First_Part = "{\"software_version\": \"" + String(SOFTWARE_VERSION) + "\", \"sensordatavalues\":["; -String JSON_LuftData ; - -const char TXT_CONTENT_TYPE_JSON[] PROGMEM = "application/json"; - -const char* host_dusti = "api.luftdaten.info"; -const char* url_dusti = "/v1/push-sensor-data/"; -int httpPort_dusti = 443; - -const char* host_madavi = "api-rrd.madavi.de"; -const char* url_madavi = "/data.php"; -const int httpPort_madavi = 443; - - -// *********************************************** -// espid is needed as login name for the web-api's -// *********************************************** -#ifdef ESP32 - String esp_chipid = String ( GetChipID() ) ; -#else - String esp_chipid = String ( ESP.getChipId() ) ; -#endif - -// ***************************************************************** -//LUFTDATTTT "15218064" ) ) ; -// ***************************************************************** -void Luftdaten_Setup ( String ChipID_2_Use ) { - Serial.println ( "V" + String ( LuftDaten_h ) + " LuftDSaten_h" ) ; - #ifdef ESP32 - Serial.println ( "Chip-ID = " + String ( GetChipID() ) ) ; - #else - Serial.println ( "Chip-ID = " + String ( ESP.getChipId() ) ) ; - #endif - if ( ChipID_2_Use != "" ) { - esp_chipid = ChipID_2_Use ; - Serial.println ( "Chip-ID used = " + esp_chipid ) ; - } -} - -/***************************************************************** -/* convert value to json string * -/*****************************************************************/ -String Value2Json(const String& type, const String& value) { - String s = F("{\"value_type\":\"{t}\",\"value\":\"{v}\"},"); - s.replace("{t}", type); s.replace("{v}", value); - return s; -} - -// *********************************************************************** -// ugly, but it works -// *********************************************************************** -void Complete_JSON_String ( signed long Loop_Sample_Count ) { - String data_sample_times ; - - int signal_strength = WiFi.RSSI(); - data_sample_times = Value2Json("samples", String( long ( Loop_Sample_Count ))); - data_sample_times += Value2Json ( "signal", String(signal_strength) ); - - JSON_LuftData += data_sample_times ; - - // ********************** - // remove the final comma - // ********************** - //if ( JSON_Data [ JSON_Data.length() - 1 ] == "," ) { //ERROR: ISO C++ forbids comparison between pointer and integer [-fpermissive] - if ( JSON_LuftData.lastIndexOf (',') == ( JSON_LuftData.length() - 1 ) ) { - JSON_LuftData.remove(JSON_LuftData.length() - 1); - } - - //JSON_LuftData += ",{\"value_type\":\"SSID\",\"value\":\"" ; - //JSON_LuftData += WiFi.SSID() ; - //JSON_LuftData += "\"}" ; - // - //JSON_LuftData += "]}"; - - JSON_LuftData += "],\"SSID\":\"" ; - JSON_LuftData += WiFi.SSID() ; - JSON_LuftData += "\"}" ; - - return ; -} - - -/***************************************************************** -/* send data to rest api * -/*****************************************************************/ -void sendData(const String& data, const int pin, const char* host, const int httpPort, const char* url, const char* basic_auth_string, const String& contentType) { -Debug ( String(host) + data ) ; -//return ; - - #if defined(ESP8266) - - //debug_out(F("Start connecting to "), DEBUG_MIN_INFO, 0); - //debug_out(host, DEBUG_MIN_INFO, 1); - - String request_head = F("POST "); request_head += String(url); request_head += F(" HTTP/1.1\r\n"); - request_head += F("Host: "); request_head += String(host) + "\r\n"; - request_head += F("Content-Type: "); request_head += contentType + "\r\n"; - if (basic_auth_string != "") { request_head += F("Authorization: Basic "); request_head += String(basic_auth_string) + "\r\n";} - request_head += F("X-PIN: "); request_head += String(pin) + "\r\n"; - request_head += F("X-Sensor: esp8266-"); request_head += esp_chipid + "\r\n"; - request_head += F("Content-Length: "); request_head += String(data.length(), DEC) + "\r\n"; - request_head += F("Connection: close\r\n\r\n"); - - // Use WiFiClient class to create TCP connections - - if (httpPort == 443) { - - WiFiClientSecure client_s; - - client_s.setNoDelay(true); - client_s.setTimeout(20000); - - if (!client_s.connect(host, httpPort)) { -// debug_out(F("connection 1 failed"), DEBUG_ERROR, 1); -Debug ( "connection 1 failed" ); - return; - } - - //debug_out(F("Requesting URL: "), DEBUG_MIN_INFO, 0); - //debug_out(url, DEBUG_MIN_INFO, 1); - //debug_out(esp_chipid, DEBUG_MIN_INFO, 1); - //debug_out(data, DEBUG_MIN_INFO, 1); - - // send request to the server - - client_s.print(request_head); - - client_s.println(data); - - delay(10); - - // Read reply from server and print them - String Line = "" ; - while(client_s.available()) { - char c = client_s.read(); - Line += String ( c ) ; -// debug_out(String(c), DEBUG_MAX_INFO, 0); -Debug ( Line ) ; - } - -// debug_out(F("\nclosing connection\n------\n\n"), DEBUG_MIN_INFO, 1); - - } else { - - WiFiClient client; - - client.setNoDelay(true); - client.setTimeout(20000); - - if (!client.connect(host, httpPort)) { -// debug_out(F("connection 2 failed"), DEBUG_ERROR, 1); -Debug ( "connection 2 failed" ) ; - return; - } - -// debug_out(F("Requesting URL: "), DEBUG_MIN_INFO, 0); -// debug_out(url, DEBUG_MIN_INFO, 1); -// debug_out(esp_chipid, DEBUG_MIN_INFO, 1); -// debug_out(data, DEBUG_MIN_INFO, 1); - - client.print(request_head); - - client.println(data); - - delay(10); - - // Read reply from server and print them - while(client.available()) { - char c = client.read(); -// debug_out(String(c), DEBUG_MAX_INFO, 0); - } - -// debug_out(F("\nclosing connection\n------\n\n"), DEBUG_MIN_INFO, 1); - - } - -// debug_out(F("End connecting to "), DEBUG_MIN_INFO, 0); -// debug_out(host, DEBUG_MIN_INFO, 1); - - wdt_reset(); // nodemcu is alive - yield(); - #endif -} - -// *********************************************************************** -// *********************************************************************** -bool _Send_LuftData () { - - if ( JSON_LuftData.indexOf ( "SDS_P1" ) < 0 ) { - Debug ( "NO DATA for Luftfaten available" ) ; - return false ; - } - - String Temp = JSON_LuftData ; - int x1 = Temp.indexOf ( '}' ) ; - int x2 = Temp.indexOf ( '}', x1+1 ) ; - Temp.remove ( x2+1 ); - Temp += "]}" ; - Temp.replace ( "SDS_", "" ); - - sendData ( Temp, SDS_API_PIN, host_dusti, httpPort_dusti, url_dusti, "", FPSTR(TXT_CONTENT_TYPE_JSON)) ; - return true ; -/* -{ "software_version": "NRZ-2017-100", - "sensordatavalues": [ {"value_type":"SDS_P1","value":"31.34"}, - {"value_type":"SDS_P2","value":"17.61"}, - {"value_type":"samples","value":"5112893"}, - {"value_type":"signal","value":"-64"}], - "SSID":"MiRa_Home_Router"} -*/ -} - - -// *********************************************************************** -// *********************************************************************** -bool _Send_MadaviData () { - - if ( JSON_LuftData.indexOf ( "SDS_P1" ) < 0 ) { - Debug ( "NO DATA for Madavi available" ) ; - return false ; - } - - sendData ( JSON_LuftData, 0, host_madavi, httpPort_madavi, url_madavi, "", FPSTR(TXT_CONTENT_TYPE_JSON)) ; - return true ; - -} - - - -#endif diff --git a/RFLink_ESP/MLX90640_API.h b/RFLink_ESP/MLX90640_API.h deleted file mode 100644 index c13a282..0000000 --- a/RFLink_ESP/MLX90640_API.h +++ /dev/null @@ -1,1260 +0,0 @@ -/** - * @copyright (C) 2017 Melexis N.V. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef _MLX640_API_H_ -#define _MLX640_API_H_ - - - - -/** - * @copyright (C) 2017 Melexis N.V. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#include "MLX90640_I2C_Driver.h" -//#include "MLX90640_API.h" -#include - - typedef struct - { - int16_t kVdd; - int16_t vdd25; - float KvPTAT; - float KtPTAT; - uint16_t vPTAT25; - float alphaPTAT; - int16_t gainEE; - float tgc; - float cpKv; - float cpKta; - uint8_t resolutionEE; - uint8_t calibrationModeEE; - float KsTa; - float ksTo[4]; - int16_t ct[4]; - float alpha[768]; - int16_t offset[768]; - float kta[768]; - float kv[768]; - float cpAlpha[2]; - int16_t cpOffset[2]; - float ilChessC[3]; - uint16_t brokenPixels[5]; - uint16_t outlierPixels[5]; - } paramsMLX90640; - - -/* - int MLX90640_DumpEE(uint8_t slaveAddr, uint16_t *eeData); - int MLX90640_GetFrameData(uint8_t slaveAddr, uint16_t *frameData); - int MLX90640_ExtractParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); - float MLX90640_GetVdd(uint16_t *frameData, const paramsMLX90640 *params); - float MLX90640_GetTa(uint16_t *frameData, const paramsMLX90640 *params); - void MLX90640_GetImage(uint16_t *frameData, const paramsMLX90640 *params, float *result); - void MLX90640_CalculateTo(uint16_t *frameData, const paramsMLX90640 *params, float emissivity, float tr, float *result); - int MLX90640_SetResolution(uint8_t slaveAddr, uint8_t resolution); - int MLX90640_GetCurResolution(uint8_t slaveAddr); - int MLX90640_SetRefreshRate(uint8_t slaveAddr, uint8_t refreshRate); - int MLX90640_GetRefreshRate(uint8_t slaveAddr); - int MLX90640_GetSubPageNumber(uint16_t *frameData); - int MLX90640_GetCurMode(uint8_t slaveAddr); - int MLX90640_SetInterleavedMode(uint8_t slaveAddr); - int MLX90640_SetChessMode(uint8_t slaveAddr); - -void ExtractVDDParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -void ExtractPTATParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -void ExtractGainParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -void ExtractTgcParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -void ExtractResolutionParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -void ExtractKsTaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -void ExtractKsToParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -void ExtractAlphaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -void ExtractOffsetParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -void ExtractKtaPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -void ExtractKvPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -void ExtractCPParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -void ExtractCILCParameters(uint16_t *eeData, paramsMLX90640 *mlx90640); -int ExtractDeviatingPixels(uint16_t *eeData, paramsMLX90640 *mlx90640); -int CheckAdjacentPixels(uint16_t pix1, uint16_t pix2); -int CheckEEPROMValid(uint16_t *eeData); -*/ - - - int CheckEEPROMValid(uint16_t *eeData) - { - int deviceSelect; - deviceSelect = eeData[10] & 0x0040; - if(deviceSelect == 0) - { - return 0; - } - - return -7; - } - -//------------------------------------------------------------------------------ -void ExtractVDDParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - int16_t kVdd; - int16_t vdd25; - - kVdd = eeData[51]; - - kVdd = (eeData[51] & 0xFF00) >> 8; - if(kVdd > 127) - { - kVdd = kVdd - 256; - } - kVdd = 32 * kVdd; - vdd25 = eeData[51] & 0x00FF; - vdd25 = ((vdd25 - 256) << 5) - 8192; - - mlx90640->kVdd = kVdd; - mlx90640->vdd25 = vdd25; -} - -//------------------------------------------------------------------------------ -void ExtractPTATParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - float KvPTAT; - float KtPTAT; - int16_t vPTAT25; - float alphaPTAT; - - KvPTAT = (eeData[50] & 0xFC00) >> 10; - if(KvPTAT > 31) - { - KvPTAT = KvPTAT - 64; - } - KvPTAT = KvPTAT/4096; - - KtPTAT = eeData[50] & 0x03FF; - if(KtPTAT > 511) - { - KtPTAT = KtPTAT - 1024; - } - KtPTAT = KtPTAT/8; - - vPTAT25 = eeData[49]; - - alphaPTAT = (eeData[16] & 0xF000) / pow(2, (double)14) + 8.0f; - - mlx90640->KvPTAT = KvPTAT; - mlx90640->KtPTAT = KtPTAT; - mlx90640->vPTAT25 = vPTAT25; - mlx90640->alphaPTAT = alphaPTAT; -} - -//------------------------------------------------------------------------------ -void ExtractGainParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - int16_t gainEE; - - gainEE = eeData[48]; - if(gainEE > 32767) - { - gainEE = gainEE -65536; - } - - mlx90640->gainEE = gainEE; -} - - -//------------------------------------------------------------------------------ -void ExtractTgcParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - float tgc; - tgc = eeData[60] & 0x00FF; - if(tgc > 127) - { - tgc = tgc - 256; - } - tgc = tgc / 32.0f; - - mlx90640->tgc = tgc; -} - - -//------------------------------------------------------------------------------ -void ExtractResolutionParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - uint8_t resolutionEE; - resolutionEE = (eeData[56] & 0x3000) >> 12; - - mlx90640->resolutionEE = resolutionEE; -} - -//------------------------------------------------------------------------------ -void ExtractKsTaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - float KsTa; - KsTa = (eeData[60] & 0xFF00) >> 8; - if(KsTa > 127) - { - KsTa = KsTa -256; - } - KsTa = KsTa / 8192.0f; - - mlx90640->KsTa = KsTa; -} - -//------------------------------------------------------------------------------ -void ExtractKsToParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - int KsToScale; - int8_t step; - - step = ((eeData[63] & 0x3000) >> 12) * 10; - - mlx90640->ct[0] = -40; - mlx90640->ct[1] = 0; - mlx90640->ct[2] = (eeData[63] & 0x00F0) >> 4; - mlx90640->ct[3] = (eeData[63] & 0x0F00) >> 8; - - mlx90640->ct[2] = mlx90640->ct[2]*step; - mlx90640->ct[3] = mlx90640->ct[2] + mlx90640->ct[3]*step; - - KsToScale = (eeData[63] & 0x000F) + 8; - KsToScale = 1 << KsToScale; - - mlx90640->ksTo[0] = eeData[61] & 0x00FF; - mlx90640->ksTo[1] = (eeData[61] & 0xFF00) >> 8; - mlx90640->ksTo[2] = eeData[62] & 0x00FF; - mlx90640->ksTo[3] = (eeData[62] & 0xFF00) >> 8; - - - for(int i = 0; i < 4; i++) - { - if(mlx90640->ksTo[i] > 127) - { - mlx90640->ksTo[i] = mlx90640->ksTo[i] -256; - } - mlx90640->ksTo[i] = mlx90640->ksTo[i] / KsToScale; - } -} - -//------------------------------------------------------------------------------ -void ExtractAlphaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - int accRow[24]; - int accColumn[32]; - int p = 0; - int alphaRef; - uint8_t alphaScale; - uint8_t accRowScale; - uint8_t accColumnScale; - uint8_t accRemScale; - - - accRemScale = eeData[32] & 0x000F; - accColumnScale = (eeData[32] & 0x00F0) >> 4; - accRowScale = (eeData[32] & 0x0F00) >> 8; - alphaScale = ((eeData[32] & 0xF000) >> 12) + 30; - alphaRef = eeData[33]; - - for(int i = 0; i < 6; i++) - { - p = i * 4; - accRow[p + 0] = (eeData[34 + i] & 0x000F); - accRow[p + 1] = (eeData[34 + i] & 0x00F0) >> 4; - accRow[p + 2] = (eeData[34 + i] & 0x0F00) >> 8; - accRow[p + 3] = (eeData[34 + i] & 0xF000) >> 12; - } - - for(int i = 0; i < 24; i++) - { - if (accRow[i] > 7) - { - accRow[i] = accRow[i] - 16; - } - } - - for(int i = 0; i < 8; i++) - { - p = i * 4; - accColumn[p + 0] = (eeData[40 + i] & 0x000F); - accColumn[p + 1] = (eeData[40 + i] & 0x00F0) >> 4; - accColumn[p + 2] = (eeData[40 + i] & 0x0F00) >> 8; - accColumn[p + 3] = (eeData[40 + i] & 0xF000) >> 12; - } - - for(int i = 0; i < 32; i ++) - { - if (accColumn[i] > 7) - { - accColumn[i] = accColumn[i] - 16; - } - } - - for(int i = 0; i < 24; i++) - { - for(int j = 0; j < 32; j ++) - { - p = 32 * i +j; - mlx90640->alpha[p] = (eeData[64 + p] & 0x03F0) >> 4; - if (mlx90640->alpha[p] > 31) - { - mlx90640->alpha[p] = mlx90640->alpha[p] - 64; - } - mlx90640->alpha[p] = mlx90640->alpha[p]*(1 << accRemScale); - mlx90640->alpha[p] = (alphaRef + (accRow[i] << accRowScale) + (accColumn[j] << accColumnScale) + mlx90640->alpha[p]); - mlx90640->alpha[p] = mlx90640->alpha[p] / pow(2,(double)alphaScale); - } - } -} - -//------------------------------------------------------------------------------ -void ExtractOffsetParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - int occRow[24]; - int occColumn[32]; - int p = 0; - int16_t offsetRef; - uint8_t occRowScale; - uint8_t occColumnScale; - uint8_t occRemScale; - - - occRemScale = (eeData[16] & 0x000F); - occColumnScale = (eeData[16] & 0x00F0) >> 4; - occRowScale = (eeData[16] & 0x0F00) >> 8; - offsetRef = eeData[17]; - if (offsetRef > 32767) - { - offsetRef = offsetRef - 65536; - } - - for(int i = 0; i < 6; i++) - { - p = i * 4; - occRow[p + 0] = (eeData[18 + i] & 0x000F); - occRow[p + 1] = (eeData[18 + i] & 0x00F0) >> 4; - occRow[p + 2] = (eeData[18 + i] & 0x0F00) >> 8; - occRow[p + 3] = (eeData[18 + i] & 0xF000) >> 12; - } - - for(int i = 0; i < 24; i++) - { - if (occRow[i] > 7) - { - occRow[i] = occRow[i] - 16; - } - } - - for(int i = 0; i < 8; i++) - { - p = i * 4; - occColumn[p + 0] = (eeData[24 + i] & 0x000F); - occColumn[p + 1] = (eeData[24 + i] & 0x00F0) >> 4; - occColumn[p + 2] = (eeData[24 + i] & 0x0F00) >> 8; - occColumn[p + 3] = (eeData[24 + i] & 0xF000) >> 12; - } - - for(int i = 0; i < 32; i ++) - { - if (occColumn[i] > 7) - { - occColumn[i] = occColumn[i] - 16; - } - } - - for(int i = 0; i < 24; i++) - { - for(int j = 0; j < 32; j ++) - { - p = 32 * i +j; - mlx90640->offset[p] = (eeData[64 + p] & 0xFC00) >> 10; - if (mlx90640->offset[p] > 31) - { - mlx90640->offset[p] = mlx90640->offset[p] - 64; - } - mlx90640->offset[p] = mlx90640->offset[p]*(1 << occRemScale); - mlx90640->offset[p] = (offsetRef + (occRow[i] << occRowScale) + (occColumn[j] << occColumnScale) + mlx90640->offset[p]); - } - } -} - -//------------------------------------------------------------------------------ -void ExtractKtaPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - int p = 0; - int8_t KtaRC[4]; - int8_t KtaRoCo; - int8_t KtaRoCe; - int8_t KtaReCo; - int8_t KtaReCe; - uint8_t ktaScale1; - uint8_t ktaScale2; - uint8_t split; - - KtaRoCo = (eeData[54] & 0xFF00) >> 8; - if (KtaRoCo > 127) - { - KtaRoCo = KtaRoCo - 256; - } - KtaRC[0] = KtaRoCo; - - KtaReCo = (eeData[54] & 0x00FF); - if (KtaReCo > 127) - { - KtaReCo = KtaReCo - 256; - } - KtaRC[2] = KtaReCo; - - KtaRoCe = (eeData[55] & 0xFF00) >> 8; - if (KtaRoCe > 127) - { - KtaRoCe = KtaRoCe - 256; - } - KtaRC[1] = KtaRoCe; - - KtaReCe = (eeData[55] & 0x00FF); - if (KtaReCe > 127) - { - KtaReCe = KtaReCe - 256; - } - KtaRC[3] = KtaReCe; - - ktaScale1 = ((eeData[56] & 0x00F0) >> 4) + 8; - ktaScale2 = (eeData[56] & 0x000F); - - for(int i = 0; i < 24; i++) - { - for(int j = 0; j < 32; j ++) - { - p = 32 * i +j; - split = 2*(p/32 - (p/64)*2) + p%2; - mlx90640->kta[p] = (eeData[64 + p] & 0x000E) >> 1; - if (mlx90640->kta[p] > 3) - { - mlx90640->kta[p] = mlx90640->kta[p] - 8; - } - mlx90640->kta[p] = mlx90640->kta[p] * (1 << ktaScale2); - mlx90640->kta[p] = KtaRC[split] + mlx90640->kta[p]; - mlx90640->kta[p] = mlx90640->kta[p] / pow(2,(double)ktaScale1); - } - } -} - -//------------------------------------------------------------------------------ -void ExtractKvPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - int p = 0; - int8_t KvT[4]; - int8_t KvRoCo; - int8_t KvRoCe; - int8_t KvReCo; - int8_t KvReCe; - uint8_t kvScale; - uint8_t split; - - KvRoCo = (eeData[52] & 0xF000) >> 12; - if (KvRoCo > 7) - { - KvRoCo = KvRoCo - 16; - } - KvT[0] = KvRoCo; - - KvReCo = (eeData[52] & 0x0F00) >> 8; - if (KvReCo > 7) - { - KvReCo = KvReCo - 16; - } - KvT[2] = KvReCo; - - KvRoCe = (eeData[52] & 0x00F0) >> 4; - if (KvRoCe > 7) - { - KvRoCe = KvRoCe - 16; - } - KvT[1] = KvRoCe; - - KvReCe = (eeData[52] & 0x000F); - if (KvReCe > 7) - { - KvReCe = KvReCe - 16; - } - KvT[3] = KvReCe; - - kvScale = (eeData[56] & 0x0F00) >> 8; - - - for(int i = 0; i < 24; i++) - { - for(int j = 0; j < 32; j ++) - { - p = 32 * i +j; - split = 2*(p/32 - (p/64)*2) + p%2; - mlx90640->kv[p] = KvT[split]; - mlx90640->kv[p] = mlx90640->kv[p] / pow(2,(double)kvScale); - } - } -} - -//------------------------------------------------------------------------------ -void ExtractCPParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - float alphaSP[2]; - int16_t offsetSP[2]; - float cpKv; - float cpKta; - uint8_t alphaScale; - uint8_t ktaScale1; - uint8_t kvScale; - - alphaScale = ((eeData[32] & 0xF000) >> 12) + 27; - - offsetSP[0] = (eeData[58] & 0x03FF); - if (offsetSP[0] > 511) - { - offsetSP[0] = offsetSP[0] - 1024; - } - - offsetSP[1] = (eeData[58] & 0xFC00) >> 10; - if (offsetSP[1] > 31) - { - offsetSP[1] = offsetSP[1] - 64; - } - offsetSP[1] = offsetSP[1] + offsetSP[0]; - - alphaSP[0] = (eeData[57] & 0x03FF); - if (alphaSP[0] > 511) - { - alphaSP[0] = alphaSP[0] - 1024; - } - alphaSP[0] = alphaSP[0] / pow(2,(double)alphaScale); - - alphaSP[1] = (eeData[57] & 0xFC00) >> 10; - if (alphaSP[1] > 31) - { - alphaSP[1] = alphaSP[1] - 64; - } - alphaSP[1] = (1 + alphaSP[1]/128) * alphaSP[0]; - - cpKta = (eeData[59] & 0x00FF); - if (cpKta > 127) - { - cpKta = cpKta - 256; - } - ktaScale1 = ((eeData[56] & 0x00F0) >> 4) + 8; - mlx90640->cpKta = cpKta / pow(2,(double)ktaScale1); - - cpKv = (eeData[59] & 0xFF00) >> 8; - if (cpKv > 127) - { - cpKv = cpKv - 256; - } - kvScale = (eeData[56] & 0x0F00) >> 8; - mlx90640->cpKv = cpKv / pow(2,(double)kvScale); - - mlx90640->cpAlpha[0] = alphaSP[0]; - mlx90640->cpAlpha[1] = alphaSP[1]; - mlx90640->cpOffset[0] = offsetSP[0]; - mlx90640->cpOffset[1] = offsetSP[1]; -} - -//------------------------------------------------------------------------------ -void ExtractCILCParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - float ilChessC[3]; - uint8_t calibrationModeEE; - - calibrationModeEE = (eeData[10] & 0x0800) >> 4; - calibrationModeEE = calibrationModeEE ^ 0x80; - - ilChessC[0] = (eeData[53] & 0x003F); - if (ilChessC[0] > 31) - { - ilChessC[0] = ilChessC[0] - 64; - } - ilChessC[0] = ilChessC[0] / 16.0f; - - ilChessC[1] = (eeData[53] & 0x07C0) >> 6; - if (ilChessC[1] > 15) - { - ilChessC[1] = ilChessC[1] - 32; - } - ilChessC[1] = ilChessC[1] / 2.0f; - - ilChessC[2] = (eeData[53] & 0xF800) >> 11; - if (ilChessC[2] > 15) - { - ilChessC[2] = ilChessC[2] - 32; - } - ilChessC[2] = ilChessC[2] / 8.0f; - - mlx90640->calibrationModeEE = calibrationModeEE; - mlx90640->ilChessC[0] = ilChessC[0]; - mlx90640->ilChessC[1] = ilChessC[1]; - mlx90640->ilChessC[2] = ilChessC[2]; -} - -//------------------------------------------------------------------------------ - int CheckAdjacentPixels(uint16_t pix1, uint16_t pix2) - { - int pixPosDif; - - pixPosDif = pix1 - pix2; - if(pixPosDif > -34 && pixPosDif < -30) - { - return -6; - } - if(pixPosDif > -2 && pixPosDif < 2) - { - return -6; - } - if(pixPosDif > 30 && pixPosDif < 34) - { - return -6; - } - - return 0; - } - - - -//------------------------------------------------------------------------------ -int ExtractDeviatingPixels(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - uint16_t pixCnt = 0; - uint16_t brokenPixCnt = 0; - uint16_t outlierPixCnt = 0; - int warn = 0; - int i; - - for(pixCnt = 0; pixCnt<5; pixCnt++) - { - mlx90640->brokenPixels[pixCnt] = 0xFFFF; - mlx90640->outlierPixels[pixCnt] = 0xFFFF; - } - - pixCnt = 0; - while (pixCnt < 768 && brokenPixCnt < 5 && outlierPixCnt < 5) - { - if(eeData[pixCnt+64] == 0) - { - mlx90640->brokenPixels[brokenPixCnt] = pixCnt; - brokenPixCnt = brokenPixCnt + 1; - } - else if((eeData[pixCnt+64] & 0x0001) != 0) - { - mlx90640->outlierPixels[outlierPixCnt] = pixCnt; - outlierPixCnt = outlierPixCnt + 1; - } - - pixCnt = pixCnt + 1; - - } - - if(brokenPixCnt > 4) - { - warn = -3; - } - else if(outlierPixCnt > 4) - { - warn = -4; - } - else if((brokenPixCnt + outlierPixCnt) > 4) - { - warn = -5; - } - else - { - for(pixCnt=0; pixCntbrokenPixels[pixCnt],mlx90640->brokenPixels[i]); - if(warn != 0) - { - return warn; - } - } - } - - for(pixCnt=0; pixCntoutlierPixels[pixCnt],mlx90640->outlierPixels[i]); - if(warn != 0) - { - return warn; - } - } - } - - for(pixCnt=0; pixCntbrokenPixels[pixCnt],mlx90640->outlierPixels[i]); - if(warn != 0) - { - return warn; - } - } - } - - } - - - return warn; - -} - - -//------------------------------------------------------------------------------ -float MLX90640_GetVdd(uint16_t *frameData, const paramsMLX90640 *params) -{ - float vdd; - float resolutionCorrection; - - int resolutionRAM; - - vdd = frameData[810]; - if(vdd > 32767) - { - vdd = vdd - 65536; - } - resolutionRAM = (frameData[832] & 0x0C00) >> 10; - resolutionCorrection = pow(2, (double)params->resolutionEE) / pow(2, (double)resolutionRAM); - vdd = (resolutionCorrection * vdd - params->vdd25) / params->kVdd + 3.3; - - return vdd; -} - -//------------------------------------------------------------------------------ -float MLX90640_GetTa(uint16_t *frameData, const paramsMLX90640 *params) -{ - float ptat; - float ptatArt; - float vdd; - float ta; - - vdd = MLX90640_GetVdd(frameData, params); - - ptat = frameData[800]; - if(ptat > 32767) - { - ptat = ptat - 65536; - } - - ptatArt = frameData[768]; - if(ptatArt > 32767) - { - ptatArt = ptatArt - 65536; - } - ptatArt = (ptat / (ptat * params->alphaPTAT + ptatArt)) * pow(2, (double)18); - - ta = (ptatArt / (1 + params->KvPTAT * (vdd - 3.3)) - params->vPTAT25); - ta = ta / params->KtPTAT + 25; - - return ta; -} - -//------------------------------------------------------------------------------ -int MLX90640_GetSubPageNumber(uint16_t *frameData) -{ - return frameData[833]; - -} - - - -int MLX90640_DumpEE(uint8_t slaveAddr, uint16_t *eeData) -{ - return MLX90640_I2CRead(slaveAddr, 0x2400, 832, eeData); -} - -// *********************************************************************************** -// *********************************************************************************** -bool MLX90640_GetFrameData_Status ( uint8_t slaveAddr, uint16_t *frameData ) { - uint16_t dataReady ; - uint16_t statusRegister ; - int error ; - error = MLX90640_I2CRead ( slaveAddr, 0x8000, 1, &statusRegister ) ; - if ( error != 0 ) return false ; - dataReady = statusRegister & 0x0008 ; - if ( dataReady == 0 ) return false ; - return true ; -} - -// *********************************************************************************** -// *********************************************************************************** -int MLX90640_GetFrameData(uint8_t slaveAddr, uint16_t *frameData) -{ - uint16_t dataReady = 1; - uint16_t controlRegister1; - uint16_t statusRegister; - int error = 1; - uint8_t cnt = 0; - - dataReady = 0; - while(dataReady == 0) - { - error = MLX90640_I2CRead(slaveAddr, 0x8000, 1, &statusRegister); - if(error != 0) - { - return error; - } - dataReady = statusRegister & 0x0008; - } - - while(dataReady != 0 && cnt < 5) - { - error = MLX90640_I2CWrite(slaveAddr, 0x8000, 0x0030); - if(error == -1) - { - return error; - } - - error = MLX90640_I2CRead(slaveAddr, 0x0400, 832, frameData); - if(error != 0) - { - return error; - } - - error = MLX90640_I2CRead(slaveAddr, 0x8000, 1, &statusRegister); - if(error != 0) - { - return error; - } - dataReady = statusRegister & 0x0008; - cnt = cnt + 1; - } - - if(cnt > 4) - { - return -8; - } - - error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1); - frameData[832] = controlRegister1; - frameData[833] = statusRegister & 0x0001; - - if(error != 0) - { - return error; - } - - return frameData[833]; -} - -int MLX90640_ExtractParameters(uint16_t *eeData, paramsMLX90640 *mlx90640) -{ - int error = CheckEEPROMValid(eeData); - - if(error == 0) - { - ExtractVDDParameters(eeData, mlx90640); - ExtractPTATParameters(eeData, mlx90640); - ExtractGainParameters(eeData, mlx90640); - ExtractTgcParameters(eeData, mlx90640); - ExtractResolutionParameters(eeData, mlx90640); - ExtractKsTaParameters(eeData, mlx90640); - ExtractKsToParameters(eeData, mlx90640); - ExtractAlphaParameters(eeData, mlx90640); - ExtractOffsetParameters(eeData, mlx90640); - ExtractKtaPixelParameters(eeData, mlx90640); - ExtractKvPixelParameters(eeData, mlx90640); - ExtractCPParameters(eeData, mlx90640); - ExtractCILCParameters(eeData, mlx90640); - error = ExtractDeviatingPixels(eeData, mlx90640); - } - - return error; - -} - -//------------------------------------------------------------------------------ - -int MLX90640_SetResolution(uint8_t slaveAddr, uint8_t resolution) -{ - uint16_t controlRegister1; - int value; - int error; - - value = (resolution & 0x03) << 10; - - error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1); - - if(error == 0) - { - value = (controlRegister1 & 0xF3FF) | value; - error = MLX90640_I2CWrite(slaveAddr, 0x800D, value); - } - - return error; -} - -//------------------------------------------------------------------------------ - -int MLX90640_GetCurResolution(uint8_t slaveAddr) -{ - uint16_t controlRegister1; - int resolutionRAM; - int error; - - error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1); - if(error != 0) - { - return error; - } - resolutionRAM = (controlRegister1 & 0x0C00) >> 10; - - return resolutionRAM; -} - -//------------------------------------------------------------------------------ - -int MLX90640_SetRefreshRate(uint8_t slaveAddr, uint8_t refreshRate) -{ - uint16_t controlRegister1; - int value; - int error; - - value = (refreshRate & 0x07)<<7; - - error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1); - if(error == 0) - { - value = (controlRegister1 & 0xFC7F) | value; - error = MLX90640_I2CWrite(slaveAddr, 0x800D, value); - } - - return error; -} - -//------------------------------------------------------------------------------ - -int MLX90640_GetRefreshRate(uint8_t slaveAddr) -{ - uint16_t controlRegister1; - int refreshRate; - int error; - - error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1); - if(error != 0) - { - return error; - } - refreshRate = (controlRegister1 & 0x0380) >> 7; - - return refreshRate; -} - -//------------------------------------------------------------------------------ - -int MLX90640_SetInterleavedMode(uint8_t slaveAddr) -{ - uint16_t controlRegister1; - int value; - int error; - - error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1); - - if(error == 0) - { - value = (controlRegister1 & 0xEFFF); - error = MLX90640_I2CWrite(slaveAddr, 0x800D, value); - } - - return error; -} - -//------------------------------------------------------------------------------ - -int MLX90640_SetChessMode(uint8_t slaveAddr) -{ - uint16_t controlRegister1; - int value; - int error; - - error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1); - - if(error == 0) - { - value = (controlRegister1 | 0x1000); - error = MLX90640_I2CWrite(slaveAddr, 0x800D, value); - } - - return error; -} - -//------------------------------------------------------------------------------ - -int MLX90640_GetCurMode(uint8_t slaveAddr) -{ - uint16_t controlRegister1; - int modeRAM; - int error; - - error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1); - if(error != 0) - { - return error; - } - modeRAM = (controlRegister1 & 0x1000) >> 12; - - return modeRAM; -} - -//------------------------------------------------------------------------------ - -void MLX90640_CalculateTo(uint16_t *frameData, const paramsMLX90640 *params, float emissivity, float tr, float *result) -{ - float vdd; - float ta; - float ta4; - float tr4; - float taTr; - float gain; - float irDataCP[2]; - float irData; - float alphaCompensated; - uint8_t mode; - int8_t ilPattern; - int8_t chessPattern; - int8_t pattern; - int8_t conversionPattern; - float Sx; - float To; - float alphaCorrR[4]; - int8_t range; - uint16_t subPage; - - subPage = frameData[833]; - vdd = MLX90640_GetVdd(frameData, params); - ta = MLX90640_GetTa(frameData, params); - ta4 = pow((ta + 273.15), (double)4); - tr4 = pow((tr + 273.15), (double)4); - taTr = tr4 - (tr4-ta4)/emissivity; - - alphaCorrR[0] = 1 / (1 + params->ksTo[0] * 40); - alphaCorrR[1] = 1 ; - alphaCorrR[2] = (1 + params->ksTo[2] * params->ct[2]); - alphaCorrR[3] = alphaCorrR[2] * (1 + params->ksTo[3] * (params->ct[3] - params->ct[2])); - -//------------------------- Gain calculation ----------------------------------- - gain = frameData[778]; - if(gain > 32767) - { - gain = gain - 65536; - } - - gain = params->gainEE / gain; - -//------------------------- To calculation ------------------------------------- - mode = (frameData[832] & 0x1000) >> 5; - - irDataCP[0] = frameData[776]; - irDataCP[1] = frameData[808]; - for( int i = 0; i < 2; i++) - { - if(irDataCP[i] > 32767) - { - irDataCP[i] = irDataCP[i] - 65536; - } - irDataCP[i] = irDataCP[i] * gain; - } - irDataCP[0] = irDataCP[0] - params->cpOffset[0] * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); - if( mode == params->calibrationModeEE) - { - irDataCP[1] = irDataCP[1] - params->cpOffset[1] * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); - } - else - { - irDataCP[1] = irDataCP[1] - (params->cpOffset[1] + params->ilChessC[0]) * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); - } - - for( int pixelNumber = 0; pixelNumber < 768; pixelNumber++) - { - ilPattern = pixelNumber / 32 - (pixelNumber / 64) * 2; - chessPattern = ilPattern ^ (pixelNumber - (pixelNumber/2)*2); - conversionPattern = ((pixelNumber + 2) / 4 - (pixelNumber + 3) / 4 + (pixelNumber + 1) / 4 - pixelNumber / 4) * (1 - 2 * ilPattern); - - if(mode == 0) - { - pattern = ilPattern; - } - else - { - pattern = chessPattern; - } - - if(pattern == frameData[833]) - { - irData = frameData[pixelNumber]; - if(irData > 32767) - { - irData = irData - 65536; - } - irData = irData * gain; - - irData = irData - params->offset[pixelNumber]*(1 + params->kta[pixelNumber]*(ta - 25))*(1 + params->kv[pixelNumber]*(vdd - 3.3)); - if(mode != params->calibrationModeEE) - { - irData = irData + params->ilChessC[2] * (2 * ilPattern - 1) - params->ilChessC[1] * conversionPattern; - } - - irData = irData / emissivity; - - irData = irData - params->tgc * irDataCP[subPage]; - - alphaCompensated = (params->alpha[pixelNumber] - params->tgc * params->cpAlpha[subPage])*(1 + params->KsTa * (ta - 25)); - - Sx = pow((double)alphaCompensated, (double)3) * (irData + alphaCompensated * taTr); - Sx = sqrt(sqrt(Sx)) * params->ksTo[1]; - - To = sqrt(sqrt(irData/(alphaCompensated * (1 - params->ksTo[1] * 273.15) + Sx) + taTr)) - 273.15; - - if(To < params->ct[1]) - { - range = 0; - } - else if(To < params->ct[2]) - { - range = 1; - } - else if(To < params->ct[3]) - { - range = 2; - } - else - { - range = 3; - } - - To = sqrt(sqrt(irData / (alphaCompensated * alphaCorrR[range] * (1 + params->ksTo[range] * (To - params->ct[range]))) + taTr)) - 273.15; - - result[pixelNumber] = To; - } - } -} - -//------------------------------------------------------------------------------ - -void MLX90640_GetImage(uint16_t *frameData, const paramsMLX90640 *params, float *result) -{ - float vdd; - float ta; - float gain; - float irDataCP[2]; - float irData; - float alphaCompensated; - uint8_t mode; - int8_t ilPattern; - int8_t chessPattern; - int8_t pattern; - int8_t conversionPattern; - float image; - uint16_t subPage; - - subPage = frameData[833]; - vdd = MLX90640_GetVdd(frameData, params); - ta = MLX90640_GetTa(frameData, params); - -//------------------------- Gain calculation ----------------------------------- - gain = frameData[778]; - if(gain > 32767) - { - gain = gain - 65536; - } - - gain = params->gainEE / gain; - -//------------------------- Image calculation ------------------------------------- - mode = (frameData[832] & 0x1000) >> 5; - - irDataCP[0] = frameData[776]; - irDataCP[1] = frameData[808]; - for( int i = 0; i < 2; i++) - { - if(irDataCP[i] > 32767) - { - irDataCP[i] = irDataCP[i] - 65536; - } - irDataCP[i] = irDataCP[i] * gain; - } - irDataCP[0] = irDataCP[0] - params->cpOffset[0] * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); - if( mode == params->calibrationModeEE) - { - irDataCP[1] = irDataCP[1] - params->cpOffset[1] * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); - } - else - { - irDataCP[1] = irDataCP[1] - (params->cpOffset[1] + params->ilChessC[0]) * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3)); - } - - for( int pixelNumber = 0; pixelNumber < 768; pixelNumber++) - { - ilPattern = pixelNumber / 32 - (pixelNumber / 64) * 2; - chessPattern = ilPattern ^ (pixelNumber - (pixelNumber/2)*2); - conversionPattern = ((pixelNumber + 2) / 4 - (pixelNumber + 3) / 4 + (pixelNumber + 1) / 4 - pixelNumber / 4) * (1 - 2 * ilPattern); - - if(mode == 0) - { - pattern = ilPattern; - } - else - { - pattern = chessPattern; - } - - if(pattern == frameData[833]) - { - irData = frameData[pixelNumber]; - if(irData > 32767) - { - irData = irData - 65536; - } - irData = irData * gain; - - irData = irData - params->offset[pixelNumber]*(1 + params->kta[pixelNumber]*(ta - 25))*(1 + params->kv[pixelNumber]*(vdd - 3.3)); - if(mode != params->calibrationModeEE) - { - irData = irData + params->ilChessC[2] * (2 * ilPattern - 1) - params->ilChessC[1] * conversionPattern; - } - - irData = irData - params->tgc * irDataCP[subPage]; - - alphaCompensated = (params->alpha[pixelNumber] - params->tgc * params->cpAlpha[subPage])*(1 + params->KsTa * (ta - 25)); - - image = irData/alphaCompensated; - - result[pixelNumber] = image; - } - } -} - - - - //------------------------------------------------------------------------------ - -#endif diff --git a/RFLink_ESP/MLX90640_I2C_Driver.h b/RFLink_ESP/MLX90640_I2C_Driver.h deleted file mode 100644 index d8cde65..0000000 --- a/RFLink_ESP/MLX90640_I2C_Driver.h +++ /dev/null @@ -1,201 +0,0 @@ -/** - @copyright (C) 2017 Melexis N.V. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ -#ifndef _MLX90640_I2C_Driver_H_ -#define _MLX90640_I2C_Driver_H_ - -#include -#include - -//Define the size of the I2C buffer based on the platform the user has -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) - -//I2C_BUFFER_LENGTH is defined in Wire.H -#define I2C_BUFFER_LENGTH BUFFER_LENGTH - -#elif defined(__SAMD21G18A__) - -//SAMD21 uses RingBuffer.h -#define I2C_BUFFER_LENGTH SERIAL_BUFFER_SIZE - -#elif __MK20DX256__ -//Teensy - -#elif ARDUINO_ARCH_ESP32 -//ESP32 based platforms - -#else - -//The catch-all default is 32 -#define I2C_BUFFER_LENGTH 32 - -#endif -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - - -//void MLX90640_I2CInit(void); -//int MLX90640_I2CRead(uint8_t slaveAddr, unsigned int startAddress, unsigned int nWordsRead, uint16_t *data); -//int MLX90640_I2CWrite(uint8_t slaveAddr, unsigned int writeAddress, uint16_t data); -//void MLX90640_I2CFreqSet(int freq); - -/** - @copyright (C) 2017 Melexis N.V. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -#include -#include - -//#include "MLX90640_I2C_Driver.h" - -// *********************************************************************************************** -// *********************************************************************************************** -void MLX90640_I2CInit() -{ -} - -// *********************************************************************************************** -//Read a number of words from startAddress. Store into Data array. -//Returns 0 if successful, -1 if error -// *********************************************************************************************** -/* -int MLX90640_I2CRead(uint8_t _deviceAddress, unsigned int startAddress, unsigned int nWordsRead, uint16_t *data) -{ - - //Caller passes number of 'unsigned ints to read', increase this to 'bytes to read' - uint16_t bytesRemaining = nWordsRead * 2; - - //It doesn't look like sequential read works. Do we need to re-issue the address command each time? - - uint16_t dataSpot = 0; //Start at beginning of array - - //Setup a series of chunked I2C_BUFFER_LENGTH byte reads - while (bytesRemaining > 0) - { - Wire.beginTransmission(_deviceAddress); - Wire.write(startAddress >> 8); //MSB - Wire.write(startAddress & 0xFF); //LSB - if (Wire.endTransmission(false) != 0) //Do not release bus - { - Serial.println("No ack read"); - return (0); //Sensor did not ACK - } - - uint16_t numberOfBytesToRead = bytesRemaining; - if (numberOfBytesToRead > I2C_BUFFER_LENGTH) numberOfBytesToRead = I2C_BUFFER_LENGTH; - - Wire.requestFrom((uint8_t)_deviceAddress, numberOfBytesToRead); - if (Wire.available()) - { - for (uint16_t x = 0 ; x < numberOfBytesToRead / 2; x++) - { - //Store data into array - data[dataSpot] = Wire.read() << 8; //MSB - data[dataSpot] |= Wire.read(); //LSB - - dataSpot++; - } - } - - bytesRemaining -= numberOfBytesToRead; - - startAddress += numberOfBytesToRead / 2; - } - - return (0); //Success -} -*/ -int MLX90640_I2CRead(uint8_t _deviceAddress, unsigned int startAddress, unsigned int nWordsRead, uint16_t *data) -{ - // nWordsRead must be <= 32767 - Wire.beginTransmission(_deviceAddress); - Wire.write(startAddress >> 8); //MSB - Wire.write(startAddress & 0xFF); //LSB - Wire.endTransmission(false); - i2c_err_t error = Wire.readTransmission(_deviceAddress, (uint8_t*) data, nWordsRead*2); - if(error != 0){//problems - Serial.printf("Block read from sensor(0x%02X) at address=%d of %d uint16_t's failed=%d(%s)\n", - _deviceAddress,startAddress,nWordsRead,error,Wire.getErrorText(error)); - } - else { // reverse byte order, sensor Big Endian, ESP32 Little Endian - for(auto a = 0; a>8)&0xff); - } - } - return 0; -} -// *********************************************************************************************** -//Set I2C Freq, in kHz -//MLX90640_I2CFreqSet(1000) sets frequency to 1MHz -// *********************************************************************************************** -void MLX90640_I2CFreqSet(int freq) -{ - //i2c.frequency(1000 * freq); - Wire.setClock((long)1000 * freq); -} - -// *********************************************************************************************** -//Write two bytes to a two byte address -// *********************************************************************************************** -int MLX90640_I2CWrite(uint8_t _deviceAddress, unsigned int writeAddress, uint16_t data) -{ - Wire.beginTransmission((uint8_t)_deviceAddress); - Wire.write(writeAddress >> 8); //MSB - Wire.write(writeAddress & 0xFF); //LSB - Wire.write(data >> 8); //MSB - Wire.write(data & 0xFF); //LSB - if (Wire.endTransmission() != 0) - { - //Sensor did not ACK - Serial.println("Error: Sensor did not ack"); - return (-1); - } - - uint16_t dataCheck; - MLX90640_I2CRead(_deviceAddress, writeAddress, 1, &dataCheck); - if (dataCheck != data) - { - //Serial.println("The write request didn't stick"); - return -2; - } - - return (0); //Success -} - - -// void MLX90640_I2CInit() -// void MLX90640_I2CFreqSet(int freq) -// int MLX90640_I2CRead(uint8_t _deviceAddress, unsigned int startAddress, unsigned int nWordsRead, uint16_t *data) -// int MLX90640_I2CWrite(uint8_t _deviceAddress, unsigned int writeAddress, uint16_t data) - -// *********************************************************************************************** -// *********************************************************************************************** - - -#endif diff --git a/RFLink_ESP/My_DateTime.h b/RFLink_ESP/My_DateTime.h deleted file mode 100644 index 34eff4c..0000000 --- a/RFLink_ESP/My_DateTime.h +++ /dev/null @@ -1,49 +0,0 @@ -// Version 0.1 16-06-2019, SM - -#ifndef My_DateTime_h -#define My_DateTime_h 0.1 - -#include - -// **************************************************************************** -// **************************************************************************** -String UnixTime_2_String ( time_t DateTime ) { - Serial.println ( "TODO: UnixTime_2_String" ) ; -} - -// **************************************************************************** -// String_2_UnixTime ( "1970-01-01 00:00:01" ) ; -// **************************************************************************** -time_t String_2_UnixTime ( String calTimestamp ) { - struct tm tm; - //Serial.println("Parsing " + calTimestamp); - String year = calTimestamp.substring ( 0, 4 ) ; - String month = calTimestamp.substring ( 5, 7 ) ; - if ( month.startsWith ( "0" ) ) { - month = month.substring ( 1 ) ; - } - String day = calTimestamp.substring ( 8, 10 ); - if ( day.startsWith ( "0" ) ) { - month = day.substring ( 1 ) ; - } - tm.tm_year = year.toInt() - 1900; - tm.tm_mon = month.toInt() - 1; - tm.tm_mday = day.toInt(); - tm.tm_hour = calTimestamp.substring ( 11, 13 ).toInt(); - tm.tm_min = calTimestamp.substring ( 14, 16 ).toInt(); - tm.tm_sec = calTimestamp.substring ( 17, 19 ).toInt(); - -/* -char datetimeBuffer[20] = ""; -sprintf(datetimeBuffer, "%04d-%02d-%02d %02d:%02d:%02d", - tm.tm_year, tm.tm_mon, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec ) ; -Serial.println(String(datetimeBuffer )) ; -Serial.println ( mktime ( &tm ) ) ; -//*/ - - return mktime ( &tm ) ; -} - - -#endif \ No newline at end of file diff --git a/RFLink_ESP/My_ESP32_Support.h b/RFLink_ESP/My_ESP32_Support.h deleted file mode 100644 index 6ba1dd2..0000000 --- a/RFLink_ESP/My_ESP32_Support.h +++ /dev/null @@ -1,17 +0,0 @@ - - -#ifndef My_ESP32_Support_h -#define My_ESP32_Support_h - - - -uint32_t GetChipID () { - uint64_t ChipID; - ChipID = ESP.getEfuseMac();//The chip ID is essentially its MAC address(length: 6 bytes). - //Serial.printf("ESP32 Chip ID = %04X",(uint16_t)(chipid>>32));//print High 2 bytes - //Serial.printf("%08X\n",(uint32_t)chipid);//print Low 4bytes. - return (uint32_t) ChipID ; -} - - -#endif \ No newline at end of file diff --git a/RFLink_ESP/My_File_Support.h b/RFLink_ESP/My_File_Support.h deleted file mode 100644 index 5ded79b..0000000 --- a/RFLink_ESP/My_File_Support.h +++ /dev/null @@ -1,31 +0,0 @@ - - -#ifndef My_File_Support_h -#define My_File_Support_h - - - -// ************************************************** -// Parse the filename and store the parts -// ************************************************** -int Parse_FileNr ( String Filename ) { - int File_Nr = 0 ; - if ( Filename.length() == 0 ) return File_Nr ; - - int x1 = Filename.indexOf ( '_' ) ; - int x2 = Filename.indexOf ( '.' ) ; -//Serial.println ( "x1 : x2" ) ; -//Serial.println ( x1 ) ; -//Serial.println ( x2 ) ; - if ( ( x1 > 0 ) && ( x2 > x1 ) ) { - String Part = Filename.substring ( x1+1, x2 ) ; - File_Nr = Part.toInt() ; -//Serial.println ( Part ); -//Serial.println ( File_Nr) ; - } - return File_Nr ; -} ; - - - -#endif diff --git a/RFLink_ESP/My_FtpServer.h b/RFLink_ESP/My_FtpServer.h deleted file mode 100644 index a0ed99f..0000000 --- a/RFLink_ESP/My_FtpServer.h +++ /dev/null @@ -1,1097 +0,0 @@ -/* - * FTP Serveur for ESP8266 - * based on FTP Serveur for Arduino Due and Ethernet shield (W5100) or WIZ820io (W5200) - * based on Jean-Michel Gallego's work - * modified to work with esp8266 SPIFFS by David Paiva david@nailbuster.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - // Uncomment to print debugging info to console attached to ESP8266 -#define FTP_DEBUG - -#ifndef My_FtpServer_h -#define My_FtpServer_h - - -//#include "Streaming.h" -#include -#include - -#define FTP_SERVER_VERSION "FTP-2017-10-18" - -#define FTP_CTRL_PORT 21 // Command port on wich server is listening -#define FTP_DATA_PORT_PASV 50009 // Data port in passive mode - -#define FTP_TIME_OUT 5 // Disconnect client after 5 minutes of inactivity -#define FTP_CMD_SIZE 255 + 8 // max size of a command -#define FTP_CWD_SIZE 255 + 8 // max size of a directory name -#define FTP_FIL_SIZE 255 // max size of a file name -//#define FTP_BUF_SIZE 1024 //512 // size of file buffer for read/write -#define FTP_BUF_SIZE 2*1460 //512 // size of file buffer for read/write - - -class FtpServer -{ -public: - void begin(String uname, String pword); - void handleFTP(); - -private: - void iniVariables(); - void clientConnected(); - void disconnectClient(); - boolean userIdentity(); - boolean userPassword(); - boolean processCommand(); - boolean dataConnect(); - boolean doRetrieve(); - boolean doStore(); - void closeTransfer(); - void abortTransfer(); - boolean makePath( char * fullname ); - boolean makePath( char * fullName, char * param ); - uint8_t getDateTime( uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, - uint8_t * phour, uint8_t * pminute, uint8_t * second ); - char * makeDateTimeStr( char * tstr, uint16_t date, uint16_t time ); - int8_t readChar(); - - IPAddress dataIp; // IP address of client for data - WiFiClient client; - WiFiClient data; - - fs::File file; - - boolean dataPassiveConn; - uint16_t dataPort; - char buf[ FTP_BUF_SIZE ]; // data buffer for transfers - char cmdLine[ FTP_CMD_SIZE ]; // where to store incoming char from client - char cwdName[ FTP_CWD_SIZE ]; // name of current directory - char command[ 5 ]; // command sent by client - boolean rnfrCmd; // previous command was RNFR - char * parameters; // point to begin of parameters sent by client - uint16_t iCL; // pointer to cmdLine next incoming char - int8_t cmdStatus, // status of ftp command connexion - transferStatus; // status of ftp data transfer - uint32_t millisTimeOut, // disconnect after 5 min of inactivity - millisDelay, - millisEndConnection, // - millisBeginTrans, // store time of beginning of a transaction - bytesTransfered; // - String _FTP_USER; - String _FTP_PASS; -}; - - -#ifdef ESP8266 -#include -#elif defined ESP32 -#include -#include "SPIFFS.h" -#endif -#include -#include - - - - -WiFiServer ftpServer( FTP_CTRL_PORT ); -WiFiServer dataServer( FTP_DATA_PORT_PASV ); - -void FtpServer::begin(String uname, String pword) -{ - // Tells the ftp server to begin listening for incoming connection - _FTP_USER=uname; - _FTP_PASS = pword; - - ftpServer.begin(); - delay(10); - dataServer.begin(); - delay(10); - millisTimeOut = (uint32_t)FTP_TIME_OUT * 60 * 1000; - millisDelay = 0; - cmdStatus = 0; - iniVariables(); -} - -void FtpServer::iniVariables() -{ - // Default for data port - dataPort = FTP_DATA_PORT_PASV; - - // Default Data connection is Active - dataPassiveConn = true; - - // Set the root directory - strcpy( cwdName, "/" ); - - rnfrCmd = false; - transferStatus = 0; - -} - -void FtpServer::handleFTP() -{ - if((int32_t) ( millisDelay - millis() ) > 0 ) - return; - - if (ftpServer.hasClient()) { - client.stop(); - client = ftpServer.available(); - } - - if( cmdStatus == 0 ) - { - if( client.connected()) - disconnectClient(); - cmdStatus = 1; - } - else if( cmdStatus == 1 ) // Ftp server waiting for connection - { - abortTransfer(); - iniVariables(); - #ifdef FTP_DEBUG - Serial.println("MYYYYYYYY Ftp server waiting for connection on port "+ String(FTP_CTRL_PORT)); - #endif - cmdStatus = 2; - } - else if( cmdStatus == 2 ) // Ftp server idle - { - - if( client.connected() ) // A client connected - { - clientConnected(); - millisEndConnection = millis() + 10 * 1000 ; // wait client id during 10 s. - cmdStatus = 3; - } - } - else if( readChar() > 0 ) // got response - { - if( cmdStatus == 3 ) // Ftp server waiting for user identity - if( userIdentity() ) - cmdStatus = 4; - else - cmdStatus = 0; - else if( cmdStatus == 4 ) // Ftp server waiting for user registration - if( userPassword() ) - { - cmdStatus = 5; - millisEndConnection = millis() + millisTimeOut; - } - else - cmdStatus = 0; - else if( cmdStatus == 5 ) // Ftp server waiting for user command - if( ! processCommand()) - cmdStatus = 0; - else - millisEndConnection = millis() + millisTimeOut; - } - else if (!client.connected() || !client) - { - cmdStatus = 1; - #ifdef FTP_DEBUG - Serial.println("client disconnected"); - #endif - } - - if( transferStatus == 1 ) // Retrieve data - { - if( ! doRetrieve()) - transferStatus = 0; - } - else if( transferStatus == 2 ) // Store data - { - if( ! doStore()) - transferStatus = 0; - } - else if( cmdStatus > 2 && ! ((int32_t) ( millisEndConnection - millis() ) > 0 )) - { - client.println("530 Timeout"); - millisDelay = millis() + 200; // delay of 200 ms - cmdStatus = 0; - } -} - -void FtpServer::clientConnected() -{ - #ifdef FTP_DEBUG - Serial.println("Client connected!"); - #endif - client.println( "220--- Welcome to FTP for ESP8266/ESP32 ---"); - client.println( "220--- By David Paiva ---"); - client.println( "220 -- Version "+ String(FTP_SERVER_VERSION) +" --"); - iCL = 0; -} - -void FtpServer::disconnectClient() -{ - #ifdef FTP_DEBUG - Serial.println(" Disconnecting client"); - #endif - abortTransfer(); - client.println("221 Goodbye"); - client.stop(); -} - -boolean FtpServer::userIdentity() -{ - if( strcmp( command, "USER" )) - client.println( "500 Syntax error"); - if( strcmp( parameters, _FTP_USER.c_str() )) - client.println( "530 user not found"); - else - { - client.println( "331 OK. Password required"); - strcpy( cwdName, "/" ); - return true; - } - millisDelay = millis() + 100; // delay of 100 ms - return false; -} - -boolean FtpServer::userPassword() -{ - if( strcmp( command, "PASS" )) - client.println( "500 Syntax error"); - else if( strcmp( parameters, _FTP_PASS.c_str() )) - client.println( "530 "); - else - { - #ifdef FTP_DEBUG - Serial.println( "OK. Waiting for commands."); - #endif - client.println( "230 OK."); - return true; - } - millisDelay = millis() + 100; // delay of 100 ms - return false; -} - -boolean FtpServer::processCommand() -{ - /////////////////////////////////////// - // // - // ACCESS CONTROL COMMANDS // - // // - /////////////////////////////////////// - - // - // CDUP - Change to Parent Directory - // - if( ! strcmp( command, "CDUP" )) - { - client.println("250 Ok. Current directory is " + String(cwdName)); - } - // - // CWD - Change Working Directory - // - else if( ! strcmp( command, "CWD" )) - { - char path[ FTP_CWD_SIZE ]; - if( strcmp( parameters, "." ) == 0 ) // 'CWD .' is the same as PWD command - client.println( "257 \"" + String(cwdName) + "\" is your current directory"); - else - { - client.println( "250 Ok. Current directory is " + String(cwdName) ); - } - - } - // - // PWD - Print Directory - // - else if( ! strcmp( command, "PWD" )) - client.println( "257 \"" + String(cwdName) + "\" is your current directory"); - // - // QUIT - // - else if( ! strcmp( command, "QUIT" )) - { - disconnectClient(); - return false; - } - - /////////////////////////////////////// - // // - // TRANSFER PARAMETER COMMANDS // - // // - /////////////////////////////////////// - - // - // MODE - Transfer Mode - // - else if( ! strcmp( command, "MODE" )) - { - if( ! strcmp( parameters, "S" )) - client.println( "200 S Ok"); - // else if( ! strcmp( parameters, "B" )) - // client.println( "200 B Ok\r\n"; - else - client.println( "504 Only S(tream) is suported"); - } - // - // PASV - Passive Connection management - // - else if( ! strcmp( command, "PASV" )) - { - if (data.connected()) data.stop(); - //dataServer.begin(); - //dataIp = Ethernet.localIP(); - dataIp = client.localIP(); - dataPort = FTP_DATA_PORT_PASV; - //data.connect( dataIp, dataPort ); - //data = dataServer.available(); - #ifdef FTP_DEBUG - Serial.println("Connection management set to passive"); - Serial.println( "Data port set to " + String(dataPort)); - #endif - client.println( "227 Entering Passive Mode ("+ String(dataIp[0]) + "," + String(dataIp[1])+","+ String(dataIp[2])+","+ String(dataIp[3])+","+String( dataPort >> 8 ) +","+String ( dataPort & 255 )+")."); - dataPassiveConn = true; - } - // - // PORT - Data Port - // - else if( ! strcmp( command, "PORT" )) - { - if (data) data.stop(); - // get IP of data client - dataIp[ 0 ] = atoi( parameters ); - char * p = strchr( parameters, ',' ); - for( uint8_t i = 1; i < 4; i ++ ) - { - dataIp[ i ] = atoi( ++ p ); - p = strchr( p, ',' ); - } - // get port of data client - dataPort = 256 * atoi( ++ p ); - p = strchr( p, ',' ); - dataPort += atoi( ++ p ); - if( p == NULL ) - client.println( "501 Can't interpret parameters"); - else - { - - client.println("200 PORT command successful"); - dataPassiveConn = false; - } - } - // - // STRU - File Structure - // - else if( ! strcmp( command, "STRU" )) - { - if( ! strcmp( parameters, "F" )) - client.println( "200 F Ok"); - // else if( ! strcmp( parameters, "R" )) - // client.println( "200 B Ok\r\n"; - else - client.println( "504 Only F(ile) is suported"); - } - // - // TYPE - Data Type - // - else if( ! strcmp( command, "TYPE" )) - { - if( ! strcmp( parameters, "A" )) - client.println( "200 TYPE is now ASII"); - else if( ! strcmp( parameters, "I" )) - client.println( "200 TYPE is now 8-bit binary"); - else - client.println( "504 Unknow TYPE"); - } - - /////////////////////////////////////// - // // - // FTP SERVICE COMMANDS // - // // - /////////////////////////////////////// - - // - // ABOR - Abort - // - else if( ! strcmp( command, "ABOR" )) - { - abortTransfer(); - client.println( "226 Data connection closed"); - } - // - // DELE - Delete a File - // - else if( ! strcmp( command, "DELE" )) - { - char path[ FTP_CWD_SIZE ]; - if( strlen( parameters ) == 0 ) - client.println( "501 No file name"); - else if( makePath( path )) - { - if( ! SPIFFS.exists( path )) - client.println( "550 File " + String(parameters) + " not found"); - else - { - if( SPIFFS.remove( path )) - client.println( "250 Deleted " + String(parameters) ); - else - client.println( "450 Can't delete " + String(parameters)); - } - } - } - // - // LIST - List - // - else if( ! strcmp( command, "LIST" )) - { - if( ! dataConnect()) - client.println( "425 No data connection"); - else - { - client.println( "150 Accepted data connection"); - uint16_t nm = 0; -#ifdef ESP8266 - fs::Dir dir=SPIFFS.openDir(cwdName); - // if( !SPIFFS.exists(cwdName)) - // client.println( "550 Can't open directory " + String(cwdName) ); - // else - { - while( dir.next()) - { - String fn, fs; - fn = dir.fileName(); - fn.remove(0, 1); - fs = String(dir.fileSize()); - data.println( "+r,s" + fs); - data.println( ",\t" + fn ); - nm ++; - } - client.println( "226 " + String(nm) + " matches total"); - } -#elif defined ESP32 - fs::File root = SPIFFS.open(cwdName); - if(!root){ - client.println( "550 Can't open directory " + String(cwdName) ); - // return; - } else { - // if(!root.isDirectory()){ - // Serial.println("Not a directory"); - // return; - // } - - fs::File file = root.openNextFile(); - while(file){ - if(file.isDirectory()){ - data.println( "+r,s " + String(file.name())); - // Serial.print(" DIR : "); - // Serial.println(file.name()); - // if(levels){ - // listDir(fs, file.name(), levels -1); - // } - } else { - String fn, fs; - fn = file.name(); - // fn.remove(0, 1); - fs = String(file.size()); - data.println( "+r,s" + fs); - data.println( ",\t" + fn ); - nm ++; - } - file = root.openNextFile(); - } - client.println( "226 " + String(nm) + " matches total"); - } -#endif - data.stop(); - } - } - // - // MLSD - Listing for Machine Processing (see RFC 3659) - // - else if( ! strcmp( command, "MLSD" )) - { - if( ! dataConnect()) - client.println( "425 No data connection MLSD"); - else - { - client.println( "150 Accepted data connection"); - uint16_t nm = 0; -#ifdef ESP8266 - fs::Dir dir= SPIFFS.openDir(cwdName); - char dtStr[ 15 ]; - // if(!SPIFFS.exists(cwdName)) - // client.println( "550 Can't open directory " +String(parameters)+ ); - // else - { - while( dir.next()) - { - String fn,fs; - fn = dir.fileName(); - fn.remove(0, 1); - fs = String(dir.fileSize()); - data.println( "Type=file;Size=" + fs + ";"+"modify=20000101160656;" +" " + fn); - nm ++; - } - client.println( "226-options: -a -l"); - client.println( "226 " + String(nm) + " matches total"); - } -#elif defined ESP32 - fs::File root = SPIFFS.open(cwdName); - // if(!root){ - // client.println( "550 Can't open directory " + String(cwdName) ); - // // return; - // } else { - // if(!root.isDirectory()){ - // Serial.println("Not a directory"); - // return; - // } - - fs::File file = root.openNextFile(); - while(file){ - // if(file.isDirectory()){ - // data.println( "+r,s " + String(file.name())); - // // Serial.print(" DIR : "); - // // Serial.println(file.name()); - // // if(levels){ - // // listDir(fs, file.name(), levels -1); - // // } - // } else { - String fn, fs; - fn = file.name(); - fn.remove(0, 1); - fs = String(file.size()); - data.println( "Type=file;Size=" + fs + ";"+"modify=20000101160656;" +" " + fn); - nm ++; - // } - file = root.openNextFile(); - } - client.println( "226-options: -a -l"); - client.println( "226 " + String(nm) + " matches total"); - // } -#endif - data.stop(); - } - } - // - // NLST - Name List - // - else if( ! strcmp( command, "NLST" )) - { - if( ! dataConnect()) - client.println( "425 No data connection"); - else - { - client.println( "150 Accepted data connection"); - uint16_t nm = 0; -#ifdef ESP8266 - fs::Dir dir=SPIFFS.openDir(cwdName); - // if( !SPIFFS.exists( cwdName )) - // client.println( "550 Can't open directory " + String(parameters)); - // else - { - while( dir.next()) - { - data.println( dir.fileName()); - nm ++; - } - client.println( "226 " + String(nm) + " matches total"); - } -#elif defined ESP32 - fs::File root = SPIFFS.open(cwdName); - if(!root){ - client.println( "550 Can't open directory " + String(cwdName) ); - } else { - - fs::File file = root.openNextFile(); - while(file){ - data.println( file.name()); - nm ++; - file = root.openNextFile(); - } - client.println( "226 " + String(nm) + " matches total"); - } -#endif - data.stop(); - } - } - // - // NOOP - // - else if( ! strcmp( command, "NOOP" )) - { - // dataPort = 0; - client.println( "200 Zzz..."); - } - // - // RETR - Retrieve - // - else if( ! strcmp( command, "RETR" )) - { - char path[ FTP_CWD_SIZE ]; - if( strlen( parameters ) == 0 ) - client.println( "501 No file name"); - else if( makePath( path )) - { - file = SPIFFS.open(path, "r"); - if( !file) - client.println( "550 File " +String(parameters)+ " not found"); - else if( !file ) - client.println( "450 Can't open " +String(parameters)); - else if( ! dataConnect()) - client.println( "425 No data connection"); - else - { - #ifdef FTP_DEBUG - Serial.println("Sending " + String(parameters)); - #endif - client.println( "150-Connected to port "+ String(dataPort)); - client.println( "150 " + String(file.size()) + " bytes to download"); - millisBeginTrans = millis(); - bytesTransfered = 0; - transferStatus = 1; - } - } - } - // - // STOR - Store - // - else if( ! strcmp( command, "STOR" )) - { - char path[ FTP_CWD_SIZE ]; - if( strlen( parameters ) == 0 ) - client.println( "501 No file name"); - else if( makePath( path )) - { - file = SPIFFS.open(path, "w"); - if( !file) - client.println( "451 Can't open/create " +String(parameters) ); - else if( ! dataConnect()) - { - client.println( "425 No data connection"); - file.close(); - } - else - { - #ifdef FTP_DEBUG - Serial.println( "Receiving " +String(parameters)); - #endif - client.println( "150 Connected to port " + String(dataPort)); - millisBeginTrans = millis(); - bytesTransfered = 0; - transferStatus = 2; - } - } - } - // - // MKD - Make Directory - // - else if( ! strcmp( command, "MKD" )) - { - client.println( "550 Can't create \"" + String(parameters)); //not support on espyet - } - // - // RMD - Remove a Directory - // - else if( ! strcmp( command, "RMD" )) - { - client.println( "501 Can't delete \"" +String(parameters)); - - } - // - // RNFR - Rename From - // - else if( ! strcmp( command, "RNFR" )) - { - buf[ 0 ] = 0; - if( strlen( parameters ) == 0 ) - client.println( "501 No file name"); - else if( makePath( buf )) - { - if( ! SPIFFS.exists( buf )) - client.println( "550 File " +String(parameters)+ " not found"); - else - { - #ifdef FTP_DEBUG - Serial.println("Renaming " + String(buf)); - #endif - client.println( "350 RNFR accepted - file exists, ready for destination"); - rnfrCmd = true; - } - } - } - // - // RNTO - Rename To - // - else if( ! strcmp( command, "RNTO" )) - { - char path[ FTP_CWD_SIZE ]; - char dir[ FTP_FIL_SIZE ]; - if( strlen( buf ) == 0 || ! rnfrCmd ) - client.println( "503 Need RNFR before RNTO"); - else if( strlen( parameters ) == 0 ) - client.println( "501 No file name"); - else if( makePath( path )) - { - if( SPIFFS.exists( path )) - client.println( "553 " +String(parameters)+ " already exists"); - else - { - #ifdef FTP_DEBUG - Serial.println("Renaming " + String(buf) + " to " + String(path)); - #endif - if( SPIFFS.rename( buf, path )) - client.println( "250 File successfully renamed or moved"); - else - client.println( "451 Rename/move failure"); - - } - } - rnfrCmd = false; - } - - /////////////////////////////////////// - // // - // EXTENSIONS COMMANDS (RFC 3659) // - // // - /////////////////////////////////////// - - // - // FEAT - New Features - // - else if( ! strcmp( command, "FEAT" )) - { - client.println( "211-Extensions suported:"); - client.println( " MLSD"); - client.println( "211 End."); - } - // - // MDTM - File Modification Time (see RFC 3659) - // - else if (!strcmp(command, "MDTM")) - { - client.println("550 Unable to retrieve time"); - } - - // - // SIZE - Size of the file - // - else if( ! strcmp( command, "SIZE" )) - { - char path[ FTP_CWD_SIZE ]; - if( strlen( parameters ) == 0 ) - client.println( "501 No file name"); - else if( makePath( path )) - { - file = SPIFFS.open(path, "r"); - if(!file) - client.println( "450 Can't open " +String(parameters) ); - else - { - client.println( "213 " + String(file.size())); - file.close(); - } - } - } - // - // SITE - System command - // - else if( ! strcmp( command, "SITE" )) - { - client.println( "500 Unknow SITE command " +String(parameters) ); - } - // - // Unrecognized commands ... - // - else - client.println( "500 Unknow command"); - - return true; -} - -boolean FtpServer::dataConnect() -{ - unsigned long startTime = millis(); - //wait 5 seconds for a data connection - if (!data.connected()) - { - while (!dataServer.hasClient() && millis() - startTime < 10000) - { - //delay(100); - yield(); - } - if (dataServer.hasClient()) { - data.stop(); - data = dataServer.available(); - #ifdef FTP_DEBUG - Serial.println("ftpdataserver client...."); - #endif - - } - } - - return data.connected(); - -} - -boolean FtpServer::doRetrieve() -{ -if (data.connected()) -{ - int16_t nb = file.readBytes(buf, FTP_BUF_SIZE); - if (nb > 0) - { - data.write((uint8_t*)buf, nb); - bytesTransfered += nb; - return true; - } -} -closeTransfer(); -return false; -} - -boolean FtpServer::doStore() -{ - // Avoid blocking by never reading more bytes than are available - int navail = data.available(); - - if (navail > 0) - { - // And be sure not to overflow buf. - if (navail > FTP_BUF_SIZE) navail = FTP_BUF_SIZE; - int16_t nb = data.read((uint8_t*) buf, navail ); - // int16_t nb = data.readBytes((uint8_t*) buf, FTP_BUF_SIZE ); - if( nb > 0 ) - { - // Serial.println( millis() << " " << nb << endl; - file.write((uint8_t*) buf, nb ); - bytesTransfered += nb; - } - } - if( !data.connected() && (navail <= 0) ) - { - closeTransfer(); - return false; - } - else - { - return true; - } -} - -void FtpServer::closeTransfer() -{ - uint32_t deltaT = (int32_t) ( millis() - millisBeginTrans ); - if( deltaT > 0 && bytesTransfered > 0 ) - { - client.println( "226-File successfully transferred"); - client.println( "226 " + String(deltaT) + " ms, "+ String(bytesTransfered / deltaT) + " kbytes/s"); - } - else - client.println( "226 File successfully transferred"); - - file.close(); - data.stop(); -} - -void FtpServer::abortTransfer() -{ - if( transferStatus > 0 ) - { - file.close(); - data.stop(); - client.println( "426 Transfer aborted" ); - #ifdef FTP_DEBUG - Serial.println( "Transfer aborted!") ; - #endif - } - transferStatus = 0; -} - -// Read a char from client connected to ftp server -// -// update cmdLine and command buffers, iCL and parameters pointers -// -// return: -// -2 if buffer cmdLine is full -// -1 if line not completed -// 0 if empty line received -// length of cmdLine (positive) if no empty line received - -int8_t FtpServer::readChar() -{ - int8_t rc = -1; - - if( client.available()) - { - char c = client.read(); - // char c; - // client.readBytes((uint8_t*) c, 1); - #ifdef FTP_DEBUG - Serial.print( c); - #endif - if( c == '\\' ) - c = '/'; - if( c != '\r' ) - if( c != '\n' ) - { - if( iCL < FTP_CMD_SIZE ) - cmdLine[ iCL ++ ] = c; - else - rc = -2; // Line too long - } - else - { - cmdLine[ iCL ] = 0; - command[ 0 ] = 0; - parameters = NULL; - // empty line? - if( iCL == 0 ) - rc = 0; - else - { - rc = iCL; - // search for space between command and parameters - parameters = strchr( cmdLine, ' ' ); - if( parameters != NULL ) - { - if( parameters - cmdLine > 4 ) - rc = -2; // Syntax error - else - { - strncpy( command, cmdLine, parameters - cmdLine ); - command[ parameters - cmdLine ] = 0; - - while( * ( ++ parameters ) == ' ' ) - ; - } - } - else if( strlen( cmdLine ) > 4 ) - rc = -2; // Syntax error. - else - strcpy( command, cmdLine ); - iCL = 0; - } - } - if( rc > 0 ) - for( uint8_t i = 0 ; i < strlen( command ); i ++ ) - command[ i ] = toupper( command[ i ] ); - if( rc == -2 ) - { - iCL = 0; - client.println( "500 Syntax error"); - } - } - return rc; -} - -// Make complete path/name from cwdName and parameters -// -// 3 possible cases: parameters can be absolute path, relative path or only the name -// -// parameters: -// fullName : where to store the path/name -// -// return: -// true, if done - -boolean FtpServer::makePath( char * fullName ) -{ - return makePath( fullName, parameters ); -} - -boolean FtpServer::makePath( char * fullName, char * param ) -{ - if( param == NULL ) - param = parameters; - - // Root or empty? - if( strcmp( param, "/" ) == 0 || strlen( param ) == 0 ) - { - strcpy( fullName, "/" ); - return true; - } - // If relative path, concatenate with current dir - if( param[0] != '/' ) - { - strcpy( fullName, cwdName ); - if( fullName[ strlen( fullName ) - 1 ] != '/' ) - strncat( fullName, "/", FTP_CWD_SIZE ); - strncat( fullName, param, FTP_CWD_SIZE ); - } - else - strcpy( fullName, param ); - // If ends with '/', remove it - uint16_t strl = strlen( fullName ) - 1; - if( fullName[ strl ] == '/' && strl > 1 ) - fullName[ strl ] = 0; - if( strlen( fullName ) < FTP_CWD_SIZE ) - return true; - - client.println( "500 Command line too long"); - return false; -} - -// Calculate year, month, day, hour, minute and second -// from first parameter sent by MDTM command (YYYYMMDDHHMMSS) -// -// parameters: -// pyear, pmonth, pday, phour, pminute and psecond: pointer of -// variables where to store data -// -// return: -// 0 if parameter is not YYYYMMDDHHMMSS -// length of parameter + space - -uint8_t FtpServer::getDateTime( uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, - uint8_t * phour, uint8_t * pminute, uint8_t * psecond ) -{ - char dt[ 15 ]; - - // Date/time are expressed as a 14 digits long string - // terminated by a space and followed by name of file - if( strlen( parameters ) < 15 || parameters[ 14 ] != ' ' ) - return 0; - for( uint8_t i = 0; i < 14; i++ ) - if( ! isdigit( parameters[ i ])) - return 0; - - strncpy( dt, parameters, 14 ); - dt[ 14 ] = 0; - * psecond = atoi( dt + 12 ); - dt[ 12 ] = 0; - * pminute = atoi( dt + 10 ); - dt[ 10 ] = 0; - * phour = atoi( dt + 8 ); - dt[ 8 ] = 0; - * pday = atoi( dt + 6 ); - dt[ 6 ] = 0 ; - * pmonth = atoi( dt + 4 ); - dt[ 4 ] = 0 ; - * pyear = atoi( dt ); - return 15; -} - -// Create string YYYYMMDDHHMMSS from date and time -// -// parameters: -// date, time -// tstr: where to store the string. Must be at least 15 characters long -// -// return: -// pointer to tstr - -char * FtpServer::makeDateTimeStr( char * tstr, uint16_t date, uint16_t time ) -{ - sprintf( tstr, "%04u%02u%02u%02u%02u%02u", - (( date & 0xFE00 ) >> 9 ) + 1980, ( date & 0x01E0 ) >> 5, date & 0x001F, - ( time & 0xF800 ) >> 11, ( time & 0x07E0 ) >> 5, ( time & 0x001F ) << 1 ); - return tstr; -} - -#endif diff --git a/RFLink_ESP/My_Settings.h b/RFLink_ESP/My_Settings.h deleted file mode 100644 index 8e47844..0000000 --- a/RFLink_ESP/My_Settings.h +++ /dev/null @@ -1,268 +0,0 @@ -// -// Version 0.1, 08-08-2019, SM - -#ifndef My_Settings_h -#define My_Settings_h 0.1 - -#include - -#ifdef FileSystem_SPIFFS - #include "FS_support.h" -#endif - -#include "html_templates.h" - -String _My_Settings_Filename = "/Settings.h" ; - -DynamicJsonDocument _My_Settings_Buffer ( 2000 ) ; // ArduinoJson V6 -//StaticJsonDocument <2000> _My_Settings_Buffer ; // ArduinoJson V6 - - - - -// *********************************************************************************** -// *********************************************************************************** -class _My_Settings_Class { - public : - JsonObject DocumentRoot ; //= _My_Settings_Buffer.as() ; - - // *********************************************************************** - // *********************************************************************** - _My_Settings_Class () { - } - - void Setup () { - //* DIT LIJKT ME ONZIN HIER IS WEL DEGELIJK NODIG !!! -#ifdef FileSystem_SPIFFS - #ifdef ESP32 - SPIFFS.begin ( true ) ; // format if no filesystem yet - #else - if ( ! SPIFFS.begin ( ) ) { - SPIFFS.format () ; - } - SPIFFS.begin ( ) ; - #endif - - Serial.println ( "===== Read_Settings from file = " + _My_Settings_Filename ) ; - fs::File file = SPIFFS.open ( _My_Settings_Filename, "r" ) ; - - if ( file ) { - DeserializationError error = deserializeJson ( _My_Settings_Buffer, file ); - if ( error ) - Serial.println( "Failed to read file JJJJJaaaa, using default configuration" + _My_Settings_Filename ); - file.close () ; - } - else { - Serial.println ( "ERROR: file not found = " + _My_Settings_Filename ) ; - } - - JsonObject DocumentRoot = _My_Settings_Buffer.as() ; -#endif - - } - -/* - // *********************************************************************** - // *********************************************************************** - void Create_Sensors ( ) { - for ( JsonPair KeyValue : DocumentRoot ) { - String Key = String ( KeyValue.key().c_str() ) ; - JsonVariant Value = KeyValue.value () ; - - if ( Key == "Sensor_Blauwe_Engel" ) { - Sensors.Add ( new _Sensor_Blauwe_Engel () ) ; - } - } - } - -//*/ - - // *********************************************************************** - // *********************************************************************** - void Remove ( String Key ) { - DocumentRoot.remove ( Key ) ; - } - - // *********************************************************************** - // *********************************************************************** - void Store_Settings ( String Filename = _My_Settings_Filename ) { -#ifdef FileSystem_SPIFFS - fs::File file = SPIFFS.open ( Filename, "w" ) ; - if ( serializeJsonPretty ( _My_Settings_Buffer, file ) == 0 ) { - Serial.println ( "Failed to write to file " + Filename ) ; - } - else UnStored_Changes = false ; - file.close () ; -#endif - } - - // *********************************************************************** - // *********************************************************************** - void Set_Unstored_Changes () { - UnStored_Changes = true ; - } - - // *********************************************************************** - // *********************************************************************** - /* - void Store_Changes ( String Filename = _My_Settings_Filename ) { - if ( UnStored_Changes ) { - this -> Store_Settings () ; - UnStored_Changes = false ; - } - } -*/ - - // *********************************************************************** - // *********************************************************************** - void Create_WebPage ( String Filename = "/Settings.html" ) { -#ifdef FileSystem_SPIFFS - Serial.print ( "\n Creating Settings Webpage @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IP = " ) ; - Serial.println ( WiFi.localIP() ) ; - - fs::File file = SPIFFS.open ( Filename, "w" ) ; - if ( ! file ) { - Serial.println ( "EEERRROOORRRRRR" ) ; - return ; - } - - String Line = "" ; - Line += String ( FPSTR(HTML_Sensor_Settings_Begin) ) ; -// Line += "

MiRa Sensors

\n" ; -// Line += "StartPage

\n" ; -// Line += "
\n" ; - file.print ( Line ) ; - - // ************************************************* - // omdat My_Settings array gewijzigd kan zijn, - // moet er onieuw een JSON object van gemaakt worden - // ************************************************* - JsonObject DocumentRoot = _My_Settings_Buffer.as() ; - //JsonVariant Variant = _My_Settings_Buffer.to(); - - for ( JsonPair KeyValue : DocumentRoot ) { - String Key = String ( KeyValue.key().c_str() ) ; -//Serial.println ( "KEY " + Key ) ; - //const char* key = p.key; - JsonVariant Value = KeyValue.value () ; - - // ************************************************ - // ************************************************ - if ( Value.is() ) { - bool Value = (bool)_My_Settings_Buffer [ Key ] ; - - Line = "