mirror of
https://github.com/jomjol/AI-on-the-edge-device.git
synced 2025-12-07 20:16:55 +03:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05a0f6fa62 | ||
|
|
2ab2f070b4 | ||
|
|
103de2011b | ||
|
|
3cec93e2f1 | ||
|
|
a23d7ee6e2 | ||
|
|
42afbcf655 | ||
|
|
c61167bdfa | ||
|
|
642cefb84f | ||
|
|
1223aa7c70 | ||
|
|
0d90977917 | ||
|
|
7e57e85e75 |
13
README.md
13
README.md
@@ -25,14 +25,21 @@ A 3d-printable housing can be found here: https://www.thingiverse.com/thing:4571
|
||||
|
||||
**General remark:** Beside the `firmware.bin`, typically also the content of `/html` needs to be updated!
|
||||
|
||||
##### Rolling - (2020-11-03)
|
||||
|
||||
* Bug-Fix in time sync on warm reboot
|
||||
|
||||
##### Rolling - (2020-10-14)
|
||||
|
||||
* based on v3.0.0 (2020-10-14)
|
||||
* based on v3.1.0 (2020-10-26)
|
||||
|
||||
|
||||
|
||||
##### 3.1.0 MQTT-Client - (2020-10-26)
|
||||
|
||||
* Update digital CNN to v6.5.0 and HTML (Info to hostname, IP, ssid)
|
||||
|
||||
* New implementation of "checkDigitConsistency" also for digits
|
||||
* MQTT-Adapter: user and password for sign in MQTT-Broker
|
||||
|
||||
##### 3.0.0 MQTT-Client (2020-10-14)
|
||||
|
||||
* Implementation of MQTT Client
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
std::string FormatFileName(std::string input);
|
||||
void FindReplace(std::string& line, std::string& oldString, std::string& newString);
|
||||
|
||||
void CopyFile(string input, string output);
|
||||
|
||||
size_t findDelimiterPos(string input, string delimiter);
|
||||
//string trim(string istring);
|
||||
string trim(string istring, string adddelimiter = "");
|
||||
bool ctype_space(const char c, string adddelimiter);
|
||||
|
||||
string getFileType(string filename);
|
||||
|
||||
string toUpper(string in);
|
||||
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
//#pragma warning(disable : 4996)
|
||||
|
||||
#include "Helper.h"
|
||||
|
||||
//#define ISWINDOWS_TRUE
|
||||
|
||||
using namespace std;
|
||||
|
||||
std::string FormatFileName(std::string input)
|
||||
{
|
||||
#ifdef ISWINDOWS_TRUE
|
||||
input.erase(0, 1);
|
||||
std::string os = "/";
|
||||
std::string ns = "\\";
|
||||
FindReplace(input, os, ns);
|
||||
#endif
|
||||
return input;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FindReplace(std::string& line, std::string& oldString, std::string& newString) {
|
||||
const size_t oldSize = oldString.length();
|
||||
|
||||
// do nothing if line is shorter than the string to find
|
||||
if (oldSize > line.length()) return;
|
||||
|
||||
const size_t newSize = newString.length();
|
||||
for (size_t pos = 0; ; pos += newSize) {
|
||||
// Locate the substring to replace
|
||||
pos = line.find(oldString, pos);
|
||||
if (pos == std::string::npos) return;
|
||||
if (oldSize == newSize) {
|
||||
// if they're same size, use std::string::replace
|
||||
line.replace(pos, oldSize, newString);
|
||||
}
|
||||
else {
|
||||
// if not same size, replace by erasing and inserting
|
||||
line.erase(pos, oldSize);
|
||||
line.insert(pos, newString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool ctype_space(const char c, string adddelimiter)
|
||||
{
|
||||
if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == 11)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (adddelimiter.find(c) != string::npos)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
string trim(string istring, string adddelimiter)
|
||||
{
|
||||
bool trimmed = false;
|
||||
|
||||
if (ctype_space(istring[istring.length() - 1], adddelimiter))
|
||||
{
|
||||
istring.erase(istring.length() - 1);
|
||||
trimmed = true;
|
||||
}
|
||||
|
||||
if (ctype_space(istring[0], adddelimiter))
|
||||
{
|
||||
istring.erase(0, 1);
|
||||
trimmed = true;
|
||||
}
|
||||
|
||||
if ((trimmed == false) || (istring.size() == 0))
|
||||
{
|
||||
return istring;
|
||||
}
|
||||
else
|
||||
{
|
||||
return trim(istring, adddelimiter);
|
||||
}
|
||||
}
|
||||
|
||||
size_t findDelimiterPos(string input, string delimiter)
|
||||
{
|
||||
size_t pos = std::string::npos;
|
||||
size_t zw;
|
||||
string akt_del;
|
||||
|
||||
for (int anz = 0; anz < delimiter.length(); ++anz)
|
||||
{
|
||||
akt_del = delimiter[anz];
|
||||
if ((zw = input.find(akt_del)) != std::string::npos)
|
||||
{
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
if (zw < pos)
|
||||
pos = zw;
|
||||
}
|
||||
else
|
||||
pos = zw;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
void CopyFile(string input, string output)
|
||||
{
|
||||
input = FormatFileName(input);
|
||||
output = FormatFileName(output);
|
||||
|
||||
char cTemp;
|
||||
FILE* fpSourceFile = fopen(input.c_str(), "rb");
|
||||
FILE* fpTargetFile = fopen(output.c_str(), "wb");
|
||||
|
||||
// Code Section
|
||||
|
||||
// Read From The Source File - "Copy"
|
||||
while (fread(&cTemp, 1, 1, fpSourceFile) == 1)
|
||||
{
|
||||
// Write To The Target File - "Paste"
|
||||
fwrite(&cTemp, 1, 1, fpTargetFile);
|
||||
}
|
||||
|
||||
// Close The Files
|
||||
fclose(fpSourceFile);
|
||||
fclose(fpTargetFile);
|
||||
}
|
||||
|
||||
|
||||
string getFileType(string filename)
|
||||
{
|
||||
int lastpos = filename.find(".", 0);
|
||||
int neu_pos;
|
||||
while ((neu_pos = filename.find(".", lastpos + 1)) > -1)
|
||||
{
|
||||
lastpos = neu_pos;
|
||||
}
|
||||
|
||||
string zw = filename.substr(lastpos + 1, filename.size() - lastpos);
|
||||
|
||||
return zw;
|
||||
}
|
||||
|
||||
|
||||
string toUpper(string in)
|
||||
{
|
||||
for (int i = 0; i < in.length(); ++i)
|
||||
in[i] = toupper(in[i]);
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ static const char *MAIN_TAG = "connect_wlan";
|
||||
std::string ssid;
|
||||
std::string passphrase;
|
||||
std::string hostname;
|
||||
std::string ipaddress;
|
||||
|
||||
std::string std_hostname = "watermeter";
|
||||
|
||||
@@ -123,6 +124,7 @@ void initialise_wifi(std::string _ssid, std::string _passphrase, std::string _ho
|
||||
xEventGroupWaitBits(wifi_event_group,CONNECTED_BIT,true,true,portMAX_DELAY);
|
||||
tcpip_adapter_ip_info_t ip_info;
|
||||
ESP_ERROR_CHECK(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info));
|
||||
ipaddress = std::string(ip4addr_ntoa(&ip_info.ip));
|
||||
printf("IPv4 : %s\n", ip4addr_ntoa(&ip_info.ip));
|
||||
printf("HostName : %s\n", hostname.c_str());
|
||||
}
|
||||
@@ -191,3 +193,14 @@ void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphra
|
||||
}
|
||||
|
||||
|
||||
std::string getHostname(){
|
||||
return hostname;
|
||||
}
|
||||
|
||||
std::string getIPAddress(){
|
||||
return ipaddress;
|
||||
}
|
||||
|
||||
std::string getSSID(){
|
||||
return ssid;
|
||||
}
|
||||
|
||||
@@ -10,4 +10,8 @@ void initialise_wifi(std::string _ssid, std::string _passphrase, std::string _ho
|
||||
|
||||
void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphrase, std::string &_hostname);
|
||||
|
||||
std::string getHostname();
|
||||
std::string getIPAddress();
|
||||
std::string getSSID();
|
||||
|
||||
#endif
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
#include "camera_define.h"
|
||||
|
||||
#include "driver/ledc.h"
|
||||
|
||||
CCamera Camera;
|
||||
|
||||
|
||||
@@ -20,6 +22,42 @@ typedef struct {
|
||||
size_t len;
|
||||
} jpg_chunking_t;
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define LEDC_LS_CH2_GPIO (4)
|
||||
#define LEDC_LS_CH2_CHANNEL LEDC_CHANNEL_2
|
||||
#define LEDC_LS_TIMER LEDC_TIMER_1
|
||||
#define LEDC_LS_MODE LEDC_LOW_SPEED_MODE
|
||||
#define LEDC_TEST_DUTY (4000)
|
||||
|
||||
void test(){
|
||||
ledc_channel_config_t ledc_channel = { };
|
||||
|
||||
ledc_channel.channel = LEDC_LS_CH2_CHANNEL;
|
||||
ledc_channel.duty = 0;
|
||||
ledc_channel.gpio_num = FLASH_GPIO;
|
||||
ledc_channel.speed_mode = LEDC_LS_MODE;
|
||||
ledc_channel.hpoint = 0;
|
||||
ledc_channel.timer_sel = LEDC_LS_TIMER;
|
||||
|
||||
ledc_channel_config(&ledc_channel);
|
||||
|
||||
ledc_set_duty(ledc_channel.speed_mode, ledc_channel.channel, LEDC_TEST_DUTY);
|
||||
ledc_update_duty(ledc_channel.speed_mode, ledc_channel.channel);
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size_t len){
|
||||
jpg_chunking_t *j = (jpg_chunking_t *)arg;
|
||||
if(!index){
|
||||
|
||||
@@ -404,6 +404,9 @@ void doReboot(){
|
||||
LogFile.WriteToFile("Reboot - now");
|
||||
KillTFliteTasks();
|
||||
xTaskCreate(&task_reboot, "reboot", configMINIMAL_STACK_SIZE * 64, NULL, 10, NULL);
|
||||
vTaskDelay(5000 / portTICK_PERIOD_MS);
|
||||
esp_restart();
|
||||
hard_restart();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -335,25 +335,23 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
Value = std::stof(zw);
|
||||
if (checkDigitIncreaseConsistency)
|
||||
{
|
||||
// Value = checkDigitConsistency(Value, DecimalShift, isanalog);
|
||||
Value = checkDigitConsistency(Value, DecimalShift, isanalog);
|
||||
}
|
||||
|
||||
zwvalue = RundeOutput(Value, AnzahlAnalog - DecimalShift);
|
||||
|
||||
if ((!AllowNegativeRates) && (Value < PreValue))
|
||||
{
|
||||
error = "Negative Rate - Returned old value - read value: " + zwvalue;
|
||||
error = error + "Negative Rate - Returned old value - read value: " + zwvalue + " ";
|
||||
Value = PreValue;
|
||||
zwvalue = RundeOutput(Value, AnzahlAnalog - DecimalShift);
|
||||
}
|
||||
else
|
||||
|
||||
if (useMaxRateValue && (abs(Value - PreValue) > MaxRateValue))
|
||||
{
|
||||
if (useMaxRateValue && (abs(Value - PreValue) > MaxRateValue))
|
||||
{
|
||||
error = "Rate too high - Returned old value - read value: " + zwvalue;
|
||||
Value = PreValue;
|
||||
zwvalue = RundeOutput(Value, AnzahlAnalog - DecimalShift);
|
||||
}
|
||||
error = error + "Rate too high - Returned old value - read value: " + zwvalue + " ";
|
||||
Value = PreValue;
|
||||
zwvalue = RundeOutput(Value, AnzahlAnalog - DecimalShift);
|
||||
}
|
||||
|
||||
ReturnValueNoError = zwvalue;
|
||||
@@ -426,7 +424,7 @@ float ClassFlowPostProcessing::checkDigitConsistency(float input, int _decilamsh
|
||||
float zw;
|
||||
|
||||
pot = _decilamshift;
|
||||
if (!_isanalog) // falls es keine analogwerte gibt, kann die letzte nicht bewerte werden
|
||||
if (!_isanalog) // falls es keine analogwerte gibt, kann die letzte nicht bewertet werden
|
||||
{
|
||||
pot++;
|
||||
}
|
||||
|
||||
@@ -75,24 +75,18 @@ void setup_time(void)
|
||||
time(&now);
|
||||
localtime_r(&now, &timeinfo);
|
||||
// Is time set? If not, tm_year will be (1970 - 1900).
|
||||
if (timeinfo.tm_year < (2016 - 1900)) {
|
||||
if ((timeinfo.tm_year < (2016 - 1900)) || setTimeAlwaysOnReboot) {
|
||||
ESP_LOGI(TAG, "Time is not set yet. Connecting to WiFi and getting time over NTP.");
|
||||
initialize_sntp();
|
||||
obtain_time();
|
||||
// update 'now' variable with current time
|
||||
time(&now);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (setTimeAlwaysOnReboot)
|
||||
{
|
||||
obtain_time();
|
||||
}
|
||||
}
|
||||
char strftime_buf[64];
|
||||
|
||||
// Set timezone to Berlin Standard Time
|
||||
setenv("TZ", "UTC+9", 1);
|
||||
// setenv("TZ", "Europe/Berlin", 1);
|
||||
tzset();
|
||||
localtime_r(&now, &timeinfo);
|
||||
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include "time_sntp.h"
|
||||
|
||||
#include "connect_wlan.h"
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#include "esp_wifi.h"
|
||||
@@ -94,6 +96,34 @@ esp_err_t info_get_handler(httpd_req_t *req)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (_task.compare("Hostname") == 0)
|
||||
{
|
||||
std::string zw;
|
||||
zw = std::string(getHostname());
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (_task.compare("IP") == 0)
|
||||
{
|
||||
std::string zw;
|
||||
zw = std::string(getIPAddress());
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (_task.compare("SSID") == 0)
|
||||
{
|
||||
std::string zw;
|
||||
zw = std::string(getSSID());
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const char* GIT_REV="2614481";
|
||||
const char* GIT_REV="2ab2f07";
|
||||
const char* GIT_TAG="";
|
||||
const char* GIT_BRANCH="master";
|
||||
const char* BUILD_TIME="2020-10-14 18:40";
|
||||
const char* BUILD_TIME="2020-11-03 22:12";
|
||||
@@ -13,7 +13,7 @@ extern "C"
|
||||
#include "Helper.h"
|
||||
#include <fstream>
|
||||
|
||||
const char* GIT_BASE_BRANCH = "master - v3.0.0 - 2020-10-14";
|
||||
const char* GIT_BASE_BRANCH = "master - v3.1.0 - 2020-10-26";
|
||||
|
||||
|
||||
const char* git_base_branch(void)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const char* GIT_REV="2614481";
|
||||
const char* GIT_REV="2ab2f07";
|
||||
const char* GIT_TAG="";
|
||||
const char* GIT_BRANCH="master";
|
||||
const char* BUILD_TIME="2020-10-14 18:40";
|
||||
const char* BUILD_TIME="2020-11-03 22:12";
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -13,7 +13,7 @@ SearchFieldY = 20
|
||||
|
||||
|
||||
[Digits]
|
||||
Model=/config/dig0640s3.tflite
|
||||
Model=/config/dig0650s3.tflite
|
||||
LogImageLocation = /log/digit
|
||||
ModelInputSize 20, 32
|
||||
digit1, 306, 120, 37, 67
|
||||
|
||||
Binary file not shown.
BIN
sd-card/config/dig0650s3.tflite
Normal file
BIN
sd-card/config/dig0650s3.tflite
Normal file
Binary file not shown.
@@ -73,8 +73,8 @@ li.dropdown {
|
||||
|
||||
<body style="font-family: arial">
|
||||
|
||||
<h1>Watermeter - AI on the edge</h1>
|
||||
<h2>An ESP32 all in neural network recognition system</h2>
|
||||
<h1>Digitizer - AI on the edge</h1>
|
||||
<h2>An ESP32 all inclusive neural network recognition system for meter digitalization</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#"onclick="document.getElementById('maincontent').src = '/wasserzaehler_roi.html';">Overview</a></li>
|
||||
|
||||
@@ -23,9 +23,42 @@ div {
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
|
||||
<body style="font-family: arial; padding: 0px 10px;">
|
||||
<h3>Host Info</h3>
|
||||
|
||||
<table style="font-family: arial">
|
||||
<tr>
|
||||
<td>
|
||||
Hostname:
|
||||
</td>
|
||||
<td>
|
||||
<div id="gitbranch">
|
||||
<object data="/version?type=Hostname"></object>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
IP-Address:
|
||||
</td>
|
||||
<td>
|
||||
<div id="gitbranch">
|
||||
<object data="/version?type=IP"></object>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
WLan-SSID:
|
||||
</td>
|
||||
<td>
|
||||
<div id="gitbranch">
|
||||
<object data="/version?type=SSID"></object>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Version Info</h3>
|
||||
|
||||
<table style="font-family: arial">
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.0.0
|
||||
1.1.0
|
||||
|
||||
Reference in New Issue
Block a user