Initial Commit
This commit is contained in:
parent
3ecc443494
commit
f4a22880fe
|
@ -0,0 +1,5 @@
|
|||
.pioenvs
|
||||
.piolibdeps
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
|
@ -0,0 +1,67 @@
|
|||
# Continuous Integration (CI) is the practice, in software
|
||||
# engineering, of merging all developer working copies with a shared mainline
|
||||
# several times a day < https://docs.platformio.org/page/ci/index.html >
|
||||
#
|
||||
# Documentation:
|
||||
#
|
||||
# * Travis CI Embedded Builds with PlatformIO
|
||||
# < https://docs.travis-ci.com/user/integration/platformio/ >
|
||||
#
|
||||
# * PlatformIO integration with Travis CI
|
||||
# < https://docs.platformio.org/page/ci/travis.html >
|
||||
#
|
||||
# * User Guide for `platformio ci` command
|
||||
# < https://docs.platformio.org/page/userguide/cmd_ci.html >
|
||||
#
|
||||
#
|
||||
# Please choice one of the following templates (proposed below) and uncomment
|
||||
# it (remove "# " before each line) or use own configuration according to the
|
||||
# Travis CI documentation (see above).
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# Template #1: General project. Test it using existing `platformio.ini`.
|
||||
#
|
||||
|
||||
# language: python
|
||||
# python:
|
||||
# - "2.7"
|
||||
#
|
||||
# sudo: false
|
||||
# cache:
|
||||
# directories:
|
||||
# - "~/.platformio"
|
||||
#
|
||||
# install:
|
||||
# - pip install -U platformio
|
||||
# - platformio update
|
||||
#
|
||||
# script:
|
||||
# - platformio run
|
||||
|
||||
|
||||
#
|
||||
# Template #2: The project is intended to by used as a library with examples
|
||||
#
|
||||
|
||||
# language: python
|
||||
# python:
|
||||
# - "2.7"
|
||||
#
|
||||
# sudo: false
|
||||
# cache:
|
||||
# directories:
|
||||
# - "~/.platformio"
|
||||
#
|
||||
# env:
|
||||
# - PLATFORMIO_CI_SRC=path/to/test/file.c
|
||||
# - PLATFORMIO_CI_SRC=examples/file.ino
|
||||
# - PLATFORMIO_CI_SRC=path/to/test/directory
|
||||
#
|
||||
# install:
|
||||
# - pip install -U platformio
|
||||
# - platformio update
|
||||
#
|
||||
# script:
|
||||
# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"terminal.integrated.env.windows": {
|
||||
"PATH": "C:\\Users\\Carsten\\.platformio\\penv\\Scripts;C:\\Users\\Carsten\\.platformio\\penv;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\WINDOWS\\System32\\OpenSSH\\;C:\\Program Files (x86)\\NVIDIA Corporation\\PhysX\\Common;C:\\Program Files\\PuTTY\\;C:\\Program Files\\Microsoft VS Code\\bin;C:\\Program Files\\Git\\cmd;C:\\Users\\Carsten\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Program Files (x86)\\Nmap;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\WINDOWS\\System32\\OpenSSH\\;C:\\Program Files (x86)\\NVIDIA Corporation\\PhysX\\Common;C:\\Program Files\\PuTTY\\;C:\\Program Files\\Microsoft VS Code\\bin;C:\\Program Files\\Git\\cmd;C:\\Users\\Carsten\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Program Files (x86)\\Nmap",
|
||||
"PLATFORMIO_CALLER": "vscode"
|
||||
},
|
||||
"files.associations": {
|
||||
"array": "cpp",
|
||||
"deque": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"initializer_list": "cpp"
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,459 @@
|
|||
/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
line-height: 1.15;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
article,
|
||||
aside,
|
||||
footer,
|
||||
header,
|
||||
nav,
|
||||
section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
figcaption,
|
||||
figure,
|
||||
main {
|
||||
display: block;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 1em 40px;
|
||||
}
|
||||
|
||||
hr {
|
||||
-webkit-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
a {
|
||||
background-color: transparent;
|
||||
-webkit-text-decoration-skip: objects;
|
||||
}
|
||||
|
||||
a:active,
|
||||
a:hover {
|
||||
outline-width: 0;
|
||||
}
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: none;
|
||||
text-decoration: underline;
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
mark {
|
||||
background-color: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
audio,
|
||||
video {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: sans-serif;
|
||||
font-size: 100%;
|
||||
line-height: 1.15;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
button,
|
||||
input {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
button,
|
||||
html [type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
button:-moz-focusring,
|
||||
[type="button"]:-moz-focusring,
|
||||
[type="reset"]:-moz-focusring,
|
||||
[type="submit"]:-moz-focusring {
|
||||
outline: 1px dotted ButtonText;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
|
||||
legend {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
color: inherit;
|
||||
display: table;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
progress {
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
[type="checkbox"],
|
||||
[type="radio"] {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type="search"] {
|
||||
-webkit-appearance: textfield;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
[type="search"]::-webkit-search-cancel-button,
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
details,
|
||||
menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
canvas {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
html {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
-webkit-box-sizing: inherit;
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
@-ms-viewport {
|
||||
width: device-width;
|
||||
}
|
||||
|
||||
html {
|
||||
-ms-overflow-style: scrollbar;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
font-size: 1rem;
|
||||
font-weight: normal;
|
||||
line-height: 1.5;
|
||||
color: #292b2c;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
[tabindex="-1"]:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
abbr[title],
|
||||
abbr[data-original-title] {
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: .5rem;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0275d8;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:focus, a:hover {
|
||||
color: #014c8c;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:not([href]):not([tabindex]) {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:not([href]):not([tabindex]):focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
[role="button"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a,
|
||||
area,
|
||||
button,
|
||||
[role="button"],
|
||||
input,
|
||||
label,
|
||||
select,
|
||||
summary,
|
||||
textarea {
|
||||
-ms-touch-action: manipulation;
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
color: #636c72;
|
||||
text-align: left;
|
||||
caption-side: bottom;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
outline: 1px dotted;
|
||||
outline: 5px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
textarea {
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
input[type="radio"]:disabled,
|
||||
input[type="checkbox"]:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
input[type="date"],
|
||||
input[type="time"],
|
||||
input[type="datetime-local"],
|
||||
input[type="month"] {
|
||||
-webkit-appearance: listbox;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: .5rem;
|
||||
font-size: 1.5rem;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
input[type="search"] {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}html{-webkit-box-sizing:border-box;box-sizing:border-box}*,::after,::before{-webkit-box-sizing:inherit;box-sizing:inherit}@-ms-viewport{width:device-width}html{-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}body{font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:1rem;font-weight:400;line-height:1.5;color:#292b2c;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{cursor:help}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}a{color:#0275d8;text-decoration:none}a:focus,a:hover{color:#014c8c;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle}[role=button]{cursor:pointer}[role=button],a,area,button,input,label,select,summary,textarea{-ms-touch-action:manipulation;touch-action:manipulation}table{border-collapse:collapse;background-color:transparent}caption{padding-top:.75rem;padding-bottom:.75rem;color:#636c72;text-align:left;caption-side:bottom}th{text-align:left}label{display:inline-block;margin-bottom:.5rem}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,select,textarea{line-height:inherit}input[type=checkbox]:disabled,input[type=radio]:disabled{cursor:not-allowed}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{-webkit-appearance:listbox}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit}input[type=search]{-webkit-appearance:none}output{display:inline-block}[hidden]{display:none!important}/*# sourceMappingURL=bootstrap_r.min.css.map */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":["../../scss/_normalize.scss","bootstrap-reboot.css","../../scss/_reboot.scss","../../scss/_variables.scss","../../scss/mixins/_hover.scss"],"names":[],"mappings":"4EAYA,KACE,YAAA,WACA,YAAA,KACA,qBAAA,KACA,yBAAA,KAUF,KACE,OAAA,EAOF,QAAA,MAAA,OAAA,OAAA,IAAA,QAME,QAAA,MAQF,GACE,UAAA,IACA,OAAA,MAAA,EAWF,WAAA,OAAA,KAGE,QAAA,MAOF,OACE,OAAA,IAAA,KAQF,GACE,mBAAA,YAAA,WAAA,YACA,OAAA,EACA,SAAA,QAQF,IACE,YAAA,UAAA,UACA,UAAA,IAWF,EACE,iBAAA,YACA,6BAAA,QAQF,SAAA,QAEE,cAAA,EAQF,YACE,cAAA,KACA,gBAAA,UACA,gBAAA,UAAA,OAOF,EAAA,OAEE,YAAA,QAOF,EAAA,OAEE,YAAA,OAQF,KAAA,IAAA,KAGE,YAAA,UAAA,UACA,UAAA,IAOF,IACE,WAAA,OAOF,KACE,iBAAA,KACA,MAAA,KAOF,MACE,UAAA,IAQF,IAAA,IAEE,UAAA,IACA,YAAA,EACA,SAAA,SACA,eAAA,SAGF,IACE,OAAA,OAGF,IACE,IAAA,MAUF,MAAA,MAEE,QAAA,aAOF,sBACE,QAAA,KACA,OAAA,EAOF,IACE,aAAA,KAOF,eACE,SAAA,OAWF,OAAA,MAAA,SAAA,OAAA,SAKE,YAAA,WACA,UAAA,KACA,YAAA,KACA,OAAA,EAQF,OAAA,MAEE,SAAA,QAQF,OAAA,OAEE,eAAA,KASF,aAAA,cAAA,OAAA,mBAIE,mBAAA,OAOF,gCAAA,+BAAA,gCAAA,yBAIE,aAAA,KACA,QAAA,EAOF,6BAAA,4BAAA,6BAAA,sBAIE,QAAA,IAAA,OAAA,WAOF,SACE,OAAA,IAAA,MAAA,OACA,OAAA,EAAA,IACA,QAAA,MAAA,OAAA,MAUF,OACE,mBAAA,WAAA,WAAA,WACA,MAAA,QACA,QAAA,MACA,UAAA,KACA,QAAA,EACA,YAAA,OAQF,SACE,QAAA,aACA,eAAA,SAOF,SACE,SAAA,KCrKF,gBAAA,aD+KE,mBAAA,WAAA,WAAA,WACA,QAAA,EC1KF,yCAAA,yCDmLE,OAAA,KC9KF,cDuLE,mBAAA,UACA,eAAA,KCnLF,4CAAA,yCD4LE,mBAAA,KAQF,6BACE,mBAAA,OACA,KAAA,QAWF,QAAA,KAEE,QAAA,MAOF,QACE,QAAA,UAUF,OACE,QAAA,aAOF,SACE,QAAA,KCnNF,SD8NE,QAAA,KEtbF,KACE,mBAAA,WAAA,WAAA,WAGF,EAAA,QAAA,SAGE,mBAAA,QAAA,WAAA,QAoBA,cAAgB,MAAA,aAQlB,KAYE,mBAAA,UAGA,4BAAA,YAGF,KACE,YAAA,cAAA,UAAA,mBAAA,WAAA,OC2K4H,iBD3K5H,MAAA,WACA,UAAA,KACA,YAAA,IACA,YAAA,IAEA,MAAA,QAEA,iBAAA,KD2LF,sBClLE,QAAA,YAYF,GAAI,GAAI,GAAI,GAAI,GAAI,GAClB,WAAA,EACA,cAAA,MAOF,EACE,WAAA,EACA,cAAA,KAIF,0BAAA,YAGE,OAAA,KAGF,QACE,cAAA,KACA,WAAA,OACA,YAAA,QAGF,GAAA,GAAA,GAGE,WAAA,EACA,cAAA,KAGF,MAAA,MAAA,MAAA,MAIE,cAAA,EAGF,GACE,YAAA,IAGF,GACE,cAAA,MACA,YAAA,EAGF,WACE,OAAA,EAAA,EAAA,KAQF,EACE,MAAA,QACA,gBAAA,KEhJE,QAAA,QFmJA,MAAA,QACA,gBAAA,UAUJ,8BACE,MAAA,QACA,gBAAA,KEhKE,oCAAA,oCFmKA,MAAA,QACA,gBAAA,KANJ,oCAUI,QAAA,EASJ,IAEE,WAAA,EAEA,cAAA,KAEA,SAAA,KAQF,OAGE,OAAA,EAAA,EAAA,KAQF,IAGE,eAAA,ODsIF,cCzHE,OAAA,QAcF,cAAA,EAAA,KAAA,OAAA,MAAA,MAAA,OAAA,QAAA,SASE,iBAAA,aAAA,aAAA,aAQF,MAEE,gBAAA,SAEA,iBAAA,YAGF,QACE,YAAA,OACA,eAAA,OACA,MAAA,QACA,WAAA,KACA,aAAA,OAGF,GAEE,WAAA,KAQF,MAEE,QAAA,aACA,cAAA,MAOF,aACE,QAAA,IAAA,OACA,QAAA,IAAA,KAAA,yBAGF,OAAA,MAAA,OAAA,SAME,YAAA,QAGF,8BAAA,2BAMI,OAAA,YAKJ,iBAAA,iBAAA,2BAAA,kBASE,mBAAA,QAGF,SAEE,OAAA,SAGF,SAME,UAAA,EAEA,QAAA,EACA,OAAA,EACA,OAAA,EAGF,OAEE,QAAA,MACA,MAAA,KACA,QAAA,EACA,cAAA,MACA,UAAA,OACA,YAAA,QAGF,mBAKE,mBAAA,KAIF,OACE,QAAA,aDsEF,SC9DE,QAAA"}
|
|
@ -0,0 +1 @@
|
|||
# Empty CSS file for your own CSS
|
|
@ -0,0 +1,150 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>Carstens Battery Analyzer</title>
|
||||
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="css/style.css" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h3>
|
||||
Battery Analyzer / Tracker - v0.3 alpha
|
||||
</h3>
|
||||
<ul class="nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="index.html">Messwerte</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="graph.html">Graph</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link disabled" href="about.html">About</a>
|
||||
</li>
|
||||
</ul>
|
||||
<table class="table table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
#
|
||||
</th>
|
||||
<th>
|
||||
Datentyp
|
||||
</th>
|
||||
<th>
|
||||
Messwert
|
||||
</th>
|
||||
<th>
|
||||
Min / Max
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
1
|
||||
</td>
|
||||
<td>
|
||||
Spannung
|
||||
</td>
|
||||
<td>
|
||||
<span id="voltage"></span> V
|
||||
</td>
|
||||
<td>
|
||||
---
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-active">
|
||||
<td>
|
||||
2
|
||||
</td>
|
||||
<td>
|
||||
Strom
|
||||
</td>
|
||||
<td>
|
||||
<span id="current"></span> A
|
||||
</td>
|
||||
<td>
|
||||
---
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
3
|
||||
</td>
|
||||
<td>
|
||||
Leistung
|
||||
</td>
|
||||
<td>
|
||||
<span id="power"></span> W
|
||||
</td>
|
||||
<td>
|
||||
---
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-active">
|
||||
<td>
|
||||
4
|
||||
</td>
|
||||
<td>
|
||||
Amperestunden
|
||||
</td>
|
||||
<td>
|
||||
<span id="Ah"></span> Ah
|
||||
</td>
|
||||
<td>
|
||||
---
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
5
|
||||
</td>
|
||||
<td>
|
||||
Wattstunden
|
||||
</td>
|
||||
<td>
|
||||
<span id="Wh"></span> Wh
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="progress">
|
||||
<div class="progress-bar w-0">
|
||||
</div>
|
||||
<button type="button" class="btn btn-success">
|
||||
<a href="/meas/run">Start</a>
|
||||
</button>
|
||||
|
||||
<button type="button" class="btn btn-danger">
|
||||
<a href="/meas/stop">Stop</a>
|
||||
</button>
|
||||
|
||||
<button type="button" class="btn btn-info">
|
||||
<a href="/meas/reset">Reset</a>
|
||||
</button>
|
||||
|
||||
<button type="button" class="btn btn-outline-primary">
|
||||
<a href="/datalog.csv">Download Log</a>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>Build by Carsten Schmiemann (2018), Akku <span id="battery"></span> V, Status: <span id="run"></span></div>
|
||||
<script src="js/jquery.min.js"></script>
|
||||
<script src="js/bootstrap.min.js"></script>
|
||||
<script src="js/scripts.js"></script>
|
||||
<script src="js/poll.js"></script>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,22 @@
|
|||
function updateData() {
|
||||
console.log("Fetching Data from ESP...");
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
console.log("Data:", this.responseText);
|
||||
var values = JSON.parse(this.responseText);
|
||||
document.getElementById("voltage").innerHTML = values.voltage;
|
||||
document.getElementById("current").innerHTML = values.current;
|
||||
document.getElementById("power").innerHTML = values.power;
|
||||
document.getElementById("Ah").innerHTML = values.Ah;
|
||||
document.getElementById("Wh").innerHTML = values.Wh;
|
||||
document.getElementById("battery").innerHTML = values.battery;
|
||||
document.getElementById("run").innerHTML = values.run;
|
||||
}
|
||||
};
|
||||
xhttp.open("GET", "/meas/values", true);
|
||||
xhttp.send();
|
||||
}
|
||||
updateData();
|
||||
window.setInterval(updateData, 3000);
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global.Popper = factory());
|
||||
}(this, (function () { 'use strict';
|
||||
|
||||
Object.assign||Object.defineProperty(Object,'assign',{enumerable:!1,configurable:!0,writable:!0,value:function value(a){if(a===void 0||null===a)throw new TypeError('Cannot convert first argument to object');var b=Object(a);for(var c=1;c<arguments.length;c++){var d=arguments[c];if(void 0!==d&&null!==d){d=Object(d);var e=Object.keys(d);for(var f=0,g=e.length;f<g;f++){var h=e[f],j=Object.getOwnPropertyDescriptor(d,h);void 0!==j&&j.enumerable&&(b[h]=d[h]);}}}return b}});
|
||||
|
||||
if(!window.requestAnimationFrame){var lastTime=0,vendors=['ms','moz','webkit','o'];for(var x=0;x<vendors.length&&!window.requestAnimationFrame;++x)window.requestAnimationFrame=window[vendors[x]+'RequestAnimationFrame'],window.cancelAnimationFrame=window[vendors[x]+'CancelAnimationFrame']||window[vendors[x]+'CancelRequestAnimationFrame'];window.requestAnimationFrame||(window.requestAnimationFrame=function(a){var b=new Date().getTime(),c=Math.max(0,16-(b-lastTime)),d=window.setTimeout(function(){a(b+c);},c);return lastTime=b+c,d}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(a){clearTimeout(a);});}
|
||||
|
||||
function findIndex(a,b,c){var d=a.filter(function(e){return e[b]===c})[0];return a.indexOf(d)}
|
||||
|
||||
function getOffsetParent(a){var b=a.offsetParent;return b&&'BODY'!==b.nodeName?b:window.document.documentElement}
|
||||
|
||||
function getStyleComputedProperty(a,b){if(1!==a.nodeType)return[];var c=window.getComputedStyle(a,null);return c[b]}
|
||||
|
||||
function getParentNode(a){return a.parentNode||a.host}
|
||||
|
||||
function getScrollParent(a){return a===window.document?window.document.body.scrollTop?window.document.body:window.document.documentElement:-1!==['scroll','auto'].indexOf(getStyleComputedProperty(a,'overflow'))||-1!==['scroll','auto'].indexOf(getStyleComputedProperty(a,'overflow-x'))||-1!==['scroll','auto'].indexOf(getStyleComputedProperty(a,'overflow-y'))?a===window.document.body?getScrollParent(getParentNode(a)):a:getParentNode(a)?getScrollParent(getParentNode(a)):a}
|
||||
|
||||
function getOffsetRect(a){var b=window.document.documentElement,c=void 0;return c=a===b?{width:Math.max(b.clientWidth,window.innerWidth||0),height:Math.max(b.clientHeight,window.innerHeight||0),left:0,top:0}:{width:a.offsetWidth,height:a.offsetHeight,left:a.offsetLeft,top:a.offsetTop},c.right=c.left+c.width,c.bottom=c.top+c.height,c}
|
||||
|
||||
function isFixed(a){return a!==window.document.body&&(!('fixed'!==getStyleComputedProperty(a,'position'))||(getParentNode(a)?isFixed(getParentNode(a)):a))}
|
||||
|
||||
function getPosition(a){var b=getOffsetParent(a),c=isFixed(b);return c?'fixed':'absolute'}
|
||||
|
||||
function getBoundingClientRect(a){var b=a.getBoundingClientRect();return{left:b.left,top:b.top,right:b.right,bottom:b.bottom,width:b.right-b.left,height:b.bottom-b.top}}
|
||||
|
||||
function getOffsetRectRelativeToCustomParent(a,b){var c=2<arguments.length&&void 0!==arguments[2]&&arguments[2],d=3<arguments.length&&void 0!==arguments[3]&&arguments[3],e=getBoundingClientRect(a),f=getBoundingClientRect(b);if(c&&!d){var j=getScrollParent(b);f.top+=j.scrollTop,f.bottom+=j.scrollTop,f.left+=j.scrollLeft,f.right+=j.scrollLeft;}var g={top:e.top-f.top,left:e.left-f.left,bottom:e.top-f.top+e.height,right:e.left-f.left+e.width,width:e.width,height:e.height},h=b.scrollTop,i=b.scrollLeft;return g.top+=h,g.bottom+=h,g.left+=i,g.right+=i,g}
|
||||
|
||||
function getBoundaries(a,b,c){var d={},e=getOffsetParent(a),f=getScrollParent(a);if('window'===c){var g=window.document.body,h=window.document.documentElement,i=Math.max(g.scrollHeight,g.offsetHeight,h.clientHeight,h.scrollHeight,h.offsetHeight),j=Math.max(g.scrollWidth,g.offsetWidth,h.clientWidth,h.scrollWidth,h.offsetWidth);d={top:0,right:j,bottom:i,left:0};}else if('viewport'===c){var _g=getOffsetRect(e),_h=getPosition(a);d='fixed'===_h?{top:0,right:window.document.documentElement.clientWidth,bottom:window.document.documentElement.clientHeight,left:0}:{top:0-_g.top,right:window.document.documentElement.clientWidth-_g.left,bottom:window.document.documentElement.clientHeight-_g.top,left:0-_g.left};}else d=f===c||'scrollParent'===c?getOffsetRectRelativeToCustomParent(f,e):getOffsetRectRelativeToCustomParent(c,e);if(e.contains(f)){var _g2=f.scrollLeft,_h2=f.scrollTop;d.right+=_g2,d.bottom+=_h2;}return d.left+=b,d.top+=b,d.right-=b,d.bottom-=b,d}
|
||||
|
||||
function getOuterSizes(a){var b=a.style.display,c=a.style.visibility;a.style.display='block',a.style.visibility='hidden';var d=window.getComputedStyle(a),e=parseFloat(d.marginTop)+parseFloat(d.marginBottom),f=parseFloat(d.marginLeft)+parseFloat(d.marginRight),g={width:a.offsetWidth+f,height:a.offsetHeight+e};return a.style.display=b,a.style.visibility=c,g}
|
||||
|
||||
function getPopperClientRect(a){return Object.assign({},a,{right:a.left+a.width,bottom:a.top+a.height})}
|
||||
|
||||
function getSupportedPropertyName(a){var b=['','ms','webkit','moz','o'];for(var c=0;c<b.length;c++){var d=b[c]?b[c]+a.charAt(0).toUpperCase()+a.slice(1):a;if('undefined'!=typeof window.document.body.style[d])return d}return null}
|
||||
|
||||
function isFunction(a){return a&&'[object Function]'==={}.toString.call(a)}
|
||||
|
||||
function isModifierRequired(a,b,c){return!!a.filter(function(d){if(d.name===c)return!0;return d.name!==b&&!1}).length}
|
||||
|
||||
function isNumeric(a){return''!==a&&!isNaN(parseFloat(a))&&isFinite(a)}
|
||||
|
||||
function isTransformed(a){return a!==window.document.body&&('none'!==getStyleComputedProperty(a,'transform')||(getParentNode(a)?isTransformed(getParentNode(a)):a))}
|
||||
|
||||
function runModifiers(a,b,c){var d=void 0===c?a:a.slice(0,findIndex(a,'name',c));return d.forEach(function(e){e.enabled&&isFunction(e.function)&&(b=e.function(b,e));}),b}
|
||||
|
||||
function setStyle(a,b){Object.keys(b).forEach(function(c){var d='';-1!==['width','height','top','right','bottom','left'].indexOf(c)&&isNumeric(b[c])&&(d='px'),a.style[c]=b[c]+d;});}
|
||||
|
||||
var Utils = {findIndex:findIndex,getBoundaries:getBoundaries,getBoundingClientRect:getBoundingClientRect,getOffsetParent:getOffsetParent,getOffsetRectRelativeToCustomParent:getOffsetRectRelativeToCustomParent,getOuterSizes:getOuterSizes,getPopperClientRect:getPopperClientRect,getPosition:getPosition,getScrollParent:getScrollParent,getStyleComputedProperty:getStyleComputedProperty,getSupportedPropertyName:getSupportedPropertyName,isFixed:isFixed,isFunction:isFunction,isModifierRequired:isModifierRequired,isNumeric:isNumeric,isTransformed:isTransformed,runModifiers:runModifiers,setStyle:setStyle};
|
||||
|
||||
var nativeHints=['native code','[object MutationObserverConstructor]'];var isNative = (function(a){return nativeHints.some(function(b){return-1<(a||'').toString().indexOf(b)})});
|
||||
|
||||
var longerTimeoutBrowsers=['Edge','Trident','Firefox']; var timeoutDuration=0;for(var a=0;a<longerTimeoutBrowsers.length;a+=1)if(0<=navigator.userAgent.indexOf(longerTimeoutBrowsers[a])){timeoutDuration=1;break}function microtaskDebounce(a){var b=!1,c=0,d=document.createElement('span'),e=new MutationObserver(function(){a(),b=!1;});return e.observe(d,{childList:!0}),function(){b||(b=!0,d.textContent=''+c,c+=1);}}function taskDebounce(a){var b=!1;return function(){b||(b=!0,setTimeout(function(){b=!1,a();},timeoutDuration));}}var supportsNativeMutationObserver=isNative(window.MutationObserver);var debounce = supportsNativeMutationObserver?microtaskDebounce:taskDebounce;
|
||||
|
||||
function getOffsets(a,b,c,d){d=d.split('-')[0];var e={};e.position=a.position;var f='fixed'===e.position,g=a.isParentTransformed,h=getOffsetParent(f&&g?c:b),i=getOffsetRectRelativeToCustomParent(c,h,f,g),j=getOuterSizes(b);return-1===['right','left'].indexOf(d)?(e.left=i.left+i.width/2-j.width/2,e.top='top'===d?i.top-j.height:i.bottom):(e.top=i.top+i.height/2-j.height/2,e.left='left'===d?i.left-j.width:i.right),e.width=j.width,e.height=j.height,{popper:e,reference:i}}
|
||||
|
||||
function setupEventListeners(a,b,c,d){if(c.updateBound=d,window.addEventListener('resize',c.updateBound,{passive:!0}),'window'!==b.boundariesElement){var e=getScrollParent(a);(e===window.document.body||e===window.document.documentElement)&&(e=window),e.addEventListener('scroll',c.updateBound,{passive:!0}),c.scrollElement=e;}}
|
||||
|
||||
function removeEventListeners(a,b){return window.removeEventListener('resize',b.updateBound),b.scrollElement&&b.scrollElement.removeEventListener('scroll',b.updateBound),b.updateBound=null,b.scrollElement=null,b}
|
||||
|
||||
function sortModifiers(c,d){if(c.order<d.order)return-1;return c.order>d.order?1:0}
|
||||
|
||||
function applyStyle(a){var b={position:a.offsets.popper.position},c=Math.round(a.offsets.popper.left),d=Math.round(a.offsets.popper.top),e=getSupportedPropertyName('transform');return a.instance.options.gpuAcceleration&&e?(b[e]='translate3d('+c+'px, '+d+'px, 0)',b.top=0,b.left=0):(b.left=c,b.top=d),Object.assign(b,a.styles),setStyle(a.instance.popper,b),a.instance.popper.setAttribute('x-placement',a.placement),a.offsets.arrow&&setStyle(a.arrowElement,a.offsets.arrow),a}function applyStyleOnLoad(a,b,c){return b.setAttribute('x-placement',c.placement),c}
|
||||
|
||||
function arrow(a,b){var c=b.element;if('string'==typeof c&&(c=a.instance.popper.querySelector(c)),!c)return a;if(!a.instance.popper.contains(c))return console.warn('WARNING: `arrowElement` must be child of its popper element!'),a;if(!isModifierRequired(a.instance.modifiers,'arrow','keepTogether'))return console.warn('WARNING: keepTogether modifier is required by arrow modifier in order to work, be sure to include it before arrow!'),a;var d={},e=a.placement.split('-')[0],f=getPopperClientRect(a.offsets.popper),g=a.offsets.reference,h=-1!==['left','right'].indexOf(e),i=h?'height':'width',j=h?'top':'left',k=h?'left':'top',l=h?'bottom':'right',m=getOuterSizes(c)[i];g[l]-m<f[j]&&(a.offsets.popper[j]-=f[j]-(g[l]-m)),g[j]+m>f[l]&&(a.offsets.popper[j]+=g[j]+m-f[l]);var n=g[j]+g[i]/2-m/2,o=n-getPopperClientRect(a.offsets.popper)[j];return o=Math.max(Math.min(f[i]-m,o),0),d[j]=o,d[k]='',a.offsets.arrow=d,a.arrowElement=c,a}
|
||||
|
||||
function getOppositePlacement(a){var b={left:'right',right:'left',bottom:'top',top:'bottom'};return a.replace(/left|right|bottom|top/g,function(c){return b[c]})}
|
||||
|
||||
function getOppositeVariation(a){if('end'===a)return'start';return'start'===a?'end':a}
|
||||
|
||||
function flip(a,b){if(a.flipped&&a.placement===a.originalPlacement)return a;var c=getBoundaries(a.instance.popper,b.padding,b.boundariesElement),d=a.placement.split('-')[0],e=getOppositePlacement(d),f=a.placement.split('-')[1]||'',g=[];return g='flip'===b.behavior?[d,e]:b.behavior,g.forEach(function(h,i){if(d!==h||g.length===i+1)return a;d=a.placement.split('-')[0],e=getOppositePlacement(d);var j=getPopperClientRect(a.offsets.popper),k='left'===d&&Math.floor(j.left)<Math.floor(c.left)||'right'===d&&Math.floor(j.right)>Math.floor(c.right)||'top'===d&&Math.floor(j.top)<Math.floor(c.top)||'bottom'===d&&Math.floor(j.bottom)>Math.floor(c.bottom),l=-1!==['top','bottom'].indexOf(d),m=!!b.flipVariations&&(l&&'start'===f&&Math.floor(j.left)<Math.floor(c.left)||l&&'end'===f&&Math.floor(j.right)>Math.floor(c.right)||!l&&'start'===f&&Math.floor(j.top)<Math.floor(c.top)||!l&&'end'===f&&Math.floor(j.bottom)>Math.floor(c.bottom));(k||m)&&(a.flipped=!0,k&&(d=g[i+1]),m&&(f=getOppositeVariation(f)),a.placement=d+(f?'-'+f:''),a.offsets.popper=getOffsets(a.instance.state,a.instance.popper,a.instance.reference,a.placement).popper,a=runModifiers(a.instance.modifiers,a,'flip'));}),a}
|
||||
|
||||
function keepTogether(a){var b=getPopperClientRect(a.offsets.popper),c=a.offsets.reference,d=Math.floor,e=a.placement.split('-')[0];return-1===['top','bottom'].indexOf(e)?(b.bottom<d(c.top)&&(a.offsets.popper.top=d(c.top)-b.height),b.top>d(c.bottom)&&(a.offsets.popper.top=d(c.bottom))):(b.right<d(c.left)&&(a.offsets.popper.left=d(c.left)-b.width),b.left>d(c.right)&&(a.offsets.popper.left=d(c.right))),a}
|
||||
|
||||
function offset(a,b){var c=a.placement,d=a.offsets.popper,e=void 0;return isNumeric(b.offset)?e=[b.offset,0]:(e=b.offset.split(' '),e=e.map(function(f,g){var h=f.match(/(\d*\.?\d*)(.*)/),i=+h[1],j=h[2],k=-1!==c.indexOf('right')||-1!==c.indexOf('left');if(1===g&&(k=!k),'%'===j||'%r'===j){var l=getPopperClientRect(a.offsets.reference),m=void 0;return m=k?l.height:l.width,m/100*i}if('%p'===j){var _l=getPopperClientRect(a.offsets.popper),_m=void 0;return _m=k?_l.height:_l.width,_m/100*i}if('vh'===j||'vw'===j){var _l2=void 0;return _l2='vh'===j?Math.max(document.documentElement.clientHeight,window.innerHeight||0):Math.max(document.documentElement.clientWidth,window.innerWidth||0),_l2/100*i}return'px'===j?+i:+f})),-1===a.placement.indexOf('left')?-1===a.placement.indexOf('right')?-1===a.placement.indexOf('top')?-1!==a.placement.indexOf('bottom')&&(d.left+=e[0],d.top+=e[1]||0):(d.left+=e[0],d.top-=e[1]||0):(d.top+=e[0],d.left+=e[1]||0):(d.top+=e[0],d.left-=e[1]||0),a}
|
||||
|
||||
function preventOverflow(c,d){var e=d.boundariesElement||getOffsetParent(c.instance.popper),f=getBoundaries(c.instance.popper,d.padding,e);d.boundaries=f;var g=d.priority,h=getPopperClientRect(c.offsets.popper),i={left:function left(){var j=h.left;return h.left<f.left&&!shouldOverflowBoundary(c,d,'left')&&(j=Math.max(h.left,f.left)),{left:j}},right:function right(){var j=h.left;return h.right>f.right&&!shouldOverflowBoundary(c,d,'right')&&(j=Math.min(h.left,f.right-h.width)),{left:j}},top:function top(){var j=h.top;return h.top<f.top&&!shouldOverflowBoundary(c,d,'top')&&(j=Math.max(h.top,f.top)),{top:j}},bottom:function bottom(){var j=h.top;return h.bottom>f.bottom&&!shouldOverflowBoundary(c,d,'bottom')&&(j=Math.min(h.top,f.bottom-h.height)),{top:j}}};return g.forEach(function(j){c.offsets.popper=Object.assign(h,i[j]());}),c}function shouldOverflowBoundary(c,d,e){return!!d.escapeWithReference&&(c.flipped&&isSameAxis(c.originalPlacement,e)||!!isSameAxis(c.originalPlacement,e)||!0)}function isSameAxis(c,d){var e=c.split('-')[0],f=d.split('-')[0];return e===f||e===getOppositePlacement(d)}
|
||||
|
||||
function shift(a){var b=a.placement,c=b.split('-')[0],d=b.split('-')[1];if(d){var e=a.offsets.reference,f=getPopperClientRect(a.offsets.popper),g={y:{start:{top:e.top},end:{top:e.top+e.height-f.height}},x:{start:{left:e.left},end:{left:e.left+e.width-f.width}}},h=-1===['bottom','top'].indexOf(c)?'y':'x';a.offsets.popper=Object.assign(f,g[h][d]);}return a}
|
||||
|
||||
function hide(a){if(!isModifierRequired(a.instance.modifiers,'hide','preventOverflow'))return console.warn('WARNING: preventOverflow modifier is required by hide modifier in order to work, be sure to include it before hide!'),a;var b=a.offsets.reference,c=a.instance.modifiers.filter(function(d){return'preventOverflow'===d.name})[0].boundaries;if(b.bottom<c.top||b.left>c.right||b.top>c.bottom||b.right<c.left){if(!0===a.hide)return a;a.hide=!0,a.instance.popper.setAttribute('x-out-of-boundaries','');}else{if(!1===a.hide)return a;a.hide=!1,a.instance.popper.removeAttribute('x-out-of-boundaries');}return a}
|
||||
|
||||
var modifiersFunctions = {applyStyle:applyStyle,arrow:arrow,flip:flip,keepTogether:keepTogether,offset:offset,preventOverflow:preventOverflow,shift:shift,hide:hide};var modifiersOnLoad={applyStyleOnLoad:applyStyleOnLoad};
|
||||
|
||||
var classCallCheck = function (instance, Constructor) {
|
||||
if (!(instance instanceof Constructor)) {
|
||||
throw new TypeError("Cannot call a class as a function");
|
||||
}
|
||||
};
|
||||
|
||||
var createClass = function () {
|
||||
function defineProperties(target, props) {
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var descriptor = props[i];
|
||||
descriptor.enumerable = descriptor.enumerable || false;
|
||||
descriptor.configurable = true;
|
||||
if ("value" in descriptor) descriptor.writable = true;
|
||||
Object.defineProperty(target, descriptor.key, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
return function (Constructor, protoProps, staticProps) {
|
||||
if (protoProps) defineProperties(Constructor.prototype, protoProps);
|
||||
if (staticProps) defineProperties(Constructor, staticProps);
|
||||
return Constructor;
|
||||
};
|
||||
}();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var get = function get(object, property, receiver) {
|
||||
if (object === null) object = Function.prototype;
|
||||
var desc = Object.getOwnPropertyDescriptor(object, property);
|
||||
|
||||
if (desc === undefined) {
|
||||
var parent = Object.getPrototypeOf(object);
|
||||
|
||||
if (parent === null) {
|
||||
return undefined;
|
||||
} else {
|
||||
return get(parent, property, receiver);
|
||||
}
|
||||
} else if ("value" in desc) {
|
||||
return desc.value;
|
||||
} else {
|
||||
var getter = desc.get;
|
||||
|
||||
if (getter === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return getter.call(receiver);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var set = function set(object, property, value, receiver) {
|
||||
var desc = Object.getOwnPropertyDescriptor(object, property);
|
||||
|
||||
if (desc === undefined) {
|
||||
var parent = Object.getPrototypeOf(object);
|
||||
|
||||
if (parent !== null) {
|
||||
set(parent, property, value, receiver);
|
||||
}
|
||||
} else if ("value" in desc && desc.writable) {
|
||||
desc.value = value;
|
||||
} else {
|
||||
var setter = desc.set;
|
||||
|
||||
if (setter !== undefined) {
|
||||
setter.call(receiver, value);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
var DEFAULTS={placement:'bottom',gpuAcceleration:!0,modifiers:{shift:{order:100,enabled:!0,function:modifiersFunctions.shift},offset:{order:200,enabled:!0,function:modifiersFunctions.offset,offset:0},preventOverflow:{order:300,enabled:!0,function:modifiersFunctions.preventOverflow,priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,function:modifiersFunctions.keepTogether},arrow:{order:500,enabled:!0,function:modifiersFunctions.arrow,element:'[x-arrow]'},flip:{order:600,enabled:!0,function:modifiersFunctions.flip,behavior:'flip',padding:5,boundariesElement:'viewport'},hide:{order:700,enabled:!0,function:modifiersFunctions.hide},applyStyle:{order:800,enabled:!0,function:modifiersFunctions.applyStyle,onLoad:modifiersOnLoad.applyStyleOnLoad}}};var Popper=function(){function Popper(a,b){var _this=this,c=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};return classCallCheck(this,Popper),this.Defaults=DEFAULTS,this.update=debounce(this.update.bind(this)),this.scheduleUpdate=function(){return requestAnimationFrame(_this.update)},this.state={isDestroyed:!1,isCreated:!1},this.reference=a.jquery?a[0]:a,this.popper=b.jquery?b[0]:b,this.options=Object.assign({},DEFAULTS,c),this.modifiers=Object.keys(DEFAULTS.modifiers).map(function(d){return Object.assign({name:d},DEFAULTS.modifiers[d])}),this.modifiers=this.modifiers.map(function(d){var e=c.modifiers&&c.modifiers[d.name]||{},f=Object.assign({},d,e);return f}),c.modifiers&&(this.options.modifiers=Object.assign({},DEFAULTS.modifiers,c.modifiers),Object.keys(c.modifiers).forEach(function(d){if(void 0===DEFAULTS.modifiers[d]){var e=c.modifiers[d];e.name=d,_this.modifiers.push(e);}})),this.modifiers=this.modifiers.sort(sortModifiers),this.modifiers.forEach(function(d){d.enabled&&isFunction(d.onLoad)&&d.onLoad(_this.reference,_this.popper,_this.options,d);}),this.state.position=getPosition(this.reference),this.state.isParentTransformed=isTransformed(this.popper.parentNode),this.update(),setupEventListeners(this.reference,this.options,this.state,this.scheduleUpdate),this}return createClass(Popper,[{key:'update',value:function update(){var a={instance:this,styles:{},flipped:!1};this.state.position=getPosition(this.reference),setStyle(this.popper,{position:this.state.position}),this.state.isDestroyed||(a.placement=this.options.placement,a.originalPlacement=this.options.placement,a.offsets=getOffsets(this.state,this.popper,this.reference,a.placement),a=runModifiers(this.modifiers,a),this.state.isCreated?isFunction(this.state.updateCallback)&&this.state.updateCallback(a):(this.state.isCreated=!0,isFunction(this.state.createCallback)&&this.state.createCallback(a)));}},{key:'onCreate',value:function onCreate(a){return this.state.createCallback=a,this}},{key:'onUpdate',value:function onUpdate(a){return this.state.updateCallback=a,this}},{key:'destroy',value:function destroy(){return this.state.isDestroyed=!0,this.popper.removeAttribute('x-placement'),this.popper.style.left='',this.popper.style.position='',this.popper.style.top='',this.popper.style[getSupportedPropertyName('transform')]='',this.state=removeEventListeners(this.reference,this.state),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}}]),Popper}();Popper.Utils=Utils;
|
||||
|
||||
return Popper;
|
||||
|
||||
})));
|
|
@ -0,0 +1 @@
|
|||
// Empty JS for your own code to be here
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
This directory is intended for the project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link to executable file.
|
||||
|
||||
The source code of each library should be placed in separate directory, like
|
||||
"lib/private_lib/[here are source files]".
|
||||
|
||||
For example, see how can be organized `Foo` and `Bar` libraries:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- readme.txt --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
Then in `src/main.c` you should use:
|
||||
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
// rest H/C/CPP code
|
||||
|
||||
PlatformIO will find your libraries automatically, configure preprocessor's
|
||||
include paths and build them.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
Binary file not shown.
After Width: | Height: | Size: 82 KiB |
|
@ -0,0 +1,6 @@
|
|||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x5000,
|
||||
otadata, data, ota, 0xe000, 0x2000,
|
||||
app0, app, ota_0, 0x10000, 0x100000,
|
||||
eeprom, data, 0x99, 0x110000,0x1000,
|
||||
spiffs, data, spiffs, 0x111000,0x2E0000,
|
|
|
@ -0,0 +1,16 @@
|
|||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:nodemcu-32s]
|
||||
platform = espressif32
|
||||
board = nodemcu-32s
|
||||
framework = arduino
|
||||
lib_deps = ArduinoINA219, Wire, EEPROM, TaskScheduler, LiquidCrystal_I2C, ESPAsyncWifiManager, ESP Async WebServer, FS, ESP8266FtpServer
|
||||
board_build.partitions = partitions.csv
|
|
@ -0,0 +1,469 @@
|
|||
/*Carstens Battery Analzyer Tracker
|
||||
*22.08.2018
|
||||
*/
|
||||
|
||||
//Libraries
|
||||
#include <Wire.h>
|
||||
#include <TaskScheduler.h>
|
||||
#include <LiquidCrystal_I2C.h>
|
||||
#include <INA219.h>
|
||||
#include <EEPROM.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <ESPAsyncWiFiManager.h>
|
||||
#include <SPIFFS.h>
|
||||
#include <ESP8266FtpServer.h>
|
||||
|
||||
//Library Config
|
||||
LiquidCrystal_I2C lcd(0x27,20,4);
|
||||
INA219 ina219;
|
||||
AsyncWebServer server(80);
|
||||
DNSServer dns;
|
||||
FtpServer ftpSrv;
|
||||
|
||||
//Konstanten
|
||||
#define R_SHUNT 0.001
|
||||
#define V_SHUNT_MAX 0.060
|
||||
#define V_BUS_MAX 26
|
||||
#define I_MAX_EXPECTED 60
|
||||
#define i2c_address 1
|
||||
#define led_lowbat_pin 27
|
||||
#define led_run_pin 26
|
||||
#define button1_pin 14
|
||||
#define button2_pin 17
|
||||
#define button3_pin 16
|
||||
#define adc_battery_pin A0
|
||||
|
||||
//Funktionsdeklarationen
|
||||
void lcd_print();
|
||||
void lcd_init();
|
||||
void lcd_header();
|
||||
void eeprom_save();
|
||||
void i2c_receive();
|
||||
void i2c_respond();
|
||||
void readCurrent();
|
||||
void read_bat();
|
||||
void read_button();
|
||||
void web_measuring_stop(AsyncWebServerRequest *request);
|
||||
void web_measuring_run(AsyncWebServerRequest *request);
|
||||
void web_measuring_reset(AsyncWebServerRequest *request);
|
||||
void web_get_values(AsyncWebServerRequest *request);
|
||||
void data_logging();
|
||||
|
||||
//Globale Variablen
|
||||
float shuntvoltage_V = 0, shuntvoltage_mV = 0, busvoltage_V = 0, busvoltage_mV = 0, current_A = 0, current_mA = 0, power_W = 0, power_mW = 0;
|
||||
float Ah = 0, mAh = 0, Wh = 0, mWh = 0;
|
||||
float battery_voltage, battery_average;
|
||||
int i_header = 0;
|
||||
bool button1, button2, button3;
|
||||
bool lcd_light = true;
|
||||
bool measuring_run = false, reset_actual = false, reset_minmax =false, battery_low = false;
|
||||
unsigned long lastread = 0;
|
||||
unsigned long tick;
|
||||
unsigned long previousMillisReadData = 0;
|
||||
unsigned long previousMillisDisplay = 0;
|
||||
unsigned long data_timestamp = 0;
|
||||
byte i2c_MasterCommand = 0;
|
||||
|
||||
//Custom LCD Characters
|
||||
byte grad[8] = {
|
||||
0b01100,
|
||||
0b10010,
|
||||
0b10010,
|
||||
0b01100,
|
||||
0b00000,
|
||||
0b00000,
|
||||
0b00000,
|
||||
0b00000
|
||||
};
|
||||
|
||||
byte sollwert[8] = {
|
||||
0b00000,
|
||||
0b00000,
|
||||
0b01111,
|
||||
0b00011,
|
||||
0b00101,
|
||||
0b01001,
|
||||
0b10000,
|
||||
0b00000
|
||||
};
|
||||
|
||||
byte batterie[8] = {
|
||||
0b01110,
|
||||
0b11011,
|
||||
0b10001,
|
||||
0b10001,
|
||||
0b10001,
|
||||
0b10001,
|
||||
0b10001,
|
||||
0b11111
|
||||
};
|
||||
|
||||
//Task Scheduler
|
||||
Task t1(500, TASK_FOREVER, &lcd_print);
|
||||
Task t2(1750, TASK_FOREVER, &lcd_header);
|
||||
Task t3(10000, TASK_FOREVER, &read_bat);
|
||||
Task t4(300, TASK_FOREVER, &read_button);
|
||||
Task t5(30000, TASK_FOREVER, &data_logging);
|
||||
//Task t3(60000, TASK_FOREVER, &eeprom_save);
|
||||
Scheduler runner;
|
||||
|
||||
|
||||
void setup() {
|
||||
//Setup GPIO
|
||||
pinMode(led_lowbat_pin, OUTPUT);
|
||||
pinMode(led_run_pin, OUTPUT);
|
||||
pinMode(button1_pin, INPUT_PULLUP);
|
||||
pinMode(button2_pin, INPUT_PULLUP);
|
||||
pinMode(button3_pin, INPUT_PULLUP);
|
||||
battery_average = analogRead(A0);
|
||||
|
||||
//Setup Debug Serial
|
||||
Serial.begin(115200);
|
||||
Serial.println("Battery Analyzer by Carsten Schmiemann (C) 2018");
|
||||
|
||||
//Init LCD and Custom Chars
|
||||
lcd.init();
|
||||
lcd.backlight();
|
||||
lcd.createChar(0, grad);
|
||||
lcd.createChar(1, sollwert);
|
||||
lcd.createChar(2, batterie);
|
||||
digitalWrite(led_lowbat_pin, 255);
|
||||
digitalWrite(led_run_pin, 255);
|
||||
delay(1000);
|
||||
|
||||
//Bootscreen
|
||||
lcd.clear();
|
||||
lcd.setCursor(4,0);
|
||||
lcd.print("Battery Power");
|
||||
lcd.setCursor(7,1);
|
||||
lcd.print("Tracker");
|
||||
lcd.setCursor(5,2);
|
||||
lcd.print("V0.3 Alpha");
|
||||
lcd.setCursor(7,3);
|
||||
lcd.print("CS,2018");
|
||||
lcd.write(1);
|
||||
|
||||
//End Test Output PWM
|
||||
digitalWrite(led_lowbat_pin, 0);
|
||||
digitalWrite(led_run_pin, 0);
|
||||
delay(5000);
|
||||
lcd.clear();
|
||||
|
||||
/*
|
||||
//Load Setpoint from EEPROM
|
||||
lcd.setCursor(0,0);
|
||||
lcd.print("Loading Setup from");
|
||||
lcd.setCursor(0,1);
|
||||
lcd.print("EEPROM...");
|
||||
EEPROM.get(0, ee_setpoint);
|
||||
setpoint = ee_setpoint;
|
||||
delay(800);
|
||||
lcd.setCursor(16,1);
|
||||
lcd.print("Done");
|
||||
delay(200);
|
||||
*/
|
||||
|
||||
//Init Wi-Fi
|
||||
lcd.setCursor(0,0);
|
||||
lcd.print("Setup Wi-Fi...");
|
||||
delay(300);
|
||||
AsyncWiFiManager wifiManager(&server,&dns);
|
||||
wifiManager.autoConnect("BatteryAnalyzer WiFi");
|
||||
lcd.setCursor(16,0);
|
||||
lcd.print("Done");
|
||||
|
||||
//Init ina219s
|
||||
lcd.setCursor(0,1);
|
||||
lcd.print("Init Sensors...");
|
||||
ina219.begin();
|
||||
ina219.configure(INA219::RANGE_16V, INA219::GAIN_2_80MV, INA219::ADC_16SAMP, INA219::ADC_16SAMP, INA219::CONT_SH_BUS);
|
||||
lastread = millis();
|
||||
ina219.calibrate(R_SHUNT, V_SHUNT_MAX, V_BUS_MAX, I_MAX_EXPECTED);
|
||||
delay(300);
|
||||
lcd.setCursor(16,1);
|
||||
lcd.print("Done");
|
||||
delay(200);
|
||||
|
||||
//Init Task Scheduler
|
||||
lcd.setCursor(0,2);
|
||||
lcd.print("Init Threads...");
|
||||
runner.init();
|
||||
runner.addTask(t1);
|
||||
runner.addTask(t2);
|
||||
runner.addTask(t3);
|
||||
runner.addTask(t4);
|
||||
runner.addTask(t5);
|
||||
t1.enable();
|
||||
t2.enable();
|
||||
t3.enable();
|
||||
t4.enable();
|
||||
t5.enable();
|
||||
//Init Filesystem and Webserver
|
||||
SPIFFS.begin();
|
||||
server.on("/meas/run", HTTP_GET, web_measuring_run);
|
||||
server.on("/meas/stop", HTTP_GET, web_measuring_stop);
|
||||
server.on("/meas/reset", HTTP_GET, web_measuring_reset);
|
||||
server.on("/meas/values", HTTP_GET, web_get_values);
|
||||
server.on("/datalog.csv", HTTP_ANY, [](AsyncWebServerRequest *request){
|
||||
request->send(SPIFFS, "/datalog.csv");
|
||||
});
|
||||
server.serveStatic("/img", SPIFFS, "/img");
|
||||
server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.html");
|
||||
server.begin();
|
||||
ftpSrv.begin("esp8266","esp8266");
|
||||
delay(500);
|
||||
lcd.setCursor(16,2);
|
||||
lcd.print("Done");
|
||||
delay(500);
|
||||
|
||||
lcd.setCursor(0,3);
|
||||
lcd.print("Done. Starting up...");
|
||||
delay(1500);
|
||||
//Load Default Screen
|
||||
lcd_init();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//Exec TaskScheduler
|
||||
runner.execute();
|
||||
ftpSrv.handleFTP();
|
||||
unsigned long currentMillis = millis();
|
||||
|
||||
if ((unsigned long)(currentMillis - previousMillisReadData) >= 250) {
|
||||
previousMillisReadData = millis();
|
||||
readCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_print() {
|
||||
if (busvoltage_V > 10) {lcd.setCursor(1,3);} else if (busvoltage_V < 0) {lcd.setCursor(1,3);} else {lcd.setCursor(1,3); lcd.print(" ");}
|
||||
lcd.print(busvoltage_V);
|
||||
if (current_A > 10) {lcd.setCursor(1,1);} else if (current_A < 0) {lcd.setCursor(1,1);} else {lcd.setCursor(1,1); lcd.print(" ");}
|
||||
lcd.print(current_A);
|
||||
if (power_W > 10) {lcd.setCursor(1,2);} else if (power_W < 0){lcd.setCursor(1,2);} else {lcd.setCursor(1,2); lcd.print(" ");}
|
||||
lcd.print(power_W);
|
||||
if (Ah > 10) {lcd.setCursor(13,1);} else if (Ah < 0){lcd.setCursor(11,1);} else {lcd.setCursor(11,1); lcd.print(" ");}
|
||||
lcd.print(Ah);
|
||||
if (Wh > 10) {lcd.setCursor(13,2);} else if (Wh < 0){lcd.setCursor(11,2);} else {lcd.setCursor(11,2); lcd.print(" ");}
|
||||
lcd.print(Wh);
|
||||
lcd.setCursor(15,3);
|
||||
if (battery_voltage > 3.4) {lcd.print(battery_voltage);} else {lcd.print("LOW ");}
|
||||
}
|
||||
|
||||
void lcd_init() {
|
||||
lcd.clear();
|
||||
lcd.setCursor(0,0);
|
||||
lcd.print("===--->Power<---===");
|
||||
lcd.setCursor(7,1);
|
||||
lcd.print("A");
|
||||
lcd.setCursor(7,2);
|
||||
lcd.print("W");
|
||||
lcd.setCursor(7,3);
|
||||
lcd.print("V");
|
||||
lcd.setCursor(17,1);
|
||||
lcd.print("Ah");
|
||||
lcd.setCursor(17,2);
|
||||
lcd.print("Wh");
|
||||
lcd.setCursor(14,3);
|
||||
lcd.write((uint8_t)2);
|
||||
lcd.setCursor(19,3);
|
||||
lcd.print("V");
|
||||
delay(300);
|
||||
}
|
||||
|
||||
void lcd_header() {
|
||||
if (measuring_run) {
|
||||
i_header++;
|
||||
if (i_header == 1) {
|
||||
lcd.setCursor(0,0);
|
||||
lcd.print("-===-->Power<--===-");
|
||||
}
|
||||
if (i_header == 2) {
|
||||
lcd.setCursor(0,0);
|
||||
lcd.print("--===->Power<-===--");
|
||||
}
|
||||
if (i_header == 3) {
|
||||
lcd.setCursor(0,0);
|
||||
lcd.print("---===>Power<===---");
|
||||
}
|
||||
if (i_header == 4) {
|
||||
lcd.setCursor(0,0);
|
||||
lcd.print("=---==>Power<==---=");
|
||||
}
|
||||
if (i_header == 5) {
|
||||
lcd.setCursor(0,0);
|
||||
lcd.print("==---=>Power<=---==");
|
||||
}
|
||||
if (i_header == 6) {
|
||||
lcd.setCursor(0,0);
|
||||
lcd.print("===--->Power<---===");
|
||||
i_header = 0;
|
||||
}
|
||||
}
|
||||
if (battery_low && digitalRead(led_lowbat_pin)) {
|
||||
digitalWrite(led_lowbat_pin,LOW);
|
||||
} else if (battery_low && digitalRead(led_lowbat_pin) == false) { digitalWrite(led_lowbat_pin,HIGH); }
|
||||
}
|
||||
|
||||
/*void eeprom_save() {
|
||||
if (ee_setpoint != setpoint) {
|
||||
EEPROM.put(0, setpoint);
|
||||
ee_setpoint = setpoint;
|
||||
lcd.setCursor(0,2);
|
||||
lcd.print(" ");
|
||||
lcd.setCursor(2,2);
|
||||
lcd.print("EEProm written.");
|
||||
}
|
||||
}*/
|
||||
|
||||
void i2c_receive(int howMany){
|
||||
i2c_MasterCommand = Wire.read();
|
||||
}
|
||||
|
||||
void i2c_respond(){
|
||||
|
||||
int returnValue = 0;
|
||||
|
||||
switch(i2c_MasterCommand){
|
||||
case 0: // No new command was received
|
||||
Wire.write("Invalid Request");
|
||||
break;
|
||||
|
||||
case 10:
|
||||
returnValue = busvoltage_V;
|
||||
break;
|
||||
|
||||
case 20:
|
||||
returnValue = current_A;
|
||||
break;
|
||||
|
||||
case 30:
|
||||
returnValue = power_W;
|
||||
|
||||
}
|
||||
|
||||
byte buffer[2];
|
||||
buffer[0] = returnValue >> 8;
|
||||
buffer[1] = returnValue & 255;
|
||||
Wire.write(buffer, 2);
|
||||
i2c_MasterCommand = 0;
|
||||
}
|
||||
|
||||
void readCurrent() {
|
||||
uint32_t count = 0;
|
||||
unsigned long newtime;
|
||||
busvoltage_V = ina219.busVoltage();
|
||||
while(!ina219.ready() && count < 500) {
|
||||
count++;
|
||||
delay(1);
|
||||
busvoltage_V = ina219.busVoltage();
|
||||
busvoltage_mV = ina219.busVoltage() * 1000;
|
||||
}
|
||||
shuntvoltage_V = ina219.shuntVoltage() * 1000;
|
||||
shuntvoltage_mV = ina219.shuntVoltage();
|
||||
current_A = ina219.shuntCurrent();
|
||||
current_mA = current_A * 1000;
|
||||
power_W = ina219.busPower();
|
||||
power_mW = power_W * 1000;
|
||||
newtime = millis();
|
||||
tick = newtime - lastread;
|
||||
if (measuring_run) {
|
||||
Ah += (current_A * tick)/3600000.0;
|
||||
mAh = Ah * 1000;
|
||||
Wh += (power_W * tick)/3600000.0;
|
||||
mWh = Wh * 1000;
|
||||
}
|
||||
if (reset_actual) {
|
||||
Ah = 0;
|
||||
Wh = 0;
|
||||
data_timestamp = 0;
|
||||
reset_actual = false;
|
||||
}
|
||||
lastread = newtime;
|
||||
}
|
||||
|
||||
void read_bat() {
|
||||
battery_average += (analogRead(adc_battery_pin) - battery_average) * 0.1;
|
||||
battery_voltage = map(battery_average,0,4096,0,490)/100.0;
|
||||
if (battery_voltage < 3.3 && battery_low == false) {
|
||||
battery_low = true;
|
||||
lcd.noBacklight();
|
||||
}
|
||||
if (battery_voltage > 3.6 && battery_low) {
|
||||
battery_low = false;
|
||||
digitalWrite(led_lowbat_pin,LOW);
|
||||
lcd.backlight();
|
||||
}
|
||||
}
|
||||
|
||||
void read_button() {
|
||||
if (digitalRead(button1_pin)) {
|
||||
button1 = false;
|
||||
}
|
||||
else {
|
||||
button1 = true;
|
||||
}
|
||||
if (digitalRead(button2_pin)) {
|
||||
button2 = false;
|
||||
}
|
||||
else {
|
||||
button2 = true;
|
||||
}
|
||||
if (digitalRead(button3_pin)) {
|
||||
button3 = false;
|
||||
}
|
||||
else {
|
||||
button3 = true;
|
||||
}
|
||||
if (button1) {
|
||||
reset_actual = true;
|
||||
}
|
||||
if (button2 && measuring_run) {
|
||||
measuring_run = false;
|
||||
} else if (button2 && measuring_run == false) {
|
||||
measuring_run = true;
|
||||
}
|
||||
if (measuring_run) {
|
||||
digitalWrite(led_run_pin,true);
|
||||
} else {
|
||||
digitalWrite(led_run_pin,false);
|
||||
}
|
||||
if (button3 && lcd_light) {
|
||||
lcd_light = false;
|
||||
lcd.noBacklight();
|
||||
} else if (button3 && lcd_light == false) {
|
||||
lcd_light = true;
|
||||
lcd.backlight();
|
||||
}
|
||||
}
|
||||
|
||||
void web_measuring_stop(AsyncWebServerRequest *request) {
|
||||
measuring_run = false;
|
||||
request->send(200);
|
||||
}
|
||||
|
||||
void web_measuring_run(AsyncWebServerRequest *request) {
|
||||
measuring_run = true;
|
||||
request->send(200);
|
||||
}
|
||||
|
||||
void web_measuring_reset(AsyncWebServerRequest *request) {
|
||||
reset_actual = true;
|
||||
request->send(200);
|
||||
}
|
||||
|
||||
void web_get_values(AsyncWebServerRequest *request) {
|
||||
request->send( 200, "application/json", "{\"voltage\":" + String(busvoltage_V) + ", \"current\":" + String(current_A) + ", \"power\":" + String(power_W) + ", \"Ah\":" + String(Ah) + ", \"Wh\":" + String(Wh) + ", \"battery\":" + String(battery_voltage) + ", \"run\":" + String(measuring_run) + "}");
|
||||
}
|
||||
|
||||
void data_logging() {
|
||||
if (measuring_run) {
|
||||
File tempLog = SPIFFS.open("/datalog.csv", "a");
|
||||
tempLog.print(data_timestamp); tempLog.print(',');
|
||||
tempLog.print(busvoltage_V); tempLog.print(',');
|
||||
tempLog.print(current_A); tempLog.print(',');
|
||||
tempLog.println(power_W);
|
||||
tempLog.close();
|
||||
data_timestamp++;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue