Compare commits

...

25 Commits

Author SHA1 Message Date
jomjol
776931c0ad v9.2.0 2021-12-02 21:56:05 +01:00
jomjol
e22b4b6fe1 v9.2.0 2021-12-02 21:52:45 +01:00
jomjol
cad534bffe update wiki 2021-12-02 21:47:37 +01:00
jomjol
3b44adb6fa Rolling 20211128 2021-11-28 09:09:24 +01:00
jomjol
cc0bd1473f Rolling 20211124 2021-11-24 07:32:03 +01:00
jomjol
58124d27bf Rolling 2021-11-23 2021-11-23 17:57:07 +01:00
Sven Rojek
9ad118814a add basic exception handling for the camera module 2021-11-21 19:05:17 +01:00
jomjol
270f8dd093 v9.1.1 2021-11-16 07:15:55 +01:00
jomjol
fde0ae4781 v9.1.0 2021-11-14 08:57:19 +01:00
jomjol
b87ce8c75d Merge branch 'master' into rolling 2021-11-14 08:52:40 +01:00
jomjol
e372c87836 v9.1.0 2021-11-14 08:52:28 +01:00
jomjol
f8478d7742 Merge branch 'master' into rolling 2021-11-14 08:48:42 +01:00
jomjol
a3d6923fec v9.1.0 2021-11-14 08:47:55 +01:00
jomjol
7bfa22187d Merge branch 'pr/398' into rolling 2021-11-14 08:19:13 +01:00
pixel::doc
7a8affae32 Update Helper.cpp
Change "open config file" to "open file"
2021-11-14 01:05:40 +01:00
jomjol
e48dd7c4c4 rolling 20211106 2021-11-06 22:46:16 +01:00
jomjol
4fe9ab92e0 image update 2021-10-27 18:57:07 +02:00
jomjol
f2ac4cdc64 v9.0.0 2021-10-23 16:35:40 +02:00
jomjol
be902401d1 Merge branch 'rolling' 2021-10-23 16:32:44 +02:00
jomjol
020e93bca2 v9.0.0 2021-10-23 16:31:55 +02:00
jomjol
61dfdc2258 Add files via upload 2021-10-23 15:44:46 +02:00
jomjol
a98e3c8eab Add files via upload 2021-10-22 21:31:21 +02:00
jomjol
58a90ff706 v8.5.0 2021-10-07 07:45:40 +02:00
jomjol
d0bf12f3d4 v8.5.0 2021-10-07 07:16:46 +02:00
jomjol
af16785bbf Rolling 20211002 2021-10-02 14:59:09 +02:00
43 changed files with 377 additions and 1007 deletions

View File

@@ -11,6 +11,12 @@
____
#### #12 Less reboots due to memory leakage
* Issue: #414 & #425 #430
#### #11 MQTT - configurable payload
* https://github.com/jomjol/AI-on-the-edge-device/issues/344

View File

@@ -6,6 +6,8 @@ This is an example of Artificial Intelligence (AI) calculations on a very cheap
A 3d-printable housing can be found here: https://www.thingiverse.com/thing:4573481
or here https://www.thingiverse.com/thing:5028229
respectively ESP32-Cam housing only: https://www.thingiverse.com/thing:4571627
<img src="https://raw.githubusercontent.com/jomjol/AI-on-the-edge-device/master/images/watermeter_all.jpg" width="200"><img src="https://raw.githubusercontent.com/jomjol/AI-on-the-edge-device/master/images/main.jpg" width="200"><img src="https://raw.githubusercontent.com/jomjol/AI-on-the-edge-device/master/images/size.png" width="200">
@@ -45,7 +47,34 @@ In other cases you can contact the developer via email: <img src="https://raw.gi
**General remark:** Beside the `firmware.bin`, typically also the content of `/html` needs to be updated!
##### 9.2.0 - External Illumination (2021-12-02)
- Direct JSON access: ``http://IP-ADRESS/json``
- Error message in log file in case camera error during startup
- Upgrade analog CNN to v9.1.0
- Upgrade digital CNN to v13.3.0 (added new images)
- html: support of different ports
##### 9.1.1 - External Illumination (2021-11-16)
- NEW 9.1.1 bug fix: LED implemenetation
- External LEDs: change control mode (resolve bug with more than 2 LEDs)
- Additional info into log file
- Bug fix: decimal shift, html, log file
##### 9.0.0 - External Illumination (2021-10-23)
* Implementation of external illumination to adjust positioning, brightness and color of the illumination now individually
* Technical details can be found in the wiki: https://github.com/jomjol/AI-on-the-edge-device/wiki/External-LED
<img src="https://raw.githubusercontent.com/jomjol/ai-on-the-edge-device/master/images/intern_vs_external.jpg" width="500">
* New housing published for external LEDs and small clearing: https://www.thingiverse.com/thing:5028229
##### 8.5.0 - Multi Meter Support (2021-10-07)
* Upgrade digital CNN to v13.1.0 (added new images)
* bug fix: wlan password with space, double digit output
##### 8.4.0 - Multi Meter Support (2021-09-25)

View File

@@ -400,24 +400,19 @@ bool GpioHandler::readConfig()
if (gpioExtLED > 0)
{
// LogFile.WriteToFile("Startsequence 06");
// LogFile.WriteToFile("Startsequence 06"); // Nremove
// vTaskDelay( xDelay );
// xDelay = 5000 / portTICK_PERIOD_MS;
// printf("main: sleep for : %ldms\n", (long) xDelay);
SmartLed leds( LED_WS2812, 2, GPIO_NUM_12, 0, DoubleBuffer );
// SmartLed leds( LED_WS2812, 2, GPIO_NUM_12, 0, DoubleBuffer );
leds[ 0 ] = Rgb{ 255, 0, 0 };
leds[ 1 ] = Rgb{ 255, 255, 255 };
leds.show();
/*
// _SmartLED = new SmartLed(LEDType, LEDNumbers, gpioExtLED, 0, DoubleBuffer);
_SmartLED = new SmartLed( LED_WS2812, 2, GPIO_NUM_12, 0, DoubleBuffer );
(*_SmartLED)[ 0 ] = Rgb{ 255, 0, 0 };
(*_SmartLED)[ 1 ] = LEDColor;
_SmartLED->show();
*/
// leds[ 0 ] = Rgb{ 255, 0, 0 };
// leds[ 1 ] = Rgb{ 255, 255, 255 };
// leds.show();
// SmartLed leds = new SmartLed(LEDType, LEDNumbers, gpioExtLED, 0, DoubleBuffer);
// _SmartLED = new SmartLed( LED_WS2812, 2, GPIO_NUM_12, 0, DoubleBuffer );
}
return true;
@@ -565,18 +560,41 @@ void GpioHandler::flashLightEnable(bool value)
{
if (it->second->getMode() == GPIO_PIN_MODE_EXTERNAL_FLASH_WS281X)
{
#ifdef __LEDGLOBAL
if (leds_global == NULL) {
ESP_LOGI(TAG_SERVERGPIO, "init SmartLed: LEDNumber=%d, GPIO=%d", LEDNumbers, (int)it->second->getGPIO());
leds_global = new SmartLed( LEDType, LEDNumbers, it->second->getGPIO(), 0, DoubleBuffer );
} else {
// wait until we can update: https://github.com/RoboticsBrno/SmartLeds/issues/10#issuecomment-386921623
leds_global->wait();
}
#else
SmartLed leds( LEDType, LEDNumbers, it->second->getGPIO(), 0, DoubleBuffer );
#endif
if (value)
{
for (int i = 0; i < LEDNumbers; ++i)
#ifdef __LEDGLOBAL
(*leds_global)[i] = LEDColor;
#else
leds[i] = LEDColor;
#endif
}
else
{
for (int i = 0; i < LEDNumbers; ++i)
#ifdef __LEDGLOBAL
(*leds_global)[i] = Rgb{0, 0, 0};
#else
leds[i] = Rgb{0, 0, 0};
#endif
}
leds.show();
#ifdef __LEDGLOBAL
leds_global->show();
#else
leds.show();
#endif
}
}
}

View File

@@ -11,6 +11,9 @@
//#include "ClassControllCamera.h"
// wenn __LEDGLOBAL definiert ist, wird eine globale Variable für die LED-Ansteuerung verwendet, ansonsten lokal und jedesmal neu
#define __LEDGLOBAL
typedef enum {
GPIO_PIN_MODE_DISABLED = 0x0,
GPIO_PIN_MODE_INPUT = 0x1,
@@ -86,7 +89,9 @@ private:
int LEDNumbers = 2;
Rgb LEDColor = Rgb{ 255, 255, 255 };
LedType LEDType = LED_WS2812;
#ifdef __LEDGLOBAL
SmartLed *leds_global = NULL;
#endif
bool readConfig();
void clear();

View File

@@ -61,6 +61,7 @@ string ClassFlowCNNGeneral::getReadout(int _analog = 0, bool _extendedResolution
prev = ZeigerEval(GENERAL[_analog]->ROI[i]->result_float, prev);
result = std::to_string(prev) + result;
}
return result;
}
if (CNNType == Digital)
@@ -72,6 +73,7 @@ string ClassFlowCNNGeneral::getReadout(int _analog = 0, bool _extendedResolution
else
result = result + std::to_string(GENERAL[_analog]->ROI[i]->result_klasse);
}
return result;
}
if (CNNType == DigitalHyprid)
@@ -116,6 +118,7 @@ string ClassFlowCNNGeneral::getReadout(int _analog = 0, bool _extendedResolution
result = "N" + result;
}
}
return result;
}
return result;
@@ -540,7 +543,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
if (debugdetailgeneral) LogFile.WriteToFile("Nach Invoke");
_num = tflite->GetOutClassification(0, 10);
_nachkomma = tflite->GetOutClassification(11, 22);
_nachkomma = tflite->GetOutClassification(11, 21);
string _zwres = "Nach Invoke - Nummer: " + to_string(_num) + " Nachkomma: " + to_string(_nachkomma);

View File

@@ -624,4 +624,30 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
}
return result;
}
}
string ClassFlowControll::getJSON()
{
std::vector<NumberPost*>* NUMBERS = flowpostprocessing->GetNumbers();
std::string json="{\n";
for (int i = 0; i < (*NUMBERS).size(); ++i)
{
json += "\"" + (*NUMBERS)[i]->name + "\":\n";
json += " {\n";
json += " \"value\": " + (*NUMBERS)[i]->ReturnValueNoError + ",\n";
json += " \"raw\": \"" + (*NUMBERS)[i]->ReturnRawValue + "\",\n";
json += " \"error\": \"" + (*NUMBERS)[i]->ErrorMessageText + "\",\n";
json += " \"rate\": " + std::to_string((*NUMBERS)[i]->FlowRateAct) + ",\n";
json += " \"timestamp\": \"" + (*NUMBERS)[i]->timeStamp + "\"\n";
if ((i+1) < (*NUMBERS).size())
json += " },\n";
else
json += " }\n";
}
json += "}";
return json;
}

View File

@@ -48,6 +48,7 @@ public:
string UpdatePrevalue(std::string _newvalue, std::string _numbers, bool _extern);
string GetPrevalue(std::string _number = "");
bool ReadParameter(FILE* pfile, string& aktparamgraph);
string getJSON();
string TranslateAktstatus(std::string _input);

View File

@@ -89,7 +89,7 @@ bool ClassFlowPostProcessing::LoadPreValue(void)
if (NUMBERS[j]->name == name)
{
NUMBERS[j]->PreValue = stof(zwvalue.c_str());
NUMBERS[j]->ReturnPreValue = RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma);
NUMBERS[j]->ReturnPreValue = RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma + 1); // SIcherheitshalber 1 Stelle mehr, da ggf. Exgtended Resolution an ist (wird erst beim ersten Durchlauf gesetzt)
time_t tStart;
int yy, month, dd, hh, mm, ss;
@@ -123,7 +123,7 @@ bool ClassFlowPostProcessing::LoadPreValue(void)
if (NUMBERS[j]->digit_roi || NUMBERS[j]->analog_roi)
{
NUMBERS[j]->ReturnValue = RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma);
NUMBERS[j]->ReturnValue = RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma + 1); // SIcherheitshalber 1 Stelle mehr, da ggf. Exgtended Resolution an ist (wird erst beim ersten Durchlauf gesetzt)
NUMBERS[j]->ReturnValueNoError = NUMBERS[j]->ReturnValue;
}
}
@@ -492,8 +492,6 @@ void ClassFlowPostProcessing::InitNUMBERS()
_number->MaxRateValue = 0.1;
_number->useMaxRateValue = false;
_number->checkDigitIncreaseConsistency = false;
_number->PreValueOkay = false;
_number->useMaxRateValue = false;
_number->DecimalShift = 0;
_number->DecimalShiftInitial = 0;
_number->isExtendedResolution = false;
@@ -568,12 +566,8 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
time_t imagetime = 0;
string rohwert;
// ErrorMessageText = "";
// Update Nachkomma, da sich beim Wechsel von CNNType Auto --> xyz auch die Nachkommastellen ändern können:
imagetime = flowMakeImage->getTimeImageTaken();
if (imagetime == 0)
time(&imagetime);
@@ -595,13 +589,14 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
if (NUMBERS[j]->digit_roi)
{
if (NUMBERS[j]->analog_roi)
if (NUMBERS[j]->analog_roi)
NUMBERS[j]->ReturnRawValue = flowDigit->getReadout(j, false);
else
NUMBERS[j]->ReturnRawValue = flowDigit->getReadout(j, NUMBERS[j]->isExtendedResolution); // Extended Resolution nur falls es keine analogen Ziffern gibt
}
if (NUMBERS[j]->digit_roi && NUMBERS[j]->analog_roi)
NUMBERS[j]->ReturnRawValue = NUMBERS[j]->ReturnRawValue + ".";
if (NUMBERS[j]->analog_roi)
NUMBERS[j]->ReturnRawValue = NUMBERS[j]->ReturnRawValue + flowAnalog->getReadout(j, NUMBERS[j]->isExtendedResolution);
@@ -661,7 +656,7 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
zwvalue = RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma);
}
if (NUMBERS[j]->useMaxRateValue && (abs(NUMBERS[j]->Value - NUMBERS[j]->PreValue) > NUMBERS[j]->MaxRateValue))
if (NUMBERS[j]->useMaxRateValue && ((abs(NUMBERS[j]->Value - NUMBERS[j]->PreValue) > NUMBERS[j]->MaxRateValue)))
{
NUMBERS[j]->ErrorMessageText = NUMBERS[j]->ErrorMessageText + "Rate too high - Read: " + RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma) + " - Pre: " + RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma);
NUMBERS[j]->Value = NUMBERS[j]->PreValue;
@@ -687,6 +682,8 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
UpdatePreValueINI = true;
}
}
string _zw = "PostProcessing - Raw: " + NUMBERS[j]->ReturnRawValue + " Value: " + NUMBERS[j]->ReturnValue + " Error: " + NUMBERS[j]->ErrorMessageText;
LogFile.WriteToFile(_zw);
}
SavePreValue();
@@ -723,8 +720,8 @@ void ClassFlowPostProcessing::UpdateNachkommaDecimalShift()
{
// printf("Nur digital + analog\n");
NUMBERS[j]->Nachkomma = NUMBERS[j]->analog_roi->ROI.size();
NUMBERS[j]->DecimalShift = NUMBERS[j]->DecimalShiftInitial;
NUMBERS[j]->Nachkomma = NUMBERS[j]->analog_roi->ROI.size() - NUMBERS[j]->DecimalShift;
if (NUMBERS[j]->isExtendedResolution && flowAnalog->isExtendedResolution()) // extended resolution ist an und soll auch bei dieser Ziffer verwendet werden
NUMBERS[j]->Nachkomma = NUMBERS[j]->Nachkomma+1;
@@ -822,14 +819,14 @@ float ClassFlowPostProcessing::checkDigitConsistency(float input, int _decilamsh
while (pot <= pot_max)
{
zw = input / pow(10, pot-1);
aktdigit_before = ((int) zw) % 10;
aktdigit_before = ((int) zw + 10) % 10;
zw = _preValue / pow(10, pot-1);
olddigit_before = ((int) zw) % 10;
olddigit_before = ((int) zw + 10) % 10;
zw = input / pow(10, pot);
aktdigit = ((int) zw) % 10;
aktdigit = ((int) zw + 10) % 10;
zw = _preValue / pow(10, pot);
olddigit = ((int) zw) % 10;
olddigit = ((int) zw + 10) % 10;
no_nulldurchgang = (olddigit_before <= aktdigit_before);

View File

@@ -80,7 +80,7 @@ void memCopyGen(uint8_t* _source, uint8_t* _target, int _size)
FILE* OpenFileAndWait(const char* nm, const char* _mode, int _waitsec)
{
printf("open config file %s in mode %s\n", nm, _mode);
printf("open file %s in mode %s\n", nm, _mode);
FILE *pfile = fopen(nm, _mode);
/*

View File

@@ -44,12 +44,12 @@ int CTfLiteClass::GetOutClassification(int _von, int _bis)
//printf("\n number output neurons: %d\n\n", numeroutput);
if (_bis == -1)
_bis = numeroutput;
_bis = numeroutput -1;
if (_von == -1)
_von = 0;
if (_bis > numeroutput)
if (_bis >= numeroutput)
{
printf("ANZAHL OUTPUT NEURONS passt nicht zu geforderter Classifizierung!");
return -1;
@@ -57,7 +57,7 @@ int CTfLiteClass::GetOutClassification(int _von, int _bis)
zw_max = output2->data.f[_von];
zw_class = _von;
for (int i = _von+1; i <= _bis; ++i)
for (int i = _von + 1; i <= _bis; ++i)
{
zw = output2->data.f[i];
if (zw > zw_max)

View File

@@ -189,6 +189,36 @@ esp_err_t handler_doflow(httpd_req_t *req)
};
esp_err_t handler_json(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_json - Start");
#endif
printf("handler_JSON uri:\n"); printf(req->uri); printf("\n");
char _query[100];
char _size[10];
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
httpd_resp_set_type(req, "application/json");
std::string zw = tfliteflow.getJSON();
if (zw.length() > 0)
httpd_resp_sendstr_chunk(req, zw.c_str());
string query = std::string(_query);
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_sendstr_chunk(req, NULL);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_JSON - Done");
#endif
return ESP_OK;
};
esp_err_t handler_wasserzaehler(httpd_req_t *req)
@@ -710,4 +740,10 @@ void register_server_tflite_uri(httpd_handle_t server)
camuri.handler = handler_wasserzaehler;
camuri.user_ctx = (void*) "Wasserzaehler";
httpd_register_uri_handler(server, &camuri);
camuri.uri = "/json";
camuri.handler = handler_json;
camuri.user_ctx = (void*) "JSON";
httpd_register_uri_handler(server, &camuri);
}

View File

@@ -184,32 +184,6 @@ void wifi_init_sta(const char *_ssid, const char *_password, const char *_hostna
ip_addr_set_ip4_u32(&dns_info.ip, ip.addr);
ESP_ERROR_CHECK(esp_netif_set_dns_info(my_sta, ESP_NETIF_DNS_MAIN, &dns_info));
}
/////////////////////////////////////////////////////////////////
// esp_netif_create_default_wifi_sta();
// wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
// ESP_ERROR_CHECK(esp_wifi_init(&cfg));
/*
////////////////////////////// esp-idf 4.2 //////////////////////////
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&event_handler,
NULL,
&instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
&event_handler,
NULL,
&instance_got_ip));
////////////////////////// ENDE esp-idf 4.2 ///////////////////////////
*/
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
@@ -253,27 +227,6 @@ void wifi_init_sta(const char *_ssid, const char *_password, const char *_hostna
} else {
ESP_LOGE(TAG, "UNEXPECTED EVENT");
}
/* The event will not be processed after unregister */
/*
////////////////////////////// esp-idf 4.2 //////////////////////////
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip));
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
////////////////////////// ENDE esp-idf 4.2 ///////////////////////////
*/
/* Deaktiveren, damit bei einen Verbindungsabbruch neu aufgebaut wird
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler));
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler));
vEventGroupDelete(s_wifi_event_group);
*/
/*
while (BlinkIsRunning)
{
vTaskDelay(100 / portTICK_PERIOD_MS);
}
*/
}

View File

@@ -12,7 +12,7 @@
#include <string.h>
std::vector<string> ZerlegeZeile(std::string input, std::string _delimiter = "")
std::vector<string> ZerlegeZeileWLAN(std::string input, std::string _delimiter = "")
{
std::vector<string> Output;
std::string delimiter = " =,";
@@ -23,13 +23,13 @@ std::vector<string> ZerlegeZeile(std::string input, std::string _delimiter = "")
input = trim(input, delimiter);
size_t pos = findDelimiterPos(input, delimiter);
std::string token;
while (pos != std::string::npos) {
if (pos != std::string::npos) // Zerlegt nur bis ersten Gleichheitszeichen !!! Sonderfall für WLAN.ini
{
token = input.substr(0, pos);
token = trim(token, delimiter);
Output.push_back(token);
input.erase(0, pos + 1);
input = trim(input, delimiter);
pos = findDelimiterPos(input, delimiter);
}
Output.push_back(input);
@@ -67,10 +67,8 @@ void LoadWlanFromFile(std::string fn, char *&_ssid, char *&_password, char *&_ho
while ((line.size() > 0) || !(feof(pFile)))
{
// printf("%s", line.c_str());
zerlegt = ZerlegeZeile(line, "=");
zerlegt = ZerlegeZeileWLAN(line, "=");
zerlegt[0] = trim(zerlegt[0], " ");
for (int i = 2; i < zerlegt.size(); ++i)
zerlegt[1] = zerlegt[1] + "=" + zerlegt[i];
if ((zerlegt.size() > 1) && (toUpper(zerlegt[0]) == "HOSTNAME")){
hostname = trim(zerlegt[1]);
@@ -212,7 +210,7 @@ bool ChangeHostName(std::string fn, std::string _newhostname)
while ((line.size() > 0) || !(feof(pFile)))
{
printf("%s", line.c_str());
zerlegt = ZerlegeZeile(line, "=");
zerlegt = ZerlegeZeileWLAN(line, "=");
zerlegt[0] = trim(zerlegt[0], " ");
if ((zerlegt.size() > 1) && (toUpper(zerlegt[0]) == "HOSTNAME")){

View File

@@ -1,132 +0,0 @@
#include "Color.h"
#include <algorithm>
#include <cmath>
#include <cassert>
namespace {
// Int -> fixed point
int up( int x ) { return x * 255; }
} // namespace
int iRgbSqrt( int num ) {
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_.28base_2.29
assert( "sqrt input should be non-negative" && num >= 0 );
assert( "sqrt input should no exceed 16 bits" && num <= 0xFFFF );
int res = 0;
int bit = 1 << 16;
while ( bit > num )
bit >>= 2;
while ( bit != 0 ) {
if ( num >= res + bit ) {
num -= res + bit;
res = ( res >> 1 ) + bit;
} else
res >>= 1;
bit >>= 2;
}
return res;
}
Rgb::Rgb( Hsv y ) {
// https://stackoverflow.com/questions/24152553/hsv-to-rgb-and-back-without-floating-point-math-in-python
// greyscale
if( y.s == 0 ) {
r = g = b = y.v;
return;
}
const int region = y.h / 43;
const int remainder = ( y.h - ( region * 43 ) ) * 6;
const int p = ( y.v * ( 255 - y.s ) ) >> 8;
const int q = ( y.v * ( 255 - ( ( y.s * remainder ) >> 8 ) ) ) >> 8;
const int t = ( y.v * ( 255 - ( ( y.s * (255 -remainder ) ) >> 8 ) ) ) >> 8;
switch( region ) {
case 0: r = y.v; g = t; b = p; break;
case 1: r = q; g = y.v; b = p; break;
case 2: r = p; g = y.v; b = t; break;
case 3: r = p; g = q; b = y.v; break;
case 4: r = t; g = p; b = y.v; break;
case 5: r = y.v; g = p; b = q; break;
default: __builtin_trap();
}
a = y.a;
}
Rgb& Rgb::operator=( Hsv hsv ) {
Rgb r{ hsv };
swap( r );
return *this;
}
Rgb Rgb::operator+( Rgb in ) const {
auto copy = *this;
copy += in;
return copy;
}
Rgb& Rgb::operator+=( Rgb in ) {
unsigned int red = r + in.r;
r = ( red < 255 ) ? red : 255;
unsigned int green = g + in.g;
g = ( green < 255 ) ? green : 255;
unsigned int blue = b + in.b;
b = ( blue < 255 ) ? blue : 255;
return *this;
}
Rgb& Rgb::blend( Rgb in ) {
unsigned int inAlpha = in.a * ( 255 - a );
unsigned int alpha = a + inAlpha;
r = iRgbSqrt( ( ( r * r * a ) + ( in.r * in.r * inAlpha ) ) / alpha );
g = iRgbSqrt( ( ( g * g * a ) + ( in.g * in.g * inAlpha ) ) / alpha );
b = iRgbSqrt( ( ( b * b * a ) + ( in.b * in.b * inAlpha ) ) / alpha );
a = alpha;
return *this;
}
uint8_t IRAM_ATTR Rgb::getGrb( int idx ) {
switch ( idx ) {
case 0: return g;
case 1: return r;
case 2: return b;
}
__builtin_unreachable();
}
Hsv::Hsv( Rgb r ) {
int min = std::min( r.r, std::min( r.g, r.b ) );
int max = std::max( r.r, std::max( r.g, r.b ) );
int chroma = max - min;
v = max;
if ( chroma == 0 ) {
h = s = 0;
return;
}
s = up( chroma ) / max;
int hh;
if ( max == r.r )
hh = ( up( int( r.g ) - int( r.b ) ) ) / chroma / 6;
else if ( max == r.g )
hh = 255 / 3 + ( up( int( r.b ) - int( r.r ) ) ) / chroma / 6;
else
hh = 2 * 255 / 3 + ( up( int( r.r ) - int( r.g ) ) ) / chroma / 6;
if ( hh < 0 )
hh += 255;
h = hh;
a = r.a;
}
Hsv& Hsv::operator=( Rgb rgb ) {
Hsv h{ rgb };
swap( h );
return *this;
}

View File

@@ -1,69 +0,0 @@
#pragma once
#include <cstdint>
#include "esp_attr.h"
union Hsv;
union Rgb {
struct __attribute__ ((packed)) {
uint8_t r, g, b, a;
};
uint32_t value;
Rgb( uint8_t r = 0, uint8_t g = 0, uint8_t b = 0, uint8_t a = 255 ) : r( r ), g( g ), b( b ), a( a ) {}
Rgb( Hsv c );
Rgb& operator=( Rgb rgb ) { swap( rgb ); return *this; }
Rgb& operator=( Hsv hsv );
Rgb operator+( Rgb in ) const;
Rgb& operator+=( Rgb in );
bool operator==( Rgb in ) const { return in.value == value; }
Rgb& blend( Rgb in );
void swap( Rgb& o ) { value = o.value; }
void linearize() {
r = channelGamma(r);
g = channelGamma(g);
b = channelGamma(b);
}
uint8_t IRAM_ATTR getGrb( int idx );
void stretchChannels( uint8_t maxR, uint8_t maxG, uint8_t maxB ) {
r = stretch( r, maxR );
g = stretch( g, maxG );
b = stretch( b, maxB );
}
void stretchChannelsEvenly( uint8_t max ) {
stretchChannels( max, max, max );
}
private:
uint8_t stretch( int value, uint8_t max ) {
return ( value * max ) >> 8;
}
uint8_t channelGamma( int channel ) {
/* The optimal gamma correction is x^2.8. However, this is expensive to
* compute. Therefore, we use x^3 for gamma correction. Also, we add a
* bias as the WS2812 LEDs do not turn on for values less than 4. */
if (channel == 0)
return channel;
channel = channel * channel * channel * 251;
channel >>= 24;
return static_cast< uint8_t >( 4 + channel );
}
};
union Hsv {
struct __attribute__ ((packed)) {
uint8_t h, s, v, a;
};
uint32_t value;
Hsv( uint8_t h, uint8_t s = 0, uint8_t v = 0, uint8_t a = 255 ) : h( h ), s( s ), v( v ), a( a ) {}
Hsv( Rgb r );
Hsv& operator=( Hsv h ) { swap( h ); return *this; }
Hsv& operator=( Rgb rgb );
bool operator==( Hsv in ) const { return in.value == value; }
void swap( Hsv& o ) { value = o.value; }
};

View File

@@ -1,63 +0,0 @@
#include "SmartLeds.h"
IsrCore SmartLed::_interruptCore = CoreCurrent;
intr_handle_t SmartLed::_interruptHandle = NULL;
SmartLed*& IRAM_ATTR SmartLed::ledForChannel( int channel ) {
static SmartLed* table[8] = { nullptr };
assert( channel < 8 );
return table[ channel ];
}
void IRAM_ATTR SmartLed::interruptHandler(void*) {
for (int channel = 0; channel != 8; channel++) {
auto self = ledForChannel( channel );
if ( RMT.int_st.val & (1 << (24 + channel ) ) ) { // tx_thr_event
if ( self )
self->copyRmtHalfBlock();
RMT.int_clr.val |= 1 << ( 24 + channel );
} else if ( RMT.int_st.val & ( 1 << (3 * channel ) ) ) { // tx_end
if ( self )
xSemaphoreGiveFromISR( self->_finishedFlag, nullptr );
RMT.int_clr.val |= 1 << ( 3 * channel );
}
}
}
void IRAM_ATTR SmartLed::copyRmtHalfBlock() {
int offset = detail::MAX_PULSES * _halfIdx;
_halfIdx = !_halfIdx;
int len = 3 - _componentPosition + 3 * ( _count - 1 );
len = std::min( len, detail::MAX_PULSES / 8 );
if ( !len ) {
for ( int i = 0; i < detail::MAX_PULSES; i++) {
RMTMEM.chan[ _channel].data32[i + offset ].val = 0;
}
}
int i;
for ( i = 0; i != len && _pixelPosition != _count; i++ ) {
uint8_t val = _buffer[ _pixelPosition ].getGrb( _componentPosition );
for ( int j = 0; j != 8; j++, val <<= 1 ) {
int bit = val >> 7;
int idx = i * 8 + offset + j;
RMTMEM.chan[ _channel ].data32[ idx ].val = _bitToRmt[ bit & 0x01 ].value;
}
if ( _pixelPosition == _count - 1 && _componentPosition == 2 ) {
RMTMEM.chan[ _channel ].data32[ i * 8 + offset + 7 ].duration1 =
_timing.TRS / ( detail::RMT_DURATION_NS * detail::DIVIDER );
}
_componentPosition++;
if ( _componentPosition == 3 ) {
_componentPosition = 0;
_pixelPosition++;
}
}
for ( i *= 8; i != detail::MAX_PULSES; i++ ) {
RMTMEM.chan[ _channel ].data32[ i + offset ].val = 0;
}
}

View File

@@ -1,530 +0,0 @@
#pragma once
/*
* A C++ driver for the WS2812 LEDs using the RMT peripheral on the ESP32.
*
* Jan "yaqwsx" Mrázek <email@honzamrazek.cz>
*
* Based on the work by Martin F. Falatic - https://github.com/FozzTexx/ws2812-demo
*/
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <memory>
#include <cassert>
#include <cstring>
#if defined ( ARDUINO )
extern "C" { // ...someone forgot to put in the includes...
#include "esp32-hal.h"
#include "esp_intr_alloc.h"
#include "esp_ipc.h"
#include "driver/gpio.h"
#include "driver/periph_ctrl.h"
#include "freertos/semphr.h"
#include "soc/rmt_struct.h"
#include <driver/spi_master.h>
#include "esp_idf_version.h"
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL( 4, 0, 0 )
#include "soc/dport_reg.h"
#endif
}
#elif defined ( ESP_PLATFORM )
extern "C" { // ...someone forgot to put in the includes...
#include <esp_intr_alloc.h>
#include <esp_ipc.h>
#include <driver/gpio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
#include <soc/dport_reg.h>
#include <soc/gpio_sig_map.h>
#include <soc/rmt_struct.h>
#include <driver/spi_master.h>
}
#include <stdio.h>
#endif
#include "Color.h"
namespace detail {
struct TimingParams {
uint32_t T0H;
uint32_t T1H;
uint32_t T0L;
uint32_t T1L;
uint32_t TRS;
};
union RmtPulsePair {
struct {
int duration0:15;
int level0:1;
int duration1:15;
int level1:1;
};
uint32_t value;
};
static const int DIVIDER = 4; // 8 still seems to work, but timings become marginal
static const int MAX_PULSES = 32; // A channel has a 64 "pulse" buffer - we use half per pass
static const double RMT_DURATION_NS = 12.5; // minimum time of a single RMT duration based on clock ns
} // namespace detail
using LedType = detail::TimingParams;
static const LedType LED_WS2812 = { 350, 700, 800, 600, 50000 };
static const LedType LED_WS2812B = { 400, 850, 850, 400, 50100 };
static const LedType LED_SK6812 = { 300, 600, 900, 600, 80000 };
static const LedType LED_WS2813 = { 350, 800, 350, 350, 300000 };
enum BufferType { SingleBuffer = 0, DoubleBuffer };
enum IsrCore { CoreFirst = 0, CoreSecond = 1, CoreCurrent = 2};
class SmartLed {
public:
// The RMT interrupt must not run on the same core as WiFi interrupts, otherwise SmartLeds
// can't fill the RMT buffer fast enough, resulting in rendering artifacts.
// Usually, that means you have to set isrCore == CoreSecond.
//
// If you use anything other than CoreCurrent, the FreeRTOS scheduler MUST be already running,
// so you can't use it if you define SmartLed as global variable.
SmartLed( const LedType& type, int count, int pin, int channel = 0, BufferType doubleBuffer = SingleBuffer, IsrCore isrCore = CoreCurrent)
: _timing( type ),
_channel( channel ),
_count( count ),
_firstBuffer( new Rgb[ count ] ),
_secondBuffer( doubleBuffer ? new Rgb[ count ] : nullptr ),
_finishedFlag( xSemaphoreCreateBinary() )
{
assert( channel >= 0 && channel < 8 );
assert( ledForChannel( channel ) == nullptr );
xSemaphoreGive( _finishedFlag );
DPORT_SET_PERI_REG_MASK( DPORT_PERIP_CLK_EN_REG, DPORT_RMT_CLK_EN );
DPORT_CLEAR_PERI_REG_MASK( DPORT_PERIP_RST_EN_REG, DPORT_RMT_RST );
PIN_FUNC_SELECT( GPIO_PIN_MUX_REG[ pin ], 2 );
gpio_set_direction( static_cast< gpio_num_t >( pin ), GPIO_MODE_OUTPUT );
gpio_matrix_out( static_cast< gpio_num_t >( pin ), RMT_SIG_OUT0_IDX + _channel, 0, 0 );
initChannel( _channel );
RMT.tx_lim_ch[ _channel ].limit = detail::MAX_PULSES;
RMT.int_ena.val |= 1 << ( 24 + _channel );
RMT.int_ena.val |= 1 << ( 3 * _channel );
_bitToRmt[ 0 ].level0 = 1;
_bitToRmt[ 0 ].level1 = 0;
_bitToRmt[ 0 ].duration0 = _timing.T0H / ( detail::RMT_DURATION_NS * detail::DIVIDER );
_bitToRmt[ 0 ].duration1 = _timing.T0L / ( detail::RMT_DURATION_NS * detail::DIVIDER );
_bitToRmt[ 1 ].level0 = 1;
_bitToRmt[ 1 ].level1 = 0;
_bitToRmt[ 1 ].duration0 = _timing.T1H / ( detail::RMT_DURATION_NS * detail::DIVIDER );
_bitToRmt[ 1 ].duration1 = _timing.T1L / ( detail::RMT_DURATION_NS * detail::DIVIDER );
if ( !anyAlive() ) {
_interruptCore = isrCore;
if(isrCore != CoreCurrent) {
ESP_ERROR_CHECK(esp_ipc_call_blocking(isrCore, registerInterrupt, NULL));
} else {
registerInterrupt(NULL);
}
}
ledForChannel( channel ) = this;
}
~SmartLed() {
ledForChannel( _channel ) = nullptr;
if ( !anyAlive() ) {
if(_interruptCore != CoreCurrent) {
ESP_ERROR_CHECK(esp_ipc_call_blocking(_interruptCore, unregisterInterrupt, NULL));
} else {
unregisterInterrupt(NULL);
}
}
vSemaphoreDelete( _finishedFlag );
}
Rgb& operator[]( int idx ) {
return _firstBuffer[ idx ];
}
const Rgb& operator[]( int idx ) const {
return _firstBuffer[ idx ];
}
void show() {
_buffer = _firstBuffer.get();
startTransmission();
swapBuffers();
}
bool wait( TickType_t timeout = portMAX_DELAY ) {
if( xSemaphoreTake( _finishedFlag, timeout ) == pdTRUE ) {
xSemaphoreGive( _finishedFlag );
return true;
}
return false;
}
int size() const {
return _count;
}
Rgb *begin() { return _firstBuffer.get(); }
const Rgb *begin() const { return _firstBuffer.get(); }
const Rgb *cbegin() const { return _firstBuffer.get(); }
Rgb *end() { return _firstBuffer.get() + _count; }
const Rgb *end() const { return _firstBuffer.get() + _count; }
const Rgb *cend() const { return _firstBuffer.get() + _count; }
private:
static intr_handle_t _interruptHandle;
static IsrCore _interruptCore;
static void initChannel( int channel ) {
RMT.apb_conf.fifo_mask = 1; //enable memory access, instead of FIFO mode.
RMT.apb_conf.mem_tx_wrap_en = 1; //wrap around when hitting end of buffer
RMT.conf_ch[ channel ].conf0.div_cnt = detail::DIVIDER;
RMT.conf_ch[ channel ].conf0.mem_size = 1;
RMT.conf_ch[ channel ].conf0.carrier_en = 0;
RMT.conf_ch[ channel ].conf0.carrier_out_lv = 1;
RMT.conf_ch[ channel ].conf0.mem_pd = 0;
RMT.conf_ch[ channel ].conf1.rx_en = 0;
RMT.conf_ch[ channel ].conf1.mem_owner = 0;
RMT.conf_ch[ channel ].conf1.tx_conti_mode = 0; //loop back mode.
RMT.conf_ch[ channel ].conf1.ref_always_on = 1; // use apb clock: 80M
RMT.conf_ch[ channel ].conf1.idle_out_en = 1;
RMT.conf_ch[ channel ].conf1.idle_out_lv = 0;
}
static void registerInterrupt(void *) {
ESP_ERROR_CHECK(esp_intr_alloc( ETS_RMT_INTR_SOURCE, 0, interruptHandler, nullptr, &_interruptHandle));
}
static void unregisterInterrupt(void*) {
esp_intr_free( _interruptHandle );
}
static SmartLed*& IRAM_ATTR ledForChannel( int channel );
static void IRAM_ATTR interruptHandler( void* );
void IRAM_ATTR copyRmtHalfBlock();
void swapBuffers() {
if ( _secondBuffer )
_firstBuffer.swap( _secondBuffer );
}
void startTransmission() {
// Invalid use of the library
if( xSemaphoreTake( _finishedFlag, 0 ) != pdTRUE )
abort();
_pixelPosition = _componentPosition = _halfIdx = 0;
copyRmtHalfBlock();
if ( _pixelPosition < _count )
copyRmtHalfBlock();
RMT.conf_ch[ _channel ].conf1.mem_rd_rst = 1;
RMT.conf_ch[ _channel ].conf1.tx_start = 1;
}
static bool anyAlive() {
for ( int i = 0; i != 8; i++ )
if ( ledForChannel( i ) != nullptr ) return true;
return false;
}
const LedType& _timing;
int _channel;
detail::RmtPulsePair _bitToRmt[ 2 ];
int _count;
std::unique_ptr< Rgb[] > _firstBuffer;
std::unique_ptr< Rgb[] > _secondBuffer;
Rgb *_buffer;
xSemaphoreHandle _finishedFlag;
int _pixelPosition;
int _componentPosition;
int _halfIdx;
};
class Apa102 {
public:
struct ApaRgb {
ApaRgb( uint8_t r = 0, uint8_t g = 0, uint32_t b = 0, uint32_t v = 0xFF )
: v( 0xE0 | v ), b( b ), g( g ), r( r )
{}
ApaRgb& operator=( const Rgb& o ) {
r = o.r;
g = o.g;
b = o.b;
return *this;
}
ApaRgb& operator=( const Hsv& o ) {
*this = Rgb{ o };
return *this;
}
uint8_t v, b, g, r;
};
static const int FINAL_FRAME_SIZE = 4;
static const int TRANS_COUNT = 2 + 8;
Apa102( int count, int clkpin, int datapin, BufferType doubleBuffer = SingleBuffer )
: _count( count ),
_firstBuffer( new ApaRgb[ count ] ),
_secondBuffer( doubleBuffer ? new ApaRgb[ count ] : nullptr ),
_initFrame( 0 )
{
spi_bus_config_t buscfg;
memset( &buscfg, 0, sizeof( buscfg ) );
buscfg.mosi_io_num = datapin;
buscfg.miso_io_num = -1;
buscfg.sclk_io_num = clkpin;
buscfg.quadwp_io_num = -1;
buscfg.quadhd_io_num = -1;
buscfg.max_transfer_sz = 65535;
spi_device_interface_config_t devcfg;
memset( &devcfg, 0, sizeof( devcfg ) );
devcfg.clock_speed_hz = 1000000;
devcfg.mode = 0;
devcfg.spics_io_num = -1;
devcfg.queue_size = TRANS_COUNT;
devcfg.pre_cb = nullptr;
auto ret = spi_bus_initialize( HSPI_HOST, &buscfg, 1 );
assert( ret == ESP_OK );
ret = spi_bus_add_device( HSPI_HOST, &devcfg, &_spi );
assert( ret == ESP_OK );
std::fill_n( _finalFrame, FINAL_FRAME_SIZE, 0xFFFFFFFF );
}
~Apa102() {
// ToDo
}
ApaRgb& operator[]( int idx ) {
return _firstBuffer[ idx ];
}
const ApaRgb& operator[]( int idx ) const {
return _firstBuffer[ idx ];
}
void show() {
_buffer = _firstBuffer.get();
startTransmission();
swapBuffers();
}
void wait() {
for ( int i = 0; i != _transCount; i++ ) {
spi_transaction_t *t;
spi_device_get_trans_result( _spi, &t, portMAX_DELAY );
}
}
private:
void swapBuffers() {
if ( _secondBuffer )
_firstBuffer.swap( _secondBuffer );
}
void startTransmission() {
for ( int i = 0; i != TRANS_COUNT; i++ ) {
_transactions[ i ].cmd = 0;
_transactions[ i ].addr = 0;
_transactions[ i ].flags = 0;
_transactions[ i ].rxlength = 0;
_transactions[ i ].rx_buffer = nullptr;
}
// Init frame
_transactions[ 0 ].length = 32;
_transactions[ 0 ].tx_buffer = &_initFrame;
spi_device_queue_trans( _spi, _transactions + 0, portMAX_DELAY );
// Data
_transactions[ 1 ].length = 32 * _count;
_transactions[ 1 ].tx_buffer = _buffer;
spi_device_queue_trans( _spi, _transactions + 1, portMAX_DELAY );
_transCount = 2;
// End frame
for ( int i = 0; i != 1 + _count / 32 / FINAL_FRAME_SIZE; i++ ) {
_transactions[ 2 + i ].length = 32 * FINAL_FRAME_SIZE;
_transactions[ 2 + i ].tx_buffer = _finalFrame;
spi_device_queue_trans( _spi, _transactions + 2 + i, portMAX_DELAY );
_transCount++;
}
}
spi_device_handle_t _spi;
int _count;
std::unique_ptr< ApaRgb[] > _firstBuffer, _secondBuffer;
ApaRgb *_buffer;
spi_transaction_t _transactions[ TRANS_COUNT ];
int _transCount;
uint32_t _initFrame;
uint32_t _finalFrame[ FINAL_FRAME_SIZE ];
};
class LDP8806 {
public:
struct LDP8806_GRB {
LDP8806_GRB( uint8_t g_7bit = 0, uint8_t r_7bit = 0, uint32_t b_7bit = 0 )
: g( g_7bit ), r( r_7bit ), b( b_7bit )
{
}
LDP8806_GRB& operator=( const Rgb& o ) {
//Convert 8->7bit colour
r = ( o.r * 127 / 256 ) | 0x80;
g = ( o.g * 127 / 256 ) | 0x80;
b = ( o.b * 127 / 256 ) | 0x80;
return *this;
}
LDP8806_GRB& operator=( const Hsv& o ) {
*this = Rgb{ o };
return *this;
}
uint8_t g, r, b;
};
static const int LED_FRAME_SIZE_BYTES = sizeof( LDP8806_GRB );
static const int LATCH_FRAME_SIZE_BYTES = 3;
static const int TRANS_COUNT_MAX = 20;//Arbitrary, supports up to 600 LED
LDP8806( int count, int clkpin, int datapin, BufferType doubleBuffer = SingleBuffer, uint32_t clock_speed_hz = 2000000 )
: _count( count ),
_firstBuffer( new LDP8806_GRB[ count ] ),
_secondBuffer( doubleBuffer ? new LDP8806_GRB[ count ] : nullptr ),
// one 'latch'/start-of-data mark frame for every 32 leds
_latchFrames( ( count + 31 ) / 32 )
{
spi_bus_config_t buscfg;
memset( &buscfg, 0, sizeof( buscfg ) );
buscfg.mosi_io_num = datapin;
buscfg.miso_io_num = -1;
buscfg.sclk_io_num = clkpin;
buscfg.quadwp_io_num = -1;
buscfg.quadhd_io_num = -1;
buscfg.max_transfer_sz = 65535;
spi_device_interface_config_t devcfg;
memset( &devcfg, 0, sizeof( devcfg ) );
devcfg.clock_speed_hz = clock_speed_hz;
devcfg.mode = 0;
devcfg.spics_io_num = -1;
devcfg.queue_size = TRANS_COUNT_MAX;
devcfg.pre_cb = nullptr;
auto ret = spi_bus_initialize( HSPI_HOST, &buscfg, 1 );
assert( ret == ESP_OK );
ret = spi_bus_add_device( HSPI_HOST, &devcfg, &_spi );
assert( ret == ESP_OK );
std::fill_n( _latchBuffer, LATCH_FRAME_SIZE_BYTES, 0x0 );
}
~LDP8806() {
// noop
}
LDP8806_GRB& operator[]( int idx ) {
return _firstBuffer[ idx ];
}
const LDP8806_GRB& operator[]( int idx ) const {
return _firstBuffer[ idx ];
}
void show() {
_buffer = _firstBuffer.get();
startTransmission();
swapBuffers();
}
void wait() {
while ( _transCount-- ) {
spi_transaction_t *t;
spi_device_get_trans_result( _spi, &t, portMAX_DELAY );
}
}
private:
void swapBuffers() {
if ( _secondBuffer )
_firstBuffer.swap( _secondBuffer );
}
void startTransmission() {
_transCount = 0;
for ( int i = 0; i != TRANS_COUNT_MAX; i++ ) {
_transactions[ i ].cmd = 0;
_transactions[ i ].addr = 0;
_transactions[ i ].flags = 0;
_transactions[ i ].rxlength = 0;
_transactions[ i ].rx_buffer = nullptr;
}
// LED Data
_transactions[ 0 ].length = ( LED_FRAME_SIZE_BYTES * 8 ) * _count;
_transactions[ 0 ].tx_buffer = _buffer;
spi_device_queue_trans( _spi, _transactions + _transCount, portMAX_DELAY );
_transCount++;
// 'latch'/start-of-data marker frames
for ( int i = 0; i < _latchFrames; i++ ) {
_transactions[ _transCount ].length = ( LATCH_FRAME_SIZE_BYTES * 8 );
_transactions[ _transCount ].tx_buffer = _latchBuffer;
spi_device_queue_trans( _spi, _transactions + _transCount, portMAX_DELAY );
_transCount++;
}
}
spi_device_handle_t _spi;
int _count;
std::unique_ptr< LDP8806_GRB[] > _firstBuffer, _secondBuffer;
LDP8806_GRB *_buffer;
spi_transaction_t _transactions[ TRANS_COUNT_MAX ];
int _transCount;
int _latchFrames;
uint8_t _latchBuffer[ LATCH_FRAME_SIZE_BYTES ];
};

View File

@@ -142,13 +142,7 @@ void task_NoSDBlink(void *pvParameter)
extern "C" void app_main(void)
{
TickType_t xDelay;
printf("Do Reset Camera\n");
PowerResetCamera();
Camera.InitCam();
Camera.LightOnOff(false);
if (!Init_NVS_SDCard())
{
xTaskCreate(&task_NoSDBlink, "task_NoSDBlink", configMINIMAL_STACK_SIZE * 64, NULL, tskIDLE_PRIORITY+1, NULL);
@@ -176,8 +170,8 @@ extern "C" void app_main(void)
printf("DNS IP: %s\n", dns);
wifi_init_sta(ssid, passwd, hostname, ip, gateway, netmask, dns);
wifi_init_sta(ssid, passwd, hostname, ip, gateway, netmask, dns);
xDelay = 2000 / portTICK_PERIOD_MS;
printf("main: sleep for : %ldms\n", (long) xDelay);
@@ -198,8 +192,8 @@ extern "C" void app_main(void)
printf("time %s\n", zw.c_str());
// Camera.InitCam();
// Camera.LightOnOff(false);
xDelay = 2000 / portTICK_PERIOD_MS;
// Camera.LightOnOff(false);
xDelay = 2000 / portTICK_PERIOD_MS;
printf("main: sleep for : %ldms\n", (long) xDelay);
vTaskDelay( xDelay );
@@ -215,6 +209,22 @@ extern "C" void app_main(void)
register_server_main_uri(server, "/sdcard");
printf("vor dotautostart\n");
TFliteDoAutoStart();
// init camera module
printf("Do Reset Camera\n");
PowerResetCamera();
esp_err_t cam = Camera.InitCam();
if (cam != ESP_OK) {
ESP_LOGE(TAGMAIN, "Failed to initialize camera module. "
"Check that your camera module is working and connected properly.");
LogFile.SwitchOnOff(true);
LogFile.WriteToFile("Failed to initialize camera module. "
"Check that your camera module is working and connected properly.");
LogFile.SwitchOnOff(false);
} else {
Camera.LightOnOff(false);
TFliteDoAutoStart();
}
}

View File

@@ -1,4 +1,4 @@
const char* GIT_REV="147d974";
const char* GIT_REV="e22b4b6";
const char* GIT_TAG="";
const char* GIT_BRANCH="master";
const char* BUILD_TIME="2021-09-25 18:55";
const char* BUILD_TIME="2021-12-02 21:53";

View File

@@ -13,7 +13,7 @@ extern "C"
#include "Helper.h"
#include <fstream>
const char* GIT_BASE_BRANCH = "master - v8.4.0 - 2021-09-25";
const char* GIT_BASE_BRANCH = "master - v9.2.0 - 2021-12-02";
const char* git_base_branch(void)

View File

@@ -1,4 +1,4 @@
const char* GIT_REV="147d974";
const char* GIT_REV="e22b4b6";
const char* GIT_TAG="";
const char* GIT_BRANCH="master";
const char* BUILD_TIME="2021-09-25 18:55";
const char* BUILD_TIME="2021-12-02 21:53";

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

BIN
images/ota-update-menue.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

View File

@@ -20,7 +20,7 @@ FlipImageSize = false
/config/ref1.jpg 442 142
[Digits]
Model = /config/dig1210s2q.tflite
Model = /config/dig1330s1q.tflite
;LogImageLocation = /log/digit
;LogfileRetentionInDays = 3
ModelInputSize = 20 32
@@ -29,7 +29,7 @@ main.dig2 343 126 30 54
main.dig3 391 126 30 54
[Analog]
Model = /config/ana0700s1lq.tflite
Model = /config/ana0910s3_longq.tflite
;LogImageLocation = /log/analog
;LogfileRetentionInDays = 3
ModelInputSize = 32 32
@@ -46,7 +46,7 @@ PreValueAgeStartup = 720
AllowNegativeRates = false
main.MaxRateValue = 0.1
ErrorMessage = true
CheckDigitIncreaseConsistency = true
CheckDigitIncreaseConsistency = false
;[MQTT]
;Uri = mqtt://IP-ADRESS:1883
@@ -62,7 +62,10 @@ CheckDigitIncreaseConsistency = true
;IO3 = input disabled 10 false false
;IO4 = built-in-led disabled 10 false false
;IO12 = input-pullup disabled 10 false false
;IO13 = input-pullup disabled 10 false false
;IO13 = input-pullup disabled 10 false false
LEDType = WS2812
LEDNumbers = 2
LEDColor = 50 50 50
[AutoTimer]
AutoStart = true

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -636,13 +636,13 @@ textarea {
<td colspan="4" style="padding-left: 20px;">
<h4><input type="checkbox" id="Category_GPIO_enabled" value="1" onclick='UpdateAfterCategoryCheck()' unchecked >
GPIO Settings
<span class="GPIO_item" style="color: red;"><b>EXPERIMENTAL</b> - Enabling GPIO handler, disable by default integrated flash light. Please enable it with GPIO4 settings.</span>
<span class="GPIO_item" > - Enabling GPIO handler, disable by default integrated flash light. Please enable it with GPIO4 (internal flash LED) settings or GPIO12 (external LED).</span>
</h4>
</td>
</tr>
<!------------- GPIO0 begin ------------------>
<tr class="GPIO_IO0 GPIO_item">
<tr class="expert" class="GPIO_IO0 GPIO_item">
<td width="20px" style="padding-left: 40px;">
<input type="checkbox" id="GPIO_IO0_enabled" value="1" onclick = 'InvertEnableItem("GPIO", "IO0")' unchecked>
</td>
@@ -656,9 +656,6 @@ textarea {
<option value="input-pullup">input pullup</option>
<option value="input-pulldown">input pulldown</option>
<option value="output">output</option>
<option value="output-pwm" disabled>output pwm (not implemented)</option>
<option value="external-flash-pwm" disabled>external flash light pwm controlled (not implemented)</option>
<option value="external-flash-ws281x" disabled>external flash light ws281x controlled (not implemented)</option>
</select>
</td>
</td>
@@ -668,10 +665,10 @@ textarea {
<span style="color: red">Pin is used to activate flash mode and must therefore be HIGH when booting.</span>
</td>
</tr>
<tr class="GPIO_IO0 GPIO_item">
<tr class="expert" class="GPIO_IO0 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 0 use interrupt</span>
<span id="GPIO_IO0_text" class="GPIO_IO0 GPIO_item">GPIO 0 use interrupt</span>
</td>
<td>
<td">
@@ -689,10 +686,10 @@ textarea {
GPIO 0 enable interrupt trigger
</td>
</tr>
<tr class="GPIO_IO0 GPIO_item">
<tr class="expert" class="GPIO_IO0 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 0 PWM duty resolution</span>
<span class="GPIO_IO0 GPIO_item">GPIO 0 PWM duty resolution</span>
</td>
<td>
<td"><input type="number" id="GPIO_IO0_value3" min="1" max="20"></td>
@@ -701,10 +698,10 @@ textarea {
GPIO 0 LEDC PWM duty resolution in bit
</td>
</tr>
<tr class="GPIO_IO0 GPIO_item">
<tr class="expert" class="GPIO_IO0 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 0 enable MQTT</span>
<span class="GPIO_IO0 GPIO_item">GPIO 0 enable MQTT</span>
</td>
<td>
<td"><input type="checkbox" id="GPIO_IO0_value4"></td>
@@ -713,10 +710,10 @@ textarea {
GPIO 0 enable MQTT publishing/subscribing
</td>
</tr>
<tr class="GPIO_IO0 GPIO_item">
<tr class="expert" class="GPIO_IO0 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 0 enable HTTP</span>
<span class="GPIO_IO0 GPIO_item">GPIO 0 enable HTTP</span>
</td>
<td>
<td"><input type="checkbox" id="GPIO_IO0_value5"></td>
@@ -725,10 +722,10 @@ textarea {
GPIO 0 enable HTTP write/read
</td>
</tr>
<tr class="GPIO_IO0 GPIO_item">
<tr class="expert" class="GPIO_IO0 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 0 name</span>
<span class="GPIO_IO0 GPIO_item">GPIO 0 name</span>
</td>
<td>
<td"><input type="text" id="GPIO_IO0_value6"></td>
@@ -740,12 +737,12 @@ textarea {
<!------------- GPIO0 end ------------------>
<!------------- GPIO1 begin ------------------>
<tr class="GPIO_IO1 GPIO_item">
<tr class="expert" class="GPIO_IO1 GPIO_item">
<td width="20px" style="padding-left: 40px;">
<input type="checkbox" id="GPIO_IO1_enabled" value="1" onclick = 'InvertEnableItem("GPIO", "IO1")' unchecked>
</td>
<td>
<span id="GPIO_IO1_text">GPIO 1 state</span>
<span id="GPIO_IO1_text" class="GPIO_IO1 GPIO_item">GPIO 1 state</span>
</td>
<td>
<td">
@@ -754,9 +751,6 @@ textarea {
<option value="input-pullup">input pullup</option>
<option value="input-pulldown">input pulldown</option>
<option value="output">output</option>
<option value="output-pwm" disabled>output pwm (not implemented)</option>
<option value="external-flash-pwm" disabled>external flash light pwm controlled (not implemented)</option>
<option value="external-flash-ws281x" disabled>external flash light ws281x controlled (not implemented)</option>
</select>
</td>
</td>
@@ -764,10 +758,10 @@ textarea {
GPIO 1 <br><span style="color: blue">Used by default for serial communication as TX pin.<br>Required for seriales monitor.</span>
</td>
</tr>
<tr class="GPIO_IO1 GPIO_item">
<tr class="expert" class="GPIO_IO1 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 1 use interrupt</span>
<span class="GPIO_IO1 GPIO_item" class="expert">GPIO 1 use interrupt</span>
</td>
<td>
<td">
@@ -785,10 +779,10 @@ textarea {
GPIO 1 enable interrupt trigger
</td>
</tr>
<tr class="GPIO_IO1 GPIO_item">
<tr class="expert" class="GPIO_IO1 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 1 PWM duty resolution</span>
<span class="GPIO_IO1 GPIO_item">GPIO 1 PWM duty resolution</span>
</td>
<td>
<td"><input type="number" id="GPIO_IO1_value3" min="1" max="20"></td>
@@ -797,10 +791,10 @@ textarea {
GPIO 1 LEDC PWM duty resolution in bit
</td>
</tr>
<tr class="GPIO_IO1 GPIO_item">
<tr class="expert" class="GPIO_IO1 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 1 enable MQTT</span>
<span class="GPIO_IO1 GPIO_item">GPIO 1 enable MQTT</span>
</td>
<td>
<td"><input type="checkbox" id="GPIO_IO1_value4"></td>
@@ -809,10 +803,10 @@ textarea {
GPIO 1 enable MQTT publishing/subscribing
</td>
</tr>
<tr class="GPIO_IO1 GPIO_item">
<tr class="expert" class="GPIO_IO1 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 1 enable HTTP</span>
<span class="GPIO_IO1 GPIO_item">GPIO 1 enable HTTP</span>
</td>
<td>
<td"><input type="checkbox" id="GPIO_IO1_value5"></td>
@@ -821,10 +815,10 @@ textarea {
GPIO 1 enable HTTP write/read
</td>
</tr>
<tr class="GPIO_IO1 GPIO_item">
<tr class="expert" class="GPIO_IO1 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 1 name</span>
<span class="GPIO_IO1 GPIO_item" class="expert">GPIO 1 name</span>
</td>
<td>
<td"><input type="text" id="GPIO_IO1_value6"></td>
@@ -836,12 +830,12 @@ textarea {
<!------------- GPIO1 end ------------------>
<!------------- GPIO3 begin ------------------>
<tr class="GPIO_IO3 GPIO_item">
<tr class="expert" class="GPIO_IO3 GPIO_item">
<td width="20px" style="padding-left: 40px;">
<input type="checkbox" id="GPIO_IO3_enabled" value="1" onclick = 'InvertEnableItem("GPIO", "IO3")' unchecked>
</td>
<td>
<span id="GPIO_IO3_text">GPIO 3 state</span>
<span id="GPIO_IO3_text" class="GPIO_IO3 GPIO_item">GPIO 3 state</span>
</td>
<td>
<td">
@@ -850,9 +844,6 @@ textarea {
<option value="input-pullup">input pullup</option>
<option value="input-pulldown">input pulldown</option>
<option value="output">output</option>
<option value="output-pwm" disabled>output pwm (not implemented)</option>
<option value="external-flash-pwm" disabled>external flash light pwm controlled (not implemented)</option>
<option value="external-flash-ws281x" disabled>external flash light ws281x controlled (not implemented)</option>
</select>
</td>
</td>
@@ -860,10 +851,10 @@ textarea {
GPIO 3 <span style="color: blue">Used by default for serial communication as RX pin.</span>
</td>
</tr>
<tr class="GPIO_IO3 GPIO_item">
<tr class="expert" class="GPIO_IO3 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 3 use interrupt</span>
<span class="GPIO_IO3 GPIO_item">GPIO 3 use interrupt</span>
</td>
<td>
<td">
@@ -881,10 +872,10 @@ textarea {
GPIO 3 Used by default for serial communication as RX pin.
</td>
</tr>
<tr class="GPIO_IO3 GPIO_item">
<tr class="expert" class="GPIO_IO3 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 3 PWM duty resolution</span>
<span class="GPIO_IO3 GPIO_item">GPIO 3 PWM duty resolution</span>
</td>
<td>
<td"><input type="number" id="GPIO_IO3_value3" min="1" max="20"></td>
@@ -893,10 +884,10 @@ textarea {
GPIO 3 LEDC PWM duty resolution in bit
</td>
</tr>
<tr class="GPIO_IO3 GPIO_item">
<tr class="expert" class="GPIO_IO3 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 3 enable MQTT</span>
<span class="GPIO_IO3 GPIO_item">GPIO 3 enable MQTT</span>
</td>
<td>
<td"><input type="checkbox" id="GPIO_IO3_value4"></td>
@@ -905,10 +896,10 @@ textarea {
GPIO 3 enable MQTT publishing/subscribing
</td>
</tr>
<tr class="GPIO_IO3 GPIO_item">
<tr class="expert" class="GPIO_IO3 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 3 enable HTTP</span>
<span class="GPIO_IO3 GPIO_item">GPIO 3 enable HTTP</span>
</td>
<td>
<td"><input type="checkbox" id="GPIO_IO3_value5"></td>
@@ -917,10 +908,10 @@ textarea {
GPIO 3 enable HTTP write/read
</td>
</tr>
<tr class="GPIO_IO3 GPIO_item">
<tr class="expert" class="GPIO_IO3 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 3 name</span>
<span class="GPIO_IO3 GPIO_item">GPIO 3 name</span>
</td>
<td>
<td"><input type="text" id="GPIO_IO3_value6"></td>
@@ -937,7 +928,7 @@ textarea {
<input type="checkbox" id="GPIO_IO4_enabled" value="1" onclick = 'InvertEnableItem("GPIO", "IO4")' unchecked>
</td>
<td>
<span id="GPIO_IO4_text">GPIO 4 state</span>
<span id="GPIO_IO4_text" class="GPIO_IO4 GPIO_item">GPIO 4 state</span>
</td>
<td>
<td">
@@ -947,9 +938,6 @@ textarea {
<option value="input-pulldown">input pulldown</option>
<option value="output">output</option>
<option value="built-in-led">built-in led flash light</option>
<option value="output-pwm" disabled>output pwm (not implemented)</option>
<option value="external-flash-pwm" disabled>external flash light pwm controlled (not implemented)</option>
<option value="external-flash-ws281x" disabled>external flash light ws281x controlled (not implemented)</option>
</select>
</td>
</td>
@@ -958,10 +946,10 @@ textarea {
<span style="color: red">Pin is used for build-in flash light.</span>
</td>
</tr>
<tr class="GPIO_IO4 GPIO_item">
<tr class="expert" class="GPIO_IO4 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 4 use interrupt</span>
<span class="GPIO_IO4 GPIO_item">GPIO 4 use interrupt</span>
</td>
<td>
<td">
@@ -979,10 +967,10 @@ textarea {
GPIO 4 enable interrupt trigger
</td>
</tr>
<tr class="GPIO_IO4 GPIO_item">
<tr class="expert" class="GPIO_IO4 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 4 PWM duty resolution</span>
<span class="GPIO_IO4 GPIO_item">GPIO 4 PWM duty resolution</span>
</td>
<td>
<td"><input type="number" id="GPIO_IO4_value3" min="1" max="20"></td>
@@ -991,10 +979,10 @@ textarea {
GPIO 4 LEDC PWM duty resolution in bit
</td>
</tr>
<tr class="GPIO_IO4 GPIO_item">
<tr class="expert" class="GPIO_IO4 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 4 enable MQTT</span>
<span class="GPIO_IO4 GPIO_item">GPIO 4 enable MQTT</span>
</td>
<td>
<td"><input type="checkbox" id="GPIO_IO4_value4"></td>
@@ -1003,10 +991,10 @@ textarea {
GPIO 4 enable MQTT publishing/subscribing
</td>
</tr>
<tr class="GPIO_IO4 GPIO_item">
<tr class="expert" class="GPIO_IO4 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 4 enable HTTP</span>
<span class="GPIO_IO4 GPIO_item">GPIO 4 enable HTTP</span>
</td>
<td>
<td"><input type="checkbox" id="GPIO_IO4_value5"></td>
@@ -1015,10 +1003,10 @@ textarea {
GPIO 4 enable HTTP write/read
</td>
</tr>
<tr class="GPIO_IO4 GPIO_item">
<tr class="expert" class="GPIO_IO4 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 4 name</span>
<span class="GPIO_IO4 GPIO_item">GPIO 4 name</span>
</td>
<td>
<td"><input type="text" id="GPIO_IO4_value6"></td>
@@ -1035,7 +1023,7 @@ textarea {
<input type="checkbox" id="GPIO_IO12_enabled" value="1" onclick = 'InvertEnableItem("GPIO", "IO12")' unchecked>
</td>
<td>
<span id="GPIO_IO12_text">GPIO 12 state</span>
<span class="GPIO_IO12 GPIO_item" id="GPIO_IO12_text">GPIO 12 state</span>
</td>
<td>
<td">
@@ -1044,9 +1032,7 @@ textarea {
<option value="input-pullup">input pullup</option>
<option value="input-pulldown">input pulldown</option>
<option value="output">output</option>
<option value="output-pwm" disabled>output pwm (not implemented)</option>
<option value="external-flash-pwm" disabled>external flash light pwm controlled (not implemented)</option>
<option value="external-flash-ws281x">external flash light ws281x controlled (experimental)</option>
<option value="external-flash-ws281x">external flash light ws281x controlled</option>
</select>
</td>
</td>
@@ -1054,14 +1040,14 @@ textarea {
GPIO 12 is usable without restrictions
</td>
</tr>
<tr class="GPIO_IO12 GPIO_item">
<tr class="expert" class="GPIO_IO12 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 12 use interrupt</span>
<span class="GPIO_IO12 GPIO_item">GPIO 12 use interrupt</span>
</td>
<td>
<td">
<select id="GPIO_IO12_value2">
<td>
<select class="GPIO_IO12 GPIO_item" id="GPIO_IO12_value2">
<option value="disabled">disabled</option>
<option value="rising-edge">rising edge</option>
<option value="falling-edge">falling edge</option>
@@ -1075,10 +1061,10 @@ textarea {
GPIO 12 enable interrupt trigger
</td>
</tr>
<tr class="GPIO_IO12 GPIO_item">
<tr class="expert" class="GPIO_IO12 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 12 PWM duty resolution</span>
<span class="GPIO_IO12 GPIO_item">GPIO 12 PWM duty resolution</span>
</td>
<td>
<td"><input type="number" id="GPIO_IO12_value3" min="1" max="20"></td>
@@ -1087,10 +1073,10 @@ textarea {
GPIO 12 LEDC PWM duty resolution in bit
</td>
</tr>
<tr class="GPIO_IO12 GPIO_item">
<tr class="expert" class="GPIO_IO12 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 12 enable MQTT</span>
<span class="GPIO_IO12 GPIO_item">GPIO 12 enable MQTT</span>
</td>
<td>
<td"><input type="checkbox" id="GPIO_IO12_value4"></td>
@@ -1099,10 +1085,10 @@ textarea {
GPIO 12 enable MQTT publishing/subscribing
</td>
</tr>
<tr class="GPIO_IO12 GPIO_item">
<tr class="expert" class="GPIO_IO12 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 12 enable HTTP</span>
<span class="GPIO_IO12 GPIO_item">GPIO 12 enable HTTP</span>
</td>
<td>
<td"><input type="checkbox" id="GPIO_IO12_value5"></td>
@@ -1111,10 +1097,10 @@ textarea {
GPIO 12 enable HTTP write/read
</td>
</tr>
<tr class="GPIO_IO12 GPIO_item">
<tr class="expert" class="GPIO_IO12 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 12 name</span>
<span class="GPIO_IO12 GPIO_item">GPIO 12 name</span>
</td>
<td>
<td"><input type="text" id="GPIO_IO12_value6"></td>
@@ -1123,10 +1109,60 @@ textarea {
GPIO 12 MQTT topic name (empty = GPIO12). Allowed characters (a-z, A-Z, 0-9, _, -)
</td>
</tr>
<tr class="GPIO_IO12 GPIO_item" id="wstypeex3">
<td width="20px" style="padding-left: 40px;">
</td>
<td>
<span class="GPIO_IO12 GPIO_item" id="GPIO_LEDType_text">LED-Type</span>
</td>
<td class="GPIO_IO12 GPIO_item">
<select class="GPIO_IO12 GPIO_item" id="GPIO_LEDType_value1">
<option value="WS2812" selected>WS2812</option>
<option value="WS2812B">WS2812B</option>
<option value="SK6812">SK6812 (not tested)</option>
<option value="WS2813">WS2813 (not tested)</option>
</select>
</td>
<td class="description">
Type of WS2812x, that is connected to GPIO12
</td>
</tr>
<tr class="GPIO_IO12 GPIO_item" id="LEDANZex8" >
<td width="20px" style="padding-left: 40px;">
</td>
<td>
<span class="GPIO_IO12 GPIO_item" id="GPIO_LEDNumbers_text">Numbers of LEDs</span>
</td>
<td>
<input type="number" name="name" id="GPIO_LEDNumbers_value1" size="13" min="1">
</td>
<td style="font-size: 80%;">
Number of LEDs on the external LED-stripe
</td>
</tr>
<tr class="GPIO_IO12 GPIO_item" id="LEDRGBex9">
<td width="20px" style="padding-left: 40px;">
</td>
<td>
<span class="GPIO_IO12 GPIO_item" id="GPIO_LEDColor_text">LED Color</span>
</td>
<td class="GPIO_IO12 GPIO_item">
R <input class="smallSelect" class="GPIO_IO12 GPIO_item" id="GPIO_LEDColor_value1" size="12">
G <input class="smallSelect" class="GPIO_IO12 GPIO_item" id="GPIO_LEDColor_value2" size="12">
B <input class="smallSelect" class="GPIO_IO12 GPIO_item" id="GPIO_LEDColor_value3" size="12">
</td>
<td style="font-size: 80%;">
Color of LEDs in (R)ed, (G)reen (B)lue from 0...255
</td>
</tr>
<!------------- GPIO12 end ------------------>
<!------------- GPIO13 begin ------------------>
<tr class="GPIO_IO13 GPIO_item">
<tr class="expert" class="GPIO_IO13 GPIO_item">
<td width="20px" style="padding-left: 40px;">
<input type="checkbox" id="GPIO_IO13_enabled" value="1" onclick = 'InvertEnableItem("GPIO", "IO13")' unchecked>
</td>
@@ -1140,9 +1176,6 @@ textarea {
<option value="input-pullup">input pullup</option>
<option value="input-pulldown">input pulldown</option>
<option value="output">output</option>
<option value="output-pwm" disabled>output pwm (not implemented)</option>
<option value="external-flash-pwm" disabled>external flash light pwm controlled (not implemented)</option>
<option value="external-flash-ws281x" disabled>external flash light ws281x controlled (not implemented)</option>
</select>
</td>
</td>
@@ -1150,10 +1183,10 @@ textarea {
GPIO 13 is usable without restrictions
</td>
</tr>
<tr class="GPIO_IO13 GPIO_item">
<tr class="expert" class="GPIO_IO13 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 13 use interrupt</span>
<span class="GPIO_IO13 GPIO_item">GPIO 13 use interrupt</span>
</td>
<td>
<td">
@@ -1171,10 +1204,10 @@ textarea {
GPIO 13 enable interrupt trigger
</td>
</tr>
<tr class="GPIO_IO13 GPIO_item">
<tr class="expert" class="GPIO_IO13 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 13 PWM duty resolution</span>
<span class="GPIO_IO13 GPIO_item">GPIO 13 PWM duty resolution</span>
</td>
<td>
<td"><input type="number" id="GPIO_IO13_value3" min="1" max="20"></td>
@@ -1183,10 +1216,10 @@ textarea {
GPIO 13 LEDC PWM duty resolution in bit
</td>
</tr>
<tr class="GPIO_IO13 GPIO_item">
<tr class="expert" class="GPIO_IO13 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 13 enable MQTT</span>
<span class="GPIO_IO13 GPIO_item">GPIO 13 enable MQTT</span>
</td>
<td>
<td"><input type="checkbox" id="GPIO_IO13_value4"></td>
@@ -1195,10 +1228,10 @@ textarea {
GPIO 13 enable MQTT publishing/subscribing
</td>
</tr>
<tr class="GPIO_IO13 GPIO_item">
<tr class="expert" class="GPIO_IO13 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 13 enable HTTP</span>
<span class="GPIO_IO13 GPIO_item">GPIO 13 enable HTTP</span>
</td>
<td>
<td"><input type="checkbox" id="GPIO_IO13_value5"></td>
@@ -1207,10 +1240,10 @@ textarea {
GPIO 13 enable HTTP write/read
</td>
</tr>
<tr class="GPIO_IO13 GPIO_item">
<tr class="expert" class="GPIO_IO13 GPIO_item">
<td width="20px" style="padding-left: 40px;"></td>
<td>
<span>GPIO 13 name</span>
<span class="GPIO_IO13 GPIO_item">GPIO 13 name</span>
</td>
<td>
<td"><input type="text" id="GPIO_IO13_value6"></td>
@@ -1496,6 +1529,11 @@ function InvertEnableItem(_cat, _param)
}
function setEnabled(className, enabled) {
_color = "color:lightgrey;";
if (enabled) {
_color = "color:black;";
}
let elements = document.getElementsByClassName(className);
for (i = 0; i < elements.length; i++) {
if (enabled) {
@@ -1509,6 +1547,7 @@ function setEnabled(className, enabled) {
if (inputs[j].id.endsWith("_enabled"))
continue;
inputs[j].style = _color
if (enabled) {
inputs[j].removeAttribute("disabled");
} else {
@@ -1700,6 +1739,9 @@ function UpdateInput() {
WriteParameter(param, category, "GPIO", "IO4", true);
WriteParameter(param, category, "GPIO", "IO12", true);
WriteParameter(param, category, "GPIO", "IO13", true);
WriteParameter(param, category, "GPIO", "LEDType", false);
WriteParameter(param, category, "GPIO", "LEDNumbers", false);
WriteParameter(param, category, "GPIO", "LEDColor", false);
WriteParameter(param, category, "AutoTimer", "AutoStart", false);
WriteParameter(param, category, "AutoTimer", "Intervall", false);
@@ -1763,6 +1805,16 @@ function ReadParameterAll()
ReadParameter(param, "GPIO", "IO4", true);
ReadParameter(param, "GPIO", "IO12", true);
ReadParameter(param, "GPIO", "IO13", true);
ReadParameter(param, "GPIO", "LEDType", false);
ReadParameter(param, "GPIO", "LEDNumbers", false);
ReadParameter(param, "GPIO", "LEDColor", false);
// Folgende Zeilen sind für Abwärtskompatibität < v9.0.0 notwendig (manchmal parameter auskommentiert)
param["GPIO"]["LEDType"]["enabled"] = true;
param["GPIO"]["LEDNumbers"]["enabled"] = true;
param["GPIO"]["LEDColor"]["enabled"] = true;
param["GPIO"]["LEDType"]["found"] = true;
param["GPIO"]["LEDNumbers"]["found"] = true;
param["GPIO"]["LEDColor"]["found"] = true;
ReadParameter(param, "AutoTimer", "AutoStart", false);
ReadParameter(param, "AutoTimer", "Intervall", false);
@@ -1799,9 +1851,13 @@ function UpdateAfterCategoryCheck() {
function UpdateExpertModus()
{
var _style = 'display:none;';
// var _style = 'display:none;';
var _style_pur = 'none';
var _hidden = true;
if (document.getElementById("ExpertModus_enabled").checked) {
_style = '';
// _style = '';
_style_pur = '';
_hidden = false;
document.getElementById("Edit_Config_Direct").style.display = "";
}
else
@@ -1811,8 +1867,22 @@ function UpdateExpertModus()
const expert = document.querySelectorAll(".expert");
for (var i = 0; i < expert.length; i++) {
document.getElementById(expert[i].id).style = _style;
expert[i].style.display = _style_pur;
// document.getElementById(expert[i].id).style = _style;
}
// Enable / Disable die Optionen in den Menues für die Auswahl. Falls kein Expertenmodus soll nur ein Wert (built-in-led oder externan-flash-ws281x) möglich sein
Array.from(document.querySelector("#GPIO_IO4_value1").options).forEach(function(option_element) {
if (option_element.value != "built-in-led")
option_element.hidden = _hidden;
});
Array.from(document.querySelector("#GPIO_IO12_value1").options).forEach(function(option_element) {
if (option_element.value != "external-flash-ws281x")
option_element.hidden = _hidden;
});
}
function saveTextAsFile()

View File

@@ -62,7 +62,7 @@ p {font-size: 1em;}
}
ParseConfig();
param = getConfigParameters();
param["System"]["SetupMode"]["enabled"] = false;
param["System"]["SetupMode"]["enabled"] = true;
param["System"]["SetupMode"]["value1"] = "false";
WriteConfigININew();

View File

@@ -3,13 +3,16 @@ function gethost_Version(){
return "1.0.0 - 20200910";
}
function getbasepath(){
var host = window.location.hostname;
if ((host == "127.0.0.1") || (host == "localhost") || (host == ""))
if (((host == "127.0.0.1") || (host == "localhost") || (host == ""))
&& ((window.location.port == "80") || (window.location.port == "")))
{
// host = "http://192.168.2.219"; // jomjol interner test
// host = "http://192.168.178.46"; // jomjol interner test
host = "http://192.168.178.22"; // jomjol interner Real
host = "http://192.168.178.79"; // jomjol interner Real
// host = "http://192.168.43.191";
// host = "."; // jomjol interner localhost
@@ -18,6 +21,10 @@ function getbasepath(){
{
host = "http://" + host;
}
if (window.location.port != "") {
host = host + ":" + window.location.port;
}
return host;
}

View File

@@ -2,9 +2,9 @@ function readconfig_Version(){
return "1.0.0 - 20200910";
}
var config_gesamt;
var config_split;
var param;
var config_gesamt = "";
var config_split = [];
var param = [];
var category;
var ref = new Array(2);
var NUMBERS = new Array(0);
@@ -31,7 +31,6 @@ function ParseConfig() {
ParamAddValue(param, catname, "ImageQuality");
ParamAddValue(param, catname, "ImageSize");
ParamAddValue(param, catname, "FixedExposure");
ParamAddValue(param, catname, "UseGPIOControlledIllumination");
var catname = "Alignment";
category[catname] = new Object();
@@ -54,7 +53,6 @@ function ParseConfig() {
ParamAddValue(param, catname, "LogImageLocation");
ParamAddValue(param, catname, "LogfileRetentionInDays");
ParamAddValue(param, catname, "ModelInputSize", 2);
// ParamAddValue(param, catname, "ExtendedResolution");
var catname = "Analog";
category[catname] = new Object();
@@ -65,7 +63,6 @@ function ParseConfig() {
ParamAddValue(param, catname, "LogImageLocation");
ParamAddValue(param, catname, "LogfileRetentionInDays");
ParamAddValue(param, catname, "ModelInputSize", 2);
// ParamAddValue(param, catname, "ExtendedResolution");
var catname = "PostProcessing";
category[catname] = new Object();
@@ -81,7 +78,6 @@ function ParseConfig() {
ParamAddValue(param, catname, "IgnoreLeadingNaN", 1, true);
ParamAddValue(param, catname, "ErrorMessage");
ParamAddValue(param, catname, "CheckDigitIncreaseConsistency");
// ParamAddValue(param, catname, "IgnoreLeadingNaN");
var catname = "MQTT";
category[catname] = new Object();
@@ -108,6 +104,12 @@ function ParseConfig() {
ParamAddValue(param, catname, "LEDType");
ParamAddValue(param, catname, "LEDNumbers");
ParamAddValue(param, catname, "LEDColor", 3);
// Default Values, um abwärtskompatiblität zu gewährleisten
param[catname]["LEDType"]["value1"] = "WS2812";
param[catname]["LEDNumbers"]["value1"] = "2";
param[catname]["LEDColor"]["value1"] = "50";
param[catname]["LEDColor"]["value2"] = "50";
param[catname]["LEDColor"]["value3"] = "50";
var catname = "AutoTimer";

View File

@@ -1 +1 @@
10.1.0
11.1.0