mirror of
https://github.com/JonasunderscoreJones/PI-server-rack.git
synced 2025-10-23 17:49:18 +02:00
Compare commits
31 commits
Author | SHA1 | Date | |
---|---|---|---|
|
c60e0db035 | ||
|
8d85068b48 | ||
|
960bebd2f1 | ||
|
3c36a24c4a | ||
|
58c0884c01 | ||
|
d1f04d1419 | ||
|
5891a1a9e3 | ||
|
40233de7f3 | ||
|
735ae1d133 | ||
|
208901d0ba | ||
|
0a78bf5c6c | ||
|
f74472f62b | ||
|
9ee12e423d | ||
|
056bc00502 | ||
|
9e9677f679 | ||
|
d17fd9877c | ||
|
d4ed59693e | ||
|
c66121cfca | ||
|
bde52a6e9b | ||
|
7179e83fa2 | ||
|
3bf2710920 | ||
|
00b78a20d5 | ||
|
ee12663b60 | ||
|
f17317be23 | ||
|
03ae07d762 | ||
|
59c3b90e0b | ||
|
6a8e2379e9 | ||
|
af15984091 | ||
|
7f33bcd42a | ||
|
8c4cb2a2e6 | ||
|
5e897a6436 |
48 changed files with 4845 additions and 303 deletions
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# temporary files
|
||||||
|
tmp/
|
||||||
|
|
||||||
|
# rust target
|
||||||
|
desktop/target/
|
||||||
|
pi-master/target/
|
||||||
|
pi-slave/target/
|
3
.idea/.gitignore
generated
vendored
Normal file
3
.idea/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
12
.idea/PI-server-rack.iml
generated
Normal file
12
.idea/PI-server-rack.iml
generated
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
7
.idea/discord.xml
generated
Normal file
7
.idea/discord.xml
generated
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DiscordProjectSettings">
|
||||||
|
<option name="show" value="PROJECT_FILES" />
|
||||||
|
<option name="description" value="" />
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/misc.xml
generated
Normal file
6
.idea/misc.xml
generated
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/PI-server-rack.iml" filepath="$PROJECT_DIR$/.idea/PI-server-rack.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
7
.vscode/arduino.json
vendored
Normal file
7
.vscode/arduino.json
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"configuration": "cpu=atmega328",
|
||||||
|
"board": "arduino:avr:nano",
|
||||||
|
"port": "/dev/ttyUSB0",
|
||||||
|
"programmer": "arduino:avrisp",
|
||||||
|
"sketch": "arduino/arduino.ino"
|
||||||
|
}
|
555
.vscode/c_cpp_properties.json
vendored
Normal file
555
.vscode/c_cpp_properties.json
vendored
Normal file
|
@ -0,0 +1,555 @@
|
||||||
|
{
|
||||||
|
"version": 4,
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Linux",
|
||||||
|
"compilerPath": "/sbin/clang",
|
||||||
|
"compilerArgs": [],
|
||||||
|
"intelliSenseMode": "linux-clang-x64",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**",
|
||||||
|
"/usr/include/openvdb/io",
|
||||||
|
"/home/jonas_jones/GitHub/PI-server-rack/arduino"
|
||||||
|
],
|
||||||
|
"forcedInclude": [],
|
||||||
|
"cStandard": "c17",
|
||||||
|
"cppStandard": "c++14",
|
||||||
|
"defines": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Arduino",
|
||||||
|
"compilerPath": "/home/jonas_jones/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
|
||||||
|
"compilerArgs": [
|
||||||
|
"-w",
|
||||||
|
"-std=gnu++11",
|
||||||
|
"-fpermissive",
|
||||||
|
"-fno-exceptions",
|
||||||
|
"-ffunction-sections",
|
||||||
|
"-fdata-sections",
|
||||||
|
"-fno-threadsafe-statics",
|
||||||
|
"-Wno-error=narrowing"
|
||||||
|
],
|
||||||
|
"intelliSenseMode": "gcc-x64",
|
||||||
|
"includePath": [
|
||||||
|
"/home/jonas_jones/.arduino15/packages/arduino/hardware/avr/1.8.5/cores/arduino",
|
||||||
|
"/home/jonas_jones/.arduino15/packages/arduino/hardware/avr/1.8.5/variants/eightanaloginputs",
|
||||||
|
"/home/jonas_jones/.arduino15/packages/arduino/hardware/avr/1.8.5/libraries/SoftwareSerial/src",
|
||||||
|
"/home/jonas_jones/Arduino/libraries/LiquidCrystal/src",
|
||||||
|
"/home/jonas_jones/Arduino/libraries/ArduinoThread",
|
||||||
|
"/home/jonas_jones/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/lib/gcc/avr/7.3.0/include",
|
||||||
|
"/home/jonas_jones/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/lib/gcc/avr/7.3.0/include-fixed",
|
||||||
|
"/home/jonas_jones/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/avr/include"
|
||||||
|
],
|
||||||
|
"forcedInclude": [
|
||||||
|
"/home/jonas_jones/.arduino15/packages/arduino/hardware/avr/1.8.5/cores/arduino/Arduino.h"
|
||||||
|
],
|
||||||
|
"cStandard": "c11",
|
||||||
|
"cppStandard": "c++11",
|
||||||
|
"defines": [
|
||||||
|
"F_CPU=16000000L",
|
||||||
|
"ARDUINO=10819",
|
||||||
|
"ARDUINO_AVR_NANO",
|
||||||
|
"ARDUINO_ARCH_AVR",
|
||||||
|
"__DBL_MIN_EXP__=(-125)",
|
||||||
|
"__HQ_FBIT__=15",
|
||||||
|
"__cpp_attributes=200809",
|
||||||
|
"__UINT_LEAST16_MAX__=0xffffU",
|
||||||
|
"__ATOMIC_ACQUIRE=2",
|
||||||
|
"__SFRACT_IBIT__=0",
|
||||||
|
"__FLT_MIN__=1.17549435e-38F",
|
||||||
|
"__GCC_IEC_559_COMPLEX=0",
|
||||||
|
"__BUILTIN_AVR_SLEEP=1",
|
||||||
|
"__BUILTIN_AVR_COUNTLSULLK=1",
|
||||||
|
"__cpp_aggregate_nsdmi=201304",
|
||||||
|
"__BUILTIN_AVR_COUNTLSULLR=1",
|
||||||
|
"__UFRACT_MAX__=0XFFFFP-16UR",
|
||||||
|
"__UINT_LEAST8_TYPE__=unsigned char",
|
||||||
|
"__DQ_FBIT__=63",
|
||||||
|
"__INTMAX_C(c)=c ## LL",
|
||||||
|
"__ULFRACT_FBIT__=32",
|
||||||
|
"__SACCUM_EPSILON__=0x1P-7HK",
|
||||||
|
"__CHAR_BIT__=8",
|
||||||
|
"__USQ_IBIT__=0",
|
||||||
|
"__UINT8_MAX__=0xff",
|
||||||
|
"__ACCUM_FBIT__=15",
|
||||||
|
"__WINT_MAX__=0x7fff",
|
||||||
|
"__FLT32_MIN_EXP__=(-125)",
|
||||||
|
"__cpp_static_assert=200410",
|
||||||
|
"__USFRACT_FBIT__=8",
|
||||||
|
"__ORDER_LITTLE_ENDIAN__=1234",
|
||||||
|
"__SIZE_MAX__=0xffffU",
|
||||||
|
"__WCHAR_MAX__=0x7fff",
|
||||||
|
"__LACCUM_IBIT__=32",
|
||||||
|
"__DBL_DENORM_MIN__=double(1.40129846e-45L)",
|
||||||
|
"__GCC_ATOMIC_CHAR_LOCK_FREE=1",
|
||||||
|
"__GCC_IEC_559=0",
|
||||||
|
"__FLT_EVAL_METHOD__=0",
|
||||||
|
"__BUILTIN_AVR_LLKBITS=1",
|
||||||
|
"__cpp_binary_literals=201304",
|
||||||
|
"__LLACCUM_MAX__=0X7FFFFFFFFFFFFFFFP-47LLK",
|
||||||
|
"__GCC_ATOMIC_CHAR32_T_LOCK_FREE=1",
|
||||||
|
"__BUILTIN_AVR_HKBITS=1",
|
||||||
|
"__BUILTIN_AVR_BITSLLK=1",
|
||||||
|
"__FRACT_FBIT__=15",
|
||||||
|
"__BUILTIN_AVR_BITSLLR=1",
|
||||||
|
"__cpp_variadic_templates=200704",
|
||||||
|
"__UINT_FAST64_MAX__=0xffffffffffffffffULL",
|
||||||
|
"__SIG_ATOMIC_TYPE__=char",
|
||||||
|
"__BUILTIN_AVR_UHKBITS=1",
|
||||||
|
"__UACCUM_FBIT__=16",
|
||||||
|
"__DBL_MIN_10_EXP__=(-37)",
|
||||||
|
"__FINITE_MATH_ONLY__=0",
|
||||||
|
"__cpp_variable_templates=201304",
|
||||||
|
"__LFRACT_IBIT__=0",
|
||||||
|
"__GNUC_PATCHLEVEL__=0",
|
||||||
|
"__FLT32_HAS_DENORM__=1",
|
||||||
|
"__LFRACT_MAX__=0X7FFFFFFFP-31LR",
|
||||||
|
"__UINT_FAST8_MAX__=0xff",
|
||||||
|
"__has_include(STR)=__has_include__(STR)",
|
||||||
|
"__DEC64_MAX_EXP__=385",
|
||||||
|
"__INT8_C(c)=c",
|
||||||
|
"__INT_LEAST8_WIDTH__=8",
|
||||||
|
"__UINT_LEAST64_MAX__=0xffffffffffffffffULL",
|
||||||
|
"__SA_FBIT__=15",
|
||||||
|
"__SHRT_MAX__=0x7fff",
|
||||||
|
"__LDBL_MAX__=3.40282347e+38L",
|
||||||
|
"__FRACT_MAX__=0X7FFFP-15R",
|
||||||
|
"__UFRACT_FBIT__=16",
|
||||||
|
"__UFRACT_MIN__=0.0UR",
|
||||||
|
"__UINT_LEAST8_MAX__=0xff",
|
||||||
|
"__GCC_ATOMIC_BOOL_LOCK_FREE=1",
|
||||||
|
"__UINTMAX_TYPE__=long long unsigned int",
|
||||||
|
"__LLFRACT_EPSILON__=0x1P-63LLR",
|
||||||
|
"__BUILTIN_AVR_DELAY_CYCLES=1",
|
||||||
|
"__DEC32_EPSILON__=1E-6DF",
|
||||||
|
"__FLT_EVAL_METHOD_TS_18661_3__=0",
|
||||||
|
"__UINT32_MAX__=0xffffffffUL",
|
||||||
|
"__GXX_EXPERIMENTAL_CXX0X__=1",
|
||||||
|
"__ULFRACT_MAX__=0XFFFFFFFFP-32ULR",
|
||||||
|
"__TA_IBIT__=16",
|
||||||
|
"__LDBL_MAX_EXP__=128",
|
||||||
|
"__WINT_MIN__=(-__WINT_MAX__ - 1)",
|
||||||
|
"__INT_LEAST16_WIDTH__=16",
|
||||||
|
"__ULLFRACT_MIN__=0.0ULLR",
|
||||||
|
"__SCHAR_MAX__=0x7f",
|
||||||
|
"__WCHAR_MIN__=(-__WCHAR_MAX__ - 1)",
|
||||||
|
"__INT64_C(c)=c ## LL",
|
||||||
|
"__DBL_DIG__=6",
|
||||||
|
"__GCC_ATOMIC_POINTER_LOCK_FREE=1",
|
||||||
|
"__AVR_HAVE_SPH__=1",
|
||||||
|
"__LLACCUM_MIN__=(-0X1P15LLK-0X1P15LLK)",
|
||||||
|
"__BUILTIN_AVR_KBITS=1",
|
||||||
|
"__BUILTIN_AVR_ABSK=1",
|
||||||
|
"__BUILTIN_AVR_ABSR=1",
|
||||||
|
"__SIZEOF_INT__=2",
|
||||||
|
"__SIZEOF_POINTER__=2",
|
||||||
|
"__GCC_ATOMIC_CHAR16_T_LOCK_FREE=1",
|
||||||
|
"__USACCUM_IBIT__=8",
|
||||||
|
"__USER_LABEL_PREFIX__",
|
||||||
|
"__STDC_HOSTED__=1",
|
||||||
|
"__LDBL_HAS_INFINITY__=1",
|
||||||
|
"__LFRACT_MIN__=(-0.5LR-0.5LR)",
|
||||||
|
"__HA_IBIT__=8",
|
||||||
|
"__FLT32_DIG__=6",
|
||||||
|
"__TQ_IBIT__=0",
|
||||||
|
"__FLT_EPSILON__=1.19209290e-7F",
|
||||||
|
"__GXX_WEAK__=1",
|
||||||
|
"__SHRT_WIDTH__=16",
|
||||||
|
"__USFRACT_IBIT__=0",
|
||||||
|
"__LDBL_MIN__=1.17549435e-38L",
|
||||||
|
"__FRACT_MIN__=(-0.5R-0.5R)",
|
||||||
|
"__AVR_SFR_OFFSET__=0x20",
|
||||||
|
"__DEC32_MAX__=9.999999E96DF",
|
||||||
|
"__cpp_threadsafe_static_init=200806",
|
||||||
|
"__DA_IBIT__=32",
|
||||||
|
"__INT32_MAX__=0x7fffffffL",
|
||||||
|
"__UQQ_FBIT__=8",
|
||||||
|
"__INT_WIDTH__=16",
|
||||||
|
"__SIZEOF_LONG__=4",
|
||||||
|
"__UACCUM_MAX__=0XFFFFFFFFP-16UK",
|
||||||
|
"__UINT16_C(c)=c ## U",
|
||||||
|
"__PTRDIFF_WIDTH__=16",
|
||||||
|
"__DECIMAL_DIG__=9",
|
||||||
|
"__LFRACT_EPSILON__=0x1P-31LR",
|
||||||
|
"__AVR_2_BYTE_PC__=1",
|
||||||
|
"__ULFRACT_MIN__=0.0ULR",
|
||||||
|
"__INTMAX_WIDTH__=64",
|
||||||
|
"__has_include_next(STR)=__has_include_next__(STR)",
|
||||||
|
"__BUILTIN_AVR_ULLRBITS=1",
|
||||||
|
"__LDBL_HAS_QUIET_NAN__=1",
|
||||||
|
"__ULACCUM_IBIT__=32",
|
||||||
|
"__UACCUM_EPSILON__=0x1P-16UK",
|
||||||
|
"__BUILTIN_AVR_SEI=1",
|
||||||
|
"__GNUC__=7",
|
||||||
|
"__ULLACCUM_MAX__=0XFFFFFFFFFFFFFFFFP-48ULLK",
|
||||||
|
"__cpp_delegating_constructors=200604",
|
||||||
|
"__HQ_IBIT__=0",
|
||||||
|
"__BUILTIN_AVR_SWAP=1",
|
||||||
|
"__FLT_HAS_DENORM__=1",
|
||||||
|
"__SIZEOF_LONG_DOUBLE__=4",
|
||||||
|
"__BIGGEST_ALIGNMENT__=1",
|
||||||
|
"__STDC_UTF_16__=1",
|
||||||
|
"__UINT24_MAX__=16777215UL",
|
||||||
|
"__BUILTIN_AVR_NOP=1",
|
||||||
|
"__GNUC_STDC_INLINE__=1",
|
||||||
|
"__DQ_IBIT__=0",
|
||||||
|
"__FLT32_HAS_INFINITY__=1",
|
||||||
|
"__DBL_MAX__=double(3.40282347e+38L)",
|
||||||
|
"__ULFRACT_IBIT__=0",
|
||||||
|
"__cpp_raw_strings=200710",
|
||||||
|
"__INT_FAST32_MAX__=0x7fffffffL",
|
||||||
|
"__DBL_HAS_INFINITY__=1",
|
||||||
|
"__INT64_MAX__=0x7fffffffffffffffLL",
|
||||||
|
"__ACCUM_IBIT__=16",
|
||||||
|
"__DEC32_MIN_EXP__=(-94)",
|
||||||
|
"__BUILTIN_AVR_UKBITS=1",
|
||||||
|
"__INTPTR_WIDTH__=16",
|
||||||
|
"__BUILTIN_AVR_FMULSU=1",
|
||||||
|
"__LACCUM_MAX__=0X7FFFFFFFFFFFFFFFP-31LK",
|
||||||
|
"__INT_FAST16_TYPE__=int",
|
||||||
|
"__LDBL_HAS_DENORM__=1",
|
||||||
|
"__BUILTIN_AVR_BITSK=1",
|
||||||
|
"__BUILTIN_AVR_BITSR=1",
|
||||||
|
"__cplusplus=201402L",
|
||||||
|
"__cpp_ref_qualifiers=200710",
|
||||||
|
"__DEC128_MAX__=9.999999999999999999999999999999999E6144DL",
|
||||||
|
"__INT_LEAST32_MAX__=0x7fffffffL",
|
||||||
|
"__USING_SJLJ_EXCEPTIONS__=1",
|
||||||
|
"__DEC32_MIN__=1E-95DF",
|
||||||
|
"__ACCUM_MAX__=0X7FFFFFFFP-15K",
|
||||||
|
"__DEPRECATED=1",
|
||||||
|
"__cpp_rvalue_references=200610",
|
||||||
|
"__DBL_MAX_EXP__=128",
|
||||||
|
"__USACCUM_EPSILON__=0x1P-8UHK",
|
||||||
|
"__WCHAR_WIDTH__=16",
|
||||||
|
"__FLT32_MAX__=3.40282347e+38F32",
|
||||||
|
"__DEC128_EPSILON__=1E-33DL",
|
||||||
|
"__SFRACT_MAX__=0X7FP-7HR",
|
||||||
|
"__FRACT_IBIT__=0",
|
||||||
|
"__PTRDIFF_MAX__=0x7fff",
|
||||||
|
"__UACCUM_MIN__=0.0UK",
|
||||||
|
"__UACCUM_IBIT__=16",
|
||||||
|
"__BUILTIN_AVR_NOPS=1",
|
||||||
|
"__BUILTIN_AVR_WDR=1",
|
||||||
|
"__FLT32_HAS_QUIET_NAN__=1",
|
||||||
|
"__GNUG__=7",
|
||||||
|
"__LONG_LONG_MAX__=0x7fffffffffffffffLL",
|
||||||
|
"__SIZEOF_SIZE_T__=2",
|
||||||
|
"__ULACCUM_MAX__=0XFFFFFFFFFFFFFFFFP-32ULK",
|
||||||
|
"__cpp_rvalue_reference=200610",
|
||||||
|
"__cpp_nsdmi=200809",
|
||||||
|
"__SIZEOF_WINT_T__=2",
|
||||||
|
"__LONG_LONG_WIDTH__=64",
|
||||||
|
"__cpp_initializer_lists=200806",
|
||||||
|
"__FLT32_MAX_EXP__=128",
|
||||||
|
"__SA_IBIT__=16",
|
||||||
|
"__ULLACCUM_MIN__=0.0ULLK",
|
||||||
|
"__BUILTIN_AVR_ROUNDUHK=1",
|
||||||
|
"__BUILTIN_AVR_ROUNDUHR=1",
|
||||||
|
"__cpp_hex_float=201603",
|
||||||
|
"__GXX_ABI_VERSION=1011",
|
||||||
|
"__INT24_MAX__=8388607L",
|
||||||
|
"__UTA_FBIT__=48",
|
||||||
|
"__FLT_MIN_EXP__=(-125)",
|
||||||
|
"__USFRACT_MAX__=0XFFP-8UHR",
|
||||||
|
"__UFRACT_IBIT__=0",
|
||||||
|
"__BUILTIN_AVR_ROUNDFX=1",
|
||||||
|
"__BUILTIN_AVR_ROUNDULK=1",
|
||||||
|
"__BUILTIN_AVR_ROUNDULR=1",
|
||||||
|
"__cpp_lambdas=200907",
|
||||||
|
"__BUILTIN_AVR_COUNTLSLLK=1",
|
||||||
|
"__BUILTIN_AVR_COUNTLSLLR=1",
|
||||||
|
"__BUILTIN_AVR_ROUNDHK=1",
|
||||||
|
"__INT_FAST64_TYPE__=long long int",
|
||||||
|
"__BUILTIN_AVR_ROUNDHR=1",
|
||||||
|
"__DBL_MIN__=double(1.17549435e-38L)",
|
||||||
|
"__BUILTIN_AVR_COUNTLSK=1",
|
||||||
|
"__BUILTIN_AVR_ROUNDLK=1",
|
||||||
|
"__BUILTIN_AVR_COUNTLSR=1",
|
||||||
|
"__BUILTIN_AVR_ROUNDLR=1",
|
||||||
|
"__LACCUM_MIN__=(-0X1P31LK-0X1P31LK)",
|
||||||
|
"__ULLACCUM_FBIT__=48",
|
||||||
|
"__BUILTIN_AVR_LKBITS=1",
|
||||||
|
"__ULLFRACT_EPSILON__=0x1P-64ULLR",
|
||||||
|
"__DEC128_MIN__=1E-6143DL",
|
||||||
|
"__REGISTER_PREFIX__",
|
||||||
|
"__UINT16_MAX__=0xffffU",
|
||||||
|
"__DBL_HAS_DENORM__=1",
|
||||||
|
"__BUILTIN_AVR_ULKBITS=1",
|
||||||
|
"__ACCUM_MIN__=(-0X1P15K-0X1P15K)",
|
||||||
|
"__AVR_ARCH__=2",
|
||||||
|
"__SQ_IBIT__=0",
|
||||||
|
"__FLT32_MIN__=1.17549435e-38F32",
|
||||||
|
"__UINT8_TYPE__=unsigned char",
|
||||||
|
"__BUILTIN_AVR_ROUNDUK=1",
|
||||||
|
"__BUILTIN_AVR_ROUNDUR=1",
|
||||||
|
"__UHA_FBIT__=8",
|
||||||
|
"__NO_INLINE__=1",
|
||||||
|
"__SFRACT_MIN__=(-0.5HR-0.5HR)",
|
||||||
|
"__UTQ_FBIT__=128",
|
||||||
|
"__FLT_MANT_DIG__=24",
|
||||||
|
"__LDBL_DECIMAL_DIG__=9",
|
||||||
|
"__VERSION__=\"7.3.0\"",
|
||||||
|
"__UINT64_C(c)=c ## ULL",
|
||||||
|
"__ULLFRACT_FBIT__=64",
|
||||||
|
"__cpp_unicode_characters=200704",
|
||||||
|
"__FRACT_EPSILON__=0x1P-15R",
|
||||||
|
"__ULACCUM_MIN__=0.0ULK",
|
||||||
|
"__UDA_FBIT__=32",
|
||||||
|
"__cpp_decltype_auto=201304",
|
||||||
|
"__LLACCUM_EPSILON__=0x1P-47LLK",
|
||||||
|
"__GCC_ATOMIC_INT_LOCK_FREE=1",
|
||||||
|
"__FLT32_MANT_DIG__=24",
|
||||||
|
"__BUILTIN_AVR_BITSUHK=1",
|
||||||
|
"__BUILTIN_AVR_BITSUHR=1",
|
||||||
|
"__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__",
|
||||||
|
"__USFRACT_MIN__=0.0UHR",
|
||||||
|
"__BUILTIN_AVR_BITSULK=1",
|
||||||
|
"__ULLACCUM_IBIT__=16",
|
||||||
|
"__BUILTIN_AVR_BITSULR=1",
|
||||||
|
"__UQQ_IBIT__=0",
|
||||||
|
"__BUILTIN_AVR_LLRBITS=1",
|
||||||
|
"__SCHAR_WIDTH__=8",
|
||||||
|
"__BUILTIN_AVR_BITSULLK=1",
|
||||||
|
"__BUILTIN_AVR_BITSULLR=1",
|
||||||
|
"__INT32_C(c)=c ## L",
|
||||||
|
"__DEC64_EPSILON__=1E-15DD",
|
||||||
|
"__ORDER_PDP_ENDIAN__=3412",
|
||||||
|
"__DEC128_MIN_EXP__=(-6142)",
|
||||||
|
"__UHQ_FBIT__=16",
|
||||||
|
"__LLACCUM_FBIT__=47",
|
||||||
|
"__FLT32_MAX_10_EXP__=38",
|
||||||
|
"__BUILTIN_AVR_ROUNDULLK=1",
|
||||||
|
"__BUILTIN_AVR_ROUNDULLR=1",
|
||||||
|
"__INT_FAST32_TYPE__=long int",
|
||||||
|
"__BUILTIN_AVR_HRBITS=1",
|
||||||
|
"__UINT_LEAST16_TYPE__=unsigned int",
|
||||||
|
"__BUILTIN_AVR_UHRBITS=1",
|
||||||
|
"__INT16_MAX__=0x7fff",
|
||||||
|
"__SIZE_TYPE__=unsigned int",
|
||||||
|
"__UINT64_MAX__=0xffffffffffffffffULL",
|
||||||
|
"__UDQ_FBIT__=64",
|
||||||
|
"__INT8_TYPE__=signed char",
|
||||||
|
"__cpp_digit_separators=201309",
|
||||||
|
"__ELF__=1",
|
||||||
|
"__ULFRACT_EPSILON__=0x1P-32ULR",
|
||||||
|
"__LLFRACT_FBIT__=63",
|
||||||
|
"__FLT_RADIX__=2",
|
||||||
|
"__INT_LEAST16_TYPE__=int",
|
||||||
|
"__BUILTIN_AVR_ABSFX=1",
|
||||||
|
"__LDBL_EPSILON__=1.19209290e-7L",
|
||||||
|
"__UINTMAX_C(c)=c ## ULL",
|
||||||
|
"__INT24_MIN__=(-__INT24_MAX__-1)",
|
||||||
|
"__SACCUM_MAX__=0X7FFFP-7HK",
|
||||||
|
"__BUILTIN_AVR_ABSHR=1",
|
||||||
|
"__SIG_ATOMIC_MAX__=0x7f",
|
||||||
|
"__GCC_ATOMIC_WCHAR_T_LOCK_FREE=1",
|
||||||
|
"__cpp_sized_deallocation=201309",
|
||||||
|
"__SIZEOF_PTRDIFF_T__=2",
|
||||||
|
"__AVR=1",
|
||||||
|
"__BUILTIN_AVR_ABSLK=1",
|
||||||
|
"__BUILTIN_AVR_ABSLR=1",
|
||||||
|
"__LACCUM_EPSILON__=0x1P-31LK",
|
||||||
|
"__DEC32_SUBNORMAL_MIN__=0.000001E-95DF",
|
||||||
|
"__INT_FAST16_MAX__=0x7fff",
|
||||||
|
"__UINT_FAST32_MAX__=0xffffffffUL",
|
||||||
|
"__UINT_LEAST64_TYPE__=long long unsigned int",
|
||||||
|
"__USACCUM_MAX__=0XFFFFP-8UHK",
|
||||||
|
"__SFRACT_EPSILON__=0x1P-7HR",
|
||||||
|
"__FLT_HAS_QUIET_NAN__=1",
|
||||||
|
"__FLT_MAX_10_EXP__=38",
|
||||||
|
"__LONG_MAX__=0x7fffffffL",
|
||||||
|
"__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL",
|
||||||
|
"__FLT_HAS_INFINITY__=1",
|
||||||
|
"__cpp_unicode_literals=200710",
|
||||||
|
"__USA_FBIT__=16",
|
||||||
|
"__UINT_FAST16_TYPE__=unsigned int",
|
||||||
|
"__DEC64_MAX__=9.999999999999999E384DD",
|
||||||
|
"__INT_FAST32_WIDTH__=32",
|
||||||
|
"__BUILTIN_AVR_RBITS=1",
|
||||||
|
"__CHAR16_TYPE__=unsigned int",
|
||||||
|
"__PRAGMA_REDEFINE_EXTNAME=1",
|
||||||
|
"__SIZE_WIDTH__=16",
|
||||||
|
"__INT_LEAST16_MAX__=0x7fff",
|
||||||
|
"__DEC64_MANT_DIG__=16",
|
||||||
|
"__UINT_LEAST32_MAX__=0xffffffffUL",
|
||||||
|
"__SACCUM_FBIT__=7",
|
||||||
|
"__FLT32_DENORM_MIN__=1.40129846e-45F32",
|
||||||
|
"__GCC_ATOMIC_LONG_LOCK_FREE=1",
|
||||||
|
"__SIG_ATOMIC_WIDTH__=8",
|
||||||
|
"__INT_LEAST64_TYPE__=long long int",
|
||||||
|
"__INT16_TYPE__=int",
|
||||||
|
"__INT_LEAST8_TYPE__=signed char",
|
||||||
|
"__SQ_FBIT__=31",
|
||||||
|
"__DEC32_MAX_EXP__=97",
|
||||||
|
"__INT_FAST8_MAX__=0x7f",
|
||||||
|
"__INTPTR_MAX__=0x7fff",
|
||||||
|
"__QQ_FBIT__=7",
|
||||||
|
"__cpp_range_based_for=200907",
|
||||||
|
"__UTA_IBIT__=16",
|
||||||
|
"__AVR_ERRATA_SKIP__=1",
|
||||||
|
"__FLT32_MIN_10_EXP__=(-37)",
|
||||||
|
"__LDBL_MANT_DIG__=24",
|
||||||
|
"__SFRACT_FBIT__=7",
|
||||||
|
"__SACCUM_MIN__=(-0X1P7HK-0X1P7HK)",
|
||||||
|
"__DBL_HAS_QUIET_NAN__=1",
|
||||||
|
"__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)",
|
||||||
|
"AVR=1",
|
||||||
|
"__BUILTIN_AVR_FMULS=1",
|
||||||
|
"__cpp_return_type_deduction=201304",
|
||||||
|
"__INTPTR_TYPE__=int",
|
||||||
|
"__UINT16_TYPE__=unsigned int",
|
||||||
|
"__WCHAR_TYPE__=int",
|
||||||
|
"__SIZEOF_FLOAT__=4",
|
||||||
|
"__AVR__=1",
|
||||||
|
"__BUILTIN_AVR_INSERT_BITS=1",
|
||||||
|
"__USQ_FBIT__=32",
|
||||||
|
"__UINTPTR_MAX__=0xffffU",
|
||||||
|
"__INT_FAST64_WIDTH__=64",
|
||||||
|
"__DEC64_MIN_EXP__=(-382)",
|
||||||
|
"__cpp_decltype=200707",
|
||||||
|
"__FLT32_DECIMAL_DIG__=9",
|
||||||
|
"__INT_FAST64_MAX__=0x7fffffffffffffffLL",
|
||||||
|
"__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1",
|
||||||
|
"__FLT_DIG__=6",
|
||||||
|
"__UINT_FAST64_TYPE__=long long unsigned int",
|
||||||
|
"__BUILTIN_AVR_BITSHK=1",
|
||||||
|
"__BUILTIN_AVR_BITSHR=1",
|
||||||
|
"__INT_MAX__=0x7fff",
|
||||||
|
"__LACCUM_FBIT__=31",
|
||||||
|
"__USACCUM_MIN__=0.0UHK",
|
||||||
|
"__UHA_IBIT__=8",
|
||||||
|
"__INT64_TYPE__=long long int",
|
||||||
|
"__BUILTIN_AVR_BITSLK=1",
|
||||||
|
"__BUILTIN_AVR_BITSLR=1",
|
||||||
|
"__FLT_MAX_EXP__=128",
|
||||||
|
"__UTQ_IBIT__=0",
|
||||||
|
"__DBL_MANT_DIG__=24",
|
||||||
|
"__cpp_inheriting_constructors=201511",
|
||||||
|
"__BUILTIN_AVR_ULLKBITS=1",
|
||||||
|
"__INT_LEAST64_MAX__=0x7fffffffffffffffLL",
|
||||||
|
"__DEC64_MIN__=1E-383DD",
|
||||||
|
"__WINT_TYPE__=int",
|
||||||
|
"__UINT_LEAST32_TYPE__=long unsigned int",
|
||||||
|
"__SIZEOF_SHORT__=2",
|
||||||
|
"__ULLFRACT_IBIT__=0",
|
||||||
|
"__LDBL_MIN_EXP__=(-125)",
|
||||||
|
"__UDA_IBIT__=32",
|
||||||
|
"__WINT_WIDTH__=16",
|
||||||
|
"__INT_LEAST8_MAX__=0x7f",
|
||||||
|
"__LFRACT_FBIT__=31",
|
||||||
|
"__LDBL_MAX_10_EXP__=38",
|
||||||
|
"__ATOMIC_RELAXED=0",
|
||||||
|
"__DBL_EPSILON__=double(1.19209290e-7L)",
|
||||||
|
"__BUILTIN_AVR_BITSUK=1",
|
||||||
|
"__BUILTIN_AVR_BITSUR=1",
|
||||||
|
"__UINT8_C(c)=c",
|
||||||
|
"__INT_LEAST32_TYPE__=long int",
|
||||||
|
"__BUILTIN_AVR_URBITS=1",
|
||||||
|
"__SIZEOF_WCHAR_T__=2",
|
||||||
|
"__LLFRACT_MAX__=0X7FFFFFFFFFFFFFFFP-63LLR",
|
||||||
|
"__TQ_FBIT__=127",
|
||||||
|
"__INT_FAST8_TYPE__=signed char",
|
||||||
|
"__ULLACCUM_EPSILON__=0x1P-48ULLK",
|
||||||
|
"__BUILTIN_AVR_ROUNDK=1",
|
||||||
|
"__BUILTIN_AVR_ROUNDR=1",
|
||||||
|
"__UHQ_IBIT__=0",
|
||||||
|
"__LLACCUM_IBIT__=16",
|
||||||
|
"__FLT32_EPSILON__=1.19209290e-7F32",
|
||||||
|
"__DBL_DECIMAL_DIG__=9",
|
||||||
|
"__STDC_UTF_32__=1",
|
||||||
|
"__INT_FAST8_WIDTH__=8",
|
||||||
|
"__DEC_EVAL_METHOD__=2",
|
||||||
|
"__TA_FBIT__=47",
|
||||||
|
"__UDQ_IBIT__=0",
|
||||||
|
"__ORDER_BIG_ENDIAN__=4321",
|
||||||
|
"__cpp_runtime_arrays=198712",
|
||||||
|
"__WITH_AVRLIBC__=1",
|
||||||
|
"__UINT64_TYPE__=long long unsigned int",
|
||||||
|
"__ACCUM_EPSILON__=0x1P-15K",
|
||||||
|
"__UINT32_C(c)=c ## UL",
|
||||||
|
"__BUILTIN_AVR_COUNTLSUHK=1",
|
||||||
|
"__INTMAX_MAX__=0x7fffffffffffffffLL",
|
||||||
|
"__cpp_alias_templates=200704",
|
||||||
|
"__BUILTIN_AVR_COUNTLSUHR=1",
|
||||||
|
"__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__",
|
||||||
|
"__FLT_DENORM_MIN__=1.40129846e-45F",
|
||||||
|
"__LLFRACT_IBIT__=0",
|
||||||
|
"__INT8_MAX__=0x7f",
|
||||||
|
"__LONG_WIDTH__=32",
|
||||||
|
"__UINT_FAST32_TYPE__=long unsigned int",
|
||||||
|
"__CHAR32_TYPE__=long unsigned int",
|
||||||
|
"__BUILTIN_AVR_COUNTLSULK=1",
|
||||||
|
"__BUILTIN_AVR_COUNTLSULR=1",
|
||||||
|
"__FLT_MAX__=3.40282347e+38F",
|
||||||
|
"__cpp_constexpr=201304",
|
||||||
|
"__USACCUM_FBIT__=8",
|
||||||
|
"__BUILTIN_AVR_COUNTLSFX=1",
|
||||||
|
"__INT32_TYPE__=long int",
|
||||||
|
"__SIZEOF_DOUBLE__=4",
|
||||||
|
"__FLT_MIN_10_EXP__=(-37)",
|
||||||
|
"__UFRACT_EPSILON__=0x1P-16UR",
|
||||||
|
"__INT_LEAST32_WIDTH__=32",
|
||||||
|
"__BUILTIN_AVR_COUNTLSHK=1",
|
||||||
|
"__BUILTIN_AVR_COUNTLSHR=1",
|
||||||
|
"__INTMAX_TYPE__=long long int",
|
||||||
|
"__BUILTIN_AVR_ABSLLK=1",
|
||||||
|
"__BUILTIN_AVR_ABSLLR=1",
|
||||||
|
"__DEC128_MAX_EXP__=6145",
|
||||||
|
"__AVR_HAVE_16BIT_SP__=1",
|
||||||
|
"__ATOMIC_CONSUME=1",
|
||||||
|
"__GNUC_MINOR__=3",
|
||||||
|
"__INT_FAST16_WIDTH__=16",
|
||||||
|
"__UINTMAX_MAX__=0xffffffffffffffffULL",
|
||||||
|
"__DEC32_MANT_DIG__=7",
|
||||||
|
"__HA_FBIT__=7",
|
||||||
|
"__BUILTIN_AVR_COUNTLSLK=1",
|
||||||
|
"__BUILTIN_AVR_COUNTLSLR=1",
|
||||||
|
"__BUILTIN_AVR_CLI=1",
|
||||||
|
"__DBL_MAX_10_EXP__=38",
|
||||||
|
"__LDBL_DENORM_MIN__=1.40129846e-45L",
|
||||||
|
"__INT16_C(c)=c",
|
||||||
|
"__cpp_generic_lambdas=201304",
|
||||||
|
"__STDC__=1",
|
||||||
|
"__PTRDIFF_TYPE__=int",
|
||||||
|
"__LLFRACT_MIN__=(-0.5LLR-0.5LLR)",
|
||||||
|
"__BUILTIN_AVR_LRBITS=1",
|
||||||
|
"__ATOMIC_SEQ_CST=5",
|
||||||
|
"__DA_FBIT__=31",
|
||||||
|
"__UINT32_TYPE__=long unsigned int",
|
||||||
|
"__BUILTIN_AVR_ROUNDLLK=1",
|
||||||
|
"__UINTPTR_TYPE__=unsigned int",
|
||||||
|
"__BUILTIN_AVR_ROUNDLLR=1",
|
||||||
|
"__USA_IBIT__=16",
|
||||||
|
"__BUILTIN_AVR_ULRBITS=1",
|
||||||
|
"__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD",
|
||||||
|
"__DEC128_MANT_DIG__=34",
|
||||||
|
"__LDBL_MIN_10_EXP__=(-37)",
|
||||||
|
"__BUILTIN_AVR_COUNTLSUK=1",
|
||||||
|
"__BUILTIN_AVR_COUNTLSUR=1",
|
||||||
|
"__SIZEOF_LONG_LONG__=8",
|
||||||
|
"__ULACCUM_EPSILON__=0x1P-32ULK",
|
||||||
|
"__cpp_user_defined_literals=200809",
|
||||||
|
"__SACCUM_IBIT__=8",
|
||||||
|
"__GCC_ATOMIC_LLONG_LOCK_FREE=1",
|
||||||
|
"__LDBL_DIG__=6",
|
||||||
|
"__FLT_DECIMAL_DIG__=9",
|
||||||
|
"__UINT_FAST16_MAX__=0xffffU",
|
||||||
|
"__GCC_ATOMIC_SHORT_LOCK_FREE=1",
|
||||||
|
"__BUILTIN_AVR_ABSHK=1",
|
||||||
|
"__BUILTIN_AVR_FLASH_SEGMENT=1",
|
||||||
|
"__INT_LEAST64_WIDTH__=64",
|
||||||
|
"__ULLFRACT_MAX__=0XFFFFFFFFFFFFFFFFP-64ULLR",
|
||||||
|
"__UINT_FAST8_TYPE__=unsigned char",
|
||||||
|
"__USFRACT_EPSILON__=0x1P-8UHR",
|
||||||
|
"__ULACCUM_FBIT__=32",
|
||||||
|
"__QQ_IBIT__=0",
|
||||||
|
"__cpp_init_captures=201304",
|
||||||
|
"__ATOMIC_ACQ_REL=4",
|
||||||
|
"__ATOMIC_RELEASE=3",
|
||||||
|
"__BUILTIN_AVR_FMUL=1",
|
||||||
|
"USBCON"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"C_Cpp.errorSquiggles": "Disabled",
|
||||||
|
"rust-analyzer.cargo.buildScripts.enable": true
|
||||||
|
}
|
202
LICENSE
Normal file
202
LICENSE
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
18
README.md
18
README.md
|
@ -1,2 +1,16 @@
|
||||||
# PI-MC-WATCHER
|
# PI-server-rack
|
||||||
A system that allows Monitoring of Raspberry PI('s) and it's running Minecraft Server(s) on PC and Mac
|
A system that allows Monitoring of Raspberry PI('s) PC and Mac as well as controlling their cooling fans.
|
||||||
|
|
||||||
|
## Why?
|
||||||
|
The idea was to create software to allow the different components inside my diy Raspberry PI server rack to communicate which each other. This is done with serial connections as they are very easy to set up and use.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
Each module has it's own `README.md` file.
|
||||||
|
|
||||||
|
- [Arduino Module](https://github.com/J-onasJones/PI-server-rack/tree/main/arduino)
|
||||||
|
- [Desktop Module](https://github.com/J-onasJones/PI-server-rack/tree/main/desktop)
|
||||||
|
- [Raspberry PI master](https://github.com/J-onasJones/PI-server-rack/tree/main/pi-master)
|
||||||
|
- [Raspberry PI slave](https://github.com/J-onasJones/PI-server-rack/tree/main/pi-slave)
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: finish README
|
||||||
|
|
37
arduino/README.md
Normal file
37
arduino/README.md
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# Arduino module
|
||||||
|
|
||||||
|
## task
|
||||||
|
The Arduino module manages the overall assets of the server rack. Those are the LCD display, the button panel and the internal and external serial communication between the computer, Raspberry PI4, Raspberry PI1.2 and itself. It also collects data about the system such as package loss, etc...
|
||||||
|
|
||||||
|
## Build from source
|
||||||
|
1. The following packages/programs need to be installed and setup:
|
||||||
|
|
||||||
|
- arduino-cli with the following libraries installed (or use libs provided in `libs/`):
|
||||||
|
- SoftwareSerial
|
||||||
|
- LiquidCristal
|
||||||
|
- git (or clone repository manually)
|
||||||
|
|
||||||
|
2. open a terminal and run the following commands:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/J-onasJones/PI-server-rack.git
|
||||||
|
cd PI-server-rack
|
||||||
|
arduino-cli --fqbn [arduino board of your choice] arduino
|
||||||
|
```
|
||||||
|
3. to upload the sketch to an arduino run the following command:
|
||||||
|
```
|
||||||
|
arduino-cli upload --fqbn [arduino board of your choice] -p [arduino port name] arduino
|
||||||
|
```
|
||||||
|
As an example on Linux for the `Arduino Nano` the following:
|
||||||
|
```
|
||||||
|
arduino-cli upload --fqbn arduino:avr:nano -p /dev/ttyUSB0 arduino
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Credits and Licensing
|
||||||
|
|
||||||
|
This project is licensed under the [Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0).
|
||||||
|
|
||||||
|
### Libraries
|
||||||
|
All provided license files for the arduino libraries at `/arduino/libs` of this repository have been added to the top of the header file of each library (the files ending in `.h`) if provided or required.
|
87
arduino/arduino.ino
Normal file
87
arduino/arduino.ino
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
// options for both vs code and arduino IDE
|
||||||
|
//include arduino installed libs
|
||||||
|
#include <SoftwareSerial.h>
|
||||||
|
#include <LiquidCrystal.h>
|
||||||
|
#include <Thread.h>
|
||||||
|
#include <ThreadController.h>
|
||||||
|
// include local libs
|
||||||
|
#include "libs/SoftwareSerial/SoftwareSerial.h"
|
||||||
|
#include "libs/LiquidCrystal/LiquidCrystal.h"
|
||||||
|
#include "libs/ArduinoThread/Thread.h"
|
||||||
|
#include "libs/ArduinoThread/ThreadController.h"
|
||||||
|
|
||||||
|
#include "src/SerialHandler.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Pinmap:
|
||||||
|
- 1 LCD 1x 6 pins
|
||||||
|
- 2 software serial ports (one for each pi) 2x 2 pins
|
||||||
|
- 2 analog shunt voltage measurement pins 2x 1 pins
|
||||||
|
- 6 buttons for manual display and fan control 6x 1 pins
|
||||||
|
|
||||||
|
Notepad:
|
||||||
|
|
||||||
|
- serial message distributor:
|
||||||
|
- check recipiant of serial message and forward it to said device
|
||||||
|
|
||||||
|
- collect data of package loss, respond times, etc...
|
||||||
|
- drive display (show stats such as cpu temps, cpu usage, system load, uptime, server status, power usage, etc.)
|
||||||
|
- accept button input from button panel
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
SoftwareSerial pi4(6, 7); // Softwareserial connection for Raspery Pi 4
|
||||||
|
SoftwareSerial pi1(8, 9); // SoftwareSerial connection for Raspery Pi 1.2B+
|
||||||
|
|
||||||
|
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // Initialize the LCD displays
|
||||||
|
|
||||||
|
ThreadController master = ThreadController(); // initialize ThreadController
|
||||||
|
|
||||||
|
Thread serialhandler = Thread(); // initialize Thread for serial handler
|
||||||
|
Thread lcdcontrol = Thread(); // initialize Thread for lcd control
|
||||||
|
Thread telemetryhandler = Thread(); // initialize Thread for telemetry handler
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
|
||||||
|
lcd.begin(16, 2); // Set the LCD size to 16x2
|
||||||
|
|
||||||
|
Serial.begin(9600); // Serial connection for desktop
|
||||||
|
pi4.begin(9600); // SoftwareSerial connection for Raspery Pi 4
|
||||||
|
pi1.begin(9600); // SoftwareSerial connection for Raspery Pi 1.2B+
|
||||||
|
|
||||||
|
serialhandler.setInterval(0);
|
||||||
|
serialhandler.onRun(serialDeliverThreadHandler);
|
||||||
|
|
||||||
|
lcdcontrol.setInterval(100);
|
||||||
|
lcdcontrol.onRun(lcdControlThreadHandler);
|
||||||
|
|
||||||
|
telemetryhandler.setInterval(1000);
|
||||||
|
telemetryhandler.onRun(telemetryThreadHandler);
|
||||||
|
|
||||||
|
master.add(&serialhandler); // add serial handler to ThreadController
|
||||||
|
master.add(&lcdcontrol); // add lcd control to ThreadController
|
||||||
|
master.add(&telemetryhandler); // add telemetry handler to ThreadController
|
||||||
|
|
||||||
|
|
||||||
|
while (!Serial || !pi4 || !pi1) {
|
||||||
|
; // wait for serial port to connect
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
master.run(); // run ThreadController
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void serialDeliverThreadHandler() {
|
||||||
|
Serial.println("serialDeliverThreadHandler");
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcdControlThreadHandler() {
|
||||||
|
Serial.println("lcdControlThreadHandler");
|
||||||
|
}
|
||||||
|
void telemetryThreadHandler() {
|
||||||
|
Serial.println("telemetryThreadHandler");
|
||||||
|
}
|
75
arduino/libs/ArduinoThread/StaticThreadController.h
Normal file
75
arduino/libs/ArduinoThread/StaticThreadController.h
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
StaticThreadController.h - Controlls a list of Threads with different timings
|
||||||
|
|
||||||
|
Basicaly, what it does is to keep track of current Threads and run when
|
||||||
|
necessary.
|
||||||
|
|
||||||
|
StaticThreadController is an extended class of Thread, because of that,
|
||||||
|
it allows you to add a StaticThreadController inside another kind of ThreadController...
|
||||||
|
|
||||||
|
It works exact as ThreadController except you can't add or remove treads dynamically.
|
||||||
|
|
||||||
|
Created by Alex Eremin, September, 2016.
|
||||||
|
Released into the public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef StaticThreadController_h
|
||||||
|
#define StaticThreadController_h
|
||||||
|
|
||||||
|
#include "Thread.h"
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
class StaticThreadController: public Thread{
|
||||||
|
protected:
|
||||||
|
//since this is a static controller, the pointers themselves can be const
|
||||||
|
//it should be distinguished from 'const Thread* thread[N]'
|
||||||
|
Thread * const thread[N];
|
||||||
|
public:
|
||||||
|
template <typename... T>
|
||||||
|
StaticThreadController(T... params) :
|
||||||
|
Thread(),
|
||||||
|
thread{params...}
|
||||||
|
{
|
||||||
|
#ifdef USE_THREAD_NAMES
|
||||||
|
// Overrides name
|
||||||
|
ThreadName = "StaticThreadController ";
|
||||||
|
ThreadName = ThreadName + ThreadID;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
// run() Method is overrided
|
||||||
|
void run() override
|
||||||
|
{
|
||||||
|
// Run this thread before
|
||||||
|
if(_onRun != nullptr && shouldRun())
|
||||||
|
_onRun();
|
||||||
|
|
||||||
|
for(int i = 0; i < N; i++){
|
||||||
|
// Is enabled? Timeout exceeded?
|
||||||
|
if(thread[i]->shouldRun()){
|
||||||
|
thread[i]->run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StaticThreadController extends Thread, so we should flag as runned thread
|
||||||
|
runned();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the quantity of Threads
|
||||||
|
static constexpr int size() { return N; };
|
||||||
|
|
||||||
|
// Return the I Thread on the array
|
||||||
|
// Returns nullptr if index is out of bounds
|
||||||
|
Thread* get(int index) {
|
||||||
|
return (index >= 0 && index < N) ? thread[index] : nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Return the I Thread on the array
|
||||||
|
// Doesn't perform any bounds checks and behaviour is
|
||||||
|
// unpredictable in case of index > N
|
||||||
|
Thread& operator[](int index) {
|
||||||
|
return *thread[index];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
52
arduino/libs/ArduinoThread/Thread.cpp
Normal file
52
arduino/libs/ArduinoThread/Thread.cpp
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#include "Thread.h"
|
||||||
|
|
||||||
|
Thread::Thread(void (*callback)(void), unsigned long _interval){
|
||||||
|
enabled = true;
|
||||||
|
onRun(callback);
|
||||||
|
_cached_next_run = 0;
|
||||||
|
last_run = millis();
|
||||||
|
|
||||||
|
ThreadID = (int)this;
|
||||||
|
#ifdef USE_THREAD_NAMES
|
||||||
|
ThreadName = "Thread ";
|
||||||
|
ThreadName = ThreadName + ThreadID;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
setInterval(_interval);
|
||||||
|
};
|
||||||
|
|
||||||
|
void Thread::runned(unsigned long time){
|
||||||
|
// Saves last_run
|
||||||
|
last_run = time;
|
||||||
|
|
||||||
|
// Cache next run
|
||||||
|
_cached_next_run = last_run + interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Thread::setInterval(unsigned long _interval){
|
||||||
|
// Save interval
|
||||||
|
interval = _interval;
|
||||||
|
|
||||||
|
// Cache the next run based on the last_run
|
||||||
|
_cached_next_run = last_run + interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Thread::shouldRun(unsigned long time){
|
||||||
|
// If the "sign" bit is set the signed difference would be negative
|
||||||
|
bool time_remaining = (time - _cached_next_run) & 0x80000000;
|
||||||
|
|
||||||
|
// Exceeded the time limit, AND is enabled? Then should run...
|
||||||
|
return !time_remaining && enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Thread::onRun(void (*callback)(void)){
|
||||||
|
_onRun = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Thread::run(){
|
||||||
|
if(_onRun != NULL)
|
||||||
|
_onRun();
|
||||||
|
|
||||||
|
// Update last_run and _cached_next_run
|
||||||
|
runned();
|
||||||
|
}
|
89
arduino/libs/ArduinoThread/Thread.h
Normal file
89
arduino/libs/ArduinoThread/Thread.h
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
Thread.h - An runnable object
|
||||||
|
|
||||||
|
Thread is responsable for holding the "action" for something,
|
||||||
|
also, it responds if it "should" or "should not" run, based on
|
||||||
|
the current time;
|
||||||
|
|
||||||
|
For instructions, go to https://github.com/ivanseidel/ArduinoThread
|
||||||
|
|
||||||
|
Created by Ivan Seidel Gomes, March, 2013.
|
||||||
|
Released into the public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Thread_h
|
||||||
|
#define Thread_h
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && ARDUINO >= 100
|
||||||
|
#include <Arduino.h>
|
||||||
|
#else
|
||||||
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Uncomment this line to enable ThreadName Strings.
|
||||||
|
|
||||||
|
It might be usefull if you are loging thread with Serial,
|
||||||
|
or displaying a list of threads...
|
||||||
|
*/
|
||||||
|
// #define USE_THREAD_NAMES 1
|
||||||
|
|
||||||
|
class Thread{
|
||||||
|
protected:
|
||||||
|
// Desired interval between runs
|
||||||
|
unsigned long interval;
|
||||||
|
|
||||||
|
// Last runned time in Ms
|
||||||
|
unsigned long last_run;
|
||||||
|
|
||||||
|
// Scheduled run in Ms (MUST BE CACHED)
|
||||||
|
unsigned long _cached_next_run;
|
||||||
|
|
||||||
|
/*
|
||||||
|
IMPORTANT! Run after all calls to run()
|
||||||
|
Updates last_run and cache next run.
|
||||||
|
NOTE: This MUST be called if extending
|
||||||
|
this class and implementing run() method
|
||||||
|
*/
|
||||||
|
void runned(unsigned long time);
|
||||||
|
|
||||||
|
// Default is to mark it runned "now"
|
||||||
|
void runned() { runned(millis()); }
|
||||||
|
|
||||||
|
// Callback for run() if not implemented
|
||||||
|
void (*_onRun)(void);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// If the current Thread is enabled or not
|
||||||
|
bool enabled;
|
||||||
|
|
||||||
|
// ID of the Thread (initialized from memory adr.)
|
||||||
|
int ThreadID;
|
||||||
|
|
||||||
|
#ifdef USE_THREAD_NAMES
|
||||||
|
// Thread Name (used for better UI).
|
||||||
|
String ThreadName;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Thread(void (*callback)(void) = NULL, unsigned long _interval = 0);
|
||||||
|
|
||||||
|
// Set the desired interval for calls, and update _cached_next_run
|
||||||
|
virtual void setInterval(unsigned long _interval);
|
||||||
|
|
||||||
|
// Return if the Thread should be runned or not
|
||||||
|
virtual bool shouldRun(unsigned long time);
|
||||||
|
|
||||||
|
// Default is to check whether it should run "now"
|
||||||
|
bool shouldRun() { return shouldRun(millis()); }
|
||||||
|
|
||||||
|
// Callback set
|
||||||
|
void onRun(void (*callback)(void));
|
||||||
|
|
||||||
|
// Runs Thread
|
||||||
|
virtual void run();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
114
arduino/libs/ArduinoThread/ThreadController.cpp
Normal file
114
arduino/libs/ArduinoThread/ThreadController.cpp
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
#include "Thread.h"
|
||||||
|
#include "ThreadController.h"
|
||||||
|
|
||||||
|
ThreadController::ThreadController(unsigned long _interval): Thread(){
|
||||||
|
cached_size = 0;
|
||||||
|
|
||||||
|
clear();
|
||||||
|
setInterval(_interval);
|
||||||
|
|
||||||
|
#ifdef USE_THREAD_NAMES
|
||||||
|
// Overrides name
|
||||||
|
ThreadName = "ThreadController ";
|
||||||
|
ThreadName = ThreadName + ThreadID;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ThreadController run() (cool stuf)
|
||||||
|
*/
|
||||||
|
void ThreadController::run(){
|
||||||
|
// Run this thread before
|
||||||
|
if(_onRun != NULL)
|
||||||
|
_onRun();
|
||||||
|
|
||||||
|
unsigned long time = millis();
|
||||||
|
int checks = 0;
|
||||||
|
for(int i = 0; i < MAX_THREADS && checks < cached_size; i++){
|
||||||
|
// Object exists? Is enabled? Timeout exceeded?
|
||||||
|
if(thread[i]){
|
||||||
|
checks++;
|
||||||
|
if(thread[i]->shouldRun(time)){
|
||||||
|
thread[i]->run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ThreadController extends Thread, so we should flag as runned thread
|
||||||
|
runned();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
List controller (boring part)
|
||||||
|
*/
|
||||||
|
bool ThreadController::add(Thread* _thread){
|
||||||
|
// Check if the Thread already exists on the array
|
||||||
|
for(int i = 0; i < MAX_THREADS; i++){
|
||||||
|
if(thread[i] != NULL && thread[i]->ThreadID == _thread->ThreadID)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find an empty slot
|
||||||
|
for(int i = 0; i < MAX_THREADS; i++){
|
||||||
|
if(!thread[i]){
|
||||||
|
// Found a empty slot, now add Thread
|
||||||
|
thread[i] = _thread;
|
||||||
|
cached_size++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Array is full
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadController::remove(int id){
|
||||||
|
// Find Threads with the id, and removes
|
||||||
|
for(int i = 0; i < MAX_THREADS; i++){
|
||||||
|
if(thread[i]->ThreadID == id){
|
||||||
|
thread[i] = NULL;
|
||||||
|
cached_size--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadController::remove(Thread* _thread){
|
||||||
|
remove(_thread->ThreadID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadController::clear(){
|
||||||
|
for(int i = 0; i < MAX_THREADS; i++){
|
||||||
|
thread[i] = NULL;
|
||||||
|
}
|
||||||
|
cached_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ThreadController::size(bool cached){
|
||||||
|
if(cached)
|
||||||
|
return cached_size;
|
||||||
|
|
||||||
|
int size = 0;
|
||||||
|
for(int i = 0; i < MAX_THREADS; i++){
|
||||||
|
if(thread[i])
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
cached_size = size;
|
||||||
|
|
||||||
|
return cached_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread* ThreadController::get(int index){
|
||||||
|
int pos = -1;
|
||||||
|
for(int i = 0; i < MAX_THREADS; i++){
|
||||||
|
if(thread[i] != NULL){
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
if(pos == index)
|
||||||
|
return thread[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
53
arduino/libs/ArduinoThread/ThreadController.h
Normal file
53
arduino/libs/ArduinoThread/ThreadController.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
ThreadController.h - Controlls a list of Threads with different timings
|
||||||
|
|
||||||
|
Basicaly, what it does is to keep track of current Threads and run when
|
||||||
|
necessary.
|
||||||
|
|
||||||
|
ThreadController is an extended class of Thread, because of that,
|
||||||
|
it allows you to add a ThreadController inside another ThreadController...
|
||||||
|
|
||||||
|
For instructions, go to https://github.com/ivanseidel/ArduinoThread
|
||||||
|
|
||||||
|
Created by Ivan Seidel Gomes, March, 2013.
|
||||||
|
Released into the public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ThreadController_h
|
||||||
|
#define ThreadController_h
|
||||||
|
|
||||||
|
#include "Thread.h"
|
||||||
|
#include "inttypes.h"
|
||||||
|
|
||||||
|
#define MAX_THREADS 15
|
||||||
|
|
||||||
|
class ThreadController: public Thread{
|
||||||
|
protected:
|
||||||
|
Thread* thread[MAX_THREADS];
|
||||||
|
int cached_size;
|
||||||
|
public:
|
||||||
|
ThreadController(unsigned long _interval = 0);
|
||||||
|
|
||||||
|
// run() Method is overrided
|
||||||
|
void run();
|
||||||
|
|
||||||
|
// Adds a thread in the first available slot (remove first)
|
||||||
|
// Returns if the Thread could be added or not
|
||||||
|
bool add(Thread* _thread);
|
||||||
|
|
||||||
|
// remove the thread (given the Thread* or ThreadID)
|
||||||
|
void remove(int _id);
|
||||||
|
void remove(Thread* _thread);
|
||||||
|
|
||||||
|
// Removes all threads
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
// Return the quantity of Threads
|
||||||
|
int size(bool cached = true);
|
||||||
|
|
||||||
|
// Return the I Thread on the array
|
||||||
|
// Returns NULL if none found
|
||||||
|
Thread* get(int index);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
326
arduino/libs/LiquidCrystal/LiquidCrystal.cpp
Normal file
326
arduino/libs/LiquidCrystal/LiquidCrystal.cpp
Normal file
|
@ -0,0 +1,326 @@
|
||||||
|
#include "LiquidCrystal.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
// When the display powers up, it is configured as follows:
|
||||||
|
//
|
||||||
|
// 1. Display clear
|
||||||
|
// 2. Function set:
|
||||||
|
// DL = 1; 8-bit interface data
|
||||||
|
// N = 0; 1-line display
|
||||||
|
// F = 0; 5x8 dot character font
|
||||||
|
// 3. Display on/off control:
|
||||||
|
// D = 0; Display off
|
||||||
|
// C = 0; Cursor off
|
||||||
|
// B = 0; Blinking off
|
||||||
|
// 4. Entry mode set:
|
||||||
|
// I/D = 1; Increment by 1
|
||||||
|
// S = 0; No shift
|
||||||
|
//
|
||||||
|
// Note, however, that resetting the Arduino doesn't reset the LCD, so we
|
||||||
|
// can't assume that its in that state when a sketch starts (and the
|
||||||
|
// LiquidCrystal constructor is called).
|
||||||
|
|
||||||
|
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
|
||||||
|
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
|
||||||
|
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
|
||||||
|
{
|
||||||
|
init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7);
|
||||||
|
}
|
||||||
|
|
||||||
|
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable,
|
||||||
|
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
|
||||||
|
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
|
||||||
|
{
|
||||||
|
init(0, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7);
|
||||||
|
}
|
||||||
|
|
||||||
|
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
|
||||||
|
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)
|
||||||
|
{
|
||||||
|
init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable,
|
||||||
|
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)
|
||||||
|
{
|
||||||
|
init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable,
|
||||||
|
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
|
||||||
|
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
|
||||||
|
{
|
||||||
|
_rs_pin = rs;
|
||||||
|
_rw_pin = rw;
|
||||||
|
_enable_pin = enable;
|
||||||
|
|
||||||
|
_data_pins[0] = d0;
|
||||||
|
_data_pins[1] = d1;
|
||||||
|
_data_pins[2] = d2;
|
||||||
|
_data_pins[3] = d3;
|
||||||
|
_data_pins[4] = d4;
|
||||||
|
_data_pins[5] = d5;
|
||||||
|
_data_pins[6] = d6;
|
||||||
|
_data_pins[7] = d7;
|
||||||
|
|
||||||
|
if (fourbitmode)
|
||||||
|
_displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
|
||||||
|
else
|
||||||
|
_displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS;
|
||||||
|
|
||||||
|
begin(16, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
|
||||||
|
if (lines > 1) {
|
||||||
|
_displayfunction |= LCD_2LINE;
|
||||||
|
}
|
||||||
|
_numlines = lines;
|
||||||
|
|
||||||
|
setRowOffsets(0x00, 0x40, 0x00 + cols, 0x40 + cols);
|
||||||
|
|
||||||
|
// for some 1 line displays you can select a 10 pixel high font
|
||||||
|
if ((dotsize != LCD_5x8DOTS) && (lines == 1)) {
|
||||||
|
_displayfunction |= LCD_5x10DOTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
pinMode(_rs_pin, OUTPUT);
|
||||||
|
// we can save 1 pin by not using RW. Indicate by passing 255 instead of pin#
|
||||||
|
if (_rw_pin != 255) {
|
||||||
|
pinMode(_rw_pin, OUTPUT);
|
||||||
|
}
|
||||||
|
pinMode(_enable_pin, OUTPUT);
|
||||||
|
|
||||||
|
// Do these once, instead of every time a character is drawn for speed reasons.
|
||||||
|
for (int i=0; i<((_displayfunction & LCD_8BITMODE) ? 8 : 4); ++i)
|
||||||
|
{
|
||||||
|
pinMode(_data_pins[i], OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
|
||||||
|
// according to datasheet, we need at least 40ms after power rises above 2.7V
|
||||||
|
// before sending commands. Arduino can turn on way before 4.5V so we'll wait 50
|
||||||
|
delayMicroseconds(50000);
|
||||||
|
// Now we pull both RS and R/W low to begin commands
|
||||||
|
digitalWrite(_rs_pin, LOW);
|
||||||
|
digitalWrite(_enable_pin, LOW);
|
||||||
|
if (_rw_pin != 255) {
|
||||||
|
digitalWrite(_rw_pin, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
//put the LCD into 4 bit or 8 bit mode
|
||||||
|
if (! (_displayfunction & LCD_8BITMODE)) {
|
||||||
|
// this is according to the hitachi HD44780 datasheet
|
||||||
|
// figure 24, pg 46
|
||||||
|
|
||||||
|
// we start in 8bit mode, try to set 4 bit mode
|
||||||
|
write4bits(0x03);
|
||||||
|
delayMicroseconds(4500); // wait min 4.1ms
|
||||||
|
|
||||||
|
// second try
|
||||||
|
write4bits(0x03);
|
||||||
|
delayMicroseconds(4500); // wait min 4.1ms
|
||||||
|
|
||||||
|
// third go!
|
||||||
|
write4bits(0x03);
|
||||||
|
delayMicroseconds(150);
|
||||||
|
|
||||||
|
// finally, set to 4-bit interface
|
||||||
|
write4bits(0x02);
|
||||||
|
} else {
|
||||||
|
// this is according to the hitachi HD44780 datasheet
|
||||||
|
// page 45 figure 23
|
||||||
|
|
||||||
|
// Send function set command sequence
|
||||||
|
command(LCD_FUNCTIONSET | _displayfunction);
|
||||||
|
delayMicroseconds(4500); // wait more than 4.1ms
|
||||||
|
|
||||||
|
// second try
|
||||||
|
command(LCD_FUNCTIONSET | _displayfunction);
|
||||||
|
delayMicroseconds(150);
|
||||||
|
|
||||||
|
// third go
|
||||||
|
command(LCD_FUNCTIONSET | _displayfunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally, set # lines, font size, etc.
|
||||||
|
command(LCD_FUNCTIONSET | _displayfunction);
|
||||||
|
|
||||||
|
// turn the display on with no cursor or blinking default
|
||||||
|
_displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
|
||||||
|
display();
|
||||||
|
|
||||||
|
// clear it off
|
||||||
|
clear();
|
||||||
|
|
||||||
|
// Initialize to default text direction (for romance languages)
|
||||||
|
_displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
|
||||||
|
// set the entry mode
|
||||||
|
command(LCD_ENTRYMODESET | _displaymode);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void LiquidCrystal::setRowOffsets(int row0, int row1, int row2, int row3)
|
||||||
|
{
|
||||||
|
_row_offsets[0] = row0;
|
||||||
|
_row_offsets[1] = row1;
|
||||||
|
_row_offsets[2] = row2;
|
||||||
|
_row_offsets[3] = row3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********** high level commands, for the user! */
|
||||||
|
void LiquidCrystal::clear()
|
||||||
|
{
|
||||||
|
command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
|
||||||
|
delayMicroseconds(2000); // this command takes a long time!
|
||||||
|
}
|
||||||
|
|
||||||
|
void LiquidCrystal::home()
|
||||||
|
{
|
||||||
|
command(LCD_RETURNHOME); // set cursor position to zero
|
||||||
|
delayMicroseconds(2000); // this command takes a long time!
|
||||||
|
}
|
||||||
|
|
||||||
|
void LiquidCrystal::setCursor(uint8_t col, uint8_t row)
|
||||||
|
{
|
||||||
|
const size_t max_lines = sizeof(_row_offsets) / sizeof(*_row_offsets);
|
||||||
|
if ( row >= max_lines ) {
|
||||||
|
row = max_lines - 1; // we count rows starting w/0
|
||||||
|
}
|
||||||
|
if ( row >= _numlines ) {
|
||||||
|
row = _numlines - 1; // we count rows starting w/0
|
||||||
|
}
|
||||||
|
|
||||||
|
command(LCD_SETDDRAMADDR | (col + _row_offsets[row]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn the display on/off (quickly)
|
||||||
|
void LiquidCrystal::noDisplay() {
|
||||||
|
_displaycontrol &= ~LCD_DISPLAYON;
|
||||||
|
command(LCD_DISPLAYCONTROL | _displaycontrol);
|
||||||
|
}
|
||||||
|
void LiquidCrystal::display() {
|
||||||
|
_displaycontrol |= LCD_DISPLAYON;
|
||||||
|
command(LCD_DISPLAYCONTROL | _displaycontrol);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turns the underline cursor on/off
|
||||||
|
void LiquidCrystal::noCursor() {
|
||||||
|
_displaycontrol &= ~LCD_CURSORON;
|
||||||
|
command(LCD_DISPLAYCONTROL | _displaycontrol);
|
||||||
|
}
|
||||||
|
void LiquidCrystal::cursor() {
|
||||||
|
_displaycontrol |= LCD_CURSORON;
|
||||||
|
command(LCD_DISPLAYCONTROL | _displaycontrol);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn on and off the blinking cursor
|
||||||
|
void LiquidCrystal::noBlink() {
|
||||||
|
_displaycontrol &= ~LCD_BLINKON;
|
||||||
|
command(LCD_DISPLAYCONTROL | _displaycontrol);
|
||||||
|
}
|
||||||
|
void LiquidCrystal::blink() {
|
||||||
|
_displaycontrol |= LCD_BLINKON;
|
||||||
|
command(LCD_DISPLAYCONTROL | _displaycontrol);
|
||||||
|
}
|
||||||
|
|
||||||
|
// These commands scroll the display without changing the RAM
|
||||||
|
void LiquidCrystal::scrollDisplayLeft(void) {
|
||||||
|
command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
|
||||||
|
}
|
||||||
|
void LiquidCrystal::scrollDisplayRight(void) {
|
||||||
|
command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is for text that flows Left to Right
|
||||||
|
void LiquidCrystal::leftToRight(void) {
|
||||||
|
_displaymode |= LCD_ENTRYLEFT;
|
||||||
|
command(LCD_ENTRYMODESET | _displaymode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is for text that flows Right to Left
|
||||||
|
void LiquidCrystal::rightToLeft(void) {
|
||||||
|
_displaymode &= ~LCD_ENTRYLEFT;
|
||||||
|
command(LCD_ENTRYMODESET | _displaymode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will 'right justify' text from the cursor
|
||||||
|
void LiquidCrystal::autoscroll(void) {
|
||||||
|
_displaymode |= LCD_ENTRYSHIFTINCREMENT;
|
||||||
|
command(LCD_ENTRYMODESET | _displaymode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will 'left justify' text from the cursor
|
||||||
|
void LiquidCrystal::noAutoscroll(void) {
|
||||||
|
_displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
|
||||||
|
command(LCD_ENTRYMODESET | _displaymode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allows us to fill the first 8 CGRAM locations
|
||||||
|
// with custom characters
|
||||||
|
void LiquidCrystal::createChar(uint8_t location, uint8_t charmap[]) {
|
||||||
|
location &= 0x7; // we only have 8 locations 0-7
|
||||||
|
command(LCD_SETCGRAMADDR | (location << 3));
|
||||||
|
for (int i=0; i<8; i++) {
|
||||||
|
write(charmap[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********** mid level commands, for sending data/cmds */
|
||||||
|
|
||||||
|
inline void LiquidCrystal::command(uint8_t value) {
|
||||||
|
send(value, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t LiquidCrystal::write(uint8_t value) {
|
||||||
|
send(value, HIGH);
|
||||||
|
return 1; // assume sucess
|
||||||
|
}
|
||||||
|
|
||||||
|
/************ low level data pushing commands **********/
|
||||||
|
|
||||||
|
// write either command or data, with automatic 4/8-bit selection
|
||||||
|
void LiquidCrystal::send(uint8_t value, uint8_t mode) {
|
||||||
|
digitalWrite(_rs_pin, mode);
|
||||||
|
|
||||||
|
// if there is a RW pin indicated, set it low to Write
|
||||||
|
if (_rw_pin != 255) {
|
||||||
|
digitalWrite(_rw_pin, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_displayfunction & LCD_8BITMODE) {
|
||||||
|
write8bits(value);
|
||||||
|
} else {
|
||||||
|
write4bits(value>>4);
|
||||||
|
write4bits(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LiquidCrystal::pulseEnable(void) {
|
||||||
|
digitalWrite(_enable_pin, LOW);
|
||||||
|
delayMicroseconds(1);
|
||||||
|
digitalWrite(_enable_pin, HIGH);
|
||||||
|
delayMicroseconds(1); // enable pulse must be >450ns
|
||||||
|
digitalWrite(_enable_pin, LOW);
|
||||||
|
delayMicroseconds(100); // commands need > 37us to settle
|
||||||
|
}
|
||||||
|
|
||||||
|
void LiquidCrystal::write4bits(uint8_t value) {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
digitalWrite(_data_pins[i], (value >> i) & 0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
pulseEnable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LiquidCrystal::write8bits(uint8_t value) {
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
digitalWrite(_data_pins[i], (value >> i) & 0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
pulseEnable();
|
||||||
|
}
|
108
arduino/libs/LiquidCrystal/LiquidCrystal.h
Normal file
108
arduino/libs/LiquidCrystal/LiquidCrystal.h
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
#ifndef LiquidCrystal_h
|
||||||
|
#define LiquidCrystal_h
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include "Print.h"
|
||||||
|
|
||||||
|
// commands
|
||||||
|
#define LCD_CLEARDISPLAY 0x01
|
||||||
|
#define LCD_RETURNHOME 0x02
|
||||||
|
#define LCD_ENTRYMODESET 0x04
|
||||||
|
#define LCD_DISPLAYCONTROL 0x08
|
||||||
|
#define LCD_CURSORSHIFT 0x10
|
||||||
|
#define LCD_FUNCTIONSET 0x20
|
||||||
|
#define LCD_SETCGRAMADDR 0x40
|
||||||
|
#define LCD_SETDDRAMADDR 0x80
|
||||||
|
|
||||||
|
// flags for display entry mode
|
||||||
|
#define LCD_ENTRYRIGHT 0x00
|
||||||
|
#define LCD_ENTRYLEFT 0x02
|
||||||
|
#define LCD_ENTRYSHIFTINCREMENT 0x01
|
||||||
|
#define LCD_ENTRYSHIFTDECREMENT 0x00
|
||||||
|
|
||||||
|
// flags for display on/off control
|
||||||
|
#define LCD_DISPLAYON 0x04
|
||||||
|
#define LCD_DISPLAYOFF 0x00
|
||||||
|
#define LCD_CURSORON 0x02
|
||||||
|
#define LCD_CURSOROFF 0x00
|
||||||
|
#define LCD_BLINKON 0x01
|
||||||
|
#define LCD_BLINKOFF 0x00
|
||||||
|
|
||||||
|
// flags for display/cursor shift
|
||||||
|
#define LCD_DISPLAYMOVE 0x08
|
||||||
|
#define LCD_CURSORMOVE 0x00
|
||||||
|
#define LCD_MOVERIGHT 0x04
|
||||||
|
#define LCD_MOVELEFT 0x00
|
||||||
|
|
||||||
|
// flags for function set
|
||||||
|
#define LCD_8BITMODE 0x10
|
||||||
|
#define LCD_4BITMODE 0x00
|
||||||
|
#define LCD_2LINE 0x08
|
||||||
|
#define LCD_1LINE 0x00
|
||||||
|
#define LCD_5x10DOTS 0x04
|
||||||
|
#define LCD_5x8DOTS 0x00
|
||||||
|
|
||||||
|
class LiquidCrystal : public Print {
|
||||||
|
public:
|
||||||
|
LiquidCrystal(uint8_t rs, uint8_t enable,
|
||||||
|
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
|
||||||
|
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
|
||||||
|
LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
|
||||||
|
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
|
||||||
|
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
|
||||||
|
LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
|
||||||
|
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
|
||||||
|
LiquidCrystal(uint8_t rs, uint8_t enable,
|
||||||
|
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
|
||||||
|
|
||||||
|
void init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable,
|
||||||
|
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
|
||||||
|
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
|
||||||
|
|
||||||
|
void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
void home();
|
||||||
|
|
||||||
|
void noDisplay();
|
||||||
|
void display();
|
||||||
|
void noBlink();
|
||||||
|
void blink();
|
||||||
|
void noCursor();
|
||||||
|
void cursor();
|
||||||
|
void scrollDisplayLeft();
|
||||||
|
void scrollDisplayRight();
|
||||||
|
void leftToRight();
|
||||||
|
void rightToLeft();
|
||||||
|
void autoscroll();
|
||||||
|
void noAutoscroll();
|
||||||
|
|
||||||
|
void setRowOffsets(int row1, int row2, int row3, int row4);
|
||||||
|
void createChar(uint8_t, uint8_t[]);
|
||||||
|
void setCursor(uint8_t, uint8_t);
|
||||||
|
virtual size_t write(uint8_t);
|
||||||
|
void command(uint8_t);
|
||||||
|
|
||||||
|
using Print::write;
|
||||||
|
private:
|
||||||
|
void send(uint8_t, uint8_t);
|
||||||
|
void write4bits(uint8_t);
|
||||||
|
void write8bits(uint8_t);
|
||||||
|
void pulseEnable();
|
||||||
|
|
||||||
|
uint8_t _rs_pin; // LOW: command. HIGH: character.
|
||||||
|
uint8_t _rw_pin; // LOW: write to LCD. HIGH: read from LCD.
|
||||||
|
uint8_t _enable_pin; // activated by a HIGH pulse.
|
||||||
|
uint8_t _data_pins[8];
|
||||||
|
|
||||||
|
uint8_t _displayfunction;
|
||||||
|
uint8_t _displaycontrol;
|
||||||
|
uint8_t _displaymode;
|
||||||
|
|
||||||
|
uint8_t _initialized;
|
||||||
|
|
||||||
|
uint8_t _numlines;
|
||||||
|
uint8_t _row_offsets[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
486
arduino/libs/SoftwareSerial/SoftwareSerial.cpp
Normal file
486
arduino/libs/SoftwareSerial/SoftwareSerial.cpp
Normal file
|
@ -0,0 +1,486 @@
|
||||||
|
/*
|
||||||
|
SoftwareSerial.cpp (formerly NewSoftSerial.cpp) -
|
||||||
|
Multi-instance software serial library for Arduino/Wiring
|
||||||
|
-- Interrupt-driven receive and other improvements by ladyada
|
||||||
|
(http://ladyada.net)
|
||||||
|
-- Tuning, circular buffer, derivation from class Print/Stream,
|
||||||
|
multi-instance support, porting to 8MHz processors,
|
||||||
|
various optimizations, PROGMEM delay tables, inverse logic and
|
||||||
|
direct port writing by Mikal Hart (http://www.arduiniana.org)
|
||||||
|
-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
|
||||||
|
-- 20MHz processor support by Garrett Mace (http://www.macetech.com)
|
||||||
|
-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
The latest version of this library can always be found at
|
||||||
|
http://arduiniana.org.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// When set, _DEBUG co-opts pins 11 and 13 for debugging with an
|
||||||
|
// oscilloscope or logic analyzer. Beware: it also slightly modifies
|
||||||
|
// the bit times, so don't rely on it too much at high baud rates
|
||||||
|
#define _DEBUG 0
|
||||||
|
#define _DEBUG_PIN1 11
|
||||||
|
#define _DEBUG_PIN2 13
|
||||||
|
//
|
||||||
|
// Includes
|
||||||
|
//
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <SoftwareSerial.h>
|
||||||
|
#include <util/delay_basic.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Statics
|
||||||
|
//
|
||||||
|
SoftwareSerial *SoftwareSerial::active_object = 0;
|
||||||
|
uint8_t SoftwareSerial::_receive_buffer[_SS_MAX_RX_BUFF];
|
||||||
|
volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0;
|
||||||
|
volatile uint8_t SoftwareSerial::_receive_buffer_head = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Debugging
|
||||||
|
//
|
||||||
|
// This function generates a brief pulse
|
||||||
|
// for debugging or measuring on an oscilloscope.
|
||||||
|
#if _DEBUG
|
||||||
|
inline void DebugPulse(uint8_t pin, uint8_t count)
|
||||||
|
{
|
||||||
|
volatile uint8_t *pport = portOutputRegister(digitalPinToPort(pin));
|
||||||
|
|
||||||
|
uint8_t val = *pport;
|
||||||
|
while (count--)
|
||||||
|
{
|
||||||
|
*pport = val | digitalPinToBitMask(pin);
|
||||||
|
*pport = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
inline void DebugPulse(uint8_t, uint8_t) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Private methods
|
||||||
|
//
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
inline void SoftwareSerial::tunedDelay(uint16_t delay) {
|
||||||
|
_delay_loop_2(delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function sets the current object as the "listening"
|
||||||
|
// one and returns true if it replaces another
|
||||||
|
bool SoftwareSerial::listen()
|
||||||
|
{
|
||||||
|
if (!_rx_delay_stopbit)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (active_object != this)
|
||||||
|
{
|
||||||
|
if (active_object)
|
||||||
|
active_object->stopListening();
|
||||||
|
|
||||||
|
_buffer_overflow = false;
|
||||||
|
_receive_buffer_head = _receive_buffer_tail = 0;
|
||||||
|
active_object = this;
|
||||||
|
|
||||||
|
setRxIntMsk(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop listening. Returns true if we were actually listening.
|
||||||
|
bool SoftwareSerial::stopListening()
|
||||||
|
{
|
||||||
|
if (active_object == this)
|
||||||
|
{
|
||||||
|
setRxIntMsk(false);
|
||||||
|
active_object = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// The receive routine called by the interrupt handler
|
||||||
|
//
|
||||||
|
void SoftwareSerial::recv()
|
||||||
|
{
|
||||||
|
|
||||||
|
#if GCC_VERSION < 40302
|
||||||
|
// Work-around for avr-gcc 4.3.0 OSX version bug
|
||||||
|
// Preserve the registers that the compiler misses
|
||||||
|
// (courtesy of Arduino forum user *etracer*)
|
||||||
|
asm volatile(
|
||||||
|
"push r18 \n\t"
|
||||||
|
"push r19 \n\t"
|
||||||
|
"push r20 \n\t"
|
||||||
|
"push r21 \n\t"
|
||||||
|
"push r22 \n\t"
|
||||||
|
"push r23 \n\t"
|
||||||
|
"push r26 \n\t"
|
||||||
|
"push r27 \n\t"
|
||||||
|
::);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t d = 0;
|
||||||
|
|
||||||
|
// If RX line is high, then we don't see any start bit
|
||||||
|
// so interrupt is probably not for us
|
||||||
|
if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
|
||||||
|
{
|
||||||
|
// Disable further interrupts during reception, this prevents
|
||||||
|
// triggering another interrupt directly after we return, which can
|
||||||
|
// cause problems at higher baudrates.
|
||||||
|
setRxIntMsk(false);
|
||||||
|
|
||||||
|
// Wait approximately 1/2 of a bit width to "center" the sample
|
||||||
|
tunedDelay(_rx_delay_centering);
|
||||||
|
DebugPulse(_DEBUG_PIN2, 1);
|
||||||
|
|
||||||
|
// Read each of the 8 bits
|
||||||
|
for (uint8_t i=8; i > 0; --i)
|
||||||
|
{
|
||||||
|
tunedDelay(_rx_delay_intrabit);
|
||||||
|
d >>= 1;
|
||||||
|
DebugPulse(_DEBUG_PIN2, 1);
|
||||||
|
if (rx_pin_read())
|
||||||
|
d |= 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_inverse_logic)
|
||||||
|
d = ~d;
|
||||||
|
|
||||||
|
// if buffer full, set the overflow flag and return
|
||||||
|
uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
|
||||||
|
if (next != _receive_buffer_head)
|
||||||
|
{
|
||||||
|
// save new data in buffer: tail points to where byte goes
|
||||||
|
_receive_buffer[_receive_buffer_tail] = d; // save new byte
|
||||||
|
_receive_buffer_tail = next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DebugPulse(_DEBUG_PIN1, 1);
|
||||||
|
_buffer_overflow = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip the stop bit
|
||||||
|
tunedDelay(_rx_delay_stopbit);
|
||||||
|
DebugPulse(_DEBUG_PIN1, 1);
|
||||||
|
|
||||||
|
// Re-enable interrupts when we're sure to be inside the stop bit
|
||||||
|
setRxIntMsk(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if GCC_VERSION < 40302
|
||||||
|
// Work-around for avr-gcc 4.3.0 OSX version bug
|
||||||
|
// Restore the registers that the compiler misses
|
||||||
|
asm volatile(
|
||||||
|
"pop r27 \n\t"
|
||||||
|
"pop r26 \n\t"
|
||||||
|
"pop r23 \n\t"
|
||||||
|
"pop r22 \n\t"
|
||||||
|
"pop r21 \n\t"
|
||||||
|
"pop r20 \n\t"
|
||||||
|
"pop r19 \n\t"
|
||||||
|
"pop r18 \n\t"
|
||||||
|
::);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t SoftwareSerial::rx_pin_read()
|
||||||
|
{
|
||||||
|
return *_receivePortRegister & _receiveBitMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Interrupt handling
|
||||||
|
//
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
inline void SoftwareSerial::handle_interrupt()
|
||||||
|
{
|
||||||
|
if (active_object)
|
||||||
|
{
|
||||||
|
active_object->recv();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(PCINT0_vect)
|
||||||
|
ISR(PCINT0_vect)
|
||||||
|
{
|
||||||
|
SoftwareSerial::handle_interrupt();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PCINT1_vect)
|
||||||
|
ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PCINT2_vect)
|
||||||
|
ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PCINT3_vect)
|
||||||
|
ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructor
|
||||||
|
//
|
||||||
|
SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */) :
|
||||||
|
_rx_delay_centering(0),
|
||||||
|
_rx_delay_intrabit(0),
|
||||||
|
_rx_delay_stopbit(0),
|
||||||
|
_tx_delay(0),
|
||||||
|
_buffer_overflow(false),
|
||||||
|
_inverse_logic(inverse_logic)
|
||||||
|
{
|
||||||
|
setTX(transmitPin);
|
||||||
|
setRX(receivePin);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Destructor
|
||||||
|
//
|
||||||
|
SoftwareSerial::~SoftwareSerial()
|
||||||
|
{
|
||||||
|
end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareSerial::setTX(uint8_t tx)
|
||||||
|
{
|
||||||
|
// First write, then set output. If we do this the other way around,
|
||||||
|
// the pin would be output low for a short while before switching to
|
||||||
|
// output high. Now, it is input with pullup for a short while, which
|
||||||
|
// is fine. With inverse logic, either order is fine.
|
||||||
|
digitalWrite(tx, _inverse_logic ? LOW : HIGH);
|
||||||
|
pinMode(tx, OUTPUT);
|
||||||
|
_transmitBitMask = digitalPinToBitMask(tx);
|
||||||
|
uint8_t port = digitalPinToPort(tx);
|
||||||
|
_transmitPortRegister = portOutputRegister(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareSerial::setRX(uint8_t rx)
|
||||||
|
{
|
||||||
|
pinMode(rx, INPUT);
|
||||||
|
if (!_inverse_logic)
|
||||||
|
digitalWrite(rx, HIGH); // pullup for normal logic!
|
||||||
|
_receivePin = rx;
|
||||||
|
_receiveBitMask = digitalPinToBitMask(rx);
|
||||||
|
uint8_t port = digitalPinToPort(rx);
|
||||||
|
_receivePortRegister = portInputRegister(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t SoftwareSerial::subtract_cap(uint16_t num, uint16_t sub) {
|
||||||
|
if (num > sub)
|
||||||
|
return num - sub;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Public methods
|
||||||
|
//
|
||||||
|
|
||||||
|
void SoftwareSerial::begin(long speed)
|
||||||
|
{
|
||||||
|
_rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0;
|
||||||
|
|
||||||
|
// Precalculate the various delays, in number of 4-cycle delays
|
||||||
|
uint16_t bit_delay = (F_CPU / speed) / 4;
|
||||||
|
|
||||||
|
// 12 (gcc 4.8.2) or 13 (gcc 4.3.2) cycles from start bit to first bit,
|
||||||
|
// 15 (gcc 4.8.2) or 16 (gcc 4.3.2) cycles between bits,
|
||||||
|
// 12 (gcc 4.8.2) or 14 (gcc 4.3.2) cycles from last bit to stop bit
|
||||||
|
// These are all close enough to just use 15 cycles, since the inter-bit
|
||||||
|
// timings are the most critical (deviations stack 8 times)
|
||||||
|
_tx_delay = subtract_cap(bit_delay, 15 / 4);
|
||||||
|
|
||||||
|
// Only setup rx when we have a valid PCINT for this pin
|
||||||
|
if (digitalPinToPCICR((int8_t)_receivePin)) {
|
||||||
|
#if GCC_VERSION > 40800
|
||||||
|
// Timings counted from gcc 4.8.2 output. This works up to 115200 on
|
||||||
|
// 16Mhz and 57600 on 8Mhz.
|
||||||
|
//
|
||||||
|
// When the start bit occurs, there are 3 or 4 cycles before the
|
||||||
|
// interrupt flag is set, 4 cycles before the PC is set to the right
|
||||||
|
// interrupt vector address and the old PC is pushed on the stack,
|
||||||
|
// and then 75 cycles of instructions (including the RJMP in the
|
||||||
|
// ISR vector table) until the first delay. After the delay, there
|
||||||
|
// are 17 more cycles until the pin value is read (excluding the
|
||||||
|
// delay in the loop).
|
||||||
|
// We want to have a total delay of 1.5 bit time. Inside the loop,
|
||||||
|
// we already wait for 1 bit time - 23 cycles, so here we wait for
|
||||||
|
// 0.5 bit time - (71 + 18 - 22) cycles.
|
||||||
|
_rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 75 + 17 - 23) / 4);
|
||||||
|
|
||||||
|
// There are 23 cycles in each loop iteration (excluding the delay)
|
||||||
|
_rx_delay_intrabit = subtract_cap(bit_delay, 23 / 4);
|
||||||
|
|
||||||
|
// There are 37 cycles from the last bit read to the start of
|
||||||
|
// stopbit delay and 11 cycles from the delay until the interrupt
|
||||||
|
// mask is enabled again (which _must_ happen during the stopbit).
|
||||||
|
// This delay aims at 3/4 of a bit time, meaning the end of the
|
||||||
|
// delay will be at 1/4th of the stopbit. This allows some extra
|
||||||
|
// time for ISR cleanup, which makes 115200 baud at 16Mhz work more
|
||||||
|
// reliably
|
||||||
|
_rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (37 + 11) / 4);
|
||||||
|
#else // Timings counted from gcc 4.3.2 output
|
||||||
|
// Note that this code is a _lot_ slower, mostly due to bad register
|
||||||
|
// allocation choices of gcc. This works up to 57600 on 16Mhz and
|
||||||
|
// 38400 on 8Mhz.
|
||||||
|
_rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 97 + 29 - 11) / 4);
|
||||||
|
_rx_delay_intrabit = subtract_cap(bit_delay, 11 / 4);
|
||||||
|
_rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (44 + 17) / 4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Enable the PCINT for the entire port here, but never disable it
|
||||||
|
// (others might also need it, so we disable the interrupt by using
|
||||||
|
// the per-pin PCMSK register).
|
||||||
|
*digitalPinToPCICR((int8_t)_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));
|
||||||
|
// Precalculate the pcint mask register and value, so setRxIntMask
|
||||||
|
// can be used inside the ISR without costing too much time.
|
||||||
|
_pcint_maskreg = digitalPinToPCMSK(_receivePin);
|
||||||
|
_pcint_maskvalue = _BV(digitalPinToPCMSKbit(_receivePin));
|
||||||
|
|
||||||
|
tunedDelay(_tx_delay); // if we were low this establishes the end
|
||||||
|
}
|
||||||
|
|
||||||
|
#if _DEBUG
|
||||||
|
pinMode(_DEBUG_PIN1, OUTPUT);
|
||||||
|
pinMode(_DEBUG_PIN2, OUTPUT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
listen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareSerial::setRxIntMsk(bool enable)
|
||||||
|
{
|
||||||
|
if (enable)
|
||||||
|
*_pcint_maskreg |= _pcint_maskvalue;
|
||||||
|
else
|
||||||
|
*_pcint_maskreg &= ~_pcint_maskvalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareSerial::end()
|
||||||
|
{
|
||||||
|
stopListening();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Read data from buffer
|
||||||
|
int SoftwareSerial::read()
|
||||||
|
{
|
||||||
|
if (!isListening())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// Empty buffer?
|
||||||
|
if (_receive_buffer_head == _receive_buffer_tail)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// Read from "head"
|
||||||
|
uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
|
||||||
|
_receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SoftwareSerial::available()
|
||||||
|
{
|
||||||
|
if (!isListening())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return ((unsigned int)(_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head)) % _SS_MAX_RX_BUFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SoftwareSerial::write(uint8_t b)
|
||||||
|
{
|
||||||
|
if (_tx_delay == 0) {
|
||||||
|
setWriteError();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// By declaring these as local variables, the compiler will put them
|
||||||
|
// in registers _before_ disabling interrupts and entering the
|
||||||
|
// critical timing sections below, which makes it a lot easier to
|
||||||
|
// verify the cycle timings
|
||||||
|
volatile uint8_t *reg = _transmitPortRegister;
|
||||||
|
uint8_t reg_mask = _transmitBitMask;
|
||||||
|
uint8_t inv_mask = ~_transmitBitMask;
|
||||||
|
uint8_t oldSREG = SREG;
|
||||||
|
bool inv = _inverse_logic;
|
||||||
|
uint16_t delay = _tx_delay;
|
||||||
|
|
||||||
|
if (inv)
|
||||||
|
b = ~b;
|
||||||
|
|
||||||
|
cli(); // turn off interrupts for a clean txmit
|
||||||
|
|
||||||
|
// Write the start bit
|
||||||
|
if (inv)
|
||||||
|
*reg |= reg_mask;
|
||||||
|
else
|
||||||
|
*reg &= inv_mask;
|
||||||
|
|
||||||
|
tunedDelay(delay);
|
||||||
|
|
||||||
|
// Write each of the 8 bits
|
||||||
|
for (uint8_t i = 8; i > 0; --i)
|
||||||
|
{
|
||||||
|
if (b & 1) // choose bit
|
||||||
|
*reg |= reg_mask; // send 1
|
||||||
|
else
|
||||||
|
*reg &= inv_mask; // send 0
|
||||||
|
|
||||||
|
tunedDelay(delay);
|
||||||
|
b >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore pin to natural state
|
||||||
|
if (inv)
|
||||||
|
*reg &= inv_mask;
|
||||||
|
else
|
||||||
|
*reg |= reg_mask;
|
||||||
|
|
||||||
|
SREG = oldSREG; // turn interrupts back on
|
||||||
|
tunedDelay(_tx_delay);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftwareSerial::flush()
|
||||||
|
{
|
||||||
|
// There is no tx buffering, simply return
|
||||||
|
}
|
||||||
|
|
||||||
|
int SoftwareSerial::peek()
|
||||||
|
{
|
||||||
|
if (!isListening())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// Empty buffer?
|
||||||
|
if (_receive_buffer_head == _receive_buffer_tail)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// Read from "head"
|
||||||
|
return _receive_buffer[_receive_buffer_head];
|
||||||
|
}
|
114
arduino/libs/SoftwareSerial/SoftwareSerial.h
Normal file
114
arduino/libs/SoftwareSerial/SoftwareSerial.h
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
SoftwareSerial.h (formerly NewSoftSerial.h) -
|
||||||
|
Multi-instance software serial library for Arduino/Wiring
|
||||||
|
-- Interrupt-driven receive and other improvements by ladyada
|
||||||
|
(http://ladyada.net)
|
||||||
|
-- Tuning, circular buffer, derivation from class Print/Stream,
|
||||||
|
multi-instance support, porting to 8MHz processors,
|
||||||
|
various optimizations, PROGMEM delay tables, inverse logic and
|
||||||
|
direct port writing by Mikal Hart (http://www.arduiniana.org)
|
||||||
|
-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
|
||||||
|
-- 20MHz processor support by Garrett Mace (http://www.macetech.com)
|
||||||
|
-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
The latest version of this library can always be found at
|
||||||
|
http://arduiniana.org.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SoftwareSerial_h
|
||||||
|
#define SoftwareSerial_h
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <Stream.h>
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Definitions
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _SS_MAX_RX_BUFF
|
||||||
|
#define _SS_MAX_RX_BUFF 64 // RX buffer size
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GCC_VERSION
|
||||||
|
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class SoftwareSerial : public Stream
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// per object data
|
||||||
|
uint8_t _receivePin;
|
||||||
|
uint8_t _receiveBitMask;
|
||||||
|
volatile uint8_t *_receivePortRegister;
|
||||||
|
uint8_t _transmitBitMask;
|
||||||
|
volatile uint8_t *_transmitPortRegister;
|
||||||
|
volatile uint8_t *_pcint_maskreg;
|
||||||
|
uint8_t _pcint_maskvalue;
|
||||||
|
|
||||||
|
// Expressed as 4-cycle delays (must never be 0!)
|
||||||
|
uint16_t _rx_delay_centering;
|
||||||
|
uint16_t _rx_delay_intrabit;
|
||||||
|
uint16_t _rx_delay_stopbit;
|
||||||
|
uint16_t _tx_delay;
|
||||||
|
|
||||||
|
uint16_t _buffer_overflow:1;
|
||||||
|
uint16_t _inverse_logic:1;
|
||||||
|
|
||||||
|
// static data
|
||||||
|
static uint8_t _receive_buffer[_SS_MAX_RX_BUFF];
|
||||||
|
static volatile uint8_t _receive_buffer_tail;
|
||||||
|
static volatile uint8_t _receive_buffer_head;
|
||||||
|
static SoftwareSerial *active_object;
|
||||||
|
|
||||||
|
// private methods
|
||||||
|
inline void recv() __attribute__((__always_inline__));
|
||||||
|
uint8_t rx_pin_read();
|
||||||
|
void setTX(uint8_t transmitPin);
|
||||||
|
void setRX(uint8_t receivePin);
|
||||||
|
inline void setRxIntMsk(bool enable) __attribute__((__always_inline__));
|
||||||
|
|
||||||
|
// Return num - sub, or 1 if the result would be < 1
|
||||||
|
static uint16_t subtract_cap(uint16_t num, uint16_t sub);
|
||||||
|
|
||||||
|
// private static method for timing
|
||||||
|
static inline void tunedDelay(uint16_t delay);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// public methods
|
||||||
|
SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false);
|
||||||
|
~SoftwareSerial();
|
||||||
|
void begin(long speed);
|
||||||
|
bool listen();
|
||||||
|
void end();
|
||||||
|
bool isListening() { return this == active_object; }
|
||||||
|
bool stopListening();
|
||||||
|
bool overflow() { bool ret = _buffer_overflow; if (ret) _buffer_overflow = false; return ret; }
|
||||||
|
int peek();
|
||||||
|
|
||||||
|
virtual size_t write(uint8_t byte);
|
||||||
|
virtual int read();
|
||||||
|
virtual int available();
|
||||||
|
virtual void flush();
|
||||||
|
operator bool() { return true; }
|
||||||
|
|
||||||
|
using Print::write;
|
||||||
|
|
||||||
|
// public only for easy access by interrupt handlers
|
||||||
|
static inline void handle_interrupt() __attribute__((__always_inline__));
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
12
arduino/src/LcdControl.cpp
Normal file
12
arduino/src/LcdControl.cpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// #include "LcdControl.h"
|
||||||
|
// #include "LiquidCrystal.h"
|
||||||
|
|
||||||
|
// //instance object
|
||||||
|
// LcdControl::LcdControl(LiquidCrystal lcd) {
|
||||||
|
// ;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //when to update a cycle
|
||||||
|
// LcdControl::update() {
|
||||||
|
// ;
|
||||||
|
// }
|
12
arduino/src/LcdControl.h
Normal file
12
arduino/src/LcdControl.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// #ifndef LcdControl_h
|
||||||
|
// #define LcdControl_h
|
||||||
|
|
||||||
|
// class LcdControl {
|
||||||
|
|
||||||
|
// private:
|
||||||
|
|
||||||
|
// public:
|
||||||
|
|
||||||
|
// };
|
||||||
|
|
||||||
|
// #endif
|
11
arduino/src/SerialHandler.cpp
Normal file
11
arduino/src/SerialHandler.cpp
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#include "SerialHandler.h"
|
||||||
|
#include "SoftwareSerial.h"
|
||||||
|
|
||||||
|
SerialHandler::SerialHandler(uint8_t rx, uint8_t tx) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Serialhandler loop
|
||||||
|
SerialHandler::update() {
|
||||||
|
;
|
||||||
|
}
|
14
arduino/src/SerialHandler.h
Normal file
14
arduino/src/SerialHandler.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
//header file with the SerialHandler class
|
||||||
|
#ifndef SerialHandler_h
|
||||||
|
#define SerialHandler_h
|
||||||
|
|
||||||
|
class SerialHandler {
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
public:
|
||||||
|
SerialHandler(uint8_t rx, uint8_t tx);
|
||||||
|
void update();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
2166
desktop/Cargo.lock
generated
Normal file
2166
desktop/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
25
desktop/Cargo.toml
Normal file
25
desktop/Cargo.toml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
[package]
|
||||||
|
name = "desktop"
|
||||||
|
version = "0.1.0"
|
||||||
|
#authors = ["Jonas_Jones"]
|
||||||
|
edition = "2021"
|
||||||
|
#description = "The desktop module of the PI-server-rack project."
|
||||||
|
#documentation = "https://github.com/JonasJones/PI-server-rack"
|
||||||
|
#readme = "README.md"
|
||||||
|
#homepage = "https://jonasjones.me/PI-server-rack"
|
||||||
|
#repository = "https://github.com/J-onasJones/PI-server-rack"
|
||||||
|
#license = "MIT OR Apache-2.0"
|
||||||
|
#keywords = ["server", "raspberry pi"]
|
||||||
|
#categories = ["config"]
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
eframe = "0.19.0"
|
||||||
|
try-catch = "0.2.2"
|
||||||
|
serde = "1.0.144"
|
||||||
|
serde_json = "1.0.85"
|
||||||
|
serde_derive = "1.0.144"
|
||||||
|
config = "0.13.2"
|
||||||
|
log = "0.4.17"
|
||||||
|
dirs = "4.0.0"
|
1
desktop/README.md
Normal file
1
desktop/README.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Desktop (PC/MAC) module
|
53
desktop/lang/en_us.json
Normal file
53
desktop/lang/en_us.json
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
{
|
||||||
|
"language.name": "English",
|
||||||
|
"language.region": "United States",
|
||||||
|
"language.code": "en-US",
|
||||||
|
"app.name": "PI-server-rack-Config",
|
||||||
|
"app.description": "A ui based configuration program for the PI-server-rack",
|
||||||
|
"window.main.title": "PI-server-rack-Config",
|
||||||
|
"window.main.menu.file": "File",
|
||||||
|
"window.main.menu.file.new": "New",
|
||||||
|
"window.main.menu.file.open": "Open",
|
||||||
|
"window.main.menu.file.save": "Save",
|
||||||
|
"window.main.menu.file.saveas": "Save as",
|
||||||
|
"window.main.menu.file.quit": "Quit",
|
||||||
|
"window.main.menu.edit": "Edit",
|
||||||
|
"window.main.menu.edit.undo": "Undo",
|
||||||
|
"window.main.menu.edit.redo": "Redo",
|
||||||
|
"window.main.menu.edit.cut": "Cut",
|
||||||
|
"window.main.menu.edit.copy": "Copy",
|
||||||
|
"window.main.menu.edit.paste": "Paste",
|
||||||
|
"window.main.menu.edit.delete": "Delete",
|
||||||
|
"window.main.menu.edit.selectall": "Select all",
|
||||||
|
"window.main.menu.edit.find": "Find",
|
||||||
|
"window.main.menu.edit.findnext": "Find next",
|
||||||
|
"window.main.menu.edit.findprev": "Find previous",
|
||||||
|
"window.main.menu.edit.replace": "Replace",
|
||||||
|
"window.main.menu.edit.goto": "Goto",
|
||||||
|
"window.main.menu.edit.selectline": "Select line",
|
||||||
|
"window.main.menu.edit.selectword": "Select word",
|
||||||
|
"window.main.menu.edit.selectblock": "Select block",
|
||||||
|
"window.main.menu.edit.indent": "Indent",
|
||||||
|
"window.main.menu.edit.unindent": "Unindent",
|
||||||
|
"window.main.menu.edit.comment": "Comment",
|
||||||
|
"window.main.menu.edit.uncomment": "Uncomment",
|
||||||
|
"window.main.menu.view": "View",
|
||||||
|
"window.main.menu.view.fullscreen": "Fullscreen",
|
||||||
|
"window.main.menu.view.zoomin": "Zoom in",
|
||||||
|
"window.main.menu.view.zoomout": "Zoom out",
|
||||||
|
"window.main.menu.view.zoomreset": "Zoom reset",
|
||||||
|
"window.main.menu.preferences": "Preferences",
|
||||||
|
"window.main.menu.preferences.Settings": "Settings",
|
||||||
|
"window.main.menu.preferences.keybinds": "Keybinds",
|
||||||
|
"window.main.menu.help": "Help",
|
||||||
|
"window.main.menu.help.about": "About",
|
||||||
|
"window.main.menu.help.documentation": "Documentation",
|
||||||
|
"window.main.menu.help.tutorial": "Tutorial",
|
||||||
|
"window.main.menu.help.faq": "FAQ",
|
||||||
|
"window.main.menu.help.bugreport": "Bug report",
|
||||||
|
"window.main.menu.help.log": "Log",
|
||||||
|
"window.main.menu.help.log.clear": "Clear",
|
||||||
|
"window.main.menu.help.log.saveas": "Save as",
|
||||||
|
"window.main.tab.overview": "Overview",
|
||||||
|
"window.main.tab.settings.title": "Settings"
|
||||||
|
}
|
38
desktop/src/confighandler/mod.rs
Normal file
38
desktop/src/confighandler/mod.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
use std::{fs::File, io::Read};
|
||||||
|
use try_catch::catch;
|
||||||
|
use serde_json::from_str;
|
||||||
|
use defaultconfigs::Mainconfig;
|
||||||
|
|
||||||
|
use crate::defaultconfigs::{self, CONFIG_PATH};
|
||||||
|
|
||||||
|
extern crate serde;
|
||||||
|
extern crate serde_json;
|
||||||
|
|
||||||
|
pub(crate) fn init() {
|
||||||
|
catch! {
|
||||||
|
try {
|
||||||
|
load()
|
||||||
|
} catch _error {
|
||||||
|
create()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load() {
|
||||||
|
// Load the config file
|
||||||
|
let mut file = File::open(CONFIG_PATH).unwrap();
|
||||||
|
let mut contents = String::new();
|
||||||
|
file.read_to_string(&mut contents).unwrap();
|
||||||
|
let config: Mainconfig = from_str(&contents).unwrap();
|
||||||
|
println!("{:?}", config);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create() {
|
||||||
|
// Create the config file
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn save() {
|
||||||
|
// Save the config file
|
||||||
|
|
||||||
|
}
|
19
desktop/src/defaultconfigs/mod.rs
Normal file
19
desktop/src/defaultconfigs/mod.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
use std::path::{PathBuf};
|
||||||
|
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use dirs::config_dir;
|
||||||
|
|
||||||
|
const SYSTEM_CONFIG_PATH: Option<PathBuf> = config_dir();
|
||||||
|
const RELATIVE_CONFIG_PATH: &str = "/pi-server-rack/config.json";
|
||||||
|
|
||||||
|
pub(crate) const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
pub(crate) const CONFIG_PATH: PathBuf= SYSTEM_CONFIG_PATH.push(RELATIVE_CONFIG_PATH); //TODO: not die from fucking rust paths
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub(crate) struct Mainconfig {
|
||||||
|
lang : String,
|
||||||
|
configpath : String,
|
||||||
|
customwindowframe : bool,
|
||||||
|
|
||||||
|
}
|
3
desktop/src/langhandler.rs
Normal file
3
desktop/src/langhandler.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fn load() {
|
||||||
|
// Load the language file
|
||||||
|
}
|
18
desktop/src/main.rs
Normal file
18
desktop/src/main.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
//import ui
|
||||||
|
mod ui;
|
||||||
|
pub(crate) mod confighandler;
|
||||||
|
pub(crate) mod defaultconfigs;
|
||||||
|
|
||||||
|
use defaultconfigs::VERSION;
|
||||||
|
|
||||||
|
use log::{info};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
info!(target: "[THREAD-MAIN]", "Welcome to PI-Server-Rack v{} !", VERSION);
|
||||||
|
//initialize config
|
||||||
|
confighandler::init();
|
||||||
|
|
||||||
|
|
||||||
|
//initialiaze ui
|
||||||
|
ui::mainloop();
|
||||||
|
}
|
53
desktop/src/ui/mod.rs
Normal file
53
desktop/src/ui/mod.rs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
|
||||||
|
|
||||||
|
pub(crate) mod tabs;
|
||||||
|
|
||||||
|
extern crate eframe;
|
||||||
|
use eframe::egui;
|
||||||
|
|
||||||
|
pub(crate) fn mainloop() {
|
||||||
|
let options = eframe::NativeOptions::default();
|
||||||
|
eframe::run_native(
|
||||||
|
"Confirm exit",
|
||||||
|
options,
|
||||||
|
Box::new(|_cc| Box::new(RootWindow::default())),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct RootWindow {
|
||||||
|
allowed_to_close: bool,
|
||||||
|
show_confirmation_dialog: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl eframe::App for RootWindow {
|
||||||
|
fn on_close_event(&mut self) -> bool {
|
||||||
|
self.show_confirmation_dialog = true;
|
||||||
|
self.allowed_to_close
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
|
||||||
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
|
ui.heading("Try to close the window");
|
||||||
|
});
|
||||||
|
|
||||||
|
if self.show_confirmation_dialog {
|
||||||
|
// Show confirmation dialog:
|
||||||
|
egui::Window::new("Do you want to quit?")
|
||||||
|
.collapsible(false)
|
||||||
|
.resizable(false)
|
||||||
|
.show(ctx, |ui| {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
if ui.button("Cancel").clicked() {
|
||||||
|
self.show_confirmation_dialog = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ui.button("Yes!").clicked() {
|
||||||
|
self.allowed_to_close = true;
|
||||||
|
frame.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
desktop/src/ui/tabs/mod.rs
Normal file
2
desktop/src/ui/tabs/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
pub(crate) mod overview;
|
||||||
|
pub(crate) mod settings;
|
0
desktop/src/ui/tabs/overview.rs
Normal file
0
desktop/src/ui/tabs/overview.rs
Normal file
0
desktop/src/ui/tabs/settings.rs
Normal file
0
desktop/src/ui/tabs/settings.rs
Normal file
79
pc/main.py
79
pc/main.py
|
@ -1,79 +0,0 @@
|
||||||
from ftplib import FTP
|
|
||||||
from io import BytesIO
|
|
||||||
from time import sleep, time
|
|
||||||
from xml.sax.handler import feature_namespace_prefixes
|
|
||||||
|
|
||||||
launch_time = time()
|
|
||||||
|
|
||||||
print_stats = True
|
|
||||||
|
|
||||||
hostname = "172.24.1.193"
|
|
||||||
username = "testuser"
|
|
||||||
password = "uwu"
|
|
||||||
|
|
||||||
ftp = FTP(hostname, username, password)
|
|
||||||
ftp.encoding = "utf-8"
|
|
||||||
|
|
||||||
filename = "output.txt"
|
|
||||||
|
|
||||||
while True:
|
|
||||||
start_time = time()
|
|
||||||
|
|
||||||
with open(filename, "wb") as file:
|
|
||||||
# use FTP's RETR command to download the file
|
|
||||||
ftp.retrbinary(f"RETR {filename}", file.write)
|
|
||||||
|
|
||||||
file = open(filename, 'r')
|
|
||||||
content = file.read()
|
|
||||||
content = content.split(";")
|
|
||||||
|
|
||||||
fanmode = content[0]
|
|
||||||
slave_fanmode = content[1]
|
|
||||||
fanspeed = content[2]
|
|
||||||
fanspeed2 = content[3]
|
|
||||||
thermal = content[4]
|
|
||||||
slave_thermal = content[5]
|
|
||||||
cpu_usage = content[6]
|
|
||||||
cpu_freq = content[7]
|
|
||||||
cpu_up = content[8]
|
|
||||||
total_ram = content[9]
|
|
||||||
ram_usage = content[10]
|
|
||||||
ram_free = content[11]
|
|
||||||
ram_percent = content[12]
|
|
||||||
swap_percent = content[13]
|
|
||||||
disk_percent = content[14]
|
|
||||||
|
|
||||||
mc_motd = content[15]
|
|
||||||
mc_version = content[16]
|
|
||||||
mc_players_max = content[17]
|
|
||||||
mc_players_on = content[18]
|
|
||||||
mc_version_brand = content[19]
|
|
||||||
mc_plugins = content[20]
|
|
||||||
mc_playerlist = content[21]
|
|
||||||
|
|
||||||
sleep(2)
|
|
||||||
|
|
||||||
stop_time = time()
|
|
||||||
|
|
||||||
if print_stats:
|
|
||||||
print("---------- Uptime: " + str(cpu_up) + " ----------")
|
|
||||||
print("Loop time:\t" + str(round(stop_time - start_time, 2)) + "\ts")
|
|
||||||
print("CMD Uptime:\t" + str(round(stop_time - launch_time, 2)) + "\ts")
|
|
||||||
print("CPU")
|
|
||||||
print("\tusage:\t" + str(cpu_usage) + "\t%")
|
|
||||||
print("\tfreq:\t" + str(cpu_freq) + "\tMHz")
|
|
||||||
print("\ttemp:\t" + str(thermal) + "\tC")
|
|
||||||
print("RAM")
|
|
||||||
print("\tusage:\t" + str(ram_percent) + "\t%")
|
|
||||||
print("\tswap :\t" + str(swap_percent) + "\t%")
|
|
||||||
print("Disks")
|
|
||||||
print("\tusage:\t" + str(disk_percent) + "\t%")
|
|
||||||
print("FANMODE")
|
|
||||||
print("\tmain:\t" + str(fanmode) + "\t%")
|
|
||||||
print("\tslave:\t" + str(slave_fanmode) + "\t%")
|
|
||||||
print("\tglobal:\t" + str(fanspeed) + "\t%")
|
|
||||||
print("\t2ndary:\t" + str(fanspeed2) + "\t%")
|
|
||||||
|
|
||||||
|
|
||||||
# Close the Connection
|
|
||||||
ftp.quit()
|
|
19
pi-master/Cargo.toml
Normal file
19
pi-master/Cargo.toml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
[package]
|
||||||
|
name = "pi-master"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = "Jonas_Jones"
|
||||||
|
edition = "2021"
|
||||||
|
description = "The Raspberry Pi master module of the PI-server-rack project."
|
||||||
|
documentation = "https://github.com/JonasJones/PI-server-rack"
|
||||||
|
readme = "README.md"
|
||||||
|
homepage = "https://jonasjones.me/PI-server-rack"
|
||||||
|
repository = "https://github.com/J-onasJones/PI-server-rack"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
keywords = ["server", "raspberry pi"]
|
||||||
|
categories = ["config"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
1
pi-master/README.md
Normal file
1
pi-master/README.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Raspberry PI master module
|
3
pi-master/src/main.rs
Normal file
3
pi-master/src/main.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
17
pi-slave/Cargo.toml
Normal file
17
pi-slave/Cargo.toml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
[package]
|
||||||
|
name = "pi-slave"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = "Jonas_Jones"
|
||||||
|
edition = "2021"
|
||||||
|
description = "The Raspberry Pi slave module of the PI-server-rack project."
|
||||||
|
documentation = "https://github.com/JonasJones/PI-server-rack"
|
||||||
|
readme = "README.md"
|
||||||
|
homepage = "https://jonasjones.me/PI-server-rack"
|
||||||
|
repository = "https://github.com/J-onasJones/PI-server-rack"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
keywords = ["server", "raspberry pi"]
|
||||||
|
categories = ["config"]
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
1
pi-slave/README.md
Normal file
1
pi-slave/README.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Raspberry PI slave module
|
3
pi-slave/src/main.rs
Normal file
3
pi-slave/src/main.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
57
pi1/main.py
57
pi1/main.py
|
@ -1,57 +0,0 @@
|
||||||
import RPi.GPIO as GPIO
|
|
||||||
import subprocess
|
|
||||||
import time
|
|
||||||
|
|
||||||
# GPIO setup
|
|
||||||
GPIO.setmode(GPIO.BCM)
|
|
||||||
GPIO.setwarnings(False)
|
|
||||||
|
|
||||||
# Powering Status Pin to indicate that control program is up
|
|
||||||
GPIO.setup(4, GPIO.OUT)
|
|
||||||
GPIO.output(4, True)
|
|
||||||
|
|
||||||
# setting up communication pins for binary fanmode transmission
|
|
||||||
GPIO.setup(17, GPIO.OUT)
|
|
||||||
GPIO.setup(18, GPIO.OUT)
|
|
||||||
|
|
||||||
# define default variables -> fan speed will be at max. if someting goes wrong with getting cpu temps
|
|
||||||
thermal = -99
|
|
||||||
fanmode = 100
|
|
||||||
i = 0
|
|
||||||
|
|
||||||
# function to get cpu temperature on linux and macOS and decide on fan speed.
|
|
||||||
def temp(thermal, fanmode):
|
|
||||||
thermal = str(round(float(subprocess.check_output("cat /sys/class/thermal/thermal_zone0/temp", shell=True).rstrip())/1000,2))
|
|
||||||
if thermal <= 20:
|
|
||||||
fanmode = 0
|
|
||||||
elif 20 < thermal <= 40:
|
|
||||||
fanmode = 25
|
|
||||||
elif 40 < thermal <= 60:
|
|
||||||
fanmode = 50
|
|
||||||
elif 60 < fanmode <= 70:
|
|
||||||
fanmode = 75
|
|
||||||
elif 70 < fanmode:
|
|
||||||
fanmode = 100
|
|
||||||
return thermal, fanmode
|
|
||||||
|
|
||||||
# main loop
|
|
||||||
while True:
|
|
||||||
# get cpu temp
|
|
||||||
temp(thermal, fanmode)
|
|
||||||
if fanmode == 0 or fanmode == 25:
|
|
||||||
GPIO.output(17, False)
|
|
||||||
GPIO.output(18, True)
|
|
||||||
elif fanmode == 50:
|
|
||||||
GPIO.output(17, True)
|
|
||||||
GPIO.output(18, False)
|
|
||||||
elif fanmode == 75:
|
|
||||||
GPIO.output(17, True)
|
|
||||||
GPIO.output(18, True)
|
|
||||||
else:
|
|
||||||
GPIO.output(17, False)
|
|
||||||
GPIO.output(18, False)
|
|
||||||
# cpu temp will be updated every 5 seconds
|
|
||||||
time.sleep(5)
|
|
||||||
i += 1
|
|
||||||
# log cpu temp and fan speed
|
|
||||||
print("----- Run Nr.:", i, "\nCpu temperature measured: ", thermal + "°C", "- Fanspeed: ", fanmode + "%")
|
|
165
pi4/main.py
165
pi4/main.py
|
@ -1,165 +0,0 @@
|
||||||
from http import server
|
|
||||||
import RPi.GPIO as GPIO
|
|
||||||
import subprocess, os, time
|
|
||||||
|
|
||||||
# GPIO setup
|
|
||||||
GPIO.setmode(GPIO.BCM)
|
|
||||||
GPIO.setwarnings(False)
|
|
||||||
|
|
||||||
# Powering Status Pin to indicate that control program is up
|
|
||||||
GPIO.setup(4, GPIO.OUT)
|
|
||||||
GPIO.output(4, True)
|
|
||||||
|
|
||||||
# setting up communication pins for binary fanmode transmission
|
|
||||||
GPIO.setup(17, GPIO.IN)
|
|
||||||
GPIO.setup(18, GPIO.IN)
|
|
||||||
|
|
||||||
# setting up control pin for fancontrol
|
|
||||||
GPIO.setuo(4, GPIO.OUT)
|
|
||||||
|
|
||||||
# define default variables -> fan speed will be at max. if someting goes wrong with getting cpu temps
|
|
||||||
thermal = -99
|
|
||||||
fanmode = 100
|
|
||||||
i = 0
|
|
||||||
|
|
||||||
file = open("output.txt", 'r+')
|
|
||||||
|
|
||||||
cpu_usage = "--"
|
|
||||||
total_ram = "--.--"
|
|
||||||
ram_usage = "--.--"
|
|
||||||
ram_free = "--.--"
|
|
||||||
|
|
||||||
# check mc server status too. Set to False to disable Minecraft server module
|
|
||||||
check_mcserver = True
|
|
||||||
mc_ip = "127.0.0.1"
|
|
||||||
mc_port = "25565"
|
|
||||||
|
|
||||||
mc_motd = "-"
|
|
||||||
mc_version = 0
|
|
||||||
mc_players_max = 0
|
|
||||||
mc_players_on = 0
|
|
||||||
mc_version_brand = "-"
|
|
||||||
mc_plugins = []
|
|
||||||
mc_player_list = []
|
|
||||||
|
|
||||||
# function to get cpu temperature on linux and macOS and decide on fan speed.
|
|
||||||
def temp(thermal, fanmode):
|
|
||||||
thermal = str(round(float(subprocess.check_output("cat /sys/class/thermal/thermal_zone0/temp", shell=True).rstrip())/1000,2))
|
|
||||||
if thermal <= 20:
|
|
||||||
fanmode = 0
|
|
||||||
elif 20 < thermal <= 40:
|
|
||||||
fanmode = 25
|
|
||||||
elif 40 < thermal <= 60:
|
|
||||||
fanmode = 50
|
|
||||||
elif 60 < fanmode <= 70:
|
|
||||||
fanmode = 75
|
|
||||||
elif 70 < fanmode:
|
|
||||||
fanmode = 100
|
|
||||||
return thermal, fanmode
|
|
||||||
|
|
||||||
# function to round values
|
|
||||||
def display(val):
|
|
||||||
return round(float(val),2)
|
|
||||||
|
|
||||||
# function to get system informations
|
|
||||||
def sys_monitor(cpu_usage, total_ram, ram_usage, ram_free):
|
|
||||||
cpu_usage = str(round(float(os.popen('''grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage }' ''').readline()),2))
|
|
||||||
total_ram = str(round(display(subprocess.check_output("free | awk 'FNR == 2 {print $2/1000000}'", shell=True))))
|
|
||||||
ram_usage = str(subprocess.check_output("free | awk 'FNR == 2 {print $3/($3+$4)*100}'", shell=True))
|
|
||||||
ram_free = str(100 - display(ram_usage))
|
|
||||||
return cpu_usage, total_ram, ram_usage, ram_free
|
|
||||||
|
|
||||||
# function to get server status if enabled
|
|
||||||
def mcserver(mc_motd, mc_version, mc_players_max, mc_players_on, mc_version_brand, mc_plugins, mc_player_list):
|
|
||||||
if check_mcserver:
|
|
||||||
# importing module mcstatus --> must be installed for this in order to work
|
|
||||||
from mcstatus import MinecraftServer
|
|
||||||
mcserver = MinecraftServer.lookup(mc_ip + ":" + mc_port)
|
|
||||||
status = mcserver.status()
|
|
||||||
mc_motd = status.description
|
|
||||||
mc_version = status.version.name
|
|
||||||
mc_players_max = status.players.max
|
|
||||||
mc_players_on = status.players.online
|
|
||||||
|
|
||||||
# IMPORTANT!
|
|
||||||
# for the following code to work, the query must be enabled in the server config file ('server.properties' --> 'enable-query=True').
|
|
||||||
# If you don't have access to that file but still want your server status, you can delete the following lines that contain the 'query' argument.
|
|
||||||
# This will provide you with a more limited status:
|
|
||||||
# the version brand (vanilla, fabric modded, bukkit, etc.), the plugin list (if any) and the list if players won't be visible in that case
|
|
||||||
query = mcserver.query()
|
|
||||||
mc_version = query.software.version
|
|
||||||
mc_version_brand = query.software.brand
|
|
||||||
mc_plugins = query.software.plugins
|
|
||||||
mc_player_list = query.players.names
|
|
||||||
|
|
||||||
# if no query --> delete 'mc_version_brand', 'mc_plugins' and 'mc_player_list' from the return argument
|
|
||||||
# the line below should then look like THIS: return mc_motd, mc_version, mc_players_max, mc_players_on
|
|
||||||
return mc_motd, mc_version, mc_players_max, mc_players_on, mc_version_brand, mc_plugins, mc_player_list
|
|
||||||
|
|
||||||
|
|
||||||
while True:
|
|
||||||
# eecute temperature function
|
|
||||||
|
|
||||||
temp(thermal, fanmode)
|
|
||||||
# determine fanmode of 2nd raspberry PI and guess CPU temps
|
|
||||||
if GPIO.input(17) and GPIO.input(18):
|
|
||||||
slave_fanmode = 75
|
|
||||||
slave_thermal = "60 - 70"
|
|
||||||
elif GPIO.input(17) and not GPIO.input(18):
|
|
||||||
slave_fanmode = 50
|
|
||||||
slave_thermal = "40 - 60"
|
|
||||||
elif not GPIO.input(17) and GPIO.input(18):
|
|
||||||
slave_fanmode = 25
|
|
||||||
slave_thermal = "0 - 40"
|
|
||||||
elif not GPIO.input(17) and not GPIO.input(18):
|
|
||||||
slave_fanmode = 100
|
|
||||||
slave_thermal = "70 - 100"
|
|
||||||
else:
|
|
||||||
slave_fanmode = 100
|
|
||||||
slave_thermal = "-"
|
|
||||||
|
|
||||||
# get other system infos and Minecraft Server stats
|
|
||||||
sys_monitor(cpu_usage, total_ram, ram_usage, ram_free)
|
|
||||||
mcserver(mc_motd, mc_version, mc_players_max, mc_players_on, mc_version_brand, mc_plugins, mc_player_list)
|
|
||||||
|
|
||||||
# write all data to list
|
|
||||||
system_infos = [fanmode, slave_fanmode, thermal, slave_thermal, cpu_usage, total_ram, ram_usage, ram_free, mc_motd, mc_version, mc_players_max, mc_players_on, mc_version_brand, mc_plugins, mc_player_list]
|
|
||||||
|
|
||||||
# delete all text in file and write list to file
|
|
||||||
file.truncate(0)
|
|
||||||
for e in system_infos:
|
|
||||||
file.write(e)
|
|
||||||
file.write(";")
|
|
||||||
|
|
||||||
# determine the PI with higher CPU temperature
|
|
||||||
if slave_fanmode > fanmode:
|
|
||||||
fanspeed = slave_fanmode
|
|
||||||
else:
|
|
||||||
fanspeed = fanmode
|
|
||||||
if fanmode == 100:
|
|
||||||
GPIO.output(4, True)
|
|
||||||
time.sleep(5)
|
|
||||||
elif fanmode == 75:
|
|
||||||
while i < 12:
|
|
||||||
GPIO.output(4, True)
|
|
||||||
time.sleep(0.3)
|
|
||||||
GPIO.outut(4, False)
|
|
||||||
time.sleep(0.1)
|
|
||||||
i += 1
|
|
||||||
elif fanmode == 50:
|
|
||||||
while i < 25:
|
|
||||||
GPIO.output(4, True)
|
|
||||||
time.sleep(0.1)
|
|
||||||
GPIO.output(4, False)
|
|
||||||
time.sleep(0.1)
|
|
||||||
i += 1
|
|
||||||
elif fanmode == 25:
|
|
||||||
while i < 12:
|
|
||||||
GPIO.output(4, True)
|
|
||||||
time.sleep(0.1)
|
|
||||||
GPIO.outut(4, False)
|
|
||||||
time.sleep(0.3)
|
|
||||||
i += 1
|
|
||||||
else:
|
|
||||||
GPIO.output(4, True)
|
|
||||||
time.sleep(5)
|
|
Loading…
Add table
Add a link
Reference in a new issue