diff --git a/Firmware b/Firmware
deleted file mode 160000
index 40e9c8a..0000000
--- a/Firmware
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 40e9c8a774ce4707db48dc1ce6462cbe0044825f
diff --git a/Firmware_V2/.cproject b/Firmware_V2/.cproject
new file mode 100644
index 0000000..b5e5732
--- /dev/null
+++ b/Firmware_V2/.cproject
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Firmware_V2/.gitignore b/Firmware_V2/.gitignore
new file mode 100644
index 0000000..652f297
--- /dev/null
+++ b/Firmware_V2/.gitignore
@@ -0,0 +1 @@
+Release/
\ No newline at end of file
diff --git a/Firmware_V2/.project b/Firmware_V2/.project
new file mode 100644
index 0000000..338a4ca
--- /dev/null
+++ b/Firmware_V2/.project
@@ -0,0 +1,40 @@
+
+
+ DIYThermocam
+
+
+
+
+
+ io.sloeber.core.inoToCpp
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.core.ccnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+ io.sloeber.arduinonature
+
+
+
+ core/core
+ 2
+ C:/Program Files (x86)/Arduino/hardware/teensy/avr/cores/teensy3
+
+
+
diff --git a/Firmware_V2/.settings/language.settings.xml b/Firmware_V2/.settings/language.settings.xml
new file mode 100644
index 0000000..934b42e
--- /dev/null
+++ b/Firmware_V2/.settings/language.settings.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Firmware_V2/.settings/org.eclipse.cdt.codan.core.prefs b/Firmware_V2/.settings/org.eclipse.cdt.codan.core.prefs
new file mode 100644
index 0000000..6907ef9
--- /dev/null
+++ b/Firmware_V2/.settings/org.eclipse.cdt.codan.core.prefs
@@ -0,0 +1,72 @@
+eclipse.preferences.version=1
+org.eclipse.cdt.codan.checkers.errnoreturn=Warning
+org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false}
+org.eclipse.cdt.codan.checkers.errreturnvalue=Error
+org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"}
+org.eclipse.cdt.codan.checkers.nocommentinside=-Error
+org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting comments\\")"}
+org.eclipse.cdt.codan.checkers.nolinecomment=-Error
+org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line comments\\")"}
+org.eclipse.cdt.codan.checkers.noreturn=Error
+org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false}
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=-Error
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"}
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"}
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"}
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"}
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No break at end of case\\")",no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false,enable_fallthrough_quickfix_param\=>false}
+org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
+org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"}
+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class members should be properly initialized\\")",skip\=>true}
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments=-Error
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"}
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"}
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"}
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"}
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"}
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"}
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"}
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"}
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"}
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"}
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false}
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false}
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused variable declaration in file scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")}
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol is not resolved\\")"}
+useParentScope=false
diff --git a/Firmware_V2/.settings/org.eclipse.cdt.core.prefs b/Firmware_V2/.settings/org.eclipse.cdt.core.prefs
new file mode 100644
index 0000000..360e2bf
--- /dev/null
+++ b/Firmware_V2/.settings/org.eclipse.cdt.core.prefs
@@ -0,0 +1,456 @@
+eclipse.preferences.version=1
+environment/project/io.sloeber.core.toolChain.release.787846084/A.ALT_SIZE_COMMAND/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.ALT_SIZE_COMMAND/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.ALT_SIZE_COMMAND/value="${A.COMPILER.PATH}${A.COMPILER.SIZE.CMD}" --format\=avr --mcu\=${A.BUILD.MCU} "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.ARCHIVE_FILE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.ARCHIVE_FILE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.ARCHIVE_FILE/value=arduino.ar
+environment/project/io.sloeber.core.toolChain.release.787846084/A.ARCHIVE_FILE_PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.ARCHIVE_FILE_PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.ARCHIVE_FILE_PATH/value=${A.BUILD.PATH}/${A.ARCHIVE_FILE}
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.ARCH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.ARCH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.ARCH/value=AVR
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.BOARD/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.BOARD/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.BOARD/value=TEENSY36
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.AR/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.AR/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.AR/value=arm-none-eabi-gcc-ar
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.G++/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.G++/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.G++/value=arm-none-eabi-g++
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.GCC/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.GCC/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.GCC/value=arm-none-eabi-gcc
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.OBJCOPY/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.OBJCOPY/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.OBJCOPY/value=arm-none-eabi-objcopy
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.OBJDUMP/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.OBJDUMP/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.OBJDUMP/value=arm-none-eabi-objdump
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.SIZE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.SIZE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.COMMAND.SIZE/value=arm-none-eabi-size
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.CORE.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.CORE.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.CORE.PATH/value=${A.RUNTIME.PLATFORM.PATH}/cores/${A.BUILD.CORE}
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.CORE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.CORE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.CORE/value=teensy3
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FCPU/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FCPU/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FCPU/value=240000000
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.C/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.C/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.C/value=
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.COMMON/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.COMMON/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.COMMON/value=-g -Wall -ffunction-sections -fdata-sections -nostdlib
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.CPP/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.CPP/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.CPP/value=-fno-exceptions -felide-constructors -std\=gnu++14 -Wno-error\=narrowing -fno-rtti
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.CPU/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.CPU/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.CPU/value=-mthumb -mcpu\=cortex-m4 -mfloat-abi\=hard -mfpu\=fpv4-sp-d16 -fsingle-precision-constant
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.DEFS/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.DEFS/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.DEFS/value=-D__MK66FX1M0__ -DTEENSYDUINO\=143
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.DEP/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.DEP/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.DEP/value=-MMD
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.LD/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.LD/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.LD/value=-Wl,--gc-sections,--relax,--defsym\=__rtc_localtime\=${A.EXTRA.TIME.LOCAL} "-T${A.BUILD.CORE.PATH}/mk66fx1m0.ld" -lstdc++
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.LDSPECS/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.LDSPECS/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.LDSPECS/value=-fuse-linker-plugin
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.LIBS/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.LIBS/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.LIBS/value=-larm_cortexM4lf_math -lm
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.OPTIMIZE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.OPTIMIZE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.OPTIMIZE/value=-O3 -flto -fno-fat-lto-objects
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.S/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.S/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.FLAGS.S/value=-x assembler-with-cpp
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.KEYLAYOUT/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.KEYLAYOUT/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.KEYLAYOUT/value=US_INTERNATIONAL
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.MCU/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.MCU/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.MCU/value=mk66fx1m0
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.PATH/value=${ProjDirPath}/${ConfigName}
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.PROJECT_NAME/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.PROJECT_NAME/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.PROJECT_NAME/value=${ProjName}
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.SYSTEM.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.SYSTEM.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.SYSTEM.PATH/value=${A.RUNTIME.PLATFORM.PATH}/system
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.TOOLCHAIN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.TOOLCHAIN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.TOOLCHAIN/value=arm/bin/
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.USBTYPE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.USBTYPE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.USBTYPE/value=USB_SERIAL
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.VARIANT.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.VARIANT.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.VARIANT.PATH/value=
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.WARN_DATA_PERCENTAGE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.WARN_DATA_PERCENTAGE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.BUILD.WARN_DATA_PERCENTAGE/value=99
+environment/project/io.sloeber.core.toolChain.release.787846084/A.COMPILER.ELF2HEX.FLAGS/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.COMPILER.ELF2HEX.FLAGS/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.COMPILER.ELF2HEX.FLAGS/value=-O ihex -R .eeprom
+environment/project/io.sloeber.core.toolChain.release.787846084/A.COMPILER.OBJCOPY.EEP.FLAGS/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.COMPILER.OBJCOPY.EEP.FLAGS/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.COMPILER.OBJCOPY.EEP.FLAGS/value=-O ihex -j .eeprom --set-section-flags\=.eeprom\=alloc,load --no-change-warnings --change-section-lma .eeprom\=0
+environment/project/io.sloeber.core.toolChain.release.787846084/A.COMPILER.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.COMPILER.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.COMPILER.PATH/value=${A.RUNTIME.HARDWARE.PATH}/../tools/
+environment/project/io.sloeber.core.toolChain.release.787846084/A.COMPILER.WARNING_FLAGS.ALL/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.COMPILER.WARNING_FLAGS.ALL/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.COMPILER.WARNING_FLAGS.ALL/value=-Wall -Wextra
+environment/project/io.sloeber.core.toolChain.release.787846084/A.COMPILER.WARNING_FLAGS/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.COMPILER.WARNING_FLAGS/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.COMPILER.WARNING_FLAGS/value=${A.COMPILER.WARNING_FLAGS.ALL}
+environment/project/io.sloeber.core.toolChain.release.787846084/A.ESP8266.NETWORK.UPLOAD.TOOL/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.ESP8266.NETWORK.UPLOAD.TOOL/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.ESP8266.NETWORK.UPLOAD.TOOL/value=esp8266OTA
+environment/project/io.sloeber.core.toolChain.release.787846084/A.EXTRA.TIME.DTS/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.EXTRA.TIME.DTS/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.EXTRA.TIME.DTS/value=3600
+environment/project/io.sloeber.core.toolChain.release.787846084/A.EXTRA.TIME.LOCAL/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.EXTRA.TIME.LOCAL/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.EXTRA.TIME.LOCAL/value=1536406810
+environment/project/io.sloeber.core.toolChain.release.787846084/A.EXTRA.TIME.UTC/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.EXTRA.TIME.UTC/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.EXTRA.TIME.UTC/value=1536399610
+environment/project/io.sloeber.core.toolChain.release.787846084/A.EXTRA.TIME.ZONE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.EXTRA.TIME.ZONE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.EXTRA.TIME.ZONE/value=3600
+environment/project/io.sloeber.core.toolChain.release.787846084/A.JANTJE.CORE.REFERENCED.PLATFORM/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.JANTJE.CORE.REFERENCED.PLATFORM/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.JANTJE.CORE.REFERENCED.PLATFORM/value=${JANTJE.SELECTED.PLATFORM}
+environment/project/io.sloeber.core.toolChain.release.787846084/A.JANTJE.USED.BOARDS_FILE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.JANTJE.USED.BOARDS_FILE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.JANTJE.USED.BOARDS_FILE/value=${JANTJE.BOARDS_FILE}
+environment/project/io.sloeber.core.toolChain.release.787846084/A.JANTJE.VARIANT.REFERENCED.PLATFORM/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.JANTJE.VARIANT.REFERENCED.PLATFORM/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.JANTJE.VARIANT.REFERENCED.PLATFORM/value=${JANTJE.SELECTED.PLATFORM}
+environment/project/io.sloeber.core.toolChain.release.787846084/A.NAME/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.NAME/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.NAME/value=Teensy 3.6
+environment/project/io.sloeber.core.toolChain.release.787846084/A.PACKAGES/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.PACKAGES/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.PACKAGES/value=${eclipse_home}/arduinoPlugin/packages
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.AR.PATTERN.1/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.AR.PATTERN.1/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.AR.PATTERN.1/value="C\:/Program Files (x86)/Arduino/hardware/teensy/../tools/arm/bin/arm-none-eabi-gcc-ar" rcs
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.AR.PATTERN.2/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.AR.PATTERN.2/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.AR.PATTERN.2/value=\
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.AR.PATTERN.3/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.AR.PATTERN.3/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.AR.PATTERN.3/value=
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.AR.PATTERN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.AR.PATTERN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.AR.PATTERN/value="${A.COMPILER.PATH}${A.BUILD.TOOLCHAIN}${A.BUILD.COMMAND.AR}" rcs "${A.ARCHIVE_FILE_PATH}" "${A.OBJECT_FILE}"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.COMBINE.PATTERN.1/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.COMBINE.PATTERN.1/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.COMBINE.PATTERN.1/value="C\:/Program Files (x86)/Arduino/hardware/teensy/../tools/arm/bin/arm-none-eabi-gcc" -O3 -flto -fno-fat-lto-objects -Wl,--gc-sections,--relax,--defsym\=__rtc_localtime\=1536406810 "-TC\:/Program Files (x86)/Arduino/hardware/teensy/avr/cores/teensy3/mk66fx1m0.ld" -lstdc++ -fuse-linker-plugin -mthumb -mcpu\=cortex-m4 -mfloat-abi\=hard -mfpu\=fpv4-sp-d16 -fsingle-precision-constant -o "C\:\\Sandbox\\DIY-Thermocam\\Firmware/Release/DIYThermocam.elf"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.COMBINE.PATTERN.2/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.COMBINE.PATTERN.2/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.COMBINE.PATTERN.2/value=\
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.COMBINE.PATTERN.3/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.COMBINE.PATTERN.3/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.COMBINE.PATTERN.3/value=\ "-LC\:\\Sandbox\\DIY-Thermocam\\Firmware/Release" -larm_cortexM4lf_math -lm
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.COMBINE.PATTERN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.COMBINE.PATTERN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.COMBINE.PATTERN/value="${A.COMPILER.PATH}${A.BUILD.TOOLCHAIN}${A.BUILD.COMMAND.GCC}" ${A.BUILD.FLAGS.OPTIMIZE} ${A.BUILD.FLAGS.LD} ${A.BUILD.FLAGS.LDSPECS} ${A.BUILD.FLAGS.CPU} -o "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf" ${A.OBJECT_FILES} "${A.BUILD.PATH}/${A.ARCHIVE_FILE}" "-L${A.BUILD.PATH}" ${A.BUILD.FLAGS.LIBS}
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.O.PATTERN.1/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.O.PATTERN.1/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.O.PATTERN.1/value="C\:/Program Files (x86)/Arduino/hardware/teensy/../tools/arm/bin/arm-none-eabi-gcc" -c -O3 -flto -fno-fat-lto-objects -g -Wall -ffunction-sections -fdata-sections -nostdlib -mthumb -mcpu\=cortex-m4 -mfloat-abi\=hard -mfpu\=fpv4-sp-d16 -fsingle-precision-constant -D__MK66FX1M0__ -DTEENSYDUINO\=143 -DARDUINO\=10802 -DF_CPU\=240000000 -DUSB_SERIAL -DLAYOUT_US_INTERNATIONAL
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.O.PATTERN.2/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.O.PATTERN.2/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.O.PATTERN.2/value=\ -o
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.O.PATTERN.3/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.O.PATTERN.3/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.O.PATTERN.3/value=
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.O.PATTERN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.O.PATTERN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.C.O.PATTERN/value="${A.COMPILER.PATH}${A.BUILD.TOOLCHAIN}${A.BUILD.COMMAND.GCC}" -c ${A.BUILD.FLAGS.OPTIMIZE} ${A.BUILD.FLAGS.COMMON} ${A.BUILD.FLAGS.DEP} ${A.BUILD.FLAGS.C} ${A.BUILD.FLAGS.CPU} ${A.BUILD.FLAGS.DEFS} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DF_CPU\=${A.BUILD.FCPU} -D${A.BUILD.USBTYPE} -DLAYOUT_${A.BUILD.KEYLAYOUT} ${A.INCLUDES} "${A.SOURCE_FILE}" -o "${A.OBJECT_FILE}"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.CPP.O.PATTERN.1/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.CPP.O.PATTERN.1/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.CPP.O.PATTERN.1/value="C\:/Program Files (x86)/Arduino/hardware/teensy/../tools/arm/bin/arm-none-eabi-g++" -c -O3 -flto -fno-fat-lto-objects -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -felide-constructors -std\=gnu++14 -Wno-error\=narrowing -fno-rtti -mthumb -mcpu\=cortex-m4 -mfloat-abi\=hard -mfpu\=fpv4-sp-d16 -fsingle-precision-constant -D__MK66FX1M0__ -DTEENSYDUINO\=143 -DARDUINO\=10802 -DF_CPU\=240000000 -DUSB_SERIAL -DLAYOUT_US_INTERNATIONAL "-IC\:\\Sandbox\\DIY-Thermocam\\Firmware/Release/pch"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.CPP.O.PATTERN.2/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.CPP.O.PATTERN.2/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.CPP.O.PATTERN.2/value=\ -o
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.CPP.O.PATTERN.3/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.CPP.O.PATTERN.3/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.CPP.O.PATTERN.3/value=
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.CPP.O.PATTERN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.CPP.O.PATTERN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.CPP.O.PATTERN/value="${A.COMPILER.PATH}${A.BUILD.TOOLCHAIN}${A.BUILD.COMMAND.G++}" -c ${A.BUILD.FLAGS.OPTIMIZE} ${A.BUILD.FLAGS.COMMON} ${A.BUILD.FLAGS.DEP} ${A.BUILD.FLAGS.CPP} ${A.BUILD.FLAGS.CPU} ${A.BUILD.FLAGS.DEFS} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DF_CPU\=${A.BUILD.FCPU} -D${A.BUILD.USBTYPE} -DLAYOUT_${A.BUILD.KEYLAYOUT} "-I${A.BUILD.PATH}/pch" ${A.INCLUDES} "${A.SOURCE_FILE}" -o "${A.OBJECT_FILE}"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.ELFPATCH.PATTERN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.ELFPATCH.PATTERN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.ELFPATCH.PATTERN/value="${A.COMPILER.PATH}/hardware/tools/${A.BUILD.ELFPATCH}" -mmcu\=${A.BUILD.MCU} "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf" "${A.SKETCH_PATH}/disk"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.HOOKS.POSTBUILD.1.PATTERN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.HOOKS.POSTBUILD.1.PATTERN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.HOOKS.POSTBUILD.1.PATTERN/value="${A.COMPILER.PATH}stdout_redirect" "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.lst" "${A.COMPILER.PATH}${A.BUILD.TOOLCHAIN}${A.BUILD.COMMAND.OBJDUMP}" -d -S -C "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.HOOKS.POSTBUILD.2.PATTERN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.HOOKS.POSTBUILD.2.PATTERN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.HOOKS.POSTBUILD.2.PATTERN/value="${A.COMPILER.PATH}stdout_redirect" "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.sym" "${A.COMPILER.PATH}${A.BUILD.TOOLCHAIN}${A.BUILD.COMMAND.OBJDUMP}" -t -C "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.HOOKS.POSTBUILD.3.PATTERN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.HOOKS.POSTBUILD.3.PATTERN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.HOOKS.POSTBUILD.3.PATTERN/value="${A.COMPILER.PATH}teensy_post_compile" "-file\=${A.BUILD.PROJECT_NAME}" "-path\=${A.BUILD.PATH}" "-tools\=${A.COMPILER.PATH}" "-board\=${A.BUILD.BOARD}"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.HOOKS.SKETCH.PREBUILD.1.PATTERN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.HOOKS.SKETCH.PREBUILD.1.PATTERN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.HOOKS.SKETCH.PREBUILD.1.PATTERN/value="${A.COMPILER.PATH}precompile_helper" "${A.RUNTIME.PLATFORM.PATH}/cores/${A.BUILD.CORE}" "${A.BUILD.PATH}" "${A.COMPILER.PATH}${A.BUILD.TOOLCHAIN}${A.BUILD.COMMAND.G++}" -x c++-header ${A.BUILD.FLAGS.OPTIMIZE} ${A.BUILD.FLAGS.COMMON} ${A.BUILD.FLAGS.DEP} ${A.BUILD.FLAGS.CPP} ${A.BUILD.FLAGS.CPU} ${A.BUILD.FLAGS.DEFS} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DF_CPU\=${A.BUILD.FCPU} -D${A.BUILD.USBTYPE} -DLAYOUT_${A.BUILD.KEYLAYOUT} "-I${A.RUNTIME.PLATFORM.PATH}/cores/${A.BUILD.CORE}" "${A.BUILD.PATH}/pch/Arduino.h" -o "${A.BUILD.PATH}/pch/Arduino.h.gch"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OBJCOPY.EEP.PATTERN.1/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OBJCOPY.EEP.PATTERN.1/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OBJCOPY.EEP.PATTERN.1/value="C\:/Program Files (x86)/Arduino/hardware/teensy/../tools/arm/bin/arm-none-eabi-objcopy" -O ihex -j .eeprom --set-section-flags\=.eeprom\=alloc,load --no-change-warnings --change-section-lma .eeprom\=0 "C\:\\Sandbox\\DIY-Thermocam\\Firmware/Release/DIYThermocam.elf" "C\:\\Sandbox\\DIY-Thermocam\\Firmware/Release/DIYThermocam.eep"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OBJCOPY.EEP.PATTERN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OBJCOPY.EEP.PATTERN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OBJCOPY.EEP.PATTERN/value="${A.COMPILER.PATH}${A.BUILD.TOOLCHAIN}${A.BUILD.COMMAND.OBJCOPY}" ${A.COMPILER.OBJCOPY.EEP.FLAGS} "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf" "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.eep"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OBJCOPY.HEX.PATTERN.1/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OBJCOPY.HEX.PATTERN.1/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OBJCOPY.HEX.PATTERN.1/value="C\:/Program Files (x86)/Arduino/hardware/teensy/../tools/arm/bin/arm-none-eabi-objcopy" -O ihex -R .eeprom "C\:\\Sandbox\\DIY-Thermocam\\Firmware/Release/DIYThermocam.elf" "C\:\\Sandbox\\DIY-Thermocam\\Firmware/Release/DIYThermocam.hex"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OBJCOPY.HEX.PATTERN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OBJCOPY.HEX.PATTERN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OBJCOPY.HEX.PATTERN/value="${A.COMPILER.PATH}${A.BUILD.TOOLCHAIN}${A.BUILD.COMMAND.OBJCOPY}" ${A.COMPILER.ELF2HEX.FLAGS} "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf" "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.hex"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OUTPUT.SAVE_FILE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OUTPUT.SAVE_FILE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OUTPUT.SAVE_FILE/value=${A.BUILD.PROJECT_NAME}.${A.BUILD.BOARD}.hex
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OUTPUT.SAVE_FILE2/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OUTPUT.SAVE_FILE2/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OUTPUT.SAVE_FILE2/value=${A.BUILD.PROJECT_NAME}.elf
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OUTPUT.TMP_FILE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OUTPUT.TMP_FILE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OUTPUT.TMP_FILE/value=${A.BUILD.PROJECT_NAME}.hex
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OUTPUT.TMP_FILE2/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OUTPUT.TMP_FILE2/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.OUTPUT.TMP_FILE2/value=${A.BUILD.PROJECT_NAME}.elf
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.PREPROC.INCLUDES/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.PREPROC.INCLUDES/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.PREPROC.INCLUDES/value="${A.COMPILER.PATH}${A.BUILD.TOOLCHAIN}${A.BUILD.COMMAND.G++}" -M -MG -MP -x c++ -w ${A.BUILD.FLAGS.CPP} ${A.BUILD.FLAGS.CPU} ${A.BUILD.FLAGS.DEFS} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DF_CPU\=${A.BUILD.FCPU} -D${A.BUILD.USBTYPE} -DLAYOUT_${A.BUILD.KEYLAYOUT} ${A.INCLUDES} "${A.SOURCE_FILE}"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.PREPROC.MACROS/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.PREPROC.MACROS/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.PREPROC.MACROS/value="${A.COMPILER.PATH}${A.BUILD.TOOLCHAIN}${A.BUILD.COMMAND.G++}" -E -CC -x c++ -w ${A.COMPILER.CPP.FLAGS} ${A.BUILD.FLAGS.COMMON} ${A.BUILD.FLAGS.CPP} ${A.BUILD.FLAGS.CPU} ${A.BUILD.FLAGS.DEFS} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DF_CPU\=${A.BUILD.FCPU} -D${A.BUILD.USBTYPE} -DLAYOUT_${A.BUILD.KEYLAYOUT} ${A.INCLUDES} "${A.SOURCE_FILE}" -o "${A.PREPROCESSED_FILE_PATH}"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.S.O.PATTERN.1/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.S.O.PATTERN.1/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.S.O.PATTERN.1/value="C\:/Program Files (x86)/Arduino/hardware/teensy/../tools/arm/bin/arm-none-eabi-gcc" -c -O3 -flto -fno-fat-lto-objects -g -Wall -ffunction-sections -fdata-sections -nostdlib -x assembler-with-cpp -mthumb -mcpu\=cortex-m4 -mfloat-abi\=hard -mfpu\=fpv4-sp-d16 -fsingle-precision-constant -D__MK66FX1M0__ -DTEENSYDUINO\=143 -DARDUINO\=10802 -DF_CPU\=240000000 -DUSB_SERIAL -DLAYOUT_US_INTERNATIONAL
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.S.O.PATTERN.2/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.S.O.PATTERN.2/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.S.O.PATTERN.2/value=\ -o
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.S.O.PATTERN.3/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.S.O.PATTERN.3/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.S.O.PATTERN.3/value=
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.S.O.PATTERN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.S.O.PATTERN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.S.O.PATTERN/value="${A.COMPILER.PATH}${A.BUILD.TOOLCHAIN}${A.BUILD.COMMAND.GCC}" -c ${A.BUILD.FLAGS.OPTIMIZE} ${A.BUILD.FLAGS.COMMON} ${A.BUILD.FLAGS.DEP} ${A.BUILD.FLAGS.S} ${A.BUILD.FLAGS.CPU} ${A.BUILD.FLAGS.DEFS} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DF_CPU\=${A.BUILD.FCPU} -D${A.BUILD.USBTYPE} -DLAYOUT_${A.BUILD.KEYLAYOUT} ${A.INCLUDES} "${A.SOURCE_FILE}" -o "${A.OBJECT_FILE}"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.SIZE.PATTERN.1/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.SIZE.PATTERN.1/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.SIZE.PATTERN.1/value="C\:/Program Files (x86)/Arduino/hardware/teensy/../tools/arm/bin/arm-none-eabi-size" -A "C\:\\Sandbox\\DIY-Thermocam\\Firmware/Release/DIYThermocam.elf"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.SIZE.PATTERN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.SIZE.PATTERN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.SIZE.PATTERN/value="${A.COMPILER.PATH}${A.BUILD.TOOLCHAIN}${A.BUILD.COMMAND.SIZE}" -A "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.SIZE.REGEX.DATA/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.SIZE.REGEX.DATA/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.SIZE.REGEX.DATA/value=^(?\:\\.usbdescriptortable|\\.dmabuffers|\\.usbbuffers|\\.data|\\.bss|\\.noinit)\\s+([0-9]+).*
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.SIZE.REGEX.EEPROM/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.SIZE.REGEX.EEPROM/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.SIZE.REGEX.EEPROM/value=^(?\:\\.eeprom)\\s+([0-9]+).*
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.SIZE.REGEX/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.SIZE.REGEX/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RECIPE.SIZE.REGEX/value=^(?\:\\.text|\\.data|\\.bootloader)\\s+([0-9]+).*
+environment/project/io.sloeber.core.toolChain.release.787846084/A.REWRITING/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.REWRITING/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.REWRITING/value=disabled
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.HARDWARE.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.HARDWARE.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.HARDWARE.PATH/value=C\:/Program Files (x86)/Arduino/hardware/teensy
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.IDE.VERSION/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.IDE.VERSION/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.IDE.VERSION/value=10802
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.PLATFORM.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.PLATFORM.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.PLATFORM.PATH/value=C\:/Program Files (x86)/Arduino/hardware/teensy/avr
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.REFERENCED.PLATFORM.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.REFERENCED.PLATFORM.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.REFERENCED.PLATFORM.PATH/value=C\:/Program Files (x86)/Arduino/hardware/teensy/avr
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.ARDUINOOTA-1.1.1.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.ARDUINOOTA-1.1.1.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.ARDUINOOTA-1.1.1.PATH/value=${eclipse_home}/arduinoPlugin/packages/arduino/tools/arduinoOTA/1.1.1
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.ARDUINOOTA.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.ARDUINOOTA.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.ARDUINOOTA.PATH/value=${eclipse_home}/arduinoPlugin/packages/arduino/tools/arduinoOTA/1.1.1
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.ARDUINOOTA1.1.1.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.ARDUINOOTA1.1.1.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.ARDUINOOTA1.1.1.PATH/value=${eclipse_home}/arduinoPlugin/packages/arduino/tools/arduinoOTA/1.1.1
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVR-GCC-4.9.2-ATMEL3.5.4-ARDUINO2.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVR-GCC-4.9.2-ATMEL3.5.4-ARDUINO2.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVR-GCC-4.9.2-ATMEL3.5.4-ARDUINO2.PATH/value=${eclipse_home}/arduinoPlugin/packages/arduino/tools/avr-gcc/4.9.2-atmel3.5.4-arduino2
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVR-GCC.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVR-GCC.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVR-GCC.PATH/value=${eclipse_home}/arduinoPlugin/packages/arduino/tools/avr-gcc/4.9.2-atmel3.5.4-arduino2
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVR-GCC4.9.2-ATMEL3.5.4-ARDUINO2.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVR-GCC4.9.2-ATMEL3.5.4-ARDUINO2.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVR-GCC4.9.2-ATMEL3.5.4-ARDUINO2.PATH/value=${eclipse_home}/arduinoPlugin/packages/arduino/tools/avr-gcc/4.9.2-atmel3.5.4-arduino2
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVRDUDE-6.3.0-ARDUINO9.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVRDUDE-6.3.0-ARDUINO9.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVRDUDE-6.3.0-ARDUINO9.PATH/value=${eclipse_home}/arduinoPlugin/packages/arduino/tools/avrdude/6.3.0-arduino9
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVRDUDE.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVRDUDE.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVRDUDE.PATH/value=${eclipse_home}/arduinoPlugin/packages/arduino/tools/avrdude/6.3.0-arduino9
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVRDUDE6.3.0-ARDUINO9.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVRDUDE6.3.0-ARDUINO9.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.RUNTIME.TOOLS.AVRDUDE6.3.0-ARDUINO9.PATH/value=${eclipse_home}/arduinoPlugin/packages/arduino/tools/avrdude/6.3.0-arduino9
+environment/project/io.sloeber.core.toolChain.release.787846084/A.SERIAL.PORT.FILE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.SERIAL.PORT.FILE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.SERIAL.PORT.FILE/value=${A.SERIAL.PORT}
+environment/project/io.sloeber.core.toolChain.release.787846084/A.SERIAL.PORT/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.SERIAL.PORT/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.SERIAL.PORT/value=${JANTJE.COM_PORT}
+environment/project/io.sloeber.core.toolChain.release.787846084/A.SERIAL.RESTART_CMD/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.SERIAL.RESTART_CMD/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.SERIAL.RESTART_CMD/value=false
+environment/project/io.sloeber.core.toolChain.release.787846084/A.SOFTWARE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.SOFTWARE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.SOFTWARE/value=ARDUINO
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ARDUINO-PREPROCESSOR.CMD.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ARDUINO-PREPROCESSOR.CMD.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ARDUINO-PREPROCESSOR.CMD.PATH/value=${A.TOOLS.ARDUINO-PREPROCESSOR.PATH}/arduino-preprocessor
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ARDUINO-PREPROCESSOR.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ARDUINO-PREPROCESSOR.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ARDUINO-PREPROCESSOR.PATH/value=${A.TOOLS.ARDUINO-PREPROCESSOR.RUNTIME.TOOLS.ARDUINO-PREPROCESSOR.PATH}
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ARDUINO-PREPROCESSOR.PATTERN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ARDUINO-PREPROCESSOR.PATTERN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ARDUINO-PREPROCESSOR.PATTERN/value="${A.TOOLS.ARDUINO-PREPROCESSOR.CMD.PATH}" "${A.TOOLS.ARDUINO-PREPROCESSOR.SOURCE_FILE}" "${A.TOOLS.ARDUINO-PREPROCESSOR.CODECOMPLETE}" -- -std\=gnu++14
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.AVRDUDE_REMOTE.UPLOAD.VERBOSE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.AVRDUDE_REMOTE.UPLOAD.VERBOSE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.AVRDUDE_REMOTE.UPLOAD.VERBOSE/value=-v
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ESP8266OTA.UPLOAD.PATTERN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ESP8266OTA.UPLOAD.PATTERN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ESP8266OTA.UPLOAD.PATTERN/value=${A.TOOLS.ESP8266OTA.TOOLS.ESPTOOL.UPLOAD.NETWORK_PATTERN}
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ESP8266OTA/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ESP8266OTA/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ESP8266OTA/value=${A.TOOLS.ESP8266OTA.TOOLS.ESPTOOL.NETWORK_CMD}
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ESPTOOL.NETWORK.PASSWORD/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ESPTOOL.NETWORK.PASSWORD/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.ESPTOOL.NETWORK.PASSWORD/value=${A.TOOLS.ESPTOOL.NETWORK.AUTH}
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.TEENSYLOADER.CMD.PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.TEENSYLOADER.CMD.PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.TEENSYLOADER.CMD.PATH/value=${A.RUNTIME.HARDWARE.PATH}/../tools
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.TEENSYLOADER.UPLOAD.PARAMS.QUIET/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.TEENSYLOADER.UPLOAD.PARAMS.QUIET/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.TEENSYLOADER.UPLOAD.PARAMS.QUIET/value=
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.TEENSYLOADER.UPLOAD.PARAMS.VERBOSE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.TEENSYLOADER.UPLOAD.PARAMS.VERBOSE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.TEENSYLOADER.UPLOAD.PARAMS.VERBOSE/value=-verbose
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.TEENSYLOADER.UPLOAD.PATTERN/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.TEENSYLOADER.UPLOAD.PATTERN/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.TOOLS.TEENSYLOADER.UPLOAD.PATTERN/value="${A.TOOLS.TEENSYLOADER.CMD.PATH}/teensy_post_compile" "-file\=${A.BUILD.PROJECT_NAME}" "-path\=${A.BUILD.PATH}" "-tools\=${A.TOOLS.TEENSYLOADER.CMD.PATH}" "-board\=${A.BUILD.BOARD}" -reboot "-port\=${A.SERIAL.PORT}" "-portlabel\=${A.TOOLS.TEENSYLOADER.SERIAL.PORT.LABEL}" "-portprotocol\=${A.TOOLS.TEENSYLOADER.SERIAL.PORT.PROTOCOL}"
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.ALTID/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.ALTID/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.ALTID/value=no_altID
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.MAXIMUM_DATA_SIZE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.MAXIMUM_DATA_SIZE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.MAXIMUM_DATA_SIZE/value=262144
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.MAXIMUM_SIZE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.MAXIMUM_SIZE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.MAXIMUM_SIZE/value=1048576
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.PROTOCOL/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.PROTOCOL/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.PROTOCOL/value=halfkay
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.SPEED/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.SPEED/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.SPEED/value=19200
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.TOOL/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.TOOL/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.TOOL/value=teensyloader
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.USBID/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.USBID/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.UPLOAD.USBID/value=no_altID
+environment/project/io.sloeber.core.toolChain.release.787846084/A.VERSION/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/A.VERSION/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/A.VERSION/value=1.8.5
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.ARCHITECTURE_ID/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.ARCHITECTURE_ID/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.ARCHITECTURE_ID/value=avr
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.BOARDS_FILE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.BOARDS_FILE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.BOARDS_FILE/value=C\:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\boards.txt
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.BOARD_ID/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.BOARD_ID/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.BOARD_ID/value=teensy36
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.BOARD_NAME/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.BOARD_NAME/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.BOARD_NAME/value=Teensy 3.6
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.COM_PORT/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.COM_PORT/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.COM_PORT/value=COM10
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.ECLIPSE_LOCATION/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.ECLIPSE_LOCATION/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.ECLIPSE_LOCATION/value=C\:\\Dev\\sloeber\\
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.ALL/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.ALL/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.ALL/value=
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.ARCHIVE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.ARCHIVE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.ARCHIVE/value=
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.ASSEMBLY/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.ASSEMBLY/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.ASSEMBLY/value=
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.C.COMPILE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.C.COMPILE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.C.COMPILE/value=
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.COMPILE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.COMPILE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.COMPILE/value=
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.CPP.COMPILE/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.CPP.COMPILE/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.CPP.COMPILE/value=
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.LINK/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.LINK/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.EXTRA.LINK/value=
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.MAKE_LOCATION/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.MAKE_LOCATION/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.MAKE_LOCATION/value=${eclipse_home}/arduinoPlugin/tools/make/
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.MENU/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.MENU/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.MENU/value=keys\=usint\nopt\=o3lto\nspeed\=240\nusb\=serial
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.OBJCOPY/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.OBJCOPY/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.OBJCOPY/value=${A.RECIPE.OBJCOPY.EEP.PATTERN}\n\t${A.RECIPE.OBJCOPY.HEX.PATTERN}
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.OS_NAME/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.OS_NAME/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.OS_NAME/value=win32
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.PACKAGE_ID/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.PACKAGE_ID/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.PACKAGE_ID/value=teensy
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.PROJECT_NAME/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.PROJECT_NAME/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.PROJECT_NAME/value=DIYThermocam
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.SELECTED.PLATFORM/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.SELECTED.PLATFORM/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.SELECTED.PLATFORM/value=C\:/Program Files (x86)/Arduino/hardware/teensy/avr
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.SIZE.SWITCH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.SIZE.SWITCH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.SIZE.SWITCH/value=${A.RECIPE.SIZE.PATTERN}
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.UPLOAD/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.UPLOAD/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.UPLOAD/value=Default
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.WARNING_LEVEL/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.WARNING_LEVEL/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.WARNING_LEVEL/value=true
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.WORKSPACE_LOCATION/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.WORKSPACE_LOCATION/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/JANTJE.WORKSPACE_LOCATION/value=C\:\\Users\\Max\\Documents\\sloeber-workspace
+environment/project/io.sloeber.core.toolChain.release.787846084/PATH/delimiter=;
+environment/project/io.sloeber.core.toolChain.release.787846084/PATH/operation=replace
+environment/project/io.sloeber.core.toolChain.release.787846084/PATH/value=${A.COMPILER.PATH}${PathDelimiter}${A.BUILD.GENERIC.PATH}${PathDelimiter}${SystemRoot}\\system32${PathDelimiter}${SystemRoot}${PathDelimiter}${SystemRoot}\\system32\\Wbem${PathDelimiter}${sloeber_path_extension}
+environment/project/io.sloeber.core.toolChain.release.787846084/append=true
+environment/project/io.sloeber.core.toolChain.release.787846084/appendContributed=true
diff --git a/Firmware_V2/.settings/org.eclipse.core.resources.prefs b/Firmware_V2/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..bc49b4f
--- /dev/null
+++ b/Firmware_V2/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding//src/hardware/camera/ov2640regs.cpp=UTF-8
diff --git a/Firmware_V2/LICENSE b/Firmware_V2/LICENSE
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/Firmware_V2/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/Firmware_V2/README.MD b/Firmware_V2/README.MD
new file mode 100644
index 0000000..bf2567a
--- /dev/null
+++ b/Firmware_V2/README.MD
@@ -0,0 +1,33 @@
+# DIY-Thermocam V2 Firmware #
+
+GNU General Public License v3.0, copyright by Max Ritter
+
+**The following hardware is supported:**
+
+- **DIY-Thermocam V2** (2017) - Lepton2.0 / Lepton2.5 / Lepton3.0 / Lepton3.5
+
+----------
+
+**THIS GUIDE IS ONLY REQUIRED, IF YOU WANT TO MAKE CHANGES TO THE FIRMWARE ON YOUR OWN!**
+
+If you just want to flash the newest version of the firmware to your device, follow the Firmware Update Guide in the Document section and use one of the pre-compiled versions (*.hex) from **[here](https://github.com/maxritter/diythermocam_firmware/releases)**.
+
+----------
+
+This guide should work on **all common operating systems** (**Windows, Linux & Mac OSX**).
+
+**Download** and **install** the following programs:
+
+1. **[Arduino 1.8.6+](https://www.arduino.cc/en/Main/Software)**
+2. **[Teensyduino 1.43+](https://www.pjrc.com/teensy/td_download.html)**
+3. **[Sloeber Eclipse](https://github.com/Sloeber/arduino-eclipse-plugin/releases/tag/4_2)**
+
+Then **clone this repo** to a path without empty spaces (f. ex. "C:\Sandbox\DIYThermocam_Firmware\") with `git clone https://github.com/maxritter/diythermocam_firmware.git`.
+
+Now **start Sloeber Eclipse**.
+
+Go to Windows -> Preferences -> Arduino and **set the Private Library Path** to the folder of your Arduino library installation (f. ex. "C:\Program Files (x86)\Arduino\libraries"). Also **set the Private Hardware Path** to the path of your Arduino hardware installation (f. ex. "C:\Program Files (x86)\Arduino\hardware").
+
+**Import the project** with File -> Import -> General -> Existing Projects into Workspace, select the root directory of this repo and click Finish.
+
+Now you should be able to build the project with Arduino -> Verify and upload it to the Thermocam with Arduino -> Upload Sketch. Have fun!
diff --git a/Firmware_V2/core/.keep b/Firmware_V2/core/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/Firmware_V2/src/general/colorschemes.cpp b/Firmware_V2/src/general/colorschemes.cpp
new file mode 100644
index 0000000..07319c6
--- /dev/null
+++ b/Firmware_V2/src/general/colorschemes.cpp
@@ -0,0 +1,132 @@
+/*
+ *
+ * COLOR SCHEMES - Contains 19 different color schemes to display the thermal image
+ *
+ * DIY-Thermocam Firmware
+ *
+ * GNU General Public License v3.0
+ *
+ * Copyright by Max Ritter
+ *
+ * http://www.diy-thermocam.net
+ * https://github.com/maxritter/DIY-Thermocam
+ *
+ */
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+
+/*############################# PUBLIC VARIABLES ##############################*/
+
+const byte colorMap_arctic[] = { 15, 16, 146, 15, 16, 146, 15, 15, 153, 15, 15, 153, 15, 15, 159, 15, 15, 159, 16, 15, 167, 16, 15, 167, 15, 15, 175, 15, 15, 175, 16, 15, 182, 16, 15, 182, 16, 16, 190, 16, 16, 190, 14, 15, 197, 14, 15, 197, 15, 15, 205, 15, 15, 205, 15, 15, 211, 15, 15, 211, 16, 15, 219, 16, 15, 219, 16, 15, 227, 16, 15, 227, 16, 18, 239, 16, 18, 239, 16, 25, 240, 16, 25, 240, 15, 34, 239, 15, 34, 239, 15, 44, 238, 15, 44, 238, 14, 54, 239, 14, 54, 239, 14, 63, 239, 14, 63, 239, 14, 74, 238, 14, 74, 238, 17, 82, 238, 17, 82, 238, 19, 92, 237, 19, 92, 237, 22, 102, 239, 22, 102, 239, 24, 111, 238, 24, 111, 238, 27, 120, 237, 27, 120, 237, 28, 131, 237, 28, 131, 237, 32, 140, 237, 32, 140, 237, 34, 150, 237, 34, 150, 237, 36, 160, 236, 36, 160, 236, 39, 168, 237, 39, 168, 237, 42, 179, 237, 42, 179, 237, 44, 188, 236, 44, 188, 236, 46, 197, 236, 46, 197, 236, 49, 208, 236, 49, 208, 236, 52, 217, 235, 52, 217, 235, 54, 227, 232, 54, 227, 232, 57, 227, 230, 57, 227, 230, 58, 226, 227, 58, 226, 227, 62, 224, 225, 62, 224, 225, 64, 222, 222, 64, 222, 222, 66, 220, 220, 66, 220, 220, 67, 215, 215, 67, 215, 215, 69, 209, 210, 69, 209, 210, 73, 205, 204, 73, 205, 204, 76, 198, 199, 76, 198, 199, 79, 193, 192, 79, 193, 192, 81, 187, 187, 81, 187, 187, 83, 181, 180, 83, 181, 180, 87, 175, 175, 87, 175, 175, 88, 170, 170, 88, 170, 170, 88, 164, 165, 88, 164, 165, 90, 158, 159, 90, 158, 159, 90, 152, 153, 90, 152, 153, 90, 146, 145, 90, 146, 145, 92, 140, 140, 92, 140, 140, 92, 134, 134, 92, 134, 134, 95, 129, 129, 95, 129, 129, 95, 123, 123, 95, 123, 123, 96, 117, 116, 96, 117, 116, 97, 111, 110, 97, 111, 110, 99, 105, 105, 99, 105, 105, 102, 102, 102, 102, 102, 102, 107, 101, 97, 107, 101, 97, 112, 101, 95, 112, 101, 95, 117, 101, 90, 117, 101, 90, 123, 102, 87, 123, 102, 87, 129, 101, 84, 129, 101, 84, 134, 101, 80, 134, 101, 80, 138, 102, 76, 138, 102, 76, 143, 101, 73, 143, 101, 73, 148, 101, 69, 148, 101, 69, 153, 101, 66, 153, 101, 66, 159, 102, 63, 159, 102, 63, 165, 102, 59, 165, 102, 59, 170, 101, 56, 170, 101, 56, 175, 101, 52, 175, 101, 52, 180, 101, 48, 180, 101, 48, 185, 100, 45, 185, 100, 45, 191, 100, 41, 191, 100, 41, 197, 101, 37, 197, 101, 37, 201, 101, 35, 201, 101, 35, 206, 101, 31, 206, 101, 31, 211, 101, 26, 211, 101, 26, 216, 101, 24, 216, 101, 24, 221, 101, 19, 221, 101, 19, 228, 101, 18, 228, 101, 18, 233, 101, 14, 233, 101, 14, 237, 101, 13, 237, 101, 13, 236, 105, 13, 236, 105, 13, 236, 112, 12, 236, 112, 12, 236, 120, 13, 236, 120, 13, 237, 123, 13, 237, 123, 13, 237, 130, 12, 237, 130, 12, 237, 137, 13, 237, 137, 13, 237, 142, 12, 237, 142, 12, 237, 149, 12, 237, 149, 12, 236, 156, 13, 236, 156, 13, 236, 160, 11, 236, 160, 11, 235, 167, 12, 235, 167, 12, 235, 173, 12, 235, 173, 12, 235, 179, 12, 235, 179, 12, 235, 185, 12, 235, 185, 12, 236, 191, 13, 236, 191, 13, 236, 196, 11, 236, 196, 11, 235, 202, 12, 235, 202, 12, 236, 204, 27, 236, 204, 27, 235, 207, 34, 235, 207, 34, 236, 208, 50, 236, 208, 50, 235, 211, 65, 235, 211, 65, 235, 212, 71, 235, 212, 71, 235, 214, 87, 235, 214, 87, 235, 216, 100, 235, 216, 100, 235, 216, 108, 235, 216, 108, 236, 220, 123, 236, 220, 123, 235, 221, 138, 235, 221, 138, 235, 221, 146, 235, 221, 146, 235, 225, 160, 235, 225, 160, 235, 225, 175, 235, 225, 175, 236, 227, 182, 236, 227, 182, 235, 229, 191, 235, 229, 191, 235, 230, 194, 235, 230, 194 };
+
+const byte colorMap_blackHot[] = { 235, 235, 235, 234, 234, 234, 233, 233, 233, 232, 232, 232, 231, 231, 231, 230, 230, 230, 229, 229, 229, 228, 228, 228, 227, 227, 227, 226, 226, 226, 225, 225, 225, 224, 224, 224, 223, 223, 223, 222, 222, 222, 221, 221, 221, 220, 220, 220, 219, 219, 219, 218, 218, 218, 217, 217, 217, 216, 216, 216, 215, 215, 215, 214, 214, 214, 213, 213, 213, 212, 212, 212, 211, 211, 211, 210, 210, 210, 209, 209, 209, 209, 209, 209, 208, 208, 208, 207, 207, 207, 206, 206, 206, 205, 205, 205, 204, 204, 204, 203, 203, 203, 202, 202, 202, 201, 201, 201, 200, 200, 200, 199, 199, 199, 198, 198, 198, 197, 197, 197, 196, 196, 196, 195, 195, 195, 194, 194, 194, 193, 193, 193, 192, 192, 192, 191, 191, 191, 190, 190, 190, 189, 189, 189, 188, 188, 188, 187, 187, 187, 186, 186, 186, 185, 185, 185, 184, 184, 184, 183, 183, 183, 182, 182, 182, 181, 181, 181, 180, 180, 180, 179, 179, 179, 178, 178, 178, 177, 177, 177, 176, 176, 176, 175, 175, 175, 174, 174, 174, 173, 173, 173, 172, 172, 172, 171, 171, 171, 170, 170, 170, 169, 169, 169, 168, 168, 168, 167, 167, 167, 166, 166, 166, 165, 165, 165, 164, 164, 164, 163, 163, 163, 162, 162, 162, 161, 161, 161, 160, 160, 160, 159, 159, 159, 158, 158, 158, 157, 157, 157, 156, 156, 156, 155, 155, 155, 154, 154, 154, 154, 154, 154, 153, 153, 153, 152, 152, 152, 151, 151, 151, 150, 150, 150, 149, 149, 149, 148, 148, 148, 147, 147, 147, 146, 146, 146, 145, 145, 145, 144, 144, 144, 143, 143, 143, 142, 142, 142, 141, 141, 141, 140, 140, 140, 139, 139, 139, 138, 138, 138, 137, 137, 137, 136, 136, 136, 135, 135, 135, 134, 134, 134, 133, 133, 133, 132, 132, 132, 131, 131, 131, 130, 130, 130, 129, 129, 129, 128, 128, 128, 127, 127, 127, 126, 126, 126, 125, 125, 125, 124, 124, 124, 123, 123, 123, 122, 122, 122, 121, 121, 121, 120, 120, 120, 119, 119, 119, 118, 118, 118, 117, 117, 117, 116, 116, 116, 115, 115, 115, 114, 114, 114, 113, 113, 113, 112, 112, 112, 111, 111, 111, 110, 110, 110, 109, 109, 109, 108, 108, 108, 107, 107, 107, 106, 106, 106, 105, 105, 105, 104, 104, 104, 103, 103, 103, 102, 102, 102, 101, 101, 101, 100, 100, 100, 99, 99, 99, 99, 99, 99, 98, 98, 98, 97, 97, 97, 96, 96, 96, 95, 95, 95, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 89, 89, 88, 88, 88, 87, 87, 87, 86, 86, 86, 85, 85, 85, 84, 84, 84, 83, 83, 83, 82, 82, 82, 81, 81, 81, 80, 80, 80, 79, 79, 79, 78, 78, 78, 77, 77, 77, 76, 76, 76, 75, 75, 75, 74, 74, 74, 73, 73, 73, 72, 72, 72, 71, 71, 71, 70, 70, 70, 69, 69, 69, 68, 68, 68, 67, 67, 67, 66, 66, 66, 65, 65, 65, 64, 64, 64, 63, 63, 63, 62, 62, 62, 61, 61, 61, 60, 60, 60, 59, 59, 59, 58, 58, 58, 57, 57, 57, 56, 56, 56, 55, 55, 55, 54, 54, 54, 53, 53, 53, 52, 52, 52, 51, 51, 51, 50, 50, 50, 49, 49, 49, 48, 48, 48, 47, 47, 47, 46, 46, 46, 45, 45, 45, 44, 44, 44, 44, 44, 44, 43, 43, 43, 42, 42, 42, 41, 41, 41, 40, 40, 40, 39, 39, 39, 38, 38, 38, 37, 37, 37, 36, 36, 36, 35, 35, 35, 34, 34, 34, 33, 33, 33, 32, 32, 32, 31, 31, 31, 30, 30, 30, 29, 29, 29, 28, 28, 28, 27, 27, 27, 26, 26, 26, 25, 25, 25, 24, 24, 24, 23, 23, 23, 22, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16 };
+
+const byte colorMap_blueRed[] = { 19, 64, 206, 18, 65, 209, 18, 67, 210, 19, 69, 212, 18, 71, 215, 19, 73, 217, 18, 75, 218, 18, 77, 219, 19, 79, 223, 19, 82, 225, 19, 84, 226, 18, 85, 227, 19, 88, 229, 21, 90, 229, 22, 93, 231, 21, 95, 230, 22, 98, 232, 22, 101, 232, 22, 103, 232, 23, 106, 234, 23, 109, 234, 24, 112, 236, 23, 114, 235, 25, 116, 235, 25, 119, 237, 27, 122, 238, 26, 124, 237, 27, 125, 236, 27, 127, 235, 27, 130, 236, 29, 133, 234, 30, 136, 234, 31, 139, 233, 32, 141, 232, 33, 145, 231, 33, 147, 231, 33, 150, 231, 34, 154, 229, 36, 156, 228, 36, 158, 227, 36, 162, 225, 38, 165, 224, 40, 167, 222, 41, 171, 221, 43, 174, 217, 45, 176, 216, 44, 178, 215, 46, 181, 212, 48, 184, 210, 49, 188, 209, 51, 190, 207, 53, 193, 206, 54, 195, 201, 56, 198, 200, 58, 200, 198, 59, 202, 196, 61, 205, 192, 63, 206, 190, 64, 208, 187, 68, 210, 184, 69, 212, 180, 71, 215, 178, 73, 216, 176, 74, 217, 173, 78, 220, 170, 79, 222, 165, 82, 224, 164, 83, 225, 161, 85, 227, 157, 88, 228, 154, 92, 228, 152, 94, 229, 149, 96, 230, 147, 99, 231, 144, 102, 230, 141, 104, 231, 136, 106, 232, 134, 109, 233, 131, 113, 234, 129, 114, 234, 125, 116, 235, 123, 119, 236, 120, 122, 235, 117, 126, 233, 113, 128, 234, 112, 131, 233, 109, 134, 232, 107, 137, 231, 103, 139, 230, 102, 143, 231, 99, 146, 230, 96, 149, 229, 94, 152, 228, 90, 154, 227, 88, 156, 227, 87, 157, 226, 85, 161, 224, 83, 164, 223, 81, 166, 221, 79, 169, 220, 77, 172, 217, 74, 175, 216, 74, 178, 213, 70, 181, 212, 70, 183, 210, 67, 186, 207, 64, 189, 206, 62, 192, 205, 60, 194, 201, 58, 197, 200, 57, 200, 197, 54, 202, 195, 53, 205, 191, 52, 207, 189, 51, 208, 187, 48, 209, 183, 48, 212, 180, 45, 214, 178, 44, 216, 175, 43, 218, 173, 42, 220, 169, 40, 222, 166, 39, 224, 164, 38, 225, 162, 35, 228, 157, 35, 227, 153, 34, 228, 149, 32, 230, 147, 33, 232, 144, 32, 231, 141, 31, 232, 138, 29, 232, 136, 28, 233, 132, 28, 235, 130, 27, 234, 127, 27, 235, 123, 25, 237, 120, 26, 235, 118, 24, 234, 115, 24, 235, 113, 24, 234, 110, 24, 234, 108, 22, 232, 105, 22, 231, 102, 22, 231, 100, 21, 231, 97, 20, 230, 94, 20, 228, 92, 20, 228, 89, 18, 228, 87, 19, 227, 84, 18, 224, 82, 18, 223, 81, 19, 222, 78, 19, 219, 76, 19, 217, 74, 17, 215, 72, 18, 214, 71, 17, 211, 69, 17, 210, 66, 17, 207, 64, 16, 206, 63, 17, 205, 62, 18, 203, 60, 16, 202, 58, 17, 198, 57, 17, 196, 54, 16, 194, 54, 17, 190, 53, 15, 188, 50, 15, 185, 50, 16, 183, 48, 15, 179, 46, 15, 177, 46, 16, 175, 43, 16, 171, 42, 15, 169, 41, 14, 166, 40, 14, 164, 37, 14, 160, 38, 15, 157, 37, 16, 154, 35, 15, 152, 35, 16, 149, 34, 15, 147, 34, 16, 142, 33, 16, 140, 33, 15, 139, 31, 15, 134, 30, 15, 131, 30, 14, 128, 28, 14, 126, 28, 15 };
+
+const byte colorMap_coldest[] = { 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239,15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 15, 15, 239, 45, 45, 45, 46, 46, 46, 47, 47, 47, 48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 51, 51, 52, 52, 52, 53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57, 58, 58, 58, 59, 59, 59, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 68, 69, 69, 69, 70, 70, 70, 71, 71, 71, 72, 72, 72, 73, 73, 73, 74, 74, 74, 75, 75, 75, 76, 76, 76, 77, 77, 77, 78, 78, 78, 79, 79, 79, 80, 80, 80, 81, 81, 81, 82, 82, 82, 83, 83, 83, 84, 84, 84, 85, 85, 85, 86, 86, 86, 87, 87, 87, 88, 88, 88, 89, 89, 89, 90, 90, 90, 91, 91, 91, 92, 92, 92, 93, 93, 93, 94, 94, 94, 95, 95, 95, 96, 96, 96, 97, 97, 97, 98, 98, 98, 99, 99, 99, 99, 99, 99, 100, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 103, 104, 104, 104, 105, 105, 105, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 110, 110, 110, 111, 111, 111, 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 119, 119, 119, 120, 120, 120, 121, 121, 121, 122, 122, 122, 123, 123, 123, 124, 124, 124, 125, 125, 125, 126, 126, 126, 127, 127, 127, 128, 128, 128, 129, 129, 129, 130, 130, 130, 131, 131, 131, 132, 132, 132, 133, 133, 133, 134, 134, 134, 135, 135, 135, 136, 136, 136, 137, 137, 137, 138, 138, 138, 139, 139, 139, 140, 140, 140, 141, 141, 141, 142, 142, 142, 143, 143, 143, 144, 144, 144, 145, 145, 145, 146, 146, 146, 147, 147, 147, 148, 148, 148, 149, 149, 149, 150, 150, 150, 151, 151, 151, 152, 152, 152, 153, 153, 153, 154, 154, 154, 154, 154, 154, 155, 155, 155, 156, 156, 156, 157, 157, 157, 158, 158, 158, 159, 159, 159, 160, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 164, 164, 164, 165, 165, 165, 166, 166, 166, 167, 167, 167, 168, 168, 168, 169, 169, 169, 170, 170, 170, 171, 171, 171, 172, 172, 172, 173, 173, 173, 174, 174, 174, 175, 175, 175, 176, 176, 176, 177, 177, 177, 178, 178, 178, 179, 179, 179, 180, 180, 180, 181, 181, 181, 182, 182, 182, 183, 183, 183, 184, 184, 184, 185, 185, 185, 186, 186, 186, 187, 187, 187, 188, 188, 188, 189, 189, 189, 190, 190, 190, 191, 191, 191, 192, 192, 192, 193, 193, 193, 194, 194, 194, 195, 195, 195, 196, 196, 196, 197, 197, 197, 198, 198, 198, 199, 199, 199, 200, 200, 200, 201, 201, 201, 202, 202, 202, 203, 203, 203, 204, 204, 204, 205, 205, 205, 206, 206, 206, 207, 207, 207, 208, 208, 208, 209, 209, 209, 209, 209, 209, 210, 210, 210, 211, 211, 211, 212, 212, 212, 213, 213, 213, 214, 214, 214, 215, 215, 215, 216, 216, 216, 217, 217, 217, 218, 218, 218, 219, 219, 219, 220, 220, 220, 221, 221, 221, 222, 222, 222, 223, 223, 223, 224, 224, 224, 225, 225, 225, 226, 226, 226, 227, 227, 227, 228, 228, 228, 229, 229, 229, 230, 230, 230, 231, 231, 231, 232, 232, 232, 233, 233, 233, 234, 234, 234, 235, 235, 235 };
+
+const byte colorMap_contrast[] = { 16, 16, 16, 23, 16, 22, 30, 15, 30, 37, 16, 37, 46, 15, 45, 53, 15, 52, 60, 15, 60, 67, 15, 67, 75, 15, 75, 82, 15, 81, 89, 15, 90, 98, 14, 96, 105, 14, 105, 112, 14, 111, 120, 15, 121, 127, 15, 127, 135, 15, 135, 143, 14, 142, 150, 14, 150, 158, 14, 157, 165, 14, 165, 172, 14, 172, 179, 14, 180, 186, 14, 187, 195, 14, 195, 202, 14, 201, 209, 14, 210, 217, 14, 216, 209, 15, 214, 202, 14, 211, 194, 15, 209, 187, 14, 206, 179, 15, 204, 172, 14, 201, 165, 15, 199, 157, 14, 196, 150, 15, 194, 141, 14, 191, 135, 15, 189, 126, 14, 186, 120, 15, 184, 112, 14, 181, 105, 15, 179, 97, 14, 176, 91, 15, 174, 82, 14, 171, 74, 15, 169, 67, 14, 166, 60, 15, 164, 52, 14, 161, 45, 15, 159, 38, 14, 156, 30, 15, 154, 23, 14, 151, 15, 15, 149, 16, 23, 152, 14, 30, 155, 15, 38, 156, 15, 44, 158, 14, 53, 162, 14, 59, 164, 15, 67, 165, 13, 74, 168, 14, 82, 171, 15, 89, 174, 13, 96, 176, 14, 104, 178, 14, 111, 180, 13, 119, 183, 13, 125, 185, 14, 133, 187, 12, 140, 189, 13, 148, 192, 14, 155, 195, 12, 162, 198, 13, 170, 199, 13, 177, 201, 12, 185, 205, 12, 191, 207, 13, 199, 208, 11, 206, 211, 12, 214, 214, 12, 208, 206, 12, 205, 200, 12, 199, 192, 12, 194, 185, 12, 190, 176, 12, 185, 169, 14, 181, 162, 12, 176, 155, 13, 170, 147, 14, 166, 141, 13, 161, 133, 13, 156, 125, 14, 151, 119, 13, 147, 110, 14, 142, 103, 14, 137, 96, 13, 132, 88, 14, 128, 81, 14, 122, 74, 13, 118, 66, 14, 113, 60, 15, 108, 52, 14, 104, 44, 15, 99, 36, 15, 93, 29, 15, 90, 22, 15, 84, 15, 23, 89, 14, 28, 93, 13, 36, 97, 15, 42, 103, 14, 49, 106, 13, 55, 112, 13, 63, 116, 12, 69, 120, 13, 76, 125, 12, 84, 129, 12, 90, 134, 11, 97, 138, 10, 104, 143, 12, 111, 147, 11, 117, 152, 10, 124, 156, 9, 130, 161, 10, 138, 165, 10, 144, 170, 9, 151, 174, 9, 159, 179, 8, 165, 183, 9, 172, 187, 8, 179, 193, 8, 186, 196, 7, 192, 202, 6, 200, 206, 8, 205, 210, 7, 213, 215, 6, 209, 208, 7, 207, 201, 7, 204, 194, 7, 200, 187, 7, 196, 180, 8, 194, 173, 8, 191, 166, 8, 187, 159, 9, 183, 153, 9, 181, 145, 9, 178, 139, 10, 174, 132, 10, 172, 124, 10, 168, 118, 11, 166, 112, 10, 162, 105, 10, 160, 98, 11, 156, 91, 11, 153, 84, 11, 150, 77, 12, 147, 70, 12, 143, 63, 12, 140, 57, 13, 137, 49, 13, 134, 43, 13, 130, 36, 14, 127, 29, 14, 124, 22, 14, 121, 15, 15, 124, 16, 17, 128, 17, 19, 130, 20, 19, 133, 21, 21, 135, 21, 22, 139, 23, 24, 141, 25, 24, 144, 26, 26, 148, 28, 28, 151, 29, 30, 153, 31, 30, 156, 32, 32, 160, 34, 34, 163, 35, 36, 164, 36, 36, 168, 38, 38, 171, 39, 40, 174, 40, 42, 176, 43, 42, 180, 44, 44, 183, 45, 46, 187, 46, 48, 189, 49, 48, 191, 49, 49, 194, 50, 51, 198, 52, 53, 200, 54, 53, 203, 55, 55, 204, 60, 61, 205, 67, 68, 206, 73, 72, 207, 79, 79, 208, 84, 84, 209, 91, 91, 210, 96, 97, 211, 103, 104, 212, 109, 108, 213, 115, 114, 214, 120, 120, 215, 127, 127, 216, 132, 133, 217, 139, 139, 218, 145, 143, 219, 151, 150, 220, 156, 156, 221, 163, 163, 222, 168, 169, 223, 175, 175, 224, 181, 179, 225, 187, 186, 226, 192, 192, 227, 199, 199, 228, 204, 204, 229, 211, 211, 230, 217, 215, 231, 223, 222, 232, 228, 228 };
+
+const byte colorMap_doubleRainbow[] = { 18, 15, 18, 25, 17, 26, 34, 18, 32, 43, 19, 39, 52, 21, 48, 60, 23, 55, 69, 25, 62, 77, 26, 70, 86, 28, 75, 95, 30, 84, 103, 31, 91, 112, 34, 98, 120, 35, 106, 129, 36, 111, 138, 39, 120, 146, 40, 128, 155, 42, 136, 150, 44, 140, 145, 47, 146, 139, 51, 151, 134, 54, 157, 130, 57, 161, 124, 60, 168, 119, 63, 172, 115, 66, 179, 109, 70, 183, 104, 73, 189, 99, 76, 194, 93, 80, 200, 89, 83, 205, 84, 86, 211, 78, 90, 216, 73, 92, 222, 69, 96, 227, 63, 99, 233, 59, 103, 238, 57, 104, 230, 54, 107, 221, 50, 109, 213, 50, 113, 206, 46, 115, 196, 45, 117, 189, 42, 120, 180, 39, 123, 171, 38, 125, 164, 35, 127, 154, 32, 130, 147, 30, 133, 138, 28, 135, 129, 25, 138, 122, 24, 140, 113, 21, 144, 104, 20, 146, 97, 16, 148, 87, 14, 152, 81, 27, 153, 75, 41, 157, 70, 54, 160, 64, 69, 164, 60, 84, 166, 54, 98, 170, 49, 110, 173, 44, 123, 176, 38, 138, 180, 34, 151, 182, 28, 166, 186, 23, 179, 189, 18, 194, 193, 13, 194, 189, 13, 194, 186, 13, 193, 183, 14, 194, 180, 15, 194, 177, 15, 194, 174, 14, 193, 171, 14, 194, 169, 15, 193, 165, 15, 194, 161, 16, 194, 160, 15, 194, 156, 17, 194, 154, 18, 195, 150, 17, 194, 147, 17, 195, 145, 18, 195, 142, 18, 195, 138, 19, 194, 135, 19, 195, 133, 20, 195, 129, 20, 195, 126, 19, 195, 124, 22, 193, 118, 21, 191, 114, 24, 189, 109, 24, 188, 104, 27, 186, 100, 27, 185, 95, 29, 183, 91, 30, 181, 86, 32, 180, 82, 33, 178, 77, 35, 177, 73, 36, 176, 67, 38, 173, 63, 39, 172, 59, 41, 172, 54, 41, 169, 50, 44, 169, 45, 45, 170, 53, 60, 171, 61, 74, 174, 68, 90, 174, 76, 103, 177, 83, 119, 179, 92, 133, 181, 99, 149, 182, 107, 162, 185, 114, 178, 186, 123, 192, 187, 131, 208, 190, 139, 222, 193, 146, 238, 194, 149, 236, 195, 153, 238, 197, 158, 237, 199, 160, 237, 200, 165, 237, 203, 168, 236, 193, 169, 235, 185, 168, 232, 176, 168, 229, 166, 168, 228, 157, 168, 225, 149, 168, 222, 140, 170, 220, 131, 169, 218, 121, 170, 215, 113, 170, 212, 103, 170, 211, 94, 170, 208, 86, 171, 206, 76, 171, 203, 68, 171, 202, 59, 171, 199, 51, 170, 196, 41, 171, 195, 33, 172, 193, 23, 172, 190, 14, 172, 187, 18, 173, 181, 24, 174, 174, 30, 175, 166, 33, 176, 160, 39, 177, 152, 45, 178, 145, 49, 179, 139, 54, 180, 131, 60, 181, 126, 64, 182, 118, 69, 183, 110, 74, 183, 104, 79, 185, 97, 84, 186, 91, 88, 187, 83, 93, 187, 76, 99, 189, 71, 103, 190, 63, 107, 191, 57, 113, 192, 50, 118, 193, 42, 122, 194, 36, 127, 195, 28, 133, 195, 20, 139, 196, 15, 143, 199, 14, 148, 200, 15, 151, 202, 13, 155, 204, 13, 161, 206, 15, 164, 208, 13, 169, 209, 13, 173, 211, 14, 178, 213, 13, 182, 214, 13, 187, 216, 14, 192, 217, 13, 196, 219, 13, 201, 221, 13, 205, 223, 13, 210, 224, 13, 213, 226, 11, 217, 228, 13, 222, 229, 13, 226, 231, 11, 231, 233, 13, 236, 234, 13, 236, 229, 13, 236, 224, 16, 237, 219, 17, 236, 214, 20, 236, 209, 22, 236, 203, 22, 236, 198, 25, 237, 193, 28, 236, 188, 30, 236, 183, 31, 236, 177, 33, 236, 172, 34, 236, 167, 36, 236, 162, 39, 238, 156, 42, 237, 151, 42, 237, 146, 45, 237, 140, 47, 238, 136, 48, 238, 131, 51, 237, 125, 53, 235, 118, 52, 235, 113, 52, 234, 105, 52, 233, 99, 52, 232, 93, 52, 231, 86, 53, 229, 80, 52, 230, 73, 52, 228, 67, 53, 227, 61, 53, 226, 54, 52, 225, 48, 52, 227, 56, 61, 227, 64, 69, 227, 73, 77, 227, 80, 86, 227, 88, 93, 229, 96, 101, 228, 105, 109, 230, 113, 118, 230, 121, 126, 231, 130, 136, 231, 138, 142, 230, 146, 150, 231, 154, 158, 233, 162, 166, 233, 170, 175, 232, 175, 178, 232, 179, 183, 233, 184, 189, 233, 189, 194, 233, 195, 198, 233, 199, 202, 235, 204, 206, 235, 208, 213, 234, 213, 216, 235, 218, 222, 235, 222, 227, 234, 227, 230, 235, 232, 235 };
+
+const byte colorMap_grayRed[] = { 218, 186, 175, 216, 186, 174, 214, 186, 173, 213, 185, 172, 212, 184, 171, 209, 183, 170, 206, 182, 170, 205, 181, 169, 202, 180, 168, 202, 180, 168, 199, 179, 168, 197, 178, 167, 194, 178, 166, 193, 177, 166, 191, 177, 165, 186, 176, 165, 185, 175, 164, 182, 173, 162, 180, 174, 162, 177, 172, 162, 174, 172, 161, 172, 170, 159, 170, 170, 160, 168, 169, 159, 165, 169, 158, 162, 167, 157, 160, 168, 157, 157, 167, 155, 156, 166, 154, 153, 165, 155, 149, 164, 155, 146, 164, 154, 143, 163, 152, 140, 162, 153, 137, 161, 151, 136, 160, 150, 134, 159, 149, 131, 159, 150, 128, 157, 148, 126, 158, 148, 124, 156, 147, 122, 156, 146, 120, 155, 147, 117, 155, 146, 115, 154, 145, 110, 152, 144, 109, 152, 144, 106, 151, 142, 105, 150, 141, 101, 149, 141, 100, 149, 141, 99, 148, 140, 96, 148, 139, 93, 146, 138, 92, 147, 138, 91, 146, 137, 90, 145, 138, 86, 143, 136, 85, 142, 135, 83, 142, 134, 80, 142, 133, 77, 140, 133, 76, 139, 132, 75, 138, 131, 74, 137, 130, 72, 137, 129, 71, 136, 130, 69, 137, 128, 68, 136, 127, 67, 134, 128, 66, 133, 127, 65, 134, 127, 64, 133, 126, 63, 132, 125, 62, 131, 124, 61, 130, 123, 60, 129, 122, 59, 128, 121, 59, 128, 121, 58, 127, 120, 58, 125, 119, 58, 125, 119, 57, 124, 118, 58, 123, 117, 58, 123, 117, 58, 123, 117, 57, 122, 116, 56, 121, 115, 56, 121, 115, 57, 120, 115, 58, 117, 111, 58, 117, 111, 59, 116, 111, 59, 116, 111, 60, 114, 110, 60, 115, 108, 61, 114, 108, 61, 112, 107, 61, 112, 107, 63, 112, 107, 63, 112, 107, 63, 110, 104, 65, 109, 104, 66, 109, 104, 67, 108, 104, 69, 106, 102, 72, 107, 101, 72, 105, 100, 73, 104, 100, 75, 103, 100, 78, 102, 98, 77, 101, 97, 79, 102, 98, 82, 101, 96, 83, 100, 96, 85, 99, 96, 86, 99, 95, 89, 98, 93, 90, 97, 93, 92, 95, 92, 96, 94, 91, 97, 94, 91, 100, 93, 89, 103, 93, 90, 104, 93, 88, 107, 91, 88, 107, 90, 86, 111, 89, 87, 112, 89, 87, 114, 88, 85, 117, 87, 83, 120, 87, 84, 122, 86, 84, 125, 85, 82, 126, 84, 82, 130, 82, 81, 134, 82, 80, 135, 82, 78, 138, 81, 78, 140, 80, 78, 143, 80, 77, 145, 79, 77, 148, 78, 75, 150, 77, 75, 153, 77, 75, 154, 77, 73, 157, 75, 73, 159, 73, 72, 163, 73, 71, 164, 72, 71, 168, 70, 69, 171, 71, 69, 173, 70, 69, 176, 68, 67, 178, 68, 67, 180, 67, 65, 182, 66, 65, 184, 66, 66, 187, 65, 64, 188, 64, 64, 191, 63, 63, 193, 63, 63, 194, 62, 61, 197, 61, 61, 198, 60, 61, 202, 59, 57, 204, 58, 57, 205, 57, 57, 208, 58, 56, 209, 57, 56, 212, 56, 56, 213, 55, 55, 214, 54, 54, 216, 53, 52, 218, 52, 52, 219, 51, 52, 221, 51, 50, 222, 50, 50, 223, 49, 50, 225, 49, 48, 227, 47, 47, 228, 48, 48, 228, 46, 47, 229, 45, 46, 231, 45, 46, 231, 45, 46, 232, 44, 46, 233, 43, 43, 234, 42, 43, 234, 40, 42, 234, 40, 42, 236, 40, 42, 236, 38, 41, 236, 38, 39, 238, 37, 39, 236, 35, 37, 237, 35, 35, 237, 35, 35, 236, 34, 36, 238, 33, 34, 237, 32, 35, 238, 31, 35, 237, 31, 32, 236, 30, 31, 235, 29, 30, 235, 29, 30, 235, 29, 30, 234, 28, 29, 234, 26, 28, 233, 25, 27, 232, 24, 26, 232, 24, 26, 231, 23, 25, 231, 23, 25, 230, 22, 24, 232, 21, 24, 231, 20, 23, 230, 19, 22, 229, 18, 21, 230, 18, 21, 229, 17, 20, 229, 17, 20, 228, 16, 19, 227, 15, 18 };
+
+const byte colorMap_glowBow[] = { 16, 16, 16, 19, 17, 18, 22, 16, 16, 25, 17, 18, 28, 17, 19, 31, 17, 20, 34, 17, 19, 36, 18, 20, 39, 18, 19, 43, 19, 21, 45, 18, 21, 48, 20, 21, 52, 19, 22, 54, 20, 23, 58, 20, 23, 63, 21, 23, 68, 21, 25, 70, 21, 26, 73, 22, 27, 75, 22, 26, 79, 22, 27, 81, 22, 28, 84, 23, 27, 87, 22, 28, 91, 24, 30, 96, 23, 30, 102, 24, 33, 104, 25, 32, 108, 25, 33, 110, 25, 34, 117, 25, 34, 120, 27, 34, 122, 27, 35, 127, 28, 35, 129, 27, 35, 132, 29, 37, 135, 27, 37, 138, 29, 38, 141, 29, 39, 143, 29, 40, 147, 29, 41, 150, 31, 41, 152, 30, 41, 155, 29, 42, 158, 30, 41, 165, 31, 44, 167, 32, 43, 170, 32, 44, 175, 33, 45, 177, 33, 46, 178, 32, 46, 182, 32, 45, 186, 33, 47, 188, 34, 48, 190, 34, 47, 194, 34, 48, 195, 35, 49, 195, 35, 47, 197, 38, 48, 196, 39, 46, 198, 39, 45, 199, 41, 44, 200, 42, 43, 201, 43, 43, 200, 44, 41, 201, 45, 42, 203, 46, 41, 204, 47, 42, 204, 47, 40, 205, 49, 40, 205, 49, 38, 206, 52, 38, 207, 52, 36, 208, 53, 37, 209, 54, 36, 210, 55, 36, 210, 58, 35, 211, 59, 34, 212, 60, 33, 213, 60, 33, 214, 61, 33, 213, 62, 31, 215, 64, 33, 215, 64, 31, 216, 66, 30, 218, 66, 30, 218, 66, 30, 218, 68, 29, 219, 70, 28, 220, 69, 28, 221, 72, 26, 223, 73, 26, 222, 74, 24, 223, 75, 25, 224, 76, 24, 225, 78, 23, 225, 78, 22, 226, 79, 23, 227, 80, 22, 227, 81, 20, 228, 82, 21, 229, 83, 20, 230, 83, 18, 231, 86, 19, 231, 86, 17, 232, 87, 16, 233, 88, 17, 234, 90, 16, 235, 91, 14, 235, 91, 14, 236, 93, 13, 237, 94, 12, 236, 96, 13, 237, 97, 13, 237, 99, 14, 237, 101, 13, 236, 103, 12, 236, 105, 13, 237, 106, 12, 236, 108, 11, 236, 112, 12, 237, 113, 13, 236, 115, 12, 236, 117, 13, 235, 119, 12, 236, 122, 12, 237, 123, 13, 237, 125, 13, 236, 127, 12, 236, 129, 13, 237, 130, 12, 236, 132, 13, 236, 134, 12, 237, 135, 12, 237, 137, 13, 237, 142, 12, 236, 144, 13, 236, 146, 12, 237, 147, 13, 237, 149, 12, 236, 151, 13, 237, 152, 13, 237, 154, 12, 236, 156, 13, 236, 158, 12, 236, 160, 11, 235, 161, 12, 236, 163, 12, 236, 165, 13, 235, 167, 12, 236, 170, 12, 236, 172, 11, 235, 173, 12, 236, 176, 12, 235, 179, 12, 236, 180, 13, 236, 182, 12, 236, 184, 11, 237, 185, 12, 236, 187, 11, 236, 188, 12, 235, 190, 12, 236, 191, 13, 235, 194, 12, 236, 196, 11, 235, 199, 11, 236, 201, 11, 235, 202, 12, 235, 204, 14, 236, 204, 19, 236, 205, 23, 236, 204, 27, 235, 206, 30, 236, 206, 34, 236, 207, 37, 236, 207, 41, 235, 208, 45, 236, 208, 48, 236, 209, 52, 236, 209, 56, 235, 211, 65, 236, 212, 68, 235, 212, 71, 236, 212, 74, 234, 212, 78, 235, 213, 82, 235, 214, 87, 236, 214, 91, 236, 215, 94, 235, 217, 97, 235, 216, 100, 235, 217, 105, 235, 216, 108, 234, 218, 111, 235, 218, 116, 235, 219, 122, 235, 220, 127, 236, 220, 131, 235, 221, 134, 235, 221, 138, 235, 222, 142, 235, 221, 146, 234, 222, 148, 235, 223, 153, 235, 224, 157, 235, 225, 160, 236, 225, 165, 234, 225, 168, 235, 226, 171, 235, 225, 175, 236, 227, 182, 235, 228, 187, 234, 228, 190, 234, 229, 195, 235, 230, 197, 236, 230, 202, 234, 230, 205, 235, 231, 208, 235, 232, 213, 235, 231, 216, 234, 232, 219, 234, 234, 224, 235, 234, 228, 235, 235, 235 };
+
+const byte colorMap_grayscale[] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11,
+ 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23,
+ 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35,
+ 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46,
+ 47, 47, 47, 48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 51, 51, 52, 52, 52, 53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57, 58, 58,
+ 58, 59, 59, 59, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 68, 69, 69, 69, 70,
+ 70, 70, 71, 71, 71, 72, 72, 72, 73, 73, 73, 74, 74, 74, 75, 75, 75, 76, 76, 76, 77, 77, 77, 78, 78, 78, 79, 79, 79, 80, 80, 80, 81, 81, 81,
+ 82, 82, 82, 83, 83, 83, 84, 84, 84, 85, 85, 85, 86, 86, 86, 87, 87, 87, 88, 88, 88, 89, 89, 89, 90, 90, 90, 91, 91, 91, 92, 92, 92, 93, 93,
+ 93, 94, 94, 94, 95, 95, 95, 96, 96, 96, 97, 97, 97, 98, 98, 98, 99, 99, 99, 100, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 103, 104,
+ 104, 104, 105, 105, 105, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 110, 110, 110, 111, 111, 111, 112, 112, 112, 113, 113,
+ 113, 114, 114, 114, 115, 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 119, 119, 119, 120, 120, 120, 121, 121, 121, 122, 122, 122,
+ 123, 123, 123, 124, 124, 124, 125, 125, 125, 126, 126, 126, 127, 127, 127, 128, 128, 128, 129, 129, 129, 130, 130, 130, 131, 131, 131, 132,
+ 132, 132, 133, 133, 133, 134, 134, 134, 135, 135, 135, 136, 136, 136, 137, 137, 137, 138, 138, 138, 139, 139, 139, 140, 140, 140, 141, 141,
+ 141, 142, 142, 142, 143, 143, 143, 144, 144, 144, 145, 145, 145, 146, 146, 146, 147, 147, 147, 148, 148, 148, 149, 149, 149, 150, 150, 150,
+ 151, 151, 151, 152, 152, 152, 153, 153, 153, 154, 154, 154, 155, 155, 155, 156, 156, 156, 157, 157, 157, 158, 158, 158, 159, 159, 159, 160,
+ 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 164, 164, 164, 165, 165, 165, 166, 166, 166, 167, 167, 167, 168, 168, 168, 169, 169,
+ 169, 170, 170, 170, 171, 171, 171, 172, 172, 172, 173, 173, 173, 174, 174, 174, 175, 175, 175, 176, 176, 176, 177, 177, 177, 178, 178, 178,
+ 179, 179, 179, 180, 180, 180, 181, 181, 181, 182, 182, 182, 183, 183, 183, 184, 184, 184, 185, 185, 185, 186, 186, 186, 187, 187, 187, 188,
+ 188, 188, 189, 189, 189, 190, 190, 190, 191, 191, 191, 192, 192, 192, 193, 193, 193, 194, 194, 194, 195, 195, 195, 196, 196, 196, 197, 197,
+ 197, 198, 198, 198, 199, 199, 199, 200, 200, 200, 201, 201, 201, 202, 202, 202, 203, 203, 203, 204, 204, 204, 205, 205, 205, 206, 206, 206,
+ 207, 207, 207, 208, 208, 208, 209, 209, 209, 210, 210, 210, 211, 211, 211, 212, 212, 212, 213, 213, 213, 214, 214, 214, 215, 215, 215, 216,
+ 216, 216, 217, 217, 217, 218, 218, 218, 219, 219, 219, 220, 220, 220, 221, 221, 221, 222, 222, 222, 223, 223, 223, 224, 224, 224, 225, 225,
+ 225, 226, 226, 226, 227, 227, 227, 228, 228, 228, 229, 229, 229, 230, 230, 230, 231, 231, 231, 232, 232, 232, 233, 233, 233, 234, 234, 234,
+ 235, 235, 235, 236, 236, 236, 237, 237, 237, 238, 238, 238, 239, 239, 239, 240, 240, 240, 241, 241, 241, 242, 242, 242, 243, 243, 243, 244,
+ 244, 244, 245, 245, 245, 246, 246, 246, 247, 247, 247, 248, 248, 248, 249, 249, 249, 250, 250, 250, 251, 251, 251, 252, 252, 252, 253, 253,
+ 253, 254, 254, 254, 255, 255, 255 };
+
+const byte colorMap_hottest[] = { 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 44, 44, 44, 45, 45, 45, 46, 46, 46, 47, 47, 47, 48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 51, 51, 52, 52, 52, 53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57, 58, 58, 58, 59, 59, 59, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 68, 69, 69, 69, 70, 70, 70, 71, 71, 71, 72, 72, 72, 73, 73, 73, 74, 74, 74, 75, 75, 75, 76, 76, 76, 77, 77, 77, 78, 78, 78, 79, 79, 79, 80, 80, 80, 81, 81, 81, 82, 82, 82, 83, 83, 83, 84, 84, 84, 85, 85, 85, 86, 86, 86, 87, 87, 87, 88, 88, 88, 89, 89, 89, 90, 90, 90, 91, 91, 91, 92, 92, 92, 93, 93, 93, 94, 94, 94, 95, 95, 95, 96, 96, 96, 97, 97, 97, 98, 98, 98, 99, 99, 99, 99, 99, 99, 100, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 103, 104, 104, 104, 105, 105, 105, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 110, 110, 110, 111, 111, 111, 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 119, 119, 119, 120, 120, 120, 121, 121, 121, 122, 122, 122, 123, 123, 123, 124, 124, 124, 125, 125, 125, 126, 126, 126, 127, 127, 127, 128, 128, 128, 129, 129, 129, 130, 130, 130, 131, 131, 131, 132, 132, 132, 133, 133, 133, 134, 134, 134, 135, 135, 135, 136, 136, 136, 137, 137, 137, 138, 138, 138, 139, 139, 139, 140, 140, 140, 141, 141, 141, 142, 142, 142, 143, 143, 143, 144, 144, 144, 145, 145, 145, 146, 146, 146, 147, 147, 147, 148, 148, 148, 149, 149, 149, 150, 150, 150, 151, 151, 151, 152, 152, 152, 153, 153, 153, 154, 154, 154, 154, 154, 154, 155, 155, 155, 156, 156, 156, 157, 157, 157, 158, 158, 158, 159, 159, 159, 160, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 164, 164, 164, 165, 165, 165, 166, 166, 166, 167, 167, 167, 168, 168, 168, 169, 169, 169, 170, 170, 170, 171, 171, 171, 172, 172, 172, 173, 173, 173, 174, 174, 174, 175, 175, 175, 176, 176, 176, 177, 177, 177, 178, 178, 178, 179, 179, 179, 180, 180, 180, 181, 181, 181, 182, 182, 182, 183, 183, 183, 184, 184, 184, 185, 185, 185, 186, 186, 186, 187, 187, 187, 188, 188, 188, 189, 189, 189, 190, 190, 190, 191, 191, 191, 192, 192, 192, 193, 193, 193, 194, 194, 194, 195, 195, 195, 196, 196, 196, 197, 197, 197, 198, 198, 198, 199, 199, 199, 200, 200, 200, 201, 201, 201, 202, 202, 202, 203, 203, 203, 204, 204, 204, 205, 205, 205, 206, 206, 206, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13, 190, 14, 13 };
+
+const byte colorMap_ironblack[] = { 255, 255, 255, 253, 253, 253, 251, 251, 251, 249, 249, 249, 247, 247, 247, 245, 245, 245, 243, 243, 243, 241, 241,
+ 241, 239, 239, 239, 237, 237, 237, 235, 235, 235, 233, 233, 233, 231, 231, 231, 229, 229, 229, 227, 227, 227, 225, 225, 225, 223, 223, 223,
+ 221, 221, 221, 219, 219, 219, 217, 217, 217, 215, 215, 215, 213, 213, 213, 211, 211, 211, 209, 209, 209, 207, 207, 207, 205, 205, 205, 203,
+ 203, 203, 201, 201, 201, 199, 199, 199, 197, 197, 197, 195, 195, 195, 193, 193, 193, 191, 191, 191, 189, 189, 189, 187, 187, 187, 185, 185,
+ 185, 183, 183, 183, 181, 181, 181, 179, 179, 179, 177, 177, 177, 175, 175, 175, 173, 173, 173, 171, 171, 171, 169, 169, 169, 167, 167, 167,
+ 165, 165, 165, 163, 163, 163, 161, 161, 161, 159, 159, 159, 157, 157, 157, 155, 155, 155, 153, 153, 153, 151, 151, 151, 149, 149, 149, 147,
+ 147, 147, 145, 145, 145, 143, 143, 143, 141, 141, 141, 139, 139, 139, 137, 137, 137, 135, 135, 135, 133, 133, 133, 131, 131, 131, 129, 129,
+ 129, 126, 126, 126, 124, 124, 124, 122, 122, 122, 120, 120, 120, 118, 118, 118, 116, 116, 116, 114, 114, 114, 112, 112, 112, 110, 110, 110,
+ 108, 108, 108, 106, 106, 106, 104, 104, 104, 102, 102, 102, 100, 100, 100, 98, 98, 98, 96, 96, 96, 94, 94, 94, 92, 92, 92, 90, 90, 90, 88, 88,
+ 88, 86, 86, 86, 84, 84, 84, 82, 82, 82, 80, 80, 80, 78, 78, 78, 76, 76, 76, 74, 74, 74, 72, 72, 72, 70, 70, 70, 68, 68, 68, 66, 66, 66, 64,
+ 64, 64, 62, 62, 62, 60, 60, 60, 58, 58, 58, 56, 56, 56, 54, 54, 54, 52, 52, 52, 50, 50, 50, 48, 48, 48, 46, 46, 46, 44, 44, 44, 42, 42, 42,
+ 40, 40, 40, 38, 38, 38, 36, 36, 36, 34, 34, 34, 32, 32, 32, 30, 30, 30, 28, 28, 28, 26, 26, 26, 24, 24, 24, 22, 22, 22, 20, 20, 20, 18, 18,
+ 18, 16, 16, 16, 14, 14, 14, 12, 12, 12, 10, 10, 10, 8, 8, 8, 6, 6, 6, 4, 4, 4, 2, 2, 2, 0, 0, 0, 0, 0, 9, 2, 0, 16, 4, 0, 24, 6, 0, 31, 8, 0,
+ 38, 10, 0, 45, 12, 0, 53, 14, 0, 60, 17, 0, 67, 19, 0, 74, 21, 0, 82, 23, 0, 89, 25, 0, 96, 27, 0, 103, 29, 0, 111, 31, 0, 118, 36, 0, 120,
+ 41, 0, 121, 46, 0, 122, 51, 0, 123, 56, 0, 124, 61, 0, 125, 66, 0, 126, 71, 0, 127, 76, 1, 128, 81, 1, 129, 86, 1, 130, 91, 1, 131, 96, 1,
+ 132, 101, 1, 133, 106, 1, 134, 111, 1, 135, 116, 1, 136, 121, 1, 136, 125, 2, 137, 130, 2, 137, 135, 3, 137, 139, 3, 138, 144, 3, 138, 149, 4,
+ 138, 153, 4, 139, 158, 5, 139, 163, 5, 139, 167, 5, 140, 172, 6, 140, 177, 6, 140, 181, 7, 141, 186, 7, 141, 189, 10, 137, 191, 13, 132, 194,
+ 16, 127, 196, 19, 121, 198, 22, 116, 200, 25, 111, 203, 28, 106, 205, 31, 101, 207, 34, 95, 209, 37, 90, 212, 40, 85, 214, 43, 80, 216, 46,
+ 75, 218, 49, 69, 221, 52, 64, 223, 55, 59, 224, 57, 49, 225, 60, 47, 226, 64, 44, 227, 67, 42, 228, 71, 39, 229, 74, 37, 230, 78, 34, 231, 81,
+ 32, 231, 85, 29, 232, 88, 27, 233, 92, 24, 234, 95, 22, 235, 99, 19, 236, 102, 17, 237, 106, 14, 238, 109, 12, 239, 112, 12, 240, 116, 12,
+ 240, 119, 12, 241, 123, 12, 241, 127, 12, 242, 130, 12, 242, 134, 12, 243, 138, 12, 243, 141, 13, 244, 145, 13, 244, 149, 13, 245, 152, 13,
+ 245, 156, 13, 246, 160, 13, 246, 163, 13, 247, 167, 13, 247, 171, 13, 248, 175, 14, 248, 178, 15, 249, 182, 16, 249, 185, 18, 250, 189, 19,
+ 250, 192, 20, 251, 196, 21, 251, 199, 22, 252, 203, 23, 252, 206, 24, 253, 210, 25, 253, 213, 27, 254, 217, 28, 254, 220, 29, 255, 224, 30,
+ 255, 227, 39, 255, 229, 53, 255, 231, 67, 255, 233, 81, 255, 234, 95, 255, 236, 109, 255, 238, 123, 255, 240, 137, 255, 242, 151, 255, 244,
+ 165, 255, 246, 179, 255, 248, 193, 255, 249, 207, 255, 251, 221, 255, 253, 235, 255, 255, 24 };
+
+const byte colorMap_lava[] = { 16, 16, 16, 17, 19, 22, 19, 21, 30, 20, 24, 37, 22, 27, 43, 22, 31, 50, 24, 32, 57, 25, 37, 65, 26, 39, 70, 28, 43, 78, 29, 44, 85, 31, 47, 94, 32, 50, 100, 34, 53, 107, 34, 57, 113, 37, 59, 122, 37, 63, 128, 39, 66, 135, 40, 69, 141, 42, 71, 149, 44, 74, 156, 41, 76, 156, 41, 76, 156, 39, 78, 157, 36, 80, 155, 36, 82, 156, 34, 82, 156, 33, 85, 157, 31, 86, 157, 30, 86, 157, 29, 88, 156, 28, 91, 157, 26, 91, 157, 26, 93, 158, 23, 95, 158, 21, 97, 159, 20, 98, 159, 18, 99, 158, 17, 101, 160, 15, 102, 159, 15, 104, 160, 13, 105, 158, 13, 105, 158, 14, 106, 157, 13, 107, 157, 14, 108, 156, 14, 110, 156, 14, 111, 154, 15, 112, 155, 13, 113, 153, 13, 113, 151, 14, 114, 152, 14, 114, 151, 14, 116, 152, 14, 116, 150, 13, 118, 149, 13, 119, 147, 14, 120, 148, 13, 121, 146, 14, 122, 146, 14, 122, 146, 14, 124, 145, 14, 125, 143, 15, 126, 144, 14, 125, 143, 15, 126, 142, 13, 127, 142, 14, 128, 142, 14, 128, 140, 14, 130, 139, 14, 130, 139, 14, 130, 139, 14, 131, 137, 13, 133, 136, 13, 133, 135, 14, 134, 136, 13, 135, 134, 13, 135, 134, 13, 135, 134, 14, 137, 133, 14, 137, 131, 19, 133, 130, 24, 130, 132, 30, 125, 131, 35, 121, 130, 39, 118, 129, 46, 114, 129, 50, 109, 127, 56, 106, 127, 62, 101, 128, 67, 99, 126, 73, 94, 125, 78, 90, 126, 84, 85, 125, 89, 82, 124, 93, 78, 123, 99, 73, 122, 105, 70, 122, 109, 66, 121, 115, 62, 122, 120, 58, 121, 123, 57, 119, 124, 57, 115, 127, 56, 114, 130, 54, 112, 133, 54, 108, 134, 53, 108, 136, 51, 104, 137, 51, 102, 140, 50, 100, 144, 50, 98, 145, 50, 96, 148, 49, 94, 148, 47, 91, 151, 46, 90, 154, 45, 88, 155, 45, 84, 158, 44, 84, 161, 43, 81, 162, 42, 79, 165, 41, 77, 167, 41, 75, 168, 41, 74, 169, 40, 72, 171, 40, 72, 172, 39, 70, 174, 39, 67, 175, 38, 67, 176, 38, 65, 178, 38, 63, 180, 38, 62, 182, 38, 60, 183, 37, 60, 184, 37, 59, 186, 37, 57, 187, 36, 55, 189, 36, 53, 190, 35, 53, 191, 35, 52, 193, 34, 50, 194, 34, 48, 196, 36, 48, 199, 37, 48, 201, 39, 48, 203, 40, 47, 205, 41, 46, 207, 43, 48, 210, 43, 47, 212, 46, 48, 213, 47, 47, 215, 47, 46, 219, 49, 46, 220, 50, 46, 222, 53, 46, 224, 53, 47, 227, 55, 47, 228, 56, 46, 229, 57, 45, 233, 59, 46, 235, 60, 45, 237, 62, 45, 238, 63, 44, 237, 65, 41, 236, 67, 40, 237, 68, 39, 236, 70, 36, 237, 71, 35, 237, 73, 34, 238, 74, 33, 237, 77, 31, 237, 79, 30, 237, 79, 27, 237, 83, 25, 236, 84, 23, 237, 86, 21, 237, 88, 20, 237, 88, 16, 236, 90, 16, 237, 92, 15, 237, 94, 12, 237, 97, 13, 237, 99, 12, 236, 103, 12, 237, 106, 12, 236, 110, 12, 237, 113, 13, 237, 116, 13, 236, 120, 13, 237, 123, 13, 236, 127, 14, 237, 130, 14, 236, 132, 13, 236, 135, 13, 236, 139, 12, 235, 143, 12, 236, 146, 12, 237, 149, 12, 236, 153, 13, 235, 155, 12, 236, 158, 12, 237, 161, 12, 236, 163, 12, 236, 165, 13, 235, 167, 12, 236, 170, 12, 236, 172, 11, 235, 173, 12, 236, 176, 12, 235, 179, 12, 235, 181, 11, 236, 183, 13, 235, 185, 12, 235, 187, 11, 236, 189, 11, 236, 191, 13, 235, 194, 12, 236, 196, 11, 236, 199, 11, 236, 200, 12, 235, 202, 12, 236, 205, 23, 235, 207, 34, 235, 208, 45, 236, 209, 56, 235, 211, 67, 234, 212, 78, 236, 214, 90, 235, 216, 100, 234, 218, 111, 236, 220, 123, 234, 220, 133, 235, 221, 146, 235, 224, 157, 236, 225, 167, 235, 226, 179, 235, 229, 191, 235, 229, 201, 235, 232, 213, 235, 233, 224, 235, 235, 235 };
+
+const byte colorMap_medical[] = { 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 36, 36, 198, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 70, 71, 238, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 25, 172, 193, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 14, 158, 13, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 15, 15, 123, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 237, 65, 197, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 238, 28, 28, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 236, 152, 93, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 230, 125, 12, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37, 236, 196, 37 };
+
+const byte colorMap_rainbow[] = { 1, 3, 74, 0, 3, 74, 0, 3, 75, 0, 3, 75, 0, 3, 76, 0, 3, 76, 0, 3, 77, 0, 3, 79, 0, 3, 82, 0, 5, 85, 0, 7, 88, 0, 10,
+ 91, 0, 14, 94, 0, 19, 98, 0, 22, 100, 0, 25, 103, 0, 28, 106, 0, 32, 109, 0, 35, 112, 0, 38, 116, 0, 40, 119, 0, 42, 123, 0, 45, 128, 0, 49,
+ 133, 0, 50, 134, 0, 51, 136, 0, 52, 137, 0, 53, 139, 0, 54, 142, 0, 55, 144, 0, 56, 145, 0, 58, 149, 0, 61, 154, 0, 63, 156, 0, 65, 159, 0,
+ 66, 161, 0, 68, 164, 0, 69, 167, 0, 71, 170, 0, 73, 174, 0, 75, 179, 0, 76, 181, 0, 78, 184, 0, 79, 187, 0, 80, 188, 0, 81, 190, 0, 84, 194,
+ 0, 87, 198, 0, 88, 200, 0, 90, 203, 0, 92, 205, 0, 94, 207, 0, 94, 208, 0, 95, 209, 0, 96, 210, 0, 97, 211, 0, 99, 214, 0, 102, 217, 0, 103,
+ 218, 0, 104, 219, 0, 105, 220, 0, 107, 221, 0, 109, 223, 0, 111, 223, 0, 113, 223, 0, 115, 222, 0, 117, 221, 0, 118, 220, 1, 120, 219, 1, 122,
+ 217, 2, 124, 216, 2, 126, 214, 3, 129, 212, 3, 131, 207, 4, 132, 205, 4, 133, 202, 4, 134, 197, 5, 136, 192, 6, 138, 185, 7, 141, 178, 8, 142,
+ 172, 10, 144, 166, 10, 144, 162, 11, 145, 158, 12, 146, 153, 13, 147, 149, 15, 149, 140, 17, 151, 132, 22, 153, 120, 25, 154, 115, 28, 156,
+ 109, 34, 158, 101, 40, 160, 94, 45, 162, 86, 51, 164, 79, 59, 167, 69, 67, 171, 60, 72, 173, 54, 78, 175, 48, 83, 177, 43, 89, 179, 39, 93,
+ 181, 35, 98, 183, 31, 105, 185, 26, 109, 187, 23, 113, 188, 21, 118, 189, 19, 123, 191, 17, 128, 193, 14, 134, 195, 12, 138, 196, 10, 142,
+ 197, 8, 146, 198, 6, 151, 200, 5, 155, 201, 4, 160, 203, 3, 164, 204, 2, 169, 205, 2, 173, 206, 1, 175, 207, 1, 178, 207, 1, 184, 208, 0, 190,
+ 210, 0, 193, 211, 0, 196, 212, 0, 199, 212, 0, 202, 213, 1, 207, 214, 2, 212, 215, 3, 215, 214, 3, 218, 214, 3, 220, 213, 3, 222, 213, 4, 224,
+ 212, 4, 225, 212, 5, 226, 212, 5, 229, 211, 5, 232, 211, 6, 232, 211, 6, 233, 211, 6, 234, 210, 6, 235, 210, 7, 236, 209, 7, 237, 208, 8, 239,
+ 206, 8, 241, 204, 9, 242, 203, 9, 244, 202, 10, 244, 201, 10, 245, 200, 10, 245, 199, 11, 246, 198, 11, 247, 197, 12, 248, 194, 13, 249, 191,
+ 14, 250, 189, 14, 251, 187, 15, 251, 185, 16, 252, 183, 17, 252, 178, 18, 253, 174, 19, 253, 171, 19, 254, 168, 20, 254, 165, 21, 254, 164,
+ 21, 255, 163, 22, 255, 161, 22, 255, 159, 23, 255, 157, 23, 255, 155, 24, 255, 149, 25, 255, 143, 27, 255, 139, 28, 255, 135, 30, 255, 131,
+ 31, 255, 127, 32, 255, 118, 34, 255, 110, 36, 255, 104, 37, 255, 101, 38, 255, 99, 39, 255, 93, 40, 255, 88, 42, 254, 82, 43, 254, 77, 45,
+ 254, 69, 47, 254, 62, 49, 253, 57, 50, 253, 53, 52, 252, 49, 53, 252, 45, 55, 251, 39, 57, 251, 33, 59, 251, 32, 60, 251, 31, 60, 251, 30, 61,
+ 251, 29, 61, 251, 28, 62, 250, 27, 63, 250, 27, 65, 249, 26, 66, 249, 26, 68, 248, 25, 70, 248, 24, 73, 247, 24, 75, 247, 25, 77, 247, 25, 79,
+ 247, 26, 81, 247, 32, 83, 247, 35, 85, 247, 38, 86, 247, 42, 88, 247, 46, 90, 247, 50, 92, 248, 55, 94, 248, 59, 96, 248, 64, 98, 248, 72,
+ 101, 249, 81, 104, 249, 87, 106, 250, 93, 108, 250, 95, 109, 250, 98, 110, 250, 100, 111, 251, 101, 112, 251, 102, 113, 251, 109, 117, 252,
+ 116, 121, 252, 121, 123, 253, 126, 126, 253, 130, 128, 254, 135, 131, 254, 139, 133, 254, 144, 136, 254, 151, 140, 255, 158, 144, 255, 163,
+ 146, 255, 168, 149, 255, 173, 152, 255, 176, 153, 255, 178, 155, 255, 184, 160, 255, 191, 165, 255, 195, 168, 255, 199, 172, 255, 203, 175,
+ 255, 207, 179, 255, 211, 182, 255, 216, 185, 255, 218, 190, 255, 220, 196, 255, 222, 200, 255, 225, 202, 255, 227, 204, 255, 230, 206, 255,
+ 233, 208 };
+
+const byte colorMap_wheel1[] = { 238, 14, 239, 234, 17, 234, 229, 22, 230, 225, 27, 225, 221, 30, 220, 216, 35, 216, 211, 39, 212, 208, 44, 207, 203, 48, 202, 198, 52, 199, 195, 56, 195, 190, 61, 191, 185, 65, 185, 180, 70, 181, 177, 74, 177, 172, 79, 172, 167, 83, 167, 163, 87, 163, 159, 92, 158, 154, 97, 154, 150, 100, 151, 145, 105, 146, 141, 109, 142, 138, 114, 138, 132, 117, 132, 127, 122, 128, 124, 127, 124, 119, 131, 119, 114, 135, 114, 111, 140, 110, 106, 144, 105, 101, 149, 101, 97, 152, 98, 93, 157, 93, 88, 162, 89, 85, 166, 85, 79, 170, 79, 75, 175, 75, 71, 179, 71, 67, 184, 66, 61, 188, 61, 57, 193, 57, 53, 197, 52, 49, 201, 50, 43, 205, 45, 40, 209, 40, 35, 214, 36, 31, 219, 32, 27, 222, 26, 22, 227, 22, 17, 232, 18, 14, 236, 13, 14, 232, 18, 14, 227, 24, 14, 224, 27, 14, 218, 31, 13, 214, 36, 14, 209, 39, 13, 205, 44, 14, 200, 50, 13, 197, 53, 14, 192, 58, 14, 188, 61, 13, 184, 66, 14, 179, 71, 13, 176, 75, 14, 171, 80, 13, 167, 85, 14, 162, 88, 14, 158, 93, 14, 153, 98, 14, 150, 102, 15, 145, 107, 14, 141, 112, 15, 136, 115, 14, 132, 120, 15, 127, 125, 14, 124, 129, 15, 119, 134, 15, 115, 139, 15, 110, 142, 15, 106, 147, 16, 102, 151, 15, 98, 156, 16, 93, 161, 15, 89, 164, 16, 84, 169, 14, 79, 173, 15, 75, 177, 15, 71, 182, 15, 66, 187, 15, 62, 190, 14, 58, 195, 15, 53, 200, 14, 49, 204, 15, 45, 209, 15, 40, 214, 15, 36, 217, 15, 32, 222, 16, 27, 227, 15, 23, 231, 16, 19, 236, 15, 14, 241, 20, 18, 235, 25, 23, 232, 28, 28, 226, 32, 32, 222, 38, 36, 219, 42, 40, 213, 45, 45, 209, 51, 50, 204, 55, 53, 200, 58, 58, 196, 62, 62, 190, 68, 66, 187, 72, 70, 181, 75, 75, 177, 81, 79, 174, 85, 83, 168, 88, 88, 164, 93, 93, 159, 98, 96, 155, 102, 100, 151, 106, 106, 146, 111, 109, 142, 115, 113, 136, 119, 119, 133, 124, 122, 129, 128, 126, 123, 133, 131, 120, 136, 136, 116, 141, 140, 110, 145, 143, 106, 149, 149, 101, 154, 153, 97, 158, 156, 93, 163, 161, 88, 166, 166, 84, 171, 170, 78, 176, 174, 75, 179, 179, 71, 184, 183, 65, 189, 187, 62, 193, 191, 56, 196, 196, 52, 202, 200, 49, 206, 204, 43, 209, 209, 39, 215, 214, 34, 219, 217, 30, 223, 221, 26, 226, 226, 20, 232, 230, 17, 236, 234, 13, 231, 235, 15, 228, 235, 21, 223, 235, 25, 219, 234, 29, 214, 235, 34, 209, 235, 38, 206, 235, 43, 201, 235, 48, 197, 235, 52, 192, 235, 56, 188, 234, 61, 184, 235, 66, 180, 235, 70, 175, 235, 74, 169, 235, 79, 166, 235, 81, 161, 236, 87, 158, 235, 91, 152, 235, 95, 149, 235, 100, 143, 235, 104, 141, 235, 109, 135, 235, 114, 130, 235, 118, 126, 235, 122, 121, 235, 126, 118, 235, 132, 113, 235, 136, 109, 235, 140, 104, 235, 145, 100, 234, 149, 96, 236, 153, 91, 236, 157, 87, 235, 161, 82, 235, 166, 78, 235, 170, 74, 236, 175, 70, 235, 180, 65, 235, 184, 61, 235, 188, 57, 236, 193, 52, 236, 198, 48, 235, 202, 43, 235, 206, 39, 235, 211, 35, 236, 216, 31, 235, 220, 26, 236, 223, 22, 235, 227, 17, 235, 232, 14, 236, 237, 17, 231, 233, 21, 227, 228, 26, 222, 224, 31, 219, 219, 34, 214, 215, 39, 209, 210, 43, 205, 206, 49, 201, 202, 53, 196, 198, 56, 192, 192, 62, 188, 189, 66, 183, 186, 71, 179, 180, 74, 174, 176, 79, 171, 172, 84, 166, 168, 88, 161, 163, 94, 157, 160, 97, 153, 154, 101, 149, 150, 106, 144, 145, 110, 140, 142, 115, 135, 137, 119, 131, 133, 123, 127, 127, 129, 122, 125, 132, 118, 119, 136, 114, 115, 142, 110, 111, 146, 105, 107, 151, 100, 101, 154, 96, 98, 159, 93, 93, 164, 87, 89, 167, 83, 84, 172, 78, 80, 177, 75, 75, 181, 70, 72, 186, 66, 66, 190, 62, 63, 195, 57, 60, 199, 53, 54, 202, 48, 50, 208, 44, 46, 212, 40, 42, 217, 35, 36, 221, 30, 33, 225, 27, 28, 230, 22, 24, 234, 18, 19, 240, 14, 16 };
+
+const byte colorMap_wheel2[] = { 17, 14, 17, 16, 23, 17, 17, 32, 17, 16, 40, 16, 16, 49, 16, 15, 58, 16, 15, 65, 16, 14, 74, 16, 15, 82, 16, 15, 91, 15, 14, 100, 15, 15, 108, 15, 14, 117, 14, 15, 125, 16, 14, 134, 15, 14, 143, 15, 15, 151, 15, 14, 160, 14, 15, 168, 14, 14, 177, 14, 14, 186, 13, 13, 192, 14, 13, 201, 14, 14, 209, 13, 14, 219, 14, 13, 228, 14, 14, 236, 13, 22, 227, 22, 28, 219, 29, 37, 212, 37, 46, 204, 46, 52, 196, 53, 61, 188, 61, 69, 181, 69, 76, 172, 76, 85, 164, 85, 94, 156, 95, 102, 147, 102, 109, 140, 110, 117, 132, 117, 126, 123, 126, 133, 116, 134, 141, 108, 141, 149, 101, 149, 157, 93, 157, 165, 84, 165, 174, 76, 175, 183, 68, 183, 189, 60, 190, 198, 52, 198, 205, 45, 205, 213, 36, 214, 222, 29, 222, 228, 21, 229, 238, 14, 239, 233, 17, 238, 229, 22, 238, 223, 27, 239, 218, 31, 238, 213, 37, 238, 209, 41, 238, 204, 45, 239, 199, 51, 239, 195, 55, 238, 191, 60, 238, 185, 65, 237, 180, 69, 238, 177, 74, 239, 171, 79, 238, 167, 84, 238, 161, 89, 239, 157, 93, 238, 153, 98, 239, 147, 101, 237, 142, 107, 237, 138, 111, 238, 133, 115, 237, 128, 121, 238, 123, 125, 237, 118, 131, 237, 114, 135, 238, 109, 139, 237, 104, 145, 237, 100, 149, 238, 96, 154, 239, 91, 159, 238, 85, 163, 237, 82, 169, 237, 76, 173, 238, 71, 177, 238, 67, 182, 237, 61, 187, 236, 57, 192, 236, 52, 196, 237, 47, 201, 237, 43, 206, 237, 37, 210, 238, 33, 215, 238, 29, 220, 237, 23, 226, 237, 19, 230, 237, 15, 235, 237, 19, 229, 232, 24, 226, 228, 28, 221, 224, 33, 216, 218, 36, 212, 214, 42, 208, 210, 46, 203, 206, 49, 199, 201, 54, 194, 197, 59, 191, 192, 64, 185, 188, 68, 181, 183, 73, 176, 179, 76, 172, 175, 81, 168, 171, 86, 163, 167, 91, 158, 162, 95, 155, 157, 100, 150, 153, 104, 146, 148, 108, 141, 144, 114, 137, 139, 117, 133, 136, 121, 129, 130, 126, 123, 126, 131, 118, 123, 136, 115, 118, 139, 111, 114, 144, 106, 109, 148, 101, 105, 154, 97, 100, 157, 93, 97, 161, 89, 91, 167, 85, 86, 172, 79, 83, 176, 75, 77, 179, 71, 73, 184, 66, 70, 189, 61, 64, 194, 57, 61, 197, 53, 56, 202, 48, 52, 207, 45, 47, 212, 39, 44, 216, 35, 38, 219, 31, 34, 225, 27, 30, 229, 22, 26, 234, 17, 20, 239, 14, 18, 233, 14, 22, 230, 13, 26, 224, 14, 31, 219, 14, 35, 214, 14, 39, 210, 13, 45, 206, 14, 49, 201, 14, 55, 195, 14, 59, 190, 14, 64, 186, 14, 68, 181, 14, 72, 176, 14, 77, 173, 14, 84, 168, 14, 88, 163, 14, 92, 158, 14, 97, 152, 14, 101, 147, 14, 107, 143, 14, 111, 139, 15, 117, 133, 14, 120, 130, 14, 125, 125, 14, 131, 120, 14, 136, 115, 14, 140, 109, 14, 144, 106, 14, 149, 100, 13, 155, 96, 15, 158, 91, 15, 164, 87, 14, 169, 82, 14, 173, 77, 14, 177, 72, 14, 182, 66, 14, 186, 64, 14, 193, 58, 15, 197, 53, 15, 202, 48, 15, 206, 44, 14, 210, 39, 14, 216, 34, 14, 221, 30, 13, 225, 24, 15, 230, 20, 15, 235, 15, 14, 241, 20, 18, 237, 23, 21, 232, 27, 26, 228, 30, 29, 223, 36, 33, 220, 38, 37, 215, 42, 41, 211, 45, 45, 207, 50, 49, 203, 54, 52, 199, 58, 56, 195, 61, 60, 192, 66, 64, 188, 69, 68, 184, 73, 72, 180, 78, 75, 176, 82, 79, 172, 84, 82, 167, 89, 87, 164, 91, 90, 159, 97, 95, 156, 100, 98, 151, 104, 103, 147, 108, 105, 144, 112, 109, 140, 115, 113, 136, 120, 117, 132, 124, 121, 128, 127, 125, 124, 131, 129, 120, 134, 133, 116, 139, 137, 111, 143, 140, 107, 148, 144, 105, 151, 148, 101, 155, 152, 97, 158, 156, 93, 162, 160, 89, 167, 164, 85, 169, 167, 80, 173, 171, 75, 176, 175, 71, 181, 179, 67, 185, 182, 63, 189, 186, 61, 192, 190, 57, 197, 194, 53, 200, 198, 49, 204, 202, 45, 209, 205, 40, 213, 209, 36, 216, 213, 32, 220, 217, 28, 223, 221, 24, 228, 225, 20, 232, 229, 16, 235, 233, 14 };
+
+const byte colorMap_wheel3[] = { 17, 14, 17, 20, 14, 26, 26, 15, 36, 30, 14, 46, 35, 15, 56, 39, 15, 65, 45, 15, 75, 49, 14, 84, 55, 14, 94, 60, 15, 104, 64, 14, 113, 70, 14, 123, 74, 14, 132, 79, 15, 142, 83, 14, 152, 89, 15, 162, 93, 14, 171, 98, 15, 181, 103, 14, 190, 108, 14, 200, 112, 14, 209, 118, 14, 219, 122, 13, 228, 128, 13, 240, 122, 22, 228, 115, 33, 218, 111, 41, 211, 107, 50, 201, 102, 60, 190, 96, 70, 181, 91, 80, 170, 87, 89, 160, 81, 99, 151, 76, 109, 140, 70, 119, 130, 66, 130, 120, 63, 137, 113, 58, 148, 101, 54, 158, 93, 47, 167, 83, 44, 177, 72, 39, 187, 63, 35, 196, 54, 29, 206, 42, 24, 216, 33, 19, 225, 24, 15, 235, 12, 24, 225, 23, 34, 215, 34, 43, 206, 43, 52, 196, 51, 63, 187, 63, 72, 177, 71, 82, 166, 82, 93, 157, 92, 102, 148, 100, 111, 137, 111, 121, 129, 120, 131, 119, 131, 141, 110, 140, 150, 100, 151, 159, 90, 159, 169, 81, 171, 179, 71, 179, 188, 61, 188, 199, 51, 199, 209, 42, 208, 218, 31, 218, 228, 23, 228, 238, 14, 239, 227, 22, 235, 218, 33, 227, 208, 40, 225, 200, 51, 219, 189, 60, 214, 179, 71, 207, 170, 79, 204, 161, 89, 201, 150, 99, 192, 140, 109, 191, 130, 118, 186, 120, 128, 179, 111, 137, 174, 100, 147, 169, 91, 156, 164, 81, 166, 159, 71, 175, 152, 61, 185, 147, 53, 195, 143, 42, 205, 138, 32, 216, 134, 23, 225, 129, 13, 236, 125, 25, 225, 125, 34, 215, 126, 42, 206, 124, 52, 195, 125, 63, 187, 125, 72, 177, 125, 82, 166, 126, 92, 158, 126, 102, 148, 126, 112, 138, 125, 120, 128, 126, 131, 120, 125, 140, 109, 126, 150, 100, 125, 159, 90, 125, 170, 80, 127, 180, 71, 125, 189, 61, 126, 198, 53, 126, 208, 42, 126, 218, 33, 125, 227, 23, 126, 238, 14, 125, 228, 23, 130, 219, 32, 135, 208, 42, 140, 199, 52, 145, 189, 61, 150, 178, 71, 153, 169, 80, 158, 158, 90, 163, 149, 100, 169, 140, 109, 173, 130, 118, 178, 119, 128, 181, 110, 138, 189, 101, 147, 192, 90, 157, 196, 80, 166, 201, 71, 176, 207, 60, 186, 212, 51, 195, 217, 41, 205, 220, 31, 216, 225, 21, 224, 234, 15, 235, 237, 23, 225, 227, 33, 214, 217, 43, 204, 208, 53, 195, 197, 63, 184, 187, 72, 175, 178, 83, 166, 168, 91, 157, 159, 101, 146, 151, 111, 136, 142, 120, 127, 131, 130, 117, 122, 140, 109, 113, 150, 99, 102, 160, 89, 93, 168, 80, 83, 178, 70, 72, 189, 61, 64, 198, 52, 53, 210, 41, 46, 218, 31, 34, 229, 23, 24, 239, 14, 18, 229, 18, 25, 218, 23, 35, 208, 28, 45, 199, 32, 54, 189, 37, 64, 180, 41, 72, 170, 46, 82, 160, 50, 91, 151, 56, 102, 140, 60, 111, 132, 65, 120, 121, 69, 130, 110, 75, 143, 101, 79, 150, 92, 83, 160, 81, 89, 168, 73, 93, 178, 62, 98, 188, 52, 102, 200, 43, 109, 209, 33, 112, 217, 24, 118, 228, 15, 122, 238, 24, 123, 228, 34, 122, 218, 43, 123, 208, 53, 123, 199, 62, 123, 189, 71, 122, 179, 80, 123, 170, 91, 123, 160, 100, 122, 150, 109, 122, 140, 118, 123, 130, 131, 123, 122, 142, 123, 112, 151, 122, 102, 160, 123, 92, 170, 123, 83, 179, 124, 72, 189, 122, 63, 199, 123, 52, 208, 123, 44, 219, 123, 33, 227, 123, 24, 237, 122, 15, 228, 117, 24, 218, 113, 33, 209, 107, 44, 200, 102, 51, 190, 98, 61, 178, 93, 74, 169, 90, 81, 162, 84, 94, 151, 79, 104, 141, 74, 113, 132, 70, 123, 122, 65, 132, 112, 61, 142, 103, 55, 151, 93, 51, 162, 83, 46, 173, 73, 43, 181, 63, 38, 190, 54, 33, 202, 44, 28, 209, 35, 23, 221, 25, 18, 231, 15, 14, 241, 25, 23, 230, 32, 32, 220, 42, 40, 213, 50, 49, 203, 59, 57, 194, 68, 67, 185, 78, 75, 176, 85, 84, 166, 93, 93, 157, 103, 102, 148, 113, 110, 139, 121, 118, 131, 130, 127, 120, 139, 136, 113, 148, 144, 103, 156, 154, 94, 164, 163, 85, 174, 172, 76, 182, 180, 66, 191, 189, 58, 201, 197, 49, 210, 207, 40, 217, 215, 31, 227, 223, 23, 235, 233, 14 };
+
+const byte colorMap_whiteHot[] = { 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 44, 44, 44, 45, 45, 45, 46, 46, 46, 47, 47, 47, 48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 51, 51, 52, 52, 52, 53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57, 58, 58, 58, 59, 59, 59, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 68, 69, 69, 69, 70, 70, 70, 71, 71, 71, 72, 72, 72, 73, 73, 73, 74, 74, 74, 75, 75, 75, 76, 76, 76, 77, 77, 77, 78, 78, 78, 79, 79, 79, 80, 80, 80, 81, 81, 81, 82, 82, 82, 83, 83, 83, 84, 84, 84, 85, 85, 85, 86, 86, 86, 87, 87, 87, 88, 88, 88, 89, 89, 89, 90, 90, 90, 91, 91, 91, 92, 92, 92, 93, 93, 93, 94, 94, 94, 95, 95, 95, 96, 96, 96, 97, 97, 97, 98, 98, 98, 99, 99, 99, 99, 99, 99, 100, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 103, 104, 104, 104, 105, 105, 105, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 110, 110, 110, 111, 111, 111, 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 119, 119, 119, 120, 120, 120, 121, 121, 121, 122, 122, 122, 123, 123, 123, 124, 124, 124, 125, 125, 125, 126, 126, 126, 127, 127, 127, 128, 128, 128, 129, 129, 129, 130, 130, 130, 131, 131, 131, 132, 132, 132, 133, 133, 133, 134, 134, 134, 135, 135, 135, 136, 136, 136, 137, 137, 137, 138, 138, 138, 139, 139, 139, 140, 140, 140, 141, 141, 141, 142, 142, 142, 143, 143, 143, 144, 144, 144, 145, 145, 145, 146, 146, 146, 147, 147, 147, 148, 148, 148, 149, 149, 149, 150, 150, 150, 151, 151, 151, 152, 152, 152, 153, 153, 153, 154, 154, 154, 154, 154, 154, 155, 155, 155, 156, 156, 156, 157, 157, 157, 158, 158, 158, 159, 159, 159, 160, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 164, 164, 164, 165, 165, 165, 166, 166, 166, 167, 167, 167, 168, 168, 168, 169, 169, 169, 170, 170, 170, 171, 171, 171, 172, 172, 172, 173, 173, 173, 174, 174, 174, 175, 175, 175, 176, 176, 176, 177, 177, 177, 178, 178, 178, 179, 179, 179, 180, 180, 180, 181, 181, 181, 182, 182, 182, 183, 183, 183, 184, 184, 184, 185, 185, 185, 186, 186, 186, 187, 187, 187, 188, 188, 188, 189, 189, 189, 190, 190, 190, 191, 191, 191, 192, 192, 192, 193, 193, 193, 194, 194, 194, 195, 195, 195, 196, 196, 196, 197, 197, 197, 198, 198, 198, 199, 199, 199, 200, 200, 200, 201, 201, 201, 202, 202, 202, 203, 203, 203, 204, 204, 204, 205, 205, 205, 206, 206, 206, 207, 207, 207, 208, 208, 208, 209, 209, 209, 209, 209, 209, 210, 210, 210, 211, 211, 211, 212, 212, 212, 213, 213, 213, 214, 214, 214, 215, 215, 215, 216, 216, 216, 217, 217, 217, 218, 218, 218, 219, 219, 219, 220, 220, 220, 221, 221, 221, 222, 222, 222, 223, 223, 223, 224, 224, 224, 225, 225, 225, 226, 226, 226, 227, 227, 227, 228, 228, 228, 229, 229, 229, 230, 230, 230, 231, 231, 231, 232, 232, 232, 233, 233, 233, 234, 234, 234, 235, 235, 235 };
+
+const byte colorMap_yellow[] = { 62, 16, 15, 63, 17, 16, 61, 18, 15, 62, 19, 16, 61, 20, 16, 61, 22, 15, 59, 22, 15, 60, 23, 16, 60, 23, 16, 60, 25, 15, 60, 25, 15, 61, 26, 16, 59, 27, 16, 58, 28, 14, 59, 29, 15, 59, 31, 14, 59, 31, 14, 60, 32, 15, 61, 34, 15, 59, 34, 15, 60, 36, 14, 60, 37, 15, 60, 37, 15, 61, 39, 14, 61, 39, 14, 60, 40, 15, 61, 42, 14, 61, 42, 14, 62, 43, 15, 63, 44, 15, 63, 46, 16, 64, 47, 15, 64, 47, 15, 65, 49, 14, 65, 50, 15, 66, 52, 14, 66, 52, 14, 68, 52, 15, 68, 54, 15, 68, 54, 15, 69, 55, 14, 70, 56, 15, 71, 57, 16, 72, 57, 14, 72, 59, 15, 73, 60, 14, 75, 61, 13, 76, 62, 14, 78, 64, 15, 78, 64, 15, 79, 65, 14, 80, 66, 15, 82, 67, 14, 83, 68, 15, 84, 69, 14, 84, 69, 14, 85, 71, 14, 88, 71, 15, 89, 72, 14, 90, 73, 15, 93, 75, 15, 94, 76, 14, 95, 78, 13, 98, 78, 14, 99, 79, 14, 100, 80, 15, 102, 81, 14, 103, 82, 15, 105, 82, 14, 106, 84, 13, 107, 85, 14, 110, 85, 14, 110, 85, 14, 113, 87, 14, 114, 88, 15, 117, 89, 14, 119, 91, 14, 120, 92, 14, 122, 93, 15, 123, 94, 14, 125, 95, 13, 126, 96, 14, 129, 96, 13, 130, 97, 14, 132, 98, 13, 133, 99, 13, 136, 100, 14, 138, 100, 13, 139, 101, 14, 141, 102, 13, 144, 105, 14, 147, 106, 14, 148, 107, 13, 150, 107, 14, 153, 108, 13, 154, 109, 14, 156, 110, 13, 157, 111, 12, 158, 112, 13, 160, 113, 13, 161, 114, 14, 164, 114, 13, 166, 115, 12, 167, 116, 13, 170, 116, 12, 172, 119, 13, 174, 119, 12, 176, 121, 14, 178, 122, 13, 179, 123, 14, 182, 124, 13, 183, 125, 13, 185, 125, 14, 185, 126, 12, 186, 127, 13, 189, 127, 12, 190, 128, 13, 192, 129, 12, 194, 131, 12, 195, 132, 13, 196, 134, 13, 199, 135, 13, 202, 136, 14, 203, 137, 13, 203, 137, 13, 205, 138, 12, 206, 139, 12, 207, 140, 13, 208, 141, 12, 209, 142, 13, 209, 142, 13, 212, 143, 12, 213, 144, 13, 215, 146, 13, 215, 147, 12, 217, 149, 12, 219, 149, 13, 220, 151, 12, 221, 152, 13, 221, 152, 11, 222, 153, 12, 223, 154, 13, 224, 155, 12, 224, 155, 12, 225, 157, 12, 226, 158, 13, 227, 159, 12, 228, 160, 13, 228, 160, 11, 229, 161, 12, 230, 163, 11, 231, 164, 12, 231, 166, 12, 231, 166, 12, 232, 167, 13, 233, 168, 12, 233, 168, 12, 234, 169, 13, 232, 170, 11, 233, 171, 12, 233, 171, 12, 234, 174, 12, 234, 174, 12, 235, 175, 11, 233, 176, 11, 235, 179, 12, 235, 179, 12, 235, 180, 13, 235, 181, 11, 236, 182, 12, 235, 182, 12, 236, 183, 13, 234, 184, 11, 235, 185, 12, 235, 187, 11, 235, 187, 11, 233, 188, 11, 234, 189, 12, 233, 190, 11, 234, 191, 12, 234, 193, 13, 234, 193, 11, 232, 194, 11, 232, 196, 12, 232, 196, 12, 231, 197, 13, 231, 198, 11, 231, 199, 12, 231, 199, 12, 231, 201, 11, 229, 202, 11, 230, 203, 12, 229, 204, 12, 229, 204, 11, 228, 206, 12, 227, 207, 12, 227, 208, 13, 225, 209, 11, 226, 210, 12, 225, 211, 12, 223, 212, 12, 223, 212, 12, 223, 214, 11, 223, 216, 12, 223, 216, 12, 221, 217, 10, 222, 218, 11, 221, 218, 11, 220, 220, 12, 220, 220, 12, 219, 223, 11, 219, 223, 11, 217, 224, 11, 217, 225, 12, 217, 226, 11, 215, 226, 11, 215, 228, 12, 216, 229, 11, 215, 230, 11, 215, 230, 11, 214, 232, 12, 213, 233, 12, 213, 233, 10, 212, 235, 11 };
diff --git a/Firmware_V2/src/general/colorschemes.h b/Firmware_V2/src/general/colorschemes.h
new file mode 100644
index 0000000..76b187c
--- /dev/null
+++ b/Firmware_V2/src/general/colorschemes.h
@@ -0,0 +1,41 @@
+/*
+*
+* COLOR SCHEMES - Contains 19 different color schemes to display the thermal image
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef COLORSCHEMES_H
+#define COLORSCHEMES_H
+
+/*################# PUBLIC CONSTANTS, VARIABLES & DATA TYPES ##################*/
+
+extern const byte colorMap_arctic[];
+extern const byte colorMap_blackHot[];
+extern const byte colorMap_blueRed[];
+extern const byte colorMap_coldest[];
+extern const byte colorMap_contrast[];
+extern const byte colorMap_doubleRainbow[];
+extern const byte colorMap_grayRed[];
+extern const byte colorMap_glowBow[];
+extern const byte colorMap_grayscale[];
+extern const byte colorMap_hottest[];
+extern const byte colorMap_ironblack[];
+extern const byte colorMap_lava[];
+extern const byte colorMap_medical[];
+extern const byte colorMap_rainbow[];
+extern const byte colorMap_wheel1[];
+extern const byte colorMap_wheel2[];
+extern const byte colorMap_wheel3[];
+extern const byte colorMap_whiteHot[];
+extern const byte colorMap_yellow[];
+
+#endif /* COLORSCHEMES_H */
diff --git a/Firmware_V2/src/general/globaldefines.h b/Firmware_V2/src/general/globaldefines.h
new file mode 100644
index 0000000..364c8c0
--- /dev/null
+++ b/Firmware_V2/src/general/globaldefines.h
@@ -0,0 +1,284 @@
+/*
+*
+* GLOBAL DEFINES - Global defines, that are used firmware-wide
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef GLOBALDEFINES_H
+#define GLOBALDEFINES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*################# PUBLIC CONSTANTS, VARIABLES & DATA TYPES ##################*/
+
+//Current firmware version
+#define Version "Firmware 2.47 from 08.09.2018"
+#define fwVersion 247
+
+//Pins
+#define pin_button 2
+#define pin_laser 4
+#define pin_touch_irq 5
+#define pin_lcd_dc 6
+#define pin_touch_cs 9 //Only resistive touch
+#define pin_cam_cs 10
+#define pin_mosi 11
+#define pin_miso 12
+#define pin_sck 13
+#define pin_alt_sck 14
+#define pin_lepton_cs 15
+#define pin_sda 18
+#define pin_scl 19
+#define pin_sd_cs 20
+#define pin_lcd_cs 21
+#define pin_lcd_backlight 22
+#define pin_bat_measure 23
+#define pin_usb_measure A14
+
+//Modes
+#define displayMode_thermal 0
+#define displayMode_visual 1
+#define displayMode_combined 2
+
+//TeensyVersion
+#define teensyVersion_old 0 //Teensy 3.1 / 3.2
+#define teensyVersion_new 1 //Teensy 3.6
+
+//MLX90614 sensor version
+#define mlx90614Version_old 0 //MLX90614-BCI
+#define mlx90614Version_new 1 //MLX90614-DCI, MLX90614-BCF, MLX90614-DCH
+
+//FLIR Lepton sensor version
+#define leptonVersion_2_0_shutter 0 //FLIR Lepton2 Shuttered
+#define leptonVersion_3_0_shutter 1 //FLIR Lepton3 Shuttered
+#define leptonVersion_2_0_noShutter 2 //FLIR Lepton2 Non-Shuttered
+#define leptonVersion_2_5_shutter 3 //FLIR Lepton 2.5 Shuttered
+#define leptonVersion_3_5_shutter 3 //FLIR Lepton 3.5 Shuttered
+
+//Temperature format
+#define tempFormat_celcius 0
+#define tempFormat_fahrenheit 1
+
+//Filter type
+#define filterType_none 0
+#define filterType_gaussian 1
+#define filterType_box 2
+
+//Display Min/Max Points
+#define minMaxPoints_disabled 0
+#define minMaxPoints_min 1
+#define minMaxPoints_max 2
+#define minMaxPoints_both 3
+
+//Shutter mode
+#define leptonShutter_manual 0
+#define leptonShutter_auto 1
+#define leptonShutter_none 2
+#define leptonShutter_autoRAD 3
+
+//Text color
+#define textColor_white 0
+#define textColor_black 1
+#define textColor_red 2
+#define textColor_green 3
+#define textColor_blue 4
+
+//Screen off time
+#define screenOffTime_disabled 0
+#define screenOffTime_5min 1
+#define screenOffTime_20min 2
+
+//Hot / cold
+#define hotColdMode_disabled 0
+#define hotColdMode_cold 1
+#define hotColdMode_hot 2
+
+//Hot / cold color
+#define hotColdColor_white 0
+#define hotColdColor_black 1
+#define hotColdColor_red 2
+#define hotColdColor_green 3
+#define hotColdColor_blue 4
+
+//Lepton3.5 Gain mode
+#define lepton_3_5_gain_high 0
+#define lepton_3_5_gain_low 1
+
+//EEPROM registers
+#define eeprom_leptonVersion 100
+#define eeprom_tempFormat 101
+#define eeprom_colorScheme 102
+#define eeprom_convertEnabled 103
+#define eeprom_visualEnabled 104
+#define eeprom_spotEnabled 105
+#define eeprom_colorbarEnabled 106
+#define eeprom_batteryEnabled 107
+#define eeprom_timeEnabled 108
+#define eeprom_dateEnabled 109
+#define eeprom_teensyVersion 110
+#define eeprom_storageEnabled 111
+#define eeprom_rotationVert 112
+#define eeprom_displayMode 113
+#define eeprom_textColor 114
+#define eeprom_filterType 115
+#define eeprom_minValue1Low 116
+#define eeprom_minValue1High 117
+#define eeprom_maxValue1Low 118
+#define eeprom_maxValue1High 119
+#define eeprom_minMax1Set 120
+#define eeprom_adjComb1Left 121
+#define eeprom_adjComb1Right 122
+#define eeprom_adjComb1Up 123
+#define eeprom_adjComb1Down 124
+#define eeprom_adjComb1Alpha 125
+#define eeprom_adjComb1Set 126
+#define eeprom_minMaxPoints 127
+#define eeprom_screenOffTime 128
+#define eeprom_massStorage 129
+#define eeprom_calSlopeSet 130
+#define eeprom_calSlopeBase 131 //4 Byte (131-134)
+#define eeprom_hotColdMode 135
+#define eeprom_hotColdLevelLow 136
+#define eeprom_hotColdLevelHigh 137
+#define eeprom_hotColdColor 138
+#define eeprom_adjComb2Left 139
+#define eeprom_adjComb2Right 140
+#define eeprom_adjComb2Up 141
+#define eeprom_adjComb2Down 142
+#define eeprom_adjComb2Alpha 143
+#define eeprom_adjComb2Set 144
+#define eeprom_adjComb3Left 145
+#define eeprom_adjComb3Right 146
+#define eeprom_adjComb3Up 147
+#define eeprom_adjComb3Down 148
+#define eeprom_adjComb3Alpha 149
+#define eeprom_firstStart 150
+#define eeprom_liveHelper 151
+#define eeprom_adjComb3Set 152
+#define eeprom_adjCombPreset 153
+#define eeprom_minValue2Low 154
+#define eeprom_minValue2High 155
+#define eeprom_maxValue2Low 156
+#define eeprom_maxValue2High 157
+#define eeprom_minMax2Set 158
+#define eeprom_minValue3Low 159
+#define eeprom_minValue3High 160
+#define eeprom_maxValue3Low 161
+#define eeprom_maxValue3High 162
+#define eeprom_minMax3Set 163
+#define eeprom_minMaxPreset 164
+#define eeprom_adjComb1Factor 165
+#define eeprom_adjComb2Factor 166
+#define eeprom_adjComb3Factor 167
+#define eeprom_hqRes 168
+#define eeprom_noShutter 169
+#define eeprom_batComp 170
+#define eeprom_rotationHorizont 171
+#define eeprom_minMax1Comp 172 //4 Byte (172-175)
+#define eeprom_minMax2Comp 176 //4 Byte (176-179)
+#define eeprom_minMax3Comp 180 //4 Byte (180-183)
+#define eeprom_lepton_3_5_gain 184
+#define eeprom_fwVersion 250
+#define eeprom_setValue 200
+
+//Presets for min/max & adjComb
+#define minMax_temporary 0
+#define minMax_preset1 1
+#define minMax_preset2 2
+#define minMax_preset3 3
+#define adjComb_temporary 0
+#define adjComb_preset1 1
+#define adjComb_preset2 2
+#define adjComb_preset3 3
+
+//Hardware diagnostic bit codes
+#define diag_spot 0
+#define diag_display 1
+#define diag_camera 2
+#define diag_touch 3
+#define diag_sd 4
+#define diag_bat 5
+#define diag_lep_conf 6
+#define diag_lep_data 7
+#define diag_ok 255
+
+//Color scheme numbers
+#define colorSchemeTotal 19
+#define colorScheme_arctic 0
+#define colorScheme_blackHot 1
+#define colorScheme_blueRed 2
+#define colorScheme_coldest 3
+#define colorScheme_contrast 4
+#define colorScheme_doubleRainbow 5
+#define colorScheme_grayRed 6
+#define colorScheme_glowBow 7
+#define colorScheme_grayscale 8
+#define colorScheme_hottest 9
+#define colorScheme_ironblack 10
+#define colorScheme_lava 11
+#define colorScheme_medical 12
+#define colorScheme_rainbow 13
+#define colorScheme_wheel1 14
+#define colorScheme_wheel2 15
+#define colorScheme_wheel3 16
+#define colorScheme_whiteHot 17
+#define colorScheme_yellow 18
+
+//Calibration
+#define cal_warmup 0
+#define cal_standard 1
+#define cal_stdSlope 0.0300f //Standard slope value
+
+//Image save marker
+#define imgSave_disabled 0
+#define imgSave_save 1
+#define imgSave_set 2
+#define imgSave_create 3
+
+//Video save marker
+#define videoSave_disabled 0
+#define videoSave_menu 1
+#define videoSave_recording 2
+#define videoSave_processing 3
+
+//Show menu state
+#define showMenu_disabled 0
+#define showMenu_desired 1
+#define showMenu_opened 2
+
+//Load touch decision marker
+#define loadTouch_none 0
+#define loadTouch_find 1
+#define loadTouch_delete 2
+#define loadTouch_previous 3
+#define loadTouch_next 4
+#define loadTouch_exit 5
+#define loadTouch_convert 6
+#define loadTouch_middle 7
+
+//Visual camera resolution
+#define camera_resLow 0 //160x120 for PTC-06 / PTC-08 and 320x240 for Arducam
+#define camera_resMiddle 1 //320x240 for Arducam and PTC-06 / PTC-08
+#define camera_resHigh 2 //640x480 for Arducam and PTC-06 / PTC-08
+
+//Visual camera transfer modes
+#define camera_stream 0
+#define camera_save 1
+#define camera_serial 2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GLOBALDEFINES_H */
diff --git a/Firmware_V2/src/general/globalvariables.cpp b/Firmware_V2/src/general/globalvariables.cpp
new file mode 100644
index 0000000..6809884
--- /dev/null
+++ b/Firmware_V2/src/general/globalvariables.cpp
@@ -0,0 +1,170 @@
+/*
+*
+* GLOBAL VARIABLES - Global variable declarations, that are used firmware-wide
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*############################# PUBLIC VARIABLES ##############################*/
+
+//320x240 buffer (Teensy 3.6 only)
+unsigned short* bigBuffer;
+//160x120 buffer
+unsigned short* smallBuffer;
+
+//Timer
+Metro screenOff;
+boolean screenPressed;
+byte screenOffTime;
+
+//Button Debouncer
+Bounce buttonDebouncer(pin_button, 200);
+Bounce touchDebouncer(pin_touch_irq, 200);
+
+//SD
+SdFat sd;
+SdFile sdFile;
+String sdInfo;
+
+//Save filename
+char saveFilename[20];
+
+//Battery ADC
+ADC *batMeasure;
+//Battery
+int8_t batPercentage;
+long batTimer;
+int8_t batComp;
+
+//Convert RAW to BMP
+bool convertEnabled;
+//Save visual image
+bool visualEnabled;
+//Automatic mode
+bool autoMode;
+//Lock current limits
+bool limitsLocked;
+//Vertical display rotation
+bool rotationVert;
+bool rotationHorizont;
+
+//Display options
+bool batteryEnabled;
+bool timeEnabled;
+bool dateEnabled;
+bool spotEnabled;
+bool colorbarEnabled;
+bool storageEnabled;
+byte filterType;
+byte minMaxPoints;
+
+//Temperature format
+bool tempFormat;
+
+//Text color
+byte textColor;
+
+//Laser state
+bool laserEnabled;
+
+//Display mode
+byte displayMode;
+
+//Resolution, V2 only
+bool hqRes;
+
+//Gain mode, Lepton3.5 only
+bool gainMode;
+
+//FLIR Lepton sensor version
+byte leptonVersion;
+//FLIR Lepton Shutter mode
+byte leptonShutter;
+
+//MLX90614 sensor version
+boolean mlx90614Version;
+
+//Teensy version
+byte teensyVersion;
+
+//HW diagnostic information
+byte diagnostic = diag_ok;
+
+//Current color scheme - standard is rainbow
+byte colorScheme;
+//Pointer to the current color scheme
+const byte *colorMap;
+//Number of rgb elements inside the color scheme
+int16_t colorElements;
+
+//Calibration offset
+float calOffset;
+//Calibration slope
+float calSlope;
+//Calibration status
+byte calStatus;
+//Calibration compensation
+float calComp;
+//Calibration warmup timer
+long calTimer;
+
+//Min & max lepton raw values
+uint16_t maxValue;
+uint16_t minValue;
+
+//Spot & ambient temperature
+float spotTemp;
+float ambTemp;
+
+//Position of min and maxtemp
+uint16_t minTempPos;
+uint16_t minTempVal;
+uint16_t maxTempPos;
+uint16_t maxTempVal;
+
+//Hot / Cold mode
+byte hotColdMode;
+int16_t hotColdLevel;
+byte hotColdColor;
+
+//Array to store the tempPoints
+uint16_t tempPoints[96][2];
+
+//Adjust combined image
+float adjCombAlpha;
+float adjCombFactor;
+byte adjCombLeft;
+byte adjCombRight;
+byte adjCombUp;
+byte adjCombDown;
+
+//Save Image in the next cycle
+volatile byte imgSave;
+//Save Video in the next cycle
+volatile byte videoSave;
+//Show Live Mode Menu in the next cycle
+volatile byte showMenu;
+//Handler for a long touch press
+volatile bool longTouch;
+//Check if in serial mode
+volatile bool serialMode;
+//Load touch decision marker
+volatile byte loadTouch;
diff --git a/Firmware_V2/src/general/globalvariables.h b/Firmware_V2/src/general/globalvariables.h
new file mode 100644
index 0000000..63cf703
--- /dev/null
+++ b/Firmware_V2/src/general/globalvariables.h
@@ -0,0 +1,101 @@
+/*
+*
+* GLOBAL VARIABLES - Global variable declarations, that are used firmware-wide
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef GLOBALVARIABLES_H
+#define GLOBALVARIABLES_H
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+
+/*################# PUBLIC CONSTANTS, VARIABLES & DATA TYPES ##################*/
+
+extern unsigned short* bigBuffer;
+extern unsigned short* smallBuffer;
+extern Metro screenOff;
+extern boolean screenPressed;
+extern byte screenOffTime;
+extern Bounce buttonDebouncer;
+extern Bounce touchDebouncer;
+extern SdFat sd;
+extern SdFile sdFile;
+extern String sdInfo;
+extern char saveFilename[20];
+extern ADC *batMeasure;
+extern int8_t batPercentage;
+extern long batTimer;
+extern int8_t batComp;
+extern bool convertEnabled;
+extern bool visualEnabled;
+extern bool autoMode;
+extern bool limitsLocked;
+extern bool rotationVert;
+extern bool rotationHorizont;
+extern bool batteryEnabled;
+extern bool timeEnabled;
+extern bool dateEnabled;
+extern bool spotEnabled;
+extern bool colorbarEnabled;
+extern bool storageEnabled;
+extern byte filterType;
+extern byte minMaxPoints;
+extern bool tempFormat;
+extern byte textColor;
+extern bool laserEnabled;
+extern byte displayMode;
+extern bool hqRes;
+extern bool gainMode;
+extern byte leptonVersion;
+extern byte leptonShutter;
+extern boolean mlx90614Version;
+extern byte teensyVersion;
+extern byte diagnostic;
+extern byte colorScheme;
+extern const byte *colorMap;
+extern int16_t colorElements;
+extern float calOffset;
+extern float calSlope;
+extern byte calStatus;
+extern float calComp;
+extern long calTimer;
+extern uint16_t maxValue;
+extern uint16_t minValue;
+extern float spotTemp;
+extern float ambTemp;
+extern uint16_t minTempPos;
+extern uint16_t minTempVal;
+extern uint16_t maxTempPos;
+extern uint16_t maxTempVal;
+extern byte hotColdMode;
+extern int16_t hotColdLevel;
+extern byte hotColdColor;
+extern uint16_t tempPoints[96][2];
+extern float adjCombAlpha;
+extern float adjCombFactor;
+extern byte adjCombLeft;
+extern byte adjCombRight;
+extern byte adjCombUp;
+extern byte adjCombDown;
+extern volatile byte imgSave;
+extern volatile byte videoSave;
+extern volatile byte showMenu;
+extern volatile bool longTouch;
+extern volatile bool serialMode;
+extern volatile byte loadTouch;
+
+#endif /* GLOBALVARIABLES_H */
diff --git a/Firmware_V2/src/gui/bitmaps.cpp b/Firmware_V2/src/gui/bitmaps.cpp
new file mode 100644
index 0000000..6b9184b
--- /dev/null
+++ b/Firmware_V2/src/gui/bitmaps.cpp
@@ -0,0 +1,1927 @@
+/*
+*
+* BITMAPS - Icons and graphics shown inside the GUI
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+
+/*############################# PUBLIC VARIABLES ##############################*/
+
+/* Main Menu Icon 1 - Change color */
+
+const uint16_t icon1Colors[] = {
+ 0xDBE5, 0xDC89, 0xFFFF, 0xFFDF
+};
+
+const uint8_t icon1Bitmap[] = {
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xEA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAF, 0x54, 0x00, 0x01, 0x7E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xD0, 0x00, 0x00, 0x00, 0x01, 0x7A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xCE, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0x06, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, 0xAA, 0xAA, 0xAA, 0xAA, 0xB4, 0x03, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xAA, 0xAA, 0xAA, 0xAF, 0x40, 0x03, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0xAA, 0xAA, 0xD0, 0x00, 0x01, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xAA, 0xA9, 0x00, 0x00, 0x01, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAC, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xAA, 0xB4, 0x00, 0x00, 0x01, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x00, 0x01, 0xEA, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xEA, 0x90, 0x00, 0x00, 0x01, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xC0, 0x00, 0x00, 0x03, 0xAA, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, 0xC0, 0x00, 0x00, 0x01, 0xAA,
+ 0xAA, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x06, 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x40, 0x00, 0x00, 0x01, 0xAA,
+ 0xAA, 0xAA, 0xAC, 0x00, 0x00, 0x00, 0x0E, 0xAA, 0xAC, 0x00, 0x00, 0x5D, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0xAA,
+ 0xAA, 0xAA, 0xB4, 0x00, 0x00, 0x00, 0x0E, 0xAA, 0xAC, 0x00, 0x01, 0xAA, 0xD0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0xAA,
+ 0xAA, 0xAA, 0x90, 0x00, 0x00, 0x00, 0x06, 0xAA, 0xA4, 0x00, 0x06, 0xAA, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAA,
+ 0xAA, 0xAA, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xAA, 0xB0, 0x00, 0x0E, 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA,
+ 0xAA, 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0xEA, 0xC0, 0x00, 0x0E, 0xAA, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xAA,
+ 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x0E, 0xAA, 0xAC, 0x00, 0x00, 0x04, 0x00, 0x00, 0x3A, 0xAA,
+ 0xAA, 0xA9, 0x00, 0x01, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA, 0xA4, 0x00, 0x00, 0x39, 0x00, 0x01, 0xEA, 0xAA,
+ 0xAA, 0xAC, 0x00, 0x06, 0xAA, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xAA, 0x90, 0x00, 0x00, 0x6A, 0xD0, 0x1E, 0xAA, 0xAA,
+ 0xAA, 0xA4, 0x00, 0x0E, 0xAA, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x00, 0x01, 0xEA, 0xC0, 0x3A, 0xAA, 0xAA,
+ 0xAA, 0xB0, 0x00, 0x1A, 0xAA, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xAA, 0x40, 0x6A, 0xAA, 0xAA,
+ 0xAA, 0x90, 0x00, 0x1A, 0xAA, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xAB, 0x01, 0xEA, 0xAA, 0xAA,
+ 0xAA, 0x90, 0x00, 0x1A, 0xAA, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xAD, 0x03, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x80, 0x00, 0x0E, 0xAA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xA4, 0x06, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xC0, 0x00, 0x07, 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0xB0, 0x0E, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xC0, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAA, 0x90, 0x1A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xAA, 0x40, 0x3A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xAB, 0x00, 0x6A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xA9, 0x00, 0x6A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, 0xA4, 0x00, 0x6A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0xB0, 0x00, 0x6A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAA, 0xD0, 0x00, 0xEA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xAA, 0x40, 0x01, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x40, 0x00, 0x07, 0xAD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAB, 0x00, 0x03, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x40, 0x00, 0x1E, 0xAB, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xAC, 0x00, 0x06, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xC0, 0x00, 0x3A, 0xAA, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xA4, 0x00, 0x1A, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xC0, 0x00, 0x6A, 0xAA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x90, 0x00, 0x7A, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x80, 0x00, 0x6A, 0xAA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x7D, 0x00, 0xEA, 0xC0, 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x90, 0x00, 0x2A, 0xAA, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xA9, 0x01, 0xAB, 0x00, 0x1E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xB0, 0x00, 0x3A, 0xAA, 0x40, 0x00, 0x00, 0x00, 0x0E, 0xAC, 0x03, 0xAD, 0x01, 0xEA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xB0, 0x00, 0x0E, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xA4, 0x06, 0xA4, 0x07, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA4, 0x00, 0x01, 0x54, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xB0, 0x1E, 0x90, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x90, 0x1A, 0x40, 0x3A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xC0, 0x3B, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x40, 0x6C, 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAB, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x40, 0xF0, 0x07, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x01, 0xC0, 0x1E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x01, 0x00, 0x7A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x01, 0xEA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x03, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x1E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE9, 0x00, 0x7A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAB, 0x47, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x07, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAB, 0x40, 0x00, 0x00, 0x00, 0x1E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xD0, 0x00, 0x00, 0x00, 0x7A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAD, 0x00, 0x00, 0x07, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xF5, 0x01, 0x7A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA
+};
+
+/* Main Menu Icon 2 - Change mode */
+
+const uint16_t icon2Colors[] = {
+ 0x4249, 0x7BF0, 0x7C10, 0xFFDF
+};
+
+const uint8_t icon2Bitmap[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFE, 0xAA, 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF,
+ 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF,
+ 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF,
+ 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF,
+ 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0x90, 0x06, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x2F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x2F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0x94, 0x1B, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xFF, 0xFF, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF,
+ 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF,
+ 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF,
+ 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF,
+ 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF,
+ 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+/* Main Menu Icon 3 - Temperature limits */
+
+const uint16_t icon3Colors[] = {
+ 0x7ACB, 0x8BAF, 0x93F0, 0xFFDF
+};
+
+const uint8_t icon3Bitmap[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x5B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x02, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x02, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAB, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x06, 0x40, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x2F, 0xE0, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF, 0xFF, 0xFF, 0xEA, 0xAA, 0xAA, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x6A, 0xAA, 0x6B, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xF8, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0xFF, 0xFF, 0xE0, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0x80, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x0B, 0xFF, 0xFF, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0x65, 0x55, 0x40, 0x00, 0x2F, 0xFF, 0xFE, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xF8, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xE0, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0x80, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFE, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xF8, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xEA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFA, 0xBF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0xBF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0xBF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0xBF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0xBF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0xBF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xAA, 0xA0, 0x6A, 0xAF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0xBF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0xBF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x40, 0x06, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+/* Main Menu Icon 4 - Load menu */
+
+const uint16_t icon4Colors[] = {
+ 0xDBE5, 0xDCAA, 0xFFDF, 0xFFDF
+};
+
+const uint8_t icon4Bitmap[] = {
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xB5, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xEA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x7A, 0xAA,
+ 0xAA, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xAA,
+ 0xAA, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xAA,
+ 0xAA, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xAA,
+ 0xAA, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xAA,
+ 0xAA, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xAA,
+ 0xAA, 0xA0, 0x00, 0x01, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x40, 0x00, 0x0A, 0xAA,
+ 0xAA, 0xA0, 0x00, 0x1A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x0A, 0xAA,
+ 0xAA, 0xA0, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0x00, 0x0A, 0xAA,
+ 0xAA, 0xA0, 0x00, 0xEA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0x00, 0x0A, 0xAA,
+ 0xAA, 0xA0, 0x00, 0xEA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0x00, 0x0A, 0xAA,
+ 0xAA, 0xA0, 0x00, 0xEA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0x00, 0x0A, 0xAA,
+ 0xAA, 0xA0, 0x00, 0xEA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0x00, 0x0A, 0xAA,
+ 0xAA, 0xA0, 0x00, 0xEA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0x00, 0x0A, 0xAA,
+ 0xAA, 0xA0, 0x00, 0xEA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0x00, 0x0A, 0xAA,
+ 0xAA, 0xA5, 0x55, 0xEA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0x55, 0x5A, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAB, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xEA,
+ 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A,
+ 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A,
+ 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A,
+ 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A,
+ 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A,
+ 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A,
+ 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A,
+ 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A,
+ 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A,
+ 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A,
+ 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A,
+ 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A,
+ 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A,
+ 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A,
+ 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA,
+ 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA,
+ 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA,
+ 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA,
+ 0xAA, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA,
+ 0xAA, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAA,
+ 0xAA, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAA,
+ 0xAA, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAA,
+ 0xAA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAA,
+ 0xAA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAA,
+ 0xAA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xAA,
+ 0xAA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xAA,
+ 0xAA, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xAA,
+ 0xAA, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAA,
+ 0xAA, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAA,
+ 0xAA, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA,
+ 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA,
+ 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA,
+ 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA,
+ 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA,
+ 0xAA, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xAA,
+ 0xAA, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xAA,
+ 0xAA, 0xAB, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA
+};
+
+/* Main Menu Icon 5 - Mass storage or Shutter */
+
+const uint16_t icon5Colors[] = {
+ 0x4249, 0x9CF3, 0xCE9A, 0xFFFF
+};
+
+const uint8_t icon5Bitmap_1[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x02, 0xAA, 0xA0, 0x0A, 0xAA, 0x80, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x03, 0xFF, 0xF0, 0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x03, 0xFF, 0xF0, 0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x03, 0xFF, 0xF0, 0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x03, 0xFF, 0xF0, 0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x03, 0xFF, 0xF0, 0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x02, 0xFF, 0xF0, 0x0F, 0xFF, 0x80, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE4, 0x00, 0x00, 0x1B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA5, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+#if defined(__MK66FX1M0__)
+const uint8_t icon5Bitmap_2[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x54, 0x16, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x02, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x2F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0B, 0xFD, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x0F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x0B, 0xFC, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x0B, 0xFC, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x02, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x3F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF,
+ 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x07, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF,
+ 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0xBF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF,
+ 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF,
+ 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF,
+ 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF,
+ 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x03, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x03, 0xFF,
+ 0xFF, 0xCF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x02, 0xFF,
+ 0xFF, 0x82, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x01, 0xFF,
+ 0xFF, 0x80, 0x3F, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x40, 0x0B, 0xFF, 0xF4, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x40, 0x01, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x0B, 0xFF, 0xF8, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x0B, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xD0, 0x00, 0xFF,
+ 0xFF, 0x40, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0xFF,
+ 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0x40, 0xFF,
+ 0xFF, 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x2F, 0xFF, 0xE2, 0xFF,
+ 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF,
+ 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF,
+ 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF,
+ 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF,
+ 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF,
+ 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFE, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF,
+ 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xE0, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF,
+ 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFD, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF,
+ 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xD0, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xD0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0xBF, 0xC0, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFD, 0x00, 0x07, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xC0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x00, 0xBF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xCB, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0x40, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x40, 0x01, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+#else
+const uint8_t* icon5Bitmap_2 = NULL;
+#endif
+
+/* Main Menu Icon 6 - Settings */
+
+const uint16_t icon6Colors[] = {
+ 0x7AEC, 0x8B6E, 0x93F0, 0xFFDF
+};
+
+const uint8_t icon6Bitmap[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x2F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFD, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x06, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF,
+ 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF,
+ 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xFF, 0xE0, 0x00, 0xBF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0xBF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xF8, 0x02, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+/* Main Menu Icon 7 - Display settings */
+
+const uint16_t icon7Colors[] = {
+ 0xD3E5, 0xDC89, 0xFFDF, 0xFFDF
+};
+
+const uint8_t icon7Bitmap[] = {
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAB, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xEA, 0xAA,
+ 0xAA, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xAA,
+ 0xAA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xAA,
+ 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAA,
+ 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA,
+ 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A,
+ 0xA9, 0x00, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAF, 0xFA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x90, 0x06, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x90, 0x06, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xB5, 0xAA, 0xC0, 0x03, 0xAA, 0xDE, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xC0, 0x7D, 0x00, 0x00, 0x7D, 0x03, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xC0, 0x00, 0x5F, 0xF5, 0x00, 0x03, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0x90, 0x01, 0xAA, 0xAA, 0x40, 0x06, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xC0, 0x0E, 0xAA, 0xAA, 0xB0, 0x03, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0x40, 0x1A, 0xAA, 0xAA, 0xA4, 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xBF, 0x40, 0x3A, 0xAA, 0xAA, 0xAD, 0x00, 0xFA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0x6A, 0xAA, 0xAA, 0xA9, 0x00, 0x05, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0x6A, 0xAA, 0xAA, 0xAB, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0xEA, 0xAA, 0xAA, 0xAB, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0xEA, 0xAA, 0xAA, 0xAB, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0x6A, 0xAA, 0xAA, 0xA9, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xF5, 0x00, 0x6A, 0xAA, 0xAA, 0xA9, 0x00, 0x5F, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0x40, 0x3A, 0xAA, 0xAA, 0xAC, 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xC0, 0x1E, 0xAA, 0xAA, 0xB4, 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0x90, 0x07, 0xAA, 0xAA, 0xD0, 0x06, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0x90, 0x00, 0x7A, 0xAF, 0x00, 0x07, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0x15, 0x54, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0x40, 0x14, 0x00, 0x00, 0x14, 0x01, 0xEA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0x91, 0xEB, 0x40, 0x01, 0xEB, 0x46, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAF, 0xAA, 0x80, 0x06, 0xAA, 0xFA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x90, 0x06, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x90, 0x06, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB5, 0x5E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x6A,
+ 0xA9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x6A,
+ 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A,
+ 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A,
+ 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A,
+ 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A,
+ 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A,
+ 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A,
+ 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA,
+ 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAA,
+ 0xAA, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xAA,
+ 0xAA, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xAA,
+ 0xAA, 0xAB, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, 0x00, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xEA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x0E, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xBF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFE, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAB, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xEA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAB, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xEA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA
+};
+
+/* Main Menu Icon 8 - Laser or HQ */
+
+const uint16_t icon8Colors[] = {
+ 0x4A6A, 0x7BF0, 0x7C10, 0xFFFF
+};
+
+const uint8_t icon8Bitmap_1[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xBF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xBB, 0x7A, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xD6, 0xAB, 0xEF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDA, 0x00, 0x6E, 0x6F, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x00, 0x07, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0x00, 0x0A, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE5, 0x00, 0x29, 0xBF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x6D, 0x00, 0xAF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xAB, 0xBB, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0xBB, 0x7E, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0x7F, 0xAF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x3F, 0xFF, 0xDF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0x54, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+#if defined(__MK66FX1M0__)
+const uint8_t icon8Bitmap_2[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xFF, 0xFF,
+ 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF,
+ 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF,
+ 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF,
+ 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF,
+ 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF,
+ 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF,
+ 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF,
+ 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF,
+ 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF,
+ 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF,
+ 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF,
+ 0xFF, 0xFF, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+#else
+const uint8_t* icon8Bitmap_2 = NULL;
+#endif
+
+
+/* Main Menu Icon 9 - Display off */
+
+const uint16_t icon9Colors[] = {
+ 0x7AEC, 0x8B8E, 0x93F0, 0xFFDF
+};
+
+const uint8_t icon9Bitmap[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0xFF,
+ 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF,
+ 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF,
+ 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x2F, 0xC0, 0x2F, 0xC2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x2F, 0xC0, 0x2F, 0xC0, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x2F, 0xC0, 0x2F, 0xC0, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x2F, 0xC0, 0x2F, 0xC0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x3F, 0xC0, 0x2F, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xBF, 0xD0, 0x2F, 0xF4, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFC, 0x02, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFC, 0x02, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xFF, 0xF8, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x2F, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xFF, 0x80, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0xBF, 0xF8, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF,
+ 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF,
+ 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF,
+ 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA0, 0x00, 0x00, 0x0A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+/* Main Menu Icon 10 - Calibration */
+
+const uint16_t icon10Colors[] = {
+ 0xDBE5, 0xDCAA, 0xFFDF, 0xFFDF
+};
+
+const uint8_t icon10Bitmap[] = {
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xA9, 0x0A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xA4, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA0, 0x06, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0x90, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x80, 0x01, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0x40, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x6A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0x40, 0x00, 0x0A, 0xA9, 0x1A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0x00, 0x00, 0x1A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0x80, 0x00, 0x02, 0xA4, 0x06, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA0, 0x00, 0x00, 0x06, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0x90, 0x00, 0x00, 0x90, 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x01, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x69, 0x00, 0x00, 0x00, 0x6A, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0x1A, 0x40, 0x00, 0x00, 0x1A, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0x00, 0x00, 0x06, 0xAA, 0xAA, 0xAA, 0xAA, 0xA0, 0x06, 0x90, 0x00, 0x00, 0x06, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0x90, 0x00, 0x00, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0xA4, 0x01, 0xA4, 0x00, 0x00, 0x01, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0x29, 0x00, 0x29, 0x00, 0x00, 0x00, 0x6A, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xAA, 0xAA, 0xA8, 0x0A, 0x40, 0x0A, 0x40, 0x00, 0x00, 0x2A, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA, 0xAA, 0xA9, 0x02, 0x90, 0x02, 0x90, 0x00, 0x00, 0x1A, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAA, 0xAA, 0x86, 0x80, 0xA4, 0x00, 0xA4, 0x00, 0x00, 0x2A, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0x01, 0xA0, 0x28, 0x00, 0x28, 0x00, 0x00, 0x6A, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xA9, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xAA, 0x40, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xA4, 0x06, 0x80, 0x00, 0x00, 0x00, 0x1A, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA, 0x41, 0xA0, 0x00, 0x00, 0x00, 0x6A, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xA5, 0x68, 0x00, 0x00, 0x01, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA, 0x9A, 0x00, 0x00, 0x06, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xAA, 0x00, 0x00, 0x1A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA, 0x90, 0x00, 0x6A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xA9, 0x01, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x90, 0x00, 0x00, 0x2A, 0x90, 0x00, 0x00, 0x00, 0x06, 0xAA, 0x96, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x2A, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0x40, 0x00, 0x1A, 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x05, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x90, 0x00, 0x0A, 0x9A, 0xAA, 0x40, 0x00, 0x00, 0x00, 0x1A, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA0, 0x00, 0x06, 0x91, 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x02, 0xA0, 0x1A, 0xAA, 0x40, 0x00, 0x00, 0x00, 0x1A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0x00, 0x01, 0xA8, 0x01, 0x6A, 0xA5, 0x00, 0x00, 0x00, 0x01, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0x00, 0x00, 0xAA, 0x00, 0x06, 0xAA, 0x90, 0x00, 0x00, 0x00, 0x6A, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x6A, 0x80, 0x00, 0x6A, 0xA9, 0x00, 0x00, 0x00, 0x1A, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0x2A, 0xA0, 0x00, 0x06, 0xAA, 0x90, 0x00, 0x00, 0x0A, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x2A, 0x80, 0x00, 0x2A, 0x64, 0x00, 0x00, 0x6A, 0xA9, 0x40, 0x00, 0x06, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0x0A, 0x90, 0x00, 0x1A, 0x90, 0x00, 0x01, 0xAA, 0xAA, 0xA4, 0x00, 0x02, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0x02, 0xA0, 0x00, 0x0A, 0x90, 0x00, 0x06, 0xAA, 0xAA, 0xAA, 0x40, 0x01, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x86, 0x41, 0xA4, 0x00, 0x06, 0x90, 0x00, 0x1A, 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x1A, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x01, 0x90, 0xA8, 0x00, 0x02, 0xA0, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0x50, 0x01, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0x00, 0x64, 0x69, 0x00, 0x01, 0xA4, 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0x50, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x19, 0x6A, 0x00, 0x00, 0xA8, 0x06, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x86, 0x80, 0x06, 0x2A, 0x40, 0x00, 0x69, 0x1A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x41, 0xA0, 0x00, 0x1A, 0x80, 0x00, 0x2A, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x90, 0x68, 0x00, 0x0A, 0x90, 0x00, 0x1A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xA1, 0xA4, 0x1A, 0x00, 0x06, 0xA0, 0x00, 0x1A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0x80, 0x69, 0x06, 0x80, 0x02, 0xA4, 0x00, 0x0A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0x40, 0x1A, 0x41, 0xA0, 0x01, 0xA8, 0x00, 0x06, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0x90, 0x06, 0x80, 0x68, 0x00, 0xA9, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xA0, 0xA4, 0x01, 0x90, 0x1A, 0x00, 0x6A, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0x80, 0x29, 0x00, 0x00, 0x06, 0x00, 0x2A, 0x40, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x00, 0x1A, 0x40, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x02, 0x90, 0x00, 0x00, 0x00, 0x0A, 0x80, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x90, 0x00, 0x00, 0xA4, 0x00, 0x00, 0x00, 0x0A, 0x90, 0x00, 0x1A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x80, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x1A, 0xA0, 0x00, 0x0A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x40, 0x00, 0x00, 0x0A, 0x40, 0x00, 0x00, 0x6A, 0xA4, 0x00, 0x0A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x40, 0x00, 0x00, 0x02, 0x90, 0x00, 0x01, 0xAA, 0xA8, 0x00, 0x06, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x90, 0x00, 0x00, 0x00, 0x40, 0x00, 0x06, 0xAA, 0xA9, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xAA, 0xAA, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xAA, 0xAA, 0x40, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0x40, 0x00, 0x00, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0x90, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0x90, 0x00, 0x00, 0x00, 0x06, 0xAA, 0xAA, 0xAA, 0xA9, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x1A, 0xAA, 0xAA, 0xAA, 0xAA, 0xA4, 0x1A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xA9, 0x00, 0x00, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0x1A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x5A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0x90, 0x00, 0x06, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x9A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x1A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA6, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xA9, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x42, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA
+};
+
+/* Main Menu Icon 11_1 - Hot / cold */
+
+const uint16_t icon11_1Colors[] = {
+ 0x4249, 0x7BF0, 0x7C10, 0xFFDF
+};
+
+const uint8_t icon11_1Bitmap[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x2F, 0xFD, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x2F, 0xF0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x2F, 0xE0, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x2F, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x0B, 0xE0, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x02, 0x80, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xE0, 0x00, 0x00, 0x0F, 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xD0, 0x00, 0x00, 0x2F, 0x80, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xC0, 0x00, 0x00, 0xBF, 0x80, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xC0, 0x18, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xC0, 0x2C, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x40, 0x00, 0x07, 0xFF, 0xE0, 0x3E, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x40, 0x00, 0x0F, 0xFF, 0xF0, 0xBF, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x40, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0xBF, 0xFF, 0xFE, 0x1F, 0xE0, 0x3F, 0x83, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xC0, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF, 0xFF, 0xFC, 0x03, 0xE0, 0x3E, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0xE0, 0x3C, 0x02, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xD0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0xFF, 0xF9, 0xFE, 0x00, 0x10, 0x10, 0x03, 0xF9, 0xBF, 0xFF, 0xFF,
+ 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x02, 0xFF, 0xE0, 0x3F, 0x80, 0x00, 0x00, 0x0F, 0xE0, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xE0, 0x2F, 0xE0, 0x00, 0x00, 0x3F, 0xD0, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFC, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xF0, 0x2F, 0xF8, 0x00, 0x00, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x40, 0x2F, 0xEF, 0xF0, 0x0F, 0xFE, 0x00, 0x03, 0xFF, 0xC0, 0x7F, 0xAF, 0xFF,
+ 0xFF, 0xFF, 0x40, 0x1F, 0xFF, 0xFF, 0xFD, 0x00, 0x7F, 0x02, 0xF4, 0x0F, 0xFF, 0x80, 0x0F, 0xFF, 0x80, 0xBD, 0x0B, 0xFF,
+ 0xFF, 0xFF, 0xD0, 0x07, 0xFF, 0xFF, 0xF4, 0x02, 0xFF, 0x00, 0x28, 0x0B, 0xFF, 0xE0, 0x3F, 0xFF, 0x40, 0xD0, 0x03, 0xFF,
+ 0xFF, 0xFF, 0xF8, 0x00, 0x6F, 0xFE, 0x40, 0x0B, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x3F, 0xFF, 0x00, 0x00, 0x0B, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x40, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xE0, 0x3F, 0xFF, 0x00, 0x00, 0x2F, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xE4, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFD, 0x00, 0x03, 0xFF, 0xE0, 0x3F, 0xFE, 0x00, 0x02, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0xBF, 0x80, 0x0B, 0xF4, 0x00, 0x0B, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x00, 0x00, 0x18, 0x00, 0x02, 0x80, 0x00, 0x00, 0x6F, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x02, 0xF4, 0x00, 0x0B, 0x00, 0x00, 0xB9, 0x00, 0x01, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x02, 0xBF, 0xFE, 0x40, 0x7F, 0xE0, 0x0B, 0xFF, 0xE9, 0x02, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0x80, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xEF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xBF, 0xF4, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x0A, 0xFF, 0xFF, 0x80, 0xBF, 0xF0, 0x0B, 0xFF, 0xFE, 0x43, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x0B, 0xF8, 0x00, 0x0B, 0x80, 0x00, 0xFE, 0x40, 0x01, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x00, 0x00, 0x1B, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0x40, 0x0B, 0xE0, 0x00, 0x06, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x02, 0xFF, 0xD0, 0x2F, 0xFD, 0x00, 0x07, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x00, 0x03, 0xFF, 0xE0, 0x3F, 0xFE, 0x00, 0x00, 0xBF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xE0, 0x3F, 0xFF, 0x00, 0x00, 0x0B, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x18, 0x0B, 0xFF, 0xE0, 0x3F, 0xFF, 0x40, 0x80, 0x03, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xB8, 0x0F, 0xFF, 0xC0, 0x2F, 0xFF, 0x80, 0xF8, 0x07, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8B, 0xF0, 0x0F, 0xFF, 0x00, 0x07, 0xFF, 0x80, 0x7F, 0x5F, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x1F, 0xFC, 0x00, 0x01, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x2F, 0xF0, 0x00, 0x00, 0xBF, 0xD0, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x3F, 0xC0, 0x00, 0x00, 0x1F, 0xE0, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xBF, 0x00, 0x00, 0x00, 0x07, 0xF4, 0xBF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0xE0, 0x38, 0x02, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x02, 0xE0, 0x3E, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0xE0, 0x3F, 0x83, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+/* Main Menu Icon 11_2 - Adjust combined */
+
+const uint16_t icon11_2Colors[] = {
+ 0x4269, 0x7BF0, 0x7C10, 0xF7BE
+};
+
+const uint8_t icon11_2Bitmap[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x01, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0x55, 0x55, 0x55, 0x54, 0x00, 0x01, 0x55, 0x55, 0x55, 0x56, 0xBF, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x55, 0x55, 0x40, 0x00, 0xBF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x01, 0x55, 0x55, 0x55, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0x80, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+/* Main Menu Icon 12 - Temperature points */
+
+const uint16_t icon12Colors[] = {
+ 0x72AB, 0x8B6E, 0x93F0, 0xFFBE
+};
+
+const uint8_t icon12Bitmap[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFE, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0x69, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xC2, 0xFF, 0x82, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x8B, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x0F, 0xFF, 0xF8, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x1F, 0xFF, 0xFC, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2F, 0xFE, 0xA8, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x1B, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2F, 0xF0, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x0A, 0x81, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2F, 0xFA, 0xA8, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xF4, 0xBF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2F, 0xFF, 0xFC, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFD, 0x2F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2F, 0xFF, 0xF8, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE2, 0xFF, 0xFE, 0x2F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2F, 0xF0, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2F, 0xF9, 0x54, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0xFF, 0xAA, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2F, 0xFF, 0xFC, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0xFD, 0x00, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2F, 0xFF, 0xFC, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0xFF, 0xAA, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2F, 0xF9, 0x54, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2F, 0xF4, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0xFF, 0xEE, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2F, 0xFF, 0xF8, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0xFD, 0x00, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2F, 0xFF, 0xFC, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0xFE, 0xAA, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2F, 0x92, 0xFC, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2F, 0x00, 0xBC, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2E, 0x00, 0x7C, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0xFE, 0x00, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2E, 0x00, 0x7C, 0xBF, 0xFF, 0xFF, 0xFF, 0xEA, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0xFE, 0x55, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2E, 0x00, 0x7C, 0xBF, 0xFF, 0xFF, 0xFE, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xD3, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2E, 0x00, 0x7C, 0xBF, 0xFF, 0xFF, 0xF4, 0x2A, 0x43, 0xFF, 0xFF, 0xFF, 0xD3, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2E, 0x00, 0x7C, 0xBF, 0xFF, 0xFF, 0xD2, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xD3, 0xE0, 0x2F, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2E, 0x00, 0x7C, 0xBF, 0xFF, 0xFF, 0x87, 0xFF, 0xF8, 0xBF, 0xFF, 0xFF, 0xD3, 0xD0, 0x0F, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x2E, 0x00, 0x7C, 0xBF, 0xFF, 0xFF, 0x8B, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xD3, 0xD0, 0x0F, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xFE, 0x1E, 0x00, 0x7C, 0x7F, 0xFF, 0xFF, 0x4F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xD3, 0xD0, 0x0F, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xF8, 0x2F, 0x00, 0x7E, 0x1F, 0xFF, 0xFF, 0x4F, 0xFE, 0xA8, 0x3F, 0xFF, 0xFF, 0xD3, 0xD0, 0x0F, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0xFE, 0x00, 0x2F, 0x8B, 0xFF, 0xFF, 0x4F, 0xF4, 0x00, 0x3F, 0xFF, 0xFF, 0xD3, 0xD0, 0x0F, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xD2, 0xF0, 0x00, 0x0B, 0xD3, 0xFF, 0xFF, 0x4F, 0xFE, 0xA8, 0x3F, 0xFF, 0xFF, 0xD3, 0xD0, 0x0F, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xC7, 0xD0, 0x00, 0x02, 0xE2, 0xFF, 0xFF, 0x4F, 0xFF, 0xFD, 0x3F, 0xFF, 0xFF, 0xD3, 0xD0, 0x0F, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0x8B, 0x80, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x4F, 0xFF, 0xB8, 0x3F, 0xFF, 0xFF, 0xD3, 0xD0, 0x0F, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0x8F, 0x40, 0x00, 0x00, 0xB8, 0xFF, 0xFF, 0x4F, 0xF4, 0x00, 0x3F, 0xFF, 0xFF, 0x83, 0xD0, 0x0F, 0x0B, 0xFF, 0xFF,
+ 0xFF, 0x8F, 0x40, 0x00, 0x00, 0xB8, 0xFF, 0xFF, 0x4F, 0xFA, 0xA4, 0x3F, 0xFF, 0xFE, 0x0B, 0xC0, 0x0F, 0xC2, 0xFF, 0xFF,
+ 0xFF, 0x8F, 0x40, 0x00, 0x00, 0xB8, 0xFF, 0xFF, 0x4F, 0xFF, 0xFD, 0x3F, 0xFF, 0xFC, 0x2F, 0x40, 0x07, 0xF0, 0xFF, 0xFF,
+ 0xFF, 0x8F, 0x40, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x4F, 0xFF, 0xFD, 0x3F, 0xFF, 0xF8, 0xBC, 0x00, 0x00, 0xF8, 0xBF, 0xFF,
+ 0xFF, 0x8B, 0x80, 0x00, 0x01, 0xF0, 0xFF, 0xFF, 0x4F, 0xF9, 0x54, 0x3F, 0xFF, 0xF4, 0xF4, 0x00, 0x00, 0x7C, 0x3F, 0xFF,
+ 0xFF, 0xC7, 0xD0, 0x00, 0x02, 0xE2, 0xFF, 0xFF, 0x4F, 0xF8, 0x00, 0x3F, 0xFF, 0xF2, 0xF0, 0x00, 0x00, 0x2E, 0x3F, 0xFF,
+ 0xFF, 0xE2, 0xF4, 0x00, 0x0B, 0xC3, 0xFF, 0xFF, 0x4F, 0xFF, 0xFD, 0x3F, 0xFF, 0xE2, 0xE0, 0x00, 0x00, 0x2E, 0x2F, 0xFF,
+ 0xFF, 0xF0, 0xBE, 0x40, 0xBF, 0x4B, 0xFF, 0xFF, 0x4F, 0xFF, 0xFD, 0x3F, 0xFF, 0xE2, 0xE0, 0x00, 0x00, 0x2E, 0x2F, 0xFF,
+ 0xFF, 0xF8, 0x2F, 0xFF, 0xFD, 0x1F, 0xFF, 0xFF, 0x4F, 0xD1, 0xBD, 0x3F, 0xFF, 0xE2, 0xE0, 0x00, 0x00, 0x2E, 0x2F, 0xFF,
+ 0xFF, 0xFE, 0x06, 0xFF, 0xE0, 0xBF, 0xFF, 0xFF, 0x4F, 0x40, 0x3D, 0x3F, 0xFF, 0xF2, 0xF0, 0x00, 0x00, 0x2E, 0x3F, 0xFF,
+ 0xFF, 0xFF, 0xE0, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0x4F, 0x40, 0x3D, 0x3F, 0xFF, 0xF4, 0xF4, 0x00, 0x00, 0x7C, 0x3F, 0xFF,
+ 0xFF, 0xFF, 0xFE, 0x55, 0xAF, 0xFF, 0xFF, 0xFF, 0x4F, 0x40, 0x3D, 0x3F, 0xFF, 0xF8, 0xBC, 0x00, 0x00, 0xF8, 0xBF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0x40, 0x3D, 0x3F, 0xFF, 0xFC, 0x2F, 0x40, 0x07, 0xF0, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0x40, 0x3D, 0x3F, 0xFF, 0xFE, 0x0B, 0xFA, 0xBF, 0xC2, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0x40, 0x3D, 0x3F, 0xFF, 0xFF, 0x82, 0xFF, 0xFE, 0x0B, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0x40, 0x3D, 0x3F, 0xFF, 0xFF, 0xE0, 0x2A, 0xA0, 0x2F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0x40, 0x3D, 0x3F, 0xFF, 0xFF, 0xFE, 0x40, 0x06, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x40, 0x3D, 0x2F, 0xFF, 0xFF, 0xFF, 0xFE, 0xBF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x2F, 0x40, 0x3E, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xBE, 0x00, 0x2F, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE2, 0xF8, 0x00, 0x07, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0xE0, 0x00, 0x02, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x00, 0xB8, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8B, 0x80, 0x00, 0x00, 0xB8, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8B, 0x80, 0x00, 0x00, 0x7C, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8B, 0x80, 0x00, 0x00, 0x7C, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8B, 0x80, 0x00, 0x00, 0xB8, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x00, 0xB8, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD3, 0xE0, 0x00, 0x02, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0xF8, 0x00, 0x07, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xBE, 0x40, 0x2F, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x2F, 0xFF, 0xFE, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0xFF, 0xE4, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x04, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x40, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+/* Main Menu Backward */
+
+const uint16_t iconBWColors[] = {
+ 0x9CC, 0x63F3, 0x7475, 0xFFFF
+};
+
+const uint8_t iconBWBitmap[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x01, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+/* Main Menu Return */
+
+const uint16_t iconReturnColors[] = {
+ 0xA22B, 0xBBD0, 0xFFDF, 0x0
+};
+
+const uint8_t iconReturnBitmap[] = {
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x06, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x06, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0x1A, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0x06, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA9, 0x56, 0xAA, 0x01, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x6A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x1A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x06, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x01, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xA5, 0x55, 0x55, 0x55, 0x55, 0x54, 0x00, 0x00, 0x6A, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x01, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x06, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x1A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x6A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA9, 0x56, 0xAA, 0x01, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0x06, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0x1A, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xA8, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x55, 0x55, 0x55, 0x54, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55, 0x55, 0x55, 0x55, 0x56, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x40, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA4, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x40, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA4, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA
+};
+
+/* Main Menu Forward */
+
+const uint16_t iconFWColors[] = {
+ 0x9CC, 0x5371, 0x7495, 0xFFFF
+};
+
+const uint8_t iconFWBitmap[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF9, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x64, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+/* DIY-Thermocam Logo */
+
+const uint16_t logoColors[] = {
+ 0x2C56, 0x44B7, 0x6538, 0xEA06, 0xF32B, 0xF40F, 0x85DA, 0x961A, 0xAE7B, 0xB69C, 0xF534, 0xFE17, 0xC6FD, 0xD75D, 0xFE99, 0xFFFF
+};
+
+const uint8_t logoBitmap[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x20, 0x00, 0x00, 0x02, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xCF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x18, 0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x1F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x01, 0xDF, 0xFF, 0xFF, 0xFD, 0x10, 0x00, 0x00, 0x00, 0x0C,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x07,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x02,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xD6, 0x66, 0x66, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0x82, 0x22, 0x21, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xD6, 0x66, 0x66, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0x72, 0x22, 0x21, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xD7, 0x66, 0x66, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x62, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00,
+ 0x22, 0x22, 0x22, 0x22, 0x26, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0x43, 0x3B, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFA, 0x33, 0x33, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x7D, 0xDD, 0xDD, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xDD, 0xDD, 0xD7, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDC, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x82, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x28, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xCD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFC, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xCF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF,
+ 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xFF,
+ 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xFF,
+ 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x97, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF,
+ 0xF9, 0x00, 0x00, 0x00, 0x00, 0x01, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x10, 0x00, 0x00, 0x00, 0x00, 0x9F,
+ 0xF2, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x2F,
+ 0xF0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x0F,
+ 0xC0, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x0C,
+ 0x80, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x08,
+ 0x70, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x00,
+ 0x6D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xF4, 0x33, 0x33, 0xEF, 0xFD, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF4, 0x33, 0x33, 0xEF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xF4, 0x33, 0x33, 0xEF, 0xFF, 0x20, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xFF, 0xF4, 0x33, 0x33, 0xEF, 0xFF, 0xD1, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xFF, 0xFF, 0xF4, 0x33, 0x33, 0xEF, 0xFF, 0xFF, 0x71, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xFF, 0xFF, 0xFF, 0xF4, 0x33, 0x33, 0xEF, 0xFF, 0xFF, 0xFF, 0x81, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x33, 0x33, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x10, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xEA, 0x53, 0x33, 0x33, 0x4A, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x01, 0xDF, 0xFF, 0xFF, 0xFF, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFE, 0x53, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x4A, 0xFF, 0xFF, 0xFF,
+ 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFD, 0x86, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFB, 0x43, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x35, 0xFF, 0xFF,
+ 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x01, 0xDF, 0xFF, 0xFE, 0x43, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3A, 0xFF,
+ 0xFF, 0xFD, 0x10, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xA3, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x4E,
+ 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xF5, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0xEF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x53, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0x3E, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF5, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0x33, 0xEF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xA3, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0x33, 0x4F, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFE, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x5B, 0xEE, 0xEE, 0xA5, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0x33, 0x35, 0xFF, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xF4, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x33, 0x33, 0x33, 0x33,
+ 0x33, 0x33, 0xBF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xB3, 0x33, 0x33, 0x33, 0x33, 0x33, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x33, 0x33, 0x33,
+ 0x33, 0x33, 0x4F, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xFF, 0x43, 0x33, 0x33, 0x33, 0x33, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x53, 0x33, 0x33,
+ 0x33, 0x33, 0x3B, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFB, 0x33, 0x33, 0x33, 0x33, 0x33, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0x33, 0x33,
+ 0x33, 0x33, 0x34, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xF4, 0x33, 0x33, 0x33, 0x33, 0x3A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x43, 0x33,
+ 0x33, 0x33, 0x33, 0xEF, 0xFF, 0x60, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xF3, 0x33, 0x33, 0x33, 0x33, 0x4F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0x33,
+ 0x33, 0x33, 0x33, 0x5F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xB3, 0x33, 0x33, 0x33, 0x33, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0x33,
+ 0x33, 0x33, 0x33, 0x4F, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x53, 0x33, 0x33, 0x33, 0x34, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x33,
+ 0x33, 0x33, 0x33, 0x3F, 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x43, 0x33, 0x33, 0x33, 0x3A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x33,
+ 0x33, 0x33, 0x33, 0x3E, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0x33, 0x33, 0x33, 0x33, 0x3B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x43,
+ 0x33, 0x33, 0x33, 0x3A, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0x33, 0x33, 0x33, 0x33, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x53,
+ 0x33, 0x33, 0x33, 0x3A, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0x33, 0x33, 0x33, 0x33, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x53,
+ 0x33, 0x33, 0x33, 0x3A, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0x33, 0x33, 0x33, 0x33, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x53,
+ 0x33, 0x33, 0x33, 0x3A, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0x33, 0x33, 0x33, 0x33, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x53,
+ 0x33, 0x33, 0x33, 0x3A, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x43, 0x33, 0x33, 0x33, 0x3A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x33,
+ 0x33, 0x33, 0x33, 0x3B, 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x53, 0x33, 0x33, 0x33, 0x35, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x33,
+ 0x33, 0x33, 0x33, 0x3E, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xA3, 0x33, 0x33, 0x33, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x33,
+ 0x33, 0x33, 0x33, 0x3F, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xE3, 0x33, 0x33, 0x33, 0x33, 0xAF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x33,
+ 0x33, 0x33, 0x33, 0x4F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xF3, 0x33, 0x33, 0x33, 0x33, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x53, 0x33,
+ 0x33, 0x33, 0x33, 0xAF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF5, 0x33, 0x33, 0x33, 0x33, 0x34, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x33, 0x33,
+ 0x33, 0x33, 0x33, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xFE, 0x33, 0x33, 0x33, 0x33, 0x33, 0x5F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0x33, 0x33,
+ 0x33, 0x33, 0x35, 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0x53, 0x33, 0x33, 0x33, 0x33, 0x34, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x33, 0x33, 0x33,
+ 0x33, 0x33, 0x3E, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xE3, 0x33, 0x33, 0x33, 0x33, 0x33, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x53, 0x33, 0x33, 0x33,
+ 0x33, 0x33, 0x5F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFA, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x4A, 0xFF, 0xFF, 0xFF, 0xFE, 0x53, 0x33, 0x33, 0x33, 0x33,
+ 0x33, 0x33, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0x43, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x45, 0x44, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0x33, 0x3B, 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF4, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0x33, 0x5F, 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFE, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0x35, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE3, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0x5F, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0x43, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3A,
+ 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xF5, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xEF,
+ 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xE4, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xAF, 0xFF,
+ 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xFF, 0xFF, 0xB4, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x5F, 0xFF, 0xFF,
+ 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0xCF, 0xFF, 0xFF, 0xFA, 0x43, 0x33, 0x33, 0x33, 0x33, 0x45, 0xEF, 0xFF, 0xFF, 0xFC,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xDF, 0xFF, 0xFF, 0xFF, 0xEE, 0xBA, 0xAE, 0xEF, 0xFF, 0xFF, 0xFF, 0xFD, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x60, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x6C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x67, 0x88, 0x88, 0x76, 0x20, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xDF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x7C, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, 0x00, 0x00, 0x07,
+ 0x70, 0x00, 0x00, 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDC, 0x86, 0x66, 0x66, 0x68, 0xCD, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x00, 0x07,
+ 0x90, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0x00, 0x00, 0x00, 0x09,
+ 0xD0, 0x00, 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x0D,
+ 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x0F,
+ 0xF6, 0x00, 0x00, 0x00, 0x00, 0x2D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD2, 0x00, 0x00, 0x00, 0x00, 0x6F,
+ 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF,
+ 0xFF, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF,
+ 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xFF,
+ 0xFF, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xFF,
+ 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
diff --git a/Firmware_V2/src/gui/bitmaps.h b/Firmware_V2/src/gui/bitmaps.h
new file mode 100644
index 0000000..7cc66a8
--- /dev/null
+++ b/Firmware_V2/src/gui/bitmaps.h
@@ -0,0 +1,66 @@
+/*
+*
+* BITMAPS - Icons and graphics shown inside the GUI
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef BITMAPS_H
+#define BITMAPS_H
+
+/*################# PUBLIC CONSTANTS, VARIABLES & DATA TYPES ##################*/
+
+extern const uint16_t icon1Colors[];
+extern const uint8_t icon1Bitmap[];
+extern const uint16_t icon2Colors[];
+extern const uint8_t icon2Bitmap[];
+extern const uint16_t icon3Colors[];
+extern const uint8_t icon3Bitmap[];
+extern const uint16_t icon4Colors[];
+extern const uint8_t icon4Bitmap[];
+extern const uint16_t icon5Colors[];
+extern const uint8_t icon5Bitmap_1[];
+#if defined(__MK66FX1M0__)
+extern const uint8_t icon5Bitmap_2[];
+#else
+extern const uint8_t* icon5Bitmap_2;
+#endif
+extern const uint16_t icon6Colors[];
+extern const uint8_t icon6Bitmap[];
+extern const uint16_t icon7Colors[];
+extern const uint8_t icon7Bitmap[];
+extern const uint16_t icon8Colors[];
+extern const uint8_t icon8Bitmap_1[];
+#if defined(__MK66FX1M0__)
+extern const uint8_t icon8Bitmap_2[];
+#else
+extern const uint8_t* icon8Bitmap_2;
+#endif
+extern const uint16_t icon9Colors[];
+extern const uint8_t icon9Bitmap[];
+extern const uint16_t icon10Colors[];
+extern const uint8_t icon10Bitmap[];
+extern const uint16_t icon11_1Colors[];
+extern const uint8_t icon11_1Bitmap[];
+extern const uint16_t icon11_2Colors[];
+extern const uint8_t icon11_2Bitmap[];
+extern const uint16_t icon12Colors[];
+extern const uint8_t icon12Bitmap[];
+extern const uint16_t iconBWColors[];
+extern const uint8_t iconBWBitmap[];
+extern const uint16_t iconReturnColors[];
+extern const uint8_t iconReturnBitmap[];
+extern const uint16_t iconFWColors[];
+extern const uint8_t iconFWBitmap[];
+extern const uint16_t logoColors[];
+extern const uint8_t logoBitmap[];
+
+#endif /* BITMAPS_H */
diff --git a/Firmware_V2/src/gui/buttons.cpp b/Firmware_V2/src/gui/buttons.cpp
new file mode 100644
index 0000000..2030565
--- /dev/null
+++ b/Firmware_V2/src/gui/buttons.cpp
@@ -0,0 +1,392 @@
+/*
+ *
+ * Buttons - Touch buttons for the GUI
+ *
+ * DIY-Thermocam Firmware
+ *
+ * GNU General Public License v3.0
+ *
+ * Copyright by Max Ritter
+ *
+ * http://www.diy-thermocam.net
+ * https://github.com/maxritter/DIY-Thermocam
+ *
+ */
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*################# DATA TYPES, CONSTANTS & MACRO DEFINITIONS #################*/
+
+#define BUTTON_DISABLED 0x0001
+#define BUTTON_SYMBOL 0x0002
+#define BUTTON_SYMBOL_REP_3X 0x0004
+#define BUTTON_BITMAP 0x0008
+#define BUTTON_NO_BORDER 0x0010
+#define BUTTON_UNUSED 0x8000
+
+typedef struct {
+ uint16_t pos_x, pos_y, width, height;
+ uint16_t flags;
+ boolean largetouch;
+ char *label;
+ const uint8_t* data;
+ const uint16_t* palette;
+} button_type;
+
+/*######################### STATIC DATA DECLARATIONS ##########################*/
+
+//Store up to 20 buttons
+static button_type buttons[20];
+//Button attributes
+static word buttons_colorText;
+static word buttons_colorTextInactive;
+static word buttons_colorBackGround;
+static word buttons_colorBorder;
+static word buttons_colorHilite;
+//Button fonts
+static uint8_t* buttons_fontText;
+static uint8_t* buttons_fontSymbol;
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* Add a text button */
+int buttons_addButton(uint16_t x, uint16_t y, uint16_t width, uint16_t height, char *label, uint16_t flags, boolean largetouch)
+{
+ int btcnt = 0;
+
+ while (((buttons[btcnt].flags & BUTTON_UNUSED) == 0)
+ && (btcnt < 20))
+ btcnt++;
+
+ if (btcnt == 20)
+ return -1;
+ else {
+ buttons[btcnt].pos_x = x;
+ buttons[btcnt].pos_y = y;
+ buttons[btcnt].width = width;
+ buttons[btcnt].height = height;
+ buttons[btcnt].flags = flags;
+ buttons[btcnt].label = label;
+ buttons[btcnt].data = NULL;
+ buttons[btcnt].palette = NULL;
+ buttons[btcnt].largetouch = largetouch;
+ return btcnt;
+ }
+}
+
+/* Add a bitmap button */
+int buttons_addButton(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t* data, const uint16_t* palette, uint16_t flags)
+{
+ int btcnt = 0;
+
+ while (((buttons[btcnt].flags & BUTTON_UNUSED) == 0) && (btcnt < 20))
+ btcnt++;
+
+ if (btcnt == 20)
+ return -1;
+ else
+ {
+ buttons[btcnt].pos_x = x;
+ buttons[btcnt].pos_y = y;
+ buttons[btcnt].width = width;
+ buttons[btcnt].height = height;
+ buttons[btcnt].flags = flags | BUTTON_BITMAP;
+ buttons[btcnt].label = NULL;
+ buttons[btcnt].data = data;
+ buttons[btcnt].palette = palette;
+ return btcnt;
+ }
+}
+
+/* Draw a specific button */
+void buttons_drawButton(int buttonID) {
+ int text_x, text_y;
+ uint8_t *_font_current = display_getFont();
+ ;
+ word _current_color = display_getColor();
+ word _current_back = display_getBackColor();
+
+ if (buttons[buttonID].flags & BUTTON_BITMAP) {
+ display_writeRect2BPP(buttons[buttonID].pos_x, buttons[buttonID].pos_y,
+ buttons[buttonID].width, buttons[buttonID].height,
+ buttons[buttonID].data, buttons[buttonID].palette);
+ if (!(buttons[buttonID].flags & BUTTON_NO_BORDER)) {
+ if ((buttons[buttonID].flags & BUTTON_DISABLED))
+ display_setColor(buttons_colorTextInactive);
+ else
+ display_setColor(buttons_colorBorder);
+ display_drawRoundRect(buttons[buttonID].pos_x, buttons[buttonID].pos_y,
+ buttons[buttonID].pos_x + buttons[buttonID].width,
+ buttons[buttonID].pos_y + buttons[buttonID].height);
+ display_drawRoundRect(buttons[buttonID].pos_x - 1, buttons[buttonID].pos_y - 1,
+ buttons[buttonID].pos_x + buttons[buttonID].width + 1,
+ buttons[buttonID].pos_y + buttons[buttonID].height + 1);
+ }
+ }
+ else {
+ display_setColor(buttons_colorBackGround);
+ display_fillRoundRect(buttons[buttonID].pos_x, buttons[buttonID].pos_y,
+ buttons[buttonID].pos_x + buttons[buttonID].width,
+ buttons[buttonID].pos_y + buttons[buttonID].height);
+ display_setColor(buttons_colorBorder);
+ display_drawRoundRect(buttons[buttonID].pos_x, buttons[buttonID].pos_y,
+ buttons[buttonID].pos_x + buttons[buttonID].width,
+ buttons[buttonID].pos_y + buttons[buttonID].height);
+ display_drawRoundRect(buttons[buttonID].pos_x - 1, buttons[buttonID].pos_y - 1,
+ buttons[buttonID].pos_x + buttons[buttonID].width + 1,
+ buttons[buttonID].pos_y + buttons[buttonID].height + 1);
+ if (buttons[buttonID].flags & BUTTON_DISABLED)
+ display_setColor(buttons_colorTextInactive);
+ else
+ display_setColor(buttons_colorText);
+ if (buttons[buttonID].flags & BUTTON_SYMBOL) {
+ display_setFont(buttons_fontSymbol);
+ text_x = (buttons[buttonID].width / 2) - (display_getFontXsize() / 2)
+ + buttons[buttonID].pos_x;
+ text_y = (buttons[buttonID].height / 2)
+ - (display_getFontYsize() / 2) + buttons[buttonID].pos_y;
+ }
+ else {
+ display_setFont(buttons_fontText);
+ text_x = ((buttons[buttonID].width / 2)
+ - ((strlen(buttons[buttonID].label) * display_getFontXsize())
+ / 2)) + buttons[buttonID].pos_x;
+ text_y = (buttons[buttonID].height / 2)
+ - (display_getFontYsize() / 2) + buttons[buttonID].pos_y;
+ }
+ display_setBackColor(buttons_colorBackGround);
+ display_print(buttons[buttonID].label, text_x, text_y);
+ if ((buttons[buttonID].flags & BUTTON_SYMBOL)
+ && (buttons[buttonID].flags & BUTTON_SYMBOL_REP_3X)) {
+ display_print(buttons[buttonID].label,
+ text_x - display_getFontXsize(), text_y);
+ display_print(buttons[buttonID].label,
+ text_x + display_getFontXsize(), text_y);
+ }
+ }
+ display_setFont(_font_current);
+ display_setColor(_current_color);
+ display_setBackColor(_current_back);
+}
+
+/* Draw all buttons */
+void buttons_drawButtons() {
+ for (int i = 0; i < 20; i++) {
+ if ((buttons[i].flags & BUTTON_UNUSED) == 0)
+ buttons_drawButton(i);
+ }
+}
+
+/* Enable a specific button */
+void buttons_enableButton(int buttonID, boolean redraw) {
+ if (!(buttons[buttonID].flags & BUTTON_UNUSED)) {
+ buttons[buttonID].flags = buttons[buttonID].flags & ~BUTTON_DISABLED;
+ if (redraw)
+ buttons_drawButton(buttonID);
+ }
+}
+
+/* Disable a specific button */
+void buttons_disableButton(int buttonID, boolean redraw) {
+ if (!(buttons[buttonID].flags & BUTTON_UNUSED)) {
+ buttons[buttonID].flags = buttons[buttonID].flags | BUTTON_DISABLED;
+ if (redraw)
+ buttons_drawButton(buttonID);
+ }
+}
+
+/* Relabel a specific button */
+void buttons_relabelButton(int buttonID, char *label, boolean redraw) {
+ if (!(buttons[buttonID].flags & BUTTON_UNUSED)) {
+ buttons[buttonID].label = label;
+ if (redraw)
+ buttons_drawButton(buttonID);
+ }
+}
+
+/* Check if the button is enabled */
+boolean buttons_buttonEnabled(int buttonID) {
+ return !(buttons[buttonID].flags & BUTTON_DISABLED);
+}
+
+/* Delete a specific button */
+void buttons_deleteButton(int buttonID) {
+ if (!(buttons[buttonID].flags & BUTTON_UNUSED))
+ buttons[buttonID].flags = BUTTON_UNUSED;
+}
+
+/* Delete all buttons */
+void buttons_deleteAllButtons() {
+ for (int i = 0; i < 20; i++) {
+ buttons[i].pos_x = 0;
+ buttons[i].pos_y = 0;
+ buttons[i].width = 0;
+ buttons[i].height = 0;
+ buttons[i].flags = BUTTON_UNUSED;
+ buttons[i].label = (char*) "";
+ }
+}
+
+/* Check which button is pressed */
+int buttons_checkButtons(boolean timeout, boolean fast) {
+ TS_Point p = touch_getPoint();
+ int x = p.x;
+ int y = p.y;
+ int result = -1;
+ word _current_color = display_getColor();
+ int xpos, ypos, width, height;
+ for (int i = 0; i < 20; i++) {
+ xpos = buttons[i].pos_x;
+ ypos = buttons[i].pos_y;
+ width = buttons[i].width;
+ height = buttons[i].height;
+ if (buttons[i].largetouch) {
+ xpos -= 30;
+ ypos -= 20;
+ width += 60;
+ height += 40;
+ }
+ if (((buttons[i].flags & BUTTON_UNUSED) == 0)
+ && ((buttons[i].flags & BUTTON_DISABLED) == 0)
+ && (result == -1)) {
+ if ((x >= xpos)
+ && (x <= (xpos + width))
+ && (y >= ypos)
+ && (y <= (ypos + height)))
+ result = i;
+ }
+ }
+ if (result != -1) {
+ if (!(buttons[result].flags & BUTTON_NO_BORDER)) {
+ display_setColor(buttons_colorHilite);
+ if (buttons[result].flags & BUTTON_BITMAP)
+ display_drawRoundRect(buttons[result].pos_x,
+ buttons[result].pos_y,
+ buttons[result].pos_x + buttons[result].width,
+ buttons[result].pos_y + buttons[result].height);
+ else
+ display_drawRoundRect(buttons[result].pos_x,
+ buttons[result].pos_y,
+ buttons[result].pos_x + buttons[result].width,
+ buttons[result].pos_y + buttons[result].height);
+ display_drawRoundRect(buttons[result].pos_x - 1,
+ buttons[result].pos_y - 1,
+ buttons[result].pos_x + buttons[result].width + 1,
+ buttons[result].pos_y + buttons[result].height + 1);
+ }
+ }
+ if (fast) {
+ long time = millis();
+ while ((touch_touched() == 1)
+ && ((millis() - time) < 50)) {
+ };
+ }
+ else if (timeout) {
+ long time = millis();
+ while ((touch_touched() == 1)
+ && ((millis() - time) < 150)) {
+ };
+ }
+ else {
+ while (touch_touched() == 1) {
+ };
+ }
+ if (result != -1) {
+ if (!(buttons[result].flags & BUTTON_NO_BORDER)) {
+ display_setColor(buttons_colorBorder);
+ if (buttons[result].flags & BUTTON_BITMAP)
+ display_drawRoundRect(buttons[result].pos_x,
+ buttons[result].pos_y,
+ buttons[result].pos_x + buttons[result].width,
+ buttons[result].pos_y + buttons[result].height);
+ else
+ display_drawRoundRect(buttons[result].pos_x,
+ buttons[result].pos_y,
+ buttons[result].pos_x + buttons[result].width,
+ buttons[result].pos_y + buttons[result].height);
+ display_drawRoundRect(buttons[result].pos_x - 1,
+ buttons[result].pos_y - 1,
+ buttons[result].pos_x + buttons[result].width + 1,
+ buttons[result].pos_y + buttons[result].height + 1);
+ }
+ }
+ display_setColor(_current_color);
+ return result;
+}
+
+/* Set a specific button to active */
+void buttons_setActive(int buttonID) {
+ int text_x, text_y;
+ display_setColor(VGA_AQUA);
+ display_fillRect(buttons[buttonID].pos_x + 3, buttons[buttonID].pos_y + 3,
+ buttons[buttonID].pos_x + buttons[buttonID].width - 3,
+ buttons[buttonID].pos_y + buttons[buttonID].height - 3);
+ display_setFont(buttons_fontText);
+ display_setColor(buttons_colorText);
+ text_x = ((buttons[buttonID].width / 2)
+ - ((strlen(buttons[buttonID].label) * display_getFontXsize()) / 2))
+ + buttons[buttonID].pos_x;
+ text_y = (buttons[buttonID].height / 2) - (display_getFontYsize() / 2)
+ + buttons[buttonID].pos_y;
+ display_setBackColor(VGA_AQUA);
+ display_print(buttons[buttonID].label, text_x, text_y);
+}
+
+/* Set a specific button to inactive */
+void buttons_setInactive(int buttonID) {
+ int text_x, text_y;
+ display_setColor(buttons_colorBackGround);
+ display_fillRect(buttons[buttonID].pos_x + 3, buttons[buttonID].pos_y + 3,
+ buttons[buttonID].pos_x + buttons[buttonID].width - 3,
+ buttons[buttonID].pos_y + buttons[buttonID].height - 3);
+ display_setFont(buttons_fontText);
+ display_setColor(buttons_colorText);
+ text_x = ((buttons[buttonID].width / 2)
+ - ((strlen(buttons[buttonID].label) * display_getFontXsize()) / 2))
+ + buttons[buttonID].pos_x;
+ text_y = (buttons[buttonID].height / 2) - (display_getFontYsize() / 2)
+ + buttons[buttonID].pos_y;
+ display_setBackColor(buttons_colorBackGround);
+ display_print(buttons[buttonID].label, text_x, text_y);
+}
+
+/* Set the text font of all buttons */
+void buttons_setTextFont(const uint8_t* font) {
+ buttons_fontText = (uint8_t*) font;
+}
+
+/* Set the symbol font of all buttons */
+void buttons_setSymbolFont(const uint8_t* font) {
+ buttons_fontSymbol = (uint8_t*) font;
+}
+
+/* Set the buttons color */
+void buttons_setButtonColors(word atxt, word iatxt, word brd, word brdhi,
+ word back) {
+ buttons_colorText = atxt;
+ buttons_colorTextInactive = iatxt;
+ buttons_colorBackGround = back;
+ buttons_colorBorder = brd;
+ buttons_colorHilite = brdhi;
+}
+
+/* Init the buttons */
+void buttons_init() {
+ buttons_deleteAllButtons();
+ buttons_colorText = VGA_WHITE;
+ buttons_colorTextInactive = VGA_GRAY;
+ buttons_colorBackGround = VGA_BLUE;
+ buttons_colorBorder = VGA_BLACK;
+ buttons_colorHilite = VGA_BLUE;
+ buttons_fontText = NULL;
+ buttons_fontSymbol = NULL;
+ buttons_setButtonColors(VGA_BLACK, VGA_BLACK, VGA_BLACK, VGA_BLUE,
+ VGA_WHITE);
+}
diff --git a/Firmware_V2/src/gui/buttons.h b/Firmware_V2/src/gui/buttons.h
new file mode 100644
index 0000000..1027798
--- /dev/null
+++ b/Firmware_V2/src/gui/buttons.h
@@ -0,0 +1,39 @@
+/*
+*
+* Buttons - Touch buttons for the GUI
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef BUTTONS_H
+#define BUTTONS_H
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+int buttons_addButton(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t* data, const uint16_t* palette, uint16_t flags = 0);
+int buttons_addButton(uint16_t x, uint16_t y, uint16_t width, uint16_t height, char *label, uint16_t flags = 0, boolean largetouch = 0);
+boolean buttons_buttonEnabled(int buttonID);
+int buttons_checkButtons(boolean timeout = 0, boolean fast = 0);
+void buttons_deleteAllButtons();
+void buttons_deleteButton(int buttonID);
+void buttons_disableButton(int buttonID, boolean redraw = 0);
+void buttons_drawButtons();
+void buttons_drawButton(int buttonID);
+void buttons_enableButton(int buttonID, boolean redraw = 0);
+void buttons_init();
+void buttons_relabelButton(int buttonID, char *label, boolean redraw = 0);
+void buttons_setActive(int buttonID);
+void buttons_setButtonColors(word atxt, word iatxt, word brd, word brdhi, word back);
+void buttons_setInactive(int buttonID);
+void buttons_setSymbolFont(const uint8_t* font);
+void buttons_setTextFont(const uint8_t* font);
+
+#endif /* BUTTONS_H */
diff --git a/Firmware_V2/src/gui/firststart.cpp b/Firmware_V2/src/gui/firststart.cpp
new file mode 100644
index 0000000..bd02974
--- /dev/null
+++ b/Firmware_V2/src/gui/firststart.cpp
@@ -0,0 +1,416 @@
+/*
+*
+* FIRST START - Menu that is displayed on the first device start
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* Check if the first start needs to be done */
+boolean checkFirstStart() {
+ return EEPROM.read(eeprom_firstStart) != eeprom_setValue;
+}
+
+/* Show welcome Screen for the first start procedure */
+void welcomeScreen() {
+ //Background & Title
+ display_fillScr(200, 200, 200);
+ display_setBackColor(200, 200, 200);
+ display_setFont(smallFont);
+ display_printC("Welcome to the", CENTER, 20);
+ display_setFont(bigFont);
+
+ //DIY-Thermocam V2
+ if (teensyVersion == teensyVersion_new)
+ display_printC("DIY-Thermocam V2", CENTER, 60, VGA_BLUE);
+
+ //DIY-Thermocam V1
+ else if (mlx90614Version == mlx90614Version_new)
+ display_printC("DIY-Thermocam V1", CENTER, 60, VGA_BLUE);
+
+ //Thermocam V4
+ else
+ display_printC("Cheap-Thermocam V4", CENTER, 60, VGA_BLUE);
+
+ //Explanation
+ display_setFont(smallFont);
+ display_printC("This is the first time setup.", CENTER, 110);
+ display_printC("It will guide you through the", CENTER, 140);
+ display_printC("basic settings for your device.", CENTER, 170);
+ display_printC("-> Please touch screen <-", CENTER, 210, VGA_BLUE);
+
+ //Wait for touch press or updater request
+ while (!touch_touched())
+ checkForUpdater();
+
+ //Touch release again
+ while (touch_touched());
+}
+
+/* Shows an info screen during the first start procedure */
+void infoScreen(String* text, bool cont) {
+ //Background & Title
+ display_fillScr(200, 200, 200);
+ display_setBackColor(200, 200, 200);
+ display_setFont(bigFont);
+ display_printC(text[0], CENTER, 20, VGA_BLUE);
+
+ //Content
+ display_setFont(smallFont);
+ display_printC(text[1], CENTER, 55);
+ display_printC(text[2], CENTER, 80);
+ display_printC(text[3], CENTER, 105);
+ display_printC(text[4], CENTER, 130);
+
+ //Show hint to touch the screen
+ if (cont) {
+ display_printC(text[5], CENTER, 155);
+ display_printC(text[6], CENTER, 180);
+ display_printC("-> Please touch screen <-", CENTER, 212, VGA_BLUE);
+ //Wait for touch press or updater request
+ while (!touch_touched())
+ checkForUpdater();
+ //Touch release again
+ while (touch_touched());
+ }
+
+ //Show more information
+ else {
+ display_printC(text[5], CENTER, 180);
+ display_printC(text[6], CENTER, 205);
+ }
+}
+
+/* Setting screen for the time and date */
+void timeDateScreen() {
+ //Content
+ String text[7];
+ text[0] = "Set Time & Date";
+ text[1] = "In the next screens, you can";
+ text[2] = "set the time and date, so ";
+ text[3] = "that it matches your current";
+ text[4] = "time zone. If the settings do";
+ text[5] = "not survive a reboot, check";
+ text[6] = "the coin cell battery voltage.";
+ infoScreen(text);
+
+ //Reset values
+ setTime(12, 30, 30, 15, 6, 2017);
+
+ //Adjust time
+ timeMenu(true);
+ timeMenuHandler(true);
+
+ //Adjust date
+ dateMenu(true);
+ dateMenuHandler(true);
+}
+
+/* Setting screen for the temperature format */
+void tempFormatScreen() {
+ //Content
+ String text[7];
+ text[0] = "Set Temp. Format";
+ text[1] = "In the next screen, you can";
+ text[2] = "set the temperature format ";
+ text[3] = "for the temperature display_";
+ text[4] = "Choose between Celsius or";
+ text[5] = "Fahrenheit, the conversion will";
+ text[6] = "be done automatically.";
+ infoScreen(text);
+
+ //Temperature format menu
+ tempFormatMenu(true);
+}
+
+/* Setting screen for the convert image option */
+void convertImageScreen() {
+ //Content
+ String text[7];
+ text[0] = "Convert DAT to BMP";
+ text[1] = "In the next screen, select if";
+ text[2] = "you also want to create a bitmap";
+ text[3] = "file for every saved thermal";
+ text[4] = "raw image file on the device. ";
+ text[5] = "You can still convert images man-";
+ text[6] = "ually in the load menu later.";
+ infoScreen(text);
+
+ //Convert image menu
+ convertImageMenu(true);
+}
+
+/* Setting screen for the visual image option */
+void visualImageScreen() {
+ //Content
+ String text[7];
+ text[0] = "Save visual image";
+ text[1] = "In the next screen, choose";
+ text[2] = "if you want to save an addi-";
+ text[3] = "tional visual image together";
+ text[4] = "with each saved thermal image.";
+ text[5] = "Enable this if you want to";
+ text[6] = "create combined images on the PC.";
+ infoScreen(text);
+
+ //Visual image menu
+ visualImageMenu(true);
+}
+
+/* Setting screen for the combined image alignment */
+void combinedAlignmentScreen() {
+ //Content
+ String text[7];
+ text[0] = "Combined Alignment";
+ text[1] = "In the next screen, you can";
+ text[2] = "move, increase or decrease";
+ text[3] = "the visual image on top of the";
+ text[4] = "thermal image. Press the A-button";
+ text[5] = "to change the alpha transparency";
+ text[6] = "and touch the middle to refresh.";
+ infoScreen(text);
+
+ //Set color scheme to rainbow
+ colorMap = colorMap_rainbow;
+ colorElements = 256;
+
+ //Disable showmenu
+ showMenu = showMenu_disabled;
+
+ //Adjust combined menu
+ adjustCombinedNewMenu(true);
+}
+
+/* Setting screen for the calibration procedure */
+void calibrationHelperScreen() {
+ //Content
+ String text[7];
+ text[0] = "Calibration";
+ text[1] = "Before using the device, you need";
+ text[2] = "to calibrate it first. Point the ";
+ text[3] = "device to different hot and cold";
+ text[4] = "objects in the surrounding area";
+ text[5] = "slowly, until the calibration";
+ text[6] = "process has been completed.";
+ infoScreen(text);
+
+ //Calibration procedure
+ calibrationProcess(false, true);
+}
+
+/* Format the SD card for the first time */
+void firstFormat() {
+ //ThermocamV4 or DIY-Thermocam V2, check SD card
+ if ((mlx90614Version == mlx90614Version_old) ||
+ (teensyVersion == teensyVersion_new)) {
+
+ //Show message
+ showFullMessage((char*) "Checking SD card..");
+
+ //Check for SD card
+ if (!checkSDCard()) {
+ showFullMessage((char*) "Please insert SD card");
+ //Wait until card is inserted
+ while (!checkSDCard())
+ delay(1000);
+ }
+ }
+
+ //Format the SD card
+ showFullMessage((char*) "Formatting SD card..");
+ formatCard();
+}
+
+/* Show the first start complete screen */
+void firstStartComplete() {
+ //Content
+ String text[7];
+ text[0] = "Setup completed";
+ text[1] = "The first-time setup is";
+ text[2] = "now complete. Please reboot";
+ text[3] = "the device by turning the";
+ text[4] = "power switch off and on again.";
+ text[5] = "Afterwards, you will be redirected";
+ text[6] = "to the align combined menu.";
+ infoScreen(text, false);
+
+ //Wait for hard-reset
+ while (true);
+}
+
+/* Check if the live mode helper needs to be shown */
+boolean checkLiveModeHelper() {
+ return EEPROM.read(eeprom_liveHelper) != eeprom_setValue;
+}
+
+/* Help screen for the first start of live mode */
+void liveModeHelper() {
+ String text[7];
+
+ //Do the first time calibration if spot sensor working and not using radiometric Lepton
+ if (checkDiagnostic(diag_spot) && (leptonVersion != leptonVersion_2_5_shutter)
+ && (leptonVersion != leptonVersion_3_5_shutter))
+ calibrationHelperScreen();
+
+ //Hint screen for the live mode #1
+ text[0] = "First time helper";
+ text[1] = "To enter the live mode menu,";
+ text[2] = "touch the screen. 'Exit' will";
+ text[3] = "bring you to the main menu.";
+ text[4] = "Pressing the push button on";
+ text[5] = "top of the device short takes";
+ text[6] = "an image, long records a video.";
+ infoScreen(text);
+
+ //Hint screen for the live mode #2
+ if ((leptonVersion != leptonVersion_2_5_shutter) && (leptonVersion != leptonVersion_3_5_shutter)) {
+ text[1] = "The device needs 30 seconds to";
+ text[2] = "warmup the sensor, more functions";
+ text[3] = "will be activated afterwards. You";
+ }
+ else {
+ text[1] = "The device has detected that you";
+ text[2] = "are using the radiometric Lepton2.5";
+ text[3] = "sensor and adjusted to that. You";
+ }
+ text[4] = "can lock the limits or toggle dif-";
+ text[5] = "ferent temperature limits by pres-";
+ text[6] = "sing the screen long in live mode.";
+ infoScreen(text);
+
+ //Show waiting message
+ showFullMessage((char*)"Please wait..");
+
+ //Set EEPROM marker to complete
+ EEPROM.write(eeprom_liveHelper, eeprom_setValue);
+}
+
+
+/* Set the EEPROM values to default for the first time */
+void stdEEPROMSet() {
+ //Flash spot sensor, not for radiometric Lepton
+ if ((leptonVersion != leptonVersion_2_5_shutter) && (leptonVersion != leptonVersion_3_5_shutter)) {
+ //Show message
+ showFullMessage((char*) "Flashing spot EEPROM settings..");
+
+ //Only if spot sensor is connected
+ if (checkDiagnostic(diag_spot))
+ {
+ //Set spot maximum temp to 380°C
+ mlx90614_setMax();
+ //Set spot minimum temp to -70°
+ mlx90614_setMin();
+ //Set spot filter settings
+ mlx90614_setFilter();
+ //Set spot emissivity to 0.9
+ mlx90614_setEmissivity();
+ }
+ }
+
+ //Set device EEPROM settings
+ EEPROM.write(eeprom_rotationVert, false);
+ EEPROM.write(eeprom_rotationHorizont, false);
+ EEPROM.write(eeprom_spotEnabled, false);
+ EEPROM.write(eeprom_colorbarEnabled, true);
+ EEPROM.write(eeprom_batteryEnabled, true);
+ EEPROM.write(eeprom_timeEnabled, true);
+ EEPROM.write(eeprom_dateEnabled, true);
+ EEPROM.write(eeprom_storageEnabled, true);
+ EEPROM.write(eeprom_displayMode, displayMode_thermal);
+ EEPROM.write(eeprom_textColor, textColor_white);
+ EEPROM.write(eeprom_minMaxPoints, minMaxPoints_max);
+ EEPROM.write(eeprom_screenOffTime, screenOffTime_disabled);
+ EEPROM.write(eeprom_hotColdMode, hotColdMode_disabled);
+
+ //Set Color Scheme to Rainbow
+ EEPROM.write(eeprom_colorScheme, colorScheme_rainbow);
+
+ //Set filter type to box blur
+ EEPROM.write(eeprom_filterType, filterType_gaussian);
+
+ //For DIY-Thermocam V2, set HQ res to true
+ if (teensyVersion == teensyVersion_new)
+ EEPROM.write(eeprom_hqRes, true);
+
+ //Set disable shutter to false
+ EEPROM.write(eeprom_noShutter, false);
+
+ //Battery gauge standard compensation values
+ //DIY-Thermocam V1
+ if ((teensyVersion == teensyVersion_old) && (mlx90614Version == mlx90614Version_new))
+ EEPROM.write(eeprom_batComp, 0);
+ //Thermocam V4
+ else if ((teensyVersion == teensyVersion_old) && (mlx90614Version == mlx90614Version_old))
+ EEPROM.write(eeprom_batComp, 0);
+ //DIY-Thermocam V2
+ else
+ EEPROM.write(eeprom_batComp, 20);
+
+ //Set current firmware version
+ EEPROM.write(eeprom_fwVersion, fwVersion);
+
+ //Set first start marker to true
+ EEPROM.write(eeprom_firstStart, eeprom_setValue);
+
+ //Set live helper to false to show it the next time
+ EEPROM.write(eeprom_liveHelper, false);
+}
+
+/* First start setup*/
+void firstStart() {
+ //Clear EEPROM
+ clearEEPROM();
+
+ //Welcome screen
+ welcomeScreen();
+
+ //Hint screen for the time and date settings
+ timeDateScreen();
+
+ //Hint screen for temperature format setting
+ tempFormatScreen();
+
+ //Hint screen for the convert image settings
+ convertImageScreen();
+
+ //Hint screen for the visual image settings
+ visualImageScreen();
+
+ //Format SD card for the first time
+ firstFormat();
+
+ //Set EEPROM values
+ stdEEPROMSet();
+
+ //Show completion message
+ firstStartComplete();
+}
diff --git a/Firmware_V2/src/gui/firststart.h b/Firmware_V2/src/gui/firststart.h
new file mode 100644
index 0000000..8f39451
--- /dev/null
+++ b/Firmware_V2/src/gui/firststart.h
@@ -0,0 +1,37 @@
+/*
+*
+* FIRST START - Menu that is displayed on the first device start
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef FIRSTSTART_H
+#define FIRSTSTART_H
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+void calibrationHelperScreen();
+boolean checkFirstStart();
+boolean checkLiveModeHelper();
+void combinedAlignmentScreen();
+void convertImageScreen();
+void firstFormat();
+void firstStartComplete();
+void firstStart();
+void infoScreen(String* text, bool cont = true);
+void liveModeHelper();
+void stdEEPROMSet();
+void tempFormatScreen();
+void timeDateScreen();
+void visualImageScreen();
+void welcomeScreen();
+
+#endif /* FIRSTSTART_H */
diff --git a/Firmware_V2/src/gui/gui.cpp b/Firmware_V2/src/gui/gui.cpp
new file mode 100644
index 0000000..831e73b
--- /dev/null
+++ b/Firmware_V2/src/gui/gui.cpp
@@ -0,0 +1,239 @@
+/*
+*
+* GUI - Main Methods to lcd the Graphical-User-Interface
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* Converts a given float to char array */
+void floatToChar(char* buffer, float val) {
+ int units = val;
+ int hundredths = val * 100;
+ hundredths = abs(hundredths % 100);
+ sprintf(buffer, "%d.%02d", units, hundredths);
+}
+
+/* Sets the text color to the right one */
+void changeTextColor() {
+ //Red
+ if (textColor == textColor_red)
+ display_setColor(VGA_RED);
+ //Black
+ else if (textColor == textColor_black)
+ display_setColor(VGA_BLACK);
+ //Green
+ else if (textColor == textColor_green)
+ display_setColor(VGA_GREEN);
+ //Blue
+ else if (textColor == textColor_blue)
+ display_setColor(VGA_BLUE);
+ //White
+ else
+ display_setColor(VGA_WHITE);
+}
+
+/* Shows a full screen message */
+void showFullMessage(char* message, bool small) {
+ //Fill screen complete
+ if (!small)
+ display_fillScr(200, 200, 200);
+
+ //Make a round corner around it
+ else {
+ display_setColor(200, 200, 200);
+ display_fillRoundRect(6, 6, 314, 234);
+ }
+
+ //Display the text
+ display_setFont(smallFont);
+ display_setBackColor(200, 200, 200);
+ display_setColor(VGA_BLACK);
+ display_print(message, CENTER, 110);
+}
+
+/* Shows a transparent message in live mode */
+void showTransMessage(char* msg) {
+ //Set text color
+ changeTextColor();
+ //Set background transparent
+ display_setBackColor(VGA_TRANSPARENT);
+ //Display to screen in big font
+ display_setFont(bigFont);
+ //Display higher if spot is enabled
+ if (spotEnabled)
+ display_print(msg, CENTER, 70);
+ else
+ display_print(msg, CENTER, 110);
+ //Switch back to small font
+ display_setFont(smallFont);
+ //Wait some time to read the text
+ delay(1000);
+}
+
+/* Draw a BigFont Text in the center of a menu*/
+void drawCenterElement(int element) {
+ display_setFont(bigFont);
+ display_setColor(VGA_BLACK);
+ display_setBackColor(200, 200, 200);
+ display_printNumI(element, CENTER, 80, 2, '0');
+ display_setFont(smallFont);
+}
+
+/* Draws the border for the main menu */
+void drawMainMenuBorder()
+{
+ display_setColor(VGA_BLACK);
+ display_fillRoundRect(5, 5, 315, 235);
+ display_fillRoundRect(4, 4, 316, 236);
+}
+
+/* Draw a title on the screen */
+void drawTitle(char* name, bool firstStart) {
+ if (firstStart)
+ display_fillScr(200, 200, 200);
+ else {
+ display_setColor(200, 200, 200);
+ display_fillRoundRect(6, 6, 314, 234);
+ }
+ display_setFont(bigFont);
+ display_setBackColor(200, 200, 200);
+ display_setColor(VGA_BLACK);
+ display_print(name, CENTER, 25);
+ display_setFont(smallFont);
+}
+
+/* Shows the hadware diagnostics */
+void showDiagnostic() {
+ //Display title & background
+ display_fillScr(200, 200, 200);
+ display_setFont(bigFont);
+ display_setBackColor(200, 200, 200);
+ display_setColor(VGA_BLUE);
+ display_print((char*) "Self-diagnostic", CENTER, 10);
+
+ //Change text color and font
+ display_setFont(smallFont);
+ display_setColor(VGA_BLACK);
+
+ //Display hardware module names
+ display_print((char*) "Spot sensor ", 50, 50);
+ display_print((char*) "Display ", 50, 70);
+ display_print((char*) "Visual camera", 50, 90);
+ display_print((char*) "Touch screen ", 50, 110);
+ display_print((char*) "SD card ", 50, 130);
+ display_print((char*) "Battery gauge", 50, 150);
+ display_print((char*) "Lepton config", 50, 170);
+ display_print((char*) "Lepton data ", 50, 190);
+
+ //Check spot sensor
+ if (checkDiagnostic(diag_spot))
+ display_print((char*) "OK ", 220, 50);
+ else
+ display_print((char*) "Failed", 220, 50);
+
+ //Check display
+ if (checkDiagnostic(diag_display))
+ display_print((char*) "OK ", 220, 70);
+ else
+ display_print((char*) "Failed", 220, 70);
+
+ //Check visual camera
+ if (checkDiagnostic(diag_camera))
+ display_print((char*) "OK ", 220, 90);
+ else
+ display_print((char*) "Failed", 220, 90);
+
+ //Check touch screen
+ if (checkDiagnostic(diag_touch))
+ display_print((char*) "OK ", 220, 110);
+ else
+ display_print((char*) "Failed", 220, 110);
+
+ //Check sd card
+ if (checkDiagnostic(diag_sd))
+ display_print((char*) "OK ", 220, 130);
+ else
+ display_print((char*) "Failed", 220, 130);
+
+ //Check battery gauge
+ if (checkDiagnostic(diag_bat))
+ display_print((char*) "OK ", 220, 150);
+ else
+ display_print((char*) "Failed", 220, 150);
+
+ //Check lepton config
+ if (checkDiagnostic(diag_lep_conf))
+ display_print((char*) "OK ", 220, 170);
+ else
+ display_print((char*) "Failed", 220, 170);
+
+ //Check lepton data
+ if (checkDiagnostic(diag_lep_data))
+ display_print((char*) "OK ", 220, 190);
+ else
+ display_print((char*) "Failed", 220, 190);
+
+ //Wait some time
+ delay(1500);
+
+ //Show hint
+ display_print((char*) "Trying to start..", CENTER, 220);
+}
+
+/* Draw the Boot screen */
+void bootScreen() {
+ //Set rotation
+ setDisplayRotation();
+
+ //Init the buttons
+ buttons_init();
+
+ //Set Fonts
+ buttons_setTextFont((uint8_t*) smallFont);
+ display_setFont(smallFont);
+
+ //Draw Screen
+ display_fillScr(255, 255, 255);
+ display_setFont(bigFont);
+ display_setBackColor(255, 255, 255);
+ display_setColor(VGA_BLACK);
+
+ //Show the logo and boot text
+ display_writeRect4BPP(90, 35, 140, 149, logoBitmap, logoColors);
+ display_print((char*) "Booting", CENTER, 194);
+ display_setFont(smallFont);
+
+ //Show hardware version
+ if (teensyVersion == teensyVersion_new)
+ display_print((char*)"DIY-Thermocam V2", CENTER, 10);
+ else
+ display_print((char*)"DIY-Thermocam V1", CENTER, 10);
+
+ //Display version
+ display_print((char*)Version, CENTER, 220);
+
+ //Wait some time
+ delay(2000);
+}
diff --git a/Firmware_V2/src/gui/gui.h b/Firmware_V2/src/gui/gui.h
new file mode 100644
index 0000000..9c36ce3
--- /dev/null
+++ b/Firmware_V2/src/gui/gui.h
@@ -0,0 +1,31 @@
+/*
+*
+* GUI - Main Methods to lcd the Graphical-User-Interface
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef GUI_H
+#define GUI_H
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+void bootScreen();
+void changeTextColor();
+void drawCenterElement(int element);
+void drawMainMenuBorder();
+void drawTitle(char* name, bool firstStart = false);
+void floatToChar(char* buffer, float val);
+void showDiagnostic();
+void showFullMessage(char* message, bool small = false);
+void showTransMessage(char* msg);
+
+#endif /* GUI_H */
diff --git a/Firmware_V2/src/gui/livemode.cpp b/Firmware_V2/src/gui/livemode.cpp
new file mode 100644
index 0000000..a861ad0
--- /dev/null
+++ b/Firmware_V2/src/gui/livemode.cpp
@@ -0,0 +1,316 @@
+/*
+*
+* LIVE MODE - GUI functions used in the live mode
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* Display battery status in percentage */
+void displayBatteryStatus() {
+ //Check battery status every 60 seconds
+ if (batTimer == 0)
+ batTimer = millis();
+ if ((millis() - batTimer) > 60000) {
+ checkBattery();
+ batTimer = millis();
+ }
+
+ //USB Power only
+ if (batPercentage == -1)
+ display_print((char*) "USB Power", 225, 0);
+
+ //Low Battery
+ else if (batPercentage == 0)
+ display_print((char*) "LOW", 270, 0);
+
+ //Display battery status in percentage
+ else {
+ //Charging, show plus symbol
+ if ((analogRead(pin_usb_measure) > 50) && (batPercentage != 100))
+ {
+ display_printNumI(batPercentage, 270, 0, 3, ' ');
+ display_print((char*) "%", 300, 0);
+ display_print((char*) "+", 310, 0);
+ }
+
+ //Not charging
+ else
+ {
+ display_printNumI(batPercentage, 280, 0, 3, ' ');
+ display_print((char*) "%", 310, 0);
+ }
+ }
+}
+
+/* Display the current time on the screen*/
+void displayTime() {
+ //Tiny font
+ if ((teensyVersion == teensyVersion_old) || (!hqRes)) {
+ display_printNumI(hour(), 5, 228, 2, '0');
+ display_print((char*) ":", 23, 228);
+ display_printNumI(minute(), 27, 228, 2, '0');
+ display_print((char*) ":", 45, 228);
+ display_printNumI(second(), 49, 228, 2, '0');
+ }
+
+ //Small font
+ else
+ {
+ display_printNumI(hour(), 5, 228, 2, '0');
+ display_print((char*) ":", 20, 228);
+ display_printNumI(minute(), 27, 228, 2, '0');
+ display_print((char*) ":", 42, 228);
+ display_printNumI(second(), 49, 228, 2, '0');
+ }
+}
+
+/* Display the date on screen */
+void displayDate() {
+ //Tiny font
+ if ((teensyVersion == teensyVersion_old) || (!hqRes)) {
+ display_printNumI(day(), 5, 0, 2, '0');
+ display_print((char*) ".", 23, 0);
+ display_printNumI(month(), 27, 0, 2, '0');
+ display_print((char*) ".", 45, 0);
+ display_printNumI(year(), 49, 0, 4);
+ }
+
+ //Small font
+ else
+ {
+ display_printNumI(day(), 5, 0, 2, '0');
+ display_print((char*) ".", 20, 0);
+ display_printNumI(month(), 27, 0, 2, '0');
+ display_print((char*) ".", 42, 0);
+ display_printNumI(year(), 49, 0, 4);
+ }
+}
+
+/* Display the warmup message on screen*/
+void displayWarmup() {
+ char buffer[25];
+
+ //Create string
+ sprintf(buffer, "Sensor warmup, %2ds left", (int)abs(30 - ((millis() - calTimer) / 1000)));
+ //Tinyfont
+ if ((teensyVersion == teensyVersion_old) || (!hqRes))
+ display_print(buffer, 45, 200);
+ //Smallfont
+ else
+ display_print(buffer, 65, 200);
+}
+
+/* Display the current temperature mode on top*/
+void displayTempMode()
+{
+ char buffer[10];
+
+ //Warmup
+ if (calStatus == cal_warmup)
+ sprintf(buffer, " WARMUP");
+ //Limits locked
+ else if (limitsLocked)
+ sprintf(buffer, " LOCKED");
+ //Auto mode
+ else if (autoMode)
+ sprintf(buffer, " AUTO");
+ //Temperature presets
+ else
+ {
+ //Check which preset is active
+ byte minMaxPreset;
+ byte read = EEPROM.read(eeprom_minMaxPreset);
+ if ((read >= minMax_preset1) && (read <= minMax_preset3))
+ minMaxPreset = read;
+ else
+ minMaxPreset = minMax_temporary;
+ //Choose corresponding text
+ if ((minMaxPreset == minMax_preset1) && (EEPROM.read(eeprom_minMax1Set) == eeprom_setValue))
+ sprintf(buffer, "PRESET 1");
+ else if ((minMaxPreset == minMax_preset2) && (EEPROM.read(eeprom_minMax2Set) == eeprom_setValue))
+ sprintf(buffer, "PRESET 2");
+ else if ((minMaxPreset == minMax_preset3) && (EEPROM.read(eeprom_minMax3Set) == eeprom_setValue))
+ sprintf(buffer, "PRESET 3");
+ else
+ sprintf(buffer, " MANUAL");
+ }
+
+ //Low resolution display
+ if ((teensyVersion == teensyVersion_old) || (!hqRes))
+ display_print(buffer, 120, 0);
+ //HQ resolution display
+ else
+ display_print(buffer, 140, 0);
+}
+
+/* Display the minimum and maximum point on the screen */
+void displayMinMaxPoint(bool min)
+{
+ int16_t xpos, ypos;
+
+ //Calculate x and y position
+ if (min)
+ calculatePointPos(&xpos, &ypos, minTempPos);
+ else
+ calculatePointPos(&xpos, &ypos, maxTempPos);
+
+ //Draw the marker
+ display_drawLine(xpos, ypos, xpos, ypos);
+
+ //Warmup completed, show absolute temp
+ if (calStatus != cal_warmup)
+ {
+ //Calc x position for the text
+ xpos -= 20;
+ if (xpos < 0)
+ xpos = 0;
+ if (xpos > 279)
+ xpos = 279;
+
+ //Calc y position for the text
+ ypos += 15;
+ if (ypos > 229)
+ ypos = 229;
+
+ //Show min or max value as absolute temperature
+ if (min)
+ display_printNumF(calFunction(minTempVal), 2, xpos, ypos);
+ else
+ display_printNumF(calFunction(maxTempVal), 2, xpos, ypos);
+ }
+
+ //Warmup, show C / H
+ else
+ {
+ //Calc x and y position
+ xpos += 4;
+ if (xpos >= 310)
+ xpos -= 10;
+ if (ypos > 230)
+ ypos = 230;
+
+ //Show min or max value as symbol
+ if (min)
+ display_print('C', xpos, ypos);
+ else
+ display_print('H', xpos, ypos);
+ }
+}
+
+/* Display free space on screen*/
+void displayFreeSpace() {
+ //Tinyfont
+ if ((teensyVersion == teensyVersion_old) || (!hqRes))
+ display_print(sdInfo, 197, 228);
+ //Smallfont
+ else
+ display_print(sdInfo, 220, 228);
+}
+
+/* Show the current spot temperature on screen*/
+void showSpot() {
+ char buffer[10];
+
+ //Draw the spot circle
+ display_drawCircle(160, 120, 12);
+
+ //Draw the lines
+ display_drawLine(136, 120, 148, 120);
+ display_drawLine(172, 120, 184, 120);
+ display_drawLine(160, 96, 160, 108);
+ display_drawLine(160, 132, 160, 144);
+
+ //Convert spot temperature to char array
+ floatToChar(buffer, spotTemp);
+
+ //Print value on display
+ display_print(buffer, 145, 150);
+}
+
+/* Display addition information on the screen */
+void displayInfos() {
+ //Set text color
+ changeTextColor();
+ //Set font and background
+ display_setBackColor(VGA_TRANSPARENT);
+
+ //For Teensy 3.6, set small font
+ if ((teensyVersion == teensyVersion_new) && (hqRes))
+ display_setFont((uint8_t*) smallFont);
+ //For Teensy 3.1 / 3.2, set tiny font
+ else
+ display_setFont((uint8_t*) tinyFont);
+
+ //Set write to image, not display
+ display_writeToImage = true;
+
+ //Check warmup
+ checkWarmup();
+
+ //If not saving image or video
+ if ((imgSave != imgSave_create) && (!videoSave)) {
+ //Show battery status in percantage
+ if (batteryEnabled)
+ displayBatteryStatus();
+ //Show the time
+ if (timeEnabled)
+ displayTime();
+ //Show the date
+ if (dateEnabled)
+ displayDate();
+ //Show storage information
+ if (storageEnabled)
+ displayFreeSpace();
+ //Display warmup if required
+ if (calStatus == cal_warmup)
+ displayWarmup();
+ //Display temperature mode
+ displayTempMode();
+ }
+
+ //Show the minimum / maximum points
+ if (minMaxPoints & minMaxPoints_min)
+ displayMinMaxPoint(true);
+ if (minMaxPoints & minMaxPoints_max)
+ displayMinMaxPoint(false);
+
+ //Show the spot in the middle
+ if (spotEnabled)
+ showSpot();
+
+ //Show the color bar when warmup is over and if enabled, not in visual mode
+ if ((colorbarEnabled) && (calStatus != cal_warmup) && (displayMode != displayMode_visual))
+ showColorBar();
+
+ //Show the temperature points
+ showTemperatures();
+
+ //Set write back to display
+ display_writeToImage = false;
+}
diff --git a/Firmware_V2/src/gui/livemode.h b/Firmware_V2/src/gui/livemode.h
new file mode 100644
index 0000000..c2cbcf6
--- /dev/null
+++ b/Firmware_V2/src/gui/livemode.h
@@ -0,0 +1,31 @@
+/*
+*
+* LIVE MODE - GUI functions used in the live mode
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef LIVEMODE_H
+#define LIVEMODE_H
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+void displayBatteryStatus();
+void displayDate();
+void displayFreeSpace();
+void displayInfos();
+void displayMinMaxPoint(bool min);
+void displayTempMode();
+void displayTime();
+void displayWarmup();
+void showSpot();
+
+#endif /* LIVEMODE_H */
diff --git a/Firmware_V2/src/gui/loadmenu.cpp b/Firmware_V2/src/gui/loadmenu.cpp
new file mode 100644
index 0000000..8ca55cf
--- /dev/null
+++ b/Firmware_V2/src/gui/loadmenu.cpp
@@ -0,0 +1,530 @@
+/*
+*
+* LOAD MENU - Display the menu to load images and videos
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* Display the GUI elements for the load menu */
+void displayGUI(int imgCount, char* infoText) {
+ //Set text color
+ changeTextColor();
+ //set Background transparent
+ display_setBackColor(VGA_TRANSPARENT);
+ display_setFont(bigFont);
+ //Delete image or video from internal storage
+ display_print((char*) "Delete", 220, 10);
+ //Find image by time and date
+ display_print((char*) "Find", 5, 10);
+ //Display prev/next if there is more than one image
+ if (imgCount != 1) {
+ display_print((char*) "<", 10, 110);
+ display_print((char*) ">", 295, 110);
+ }
+ //Convert image to bitmap
+ display_print((char*) "Convert", 5, 210);
+ //Exit to main menu
+ display_print((char*) "Exit", 250, 210);
+ display_setFont(smallFont);
+ //Display either frame number or image date and time
+ display_print(infoText, 80, 12);
+}
+
+/* Asks the user if he wants to delete the video */
+void deleteVideo(char* dirname) {
+ //Title & Background
+ drawTitle((char*) "Delete Video", true);
+ display_setColor(VGA_BLACK);
+ display_setFont(smallFont);
+ display_setBackColor(200, 200, 200);
+ display_print((char*)"Do you want to delete this video?", CENTER, 66);
+ display_print((char*)"This will also remove the", CENTER, 105);
+ display_print((char*)"other related files to it. ", CENTER, 125);
+ //Draw the buttons
+ buttons_deleteAllButtons();
+ buttons_setTextFont(bigFont);
+ buttons_addButton(15, 160, 140, 55, (char*) "Yes");
+ buttons_addButton(165, 160, 140, 55, (char*) "No");
+ buttons_drawButtons();
+ buttons_setTextFont(smallFont);
+ //Touch handler
+ while (true) {
+ //If touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons(true);
+ //YES
+ if (pressedButton == 0) {
+ showFullMessage((char*) "Delete video..");
+ //Start SD
+ startAltClockline();
+
+ //Delete the ending for a video
+ dirname[14] = '\0';
+
+ //Go into the video folder
+ sd.chdir("/");
+ sd.chdir(dirname);
+ //Delete all files
+ uint16_t videoCounter = 0;
+ bool exists;
+ char filename[] = "00000.DAT";
+ //Go through the frames
+ while (1) {
+ //Get the frame name
+ frameFilename(filename, videoCounter);
+ //Check frame existance
+ exists = sd.exists(filename);
+ //If the frame does not exists, end remove
+ if (!exists)
+ break;
+ //Otherwise remove file
+ else
+ sd.remove(filename);
+ //Remove Bitmap if there
+ strcpy(&filename[5], ".BMP");
+ if (sd.exists(filename))
+ sd.remove(filename);
+ //Remove Jpeg if there
+ strcpy(&filename[5], ".JPG");
+ if (sd.exists(filename))
+ sd.remove(filename);
+ //Reset ending
+ strcpy(&filename[5], ".DAT");
+ //Raise counter
+ videoCounter++;
+ }
+ //Switch back to the root
+ sd.chdir("/");
+ //Remove the folder itself
+ sd.rmdir(dirname);
+ //End SD
+ endAltClockline();
+ showFullMessage((char*) "Video deleted");
+ delay(1000);
+ return;
+ }
+ //NO
+ else if (pressedButton == 1) {
+ //Start SD
+ startAltClockline();
+ sd.chdir("/");
+ endAltClockline();
+ return;
+ }
+ }
+ }
+}
+
+/* Asks the user if he wants to delete the image */
+void deleteImage(char* filename) {
+ //Title & Background
+ drawTitle((char*) "Delete Image", true);
+ display_setColor(VGA_BLACK);
+ display_setFont(smallFont);
+ display_setBackColor(200, 200, 200);
+ display_print((char*)"Do you want to delete this image?", CENTER, 66);
+ display_print((char*)"This will also remove the", CENTER, 105);
+ display_print((char*)"other related files to it. ", CENTER, 125);
+ //Draw the buttons
+ buttons_deleteAllButtons();
+ buttons_setTextFont(bigFont);
+ buttons_addButton(165, 160, 140, 55, (char*) "Yes");
+ buttons_addButton(15, 160, 140, 55, (char*) "No");
+ buttons_drawButtons();
+ buttons_setTextFont(smallFont);;
+ //Touch handler
+ while (true) {
+ //If touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons(true);
+ //YES
+ if (pressedButton == 0) {
+ showFullMessage((char*) "Delete image..");
+ //Start SD
+ startAltClockline();
+ //Delete .DAT file
+ sd.remove(filename);
+ //Delete .JPG file
+ strcpy(&filename[14], ".JPG");
+ if (sd.exists(filename))
+ sd.remove(filename);
+ //Delete .BMP file
+ strcpy(&filename[14], ".BMP");
+ if (sd.exists(filename))
+ sd.remove(filename);
+ endAltClockline();
+ showFullMessage((char*) "Image deleted");
+ delay(1000);
+ return;
+ }
+ //NO
+ else if (pressedButton == 1) {
+ return;
+ }
+ }
+ }
+}
+
+/* Asks the user if he really wants to convert the image/video */
+bool convertPrompt() {
+ //Title & Background
+ drawTitle((char*) "Conversion Prompt", true);
+ display_setColor(VGA_BLACK);
+ display_setFont(smallFont);
+ display_setBackColor(200, 200, 200);
+ display_print((char*)"Do you want to convert?", CENTER, 66);
+ display_print((char*)"That process will create", CENTER, 105);
+ display_print((char*)"bitmap(s) out of the raw data.", CENTER, 125);
+ //Draw the buttons
+ buttons_deleteAllButtons();
+ buttons_setTextFont(bigFont);
+ buttons_addButton(165, 160, 140, 55, (char*) "Yes");
+ buttons_addButton(15, 160, 140, 55, (char*) "No");
+ buttons_drawButtons();
+ buttons_setTextFont(smallFont);
+ //Wait for touch release
+ while (touch_touched());
+ //Touch handler
+ while (true) {
+ //If touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons(true);
+ //YES
+ if (pressedButton == 0) {
+ return true;
+ }
+ //NO
+ else if (pressedButton == 1) {
+ return false;
+ }
+ }
+ }
+}
+
+/* Convert a raw image lately to BMP */
+void convertImage(char* filename) {
+
+ //Check if image is a bitmap
+ if (filename[15] == 'B') {
+ showFullMessage((char*) "Image is already converted");
+ delay(500);
+ return;
+ }
+
+ //Check if the image is already there
+ strcpy(&filename[14], ".BMP");
+ startAltClockline();
+ bool exists = sd.exists(filename);
+ endAltClockline();
+
+ //If image is already converted, return
+ if (exists) {
+ showFullMessage((char*) "Image is already converted");
+ delay(500);
+ strcpy(&filename[14], ".DAT");
+ return;
+ }
+
+ //If the user does not want to convert, return
+ if (!convertPrompt()) {
+ strcpy(&filename[14], ".DAT");
+ return;
+ }
+
+ //Show convert message
+ showFullMessage((char*) "Converting image to BMP..");
+
+ //Save image
+ saveBuffer(filename);
+
+ //Show finish message
+ showFullMessage((char*) "Image converted");
+ delay(1000);
+ strcpy(&filename[14], ".DAT");
+}
+
+/* Convert a raw video lately to BMP frames */
+void convertVideo(char* dirname) {
+ uint16_t frames = getVideoFrameNumber(dirname);
+ char filename[] = "00000.BMP";
+
+ //Switch Clock to Alternative
+ startAltClockline();
+
+ //Delete the ending for a video
+ dirname[14] = '\0';
+
+ //Go into the folder
+ sd.chdir(dirname);
+
+ //Get the frame name of the first frame
+ frameFilename(filename, 0);
+ bool exists = sd.exists(filename);
+ endAltClockline();
+
+ //If video is already converted, return
+ if (exists) {
+ showFullMessage((char*) "Video is already converted");
+ delay(500);
+ return;
+ }
+
+ //If the user does not want to convert the video, return
+ if (!convertPrompt())
+ return;
+
+ //Show convert message
+ showFullMessage((char*) "Converting video to BMP..");
+ delay(1000);
+
+ //Convert video
+ processVideoFrames(frames, dirname);
+ videoSave = videoSave_disabled;
+}
+
+/* Loads an image from the SDCard and prints it on screen */
+void openImage(char* filename, int imgCount) {
+ //Show message on screen
+ showFullMessage((char*) "Please wait, image is loading..");
+
+ //Display raw data
+ if (filename[15] == 'D') {
+ //Load Raw data
+ loadRawData(filename);
+ //Display Raw Data
+ displayRawData();
+ }
+
+ //Load bitmap
+ else if (filename[15] == 'B') {
+ loadBMPImage(filename);
+ }
+
+ //Unsupported file type
+ else {
+ showFullMessage((char*) "Unsupported file type");
+ delay(1000);
+ return;
+ }
+
+ //Create string for time and date
+ char nameStr[20] = {
+ //Day
+ filename[6], filename[7], '.',
+ //Month
+ filename[4], filename[5], '.',
+ //Year
+ filename[2], filename[3], ' ',
+ //Hour
+ filename[8], filename[9], ':',
+ //Minute
+ filename[10], filename[11], ':',
+ //Second
+ filename[12], filename[13], '\0'
+ };
+
+ //Display GUI
+ displayGUI(imgCount, nameStr);
+
+ //Attach interrupt
+ attachInterrupt(pin_touch_irq, loadTouchIRQ, FALLING);
+
+ //Wait for touch press
+ while (loadTouch == loadTouch_none);
+
+ //Disable touch handler
+ detachInterrupt(pin_touch_irq);
+}
+
+/* Get the number of frames in the video */
+uint16_t getVideoFrameNumber(char* dirname) {
+ uint16_t videoCounter = 0;
+ bool exists;
+ char filename[] = "00000.DAT";
+ //Switch Clock to Alternative
+ startAltClockline();
+ //Go into the folder
+ sd.chdir(dirname);
+ //Look how many frames we have
+ while (true) {
+ //Get the frame name
+ frameFilename(filename, videoCounter);
+ //Check frame existance
+ exists = sd.exists(filename);
+ //Raise counter
+ if (exists)
+ videoCounter++;
+ //Leave
+ else
+ break;
+ }
+ //Switch Clock back to Standard
+ endAltClockline();
+ return videoCounter;
+}
+
+/* Display the selected video frame */
+void displayVideoFrame(int i, char* dirname)
+{
+ char filename[] = "00000.DAT";
+
+ //Get the frame name
+ frameFilename(filename, i);
+
+ //Load Raw data
+ loadRawData(filename, dirname);
+
+ //Display Raw Data
+ displayRawData();
+}
+
+/* Play a video from the internal storage */
+void playVideo(char* dirname, int imgCount) {
+ char buffer[14];
+ //Save the current frame number
+ int frameNumber = 0;
+
+ //Get the total number of frames in the dir
+ uint16_t numberOfFrames = getVideoFrameNumber(dirname);
+
+ //Jump here when pausing a video
+showFrame:
+ //Display frame
+ displayVideoFrame(frameNumber, dirname);
+ //Create string
+ sprintf(buffer, "%5d / %-5d", frameNumber + 1, numberOfFrames);
+ //Display GUI
+ displayGUI(imgCount, buffer);
+ //Display play message
+ display_setFont(bigFont);
+ if (spotEnabled)
+ display_print((char*) "Play", CENTER, 70);
+ else
+ display_print((char*) "Play", CENTER, 110);
+ display_setFont(smallFont);
+
+ //Repeat until we get a valid touch
+ do {
+ //Wait for touch press
+ while (!touch_touched());
+ //Interpret touch coordinates
+ loadTouchIRQ();
+ } while (loadTouch == loadTouch_none);
+
+ //Wait for touch to release
+ while (touch_touched());
+
+ //Check if we play the video
+ if (loadTouch != loadTouch_middle)
+ return;
+ loadTouch = loadTouch_none;
+
+ //Play forever
+ while (true) {
+ //Go through the frames
+ for (; frameNumber < numberOfFrames; frameNumber++) {
+ //Check for touch press
+ if (touch_touched())
+ //Get touch function
+ loadTouchIRQ();
+ //Pause the video
+ if (loadTouch == loadTouch_middle)
+ {
+ //Wait for touch release
+ while (touch_touched());
+ //Display the static frame
+ goto showFrame;
+ }
+ //Any other action
+ if (loadTouch != loadTouch_none)
+ return;
+
+ //Display frame
+ displayVideoFrame(frameNumber, dirname);
+ //Create string
+ sprintf(buffer, "%5d / %-5d", frameNumber + 1, numberOfFrames);
+ //Display GUI
+ displayGUI(imgCount, buffer);
+ }
+ //Reset frame number for next play
+ frameNumber = 0;
+ }
+}
+
+/* Shows a menu where the user can choose the time & date items for the image */
+int loadMenu(char* title, int* array, int length) {
+ //Draw the title on screen
+ drawTitle(title);
+ //Draw the Buttons
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 70, 70, (char*) "-");
+ buttons_addButton(230, 60, 70, 70, (char*) "+");
+ buttons_addButton(20, 150, 130, 70, (char*) "Back");
+ buttons_addButton(170, 150, 130, 70, (char*) "Choose");
+ buttons_drawButtons();
+ int currentPos = 0;
+ //Display the first element for the array
+ drawCenterElement(array[currentPos]);
+ //Touch handler
+ while (true) {
+ //Touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons();
+ //Minus
+ if (pressedButton == 1) {
+ //Decrease element by one
+ if (currentPos > 0)
+ currentPos--;
+ //Go from lowest to highest element
+ else if (currentPos == 0)
+ currentPos = length - 1;
+ //Draw it on screen
+ drawCenterElement(array[currentPos]);
+ }
+ //Plus
+ else if (pressedButton == 0) {
+ //Increase element by one
+ if (currentPos < (length - 1))
+ currentPos++;
+ //Go from highest to lowest element
+ else if (currentPos == (length - 1))
+ currentPos = 0;
+ //Draw it on screen
+ drawCenterElement(array[currentPos]);
+ }
+ //Back - return minus 1
+ else if (pressedButton == 2) {
+ return -1;
+ }
+ //Set - return element's position
+ else if (pressedButton == 3) {
+ return currentPos;
+ }
+ }
+ }
+}
diff --git a/Firmware_V2/src/gui/loadmenu.h b/Firmware_V2/src/gui/loadmenu.h
new file mode 100644
index 0000000..71ab7d1
--- /dev/null
+++ b/Firmware_V2/src/gui/loadmenu.h
@@ -0,0 +1,33 @@
+/*
+*
+* LOAD MENU - Display the menu to load images and videos
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef LOADMENU_H
+#define LOADMENU_H
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+void convertImage(char* filename);
+bool convertPrompt();
+void convertVideo(char* dirname);
+void deleteImage(char* filename);
+void deleteVideo(char* dirname);
+void displayGUI(int imgCount, char* infoText);
+void displayVideoFrame(int i, char* dirname);
+uint16_t getVideoFrameNumber(char* dirname);
+int loadMenu(char* title, int* array, int length);
+void openImage(char* filename, int imgCount);
+void playVideo(char* dirname, int imgCount);
+
+#endif /* LOADMENU_H */
diff --git a/Firmware_V2/src/gui/mainmenu.cpp b/Firmware_V2/src/gui/mainmenu.cpp
new file mode 100644
index 0000000..cb3b567
--- /dev/null
+++ b/Firmware_V2/src/gui/mainmenu.cpp
@@ -0,0 +1,1806 @@
+/*
+ *
+ * MAIN MENU - Display the main menu with icons
+ *
+ * DIY-Thermocam Firmware
+ *
+ * GNU General Public License v3.0
+ *
+ * Copyright by Max Ritter
+ *
+ * http://www.diy-thermocam.net
+ * https://github.com/maxritter/DIY-Thermocam
+ *
+ */
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* Draws the background in the main menu */
+void mainMenuBackground()
+{
+ display_setColor(120, 120, 120);
+ display_fillRoundRect(6, 6, 314, 234);
+ display_setColor(200, 200, 200);
+ display_fillRect(6, 36, 314, 180);
+ display_setColor(VGA_BLACK);
+ display_drawHLine(6, 36, 314);
+ display_drawHLine(6, 180, 314);
+}
+
+/* Draws the content of the selection menu*/
+void drawSelectionMenu()
+{
+ //Buttons
+ buttons_deleteAllButtons();
+ buttons_setTextFont(bigFont);
+ buttons_addButton(15, 45, 38, 77, (char*) "<", 0, true);
+ buttons_addButton(267, 45, 38, 77, (char*) ">", 0, true);
+ buttons_addButton(15, 188, 120, 40, (char*) "Back");
+ buttons_addButton(95, 132, 130, 35, (char*) "OK");
+ buttons_drawButtons();
+ //Border
+ display_setColor(VGA_BLUE);
+ display_drawRect(65, 57, 257, 111);
+}
+
+/* Draws the title in the main menu */
+void mainMenuTitle(char* title)
+{
+ display_setFont(bigFont);
+ display_setBackColor(120, 120, 120);
+ display_setColor(VGA_WHITE);
+ display_print(title, CENTER, 14);
+}
+
+/* Draws the current selection in the menu */
+void mainMenuSelection(char* selection)
+{
+ //Clear the old content
+ display_setColor(VGA_WHITE);
+ display_fillRect(66, 58, 257, 111);
+ //Print the text
+ display_setBackColor(VGA_WHITE);
+ display_setColor(VGA_BLUE);
+ display_print(selection, CENTER, 77);
+}
+
+/* Asks the user if he really wants to enter mass storage mode */
+bool massStoragePrompt()
+{
+ //Title & Background
+ drawTitle((char*) "USB File Transfer");
+ display_setColor(VGA_BLACK);
+ display_setFont(smallFont);
+ display_setBackColor(200, 200, 200);
+ display_print((char*) "Do you want to enter mass storage", CENTER, 65);
+ display_print((char*) "to transfer files to the PC?", CENTER, 85);
+ display_print((char*) "Do not use this for FW updates", CENTER, 105);
+ display_print((char*) "or for the USB serial connection.", CENTER, 125);
+ //Draw the buttons
+ buttons_deleteAllButtons();
+ buttons_setTextFont(bigFont);
+ buttons_addButton(165, 160, 140, 55, (char*) "Yes");
+ buttons_addButton(15, 160, 140, 55, (char*) "No");
+ buttons_drawButtons();
+ buttons_setTextFont(smallFont);
+ //Wait for touch release
+ while (touch_touched())
+ ;
+ //Touch handler
+ while (true)
+ {
+ //If touch pressed
+ if (touch_touched() == true)
+ {
+ int pressedButton = buttons_checkButtons(true);
+ //YES
+ if (pressedButton == 0)
+ {
+ return true;
+ }
+ //NO
+ if (pressedButton == 1)
+ {
+ return false;
+ }
+ }
+ }
+}
+
+/* Calibration Repeat Choose */
+bool calibrationRepeat()
+{
+ //Title & Background
+ mainMenuBackground();
+ mainMenuTitle((char*) "Bad Calibration");
+ display_setColor(VGA_BLACK);
+ display_setFont(bigFont);
+ display_setBackColor(200, 200, 200);
+ display_print((char*) "Try again?", CENTER, 66);
+ display_setFont(smallFont);
+ display_setBackColor(120, 120, 120);
+ display_setColor(VGA_WHITE);
+ display_print((char*) "Use different calibration objects", CENTER, 201);
+ //Draw the buttons
+ buttons_deleteAllButtons();
+ buttons_setTextFont(bigFont);
+ buttons_addButton(165, 106, 140, 55, (char*) "Yes");
+ buttons_addButton(15, 106, 140, 55, (char*) "No");
+ buttons_drawButtons();
+ //Touch handler
+ while (true)
+ {
+ //If touch pressed
+ if (touch_touched() == true)
+ {
+ int pressedButton = buttons_checkButtons(true);
+ //YES
+ if (pressedButton == 0)
+ {
+ return true;
+ }
+ //NO
+ if (pressedButton == 1)
+ {
+ return false;
+ }
+ }
+ }
+}
+
+/* Calibration*/
+void calibrationScreen(bool firstStart)
+{
+ //Normal mode
+ if (firstStart == false)
+ {
+ mainMenuBackground();
+ mainMenuTitle((char*) "Calibrating..");
+ display_setColor(VGA_BLACK);
+ display_setBackColor(200, 200, 200);
+ display_setFont(smallFont);
+ display_print((char*) "Point the camera to different", CENTER, 63);
+ display_print((char*) "hot and cold objects in the area.", CENTER, 96);
+ buttons_deleteAllButtons();
+ buttons_setTextFont(bigFont);
+ buttons_addButton(90, 188, 140, 40, (char*) "Abort");
+ buttons_drawButtons();
+ display_setFont(bigFont);
+ display_print((char*) "Status: 0%", CENTER, 140);
+ }
+ //First start
+ else
+ {
+ display_fillScr(200, 200, 200);
+ display_setFont(bigFont);
+ display_setBackColor(200, 200, 200);
+ display_setColor(VGA_BLACK);
+ display_print((char*) "Calibrating..", CENTER, 100);
+ display_print((char*) "Status: 0%", CENTER, 140);
+ }
+}
+
+/* Menu to add or remove temperature points to the thermal image */
+bool tempPointsMenu()
+{
+ //Still in warmup, do not add points
+ if (calStatus == cal_warmup)
+ {
+ showFullMessage((char*) "Please wait for sensor warmup", true);
+ delay(1000);
+ return false;
+ }
+ redraw:
+ //Background
+ mainMenuBackground();
+ //Title
+ mainMenuTitle((char*) "Temp. points");
+ //Draw the selection menu
+ buttons_deleteAllButtons();
+ buttons_setTextFont(smallFont);
+ buttons_addButton(15, 45, 90, 122, (char*) "Add");
+ buttons_addButton(115, 45, 90, 122, (char*) "Remove");
+ buttons_addButton(215, 45, 90, 122, (char*) "Clear");
+ buttons_addButton(15, 188, 120, 40, (char*) "Back");
+ buttons_drawButtons();
+ //Save the current position inside the menu
+ while (true)
+ {
+ //Touch screen pressed
+ if (touch_touched() == true)
+ {
+ int pressedButton = buttons_checkButtons(true);
+ //Add
+ if (pressedButton == 0)
+ {
+ tempPointFunction(false);
+ goto redraw;
+ }
+ //Remove
+ if (pressedButton == 1)
+ {
+ tempPointFunction(true);
+ goto redraw;
+ }
+ //Clear
+ if (pressedButton == 2)
+ {
+ clearTempPoints();
+ showFullMessage((char*) "All points cleared", true);
+ delay(1000);
+ goto redraw;
+ }
+ //BACK
+ if (pressedButton == 3)
+ return false;
+ }
+ }
+}
+
+/* Select the color for the live mode string */
+void hotColdColorMenuString(int pos)
+{
+ char* text = (char*) "";
+ switch (pos)
+ {
+ //White
+ case 0:
+ text = (char*) "White";
+ break;
+ //Black
+ case 1:
+ text = (char*) "Black";
+ break;
+ //Red
+ case 2:
+ text = (char*) "Red";
+ break;
+ //Green
+ case 3:
+ text = (char*) "Green";
+ break;
+ //Blue
+ case 4:
+ text = (char*) "Blue";
+ break;
+ }
+ mainMenuSelection(text);
+}
+
+/* Menu to display the color in hot/cold color mode */
+bool hotColdColorMenu()
+{
+ //Save the current position inside the menu
+ byte hotColdColorMenuPos;
+ if (hotColdMode == hotColdMode_hot)
+ hotColdColorMenuPos = 2;
+ else if (hotColdMode == hotColdMode_cold)
+ hotColdColorMenuPos = 4;
+ else
+ hotColdColorMenuPos = 0;
+ //Background
+ mainMenuBackground();
+ //Title
+ mainMenuTitle((char*) "Select color");
+ //Draw the selection menu
+ drawSelectionMenu();
+ //Draw the current item
+ hotColdColorMenuString(hotColdColorMenuPos);
+ //Save the current position inside the menu
+ while (true)
+ {
+ //Touch screen pressed
+ if (touch_touched() == true)
+ {
+ int pressedButton = buttons_checkButtons(true);
+ //SELECT
+ if (pressedButton == 3)
+ {
+ //Save
+ hotColdColor = hotColdColorMenuPos;
+ //Write to EEPROM
+ EEPROM.write(eeprom_hotColdColor, hotColdColor);
+ return true;
+ }
+ //BACK
+ if (pressedButton == 2)
+ return false;
+ //BACKWARD
+ else if (pressedButton == 0)
+ {
+ if (hotColdColorMenuPos > 0)
+ hotColdColorMenuPos--;
+ else if (hotColdColorMenuPos == 0)
+ hotColdColorMenuPos = 4;
+ }
+ //FORWARD
+ else if (pressedButton == 1)
+ {
+ if (hotColdColorMenuPos < 4)
+ hotColdColorMenuPos++;
+ else if (hotColdColorMenuPos == 4)
+ hotColdColorMenuPos = 0;
+ }
+ //Change the menu name
+ hotColdColorMenuString(hotColdColorMenuPos);
+ }
+ }
+}
+
+/* Touch handler for the hot & cold limit changer menu */
+void hotColdChooserHandler()
+{
+ //Help variables
+ char margin[14];
+
+ //Display level as temperature
+ if (!tempFormat)
+ {
+ sprintf(margin, "Limit: %dC", hotColdLevel);
+ }
+ else
+ {
+ sprintf(margin, "Limit: %dF", hotColdLevel);
+ }
+ display_print(margin, CENTER, 153);
+
+ //Touch handler
+ while (true)
+ {
+ waitTouch:
+
+ //If touch pressed
+ if (touch_touched() == true)
+ {
+ int pressedButton = buttons_checkButtons(true);
+ //RESET
+ if (pressedButton == 0)
+ {
+ if (hotColdMode == hotColdMode_cold)
+ hotColdLevel = (int16_t) round(
+ calFunction(
+ 0.2 * (maxValue - minValue) + minValue));
+ if (hotColdMode == hotColdMode_hot)
+ hotColdLevel = (int16_t) round(
+ calFunction(
+ 0.8 * (maxValue - minValue) + minValue));
+ }
+ //SELECT
+ else if (pressedButton == 1)
+ {
+ //Save to EEPROM
+ EEPROM.write(eeprom_hotColdLevelHigh,
+ (hotColdLevel & 0xFF00) >> 8);
+ EEPROM.write(eeprom_hotColdLevelLow, hotColdLevel & 0x00FF);
+ break;
+ }
+ //MINUS
+ else if (pressedButton == 2)
+ {
+ if (hotColdLevel > round(calFunction(minValue)))
+ hotColdLevel--;
+ else
+ goto waitTouch;
+ }
+ //PLUS
+ else if (pressedButton == 3)
+ {
+ if (hotColdLevel < round(calFunction(maxValue)))
+ hotColdLevel++;
+ else
+ goto waitTouch;
+ }
+ //Prepare the preview image
+ delay(10);
+ createThermalImg(true);
+ //Display the preview image
+ display_drawBitmap(80, 48, 160, 120, smallBuffer, 1);
+
+ //Display level as temperature
+ if (!tempFormat)
+ {
+ sprintf(margin, "Limit: %dC", hotColdLevel);
+ }
+ else
+ {
+ sprintf(margin, "Limit: %dF", hotColdLevel);
+ }
+ display_print(margin, CENTER, 153);
+ }
+ }
+}
+
+/* Select the limit in hot/cold mode */
+void hotColdChooser()
+{
+ //Background & title
+ mainMenuBackground();
+ mainMenuTitle((char*) "Set Limit");
+
+ //Draw the buttons
+ buttons_deleteAllButtons();
+ buttons_setTextFont(bigFont);
+ buttons_addButton(15, 188, 140, 40, (char*) "Reset");
+ buttons_addButton(165, 188, 140, 40, (char*) "OK");
+ buttons_addButton(15, 48, 55, 120, (char*) "-");
+ buttons_addButton(250, 48, 55, 120, (char*) "+");
+ buttons_drawButtons();
+
+ //Draw the border for the preview image
+ display_setColor(VGA_BLACK);
+ display_drawRect(79, 47, 241, 169);
+
+ //Set text color
+ display_setFont(smallFont);
+ display_setBackColor(VGA_TRANSPARENT);
+ changeTextColor();
+
+ //Find min and max values
+ if ((autoMode) && (!limitsLocked))
+ {
+ lepton_getRawValues();
+ limitValues();
+ }
+
+ //Calculate initial level
+ if (hotColdMode == hotColdMode_cold)
+ hotColdLevel = (int16_t) round(
+ calFunction(0.2 * (maxValue - minValue) + minValue));
+ if (hotColdMode == hotColdMode_hot)
+ hotColdLevel = (int16_t) round(
+ calFunction(0.8 * (maxValue - minValue) + minValue));
+
+ //Prepare the preview image
+ delay(10);
+ createThermalImg(true);
+
+ //Display the preview image
+ display_drawBitmap(80, 48, 160, 120, smallBuffer, 1);
+
+ //Go into the normal touch handler
+ hotColdChooserHandler();
+}
+
+/* Menu to display hot or cold areas */
+bool hotColdMenu()
+{
+ //Still in warmup, do not add points
+ if (calStatus == cal_warmup)
+ {
+ showFullMessage((char*) "Please wait for sensor warmup", true);
+ delay(1000);
+ return false;
+ }
+
+ redraw:
+ //Background
+ mainMenuBackground();
+
+ //Title
+ mainMenuTitle((char*) "Hot / Cold");
+
+ //Draw the selection menu
+ buttons_deleteAllButtons();
+ buttons_setTextFont(smallFont);
+ buttons_addButton(15, 45, 90, 122, (char*) "Hot");
+ buttons_addButton(115, 45, 90, 122, (char*) "Cold");
+ buttons_addButton(215, 45, 90, 122, (char*) "Disabled");
+ buttons_addButton(15, 188, 120, 40, (char*) "Back");
+ buttons_drawButtons();
+
+ //Save the current position inside the menu
+ while (true)
+ {
+ //Touch screen pressed
+ if (touch_touched() == true)
+ {
+ int pressedButton = buttons_checkButtons(true);
+ //Hot
+ if (pressedButton == 0)
+ {
+ //Set marker to hot
+ hotColdMode = hotColdMode_hot;
+
+ //Choose the color
+ if (hotColdColorMenu())
+ //Set the limit
+ hotColdChooser();
+
+ //Go back
+ else
+ {
+ hotColdMode = hotColdMode_disabled;
+ goto redraw;
+ }
+
+ //Leave loop
+ break;
+ }
+ //Cold
+ if (pressedButton == 1)
+ {
+ //Set marker to cold
+ hotColdMode = hotColdMode_cold;
+
+ //Choose the color
+ if (hotColdColorMenu())
+ //Set the limit
+ hotColdChooser();
+
+ //Go back
+ else
+ {
+ hotColdMode = hotColdMode_disabled;
+ goto redraw;
+ }
+
+ //Leave loop
+ break;
+ }
+ //Disabled
+ if (pressedButton == 2)
+ {
+ //Set marker to disabled
+ hotColdMode = hotColdMode_disabled;
+
+ //Leave loop
+ break;
+ }
+ //Back to main menu
+ if (pressedButton == 3)
+ return false;
+ }
+ }
+
+ //Write to EEPROM
+ EEPROM.write(eeprom_hotColdMode, hotColdMode);
+
+ //Disable auto FFC for isotherm mode
+ if (hotColdMode != hotColdMode_disabled)
+ lepton_ffcMode(false);
+ //Enable it when isotherm disabled
+ else
+ lepton_ffcMode(true);
+
+ //Go back
+ return true;
+}
+
+/* Switch the current preset menu item */
+void tempLimitsPresetSaveString(int pos)
+{
+ char* text = (char*) "";
+ switch (pos)
+ {
+ case 0:
+ text = (char*) "Temporary";
+ break;
+ case 1:
+ text = (char*) "Preset 1";
+ break;
+ case 2:
+ text = (char*) "Preset 2";
+ break;
+ case 3:
+ text = (char*) "Preset 3";
+ break;
+ }
+ mainMenuSelection(text);
+}
+
+/* Menu to save the temperature limits to a preset */
+bool tempLimitsPresetSaveMenu()
+{
+ //Save the current position inside the menu
+ byte menuPos = 1;
+ //Background
+ mainMenuBackground();
+ //Title
+ mainMenuTitle((char*) "Select Preset");
+ //Draw the selection menu
+ drawSelectionMenu();
+ //Draw the current item
+ tempLimitsPresetSaveString(menuPos);
+ //Save the current position inside the menu
+ while (true)
+ {
+ //Touch screen pressed
+ if (touch_touched() == true)
+ {
+ int pressedButton = buttons_checkButtons(true);
+ //SELECT
+ if (pressedButton == 3)
+ {
+ uint8_t farray[4];
+ switch (menuPos)
+ {
+ //Temporary
+ case 0:
+ EEPROM.write(eeprom_minMaxPreset, minMax_temporary);
+ break;
+ //Preset 1
+ case 1:
+ EEPROM.write(eeprom_minValue1High,
+ (minValue & 0xFF00) >> 8);
+ EEPROM.write(eeprom_minValue1Low, minValue & 0x00FF);
+ EEPROM.write(eeprom_maxValue1High,
+ (maxValue & 0xFF00) >> 8);
+ EEPROM.write(eeprom_maxValue1Low, maxValue & 0x00FF);
+ floatToBytes(farray, (float) calComp);
+ for (int i = 0; i < 4; i++)
+ EEPROM.write(eeprom_minMax1Comp + i, (farray[i]));
+ EEPROM.write(eeprom_minMax1Set, eeprom_setValue);
+ EEPROM.write(eeprom_minMaxPreset, minMax_preset1);
+ break;
+ //Preset 2
+ case 2:
+ EEPROM.write(eeprom_minValue2High,
+ (minValue & 0xFF00) >> 8);
+ EEPROM.write(eeprom_minValue2Low, minValue & 0x00FF);
+ EEPROM.write(eeprom_maxValue2High,
+ (maxValue & 0xFF00) >> 8);
+ EEPROM.write(eeprom_maxValue2Low, maxValue & 0x00FF);
+ floatToBytes(farray, (float) calComp);
+ for (int i = 0; i < 4; i++)
+ EEPROM.write(eeprom_minMax2Comp + i, (farray[i]));
+ EEPROM.write(eeprom_minMax2Set, eeprom_setValue);
+ EEPROM.write(eeprom_minMaxPreset, minMax_preset2);
+ break;
+ //Preset 3
+ case 3:
+ EEPROM.write(eeprom_minValue3High,
+ (minValue & 0xFF00) >> 8);
+ EEPROM.write(eeprom_minValue3Low, minValue & 0x00FF);
+ EEPROM.write(eeprom_maxValue3High,
+ (maxValue & 0xFF00) >> 8);
+ EEPROM.write(eeprom_maxValue3Low, maxValue & 0x00FF);
+ floatToBytes(farray, (float) calComp);
+ for (int i = 0; i < 4; i++)
+ EEPROM.write(eeprom_minMax3Comp + i, (farray[i]));
+ EEPROM.write(eeprom_minMax3Set, eeprom_setValue);
+ EEPROM.write(eeprom_minMaxPreset, minMax_preset3);
+ break;
+ }
+ return true;
+ }
+ //BACKWARD
+ else if (pressedButton == 0)
+ {
+ if (menuPos > 0)
+ menuPos--;
+ else if (menuPos == 0)
+ menuPos = 3;
+ }
+ //FORWARD
+ else if (pressedButton == 1)
+ {
+ if (menuPos < 3)
+ menuPos++;
+ else if (menuPos == 3)
+ menuPos = 0;
+ }
+ //BACK
+ else if (pressedButton == 2)
+ return false;
+ //Change the menu name
+ tempLimitsPresetSaveString(menuPos);
+ }
+ }
+}
+
+/* Touch Handler for the limit chooser menu */
+bool tempLimitsManualHandler()
+{
+
+ //Set both modes to false for the first time
+ bool minChange = false;
+ bool maxChange = false;
+ //Buffer
+ int min, max;
+ char minC[10];
+ char maxC[10];
+
+ //Touch handler
+ while (true)
+ {
+ //Set font & text color
+ display_setFont(smallFont);
+ display_setBackColor(VGA_TRANSPARENT);
+ changeTextColor();
+
+ //Update minimum & maximum
+ min = (int) round(calFunction(minValue));
+ max = (int) round(calFunction(maxValue));
+ if (tempFormat == tempFormat_celcius)
+ {
+ sprintf(minC, "Min:%dC", min);
+ sprintf(maxC, "Max:%dC", max);
+ }
+ else
+ {
+ sprintf(minC, "Min:%dF", min);
+ sprintf(maxC, "Max:%dF", max);
+ }
+ display_print(maxC, 180, 153);
+ display_print(minC, 85, 153);
+ display_setFont(bigFont);
+
+ //If touch pressed
+ if (touch_touched() == true)
+ {
+ int pressedButton;
+ //Change values continously and fast when the user holds the plus or minus button
+ if (minChange || maxChange)
+ pressedButton = buttons_checkButtons(true, true);
+ //Normal check when not in minChange or maxChange mode
+ else
+ pressedButton = buttons_checkButtons();
+ //RESET
+ if (pressedButton == 0)
+ {
+ //Refresh min and max
+ delay(10);
+ lepton_getRawValues();
+ limitValues();
+ }
+ //SELECT
+ else if (pressedButton == 1)
+ {
+ //Leave the minimum or maximum change mode
+ if (minChange || maxChange)
+ {
+ buttons_relabelButton(1, (char*) "OK", true);
+ buttons_relabelButton(2, (char*) "Min", true);
+ buttons_relabelButton(3, (char*) "Max", true);
+ if (minChange == true)
+ minChange = false;
+ if (maxChange == true)
+ maxChange = false;
+ }
+ //Go back
+ else
+ {
+ if (tempLimitsPresetSaveMenu())
+ return true;
+ else
+ return false;
+ }
+ }
+ //DECREASE
+ else if (pressedButton == 2)
+ {
+ //In minimum change mode - decrease minimum temp
+ if ((minChange == true) && (maxChange == false))
+ {
+ //Check if minimum is in range
+ if (min > -70)
+ {
+ min--;
+ minValue = tempToRaw(min);
+ }
+ }
+ //Enter minimum change mode
+ else if ((minChange == false) && (maxChange == false))
+ {
+ buttons_relabelButton(1, (char*) "Back", true);
+ buttons_relabelButton(2, (char*) "-", true);
+ buttons_relabelButton(3, (char*) "+", true);
+ minChange = true;
+ }
+ //In maximum change mode - decrease maximum temp
+ else if ((minChange == false) && (maxChange == true))
+ {
+ //Check if maximum is bigger than minimum
+ if (max > (min + 1))
+ {
+ max--;
+ maxValue = tempToRaw(max);
+ }
+ }
+ }
+ //INCREASE
+ else if (pressedButton == 3)
+ {
+ //In maximum change mode - increase maximum temp
+ if ((minChange == false) && (maxChange == true))
+ {
+ //Check if maximum is in range
+ if (max < 380)
+ {
+ max++;
+ maxValue = tempToRaw(max);
+ }
+ }
+ //Enter maximum change mode
+ else if ((minChange == false) && (maxChange == false))
+ {
+ buttons_relabelButton(1, (char*) "Back", true);
+ buttons_relabelButton(2, (char*) "-", true);
+ buttons_relabelButton(3, (char*) "+", true);
+ maxChange = true;
+
+ }
+ //In minimum change mode - increase minimum temp
+ else if ((minChange == true) && (maxChange == false))
+ {
+ //Check if minimum is smaller than maximum
+ if (min < (max - 1))
+ {
+ min++;
+ minValue = tempToRaw(min);
+ }
+ }
+ }
+
+ //Prepare the preview image
+ delay(10);
+ createThermalImg(true);
+
+ //Display the preview image
+ display_drawBitmap(80, 48, 160, 120, smallBuffer, 1);
+ }
+ }
+}
+
+/* Select the limits in Manual Mode*/
+void tempLimitsManual()
+{
+ redraw:
+ //Background & title
+ mainMenuBackground();
+ mainMenuTitle((char*) "Temp. Limits");
+
+ //Draw the buttons
+ buttons_deleteAllButtons();
+ buttons_setTextFont(bigFont);
+ buttons_addButton(15, 188, 140, 40, (char*) "Reset");
+ buttons_addButton(165, 188, 140, 40, (char*) "OK");
+ buttons_addButton(15, 48, 55, 120, (char*) "Min");
+ buttons_addButton(250, 48, 55, 120, (char*) "Max");
+ buttons_drawButtons();
+
+ //Prepare the preview image
+ delay(10);
+ autoMode = true;
+ createThermalImg(true);
+ autoMode = false;
+
+ //Display the preview image
+ display_drawBitmap(80, 48, 160, 120, smallBuffer, 1);
+
+ //Draw the border for the preview image
+ display_setColor(VGA_BLACK);
+ display_drawRect(79, 47, 241, 169);
+
+ //Go into the normal touch handler
+ if (!tempLimitsManualHandler())
+ goto redraw;
+}
+
+/* Switch the temperature limits preset string */
+void tempLimitsPresetsString(int pos)
+{
+ char* text = (char*) "";
+ switch (pos)
+ {
+ case 0:
+ text = (char*) "New";
+ break;
+ case 1:
+ text = (char*) "Preset 1";
+ break;
+ case 2:
+ text = (char*) "Preset 2";
+ break;
+ case 3:
+ text = (char*) "Preset 3";
+ break;
+ }
+ mainMenuSelection(text);
+}
+
+/* Menu to save the temperature limits to a preset */
+bool tempLimitsPresets()
+{
+ //Save the current position inside the menu
+ byte tempLimitsMenuPos = 0;
+ //Background
+ mainMenuBackground();
+ //Title
+ mainMenuTitle((char*) "Choose Preset");
+ //Draw the selection menu
+ drawSelectionMenu();
+ //Draw the current item
+ tempLimitsPresetsString(tempLimitsMenuPos);
+ //Save the current position inside the menu
+ while (true)
+ {
+ //Touch screen pressed
+ if (touch_touched() == true)
+ {
+ int pressedButton = buttons_checkButtons(true);
+ //SELECT
+ if (pressedButton == 3)
+ {
+ switch (tempLimitsMenuPos)
+ {
+ //New
+ case 0:
+ tempLimitsManual();
+ return true;
+ //Load Preset 1
+ case 1:
+ if (EEPROM.read(eeprom_minMax1Set) == eeprom_setValue)
+ EEPROM.write(eeprom_minMaxPreset, minMax_preset1);
+ else
+ {
+ showFullMessage((char*) "Preset 1 not saved", true);
+ delay(1000);
+ return false;
+ }
+ break;
+ //Load Preset 2
+ case 2:
+ if (EEPROM.read(eeprom_minMax2Set) == eeprom_setValue)
+ EEPROM.write(eeprom_minMaxPreset, minMax_preset2);
+ else
+ {
+ showFullMessage((char*) "Preset 2 not saved", true);
+ delay(1000);
+ return false;
+ }
+ break;
+ //Load Preset 3
+ case 3:
+ if (EEPROM.read(eeprom_minMax2Set) == eeprom_setValue)
+ EEPROM.write(eeprom_minMaxPreset, minMax_preset3);
+ else
+ {
+ showFullMessage((char*) "Preset 3 not saved", true);
+ delay(1000);
+ return false;
+ }
+ break;
+ }
+ //Read temperature limits from EEPROM
+ readTempLimits();
+ return true;
+ }
+ //BACKWARD
+ else if (pressedButton == 0)
+ {
+ if (tempLimitsMenuPos > 0)
+ tempLimitsMenuPos--;
+ else if (tempLimitsMenuPos == 0)
+ tempLimitsMenuPos = 3;
+ }
+ //FORWARD
+ else if (pressedButton == 1)
+ {
+ if (tempLimitsMenuPos < 3)
+ tempLimitsMenuPos++;
+ else if (tempLimitsMenuPos == 3)
+ tempLimitsMenuPos = 0;
+ }
+ //BACK
+ else if (pressedButton == 2)
+ return false;
+ //Change the menu name
+ tempLimitsPresetsString(tempLimitsMenuPos);
+ }
+ }
+}
+
+void changeGain()
+{
+ /* Generate menu */
+ drawTitle((char*) "Gain Mode");
+ buttons_deleteAllButtons();
+ buttons_setTextFont(smallFont);
+ buttons_addButton(20, 60, 130, 70, (char*) "-10C - +140C");
+ buttons_addButton(170, 60, 130, 70, (char*) "-10C - +450C");
+ buttons_addButton(20, 150, 280, 70, (char*) "Save");
+ buttons_drawButtons();
+ if (gainMode == lepton_3_5_gain_high)
+ buttons_setActive(0);
+ else
+ buttons_setActive(1);
+ //Touch handler
+ while (true)
+ {
+ //touch pressed
+ if (touch_touched() == true)
+ {
+ int pressedButton = buttons_checkButtons();
+ //High gain
+ if (pressedButton == 0)
+ {
+ if (gainMode == lepton_3_5_gain_low)
+ {
+ gainMode = lepton_3_5_gain_high;
+ buttons_setActive(0);
+ buttons_setInactive(1);
+ }
+ }
+ //Low gain
+ else if (pressedButton == 1)
+ {
+ if (gainMode == lepton_3_5_gain_high)
+ {
+ gainMode = lepton_3_5_gain_low;
+ buttons_setActive(1);
+ buttons_setInactive(0);
+ }
+ }
+ //Save
+ else if (pressedButton == 2)
+ {
+ //Change gain mode
+ if(gainMode == lepton_3_5_gain_low)
+ {
+ lepton_3_5_set_low_gain();
+ }
+ else
+ {
+ lepton_3_5_set_high_gain();
+ }
+
+ //Write new settings to EEPROM
+ EEPROM.write(eeprom_lepton_3_5_gain, gainMode);
+
+ //Trigger shutter
+ lepton_ffc(true, true);
+
+ break;
+ }
+ }
+ }
+}
+
+/* Temperature Limit Mode Selection */
+bool tempLimits()
+{
+ //Do not show in visual mode
+ if (displayMode == displayMode_visual)
+ {
+ showFullMessage((char*) "No use in visual mode", true);
+ delay(1000);
+ return false;
+ }
+
+ //Still in warmup, do not let the user do this
+ if (calStatus == cal_warmup)
+ {
+ showFullMessage((char*) "Please wait for sensor warmup", true);
+ delay(1000);
+ return false;
+ }
+
+ //Title & Background
+ redraw:
+ mainMenuBackground();
+ mainMenuTitle((char*) "Temp. Limits");
+
+ //Draw the buttons
+ buttons_deleteAllButtons();
+ buttons_setTextFont(bigFont);
+ buttons_addButton(15, 47, 140, 120, (char*) "Auto");
+ buttons_addButton(165, 47, 140, 120, (char*) "Manual");
+ buttons_addButton(15, 188, 140, 40, (char*) "Back");
+ if (leptonVersion == leptonVersion_3_5_shutter)
+ {
+ buttons_addButton(165, 188, 140, 40, (char*) "Gain");
+ }
+ buttons_drawButtons();
+
+ //Touch handler
+ while (true)
+ {
+ //If touch pressed
+ if (touch_touched() == true)
+ {
+ int pressedButton = buttons_checkButtons(true);
+ //AUTO
+ if (pressedButton == 0)
+ {
+ //Show message
+ showFullMessage((char*) "Please wait..", true);
+
+ //Enable auto mode again and disable limits locked
+ autoMode = true;
+ limitsLocked = false;
+
+ //Set temperature presets to temporary, so it does not load
+ EEPROM.write(eeprom_minMaxPreset, minMax_temporary);
+
+ //Enable auto FFC
+ lepton_ffcMode(true);
+
+ //Go back
+ return true;
+ }
+ //MANUAL
+ if (pressedButton == 1)
+ {
+ //Switch to manual FFC mode
+ if (leptonShutter == leptonShutter_auto)
+ lepton_ffcMode(false);
+
+ //Disable auto mode and limits locked
+ autoMode = false;
+ limitsLocked = false;
+
+ //Let the user choose the new limits
+ return tempLimitsPresets();
+ }
+ //BACK
+ if (pressedButton == 2)
+ return false;
+ //GAIN
+ if ((leptonVersion == leptonVersion_3_5_shutter)
+ && (pressedButton == 3))
+ {
+ changeGain();
+ goto redraw;
+ }
+ }
+ }
+}
+
+/* Switch the current display option item */
+void liveDispMenuString(int pos)
+{
+ char* text = (char*) "";
+ switch (pos)
+ {
+ //Battery
+ case 0:
+ if (batteryEnabled)
+ text = (char*) "Battery On";
+ else
+ text = (char*) "Battery Off";
+ break;
+ //Time
+ case 1:
+ if (timeEnabled)
+ text = (char*) "Time On";
+ else
+ text = (char*) "Time Off";
+ break;
+ //Date
+ case 2:
+ if (dateEnabled)
+ text = (char*) "Date On";
+ else
+ text = (char*) "Date Off";
+ break;
+ //Spot
+ case 3:
+ if (spotEnabled)
+ text = (char*) "Spot On";
+ else
+ text = (char*) "Spot Off";
+ break;
+ //Colorbar
+ case 4:
+ if (colorbarEnabled)
+ text = (char*) "Bar On";
+ else
+ text = (char*) "Bar Off";
+ break;
+ //Storage
+ case 5:
+ if (storageEnabled)
+ text = (char*) "Storage On";
+ else
+ text = (char*) "Storage Off";
+ break;
+ //Filter
+ case 6:
+ if (filterType == filterType_box)
+ text = (char*) "Box-Filter";
+ else if (filterType == filterType_gaussian)
+ text = (char*) "Gaus-Filter";
+ else
+ text = (char*) "No Filter";
+ break;
+ //Text Color
+ case 7:
+ if (textColor == textColor_black)
+ text = (char*) "Black Text";
+ else if (textColor == textColor_red)
+ text = (char*) "Red Text";
+ else if (textColor == textColor_green)
+ text = (char*) "Green Text";
+ else if (textColor == textColor_blue)
+ text = (char*) "Blue Text";
+ else
+ text = (char*) "White Text";
+ break;
+ //Hottest or coldest
+ case 8:
+ if (minMaxPoints == minMaxPoints_disabled)
+ text = (char*) "No Cold/Hot";
+ else if (minMaxPoints == minMaxPoints_min)
+ text = (char*) "Coldest";
+ else if (minMaxPoints == minMaxPoints_max)
+ text = (char*) "Hottest";
+ else
+ text = (char*) "Both C/H";
+ break;
+
+ }
+ mainMenuSelection(text);
+}
+
+/* Change the live display options */
+bool liveDispMenu()
+{
+ //Save the current position inside the menu
+ static byte displayOptionsPos = 0;
+ //Background
+ mainMenuBackground();
+ //Title
+ mainMenuTitle((char*) "Live Disp. Options");
+ //Draw the selection menu
+ drawSelectionMenu();
+ //Rename OK button
+ buttons_relabelButton(3, (char*) "Switch", true);
+ //Draw the current item
+ liveDispMenuString(displayOptionsPos);
+ while (true)
+ {
+ //Touch screen pressed
+ if (touch_touched() == true)
+ {
+ int pressedButton = buttons_checkButtons(true);
+ //SELECT
+ if (pressedButton == 3)
+ {
+ changeDisplayOptions(&displayOptionsPos);
+ }
+ //BACK
+ if (pressedButton == 2)
+ {
+ return false;
+ }
+ //BACKWARD
+ else if (pressedButton == 0)
+ {
+ if (displayOptionsPos > 0)
+ displayOptionsPos--;
+ else if (displayOptionsPos == 0)
+ displayOptionsPos = 8;
+ }
+ //FORWARD
+ else if (pressedButton == 1)
+ {
+ if (displayOptionsPos < 8)
+ displayOptionsPos++;
+ else if (displayOptionsPos == 8)
+ displayOptionsPos = 0;
+ }
+ //Change the menu name
+ liveDispMenuString(displayOptionsPos);
+ }
+ }
+}
+
+/* Switch the current color scheme item */
+void colorMenuString(int pos)
+{
+ char* text = (char*) "";
+ switch (pos)
+ {
+ case colorScheme_arctic:
+ text = (char*) "Arctic";
+ break;
+ case colorScheme_blackHot:
+ text = (char*) "Black-Hot";
+ break;
+ case colorScheme_blueRed:
+ text = (char*) "Blue-Red";
+ break;
+ case colorScheme_coldest:
+ text = (char*) "Coldest";
+ break;
+ case colorScheme_contrast:
+ text = (char*) "Contrast";
+ break;
+ case colorScheme_doubleRainbow:
+ text = (char*) "Double-Rain";
+ break;
+ case colorScheme_grayRed:
+ text = (char*) "Gray-Red";
+ break;
+ case colorScheme_glowBow:
+ text = (char*) "Glowbow";
+ break;
+ case colorScheme_grayscale:
+ text = (char*) "Grayscale";
+ break;
+ case colorScheme_hottest:
+ text = (char*) "Hottest";
+ break;
+ case colorScheme_ironblack:
+ text = (char*) "Ironblack";
+ break;
+ case colorScheme_lava:
+ text = (char*) "Lava";
+ break;
+ case colorScheme_medical:
+ text = (char*) "Medical";
+ break;
+ case colorScheme_rainbow:
+ text = (char*) "Rainbow";
+ break;
+ case colorScheme_wheel1:
+ text = (char*) "Wheel 1";
+ break;
+ case colorScheme_wheel2:
+ text = (char*) "Wheel 2";
+ break;
+ case colorScheme_wheel3:
+ text = (char*) "Wheel 3";
+ break;
+ case colorScheme_whiteHot:
+ text = (char*) "White-Hot";
+ break;
+ case colorScheme_yellow:
+ text = (char*) "Yellow";
+ break;
+ }
+ mainMenuSelection(text);
+}
+
+/* Choose the applied color scale */
+bool colorMenu()
+{
+ //Do not show in visual mode
+ if (displayMode == displayMode_visual)
+ {
+ showFullMessage((char*) "No use in visual mode", true);
+ delay(1000);
+ return false;
+ }
+
+ //Save the current position inside the menu
+ byte changeColorPos = colorScheme;
+ //Background
+ mainMenuBackground();
+ //Title
+ mainMenuTitle((char*) "Change Color");
+ //Draw the selection menu
+ drawSelectionMenu();
+ //Draw the current item
+ colorMenuString(changeColorPos);
+ while (true)
+ {
+ //Touch screen pressed
+ if (touch_touched() == true)
+ {
+ int pressedButton = buttons_checkButtons(true);
+ //SELECT
+ if (pressedButton == 3)
+ {
+ changeColorScheme(&changeColorPos);
+ return true;
+ }
+ //BACK
+ if (pressedButton == 2)
+ return false;
+ //BACKWARD
+ else if (pressedButton == 0)
+ {
+ if (changeColorPos > 0)
+ changeColorPos--;
+ else if (changeColorPos == 0)
+ changeColorPos = colorSchemeTotal - 1;
+ }
+ //FORWARD
+ else if (pressedButton == 1)
+ {
+ if (changeColorPos < (colorSchemeTotal - 1))
+ changeColorPos++;
+ else if (changeColorPos == (colorSchemeTotal - 1))
+ changeColorPos = 0;
+ }
+ //Change the menu name
+ colorMenuString(changeColorPos);
+ }
+ }
+}
+
+/* Choose the current display mode */
+bool modeMenu()
+{
+ //Background
+ mainMenuBackground();
+ //Title
+ mainMenuTitle((char*) "Change Mode");
+ //Draw the selection menu
+ buttons_deleteAllButtons();
+ buttons_setTextFont(smallFont);
+ buttons_addButton(15, 45, 90, 122, (char*) "Thermal");
+ buttons_addButton(115, 45, 90, 122, (char*) "Visual");
+ buttons_addButton(215, 45, 90, 122, (char*) "Combined");
+ buttons_addButton(15, 188, 120, 40, (char*) "Back");
+ buttons_drawButtons();
+ while (true)
+ {
+ //Touch screen pressed
+ if (touch_touched() == true)
+ {
+ int pressedButton = buttons_checkButtons(true);
+ //Thermal
+ if (pressedButton == 0)
+ {
+ //Show message
+ showFullMessage((char*) "Please wait..", true);
+
+ //Set camera resolution to save
+ camera_setSaveRes();
+
+ //Set display mode to thermal
+ displayMode = displayMode_thermal;
+ EEPROM.write(eeprom_displayMode, displayMode_thermal);
+ return true;
+ }
+
+ //Visual or combined
+ if ((pressedButton == 1) || (pressedButton == 2))
+ {
+ //If the visual camera is not working
+ if (!checkDiagnostic(diag_camera))
+ {
+ showFullMessage((char*) "Cam not connected", true);
+ delay(1000);
+ return false;
+ }
+
+ //Show message
+ showFullMessage((char*) "Please wait..", true);
+
+ //Set camera resolution to streaming
+ camera_setDisplayRes();
+
+ //Set display mode to visual
+ if (pressedButton == 1)
+ {
+ displayMode = displayMode_visual;
+ EEPROM.write(eeprom_displayMode, displayMode_visual);
+ }
+ //Set display mode to combined
+ else
+ {
+ displayMode = displayMode_combined;
+ EEPROM.write(eeprom_displayMode, displayMode_combined);
+ }
+ return true;
+ }
+ //Back
+ if (pressedButton == 3)
+ return false;
+ }
+ }
+}
+
+/* HQ Resolution Menu */
+void hqResolutionMenu()
+{
+ drawTitle((char*) "HQ Resolution");
+ buttons_deleteAllButtons();
+ buttons_setTextFont(smallFont);
+ buttons_addButton(20, 60, 130, 70, (char*) "Off (160x120)");
+ buttons_addButton(170, 60, 130, 70, (char*) "On (320x240)");
+ buttons_addButton(20, 150, 280, 70, (char*) "Save");
+ buttons_drawButtons();
+ if (hqRes)
+ buttons_setActive(1);
+ else
+ buttons_setActive(0);
+ //Touch handler
+ while (true)
+ {
+ //touch pressed
+ if (touch_touched() == true)
+ {
+ int pressedButton = buttons_checkButtons();
+ //Off
+ if (pressedButton == 0)
+ {
+ if (hqRes)
+ {
+ hqRes = false;
+ buttons_setActive(0);
+ buttons_setInactive(1);
+ }
+ }
+ //On
+ else if (pressedButton == 1)
+ {
+ if (!hqRes)
+ {
+ hqRes = true;
+ buttons_setActive(1);
+ buttons_setInactive(0);
+ }
+ }
+ //Save
+ else if (pressedButton == 2)
+ {
+ //Change camera resolution
+ if (displayMode == displayMode_thermal)
+ camera_setSaveRes();
+ else
+ camera_setDisplayRes();
+
+ //Write new settings to EEPROM
+ EEPROM.write(eeprom_hqRes, hqRes);
+ break;
+ }
+ }
+ }
+}
+
+/* Draws the content of the main menu*/
+void drawMainMenu(byte pos)
+{
+ //Border
+ drawMainMenuBorder();
+ //Background
+ display_setColor(200, 200, 200);
+ display_fillRoundRect(6, 6, 314, 234);
+ //Buttons
+ buttons_deleteAllButtons();
+ //First page
+ if (pos == 0)
+ {
+ buttons_addButton(23, 28, 80, 80, icon1Bitmap, icon1Colors);
+ buttons_addButton(120, 28, 80, 80, icon2Bitmap, icon2Colors);
+ buttons_addButton(217, 28, 80, 80, icon3Bitmap, icon3Colors);
+ }
+ //Second page
+ if (pos == 1)
+ {
+ buttons_addButton(23, 28, 80, 80, icon4Bitmap, icon4Colors);
+ if (teensyVersion == teensyVersion_old)
+ buttons_addButton(120, 28, 80, 80, icon5Bitmap_1, icon5Colors);
+ else
+ buttons_addButton(120, 28, 80, 80, icon5Bitmap_2, icon5Colors);
+ buttons_addButton(217, 28, 80, 80, icon6Bitmap, icon6Colors);
+ }
+ //Third page
+ if (pos == 2)
+ {
+ buttons_addButton(23, 28, 80, 80, icon7Bitmap, icon7Colors);
+ if (teensyVersion == teensyVersion_old)
+ buttons_addButton(120, 28, 80, 80, icon8Bitmap_1, icon8Colors);
+ else
+ buttons_addButton(120, 28, 80, 80, icon8Bitmap_2, icon8Colors);
+ buttons_addButton(217, 28, 80, 80, icon9Bitmap, icon9Colors);
+ }
+ //Fourth page
+ if (pos == 3)
+ {
+ buttons_addButton(23, 28, 80, 80, icon10Bitmap, icon10Colors);
+ if (displayMode == displayMode_thermal)
+ buttons_addButton(120, 28, 80, 80, icon11_1Bitmap, icon11_1Colors);
+ else
+ buttons_addButton(120, 28, 80, 80, icon11_2Bitmap, icon11_2Colors);
+ buttons_addButton(217, 28, 80, 80, icon12Bitmap, icon12Colors);
+ }
+ buttons_addButton(23, 132, 80, 80, iconBWBitmap, iconBWColors);
+ buttons_addButton(120, 132, 80, 80, iconReturnBitmap, iconReturnColors);
+ buttons_addButton(217, 132, 80, 80, iconFWBitmap, iconFWColors);
+ buttons_drawButtons();
+}
+
+/* Select the action when the select button is pressed */
+bool mainMenuSelect(byte pos, byte page)
+{
+ //First page
+ if (page == 0)
+ {
+ //Change color
+ if (pos == 0)
+ {
+ return colorMenu();
+ }
+ //Change mode
+ if (pos == 1)
+ {
+ return modeMenu();
+ }
+ //Temperature limits
+ if (pos == 2)
+ {
+ return tempLimits();
+ }
+ }
+ //Second page
+ if (page == 1)
+ {
+ //Load menu
+ if (pos == 0)
+ {
+ loadFiles();
+ }
+ //File Transfer or Shutter
+ if (pos == 1)
+ {
+ if (teensyVersion == teensyVersion_old)
+ massStorage();
+ else
+ lepton_ffc(true);
+ }
+ //Settings
+ if (pos == 2)
+ {
+ settingsMenu();
+ settingsMenuHandler();
+ }
+ }
+ //Third page
+ if (page == 2)
+ {
+ //Display options
+ if (pos == 0)
+ {
+ return liveDispMenu();
+ }
+ //Laser or HQ resolution
+ if (pos == 1)
+ {
+ if (teensyVersion == teensyVersion_old)
+ toggleLaser(true);
+ else
+ hqResolutionMenu();
+ }
+ //Toggle display
+ if (pos == 2)
+ {
+ toggleDisplay();
+ }
+ }
+ //Fourth page
+ if (page == 3)
+ {
+ //Calibration
+ if (pos == 0)
+ {
+ return calibration();
+ }
+ //Isotherm or adjust visual
+ if (pos == 1)
+ {
+ if (displayMode == displayMode_thermal)
+ return hotColdMenu();
+ else
+ return adjustCombinedMenu();
+ }
+ //Points
+ if (pos == 2)
+ {
+ return tempPointsMenu();
+ }
+ }
+ return false;
+}
+
+/* Touch Handler for the Live Menu */
+void mainMenuHandler(byte* pos)
+{
+ //Main loop
+ while (true)
+ {
+ //Check for screen sleep
+ if (screenOffCheck())
+ drawMainMenu(*pos);
+
+ //Touch screen pressed
+ if (touch_touched() == true)
+ {
+ int pressedButton = buttons_checkButtons(true);
+ //FIRST BUTTON
+ if (pressedButton == 0)
+ {
+ //Leave menu
+ if (mainMenuSelect(0, *pos))
+ break;
+ }
+ //SECOND BUTTON
+ if (pressedButton == 1)
+ {
+ //Leave menu
+ if (mainMenuSelect(1, *pos))
+ break;
+ }
+ //THIRD BUTTON
+ if (pressedButton == 2)
+ {
+ //Leave menu
+ if (mainMenuSelect(2, *pos))
+ break;
+ }
+ //BACKWARD
+ else if (pressedButton == 3)
+ {
+ if (*pos > 0)
+ *pos = *pos - 1;
+ else if (*pos == 0)
+ *pos = 3;
+ }
+ //EXIT
+ if (pressedButton == 4)
+ {
+ showFullMessage((char*) "Please wait..", true);
+ return;
+ }
+ //FORWARD
+ else if (pressedButton == 5)
+ {
+ if (*pos < 3)
+ *pos = *pos + 1;
+ else if (*pos == 3)
+ *pos = 0;
+ }
+ drawMainMenu(*pos);
+ }
+ }
+}
+
+/* Start live menu */
+void mainMenu()
+{
+ //Set show menu to opened
+ showMenu = showMenu_opened;
+
+ //Position in the main menu
+ static byte mainMenuPos = 0;
+
+ //Draw content
+ drawMainMenu(mainMenuPos);
+
+ //Touch handler - return true if exit to Main menu, otherwise false
+ mainMenuHandler(&mainMenuPos);
+
+ //Restore old fonts
+ display_setFont(smallFont);
+ buttons_setTextFont(smallFont);
+
+ //Delete the old buttons
+ buttons_deleteAllButtons();
+
+ //Wait a short time
+ delay(500);
+
+ //Clear serial buffer
+ Serial.clear();
+
+ //Disable menu marker
+ showMenu = showMenu_disabled;
+}
diff --git a/Firmware_V2/src/gui/mainmenu.h b/Firmware_V2/src/gui/mainmenu.h
new file mode 100644
index 0000000..439cb13
--- /dev/null
+++ b/Firmware_V2/src/gui/mainmenu.h
@@ -0,0 +1,53 @@
+/*
+*
+* MAIN MENU - Display the main menu with icons
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef MAINMENU_H
+#define MAINMENU_H
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+bool calibrationRepeat();
+void calibrationScreen(bool firstStart = false);
+bool colorMenu();
+void colorMenuString(int pos);
+void drawMainMenu(byte pos);
+void drawSelectionMenu();
+void hotColdChooserHandler();
+void hotColdChooser();
+bool hotColdColorMenu();
+void hotColdColorMenuString(int pos);
+bool hotColdMenu();
+void hqResolutionMenu();
+bool liveDispMenu();
+void liveDispMenuString(int pos);
+void mainMenuBackground();
+void mainMenuHandler(byte* pos);
+bool mainMenuSelect(byte pos, byte page);
+void mainMenuSelection(char* selection);
+void mainMenuTitle(char* title);
+void mainMenu();
+bool massStoragePrompt();
+bool modeMenu();
+bool tempLimits();
+bool tempLimitsManualHandler();
+void tempLimitsManual();
+bool tempLimitsPresetSaveMenu();
+void tempLimitsPresetSaveString(int pos);
+bool tempLimitsPresets();
+void tempLimitsPresetsString(int pos);
+bool tempPointsMenu();
+
+#endif /* MAINMENU_H */
+
diff --git a/Firmware_V2/src/gui/settingsmenu.cpp b/Firmware_V2/src/gui/settingsmenu.cpp
new file mode 100644
index 0000000..3ee5b0b
--- /dev/null
+++ b/Firmware_V2/src/gui/settingsmenu.cpp
@@ -0,0 +1,1330 @@
+/*
+*
+* SETTINGS MENU - Adjust different on-device settings
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* Draw the GUI elements for the adjust combined menu */
+void adjustCombinedGUI() {
+ //Color and font
+ changeTextColor();
+ display_setFont(bigFont);
+ display_setBackColor(VGA_TRANSPARENT);
+
+ //Down arrow
+ display_drawLine(149, 225, 159, 235);
+ display_drawLine(150, 225, 160, 235);
+ display_drawLine(151, 225, 161, 235);
+ display_drawLine(159, 235, 169, 225);
+ display_drawLine(160, 235, 170, 225);
+ display_drawLine(161, 235, 171, 225);
+ //Left arrow
+ display_drawLine(15, 109, 5, 119);
+ display_drawLine(15, 110, 5, 120);
+ display_drawLine(15, 111, 5, 121);
+ display_drawLine(5, 119, 15, 129);
+ display_drawLine(5, 120, 15, 130);
+ display_drawLine(5, 121, 15, 131);
+ //Up arrow
+ display_drawLine(149, 15, 159, 5);
+ display_drawLine(150, 15, 160, 5);
+ display_drawLine(151, 15, 161, 5);
+ display_drawLine(159, 5, 169, 15);
+ display_drawLine(160, 5, 170, 15);
+ display_drawLine(161, 5, 171, 15);
+ //Right arrow
+ display_drawLine(305, 109, 315, 119);
+ display_drawLine(305, 110, 315, 120);
+ display_drawLine(305, 111, 315, 121);
+ display_drawLine(315, 119, 305, 129);
+ display_drawLine(315, 120, 305, 130);
+ display_drawLine(315, 121, 305, 131);
+ //Decrease
+ display_drawLine(5, 224, 25, 224);
+ display_drawLine(5, 225, 25, 225);
+ display_drawLine(5, 226, 25, 226);
+ //Increase
+ display_drawLine(5, 14, 25, 14);
+ display_drawLine(5, 15, 25, 15);
+ display_drawLine(5, 16, 25, 16);
+ display_drawLine(14, 5, 14, 25);
+ display_drawLine(15, 5, 15, 25);
+ display_drawLine(16, 5, 16, 25);
+
+ //Alpha level
+ display_print('A', 300, 5);
+
+ //Color for confirm
+ display_setColor(0, 255, 0);
+ //Confirm button
+ display_drawLine(294, 225, 304, 235);
+ display_drawLine(295, 225, 305, 235);
+ display_drawLine(296, 225, 306, 235);
+ display_drawLine(304, 235, 314, 215);
+ display_drawLine(305, 235, 315, 215);
+ display_drawLine(306, 235, 316, 215);
+
+ //Restore old font
+ display_setFont(smallFont);
+}
+
+/* Refresh the screen content in adjust combined menu */
+void adjustCombinedRefresh() {
+ //Create the combined image
+ createVisCombImg();
+
+ //Display it on the screen
+ displayBuffer();
+
+ //Display the GUI
+ adjustCombinedGUI();
+}
+
+/* Shows on the screen that is refreshes */
+void adjustCombinedLoading() {
+ //Set Text Color
+ changeTextColor();
+ //set Background transparent
+ display_setBackColor(VGA_TRANSPARENT);
+ //Give the user a hint that it tries to save
+ display_setFont(bigFont);
+ //Show text
+ display_print((char*) "Please wait..", CENTER, 110);
+ //Return to small font
+ display_setFont(smallFont);
+}
+
+/* Switch the current preset menu item */
+void adjustCombinedPresetSaveString(int pos) {
+ char* text = (char*) "";
+ switch (pos) {
+ case 0:
+ text = (char*) "Temporary";
+ break;
+ case 1:
+ text = (char*) "Preset 1";
+ break;
+ case 2:
+ text = (char*) "Preset 2";
+ break;
+ case 3:
+ text = (char*) "Preset 3";
+ break;
+ }
+ mainMenuSelection(text);
+}
+
+/* Menu to save the adjust combined settings to a preset */
+bool adjustCombinedPresetSaveMenu() {
+ //Save the current position inside the menu
+ byte menuPos = 1;
+ //Border
+ drawMainMenuBorder();
+ //Background
+ mainMenuBackground();
+ //Title
+ mainMenuTitle((char*) "Select Preset");
+ //Draw the selection menu
+ drawSelectionMenu();
+ //Draw the current item
+ adjustCombinedPresetSaveString(menuPos);
+ //Save the current position inside the menu
+ while (true) {
+ //Touch screen pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons(true);
+ //SELECT
+ if (pressedButton == 3) {
+ switch (menuPos) {
+ //Temporary
+ case 0:
+ EEPROM.write(eeprom_adjCombPreset, adjComb_temporary);
+ break;
+ //Preset 1
+ case 1:
+ EEPROM.write(eeprom_adjComb1Left, adjCombLeft);
+ EEPROM.write(eeprom_adjComb1Right, adjCombRight);
+ EEPROM.write(eeprom_adjComb1Up, adjCombUp);
+ EEPROM.write(eeprom_adjComb1Down, adjCombDown);
+ EEPROM.write(eeprom_adjComb1Alpha, round(adjCombAlpha * 100.0));
+ EEPROM.write(eeprom_adjComb1Factor, round(adjCombFactor * 100.0));
+ EEPROM.write(eeprom_adjComb1Set, eeprom_setValue);
+ EEPROM.write(eeprom_adjCombPreset, adjComb_preset1);
+ break;
+ //Preset 2
+ case 2:
+ EEPROM.write(eeprom_adjComb2Left, adjCombLeft);
+ EEPROM.write(eeprom_adjComb2Right, adjCombRight);
+ EEPROM.write(eeprom_adjComb2Up, adjCombUp);
+ EEPROM.write(eeprom_adjComb2Down, adjCombDown);
+ EEPROM.write(eeprom_adjComb2Alpha, round(adjCombAlpha * 100.0));
+ EEPROM.write(eeprom_adjComb2Factor, round(adjCombFactor * 100.0));
+ EEPROM.write(eeprom_adjComb2Set, eeprom_setValue);
+ EEPROM.write(eeprom_adjCombPreset, adjComb_preset2);
+ break;
+ //Preset 3
+ case 3:
+ EEPROM.write(eeprom_adjComb3Left, adjCombLeft);
+ EEPROM.write(eeprom_adjComb3Right, adjCombRight);
+ EEPROM.write(eeprom_adjComb3Up, adjCombUp);
+ EEPROM.write(eeprom_adjComb3Down, adjCombDown);
+ EEPROM.write(eeprom_adjComb3Alpha, round(adjCombAlpha * 100.0));
+ EEPROM.write(eeprom_adjComb3Factor, round(adjCombFactor * 100.0));
+ EEPROM.write(eeprom_adjComb3Set, eeprom_setValue);
+ EEPROM.write(eeprom_adjCombPreset, adjComb_preset3);
+ break;
+ }
+ return true;
+ }
+ //BACKWARD
+ else if (pressedButton == 0) {
+ if (menuPos > 0)
+ menuPos--;
+ else if (menuPos == 0)
+ menuPos = 3;
+ }
+ //FORWARD
+ else if (pressedButton == 1) {
+ if (menuPos < 3)
+ menuPos++;
+ else if (menuPos == 3)
+ menuPos = 0;
+ }
+ //BACK
+ else if (pressedButton == 2)
+ return false;
+ //Change the menu name
+ adjustCombinedPresetSaveString(menuPos);
+ }
+ }
+}
+
+/* Touch handler for the new adjust combined menu */
+void adjustCombinedNewMenuHandler(bool firstStart) {
+ //Touch handler
+ while (true) {
+ //Touch pressed
+ if (touch_touched() == true) {
+ //Get coordinates
+ TS_Point p = touch_getPoint();
+ uint16_t x = p.x;
+ uint16_t y = p.y;
+ //Increase
+ if ((x >= 0) && (x <= 50) && (y >= 0) && (y <= 50)) {
+ if (adjCombFactor < 1.0) {
+ adjustCombinedLoading();
+ adjCombFactor += 0.02;
+ adjustCombinedRefresh();
+ }
+ }
+ //Decrease
+ else if ((x >= 0) && (x <= 50) && (y >= 190) && (y <= 240)) {
+ if (adjCombFactor > 0.70) {
+ adjustCombinedLoading();
+ adjCombFactor -= 0.02;
+ adjustCombinedRefresh();
+ }
+ }
+ //Left
+ else if ((x >= 0) && (x <= 50) && (y >= 95) && (y <= 145)) {
+ if (adjCombLeft < 10) {
+ adjustCombinedLoading();
+ if (adjCombRight > 0)
+ adjCombRight -= 1;
+ else
+ adjCombLeft += 1;
+ adjustCombinedRefresh();
+ }
+ }
+ //Right
+ else if ((x >= 270) && (x <= 320) && (y >= 95) && (y <= 145)) {
+ if (adjCombRight < 10) {
+ adjustCombinedLoading();
+ if (adjCombLeft > 0)
+ adjCombLeft -= 1;
+ else
+ adjCombRight += 1;
+ adjustCombinedRefresh();
+ }
+ }
+ //Up
+ else if ((x >= 135) && (x <= 185) && (y >= 0) && (y <= 50)) {
+ if (adjCombUp < 10) {
+ adjustCombinedLoading();
+ if (adjCombDown > 0)
+ adjCombDown -= 1;
+ else
+ adjCombUp += 1;
+ adjustCombinedRefresh();
+ }
+ }
+ //Down
+ else if ((x >= 135) && (x <= 185) && (y >= 190) && (y <= 240)) {
+ if (adjCombDown < 10) {
+ adjustCombinedLoading();
+ if (adjCombUp > 0)
+ adjCombUp -= 1;
+ else
+ adjCombDown += 1;
+ adjustCombinedRefresh();
+ }
+ }
+ //OK
+ else if ((x >= 270) && (x <= 320) && (y >= 190) && (y <= 240)) {
+ //Preset chooser
+ if (!firstStart) {
+ if (adjustCombinedPresetSaveMenu())
+ return;
+ else
+ adjustCombinedRefresh();
+ }
+ //First start, save as preset 1
+ else {
+ EEPROM.write(eeprom_adjComb1Left, adjCombLeft);
+ EEPROM.write(eeprom_adjComb1Right, adjCombRight);
+ EEPROM.write(eeprom_adjComb1Up, adjCombUp);
+ EEPROM.write(eeprom_adjComb1Down, adjCombDown);
+ EEPROM.write(eeprom_adjComb1Alpha, round(adjCombAlpha * 100.0));
+ EEPROM.write(eeprom_adjComb1Factor, round(adjCombFactor * 100.0));
+ EEPROM.write(eeprom_adjComb1Set, eeprom_setValue);
+ EEPROM.write(eeprom_adjCombPreset, adjComb_preset1);
+ return;
+ }
+ }
+ //Refresh
+ else if ((x >= 50) && (x <= 270) && (y >= 50) && (y <= 210)) {
+ adjustCombinedLoading();
+ adjustCombinedRefresh();
+ }
+ //Change alpha
+ else if ((x >= 270) && (x <= 320) && (y >= 0) && (y <= 50)) {
+ char buffer[20];
+ if (adjCombAlpha < 0.7)
+ adjCombAlpha += 0.1;
+ else
+ adjCombAlpha = 0.3;
+ sprintf(buffer, "Alpha set to %.1f", adjCombAlpha);
+ display_setFont(bigFont);
+ changeTextColor();
+ display_print(buffer, CENTER, 110);
+ display_setFont(smallFont);
+ adjustCombinedRefresh();
+ }
+ }
+ }
+}
+
+/* Adjust combined new menu */
+void adjustCombinedNewMenu(bool firstStart) {
+ //Show loading message
+ showFullMessage((char*)"Please wait..");
+ //Prepare the preview image
+ byte displayMode_old = displayMode;
+ displayMode = displayMode_combined;
+ //Load the defaults
+ adjCombDown = 0;
+ adjCombUp = 0;
+ adjCombLeft = 0;
+ adjCombRight = 0;
+ adjCombAlpha = 0.5;
+ adjCombFactor = 1.0;
+ //Show the preview image
+ adjustCombinedRefresh();
+ //Run the handler and
+ adjustCombinedNewMenuHandler(firstStart);
+ //Show message
+ showFullMessage((char*) "Please wait..");
+ //Restore the old mode
+ displayMode = displayMode_old;
+}
+
+/* Switch the current temperature menu item */
+void adjustCombinedString(int pos) {
+ char* text = (char*) "";
+ switch (pos) {
+ case 0:
+ text = (char*) "New";
+ break;
+ case 1:
+ text = (char*) "Preset 1";
+ break;
+ case 2:
+ text = (char*) "Preset 2";
+ break;
+ case 3:
+ text = (char*) "Preset 3";
+ break;
+ }
+ mainMenuSelection(text);
+}
+
+/* Menu to save the adjust combined settings to a preset */
+bool adjustCombinedMenu() {
+ //Save the current position inside the menu
+ byte adjCombMenuPos = 0;
+ //Background
+ mainMenuBackground();
+ //Title
+ mainMenuTitle((char*) "Adjust Combined");
+ //Draw the selection menu
+ drawSelectionMenu();
+ //Draw the current item
+ adjustCombinedString(adjCombMenuPos);
+ //Save the current position inside the menu
+ while (true) {
+ //Touch screen pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons(true);
+ //SELECT
+ if (pressedButton == 3) {
+ switch (adjCombMenuPos) {
+ //New
+ case 0:
+ adjustCombinedNewMenu();
+ return true;
+ //Load Preset 1
+ case 1:
+ EEPROM.write(eeprom_adjCombPreset, adjComb_preset1);
+ break;
+ //Load Preset 2
+ case 2:
+ EEPROM.write(eeprom_adjCombPreset, adjComb_preset2);
+ break;
+ //Load Preset 3
+ case 3:
+ EEPROM.write(eeprom_adjCombPreset, adjComb_preset3);
+ break;
+ }
+ //Read config from EEPROM
+ readAdjustCombined();
+ return true;
+ }
+ //BACKWARD
+ else if (pressedButton == 0) {
+ if (adjCombMenuPos > 0)
+ adjCombMenuPos--;
+ else if (adjCombMenuPos == 0)
+ adjCombMenuPos = 3;
+ }
+ //FORWARD
+ else if (pressedButton == 1) {
+ if (adjCombMenuPos < 3)
+ adjCombMenuPos++;
+ else if (adjCombMenuPos == 3)
+ adjCombMenuPos = 0;
+ }
+ //BACK
+ else if (pressedButton == 2)
+ return false;
+
+ //Change the menu name
+ adjustCombinedString(adjCombMenuPos);
+ }
+ }
+}
+
+
+/* Second Menu */
+void secondMenu(bool firstStart) {
+ drawTitle((char*) "Second", firstStart);
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 70, 70, (char*) "-");
+ buttons_addButton(230, 60, 70, 70, (char*) "+");
+ buttons_addButton(20, 150, 280, 70, (char*) "Back");
+ buttons_drawButtons();
+ drawCenterElement(second());
+ //Touch handler
+ while (true) {
+ //touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons(true);
+ //Minus
+ if (pressedButton == 0) {
+ if (second() >= 0) {
+ if (second() > 0)
+ setTime(hour(), minute(), second() - 1, day(), month(),
+ year());
+ else if (second() == 0)
+ setTime(hour(), minute(), 59, day(), month(), year());
+ drawCenterElement(second());
+ }
+ }
+ //Plus
+ else if (pressedButton == 1) {
+ if (second() <= 59) {
+ if (second() < 59)
+ setTime(hour(), minute(), second() + 1, day(), month(),
+ year());
+ else if (second() == 59)
+ setTime(hour(), minute(), 0, day(), month(), year());
+ drawCenterElement(second());
+ }
+ }
+ //Back
+ else if (pressedButton == 2) {
+ Teensy3Clock.set(now());
+ timeMenu(firstStart);
+ break;
+ }
+ }
+ }
+}
+
+/* Minute Menu */
+void minuteMenu(bool firstStart) {
+ drawTitle((char*) "Minute", firstStart);
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 70, 70, (char*) "-");
+ buttons_addButton(230, 60, 70, 70, (char*) "+");
+ buttons_addButton(20, 150, 280, 70, (char*) "Back");
+ buttons_drawButtons();
+ drawCenterElement(minute());
+ //Touch handler
+ while (true) {
+ //touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons(true);
+ //Minus
+ if (pressedButton == 0) {
+ if (minute() >= 0) {
+ if (minute() > 0)
+ setTime(hour(), minute() - 1, second(), day(), month(),
+ year());
+ else if (minute() == 0)
+ setTime(hour(), 59, second(), day(), month(), year());
+ drawCenterElement(minute());
+ }
+ }
+ //Plus
+ else if (pressedButton == 1) {
+ if (minute() <= 59) {
+ if (minute() < 59)
+ setTime(hour(), minute() + 1, second(), day(), month(),
+ year());
+ else if (minute() == 59)
+ setTime(hour(), 0, second(), day(), month(), year());
+ drawCenterElement(minute());
+ }
+ }
+ //Back
+ else if (pressedButton == 2) {
+ Teensy3Clock.set(now());
+ timeMenu(firstStart);
+ break;
+ }
+ }
+ }
+}
+
+/* Hour menu */
+void hourMenu(bool firstStart) {
+ drawTitle((char*) "Hour", firstStart);
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 70, 70, (char*) "-");
+ buttons_addButton(230, 60, 70, 70, (char*) "+");
+ buttons_addButton(20, 150, 280, 70, (char*) "Back");
+ buttons_drawButtons();
+ drawCenterElement(hour());
+ //Touch handler
+ while (true) {
+ //touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons(true);
+ //Minus
+ if (pressedButton == 0) {
+ if (hour() >= 0) {
+ if (hour() > 0)
+ setTime(hour() - 1, minute(), second(), day(), month(),
+ year());
+ else if (hour() == 0)
+ setTime(23, minute(), second(), day(), month(), year());
+ drawCenterElement(hour());
+ }
+ }
+ //Plus
+ else if (pressedButton == 1) {
+ if (hour() <= 23) {
+ if (hour() < 23)
+ setTime(hour() + 1, minute(), second(), day(), month(),
+ year());
+ else if (hour() == 23)
+ setTime(0, minute(), second(), day(), month(), year());
+ drawCenterElement(hour());
+ }
+ }
+ //Back
+ else if (pressedButton == 2) {
+ Teensy3Clock.set(now());
+ timeMenu(firstStart);
+ break;
+ }
+ }
+ }
+}
+
+/* Day Menu */
+void dayMenu(bool firstStart) {
+ drawTitle((char*) "Day", firstStart);
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 70, 70, (char*) "-");
+ buttons_addButton(230, 60, 70, 70, (char*) "+");
+ buttons_addButton(20, 150, 280, 70, (char*) "Back");
+ buttons_drawButtons();
+ drawCenterElement(day());
+ //Touch handler
+ while (true) {
+ //touch press
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons(true);
+ //Minus
+ if (pressedButton == 0) {
+ if (day() >= 1) {
+ if (day() > 1)
+ setTime(hour(), minute(), second(), day() - 1, month(),
+ year());
+ else if (day() == 1)
+ setTime(hour(), minute(), second(), 31, month(),
+ year());
+ drawCenterElement(day());
+ }
+ }
+ //Plus
+ else if (pressedButton == 1) {
+ if (day() <= 31) {
+ if (day() < 31)
+ setTime(hour(), minute(), second(), day() + 1, month(),
+ year());
+ else if (day() == 31)
+ setTime(hour(), minute(), second(), 1, month(), year());
+ drawCenterElement(day());
+ }
+ }
+ //Back
+ else if (pressedButton == 2) {
+ Teensy3Clock.set(now());
+ dateMenu(firstStart);
+ break;
+ }
+ }
+ }
+}
+
+/* Month Menu */
+void monthMenu(bool firstStart) {
+ drawTitle((char*) "Month", firstStart);
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 70, 70, (char*) "-");
+ buttons_addButton(230, 60, 70, 70, (char*) "+");
+ buttons_addButton(20, 150, 280, 70, (char*) "Back");
+ buttons_drawButtons();
+ drawCenterElement(month());
+ //Touch handler
+ while (true) {
+ //touch press
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons(true);
+ //Minus
+ if (pressedButton == 0) {
+ if (month() >= 1) {
+ if (month() > 1)
+ setTime(hour(), minute(), second(), day(), month() - 1,
+ year());
+ else if (month() == 1)
+ setTime(hour(), minute(), second(), day(), 12, year());
+ drawCenterElement(month());
+ }
+ }
+ //Plus
+ else if (pressedButton == 1) {
+ if (month() <= 12) {
+ if (month() < 12)
+ setTime(hour(), minute(), second(), day(), month() + 1,
+ year());
+ else if (month() == 12)
+ setTime(hour(), minute(), second(), day(), 1, year());
+ drawCenterElement(month());
+ }
+ }
+ //Back
+ else if (pressedButton == 2) {
+ Teensy3Clock.set(now());
+ dateMenu(firstStart);
+ break;
+ }
+ }
+ }
+}
+
+/* Year Menu */
+void yearMenu(bool firstStart) {
+ drawTitle((char*) "Year", firstStart);
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 70, 70, (char*) "-");
+ buttons_addButton(230, 60, 70, 70, (char*) "+");
+ buttons_addButton(20, 150, 280, 70, (char*) "Back");
+ buttons_drawButtons();
+ drawCenterElement(year());
+ //Touch handler
+ while (true) {
+ //touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons(true);
+ //Minus
+ if (pressedButton == 0) {
+ if (year() > 2017) {
+ setTime(hour(), minute(), second(), day(), month(),
+ year() - 1);
+ drawCenterElement(year());
+ }
+ }
+ //Plus
+ else if (pressedButton == 1) {
+ if (year() < 2099) {
+ setTime(hour(), minute(), second(), day(), month(),
+ year() + 1);
+ drawCenterElement(year());
+ }
+ }
+ //Back
+ else if (pressedButton == 2) {
+ Teensy3Clock.set(now());
+ dateMenu(firstStart);
+ break;
+ }
+ }
+ }
+}
+
+/* Calibrate the battery gauge */
+void batteryGauge()
+{
+ //Title & Background
+ drawTitle((char*) "Battery Gauge", true);
+ display_setColor(VGA_BLACK);
+ display_setFont(smallFont);
+ display_setBackColor(200, 200, 200);
+ display_print((char*)"Do you want to calibrate the", CENTER, 75);
+ display_print((char*)"battery gauge? Fully charge the", CENTER, 95);
+ display_print((char*)"battery first (LED green/blue).", CENTER, 115);
+ //Draw the buttons
+ buttons_deleteAllButtons();
+ buttons_setTextFont(bigFont);
+ buttons_addButton(165, 160, 140, 55, (char*) "Yes");
+ buttons_addButton(15, 160, 140, 55, (char*) "No");
+ buttons_drawButtons();
+ buttons_setTextFont(smallFont);;
+ //Touch handler
+ while (true) {
+ //If touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons(true);
+ //YES
+ if (pressedButton == 0) {
+ //Calc the compensation value
+ checkBattery(false, true);
+
+ //Show Message
+ showFullMessage((char*) "Battery gauge calibrated", true);
+ delay(1000);
+
+ //Return
+ otherMenu();
+ return;
+ }
+ //NO
+ else if (pressedButton == 1) {
+ otherMenu();
+ return;
+ }
+ }
+ }
+}
+
+/* Date Menu */
+void dateMenu(bool firstStart) {
+ drawTitle((char*) "Date", firstStart);
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 130, 70, (char*) "Day");
+ buttons_addButton(170, 60, 130, 70, (char*) "Month");
+ buttons_addButton(20, 150, 130, 70, (char*) "Year");
+ if (firstStart)
+ buttons_addButton(170, 150, 130, 70, (char*) "Save");
+ else
+ buttons_addButton(170, 150, 130, 70, (char*) "Back");
+ buttons_drawButtons();
+}
+
+/* Date Menu Handler */
+void dateMenuHandler(bool firstStart) {
+ while (true) {
+ //touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons();
+ //Day
+ if (pressedButton == 0) {
+ dayMenu(firstStart);
+ }
+ //Month
+ else if (pressedButton == 1) {
+ monthMenu(firstStart);
+ }
+ //Year
+ else if (pressedButton == 2) {
+ yearMenu(firstStart);
+ }
+ //Back
+ else if (pressedButton == 3) {
+ if (!firstStart)
+ otherMenu();
+ break;
+ }
+ }
+ }
+}
+
+/* Time Menu */
+void timeMenu(bool firstStart) {
+ drawTitle((char*) "Time", firstStart);
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 130, 70, (char*) "Hour");
+ buttons_addButton(170, 60, 130, 70, (char*) "Minute");
+ buttons_addButton(20, 150, 130, 70, (char*) "Second");
+ if (firstStart)
+ buttons_addButton(170, 150, 130, 70, (char*) "Save");
+ else
+ buttons_addButton(170, 150, 130, 70, (char*) "Back");
+ buttons_drawButtons();
+}
+
+/* Time Menu Handler */
+void timeMenuHandler(bool firstStart) {
+ while (true) {
+ //touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons();
+ //Hours
+ if (pressedButton == 0) {
+ hourMenu(firstStart);
+ }
+ //Minutes
+ else if (pressedButton == 1) {
+ minuteMenu(firstStart);
+ }
+ //Seconds
+ else if (pressedButton == 2) {
+ secondMenu(firstStart);
+ }
+ //Back
+ else if (pressedButton == 3) {
+ if (!firstStart)
+ otherMenu();
+ break;
+ }
+ }
+ }
+}
+
+/* Time & Date Menu */
+void otherMenu() {
+ drawTitle((char*) "Other Settings");
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 130, 70, (char*) "Time");
+ buttons_addButton(170, 60, 130, 70, (char*) "Date");
+ buttons_addButton(20, 150, 130, 70, (char*) "Battery Gauge");
+ buttons_addButton(170, 150, 130, 70, (char*) "Back");
+ buttons_drawButtons();
+}
+
+/* Time & Date Menu Handler */
+void otherMenuHandler() {
+ while (true) {
+ //touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons();
+ //Time
+ if (pressedButton == 0) {
+ timeMenu();
+ timeMenuHandler();
+ }
+ //Date
+ else if (pressedButton == 1) {
+ dateMenu();
+ dateMenuHandler();
+ }
+ //Battery Gauge
+ else if (pressedButton == 2) {
+ batteryGauge();
+ }
+ //Back
+ else if (pressedButton == 3) {
+ settingsMenu();
+ break;
+ }
+ }
+ }
+}
+
+
+
+/* Visual image selection menu */
+void visualImageMenu(bool firstStart) {
+ drawTitle((char*) "Visual image", firstStart);
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 130, 70, (char*) "Disabled");
+ buttons_addButton(170, 60, 130, 70, (char*) "Save JPEG");
+ if (firstStart) {
+ buttons_addButton(20, 150, 280, 70, (char*) "Set");
+ visualEnabled = true;
+ }
+ else
+ buttons_addButton(20, 150, 280, 70, (char*) "Back");
+ buttons_drawButtons();
+ if (!visualEnabled)
+ buttons_setActive(0);
+ else
+ buttons_setActive(1);
+ //Touch handler
+ while (true) {
+ //touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons();
+ //Disabled
+ if (pressedButton == 0) {
+ if (visualEnabled) {
+ visualEnabled = false;
+ buttons_setActive(0);
+ buttons_setInactive(1);
+ }
+ }
+ //Save JPEG, only when visual camera works
+ else if ((pressedButton == 1) && (checkDiagnostic(diag_camera))) {
+ if (!visualEnabled) {
+ visualEnabled = true;
+ buttons_setActive(1);
+ buttons_setInactive(0);
+ }
+ }
+ //Save
+ else if (pressedButton == 2) {
+ //Write new settings to EEPROM
+ EEPROM.write(eeprom_visualEnabled, visualEnabled);
+ if (firstStart)
+ return;
+ else {
+ storageMenu();
+ }
+ break;
+ }
+ }
+ }
+}
+
+/* Convert image selection menu */
+void convertImageMenu(bool firstStart) {
+ drawTitle((char*) "Convert image", firstStart);
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 130, 70, (char*) "DAT only");
+ buttons_addButton(170, 60, 130, 70, (char*) "BMP & DAT");
+ if (firstStart) {
+ buttons_addButton(20, 150, 280, 70, (char*) "Set");
+ convertEnabled = false;
+ }
+ else
+ buttons_addButton(20, 150, 280, 70, (char*) "Back");
+ buttons_drawButtons();
+ if (!convertEnabled)
+ buttons_setActive(0);
+ else
+ buttons_setActive(1);
+
+ //Touch handler
+ while (true) {
+ //touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons();
+ //DAT only
+ if (pressedButton == 0) {
+ if (convertEnabled) {
+ convertEnabled = false;
+ buttons_setActive(0);
+ buttons_setInactive(1);
+ }
+ }
+ //BMP & DAT
+ else if (pressedButton == 1) {
+ if (!convertEnabled) {
+ convertEnabled = true;
+ buttons_setActive(1);
+ buttons_setInactive(0);
+ }
+ }
+
+ //Save
+ else if (pressedButton == 2) {
+ //Write new settings to EEPROM
+ EEPROM.write(eeprom_convertEnabled, convertEnabled);
+ if (firstStart)
+ return;
+ else {
+ storageMenu();
+ }
+ break;
+ }
+ }
+ }
+}
+
+/* Asks the user if he really wants to format */
+void formatStorage() {
+ //ThermocamV4 or DIY-Thermocam V2, check SD card
+ if ((mlx90614Version == mlx90614Version_old) ||
+ (teensyVersion == teensyVersion_new)) {
+ showFullMessage((char*) "Checking SD card..", true);
+ if (!checkSDCard()) {
+ showFullMessage((char*) "Insert SD card", true);
+ delay(1000);
+ storageMenu();
+ return;
+ }
+ }
+ //Title & Background
+ drawTitle((char*) "Storage");
+ display_setColor(VGA_BLACK);
+ display_setFont(smallFont);
+ display_setBackColor(200, 200, 200);
+ display_print((char*)"Do you really want to format?", CENTER, 66);
+ display_print((char*)"This will delete all images", CENTER, 105);
+ display_print((char*)"and videos on the internal storage.", CENTER, 125);
+ //Draw the buttons
+ buttons_deleteAllButtons();
+ buttons_setTextFont(bigFont);
+ buttons_addButton(165, 160, 140, 55, (char*) "Yes");
+ buttons_addButton(15, 160, 140, 55, (char*) "No");
+ buttons_drawButtons();
+ buttons_setTextFont(smallFont);
+ //Touch handler
+ while (true) {
+ //If touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons(true);
+ //YES
+ if (pressedButton == 0) {
+ showFullMessage((char*) "Format storage..", true);
+ formatCard();
+ refreshFreeSpace();
+ showFullMessage((char*) "Formatting finished", true);
+ delay(1000);
+ break;
+ }
+ //NO
+ if (pressedButton == 1) {
+ break;
+ }
+ }
+ }
+ //Go back to the storage menu
+ storageMenu();
+}
+
+/* Storage menu handler*/
+void storageMenuHandler() {
+ while (true) {
+ //touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons();
+ //Convert image
+ if (pressedButton == 0) {
+ convertImageMenu();
+ }
+ //Visual image
+ else if (pressedButton == 1) {
+ visualImageMenu();
+ }
+ //Format
+ else if (pressedButton == 2) {
+ formatStorage();
+ }
+ //Back
+ else if (pressedButton == 3) {
+ settingsMenu();
+ break;
+ }
+ }
+ }
+}
+
+/* Storage menu */
+void storageMenu() {
+ drawTitle((char*) "Storage Settings");
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 130, 70, (char*) "Convert image");
+ buttons_addButton(170, 60, 130, 70, (char*) "Visual image");
+ buttons_addButton(20, 150, 130, 70, (char*) "Format");
+ buttons_addButton(170, 150, 130, 70, (char*) "Back");
+ buttons_drawButtons();
+}
+
+/* Temperature format menu */
+void tempFormatMenu(bool firstStart) {
+ drawTitle((char*) "Temp. Format", firstStart);
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 130, 70, (char*) "Celcius");
+ buttons_addButton(170, 60, 130, 70, (char*) "Fahrenheit");
+ buttons_addButton(20, 150, 280, 70, (char*) "Save");
+ if (firstStart) {
+ buttons_relabelButton(2, (char*) "Set", false);
+ tempFormat = tempFormat_celcius;
+ }
+ buttons_drawButtons();
+ if (tempFormat == tempFormat_celcius)
+ buttons_setActive(tempFormat_celcius);
+ else
+ buttons_setActive(tempFormat_fahrenheit);
+ //Touch handler
+ while (true) {
+ //touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons();
+ //Celcius
+ if (pressedButton == 0) {
+ if (tempFormat == tempFormat_fahrenheit) {
+ tempFormat = tempFormat_celcius;
+ buttons_setActive(0);
+ buttons_setInactive(1);
+ }
+ }
+ //Fahrenheit
+ else if (pressedButton == 1) {
+ if (tempFormat == tempFormat_celcius) {
+ tempFormat = tempFormat_fahrenheit;
+ buttons_setActive(1);
+ buttons_setInactive(0);
+ }
+ }
+ //Save
+ else if (pressedButton == 2) {
+ //Write new settings to EEPROM
+ EEPROM.write(eeprom_tempFormat, tempFormat);
+ if (firstStart)
+ return;
+ else {
+ displayMenu();
+ }
+ break;
+ }
+ }
+ }
+}
+
+/* Rotate display menu */
+void rotateDisplayMenu(bool firstStart) {
+ drawTitle((char*) "Disp. rotation", firstStart);
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 130, 70, (char*) "Rotation");
+ buttons_addButton(170, 60, 130, 70, (char*) "Hor. Flip");
+ buttons_addButton(20, 150, 130, 70, (char*) "Disabled");
+ buttons_addButton(170, 150, 130, 70, (char*) "Save");
+ if (firstStart)
+ buttons_relabelButton(3, (char*) "Set", false);
+ buttons_drawButtons();
+ if (rotationVert)
+ buttons_setActive(0);
+ else if (rotationHorizont)
+ buttons_setActive(1);
+ else
+ buttons_setActive(2);
+ //Touch handler
+ while (true) {
+ //touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons();
+ //Rotate 180°
+ if (pressedButton == 0) {
+ if (!rotationVert) {
+ rotationVert = true;
+ rotationHorizont = false;
+ buttons_setActive(0);
+ buttons_setInactive(1);
+ buttons_setInactive(2);
+ }
+ }
+ //Mirror horizontally
+ else if (pressedButton == 1) {
+ if (!rotationHorizont) {
+ rotationHorizont = true;
+ rotationVert = false;
+ buttons_setActive(1);
+ buttons_setInactive(0);
+ buttons_setInactive(2);
+ }
+ }
+ //Disable
+ else if (pressedButton == 2) {
+ rotationVert = false;
+ rotationHorizont = false;
+ buttons_setActive(2);
+ buttons_setInactive(0);
+ buttons_setInactive(1);
+ }
+ //Save
+ else if (pressedButton == 3) {
+ //Write new settings to EEPROM
+ EEPROM.write(eeprom_rotationVert, rotationVert);
+ EEPROM.write(eeprom_rotationHorizont, rotationHorizont);
+ if (firstStart)
+ return;
+ //Set the rotation
+ setDisplayRotation();
+ //Show the display menu
+ displayMenu();
+ break;
+ }
+ }
+ }
+}
+
+/* Screen timeout menu */
+void screenTimeoutMenu() {
+ drawTitle((char*) "Screen timeout");
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 130, 70, (char*) "Disabled");
+ buttons_addButton(170, 60, 130, 70, (char*) "5 Min.");
+ buttons_addButton(20, 150, 130, 70, (char*) "20 Min.");
+ buttons_addButton(170, 150, 130, 70, (char*) "Back");
+ buttons_drawButtons();
+ //Set current one active
+ buttons_setActive(screenOffTime);
+ //Touch handler
+ while (true) {
+ //Touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons();
+ //Set to new color
+ if ((pressedButton == 0) || (pressedButton == 1) || (pressedButton == 2)) {
+ buttons_setInactive(screenOffTime);
+ screenOffTime = pressedButton;
+ buttons_setActive(screenOffTime);
+ }
+ //Save
+ else if (pressedButton == 3) {
+ //Write new settings to EEPROM
+ EEPROM.write(eeprom_screenOffTime, screenOffTime);
+ //Init timer
+ initScreenOffTimer();
+ //Return to display menu
+ displayMenu();
+ break;
+ }
+ }
+ }
+}
+
+
+/* Display menu handler*/
+void displayMenuHandler() {
+ while (true) {
+ //touch pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons();
+ //Temp. format
+ if (pressedButton == 0) {
+ tempFormatMenu();
+ }
+ //Rotate display
+ else if (pressedButton == 1) {
+ rotateDisplayMenu();
+ }
+ //Screen timeout
+ else if (pressedButton == 2) {
+ screenTimeoutMenu();
+ }
+ //Back
+ else if (pressedButton == 3) {
+ settingsMenu();
+ break;
+ }
+ }
+ }
+}
+
+/* Display menu */
+void displayMenu() {
+ drawTitle((char*) "Display Settings");
+ buttons_deleteAllButtons();
+ buttons_addButton(20, 60, 130, 70, (char*) "Temp. format");
+ buttons_addButton(170, 60, 130, 70, (char*) "Disp. rotation");
+ buttons_addButton(20, 150, 130, 70, (char*) "Screen timeout");
+ buttons_addButton(170, 150, 130, 70, (char*) "Back");
+ buttons_drawButtons();
+
+}
+
+/* Touch handler for the settings menu */
+void settingsMenuHandler() {
+ while (true) {
+ //touch press
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons();
+ //Display
+ if (pressedButton == 0) {
+ displayMenu();
+ displayMenuHandler();
+ }
+ //Storage
+ else if (pressedButton == 1) {
+ storageMenu();
+ storageMenuHandler();
+ }
+ //Other
+ else if (pressedButton == 2) {
+ otherMenu();
+ otherMenuHandler();
+ }
+ //Back
+ else if (pressedButton == 3)
+ break;
+ }
+ }
+}
+
+/* Settings menu main screen */
+void settingsMenu() {
+ drawTitle((char*) "Settings");
+ buttons_deleteAllButtons();
+ buttons_setTextFont(smallFont);
+ buttons_addButton(20, 60, 130, 70, (char*) "Display");
+ buttons_addButton(170, 60, 130, 70, (char*) "Storage");
+ buttons_addButton(20, 150, 130, 70, (char*) "Other");
+ buttons_addButton(170, 150, 130, 70, (char*) "Back");
+ buttons_drawButtons();
+}
diff --git a/Firmware_V2/src/gui/settingsmenu.h b/Firmware_V2/src/gui/settingsmenu.h
new file mode 100644
index 0000000..afe68b8
--- /dev/null
+++ b/Firmware_V2/src/gui/settingsmenu.h
@@ -0,0 +1,56 @@
+/*
+*
+* SETTINGS MENU - Adjust different on-device settings
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef SETTINGSMENU_H
+#define SETTINGSMENU_H
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+void adjustCombinedGUI();
+void adjustCombinedLoading();
+bool adjustCombinedMenu();
+void adjustCombinedNewMenuHandler(bool firstStart = false);
+void adjustCombinedNewMenu(bool firstStart = false);
+bool adjustCombinedPresetSaveMenu();
+void adjustCombinedPresetSaveString(int pos);
+void adjustCombinedRefresh();
+void adjustCombinedString(int pos);
+void batteryGauge();
+void convertImageMenu(bool firstStart = false);
+void dateMenuHandler(bool firstStart = false);
+void dateMenu(bool firstStart = false);
+void dayMenu(bool firstStart);
+void displayMenuHandler();
+void displayMenu();
+void formatStorage();
+void hourMenu(bool firstStart);
+void minuteMenu(bool firstStart);
+void monthMenu(bool firstStart);
+void otherMenuHandler();
+void otherMenu();
+void rotateDisplayMenu(bool firstStart = false);
+void screenTimeoutMenu();
+void secondMenu(bool firstStart);
+void settingsMenuHandler();
+void settingsMenu();
+void storageMenuHandler();
+void storageMenu();
+void tempFormatMenu(bool firstStart = false);
+void timeMenuHandler(bool firstStart = false);
+void timeMenu(bool firstStart = false);
+void visualImageMenu(bool firstStart = false);
+void yearMenu(bool firstStart);
+
+#endif /* SETTINGSMENU_H */
diff --git a/Firmware_V2/src/gui/videomenu.cpp b/Firmware_V2/src/gui/videomenu.cpp
new file mode 100644
index 0000000..2481f2d
--- /dev/null
+++ b/Firmware_V2/src/gui/videomenu.cpp
@@ -0,0 +1,452 @@
+/*
+*
+* VIDEO MENU - Record single frames or time interval videos
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*######################### STATIC DATA DECLARATIONS ##########################*/
+
+//Video save interval in seconds
+static int16_t videoInterval;
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* Switch the video interval string*/
+void videoIntervalString(int pos) {
+ char* text = (char*) "";
+ switch (pos) {
+ //1 second
+ case 0:
+ text = (char*) "1 second";
+ break;
+ //5 seconds
+ case 1:
+ text = (char*) "5 seconds";
+ break;
+ //10 seconds
+ case 2:
+ text = (char*) "10 seconds";
+ break;
+ //20 seconds
+ case 3:
+ text = (char*) "20 seconds";
+ break;
+ //30 seconds
+ case 4:
+ text = (char*) "30 seconds";
+ break;
+ //1 minute
+ case 5:
+ text = (char*) "1 minute";
+ break;
+ //5 minutes
+ case 6:
+ text = (char*) "5 minutes";
+ break;
+ //10 minutes
+ case 7:
+ text = (char*) "10 minutes";
+ break;
+ }
+ //Draws the current selection
+ mainMenuSelection(text);
+}
+
+/* Touch Handler for the video interval chooser */
+bool videoIntervalHandler(byte* pos) {
+ //Main loop
+ while (true) {
+ //Touch screen pressed
+ if (touch_touched() == true) {
+ int pressedButton = buttons_checkButtons(true);
+ //SELECT
+ if (pressedButton == 3) {
+ switch (*pos) {
+ //1 second
+ case 0:
+ videoInterval = 1;
+ break;
+ //5 seconds
+ case 1:
+ videoInterval = 5;
+ break;
+ //10 seconds
+ case 2:
+ videoInterval = 10;
+ break;
+ //20 seconds
+ case 3:
+ videoInterval = 20;
+ break;
+ //30 seconds
+ case 4:
+ videoInterval = 30;
+ break;
+ //1 minute
+ case 5:
+ videoInterval = 60;
+ break;
+ //5 minutes
+ case 6:
+ videoInterval = 300;
+ break;
+ //10 minutes
+ case 7:
+ videoInterval = 600;
+ break;
+ }
+ return true;
+ }
+ //BACK
+ else if (pressedButton == 2) {
+ return false;
+ }
+ //BACKWARD
+ else if (pressedButton == 0) {
+ if (*pos > 0)
+ *pos = *pos - 1;
+ else if (*pos == 0)
+ *pos = 7;
+ }
+ //FORWARD
+ else if (pressedButton == 1) {
+ if (*pos < 7)
+ *pos = *pos + 1;
+ else if (*pos == 7)
+ *pos = 0;
+ }
+ //Change the menu name
+ videoIntervalString(*pos);
+ }
+ }
+}
+
+/* Start video menu to choose interval */
+bool videoIntervalChooser() {
+ bool rtn;
+ static byte videoIntervalPos = 0;
+ //Background
+ mainMenuBackground();
+ //Title
+ mainMenuTitle((char*) "Choose interval");
+ //Draw the selection menu
+ drawSelectionMenu();
+ //Current choice name
+ videoIntervalString(videoIntervalPos);
+ //Touch handler - return true if exit to Main menu, otherwise false
+ rtn = videoIntervalHandler(&videoIntervalPos);
+ //Restore old fonts
+ display_setFont(smallFont);
+ buttons_setTextFont(smallFont);
+ //Delete the old buttons
+ buttons_deleteAllButtons();
+ return rtn;
+}
+
+/* Captures video frames in an interval */
+void videoCaptureInterval(int16_t* remainingTime, int* framesCaptured, char* dirname) {
+ char buffer[30];
+
+ //Measure time
+ long measure = millis();
+
+ //If there is no more time or the first frame
+ if ((*remainingTime <= 0) || (*framesCaptured == 0)) {
+
+ //Send capture command to camera if activated and there is enough time
+ if ((visualEnabled && ((videoInterval >= 10) ||
+ teensyVersion == teensyVersion_new) && checkDiagnostic(diag_camera)) &&
+ ((*remainingTime == 0) || (*framesCaptured == 0)))
+ camera_capture();
+
+ //Save video raw frame
+ saveRawData(false, dirname, *framesCaptured);
+ }
+
+ //Convert lepton data to RGB565 colors
+ convertColors();
+
+ //Display infos
+ displayInfos();
+
+ //Write to image buffer
+ display_writeToImage = true;
+
+ //Display title
+ if ((teensyVersion == teensyVersion_new) && (hqRes))
+ display_print((char*) "Interval capture", 105, 20);
+ else
+ display_print((char*) "Interval capture", 90, 20);
+
+ //Show saving message
+ if ((*remainingTime <= 0) || (*framesCaptured == 0))
+ sprintf(buffer, "Saving now..");
+ //Show waiting time
+ else
+ sprintf(buffer, "Saving in %ds", *remainingTime);
+
+ //Display message on buffer
+ if ((teensyVersion == teensyVersion_new) && (hqRes))
+ display_print(buffer, 120, 200);
+ else
+ display_print(buffer, 105, 200);
+
+ //Disable image buffer
+ display_writeToImage = false;
+
+ //Draw thermal image on screen
+ displayBuffer();
+
+ //If there is no more time or the first frame
+ if ((*remainingTime <= 0) || (*framesCaptured == 0)) {
+ //Save visual image if activated and camera connected
+ if (visualEnabled && ((videoInterval >= 10) ||
+ teensyVersion == teensyVersion_new) && checkDiagnostic(diag_camera)) {
+
+ //Create filename to save data
+ frameFilename(saveFilename, *framesCaptured);
+
+ //Save visual image
+ camera_get(camera_save, dirname);
+
+ //Reset counter
+ int16_t elapsed = (millis() - measure) / 1000;
+ *remainingTime = videoInterval - elapsed;
+ }
+ else
+ *remainingTime = videoInterval;
+
+ //Raise capture counter
+ *framesCaptured = *framesCaptured + 1;
+ }
+ else
+ {
+ //Wait rest of the time
+ measure = millis() - measure;
+ if (measure < 1000)
+ delay(1000 - measure);
+
+ //Decrease remaining time by one
+ *remainingTime -= 1;
+ }
+}
+
+/* Normal video capture */
+void videoCaptureNormal(char* dirname, int* framesCaptured) {
+ char buffer[30];
+
+ //Save video raw frame
+ saveRawData(false, dirname, *framesCaptured);
+
+ //Convert the colors
+ convertColors();
+
+ //Display infos
+ displayInfos();
+
+ //Write to image buffer
+ display_writeToImage = true;
+
+ //Display title
+ if ((teensyVersion == teensyVersion_new) && (hqRes))
+ display_print((char*) "Video capture", 115, 20);
+ else
+ display_print((char*) "Video capture", 100, 20);
+
+ //Raise capture counter
+ *framesCaptured = *framesCaptured + 1;
+
+ //Display current frames captured
+ sprintf(buffer, "Frames captured: %5d", *framesCaptured);
+ if ((teensyVersion == teensyVersion_new) && (hqRes))
+ display_print(buffer, 70, 200);
+ else
+ display_print(buffer, 55, 200);
+
+ //Disable image buffer
+ display_writeToImage = false;
+
+ //Refresh capture
+ displayBuffer();
+
+}
+
+/* This screen is shown during the video capture */
+void videoCapture() {
+ //Help variables
+ char dirname[20];
+ int16_t delayTime = videoInterval;
+ int framesCaptured = 0;
+
+ //Show message
+ showFullMessage((char*)"Touch screen to turn it off");
+ display_print((char*) "Press the button to abort", CENTER, 170);
+ delay(1500);
+
+ //Create folder
+ createVideoFolder(dirname);
+
+ //Switch to recording mode
+ videoSave = videoSave_recording;
+
+ //Main loop
+ while (videoSave == videoSave_recording) {
+
+ //Touch - turn display on or off
+ if (!digitalRead(pin_touch_irq)) {
+ digitalWrite(pin_lcd_backlight, !(checkScreenLight()));
+ while (!digitalRead(pin_touch_irq));
+ }
+
+ //Create the thermal image
+ createThermalImg();
+
+ //Video capture
+ if (videoInterval == 0) {
+ videoCaptureNormal(dirname, &framesCaptured);
+ }
+ //Interval capture
+ else {
+ videoCaptureInterval(&delayTime, &framesCaptured, dirname);
+ }
+ }
+
+ //Turn the display on if it was off before
+ if (!checkScreenLight())
+ enableScreenLight();
+
+ //Post processing for interval videos if enabled and wished
+ if ((framesCaptured > 0) && (convertPrompt()))
+ processVideoFrames(framesCaptured, dirname);
+
+ //Show finished message
+ else {
+ showFullMessage((char*) "Video capture finished");
+ delay(1000);
+ }
+
+ //Refresh free space
+ refreshFreeSpace();
+
+ //Disable mode
+ videoSave = videoSave_disabled;
+}
+
+/* Video mode, choose intervall or normal */
+void videoMode() {
+
+ //Show message that video is only possible in thermal mode
+ if (displayMode != displayMode_thermal) {
+ //Show message
+ showFullMessage((char*) "Works only in thermal mode");
+ delay(1000);
+
+ //Disable mode and return
+ videoSave = videoSave_disabled;
+ return;
+ }
+
+ //ThermocamV4 or DIY-Thermocam V2 - check SD card
+ if (!checkSDCard()) {
+ //Show message
+ showFullMessage((char*) "Waiting for card..");
+
+ //Wait for SD card
+ while (!checkSDCard());
+
+ //Redraw the last screen content
+ displayBuffer();
+ }
+
+ //Check if there is at least 1MB of space left
+ if (getSDSpace() < 1000) {
+ //Show message
+ showFullMessage((char*) "The SD card is full");
+ delay(1000);
+
+ //Disable mode and return
+ videoSave = videoSave_disabled;
+ return;
+ }
+
+ //Border
+ drawMainMenuBorder();
+
+redraw:
+ //Title & Background
+ mainMenuBackground();
+ mainMenuTitle((char*)"Video Mode");
+ //Draw the buttons
+ buttons_deleteAllButtons();
+ buttons_setTextFont(bigFont);
+ buttons_addButton(15, 47, 140, 120, (char*) "Normal");
+ buttons_addButton(165, 47, 140, 120, (char*) "Interval");
+ buttons_addButton(15, 188, 140, 40, (char*) "Back");
+ buttons_drawButtons();
+
+ //Touch handler
+ while (true) {
+
+ //If touch pressed
+ if (touch_touched() == true) {
+ //Check which button has been pressed
+ int pressedButton = buttons_checkButtons(true);
+
+ //Normal
+ if (pressedButton == 0) {
+ //Set video interval to zero, means normal
+ videoInterval = 0;
+ //Start capturing a video
+ videoCapture();
+ break;
+ }
+
+ //Interval
+ if (pressedButton == 1) {
+ //Choose the time interval
+ if (!videoIntervalChooser())
+ //Redraw video mode if user pressed back
+ goto redraw;
+ //Start capturing a video
+ videoCapture();
+ break;
+ }
+
+ //Back
+ if (pressedButton == 2) {
+ //Disable mode and return
+ videoSave = videoSave_disabled;
+ return;
+ }
+ }
+ }
+}
diff --git a/Firmware_V2/src/gui/videomenu.h b/Firmware_V2/src/gui/videomenu.h
new file mode 100644
index 0000000..25ce4c8
--- /dev/null
+++ b/Firmware_V2/src/gui/videomenu.h
@@ -0,0 +1,29 @@
+/*
+*
+* VIDEO MENU - Record single frames or time interval videos
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef VIDEOMENU_H
+#define VIDEOMENU_H
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+void videoCaptureInterval(int16_t* remainingTime, int* framesCaptured, char* dirname);
+void videoCaptureNormal(char* dirname, int* framesCaptured);
+void videoCapture();
+bool videoIntervalChooser();
+bool videoIntervalHandler(byte* pos);
+void videoIntervalString(int pos);
+void videoMode();
+
+#endif /* VIDEOMENU_H */
diff --git a/Firmware_V2/src/hardware/battery.cpp b/Firmware_V2/src/hardware/battery.cpp
new file mode 100644
index 0000000..bebf658
--- /dev/null
+++ b/Firmware_V2/src/hardware/battery.cpp
@@ -0,0 +1,108 @@
+/*
+ *
+ * BATTERY - Measure the lithium battery status
+ *
+ * DIY-Thermocam Firmware
+ *
+ * GNU General Public License v3.0
+ *
+ * Copyright by Max Ritter
+ *
+ * http://www.diy-thermocam.net
+ * https://github.com/maxritter/DIY-Thermocam
+ *
+ */
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* A method to calculate the lipo percentage out of its voltage */
+int getLipoPerc(float vol) {
+ if (vol >= 4.10)
+ return 100;
+ if (vol >= 4.00)
+ return 90;
+ if (vol >= 3.93)
+ return 80;
+ if (vol >= 3.88)
+ return 70;
+ if (vol >= 3.84)
+ return 60;
+ if (vol >= 3.80)
+ return 50;
+ if (vol >= 3.76)
+ return 40;
+ if (vol >= 3.73)
+ return 30;
+ if (vol >= 3.70)
+ return 20;
+ if (vol >= 3.66)
+ return 10;
+ if (vol >= 3.00)
+ return 0;
+ return -1;
+}
+
+/* Measure the battery voltage and convert it to percent */
+void checkBattery(bool start, bool calibrate) {
+ //Read battery voltage
+ float vBat = (batMeasure->analogRead(pin_bat_measure) * 1.5 * 3.3) / batMeasure->getMaxValue(ADC_0);
+
+ //Check if the device is charging
+ int vUSB = analogRead(pin_usb_measure);
+ //Battery is not working if no voltage measured and not connected to USB
+ if ((vBat == -1) && (vUSB <= 50))
+ setDiagnostic(diag_bat);
+
+ //If not charging, add some value to correct the voltage
+ if (vUSB <= 50)
+ {
+ //DIY-Thermocam V1
+ if ((teensyVersion == teensyVersion_old) && (mlx90614Version == mlx90614Version_new))
+ vBat += 0.05;
+ //Thermocam V4
+ else if ((teensyVersion == teensyVersion_old) && (mlx90614Version == mlx90614Version_old))
+ vBat += 0.25;
+ //DIY-Thermocam V2
+ else
+ vBat += 0.15;
+ }
+
+ //Recalibrate the battery gauge
+ if (calibrate)
+ {
+ //Calculate value to correct
+ float compensation = (4.15 - vBat) * 100;
+ batComp = (int8_t) round(compensation);
+
+ //Save to EEPROM
+ EEPROM.write(eeprom_batComp, batComp);
+ }
+
+ //At first launch, read value from EEPROM
+ if(start)
+ batComp = EEPROM.read(eeprom_batComp);
+
+ //Correct voltage
+ if (batComp != 0)
+ vBat += (float) batComp / 100.0;
+
+ //Calculate the percentage out of the voltage
+ batPercentage = getLipoPerc(vBat);
+
+ //Show warning on startup if the battery is low
+ if ((batPercentage <= 20) && (batPercentage != -1) && (start)) {
+ showFullMessage((char*) "Battery almost empty, charge");
+ delay(1000);
+ }
+}
diff --git a/Firmware_V2/src/hardware/battery.h b/Firmware_V2/src/hardware/battery.h
new file mode 100644
index 0000000..623e601
--- /dev/null
+++ b/Firmware_V2/src/hardware/battery.h
@@ -0,0 +1,24 @@
+/*
+*
+* BATTERY - Measure the lithium battery status
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef BATTERY_H
+#define BATTERY_H
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+void checkBattery(bool start = false, bool calibrate = false);
+int getLipoPerc(float vol);
+
+#endif /* BATTERY_H */
diff --git a/Firmware_V2/src/hardware/camera/camera.cpp b/Firmware_V2/src/hardware/camera/camera.cpp
new file mode 100644
index 0000000..e1f062e
--- /dev/null
+++ b/Firmware_V2/src/hardware/camera/camera.cpp
@@ -0,0 +1,414 @@
+/*
+*
+* Camera - Visual camera module
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*################# DATA TYPES, CONSTANTS & MACRO DEFINITIONS #################*/
+
+//JPEG Decompressor structure
+typedef struct {
+ const byte* jpic;
+ unsigned short jsize;
+ unsigned short joffset;
+} IODEV;
+
+/*############################# PUBLIC VARIABLES ##############################*/
+
+//The current camera resolution
+byte camera_resolution;
+
+/*######################### STATIC DATA DECLARATIONS ##########################*/
+
+//JPEG Decompressor
+static void* camera_jdwork;
+static JDEC camera_jd;
+static IODEV camera_iodev;
+
+//Buffer to store the JPEG data
+static uint8_t* camera_jpegData;
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* Capture an image on the camera */
+void camera_capture(void)
+{
+ //Arducam-Mini
+ if (teensyVersion == teensyVersion_new)
+ ov2640_capture();
+ //PTC-06 or PTC-08
+ else
+ vc0706_capture();
+}
+
+/* Change the resolution of the camera */
+void camera_changeRes(byte camRes)
+{
+ //If camera not working, skip
+ if (!checkDiagnostic(diag_camera))
+ return;
+
+ //Change resolution
+ camera_resolution = camRes;
+
+ //According to camera resolution set
+ switch (camera_resolution)
+ {
+ //Low resolution (160x120)
+ case camera_resLow:
+ //Arducam
+ if (teensyVersion == teensyVersion_new)
+ ov2640_setJPEGSize(OV2640_160x120);
+ //PTC-06 or PTC-08
+ else
+ vc0706_changeCamRes(VC0706_160x120);
+ break;
+ //Middle resolution (320x240)
+ case camera_resMiddle:
+ // Arducam
+ if (teensyVersion == teensyVersion_new)
+ ov2640_setJPEGSize(OV2640_320x240);
+ //PTC-06 or PTC-08
+ else
+ vc0706_changeCamRes(VC0706_320x240);
+ break;
+ //High resolution (640x480)
+ case camera_resHigh:
+ // Arducam
+ if (teensyVersion == teensyVersion_new)
+ ov2640_setJPEGSize(OV2640_640x480);
+ //PTC-06 or PTC-08
+ else
+ vc0706_changeCamRes(VC0706_640x480);
+ break;
+ }
+
+ //For OV2640, capture one frame and discard
+ if (teensyVersion == teensyVersion_new)
+ camera_capture();
+}
+
+/* Set the resolution to saving */
+void camera_setSaveRes()
+{
+ camera_changeRes(camera_resHigh);
+}
+
+/* Set the resolution to streaming over serial */
+void camera_setStreamRes()
+{
+ camera_changeRes(camera_resMiddle);
+}
+
+/* Set the resolution to display */
+void camera_setDisplayRes()
+{
+ //Set camera resolution to low
+ if ((teensyVersion == teensyVersion_old) || (!hqRes))
+ camera_changeRes(camera_resLow);
+
+ //Set to middle for HQ on Teensy 3.6
+ else
+ camera_changeRes(camera_resMiddle);
+}
+
+/* Init the camera module */
+void camera_init(void)
+{
+ boolean init;
+
+ //Allocate space for the decompressor
+ camera_jdwork = malloc(3100);
+
+ //Init Arducam-Mini
+ if (teensyVersion == teensyVersion_new)
+ init = ov2640_init();
+ //Init PTC-06 or PTC-08
+ else
+ init = vc0706_init();
+
+ //If init failed, set diagnostic
+ if (!init) {
+ setDiagnostic(diag_camera);
+ return;
+ }
+
+ //Change resolution to save
+ camera_setSaveRes();
+}
+
+/* Normal output function for the JPEG Decompressor - Teensy 3.6 */
+unsigned int camera_decompOutNormal(JDEC * jd, void * bitmap, JRECT * rect)
+{
+ unsigned short * bmp = (unsigned short *)bitmap;
+ unsigned short x, y;
+ uint32_t count = 0;
+ uint32_t imagepos;
+
+ //Go through the image vertically
+ for (y = rect->top; y <= rect->bottom; y++) {
+
+ //Check if we draw inside the screen on y position
+ if (((y + (5 * adjCombDown) <= 239) && (y - (5 * adjCombUp) >= 0))) {
+
+ //Go through the image horizontally
+ for (x = rect->left; x <= rect->right; x++) {
+
+ //Check if we draw inside the screen on x position
+ if (((x + (5 * adjCombRight) <= 319) && (x - (5 * adjCombLeft) >= 0))) {
+
+ //Get the image position
+ imagepos = x + (y * 320);
+
+ //Do the visual alignment
+ imagepos += 5 * adjCombRight;
+ imagepos -= 5 * adjCombLeft;
+ imagepos += 5 * adjCombDown * 320;
+ imagepos -= 5 * adjCombUp * 320;
+
+ //Do not use zero
+ if (bmp[count] == 0)
+ bmp[count] = 1;
+
+ //Write to image buffer, rotated
+ if (rotationVert)
+ bigBuffer[76799 - imagepos] = bmp[count];
+ //Write to image buffer, normal
+ else
+ bigBuffer[imagepos] = bmp[count];;
+ }
+
+ //Raise counter
+ count++;
+ }
+ }
+ }
+ return 1;
+}
+
+/* Combined output function for the JPEG Decompressor - Teensy 3.1 / 3.2 only */
+unsigned int camera_decompOutCombined(JDEC * jd, void * bitmap, JRECT * rect) {
+ //Help Variables
+ byte redV, greenV, blueV, redT, greenT, blueT, red, green, blue, xPos;
+ unsigned short pixel, x, y, imagepos, count;
+ unsigned short * bmp = (unsigned short *)bitmap;
+ count = 0;
+ //Go through the visual image
+ for (y = rect->top; y <= rect->bottom; y++) {
+
+ //Check if we draw inside the screen on y position
+ if (((y + (5 * adjCombDown) <= 119) && (y - (5 * adjCombUp) >= 0))) {
+
+ for (x = rect->left; x <= rect->right; x++) {
+
+ //Mirror visual image for old HW
+ if (mlx90614Version == mlx90614Version_old)
+ xPos = (159 - x);
+ else
+ xPos = x;
+
+ //Check if we draw inside the screen on x position
+ if (((xPos + (5 * adjCombRight) <= 159) && (xPos - (5 * adjCombLeft) >= 0))) {
+
+ //Get the image position
+ imagepos = xPos + (y * 160);
+ //Do the visual alignment
+ imagepos += 5 * adjCombRight;
+ imagepos -= 5 * adjCombLeft;
+ imagepos += 5 * adjCombDown * 160;
+ imagepos -= 5 * adjCombUp * 160;
+
+ //Create combined pixel out of thermal and visual
+ if (displayMode == displayMode_combined) {
+ //Get the visual image color
+ pixel = bmp[count++];
+ //And extract the RGB values out of it
+ redV = (pixel & 0xF800) >> 8;
+ greenV = (pixel & 0x7E0) >> 3;
+ blueV = (pixel & 0x1F) << 3;
+
+ //Get the thermal image color, rotated
+ if (rotationVert)
+ pixel = smallBuffer[19199 - imagepos];
+ //Get the thermal image color, normal
+ else
+ pixel = smallBuffer[imagepos];
+ //And extract the RGB values out of it
+ redT = (pixel & 0xF800) >> 8;
+ greenT = (pixel & 0x7E0) >> 3;
+ blueT = (pixel & 0x1F) << 3;
+
+ //Mix both
+ red = redT * (1 - adjCombAlpha) + redV * adjCombAlpha;
+ green = greenT * (1 - adjCombAlpha) + greenV * adjCombAlpha;
+ blue = blueT * (1 - adjCombAlpha) + blueV * adjCombAlpha;
+
+ //Set the pixel to the calculated RGB565 value
+ pixel = (((red & 248) | green >> 5) << 8)
+ | ((green & 28) << 3 | blue >> 3);
+
+ }
+
+ //Set pixel to visual image only
+ else
+ pixel = bmp[count++];
+
+ //Write to image buffer, rotated
+ if (rotationVert)
+ smallBuffer[19199 - imagepos] = pixel;
+ //Write to image buffer, normal
+ else
+ smallBuffer[imagepos] = pixel;
+ }
+ //Raise counter if it is not inside the image
+ else
+ count++;
+ }
+ }
+ }
+ return 1;
+}
+
+/* Help function to insert the JPEG data into the decompressor */
+unsigned int camera_decompIn(JDEC * jd, byte* buff, unsigned int ndata) {
+ IODEV * dev = (IODEV *)jd->device;
+ ndata = (unsigned int)dev->jsize - dev->joffset > ndata ?
+ ndata : dev->jsize - dev->joffset;
+ if (buff)
+ memcpy(buff, dev->jpic + dev->joffset, ndata);
+ dev->joffset += ndata;
+ return ndata;
+}
+
+/* Transfer, decompress or save the visual image */
+void camera_get(byte mode, char* dirname)
+{
+ uint32_t jpegLen;
+
+ //Get length from Arducam for streaming
+ if (teensyVersion == teensyVersion_new) {
+ //Wait for image to be there
+ while (!ov2640_getBit(ARDUCHIP_TRIG, CAP_DONE_MASK));
+ //Get JPEG length
+ jpegLen = ov2640_readFifoLength();
+ }
+
+ //Get length from PTC-06 or PTC-08
+ else
+ jpegLen = vc0706_frameLength();
+
+ //Buffer for Teensy 3.1 / 3.2
+ if (teensyVersion == teensyVersion_old)
+ {
+ //When streaming, allocate bytes
+ if (mode == camera_stream)
+ camera_jpegData = (uint8_t*)malloc(jpegLen);
+ //For saving and serial, do write directly
+ else
+ camera_jpegData = NULL;
+ }
+ //Buffer for Teensy 3.6
+ else
+ {
+ //If rotated and not streaming, add EXIF header
+ if ((rotationVert) && (mode != camera_stream))
+ camera_jpegData = (uint8_t*)malloc(jpegLen + 100);
+ //Otherwise allocate byte for JPEG data only
+ else
+ camera_jpegData = (uint8_t*)malloc(jpegLen);
+ }
+
+ //Arducam
+ if (teensyVersion == teensyVersion_new) {
+ //Stream
+ if (mode == camera_stream)
+ ov2640_transfer(camera_jpegData, 1, &jpegLen);
+
+ //Save
+ else if (mode == camera_save) {
+ //Transfer from camera
+ ov2640_transfer(camera_jpegData, 0, &jpegLen);
+
+ //Start SD transmission
+ startAltClockline();
+
+ //Create JPEG file
+ createJPEGFile(dirname);
+
+ //Write to SD file, EXIF included if rotated
+ sdFile.write(camera_jpegData, jpegLen);
+
+ //Close file
+ sdFile.close();
+ endAltClockline();
+
+ //Free buffer
+ free(camera_jpegData);
+ }
+
+ //Serial transfer
+ else if (mode == camera_serial)
+ {
+ //Transfer from camera
+ ov2640_transfer(camera_jpegData, 0, &jpegLen);
+
+ //Send length
+ Serial.write((jpegLen & 0xFF00) >> 8);
+ Serial.write(jpegLen & 0x00FF);
+
+ //Send JPEG bytestream to serial port
+ Serial.write(camera_jpegData, jpegLen);
+
+ //Free buffer
+ free(camera_jpegData);
+ }
+ }
+ //PTC-06 or PTC-08
+ else
+ vc0706_transfer(camera_jpegData, jpegLen, mode, dirname);
+
+ //For streaming, decompress data and capture next frame
+ if (mode == camera_stream) {
+
+ //Decompress the image if not saving
+ camera_iodev.jpic = camera_jpegData;
+ camera_iodev.jsize = jpegLen;
+
+ //the offset is zero
+ camera_iodev.joffset = 0;
+
+ //Prepare the image for convertion to RGB565
+ jd_prepare(&camera_jd, camera_decompIn, camera_jdwork, 3100, &camera_iodev);
+
+ //Decompress into 320x240 buffer
+ if ((teensyVersion == teensyVersion_new) && (hqRes))
+ jd_decomp(&camera_jd, camera_decompOutNormal, 0);
+
+ //Decompress into 160x120 buffer, also with transparency
+ else
+ jd_decomp(&camera_jd, camera_decompOutCombined, 0);
+
+ //Free the jpeg data array
+ free(camera_jpegData);
+ }
+}
diff --git a/Firmware_V2/src/hardware/camera/camera.h b/Firmware_V2/src/hardware/camera/camera.h
new file mode 100644
index 0000000..a62338e
--- /dev/null
+++ b/Firmware_V2/src/hardware/camera/camera.h
@@ -0,0 +1,41 @@
+/*
+*
+* Camera - Visual camera module
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef CAMERA_H
+#define CAMERA_H
+
+/*################################# INCLUDES ##################################*/
+
+#include
+
+/*################# PUBLIC CONSTANTS, VARIABLES & DATA TYPES ##################*/
+
+//The current camera resolution
+extern byte camera_resolution;
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+void camera_capture(void);
+void camera_changeRes(byte camRes);
+unsigned int camera_decompIn(JDEC * jd, byte* buff, unsigned int ndata);
+unsigned int camera_decompOutCombined(JDEC * jd, void * bitmap, JRECT * rect);
+unsigned int camera_decompOutNormal(JDEC * jd, void * bitmap, JRECT * rect);
+void camera_get(byte mode, char* dirname = NULL);
+void camera_init(void);
+void camera_setDisplayRes();
+void camera_setSaveRes();
+void camera_setStreamRes();
+
+#endif /* CAMERA_H */
diff --git a/Firmware_V2/src/hardware/camera/ov2640.cpp b/Firmware_V2/src/hardware/camera/ov2640.cpp
new file mode 100644
index 0000000..12cb2a1
--- /dev/null
+++ b/Firmware_V2/src/hardware/camera/ov2640.cpp
@@ -0,0 +1,465 @@
+/*
+*
+* OV2640 - Driver for the Arducam camera module
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*################# DATA TYPES, CONSTANTS & MACRO DEFINITIONS #################*/
+
+/* Sensor related definitions */
+
+#define SPISPEED 4000000
+#define BMP 0
+#define JPEG 1
+#define OV2640_ADDRESS 0x60
+#define OV2640_CHIPID_HIGH 0x0A
+#define OV2640_CHIPID_LOW 0x0B
+
+/* I2C control definition */
+
+#define I2C_ADDR_8BIT 0
+#define I2C_ADDR_16BIT 1
+#define I2C_REG_8BIT 0
+#define I2C_REG_16BIT 1
+#define I2C_DAT_8BIT 0
+#define I2C_DAT_16BIT 1
+
+/* Register initialization tables for SENSORs */
+
+#define SENSOR_REG_TERM_8BIT 0xFF
+#define SENSOR_REG_TERM_16BIT 0xFFFF
+#define SENSOR_VAL_TERM_8BIT 0xFF
+#define SENSOR_VAL_TERM_16BIT 0xFFFF
+#define MAX_FIFO_SIZE 0x5FFFF
+
+/* ArduChip registers definition */
+
+#define RWBIT 0x80
+#define ARDUCHIP_TEST1 0x00
+#define ARDUCHIP_MODE 0x02
+#define MCU2LCD_MODE 0x00
+#define CAM2LCD_MODE 0x01
+#define LCD2MCU_MODE 0x02
+#define ARDUCHIP_TIM 0x03
+#define ARDUCHIP_FIFO 0x04
+#define FIFO_CLEAR_MASK 0x01
+#define FIFO_START_MASK 0x02
+#define FIFO_RDPTR_RST_MASK 0x10
+#define FIFO_WRPTR_RST_MASK 0x20
+#define ARDUCHIP_GPIO 0x06
+#define GPIO_RESET_MASK 0x01
+#define GPIO_PWDN_MASK 0x02
+#define GPIO_PWREN_MASK 0x04
+#define BURST_FIFO_READ 0x3C
+#define SINGLE_FIFO_READ 0x3D
+#define ARDUCHIP_REV 0x40
+#define VER_LOW_MASK 0x3F
+#define VER_HIGH_MASK 0xC0
+#define VSYNC_MASK 0x01
+#define SHUTTER_MASK 0x02
+
+#define FIFO_SIZE1 0x42
+#define FIFO_SIZE2 0x43
+#define FIFO_SIZE3 0x44
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* I2C Write 8bit address, 8bit data */
+byte ov2640_wrSensorReg8_8(int regID, int regDat) {
+ Wire.beginTransmission(0x60 >> 1);
+ Wire.write(regID & 0x00FF);
+ Wire.write(regDat & 0x00FF);
+
+ if (Wire.endTransmission())
+ return 0;
+
+ delay(1);
+
+ return 1;
+}
+
+/* I2C Read 8bit address, 8bit data */
+byte ov2640_rdSensorReg8_8(uint8_t regID, uint8_t* regDat) {
+ Wire.beginTransmission(0x60 >> 1);
+ Wire.write(regID & 0x00FF);
+ Wire.endTransmission();
+
+ Wire.requestFrom((0x60 >> 1), 1);
+ if (Wire.available())
+ *regDat = Wire.read();
+
+ delay(1);
+ return (1);
+}
+
+/* I2C Array Write 8bit address, 8bit data */
+int ov2640_wrSensorRegs8_8(const struct sensor_reg* reglist) {
+ uint16_t reg_addr = 0;
+ uint16_t reg_val = 0;
+ const struct sensor_reg *next = reglist;
+ while ((reg_addr != 0xff) | (reg_val != 0xff))
+ {
+ reg_addr = pgm_read_word(&next->reg);
+ reg_val = pgm_read_word(&next->val);
+ ov2640_wrSensorReg8_8(reg_addr, reg_val);
+ next++;
+ }
+
+ return 1;
+}
+
+/* SPI write operation */
+void ov2640_busWrite(int address, int value) {
+ startAltClockline();
+ CORE_PIN8_CONFIG = PORT_PCR_MUX(2);
+ CORE_PIN12_CONFIG = PORT_PCR_MUX(1);
+ //Take the SS pin low to select the chip
+ SPI.beginTransaction(SPISettings(SPISPEED, MSBFIRST, SPI_MODE0));
+ digitalWriteFast(pin_cam_cs, LOW);
+ //Send in the address and value via SPI
+ SPI.transfer(address);
+ SPI.transfer(value);
+ //Take the SS pin high to de-select the chip
+ digitalWriteFast(pin_cam_cs, HIGH);
+ SPI.endTransaction();
+ CORE_PIN8_CONFIG = PORT_PCR_MUX(1);
+ CORE_PIN12_CONFIG = PORT_PCR_MUX(2);
+ endAltClockline();
+}
+
+/* SPI read operation */
+uint8_t ov2640_busRead(int address) {
+ startAltClockline();
+ CORE_PIN8_CONFIG = PORT_PCR_MUX(2);
+ CORE_PIN12_CONFIG = PORT_PCR_MUX(1);
+ //Take the SS pin low to select the chip
+ SPI.beginTransaction(SPISettings(SPISPEED, MSBFIRST, SPI_MODE0));
+ digitalWriteFast(pin_cam_cs, LOW);
+ //Send in the address and value via SPI
+ SPI.transfer(address);
+ uint8_t value = SPI.transfer(0x00);
+ //Take the SS pin high to de-select the chip
+ digitalWriteFast(pin_cam_cs, HIGH);
+ SPI.endTransaction();
+ CORE_PIN8_CONFIG = PORT_PCR_MUX(1);
+ CORE_PIN12_CONFIG = PORT_PCR_MUX(2);
+ endAltClockline();
+ //Return value
+ return value;
+}
+
+/* Read ArduChip internal registers */
+uint8_t ov2640_readReg(uint8_t addr) {
+ uint8_t data;
+ data = ov2640_busRead(addr & 0x7F);
+ return data;
+}
+
+/* Write ArduChip internal registers */
+void ov2640_writeReg(uint8_t addr, uint8_t data) {
+ ov2640_busWrite(addr | 0x80, data);
+}
+
+/* Init the camera */
+bool ov2640_init(void) {
+ bool retVal = true;
+ uint8_t vid, pid;
+
+ //Test SPI connection first
+ ov2640_writeReg(ARDUCHIP_TEST1, 0x55);
+ uint8_t rtnVal = ov2640_readReg(ARDUCHIP_TEST1);
+ if (rtnVal != 0x55)
+ retVal = false;
+
+ //Test I2C connection second
+ ov2640_wrSensorReg8_8(0xff, 0x01);
+ ov2640_rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid);
+ ov2640_rdSensorReg8_8(OV2640_CHIPID_LOW, &pid);
+ if ((vid != 0x26) || ((pid != 0x42) && (pid != 0x41)))
+ retVal = false;
+
+ //Init registers
+ ov2640_wrSensorReg8_8(0xff, 0x01);
+ ov2640_wrSensorReg8_8(0x12, 0x80);
+
+ //Wait some time
+ delay(100);
+
+ //Set format to JPEG
+ ov2640_wrSensorRegs8_8(OV2640_JPEG_INIT);
+ ov2640_wrSensorRegs8_8(OV2640_YUV422);
+ ov2640_wrSensorRegs8_8(OV2640_JPEG);
+ ov2640_wrSensorReg8_8(0xff, 0x01);
+ ov2640_wrSensorReg8_8(0x15, 0x00);
+ ov2640_wrSensorRegs8_8(OV2640_320x240_JPEG);
+
+ //Return status
+ return retVal;
+}
+
+/* Set the format to JPEG or BMP */
+void ov2640_setFormat(byte fmt) {
+ //BMP
+ if (fmt == BMP) {
+ ov2640_wrSensorRegs8_8(OV2640_QVGA);
+ }
+ //JPEG
+ else {
+ ov2640_wrSensorRegs8_8(OV2640_JPEG_INIT);
+ ov2640_wrSensorRegs8_8(OV2640_YUV422);
+ ov2640_wrSensorRegs8_8(OV2640_JPEG);
+ ov2640_wrSensorReg8_8(0xff, 0x01);
+ ov2640_wrSensorReg8_8(0x15, 0x00);
+ ov2640_wrSensorRegs8_8(OV2640_320x240_JPEG);
+ }
+}
+
+/* Set the JPEG pixel size of the image */
+void ov2640_setJPEGSize(uint8_t size) {
+ switch (size)
+ {
+ case OV2640_160x120:
+ ov2640_wrSensorRegs8_8(OV2640_160x120_JPEG);
+ break;
+ case OV2640_176x144:
+ ov2640_wrSensorRegs8_8(OV2640_176x144_JPEG);
+ break;
+ case OV2640_320x240:
+ ov2640_wrSensorRegs8_8(OV2640_320x240_JPEG);
+ break;
+ case OV2640_352x288:
+ ov2640_wrSensorRegs8_8(OV2640_352x288_JPEG);
+ break;
+ case OV2640_640x480:
+ ov2640_wrSensorRegs8_8(OV2640_640x480_JPEG);
+ break;
+ case OV2640_800x600:
+ ov2640_wrSensorRegs8_8(OV2640_800x600_JPEG);
+ break;
+ case OV2640_1024x768:
+ ov2640_wrSensorRegs8_8(OV2640_1024x768_JPEG);
+ break;
+ case OV2640_1280x1024:
+ ov2640_wrSensorRegs8_8(OV2640_1280x1024_JPEG);
+ break;
+ case OV2640_1600x1200:
+ ov2640_wrSensorRegs8_8(OV2640_1600x1200_JPEG);
+ break;
+ default:
+ ov2640_wrSensorRegs8_8(OV2640_320x240_JPEG);
+ break;
+ }
+}
+
+/* Read Write FIFO length */
+uint32_t ov2640_readFifoLength(void) {
+ uint32_t len1, len2, len3, length;
+ len1 = ov2640_readReg(FIFO_SIZE1);
+ len2 = ov2640_readReg(FIFO_SIZE2);
+ len3 = ov2640_readReg(FIFO_SIZE3) & 0x7f;
+ length = ((len3 << 16) | (len2 << 8) | len1) & 0x07fffff;
+ return length;
+}
+
+/* Start the FIFO burst mode */
+void ov2640_startFifoBurst(void) {
+ CORE_PIN8_CONFIG = PORT_PCR_MUX(2);
+ CORE_PIN12_CONFIG = PORT_PCR_MUX(1);
+ startAltClockline();
+ SPI.beginTransaction(SPISettings(SPISPEED, MSBFIRST, SPI_MODE0));
+ digitalWriteFast(pin_cam_cs, LOW);
+ SPI.transfer(BURST_FIFO_READ);
+}
+
+/* End the FIFO burst mode */
+void ov2640_endFifoBurst(void) {
+ digitalWriteFast(pin_cam_cs, HIGH);
+ SPI.endTransaction();
+ CORE_PIN8_CONFIG = PORT_PCR_MUX(1);
+ CORE_PIN12_CONFIG = PORT_PCR_MUX(2);
+ endAltClockline();
+}
+
+/* Set corresponding bit */
+void ov2640_setBit(uint8_t addr, uint8_t bit) {
+ uint8_t temp;
+ temp = ov2640_readReg(addr);
+ ov2640_writeReg(addr, temp | bit);
+}
+
+/* Clear corresponding bit */
+void ov2640_clearBit(uint8_t addr, uint8_t bit) {
+ uint8_t temp;
+ temp = ov2640_readReg(addr);
+ ov2640_writeReg(addr, temp & (~bit));
+}
+
+/* Get corresponding bit status */
+uint8_t ov2640_getBit(uint8_t addr, uint8_t bit) {
+ uint8_t temp;
+ temp = ov2640_readReg(addr);
+ temp = temp & bit;
+ return temp;
+}
+
+/* Set ArduCAM working mode */
+void ov2640_setMode(uint8_t mode) {
+ switch (mode)
+ {
+ //MCU2LCD_MODE: MCU writes the LCD screen GRAM
+ case MCU2LCD_MODE:
+ ov2640_writeReg(ARDUCHIP_MODE, MCU2LCD_MODE);
+ break;
+ //CAM2LCD_MODE: Camera takes control of the LCD screen
+ case CAM2LCD_MODE:
+ ov2640_writeReg(ARDUCHIP_MODE, CAM2LCD_MODE);
+ break;
+ //LCD2MCU_MODE: MCU read the LCD screen GRAM
+ case LCD2MCU_MODE:
+ ov2640_writeReg(ARDUCHIP_MODE, LCD2MCU_MODE);
+ break;
+ //Default is MCU2LCD_MODE
+ default:
+ ov2640_writeReg(ARDUCHIP_MODE, MCU2LCD_MODE);
+ break;
+ }
+}
+
+/* Reset the FIFO pointer to zero */
+void ov2640_flushFifo(void) {
+ ov2640_writeReg(ARDUCHIP_FIFO, FIFO_CLEAR_MASK);
+}
+
+/* Send capture command */
+void ov2640_startCapture(void) {
+ ov2640_writeReg(ARDUCHIP_FIFO, FIFO_START_MASK);
+}
+
+/* Clear FIFO Complete flag */
+void ov2640_clearFifoFlag(void) {
+ ov2640_writeReg(ARDUCHIP_FIFO, FIFO_CLEAR_MASK);
+}
+
+/* Read FIFO single */
+uint8_t ov2640_readFifo(void) {
+ uint8_t data;
+ data = ov2640_busRead(SINGLE_FIFO_READ);
+ return data;
+}
+
+/* Send the capture command to the camera */
+void ov2640_capture(void) {
+ //Flush the FIFO
+ ov2640_flushFifo();
+ //Clear the capture done flag
+ ov2640_clearFifoFlag();
+ //Start capture
+ ov2640_startCapture();
+}
+
+/* Transfer the JPEG data from the OV2640 */
+void ov2640_transfer(uint8_t * jpegData, boolean stream, uint32_t* length)
+{
+repeat:
+
+ //Count variable
+ uint32_t counter = 0;
+
+ //Start FIFO Burst
+ ov2640_startFifoBurst();
+
+ //Transfer data
+ uint8_t temp = 0xff, temp_last;
+ boolean is_header = 0;
+
+ //Repeat as long as needed
+ while (counter < *length)
+ {
+ //If main menu should be entered
+ if (showMenu == showMenu_desired)
+ {
+ //Stop FIFO Burst
+ ov2640_endFifoBurst();
+ //Go back
+ return;
+ }
+
+ //Save last byte
+ temp_last = temp;
+ //Get new byte over SPI
+ temp = SPI.transfer(0x00);
+
+ //Normal bytestream
+ if (is_header)
+ {
+ jpegData[counter] = temp;
+ counter++;
+ }
+
+ //Start byte sqeuence
+ else if ((temp == 0xD8) & (temp_last == 0xFF))
+ {
+ is_header = 1;
+ jpegData[0] = temp_last;
+ jpegData[1] = temp;
+ counter = 2;
+ }
+
+ //If rotation enabled and saving / sending, include EXIF header
+ if ((counter == 20) && (!stream) && (rotationVert))
+ {
+ for (uint8_t i = 0; i < 100; i++)
+ {
+ jpegData[counter + i] = exifHeader_rotated[i];
+ }
+ counter += 100;
+ }
+
+ //End byte sequence
+ if (((temp == 0xD9) && (temp_last == 0xFF)))
+ {
+ //Stop FIFO Burst
+ ov2640_endFifoBurst();
+
+ //Save length
+ *length = counter;
+
+ //Everything was OK
+ return;
+ }
+ }
+
+ //Stop FIFO Burst
+ ov2640_endFifoBurst();
+
+ //Get a new frame for stream
+ if (stream)
+ {
+ //Send capture command
+ camera_capture();
+
+ //Repeat frame receive
+ goto repeat;
+ }
+}
diff --git a/Firmware_V2/src/hardware/camera/ov2640.h b/Firmware_V2/src/hardware/camera/ov2640.h
new file mode 100644
index 0000000..22b27e9
--- /dev/null
+++ b/Firmware_V2/src/hardware/camera/ov2640.h
@@ -0,0 +1,66 @@
+/*
+*
+* OV2640 - Driver for the Arducam camera module
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef OV2640_H
+#define OV2640_H
+
+/*################# PUBLIC CONSTANTS, VARIABLES & DATA TYPES ##################*/
+
+#define OV2640_160x120 0
+#define OV2640_176x144 1
+#define OV2640_320x240 2
+#define OV2640_352x288 3
+#define OV2640_640x480 4
+#define OV2640_800x600 5
+#define OV2640_1024x768 6
+#define OV2640_1280x1024 7
+#define OV2640_1600x1200 8
+
+#define CAP_DONE_MASK 0x08
+#define ARDUCHIP_TRIG 0x41
+
+struct sensor_reg
+{
+ uint16_t reg;
+ uint16_t val;
+};
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+uint8_t ov2640_busRead(int address);
+void ov2640_busWrite(int address, int value);
+void ov2640_capture(void);
+void ov2640_clearBit(uint8_t addr, uint8_t bit);
+void ov2640_clearFifoFlag(void);
+void ov2640_endFifoBurst(void);
+void ov2640_flushFifo(void);
+uint8_t ov2640_getBit(uint8_t addr, uint8_t bit);
+bool ov2640_init(void);
+byte ov2640_rdSensorReg8_8(uint8_t regID, uint8_t* regDat);
+uint32_t ov2640_readFifoLength(void);
+uint8_t ov2640_readFifo(void);
+uint8_t ov2640_readReg(uint8_t addr);
+void ov2640_setBit(uint8_t addr, uint8_t bit);
+void ov2640_setFormat(byte fmt);
+void ov2640_setJPEGSize(uint8_t size);
+void ov2640_setMode(uint8_t mode);
+void ov2640_startCapture(void);
+void ov2640_startFifoBurst(void);
+void ov2640_transfer(uint8_t * jpegData, boolean stream, uint32_t* length);
+void ov2640_writeReg(uint8_t addr, uint8_t data);
+byte ov2640_wrSensorReg8_8(int regID, int regDat);
+int ov2640_wrSensorRegs8_8(const struct sensor_reg* reglist);
+
+#endif /* OV2640_H */
diff --git a/Firmware_V2/src/hardware/camera/ov2640regs.cpp b/Firmware_V2/src/hardware/camera/ov2640regs.cpp
new file mode 100644
index 0000000..7bb7b6b
--- /dev/null
+++ b/Firmware_V2/src/hardware/camera/ov2640regs.cpp
@@ -0,0 +1,882 @@
+/*
+ *
+ * OV2640Regs - Register for the Arducam camera module
+ *
+ * DIY-Thermocam Firmware
+ *
+ * GNU General Public License v3.0
+ *
+ * Copyright by Max Ritter
+ *
+ * http://www.diy-thermocam.net
+ * https://github.com/maxritter/DIY-Thermocam
+ *
+ */
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+
+/*############################# PUBLIC VARIABLES ##############################*/
+
+//EXIF header for 180 degree rotation
+const uint8_t exifHeader_rotated[] =
+{ 0xFF,0xE1,0x00,0x62,0x45,0x78,0x69,0x66,0x00,0x00,0x4D,0x4D,0x00,0x2A,
+ 0x00,0x00,0x00,0x08,0x00,0x05,0x01,0x12,0x00,0x03,0x00,0x00,0x00,0x01,
+ 0x00,0x03,0x00,0x00,0x01,0x1A,0x00,0x05,0x00,0x00,0x00,0x01,0x00,0x00,
+ 0x00,0x4A,0x01,0x1B,0x00,0x05,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x52,
+ 0x01,0x28,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x02,0x13,
+ 0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x01 };
+
+const struct sensor_reg OV2640_QVGA[] PROGMEM =
+{
+ { 0xff, 0x0 },
+ { 0x2c, 0xff },
+ { 0x2e, 0xdf },
+ { 0xff, 0x1 },
+ { 0x3c, 0x32 },
+ { 0x11, 0x0 },
+ { 0x9, 0x2 },
+ { 0x4, 0xa8 },
+ { 0x13, 0xe5 },
+ { 0x14, 0x48 },
+ { 0x2c, 0xc },
+ { 0x33, 0x78 },
+ { 0x3a, 0x33 },
+ { 0x3b, 0xfb },
+ { 0x3e, 0x0 },
+ { 0x43, 0x11 },
+ { 0x16, 0x10 },
+ { 0x39, 0x2 },
+ { 0x35, 0x88 },
+
+ { 0x22, 0xa },
+ { 0x37, 0x40 },
+ { 0x23, 0x0 },
+ { 0x34, 0xa0 },
+ { 0x6, 0x2 },
+ { 0x6, 0x88 },
+ { 0x7, 0xc0 },
+ { 0xd, 0xb7 },
+ { 0xe, 0x1 },
+ { 0x4c, 0x0 },
+ { 0x4a, 0x81 },
+ { 0x21, 0x99 },
+ { 0x24, 0x40 },
+ { 0x25, 0x38 },
+ { 0x26, 0x82 },
+ { 0x5c, 0x0 },
+ { 0x63, 0x0 },
+ { 0x46, 0x22 },
+ { 0xc, 0x3a },
+ { 0x5d, 0x55 },
+ { 0x5e, 0x7d },
+ { 0x5f, 0x7d },
+ { 0x60, 0x55 },
+ { 0x61, 0x70 },
+ { 0x62, 0x80 },
+ { 0x7c, 0x5 },
+ { 0x20, 0x80 },
+ { 0x28, 0x30 },
+ { 0x6c, 0x0 },
+ { 0x6d, 0x80 },
+ { 0x6e, 0x0 },
+ { 0x70, 0x2 },
+ { 0x71, 0x94 },
+ { 0x73, 0xc1 },
+ { 0x3d, 0x34 },
+ { 0x12, 0x4 },
+ { 0x5a, 0x57 },
+ { 0x4f, 0xbb },
+ { 0x50, 0x9c },
+ { 0xff, 0x0 },
+ { 0xe5, 0x7f },
+ { 0xf9, 0xc0 },
+ { 0x41, 0x24 },
+ { 0xe0, 0x14 },
+ { 0x76, 0xff },
+ { 0x33, 0xa0 },
+ { 0x42, 0x20 },
+ { 0x43, 0x18 },
+ { 0x4c, 0x0 },
+ { 0x87, 0xd0 },
+ { 0x88, 0x3f },
+ { 0xd7, 0x3 },
+ { 0xd9, 0x10 },
+ { 0xd3, 0x82 },
+ { 0xc8, 0x8 },
+ { 0xc9, 0x80 },
+ { 0x7c, 0x0 },
+ { 0x7d, 0x0 },
+ { 0x7c, 0x3 },
+ { 0x7d, 0x48 },
+ { 0x7d, 0x48 },
+ { 0x7c, 0x8 },
+ { 0x7d, 0x20 },
+ { 0x7d, 0x10 },
+ { 0x7d, 0xe },
+ { 0x90, 0x0 },
+ { 0x91, 0xe },
+ { 0x91, 0x1a },
+ { 0x91, 0x31 },
+ { 0x91, 0x5a },
+ { 0x91, 0x69 },
+ { 0x91, 0x75 },
+ { 0x91, 0x7e },
+ { 0x91, 0x88 },
+ { 0x91, 0x8f },
+ { 0x91, 0x96 },
+ { 0x91, 0xa3 },
+ { 0x91, 0xaf },
+ { 0x91, 0xc4 },
+ { 0x91, 0xd7 },
+ { 0x91, 0xe8 },
+ { 0x91, 0x20 },
+ { 0x92, 0x0 },
+
+ { 0x93, 0x6 },
+ { 0x93, 0xe3 },
+ { 0x93, 0x3 },
+ { 0x93, 0x3 },
+ { 0x93, 0x0 },
+ { 0x93, 0x2 },
+ { 0x93, 0x0 },
+ { 0x93, 0x0 },
+ { 0x93, 0x0 },
+ { 0x93, 0x0 },
+ { 0x93, 0x0 },
+ { 0x93, 0x0 },
+ { 0x93, 0x0 },
+ { 0x96, 0x0 },
+ { 0x97, 0x8 },
+ { 0x97, 0x19 },
+ { 0x97, 0x2 },
+ { 0x97, 0xc },
+ { 0x97, 0x24 },
+ { 0x97, 0x30 },
+ { 0x97, 0x28 },
+ { 0x97, 0x26 },
+ { 0x97, 0x2 },
+ { 0x97, 0x98 },
+ { 0x97, 0x80 },
+ { 0x97, 0x0 },
+ { 0x97, 0x0 },
+ { 0xa4, 0x0 },
+ { 0xa8, 0x0 },
+ { 0xc5, 0x11 },
+ { 0xc6, 0x51 },
+ { 0xbf, 0x80 },
+ { 0xc7, 0x10 },
+ { 0xb6, 0x66 },
+ { 0xb8, 0xa5 },
+ { 0xb7, 0x64 },
+ { 0xb9, 0x7c },
+ { 0xb3, 0xaf },
+ { 0xb4, 0x97 },
+ { 0xb5, 0xff },
+ { 0xb0, 0xc5 },
+ { 0xb1, 0x94 },
+ { 0xb2, 0xf },
+ { 0xc4, 0x5c },
+ { 0xa6, 0x0 },
+ { 0xa7, 0x20 },
+ { 0xa7, 0xd8 },
+ { 0xa7, 0x1b },
+ { 0xa7, 0x31 },
+ { 0xa7, 0x0 },
+ { 0xa7, 0x18 },
+ { 0xa7, 0x20 },
+ { 0xa7, 0xd8 },
+ { 0xa7, 0x19 },
+ { 0xa7, 0x31 },
+ { 0xa7, 0x0 },
+ { 0xa7, 0x18 },
+ { 0xa7, 0x20 },
+ { 0xa7, 0xd8 },
+ { 0xa7, 0x19 },
+ { 0xa7, 0x31 },
+ { 0xa7, 0x0 },
+ { 0xa7, 0x18 },
+ { 0x7f, 0x0 },
+ { 0xe5, 0x1f },
+ { 0xe1, 0x77 },
+ { 0xdd, 0x7f },
+ { 0xc2, 0xe },
+
+ { 0xff, 0x0 },
+ { 0xe0, 0x4 },
+ { 0xc0, 0xc8 },
+ { 0xc1, 0x96 },
+ { 0x86, 0x3d },
+ { 0x51, 0x90 },
+ { 0x52, 0x2c },
+ { 0x53, 0x0 },
+ { 0x54, 0x0 },
+ { 0x55, 0x88 },
+ { 0x57, 0x0 },
+
+ { 0x50, 0x92 },
+ { 0x5a, 0x50 },
+ { 0x5b, 0x3c },
+ { 0x5c, 0x0 },
+ { 0xd3, 0x4 },
+ { 0xe0, 0x0 },
+
+ { 0xff, 0x0 },
+ { 0x5, 0x0 },
+
+ { 0xda, 0x8 },
+ { 0xd7, 0x3 },
+ { 0xe0, 0x0 },
+
+ { 0x5, 0x0 },
+
+
+ { 0xff,0xff }
+};
+
+const struct sensor_reg OV2640_JPEG_INIT[] PROGMEM =
+{
+ { 0xff, 0x00 },
+ { 0x2c, 0xff },
+ { 0x2e, 0xdf },
+ { 0xff, 0x01 },
+ { 0x3c, 0x32 },
+ { 0x11, 0x00 },
+ { 0x09, 0x02 },
+ { 0x04, 0x28 },
+ { 0x13, 0xe5 },
+ { 0x14, 0x48 },
+ { 0x2c, 0x0c },
+ { 0x33, 0x78 },
+ { 0x3a, 0x33 },
+ { 0x3b, 0xfB },
+ { 0x3e, 0x00 },
+ { 0x43, 0x11 },
+ { 0x16, 0x10 },
+ { 0x39, 0x92 },
+ { 0x35, 0xda },
+ { 0x22, 0x1a },
+ { 0x37, 0xc3 },
+ { 0x23, 0x00 },
+ { 0x34, 0xc0 },
+ { 0x36, 0x1a },
+ { 0x06, 0x88 },
+ { 0x07, 0xc0 },
+ { 0x0d, 0x87 },
+ { 0x0e, 0x41 },
+ { 0x4c, 0x00 },
+ { 0x48, 0x00 },
+ { 0x5B, 0x00 },
+ { 0x42, 0x03 },
+ { 0x4a, 0x81 },
+ { 0x21, 0x99 },
+ { 0x24, 0x40 },
+ { 0x25, 0x38 },
+ { 0x26, 0x82 },
+ { 0x5c, 0x00 },
+ { 0x63, 0x00 },
+ { 0x61, 0x70 },
+ { 0x62, 0x80 },
+ { 0x7c, 0x05 },
+ { 0x20, 0x80 },
+ { 0x28, 0x30 },
+ { 0x6c, 0x00 },
+ { 0x6d, 0x80 },
+ { 0x6e, 0x00 },
+ { 0x70, 0x02 },
+ { 0x71, 0x94 },
+ { 0x73, 0xc1 },
+ { 0x12, 0x40 },
+ { 0x17, 0x11 },
+ { 0x18, 0x43 },
+ { 0x19, 0x00 },
+ { 0x1a, 0x4b },
+ { 0x32, 0x09 },
+ { 0x37, 0xc0 },
+ { 0x4f, 0x60 },
+ { 0x50, 0xa8 },
+ { 0x6d, 0x00 },
+ { 0x3d, 0x38 },
+ { 0x46, 0x3f },
+ { 0x4f, 0x60 },
+ { 0x0c, 0x3c },
+ { 0xff, 0x00 },
+ { 0xe5, 0x7f },
+ { 0xf9, 0xc0 },
+ { 0x41, 0x24 },
+ { 0xe0, 0x14 },
+ { 0x76, 0xff },
+ { 0x33, 0xa0 },
+ { 0x42, 0x20 },
+ { 0x43, 0x18 },
+ { 0x4c, 0x00 },
+ { 0x87, 0xd5 },
+ { 0x88, 0x3f },
+ { 0xd7, 0x03 },
+ { 0xd9, 0x10 },
+ { 0xd3, 0x82 },
+ { 0xc8, 0x08 },
+ { 0xc9, 0x80 },
+ { 0x7c, 0x00 },
+ { 0x7d, 0x00 },
+ { 0x7c, 0x03 },
+ { 0x7d, 0x48 },
+ { 0x7d, 0x48 },
+ { 0x7c, 0x08 },
+ { 0x7d, 0x20 },
+ { 0x7d, 0x10 },
+ { 0x7d, 0x0e },
+ { 0x90, 0x00 },
+ { 0x91, 0x0e },
+ { 0x91, 0x1a },
+ { 0x91, 0x31 },
+ { 0x91, 0x5a },
+ { 0x91, 0x69 },
+ { 0x91, 0x75 },
+ { 0x91, 0x7e },
+ { 0x91, 0x88 },
+ { 0x91, 0x8f },
+ { 0x91, 0x96 },
+ { 0x91, 0xa3 },
+ { 0x91, 0xaf },
+ { 0x91, 0xc4 },
+ { 0x91, 0xd7 },
+ { 0x91, 0xe8 },
+ { 0x91, 0x20 },
+ { 0x92, 0x00 },
+ { 0x93, 0x06 },
+ { 0x93, 0xe3 },
+ { 0x93, 0x05 },
+ { 0x93, 0x05 },
+ { 0x93, 0x00 },
+ { 0x93, 0x04 },
+ { 0x93, 0x00 },
+ { 0x93, 0x00 },
+ { 0x93, 0x00 },
+ { 0x93, 0x00 },
+ { 0x93, 0x00 },
+ { 0x93, 0x00 },
+ { 0x93, 0x00 },
+ { 0x96, 0x00 },
+ { 0x97, 0x08 },
+ { 0x97, 0x19 },
+ { 0x97, 0x02 },
+ { 0x97, 0x0c },
+ { 0x97, 0x24 },
+ { 0x97, 0x30 },
+ { 0x97, 0x28 },
+ { 0x97, 0x26 },
+ { 0x97, 0x02 },
+ { 0x97, 0x98 },
+ { 0x97, 0x80 },
+ { 0x97, 0x00 },
+ { 0x97, 0x00 },
+ { 0xc3, 0xed },
+ { 0xa4, 0x00 },
+ { 0xa8, 0x00 },
+ { 0xc5, 0x11 },
+ { 0xc6, 0x51 },
+ { 0xbf, 0x80 },
+ { 0xc7, 0x10 },
+ { 0xb6, 0x66 },
+ { 0xb8, 0xA5 },
+ { 0xb7, 0x64 },
+ { 0xb9, 0x7C },
+ { 0xb3, 0xaf },
+ { 0xb4, 0x97 },
+ { 0xb5, 0xFF },
+ { 0xb0, 0xC5 },
+ { 0xb1, 0x94 },
+ { 0xb2, 0x0f },
+ { 0xc4, 0x5c },
+ { 0xc0, 0x64 },
+ { 0xc1, 0x4B },
+ { 0x8c, 0x00 },
+ { 0x86, 0x3D },
+ { 0x50, 0x00 },
+ { 0x51, 0xC8 },
+ { 0x52, 0x96 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x00 },
+ { 0x5a, 0xC8 },
+ { 0x5b, 0x96 },
+ { 0x5c, 0x00 },
+ { 0xd3, 0x00 }, //{ 0xd3, 0x7f },
+ { 0xc3, 0xed },
+ { 0x7f, 0x00 },
+ { 0xda, 0x00 },
+ { 0xe5, 0x1f },
+ { 0xe1, 0x67 },
+ { 0xe0, 0x00 },
+ { 0xdd, 0x7f },
+ { 0x05, 0x00 },
+
+ { 0x12, 0x40 },
+ { 0xd3, 0x04 }, //{ 0xd3, 0x7f },
+ { 0xc0, 0x16 },
+ { 0xC1, 0x12 },
+ { 0x8c, 0x00 },
+ { 0x86, 0x3d },
+ { 0x50, 0x00 },
+ { 0x51, 0x2C },
+ { 0x52, 0x24 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x00 },
+ { 0x5A, 0x2c },
+ { 0x5b, 0x24 },
+ { 0x5c, 0x00 },
+ { 0xff, 0xff },
+};
+
+const struct sensor_reg OV2640_YUV422[] PROGMEM =
+{
+ { 0xFF, 0x00 },
+ { 0x05, 0x00 },
+ { 0xDA, 0x10 },
+ { 0xD7, 0x03 },
+ { 0xDF, 0x00 },
+ { 0x33, 0x80 },
+ { 0x3C, 0x40 },
+ { 0xe1, 0x77 },
+ { 0x00, 0x00 },
+ { 0xff, 0xff },
+};
+
+const struct sensor_reg OV2640_JPEG[] PROGMEM =
+{
+ { 0xe0, 0x14 },
+ { 0xe1, 0x77 },
+ { 0xe5, 0x1f },
+ { 0xd7, 0x03 },
+ { 0xda, 0x10 },
+ { 0xe0, 0x00 },
+ { 0xFF, 0x01 },
+ { 0x04, 0x08 },
+ { 0xff, 0xff },
+};
+
+/* JPG 160x120 */
+const struct sensor_reg OV2640_160x120_JPEG[] PROGMEM =
+{
+ { 0xff, 0x01 },
+ { 0x12, 0x40 },
+ { 0x17, 0x11 },
+ { 0x18, 0x43 },
+ { 0x19, 0x00 },
+ { 0x1a, 0x4b },
+ { 0x32, 0x09 },
+ { 0x4f, 0xca },
+ { 0x50, 0xa8 },
+ { 0x5a, 0x23 },
+ { 0x6d, 0x00 },
+ { 0x39, 0x12 },
+ { 0x35, 0xda },
+ { 0x22, 0x1a },
+ { 0x37, 0xc3 },
+ { 0x23, 0x00 },
+ { 0x34, 0xc0 },
+ { 0x36, 0x1a },
+ { 0x06, 0x88 },
+ { 0x07, 0xc0 },
+ { 0x0d, 0x87 },
+ { 0x0e, 0x41 },
+ { 0x4c, 0x00 },
+ { 0xff, 0x00 },
+ { 0xe0, 0x04 },
+ { 0xc0, 0x64 },
+ { 0xc1, 0x4b },
+ { 0x86, 0x35 },
+ { 0x50, 0x92 },
+ { 0x51, 0xc8 },
+ { 0x52, 0x96 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x00 },
+ { 0x57, 0x00 },
+ { 0x5a, 0x28 },
+ { 0x5b, 0x1e },
+ { 0x5c, 0x00 },
+ { 0xe0, 0x00 },
+ { 0xff, 0xff },
+};
+
+/* JPG, 0x176x144 */
+const struct sensor_reg OV2640_176x144_JPEG[] PROGMEM =
+{
+ { 0xff, 0x01 },
+ { 0x12, 0x40 },
+ { 0x17, 0x11 },
+ { 0x18, 0x43 },
+ { 0x19, 0x00 },
+ { 0x1a, 0x4b },
+ { 0x32, 0x09 },
+ { 0x4f, 0xca },
+ { 0x50, 0xa8 },
+ { 0x5a, 0x23 },
+ { 0x6d, 0x00 },
+ { 0x39, 0x12 },
+ { 0x35, 0xda },
+ { 0x22, 0x1a },
+ { 0x37, 0xc3 },
+ { 0x23, 0x00 },
+ { 0x34, 0xc0 },
+ { 0x36, 0x1a },
+ { 0x06, 0x88 },
+ { 0x07, 0xc0 },
+ { 0x0d, 0x87 },
+ { 0x0e, 0x41 },
+ { 0x4c, 0x00 },
+ { 0xff, 0x00 },
+ { 0xe0, 0x04 },
+ { 0xc0, 0x64 },
+ { 0xc1, 0x4b },
+ { 0x86, 0x35 },
+ { 0x50, 0x92 },
+ { 0x51, 0xc8 },
+ { 0x52, 0x96 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x00 },
+ { 0x57, 0x00 },
+ { 0x5a, 0x2c },
+ { 0x5b, 0x24 },
+ { 0x5c, 0x00 },
+ { 0xe0, 0x00 },
+ { 0xff, 0xff },
+};
+
+/* JPG 320x240 */
+const struct sensor_reg OV2640_320x240_JPEG[] PROGMEM =
+{
+ { 0xff, 0x01 },
+ { 0x12, 0x40 },
+ { 0x17, 0x11 },
+ { 0x18, 0x43 },
+ { 0x19, 0x00 },
+ { 0x1a, 0x4b },
+ { 0x32, 0x09 },
+ { 0x4f, 0xca },
+ { 0x50, 0xa8 },
+ { 0x5a, 0x23 },
+ { 0x6d, 0x00 },
+ { 0x39, 0x12 },
+ { 0x35, 0xda },
+ { 0x22, 0x1a },
+ { 0x37, 0xc3 },
+ { 0x23, 0x00 },
+ { 0x34, 0xc0 },
+ { 0x36, 0x1a },
+ { 0x06, 0x88 },
+ { 0x07, 0xc0 },
+ { 0x0d, 0x87 },
+ { 0x0e, 0x41 },
+ { 0x4c, 0x00 },
+ { 0xff, 0x00 },
+ { 0xe0, 0x04 },
+ { 0xc0, 0x64 },
+ { 0xc1, 0x4b },
+ { 0x86, 0x35 },
+ { 0x50, 0x89 },
+ { 0x51, 0xc8 },
+ { 0x52, 0x96 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x00 },
+ { 0x57, 0x00 },
+ { 0x5a, 0x50 },
+ { 0x5b, 0x3c },
+ { 0x5c, 0x00 },
+ { 0xe0, 0x00 },
+ { 0xff, 0xff },
+};
+
+/* JPG 352x288 */
+const struct sensor_reg OV2640_352x288_JPEG[] PROGMEM =
+{
+ { 0xff, 0x01 },
+ { 0x12, 0x40 },
+ { 0x17, 0x11 },
+ { 0x18, 0x43 },
+ { 0x19, 0x00 },
+ { 0x1a, 0x4b },
+ { 0x32, 0x09 },
+ { 0x4f, 0xca },
+ { 0x50, 0xa8 },
+ { 0x5a, 0x23 },
+ { 0x6d, 0x00 },
+ { 0x39, 0x12 },
+ { 0x35, 0xda },
+ { 0x22, 0x1a },
+ { 0x37, 0xc3 },
+ { 0x23, 0x00 },
+ { 0x34, 0xc0 },
+ { 0x36, 0x1a },
+ { 0x06, 0x88 },
+ { 0x07, 0xc0 },
+ { 0x0d, 0x87 },
+ { 0x0e, 0x41 },
+ { 0x4c, 0x00 },
+ { 0xff, 0x00 },
+ { 0xe0, 0x04 },
+ { 0xc0, 0x64 },
+ { 0xc1, 0x4b },
+ { 0x86, 0x35 },
+ { 0x50, 0x89 },
+ { 0x51, 0xc8 },
+ { 0x52, 0x96 },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x00 },
+ { 0x57, 0x00 },
+ { 0x5a, 0x58 },
+ { 0x5b, 0x48 },
+ { 0x5c, 0x00 },
+ { 0xe0, 0x00 },
+ { 0xff, 0xff },
+};
+
+/* JPG 640x480 */
+const struct sensor_reg OV2640_640x480_JPEG[] PROGMEM =
+{
+ { 0xff, 0x01 },
+ { 0x11, 0x01 },
+ { 0x12, 0x00 }, // Bit[6:4]: Resolution selection//0x02
+ { 0x17, 0x11 }, // HREFST[10:3]
+ { 0x18, 0x75 }, // HREFEND[10:3]
+ { 0x32, 0x36 }, // Bit[5:3]: HREFEND[2:0]; Bit[2:0]: HREFST[2:0]
+ { 0x19, 0x01 }, // VSTRT[9:2]
+ { 0x1a, 0x97 }, // VEND[9:2]
+ { 0x03, 0x0f }, // Bit[3:2]: VEND[1:0]; Bit[1:0]: VSTRT[1:0]
+ { 0x37, 0x40 },
+ { 0x4f, 0xbb },
+ { 0x50, 0x9c },
+ { 0x5a, 0x57 },
+ { 0x6d, 0x80 },
+ { 0x3d, 0x34 },
+ { 0x39, 0x02 },
+ { 0x35, 0x88 },
+ { 0x22, 0x0a },
+ { 0x37, 0x40 },
+ { 0x34, 0xa0 },
+ { 0x06, 0x02 },
+ { 0x0d, 0xb7 },
+ { 0x0e, 0x01 },
+
+ { 0xff, 0x00 },
+ { 0xe0, 0x04 },
+ { 0xc0, 0xc8 },
+ { 0xc1, 0x96 },
+ { 0x86, 0x3d },
+ { 0x50, 0x89 },
+ { 0x51, 0x90 },
+ { 0x52, 0x2c },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x88 },
+ { 0x57, 0x00 },
+ { 0x5a, 0xa0 },
+ { 0x5b, 0x78 },
+ { 0x5c, 0x00 },
+ { 0xd3, 0x04 },
+ { 0xe0, 0x00 },
+
+ { 0xff, 0xff },
+};
+
+/* JPG 800x600 */
+const struct sensor_reg OV2640_800x600_JPEG[] PROGMEM =
+{
+ { 0xff, 0x01 },
+ { 0x11, 0x01 },
+ { 0x12, 0x00 }, // Bit[6:4]: Resolution selection//0x02为彩æ¡
+ { 0x17, 0x11 }, // HREFST[10:3]
+ { 0x18, 0x75 }, // HREFEND[10:3]
+ { 0x32, 0x36 }, // Bit[5:3]: HREFEND[2:0]; Bit[2:0]: HREFST[2:0]
+ { 0x19, 0x01 }, // VSTRT[9:2]
+ { 0x1a, 0x97 }, // VEND[9:2]
+ { 0x03, 0x0f }, // Bit[3:2]: VEND[1:0]; Bit[1:0]: VSTRT[1:0]
+ { 0x37, 0x40 },
+ { 0x4f, 0xbb },
+ { 0x50, 0x9c },
+ { 0x5a, 0x57 },
+ { 0x6d, 0x80 },
+ { 0x3d, 0x34 },
+ { 0x39, 0x02 },
+ { 0x35, 0x88 },
+ { 0x22, 0x0a },
+ { 0x37, 0x40 },
+ { 0x34, 0xa0 },
+ { 0x06, 0x02 },
+ { 0x0d, 0xb7 },
+ { 0x0e, 0x01 },
+
+ { 0xff, 0x00 },
+ { 0xe0, 0x04 },
+ { 0xc0, 0xc8 },
+ { 0xc1, 0x96 },
+ { 0x86, 0x35 },
+ { 0x50, 0x89 },
+ { 0x51, 0x90 },
+ { 0x52, 0x2c },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x88 },
+ { 0x57, 0x00 },
+ { 0x5a, 0xc8 },
+ { 0x5b, 0x96 },
+ { 0x5c, 0x00 },
+ { 0xd3, 0x02 },
+ { 0xe0, 0x00 },
+
+ { 0xff, 0xff },
+};
+
+/* JPG 1024x768 */
+const struct sensor_reg OV2640_1024x768_JPEG[] PROGMEM =
+{
+ { 0xff, 0x01 },
+ { 0x11, 0x01 },
+ { 0x12, 0x00 }, // Bit[6:4]: Resolution selection//0x02为彩æ¡
+ { 0x17, 0x11 }, // HREFST[10:3]
+ { 0x18, 0x75 }, // HREFEND[10:3]
+ { 0x32, 0x36 }, // Bit[5:3]: HREFEND[2:0]; Bit[2:0]: HREFST[2:0]
+ { 0x19, 0x01 }, // VSTRT[9:2]
+ { 0x1a, 0x97 }, // VEND[9:2]
+ { 0x03, 0x0f }, // Bit[3:2]: VEND[1:0]; Bit[1:0]: VSTRT[1:0]
+ { 0x37, 0x40 },
+ { 0x4f, 0xbb },
+ { 0x50, 0x9c },
+ { 0x5a, 0x57 },
+ { 0x6d, 0x80 },
+ { 0x3d, 0x34 },
+ { 0x39, 0x02 },
+ { 0x35, 0x88 },
+ { 0x22, 0x0a },
+ { 0x37, 0x40 },
+ { 0x34, 0xa0 },
+ { 0x06, 0x02 },
+ { 0x0d, 0xb7 },
+ { 0x0e, 0x01 },
+
+ { 0xff, 0x00 },
+ { 0xc0, 0xC8 },
+ { 0xc1, 0x96 },
+ { 0x8c, 0x00 },
+ { 0x86, 0x3D },
+ { 0x50, 0x00 },
+ { 0x51, 0x90 },
+ { 0x52, 0x2C },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x88 },
+ { 0x5a, 0x00 },
+ { 0x5b, 0xC0 },
+ { 0x5c, 0x01 },
+ { 0xd3, 0x02 },
+
+
+ { 0xff, 0xff },
+};
+
+/* JPG 1280x1024 */
+const struct sensor_reg OV2640_1280x1024_JPEG[] PROGMEM =
+{
+ { 0xff, 0x01 },
+ { 0x11, 0x01 },
+ { 0x12, 0x00 }, // Bit[6:4]: Resolution selection//0x02
+ { 0x17, 0x11 }, // HREFST[10:3]
+ { 0x18, 0x75 }, // HREFEND[10:3]
+ { 0x32, 0x36 }, // Bit[5:3]: HREFEND[2:0]; Bit[2:0]: HREFST[2:0]
+ { 0x19, 0x01 }, // VSTRT[9:2]
+ { 0x1a, 0x97 }, // VEND[9:2]
+ { 0x03, 0x0f }, // Bit[3:2]: VEND[1:0]; Bit[1:0]: VSTRT[1:0]
+ { 0x37, 0x40 },
+ { 0x4f, 0xbb },
+ { 0x50, 0x9c },
+ { 0x5a, 0x57 },
+ { 0x6d, 0x80 },
+ { 0x3d, 0x34 },
+ { 0x39, 0x02 },
+ { 0x35, 0x88 },
+ { 0x22, 0x0a },
+ { 0x37, 0x40 },
+ { 0x34, 0xa0 },
+ { 0x06, 0x02 },
+ { 0x0d, 0xb7 },
+ { 0x0e, 0x01 },
+
+ { 0xff, 0x00 },
+ { 0xe0, 0x04 },
+ { 0xc0, 0xc8 },
+ { 0xc1, 0x96 },
+ { 0x86, 0x3d },
+ { 0x50, 0x00 },
+ { 0x51, 0x90 },
+ { 0x52, 0x2c },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x88 },
+ { 0x57, 0x00 },
+ { 0x5a, 0x40 },
+ { 0x5b, 0xf0 },
+ { 0x5c, 0x01 },
+ { 0xd3, 0x02 },
+ { 0xe0, 0x00 },
+
+ { 0xff, 0xff },
+};
+
+/* JPG 1600x1200 */
+const struct sensor_reg OV2640_1600x1200_JPEG[] PROGMEM =
+{
+ { 0xff, 0x01 },
+ { 0x11, 0x01 },
+ { 0x12, 0x00 }, // Bit[6:4]: Resolution selection//0x02为
+ { 0x17, 0x11 }, // HREFST[10:3]
+ { 0x18, 0x75 }, // HREFEND[10:3]
+ { 0x32, 0x36 }, // Bit[5:3]: HREFEND[2:0]; Bit[2:0]: HREFST[2:0]
+ { 0x19, 0x01 }, // VSTRT[9:2]
+ { 0x1a, 0x97 }, // VEND[9:2]
+ { 0x03, 0x0f }, // Bit[3:2]: VEND[1:0]; Bit[1:0]: VSTRT[1:0]
+ { 0x37, 0x40 },
+ { 0x4f, 0xbb },
+ { 0x50, 0x9c },
+ { 0x5a, 0x57 },
+ { 0x6d, 0x80 },
+ { 0x3d, 0x34 },
+ { 0x39, 0x02 },
+ { 0x35, 0x88 },
+ { 0x22, 0x0a },
+ { 0x37, 0x40 },
+ { 0x34, 0xa0 },
+ { 0x06, 0x02 },
+ { 0x0d, 0xb7 },
+ { 0x0e, 0x01 },
+
+ { 0xff, 0x00 },
+ { 0xe0, 0x04 },
+ { 0xc0, 0xc8 },
+ { 0xc1, 0x96 },
+ { 0x86, 0x3d },
+ { 0x50, 0x00 },
+ { 0x51, 0x90 },
+ { 0x52, 0x2c },
+ { 0x53, 0x00 },
+ { 0x54, 0x00 },
+ { 0x55, 0x88 },
+ { 0x57, 0x00 },
+ { 0x5a, 0x90 },
+ { 0x5b, 0x2C },
+ { 0x5c, 0x05 }, //bit2->1;bit[1:0]->1
+ { 0xd3, 0x02 },
+ { 0xe0, 0x00 },
+
+ { 0xff, 0xff },
+};
diff --git a/Firmware_V2/src/hardware/camera/ov2640regs.h b/Firmware_V2/src/hardware/camera/ov2640regs.h
new file mode 100644
index 0000000..b0dd57f
--- /dev/null
+++ b/Firmware_V2/src/hardware/camera/ov2640regs.h
@@ -0,0 +1,36 @@
+/*
+ *
+ * OV2640Regs - Register for the Arducam camera module
+ *
+ * DIY-Thermocam Firmware
+ *
+ * GNU General Public License v3.0
+ *
+ * Copyright by Max Ritter
+ *
+ * http://www.diy-thermocam.net
+ * https://github.com/maxritter/DIY-Thermocam
+ *
+ */
+
+#ifndef OV2640_REGS_H
+#define OV2640_REGS_H
+
+/*################# PUBLIC CONSTANTS, VARIABLES & DATA TYPES ##################*/
+
+extern const uint8_t exifHeader_rotated[];
+extern const struct sensor_reg OV2640_QVGA[] PROGMEM;
+extern const struct sensor_reg OV2640_JPEG_INIT[] PROGMEM;
+extern const struct sensor_reg OV2640_YUV422[] PROGMEM;
+extern const struct sensor_reg OV2640_JPEG[] PROGMEM;
+extern const struct sensor_reg OV2640_160x120_JPEG[] PROGMEM;
+extern const struct sensor_reg OV2640_176x144_JPEG[] PROGMEM;
+extern const struct sensor_reg OV2640_320x240_JPEG[] PROGMEM;
+extern const struct sensor_reg OV2640_352x288_JPEG[] PROGMEM;
+extern const struct sensor_reg OV2640_640x480_JPEG[] PROGMEM;
+extern const struct sensor_reg OV2640_800x600_JPEG[] PROGMEM;
+extern const struct sensor_reg OV2640_1024x768_JPEG[] PROGMEM;
+extern const struct sensor_reg OV2640_1280x1024_JPEG[] PROGMEM;
+extern const struct sensor_reg OV2640_1600x1200_JPEG[] PROGMEM;
+
+#endif /* OV2640_REGS_H */
diff --git a/Firmware_V2/src/hardware/camera/vc0706.cpp b/Firmware_V2/src/hardware/camera/vc0706.cpp
new file mode 100644
index 0000000..e09955b
--- /dev/null
+++ b/Firmware_V2/src/hardware/camera/vc0706.cpp
@@ -0,0 +1,379 @@
+/*
+*
+* VC0706 - Driver for the PTC-06 or PTC-08 camera module
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*######################### STATIC DATA DECLARATIONS ##########################*/
+
+static uint8_t serialNum = 0;
+static uint8_t camerabuff[101];
+static uint8_t bufferLen = 0;
+static uint16_t frameptr = 0;
+
+//EXIF header for horizontal mirror in ThermocamV4
+static const uint8_t exifHeader_mirror[] =
+{ 0xFF, 0xE1, 0x00, 0x62, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00, 0x4D, 0x4D, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x08,
+0x00, 0x05, 0x01, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x1A, 0x00, 0x05,
+0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4A, 0x01, 0x1B, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+0x00, 0x52, 0x01, 0x28, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x02, 0x13, 0x00, 0x03,
+0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00,
+0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01 };
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* Send a specific command */
+void vc0706_sendCommand(uint8_t cmd, uint8_t args[], uint8_t argn) {
+ Serial1.print(0x56, 0);
+ Serial1.print(serialNum, 0);
+ Serial1.print(cmd, 0);
+
+ for (uint8_t i = 0; i < argn; i++) {
+ Serial1.print(args[i], 0);
+ }
+}
+
+/* Read the response from the camera */
+uint8_t vc0706_readResponse(uint8_t numbytes, uint8_t timeout) {
+ uint8_t counter = 0;
+ bufferLen = 0;
+ int avail;
+ while ((timeout != counter) && (bufferLen != numbytes)) {
+ avail = Serial1.available();
+ if (avail <= 0) {
+ delay(1);
+ counter++;
+ continue;
+ }
+ counter = 0;
+ camerabuff[bufferLen++] = Serial1.read();
+ }
+ return bufferLen;
+}
+
+/* Verify the response from the camera */
+boolean vc0706_verifyResponse(uint8_t command) {
+ if ((camerabuff[0] != 0x76) ||
+ (camerabuff[1] != serialNum) ||
+ (camerabuff[2] != command) ||
+ (camerabuff[3] != 0x0))
+ return 0;
+ return 1;
+}
+
+/* Run a specific command */
+boolean vc0706_runCommand(uint8_t cmd, uint8_t *args, uint8_t argn, uint8_t resplen, boolean flushflag) {
+ if (flushflag) {
+ vc0706_readResponse(100, 10);
+ }
+ vc0706_sendCommand(cmd, args, argn);
+ if (vc0706_readResponse(resplen, 200) != resplen)
+ return 0;
+ if (!vc0706_verifyResponse(cmd))
+ return 0;
+ return 1;
+}
+
+/* Reset the connection */
+boolean vc0706_reset(void)
+{
+ uint8_t args[] = { 0x0 };
+ return vc0706_runCommand(0x26, args, 1, 5);
+}
+
+/* End the connection */
+boolean vc0706_end() {
+ uint8_t args[] = { 0x01, 0x03 };
+ return vc0706_runCommand(0x36, args, sizeof(args), 5);
+}
+
+
+/* Change the baudrate */
+boolean vc0706_changeBaudRate() {
+ uint8_t args[] = { 0x03, 0x01, 0x0D, 0xA6 };
+ return vc0706_runCommand(0x24, args, sizeof(args), 5);
+}
+
+/* Set the image size */
+boolean vc0706_setImageSize(uint8_t x) {
+ uint8_t args[] = { 0x05, 0x04, 0x01, 0x00, 0x19, x };
+ return vc0706_runCommand(0x31, args, sizeof(args), 5);
+}
+
+/* Get the image size */
+uint8_t vc0706_getImageSize() {
+ uint8_t args[] = { 0x4, 0x4, 0x1, 0x00, 0x19 };
+ if (!vc0706_runCommand(0x30, args, sizeof(args), 6))
+ return -1;
+ return camerabuff[5];
+}
+
+/* Set the compression ratio */
+boolean vc0706_setCompression(uint8_t c) {
+ uint8_t args[] = { 0x5, 0x1, 0x1, 0x12, 0x04, c };
+ return vc0706_runCommand(0x31, args, sizeof(args), 5);
+}
+
+/* Transfer a package from the VC0706 camera */
+void vc0706_transPackage(byte bytesToRead, uint8_t* buffer)
+{
+ int avail;
+ //Send counter and buffer length to zero
+ uint8_t counter = 0;
+ uint8_t bufferLen = 0;
+ //As long as no timeout and not all bytes read
+ while ((10 != counter) && (bufferLen != (bytesToRead + 5))) {
+ //Check how many bytes are available
+ avail = Serial1.available();
+ //If there are none, raise timeout counter
+ if (avail <= 0) {
+ delay(1);
+ counter++;
+ continue;
+ }
+ //Reset timeout counter if there is a packet
+ counter = 0;
+ //Add the data to the buffer
+ buffer[bufferLen++] = Serial1.read();
+ }
+}
+
+/* Control the framebuffer */
+boolean vc0706_cameraFrameBuffCtrl(uint8_t command) {
+ uint8_t args[] = { 0x1, command };
+ return vc0706_runCommand(0x36, args, sizeof(args), 5);
+}
+
+/* Take a picture */
+boolean vc0706_capture() {
+ frameptr = 0;
+ return vc0706_cameraFrameBuffCtrl(0x0);
+}
+
+/* Get the JPEG frame length */
+uint32_t vc0706_frameLength(void) {
+ uint8_t args[] = { 0x01, 0x00 };
+ if (!vc0706_runCommand(0x34, args, sizeof(args), 9))
+ return 0;
+ uint32_t len;
+ len = camerabuff[5];
+ len <<= 8;
+ len |= camerabuff[6];
+ len <<= 8;
+ len |= camerabuff[7];
+ len <<= 8;
+ len |= camerabuff[8];
+ return len;
+}
+
+/* Check if data is available */
+uint8_t vc0706_available(void) {
+ return bufferLen;
+}
+
+/* Read the JPEG picture */
+boolean vc0706_readPicture(uint8_t n) {
+ uint8_t args[] = { 0x0C, 0x0, 0x0A,
+ 0, 0, (uint8_t)(frameptr >> 8), (uint8_t)(frameptr & 0xFF),
+ 0, 0, 0, n,
+ 10 >> 8, 10 & 0xFF };
+
+ if (!vc0706_runCommand(0x32, args, sizeof(args), 5, 0))
+ return 0;
+ frameptr += n;
+ return 1;
+}
+
+/* Transfer the JPEG bytestream*/
+void vc0706_transfer(uint8_t* jpegData, uint16_t jpegLen, byte mode, char* dirname)
+{
+ //Count variable
+ uint16_t counter = 0;
+
+ //Create the buffer
+ uint8_t* buffer = (uint8_t*)malloc(128 + 5);
+
+ //For serial transfer, send frame length
+ if (mode == camera_serial)
+ {
+ //When rotation is enabled or using the ThermocamV4, send EXIF
+ if ((rotationVert && (mlx90614Version == mlx90614Version_new)) || (mlx90614Version == mlx90614Version_old))
+ {
+ Serial.write(((jpegLen + 100) & 0xFF00) >> 8);
+ Serial.write((jpegLen + 100) & 0x00FF);
+ }
+ //Send JPEG Bytestream only
+ else
+ {
+ Serial.write((jpegLen & 0xFF00) >> 8);
+ Serial.write(jpegLen & 0x00FF);
+ }
+ }
+
+ //For saving to SD card
+ if (mode == camera_save)
+ {
+ //Start alternative clock line
+ startAltClockline();
+ //Create JPEG file
+ createJPEGFile(dirname);
+ }
+
+ //Transfer data
+ while (jpegLen > 0) {
+ //Calculate the bytes left to read
+ uint8_t bytesToRead = min(jpegLen, 128);
+
+ //Send the read command
+ if (!vc0706_readPicture(bytesToRead))
+ continue;
+
+ //Transfer a package
+ vc0706_transPackage(bytesToRead, buffer);
+
+ //For streaming, add it to the jpeg data buffer
+ if (mode == camera_stream)
+ {
+ for (int i = 0; i < bytesToRead; i++) {
+ jpegData[counter] = buffer[i];
+ counter++;
+ }
+ }
+
+ //For serial transfer
+ if (mode == camera_serial)
+ {
+ //Rotation on DIY-Thermocam V1 or V2
+ if ((counter == 0) && rotationVert && (mlx90614Version == mlx90614Version_new))
+ {
+ Serial.write(buffer, 40);
+ Serial.write(exifHeader_rotated, 100);
+ Serial.write(&buffer[40], (bytesToRead - 40));
+ counter++;
+ }
+ //Mirror on ThermocamV4
+ else if ((counter == 0) && (mlx90614Version == mlx90614Version_old))
+ {
+ Serial.write(buffer, 40);
+ Serial.write(exifHeader_mirror, sizeof(exifHeader_mirror));
+ Serial.write(&buffer[40], (bytesToRead - 40));
+ counter++;
+ }
+ //No EXIF
+ else
+ Serial.write(buffer, bytesToRead);
+ }
+
+ //For saving to SD card
+ if (mode == camera_save)
+ {
+ //Rotation on DIY-Thermocam V1 or V2
+ if ((counter == 0) && rotationVert && (mlx90614Version == mlx90614Version_new))
+ {
+ sdFile.write(buffer, 40);
+ sdFile.write(exifHeader_rotated, 100);
+ sdFile.write(&buffer[40], (bytesToRead - 40));
+ counter++;
+ }
+ //Mirror on ThermocamV4
+ else if ((counter == 0) && (mlx90614Version == mlx90614Version_old))
+ {
+ sdFile.write(buffer, 40);
+ sdFile.write(exifHeader_mirror, sizeof(exifHeader_mirror));
+ sdFile.write(&buffer[40], (bytesToRead - 40));
+ counter++;
+ }
+ //No EXIF
+ else
+ sdFile.write(buffer, bytesToRead);
+ }
+
+ //Substract transfered bytes from total
+ jpegLen -= bytesToRead;
+ }
+
+ //Free the buffer
+ free(buffer);
+
+ //End transmission
+ vc0706_end();
+
+ //For saving to SD, close file
+ if (mode == camera_save)
+ {
+ //Close the file
+ sdFile.close();
+ //End SD Transmission
+ endAltClockline();
+ }
+}
+
+/* Start connecting to the camera */
+void vc0706_begin(void) {
+ //Start with 38400 to send new baudrate
+ Serial1.begin(38400);
+ //Wait
+ delay(15);
+ //Change baudrate
+ vc0706_changeBaudRate();
+ //Reconnect using 115.2k
+ Serial1.begin(115200);
+ //Wait
+ delay(15);
+}
+
+/* Init the camera module */
+boolean vc0706_init(void)
+{
+ //Start connection at 115.2k Baud
+ vc0706_begin();
+ //Test if the camera works
+ if (!vc0706_capture()) {
+ //Try it again after 100ms
+ delay(100);
+ //Reset
+ vc0706_reset();
+ //Restart connection at 115.2k Baud
+ vc0706_begin();
+ //Try to take a picture again
+ if (!vc0706_capture())
+ return 0;
+ }
+ //Set compression
+ vc0706_setCompression(95);
+ //Skip the picture
+ vc0706_end();
+ //Everything working
+ return 1;
+}
+
+/* Change the resolution of the device */
+void vc0706_changeCamRes(uint8_t size) {
+ //Change resolution
+ vc0706_setImageSize(size);
+ //Reset the device to change the resolution
+ vc0706_reset();
+ //Wait some time
+ delay(300);
+ //Re-establish the connection to the device
+ vc0706_begin();
+}
diff --git a/Firmware_V2/src/hardware/camera/vc0706.h b/Firmware_V2/src/hardware/camera/vc0706.h
new file mode 100644
index 0000000..aec3e59
--- /dev/null
+++ b/Firmware_V2/src/hardware/camera/vc0706.h
@@ -0,0 +1,56 @@
+/*
+*
+* VC0706 - Driver for the PTC-06 or PTC-08 camera module
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef VC0706_H
+#define VC0706_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*################# PUBLIC CONSTANTS, VARIABLES & DATA TYPES ##################*/
+
+#define VC0706_640x480 0x00
+#define VC0706_320x240 0x11
+#define VC0706_160x120 0x22
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+uint8_t vc0706_available(void);
+void vc0706_begin(void);
+boolean vc0706_cameraFrameBuffCtrl(uint8_t command);
+boolean vc0706_capture();
+boolean vc0706_changeBaudRate();
+void vc0706_changeCamRes(uint8_t size);
+boolean vc0706_end();
+uint32_t vc0706_frameLength(void);
+uint8_t vc0706_getImageSize();
+boolean vc0706_init(void);
+boolean vc0706_readPicture(uint8_t n);
+uint8_t vc0706_readResponse(uint8_t numbytes, uint8_t timeout);
+boolean vc0706_reset(void);
+boolean vc0706_runCommand(uint8_t cmd, uint8_t *args, uint8_t argn, uint8_t resplen, boolean flushflag = 1);
+void vc0706_sendCommand(uint8_t cmd, uint8_t args[] = 0, uint8_t argn = 0);
+boolean vc0706_setCompression(uint8_t c);
+boolean vc0706_setImageSize(uint8_t x);
+void vc0706_transfer(uint8_t* jpegData, uint16_t jpegLen, byte mode, char* dirname);
+void vc0706_transPackage(byte bytesToRead, uint8_t* buffer);
+boolean vc0706_verifyResponse(uint8_t command);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VC0706_H */
diff --git a/Firmware_V2/src/hardware/connection.cpp b/Firmware_V2/src/hardware/connection.cpp
new file mode 100644
index 0000000..2d30a19
--- /dev/null
+++ b/Firmware_V2/src/hardware/connection.cpp
@@ -0,0 +1,1232 @@
+/*
+*
+* CONNECTION - Communication protocol for the USB serial data transmission
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*######################### STATIC DATA DECLARATIONS ##########################*/
+
+//Command, default send frame
+static byte sendCmd = FRAME_NORMAL;
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* Get integer out of a text string */
+int getInt(String text)
+{
+ char temp[6];
+ text.toCharArray(temp, 5);
+ int x = atoi(temp);
+ return x;
+}
+
+/* Enter the serial connection mode if no display attached */
+bool checkNoDisplay()
+{
+ //No connection to ILI9341 and touch screen -> go to USB serial
+ if (!checkDiagnostic(diag_display) && !checkDiagnostic(diag_touch))
+ return true;
+ //Display connected
+ return false;
+}
+
+/* Send the lepton raw limits */
+void sendRawLimits() {
+ //Send min
+ Serial.write((minValue & 0xFF00) >> 8);
+ Serial.write(minValue & 0x00FF);
+ //Send max
+ Serial.write((maxValue & 0xFF00) >> 8);
+ Serial.write(maxValue & 0x00FF);
+}
+
+/* Send the lepton raw data*/
+void sendRawData(bool color) {
+ uint16_t result;
+
+ //For the Lepton2.x sensor, write 4800 raw values
+ if ((leptonVersion != leptonVersion_3_0_shutter) && (leptonVersion != leptonVersion_3_5_shutter) && (!color)) {
+ for (int line = 0; line < 60; line++) {
+ for (int column = 0; column < 80; column++) {
+ result = smallBuffer[(line * 2 * 160) + (column * 2)];
+ Serial.write((result & 0xFF00) >> 8);
+ Serial.write(result & 0x00FF);
+ }
+ }
+ }
+ //For the Lepton3 sensor, write 19200 raw values
+ else {
+ for (int i = 0; i < 19200; i++) {
+ Serial.write((smallBuffer[i] & 0xFF00) >> 8);
+ Serial.write(smallBuffer[i] & 0x00FF);
+ }
+ }
+}
+
+/* Sends the framebuffer */
+void sendFramebuffer()
+{
+ //160x120
+ if ((teensyVersion == teensyVersion_old) || (!hqRes))
+ {
+ for (int i = 0; i < 19200; i++)
+ {
+ Serial.write((smallBuffer[i] & 0xFF00) >> 8);
+ Serial.write(smallBuffer[i] & 0x00FF);
+ }
+ }
+
+ //320x240
+ else
+ {
+ for (uint32_t i = 0; i < 76800; i++)
+ {
+ Serial.write((bigBuffer[i] & 0xFF00) >> 8);
+ Serial.write(bigBuffer[i] & 0x00FF);
+ }
+ }
+}
+
+/* Sends the configuration data */
+void sendConfigData() {
+ //Lepton version
+ if (leptonVersion == leptonVersion_2_5_shutter)
+ Serial.write(leptonVersion_2_0_shutter);
+ else if (leptonVersion == leptonVersion_3_5_shutter)
+ Serial.write(leptonVersion_3_0_shutter);
+ else
+ Serial.write(leptonVersion);
+ //Rotation
+ Serial.write(rotationVert);
+ //Send color scheme
+ Serial.write(colorScheme);
+ //Send the temperature format
+ Serial.write(tempFormat);
+ //Send the show spot attribute
+ Serial.write(spotEnabled);
+ //Send the show colorbar attribute
+ Serial.write(colorbarEnabled);
+ //Send the show hottest / coldest attribute
+ Serial.write(minMaxPoints);
+ //Send the text color
+ Serial.write(textColor);
+ //Send the filter type
+ Serial.write(filterType);
+ //Send adjust limits allowed
+ Serial.write((autoMode) && (!limitsLocked));
+}
+
+/* Sends the calibration status */
+void sendCalStatus() {
+ //Send status byte
+ Serial.write(calStatus);
+ //Send remaining seconds left
+ if (calStatus == cal_warmup)
+ Serial.write((byte)abs(30 - ((millis() - calTimer) / 1000)));
+ else
+ Serial.write(0);
+}
+
+/* Sends the visual image in low or high quality */
+void sendVisualImg()
+{
+ bool high;
+
+ //If not enough data available, leave
+ if (Serial.available() < 1)
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Read byte from serial port
+ byte read = Serial.read();
+ //Check if it has a valid number
+ if ((read >= 0) && (read <= 1))
+ high = read;
+ //Send invalid
+ else
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Only when camera is working
+ if (checkDiagnostic(diag_camera)) {
+
+ //Change resolution to 320x240 for serial streaming
+ if ((!high) && (camera_resolution != camera_resMiddle))
+ camera_setStreamRes();
+
+ //Change resolution to 640x480 for snapshots
+ if ((high) && (camera_resolution != camera_resHigh))
+ camera_setSaveRes();
+
+ //Capture a frame
+ camera_capture();
+
+ //Send the data over the serial port
+ camera_get(camera_serial);
+ }
+
+ //Send invalid
+ else
+ Serial.write(CMD_INVALID);
+}
+
+/* Sends the calibration data */
+void sendCalibrationData() {
+ uint8_t farray[4];
+
+ //Send the calibration offset first
+ floatToBytes(farray, (float)calOffset);
+ for (int i = 0; i < 4; i++)
+ Serial.write(farray[i]);
+ //Send the calibration slope
+ floatToBytes(farray, (float)calSlope);
+ for (int i = 0; i < 4; i++)
+ Serial.write(farray[i]);
+}
+
+/* Sends the spot temp*/
+void sendSpotTemp() {
+ //Array to store the byte-converted float value
+ uint8_t farray[4];
+
+ //Convert float to bytes
+ floatToBytes(farray, spotTemp);
+
+ //Send the four bytes out
+ for (int i = 0; i < 4; i++)
+ Serial.write(farray[i]);
+}
+
+/* Sets the time */
+void setTime() {
+ //Wait for time string, maximum 1 second
+ uint32_t timer = millis();
+ while (!Serial.available() && ((millis() - timer) < 1000));
+
+ //If there was no timestring
+ if (Serial.available() == 0)
+ {
+ //Send ACK and return
+ Serial.write(CMD_SET_TIME);
+ return;
+ }
+
+ //Read time
+ String dateIn = Serial.readString();
+
+ //Check if valid
+ if (getInt(dateIn.substring(0, 4) >= 2017)) {
+ //Set the clock
+ setTime(getInt(dateIn.substring(11, 13)), getInt(dateIn.substring(14, 16)), getInt(dateIn.substring(17, 19)),
+ getInt(dateIn.substring(8, 10)), getInt(dateIn.substring(5, 7)), getInt(dateIn.substring(0, 4)));
+ //Set the RTC
+ Teensy3Clock.set(now());
+ }
+
+ //Send ACK
+ Serial.write(CMD_SET_TIME);
+}
+
+/* Sets the calibration offset */
+void setCalOffset() {
+ uint8_t farray[4];
+
+ //If not enough data available or RAD, leave
+ if ((Serial.available() < 4) || (leptonVersion == leptonVersion_2_5_shutter) || (leptonVersion == leptonVersion_3_5_shutter))
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Read calibration offset
+ for (int i = 0; i < 4; i++)
+ farray[i] = Serial.read();
+ calOffset = bytesToFloat(farray);
+
+ //Store to EEPROM
+ storeCalibration();
+
+ //Send ACK
+ Serial.write(CMD_SET_CALOFFSET);
+}
+
+/* Sets the calibration slope */
+void setCalSlope() {
+ uint8_t farray[4];
+
+ //If not enough data available or RAD, leave
+ if ((Serial.available() < 4) || (leptonVersion == leptonVersion_2_5_shutter) || (leptonVersion == leptonVersion_3_5_shutter))
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Read calibration slope
+ for (int i = 0; i < 4; i++)
+ farray[i] = Serial.read();
+ calSlope = bytesToFloat(farray);
+
+ //Store to EEPROM
+ storeCalibration();
+
+ //Send ACK
+ Serial.write(CMD_SET_CALSLOPE);
+}
+
+/* Send the temperature points */
+void sendTempPoints() {
+ for (byte i = 0; i < 96; i++) {
+ //Send index value
+ Serial.write((tempPoints[i][0] & 0xFF00) >> 8);
+ Serial.write(tempPoints[i][0] & 0x00FF);
+ //Send raw value
+ Serial.write((tempPoints[i][1] & 0xFF00) >> 8);
+ Serial.write(tempPoints[i][1] & 0x00FF);
+ }
+}
+
+/* Send the laser state */
+void sendLaserState() {
+ Serial.write(laserEnabled);
+}
+
+/* Send the shutter mode */
+void sendShutterMode() {
+ Serial.write(leptonShutter);
+}
+
+/* Send the battery status in percentage */
+void sendBatteryStatus() {
+ Serial.write(batPercentage);
+}
+
+/* Send the current firmware version */
+void sendFWVersion() {
+ Serial.write(fwVersion);
+}
+
+/* Set the temperature limits */
+void setLimits()
+{
+ //If not enough data available, leave
+ if (Serial.available() < 1)
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Read byte from serial port
+ byte read = Serial.read();
+
+ //Check if it has a valid number
+ if ((read >= 0) && (read <= 1))
+ {
+ //Lock limits
+ if (read == 0)
+ limitsLocked = true;
+
+ //Auto mode
+ else {
+ //Enable auto mode
+ autoMode = true;
+ //Disable limits locked
+ limitsLocked = false;
+ }
+ }
+ //Send invalid
+ else
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Send ACK
+ Serial.write(CMD_SET_LIMITS);
+}
+
+/* Set the text color */
+void setTextColor()
+{
+ //If not enough data available, leave
+ if (Serial.available() < 1)
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Read byte from serial port
+ byte read = Serial.read();
+
+ //Check if read result is valid
+ if ((read >= textColor_white) && (read <= textColor_blue))
+ {
+ //Set text color to input
+ textColor = read;
+ //Change it
+ changeTextColor();
+ //Save to EEPROM
+ EEPROM.write(eeprom_textColor, textColor);
+ }
+ //Send invalid
+ else
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Send ACK
+ Serial.write(CMD_SET_TEXTCOLOR);
+}
+
+/* Set the color scheme */
+void setColorScheme()
+{
+ //If not enough data available, leave
+ if (Serial.available() < 1)
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Read byte from serial port
+ byte read = Serial.read();
+
+ //Check if it has a valid number
+ if ((read >= 0) && (read <= (colorSchemeTotal - 1)))
+ {
+ //Set color scheme to input
+ colorScheme = read;
+ //Select right color scheme
+ selectColorScheme();
+ //Save to EEPROM
+ EEPROM.write(eeprom_colorScheme, colorScheme);
+ }
+ //Send invalid
+ else
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Send ACK
+ Serial.write(CMD_SET_COLORSCHEME);
+}
+
+
+/* Set the temperature format */
+void setTempFormat()
+{
+ //If not enough data available, leave
+ if (Serial.available() < 1)
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Read byte from serial port
+ byte read = Serial.read();
+
+ //Check if it has a valid number
+ if ((read >= 0) && (read <= 1))
+ {
+ //Set temperature format to input
+ tempFormat = read;
+ //Save to EEPROM
+ EEPROM.write(eeprom_tempFormat, tempFormat);
+ }
+ //Send invalid
+ else
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Send ACK
+ Serial.write(CMD_SET_TEMPFORMAT);
+}
+
+/* Set the show spot information */
+void setShowSpot()
+{
+ //If not enough data available, leave
+ if (Serial.available() < 1)
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Read byte from serial port
+ byte read = Serial.read();
+
+ //Check if it has a valid number
+ if ((read >= 0) && (read <= 1))
+ {
+ //Set show spot to input
+ spotEnabled = read;
+ //Save to EEPROM
+ EEPROM.write(eeprom_spotEnabled, spotEnabled);
+ }
+ //Send invalid
+ else
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Send ACK
+ Serial.write(CMD_SET_SHOWSPOT);
+}
+
+/* Set the show colorbar information */
+void setShowColorbar()
+{
+ //If not enough data available, leave
+ if (Serial.available() < 1)
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Read byte from serial port
+ byte read = Serial.read();
+
+ //Check if it has a valid number
+ if ((read >= 0) && (read <= 1))
+ {
+ //Set show colorbar to input
+ colorbarEnabled = read;
+ //Save to EEPROM
+ EEPROM.write(eeprom_colorbarEnabled, colorbarEnabled);
+ }
+ //Send invalid
+ else
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Send ACK
+ Serial.write(CMD_SET_SHOWCOLORBAR);
+}
+
+/* Set the show colorbar information */
+void setMinMax()
+{
+ //If not enough data available, leave
+ if (Serial.available() < 1)
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Read byte from serial port
+ byte read = Serial.read();
+
+ //Check if it has a valid number
+ if ((read >= minMaxPoints_disabled) && (read <= minMaxPoints_both))
+ {
+ //Set show colorbar to input
+ minMaxPoints = read;
+ //Save to EEPROM
+ EEPROM.write(eeprom_minMaxPoints, minMaxPoints);
+ }
+ //Send invalid
+ else
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Send ACK
+ Serial.write(CMD_SET_SHOWMINMAX);
+}
+
+/* Set the shutter mode */
+void setShutterMode()
+{
+ //If not enough data available, leave
+ if (Serial.available() < 1)
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Read byte from serial port
+ byte read = Serial.read();
+
+ //Check if it has a valid number
+ if ((read >= 0) && (read <= 1))
+ //Set lepton shutter mode
+ lepton_ffcMode(read);
+ //Send invalid
+ else
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Send ACK
+ Serial.write(CMD_SET_SHUTTERMODE);
+}
+
+/* Set the fitler type */
+void setFilterType()
+{
+ //If not enough data available, leave
+ if (Serial.available() < 1)
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Read byte from serial port
+ byte read = Serial.read();
+
+ //Check if it has a valid number
+ if ((read >= filterType_none) && (read <= filterType_box))
+ {
+ //Set filter type to input
+ filterType = read;
+ //Save to EEPROM
+ EEPROM.write(eeprom_filterType, filterType);
+ }
+ //Send invalid
+ else
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Send ACK
+ Serial.write(CMD_SET_FILTERTYPE);
+}
+
+/* Set the rotation */
+void setRotation()
+{
+ //If not enough data available, leave
+ if (Serial.available() < 1)
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Read byte from serial port
+ byte read = Serial.read();
+
+ //Check if it has a valid number
+ if ((read >= 0) && (read <= 1))
+ {
+ //Set rotation to input
+ rotationVert = read;
+ //Apply to display
+ setDisplayRotation();
+ //Save to EEPROM
+ EEPROM.write(eeprom_rotationVert, rotationVert);
+ }
+ //Send invalid
+ else
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Send ACK
+ Serial.write(CMD_SET_ROTATION);
+}
+
+/* Send the hardware version */
+void sendHardwareVersion()
+{
+ //Send hardware version
+ Serial.write(teensyVersion);
+}
+
+/* Send the diagnostic information */
+void sendDiagnostic()
+{
+ //Send the diag byte
+ Serial.write(diagnostic);
+}
+
+/* Send the HQ Resolution information */
+void sendHQResolution()
+{
+ //For the DIY-Thermocam V1, send false
+ if (teensyVersion == teensyVersion_old)
+ Serial.write(0);
+ //For the DIY-Thermocam V2, send the hqRes byte
+ else
+ Serial.write(hqRes);
+}
+
+/* Set temperature points array */
+void setTempPoints()
+{
+ //If not enough data available, leave
+ if (Serial.available() < 384)
+ {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Go through the temp points array
+ for (byte i = 0; i < 96; i++) {
+ //Read index
+ tempPoints[i][0] = (Serial.read() << 8) + Serial.read();
+
+ //Correct old not_set marker
+ if (tempPoints[i][0] == 65535)
+ tempPoints[i][0] = 0;
+
+ //Read value
+ tempPoints[i][1] = (Serial.read() << 8) + Serial.read();
+ }
+
+ //Send ACK
+ Serial.write(CMD_SET_TEMPPOINTS);
+}
+
+/* Sends a raw or color frame */
+void sendFrame(bool color) {
+ //Send type of frame response
+ Serial.write(sendCmd);
+ Serial.flush();
+
+ //Send frame
+ if (sendCmd == FRAME_NORMAL) {
+ //Clear all serial buffers
+ Serial.clear();
+ //Convert to colors
+ if (color) {
+ //Apply low-pass filter
+ if (filterType == filterType_box)
+ boxFilter();
+ else if (filterType == filterType_gaussian)
+ gaussianFilter();
+ //Convert to RGB565
+ convertColors(true);
+ }
+ //Send raw data
+ sendRawData(color);
+
+ //Send limits
+ sendRawLimits();
+ //Send spot temp
+ sendSpotTemp();
+ //Send calibration data
+ sendCalibrationData();
+ }
+ //Switch back to send frame the next time
+ else
+ sendCmd = FRAME_NORMAL;
+}
+
+/* Saves a frame to the internal sd card*/
+void saveFrame() {
+ //ThermocamV4 or DIY-Thermocam V2 - check SD card
+ if (!checkSDCard() || (getSDSpace() < 1000)) {
+ Serial.write(CMD_INVALID);
+ return;
+ }
+
+ //Build save filename from the current time & date
+ createSDName(saveFilename);
+
+ //Capture visual image if enabled
+ if (visualEnabled && (checkDiagnostic(diag_camera)))
+ {
+ //Capture visual frame
+ camera_capture();
+ //Short delay
+ delay(100);
+ //Save visual image in full-res
+ camera_get(camera_save);
+ }
+
+ //Enable image save marker
+ imgSave = imgSave_create;
+
+ //Create image and save raw file
+ createThermalImg();
+
+ //Save Bitmap image if activated
+ if (convertEnabled) {
+ displayInfos();
+ saveBuffer(saveFilename);
+ }
+
+ //Refresh free space
+ refreshFreeSpace();
+
+ //Disable image save marker
+ imgSave = imgSave_disabled;
+
+ //Send ACK
+ Serial.write(CMD_FRAME_SAVE);
+}
+
+/* Sends the display content as frame */
+void sendDisplayFrame() {
+ //Send type of frame response
+ Serial.write(sendCmd);
+ Serial.flush();
+
+ //Send frame
+ if (sendCmd == FRAME_NORMAL) {
+ //Find min / max position
+ if (minMaxPoints != minMaxPoints_disabled)
+ refreshMinMax();
+
+ //Apply low-pass filter
+ if (filterType == filterType_box)
+ boxFilter();
+ else if (filterType == filterType_gaussian)
+ gaussianFilter();
+
+ //Teensy 3.6 - Resize to big buffer when HQRes
+ if ((teensyVersion == teensyVersion_new) && (hqRes))
+ smallToBigBuffer();
+
+ //Convert lepton data to RGB565 colors
+ convertColors();
+
+ //Display additional information
+ imgSave = imgSave_create;
+ displayInfos();
+ imgSave = imgSave_disabled;
+
+ //Send the framebuffer
+ sendFramebuffer();
+ }
+
+ //Switch back to send frame the next time
+ else
+ sendCmd = FRAME_NORMAL;
+}
+
+/* Evaluates commands from the serial port*/
+bool serialHandler() {
+ //Read command from Serial Port
+ byte recCmd = Serial.read();
+
+ //Decide what to do
+ switch (recCmd) {
+ //Send raw limits
+ case CMD_GET_RAWLIMITS:
+ sendRawLimits();
+ break;
+ //Send raw data
+ case CMD_GET_RAWDATA:
+ sendRawData();
+ break;
+ //Send config data
+ case CMD_GET_CONFIGDATA:
+ sendConfigData();
+ break;
+ //Send the calibration status
+ case CMD_GET_CALSTATUS:
+ sendCalStatus();
+ break;
+ //Send calibration data
+ case CMD_GET_CALIBDATA:
+ sendCalibrationData();
+ break;
+ //Send spot temp
+ case CMD_GET_SPOTTEMP:
+ sendSpotTemp();
+ break;
+ //Change time
+ case CMD_SET_TIME:
+ setTime();
+ break;
+ //Send temperature points
+ case CMD_GET_TEMPPOINTS:
+ sendTempPoints();
+ break;
+ //Toggle laser
+ case CMD_SET_LASER:
+ toggleLaser();
+ //Send ACK
+ Serial.write(CMD_SET_LASER);
+ break;
+ //Send laser state
+ case CMD_GET_LASER:
+ sendLaserState();
+ break;
+ //Run the shutter
+ case CMD_SET_SHUTTERRUN:
+ lepton_ffc();
+ //Send ACK
+ Serial.write(CMD_SET_SHUTTERRUN);
+ break;
+ //Set shutter mode
+ case CMD_SET_SHUTTERMODE:
+ setShutterMode();
+ break;
+ //Set the filter type
+ case CMD_SET_FILTERTYPE:
+ setFilterType();
+ break;
+ //Get the shutter mode
+ case CMD_GET_SHUTTERMODE:
+ sendShutterMode();
+ break;
+ //Send battery status
+ case CMD_GET_BATTERYSTATUS:
+ sendBatteryStatus();
+ break;
+ //Set calibration offset
+ case CMD_SET_CALOFFSET:
+ setCalOffset();
+ break;
+ //Set calibration slope
+ case CMD_SET_CALSLOPE:
+ setCalSlope();
+ break;
+ //Send visual image
+ case CMD_GET_VISUALIMG:
+ sendVisualImg();
+ break;
+ //Send firmware version
+ case CMD_GET_FWVERSION:
+ sendFWVersion();
+ break;
+ //Set limits
+ case CMD_SET_LIMITS:
+ setLimits();
+ break;
+ //Set limits to locked
+ case CMD_SET_TEXTCOLOR:
+ setTextColor();
+ break;
+ //Change colorscheme
+ case CMD_SET_COLORSCHEME:
+ setColorScheme();
+ break;
+ //Set temperature format
+ case CMD_SET_TEMPFORMAT:
+ setTempFormat();
+ break;
+ //Set show spot temp
+ case CMD_SET_SHOWSPOT:
+ setShowSpot();
+ break;
+ //Set show color bar
+ case CMD_SET_SHOWCOLORBAR:
+ setShowColorbar();
+ break;
+ //Set show min max
+ case CMD_SET_SHOWMINMAX:
+ setMinMax();
+ break;
+ //Set temperature points
+ case CMD_SET_TEMPPOINTS:
+ setTempPoints();
+ break;
+ //Get hardware version
+ case CMD_GET_HWVERSION:
+ sendHardwareVersion();
+ break;
+ //Set rotation
+ case CMD_SET_ROTATION:
+ setRotation();
+ break;
+ //Run calibration
+ case CMD_SET_CALIBRATION:
+ calibrationProcess(true, false);
+ break;
+ //Get diagnostic information
+ case CMD_GET_DIAGNOSTIC:
+ sendDiagnostic();
+ break;
+ //Get HQ resolution information
+ case CMD_GET_HQRESOLUTION:
+ sendHQResolution();
+ break;
+ //Send raw frame
+ case CMD_FRAME_RAW:
+ sendFrame(false);
+ break;
+ //Send color frame
+ case CMD_FRAME_COLOR:
+ sendFrame(true);
+ break;
+ //Send display frame
+ case CMD_FRAME_DISPLAY:
+ sendDisplayFrame();
+ break;
+ //Save display frame
+ case CMD_FRAME_SAVE:
+ saveFrame();
+ break;
+ //End connection
+ case CMD_END:
+ return true;
+ //Start connection, send ACK
+ case CMD_START:
+ Serial.write(CMD_START);
+ break;
+ //Invalid command
+ default:
+ Serial.write(CMD_INVALID);
+ break;
+ }
+ Serial.flush();
+ return false;
+}
+
+/* Evaluate button presses */
+void buttonHandler() {
+ //Count the time to choose selection
+ long startTime = millis();
+ delay(10);
+ long endTime = millis() - startTime;
+
+ //As long as the button is pressed
+ while (extButtonPressed() && (endTime <= 1000))
+ endTime = millis() - startTime;
+
+ //Short press - request to save a thermal image
+ if (endTime < 1000) {
+ sendCmd = FRAME_CAPTURE_THERMAL;
+ }
+
+ //Long press - request to start or stop a video
+ else {
+ sendCmd = FRAME_CAPTURE_VIDEO;
+ //Wait until button release
+ while (extButtonPressed());
+ }
+}
+
+/* Evaluate touch presses */
+bool touchHandler()
+{
+ //Count the time to choose selection
+ long startTime = millis();
+ delay(10);
+ long endTime = millis() - startTime;
+
+ //Wait for touch release, but not longer than a second
+ if (touch_capacitive) {
+ while ((touch_touched()) && (endTime <= 1000))
+ endTime = millis() - startTime;
+ }
+ else {
+ while ((!digitalRead(pin_touch_irq)) && (endTime <= 1000))
+ endTime = millis() - startTime;
+ }
+ endTime = millis() - startTime;
+
+ //Short press - take visual image
+ if (endTime < 1000)
+ {
+ sendCmd = FRAME_CAPTURE_VISUAL;
+ return false;
+ }
+
+ //Long press
+ return true;
+}
+
+
+/* Check for serial connection */
+void checkSerial() {
+ //If start command received
+ if ((Serial.available() > 0) && (Serial.read() == CMD_START)) {
+ serialMode = true;
+ serialConnect();
+ serialMode = false;
+ }
+
+ //Another command received, discard it
+ else if ((Serial.available() > 0))
+ Serial.read();
+}
+
+/* Check for updater requests */
+void checkForUpdater()
+{
+ //We received something
+ if (Serial.available() > 0) {
+ //Read command from Serial Port
+ byte recCmd = Serial.read();
+ //Decide what to do
+ switch (recCmd) {
+ //Send firmware version
+ case CMD_GET_FWVERSION:
+ sendFWVersion();
+ break;
+ //Get hardware version
+ case CMD_GET_HWVERSION:
+ sendHardwareVersion();
+ break;
+ //Get diagnostic information
+ case CMD_GET_DIAGNOSTIC:
+ sendDiagnostic();
+ break;
+ //Get HQ resolution information
+ case CMD_GET_HQRESOLUTION:
+ sendHQResolution();
+ break;
+ //Send the calibration status
+ case CMD_GET_CALSTATUS:
+ sendCalStatus();
+ break;
+ //Send battery status
+ case CMD_GET_BATTERYSTATUS:
+ sendBatteryStatus();
+ break;
+
+ //Start connection, send ACK
+ case CMD_START:
+ Serial.write(CMD_START);
+ break;
+ }
+ Serial.flush();
+ }
+}
+
+/* Go into video output mode and wait for connected module */
+void serialOutput() {
+ //Send the frames
+ while (true) {
+
+ //Abort transmission when touched long or save visual when short
+ if (touch_touched() && checkDiagnostic(diag_touch))
+ if (touchHandler())
+ break;
+
+ //Check warmup status
+ checkWarmup();
+
+ //Get the temps
+ if (checkDiagnostic(diag_lep_data))
+ lepton_getRawValues();
+
+ //Get the spot temperature
+ getSpotTemp();
+
+ //Compensate calibration with MLX90614 for non-radiometric Lepton
+ if ((leptonVersion != leptonVersion_2_5_shutter) && (leptonVersion != leptonVersion_3_5_shutter))
+ compensateCalib();
+
+ //Refresh the temp points
+ refreshTempPoints();
+
+ //Find min and max if not in manual mode and limits not locked
+ if ((autoMode) && (!limitsLocked))
+ limitValues();
+
+ //Check button press if not in terminal mode
+ if (extButtonPressed())
+ buttonHandler();
+
+ //Check for serial commands
+ if (Serial.available() > 0) {
+ //Check for exit
+ if (serialHandler())
+ break;
+ }
+ }
+}
+
+/* Method to init some basic values in case no display is used */
+void serialInit()
+{
+ //Read all settings from EEPROM
+ readEEPROM();
+
+ //Select color scheme
+ selectColorScheme();
+
+ //Clear show temp array
+ clearTempPoints();
+
+ //Receive and send commands over serial port
+ while (true)
+ serialOutput();
+}
+
+/* Tries to establish a connection to a thermal viewer or video output module*/
+void serialConnect() {
+ //Show message
+ showFullMessage((char*)"Serial connection detected");
+ display_print((char*) "Touch screen long to return", CENTER, 170);
+ delay(1000);
+
+ //Disable screen backlight
+ disableScreenLight();
+
+ //Turn laser off if enabled
+ if (laserEnabled)
+ toggleLaser();
+
+ //Set visual camera resolution to save
+ camera_setSaveRes();
+
+ //Send ACK for Start
+ Serial.write(CMD_START);
+
+ //Go to the serial output
+ serialOutput();
+
+ //Send ACK for End
+ Serial.write(CMD_END);
+
+ //Re-Enable display backlight
+ enableScreenLight();
+
+ //Show message
+ showFullMessage((char*)"Connection ended, return..");
+ delay(1000);
+
+ //Clear all serial buffers
+ Serial.clear();
+
+ //Change camera resolution back
+ if (displayMode == displayMode_thermal)
+ camera_setSaveRes();
+ else
+ camera_setDisplayRes();
+
+ //Turn laser off if enabled
+ if (laserEnabled)
+ toggleLaser();
+}
diff --git a/Firmware_V2/src/hardware/connection.h b/Firmware_V2/src/hardware/connection.h
new file mode 100644
index 0000000..46c75c8
--- /dev/null
+++ b/Firmware_V2/src/hardware/connection.h
@@ -0,0 +1,118 @@
+/*
+*
+* CONNECTION - Communication protocol for the USB serial data transmission
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef CONNECTION_H
+#define CONNECTION_H
+
+/*################# PUBLIC CONSTANTS, VARIABLES & DATA TYPES ##################*/
+
+//Start & Stop command
+#define CMD_START 100
+#define CMD_END 200
+#define CMD_INVALID 0
+
+//Serial terminal commands
+#define CMD_GET_RAWLIMITS 110
+#define CMD_GET_RAWDATA 111
+#define CMD_GET_CONFIGDATA 112
+#define CMD_GET_CALSTATUS 113
+#define CMD_GET_CALIBDATA 114
+#define CMD_GET_SPOTTEMP 115
+#define CMD_SET_TIME 116
+#define CMD_GET_TEMPPOINTS 117
+#define CMD_SET_LASER 118
+#define CMD_GET_LASER 119
+#define CMD_SET_SHUTTERRUN 120
+#define CMD_SET_SHUTTERMODE 121
+#define CMD_SET_FILTERTYPE 122
+#define CMD_GET_SHUTTERMODE 123
+#define CMD_GET_BATTERYSTATUS 124
+#define CMD_SET_CALSLOPE 125
+#define CMD_SET_CALOFFSET 126
+#define CMD_GET_DIAGNOSTIC 127
+#define CMD_GET_VISUALIMG 128
+#define CMD_GET_FWVERSION 129
+#define CMD_SET_LIMITS 130
+#define CMD_SET_TEXTCOLOR 131
+#define CMD_SET_COLORSCHEME 132
+#define CMD_SET_TEMPFORMAT 133
+#define CMD_SET_SHOWSPOT 134
+#define CMD_SET_SHOWCOLORBAR 135
+#define CMD_SET_SHOWMINMAX 136
+#define CMD_SET_TEMPPOINTS 137
+#define CMD_GET_HWVERSION 138
+#define CMD_SET_ROTATION 139
+#define CMD_SET_CALIBRATION 140
+#define CMD_GET_HQRESOLUTION 141
+
+//Serial frame commands
+#define CMD_FRAME_RAW 150
+#define CMD_FRAME_COLOR 151
+#define CMD_FRAME_DISPLAY 152
+#define CMD_FRAME_SAVE 153
+
+//Types of raw frame responses
+#define FRAME_CAPTURE_THERMAL 180
+#define FRAME_CAPTURE_VISUAL 181
+#define FRAME_CAPTURE_VIDEO 182
+#define FRAME_NORMAL 183
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+void buttonHandler();
+void checkForUpdater();
+bool checkNoDisplay();
+void checkSerial();
+int getInt(String text);
+void saveFrame();
+void sendBatteryStatus();
+void sendCalibrationData();
+void sendCalStatus();
+void sendConfigData();
+void sendDiagnostic();
+void sendDisplayFrame();
+void sendFramebuffer();
+void sendFrame(bool color);
+void sendFWVersion();
+void sendHardwareVersion();
+void sendHQResolution();
+void sendLaserState();
+void sendRawData(bool color = false);
+void sendRawLimits();
+void sendShutterMode();
+void sendSpotTemp();
+void sendTempPoints();
+void sendVisualImg();
+void serialConnect();
+bool serialHandler();
+void serialInit();
+void serialOutput();
+void setCalOffset();
+void setCalSlope();
+void setColorScheme();
+void setFilterType();
+void setLimits();
+void setMinMax();
+void setRotation();
+void setShowColorbar();
+void setShowSpot();
+void setShutterMode();
+void setTempFormat();
+void setTempPoints();
+void setTextColor();
+void setTime();
+bool touchHandler();
+
+#endif /* CONNECTION_H */
diff --git a/Firmware_V2/src/hardware/display/display.cpp b/Firmware_V2/src/hardware/display/display.cpp
new file mode 100644
index 0000000..344a160
--- /dev/null
+++ b/Firmware_V2/src/hardware/display/display.cpp
@@ -0,0 +1,1605 @@
+/*
+*
+* Display - ILI9341 SPI Display Module
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*################# DATA TYPES, CONSTANTS & MACRO DEFINITIONS #################*/
+
+#define SPICLOCK 30000000
+
+#define LED 22
+#define CS 21
+#define DC 6
+
+#define ILI9341_TFTWIDTH 240
+#define ILI9341_TFTHEIGHT 320
+
+#define ILI9341_NOP 0x00
+#define ILI9341_SWRESET 0x01
+#define ILI9341_RDDID 0x04
+#define ILI9341_RDDST 0x09
+
+#define ILI9341_SLPIN 0x10
+#define ILI9341_SLPOUT 0x11
+#define ILI9341_PTLON 0x12
+#define ILI9341_NORON 0x13
+
+#define ILI9341_RDMODE 0x0A
+#define ILI9341_RDMADCTL 0x0B
+#define ILI9341_RDPIXFMT 0x0C
+#define ILI9341_RDIMGFMT 0x0A
+#define ILI9341_RDSELFDIAG 0x0F
+
+#define ILI9341_INVOFF 0x20
+#define ILI9341_INVON 0x21
+#define ILI9341_GAMMASET 0x26
+#define ILI9341_DISPOFF 0x28
+#define ILI9341_DISPON 0x29
+
+#define ILI9341_CASET 0x2A
+#define ILI9341_PASET 0x2B
+#define ILI9341_RAMWR 0x2C
+#define ILI9341_RAMRD 0x2E
+
+#define ILI9341_PTLAR 0x30
+#define ILI9341_MADCTL 0x36
+#define ILI9341_PIXFMT 0x3A
+
+#define ILI9341_FRMCTR1 0xB1
+#define ILI9341_FRMCTR2 0xB2
+#define ILI9341_FRMCTR3 0xB3
+#define ILI9341_INVCTR 0xB4
+#define ILI9341_DFUNCTR 0xB6
+
+#define ILI9341_PWCTR1 0xC0
+#define ILI9341_PWCTR2 0xC1
+#define ILI9341_PWCTR3 0xC2
+#define ILI9341_PWCTR4 0xC3
+#define ILI9341_PWCTR5 0xC4
+#define ILI9341_VMCTR1 0xC5
+#define ILI9341_VMCTR2 0xC7
+
+#define ILI9341_RDID1 0xDA
+#define ILI9341_RDID2 0xDB
+#define ILI9341_RDID3 0xDC
+#define ILI9341_RDID4 0xDD
+
+#define ILI9341_GMCTRP1 0xE0
+#define ILI9341_GMCTRN1 0xE1
+
+#define MADCTL_MY 0x80
+#define MADCTL_MX 0x40
+#define MADCTL_MV 0x20
+#define MADCTL_ML 0x10
+#define MADCTL_RGB 0x00
+#define MADCTL_BGR 0x08
+#define MADCTL_MH 0x04
+
+#define swap(type, i, j) {type t = i; i = j; j = t;}
+#define fontbyte(x) cfont.font[x]
+
+struct current_font
+{
+ uint8_t* font;
+ uint8_t x_size;
+ uint8_t y_size;
+ uint8_t offset;
+ uint8_t numchars;
+};
+
+/*######################### STATIC DATA DECLARATIONS ##########################*/
+
+static uint8_t pcs_data, pcs_command, rotation;
+static current_font cfont;
+static boolean transparent;
+static byte fch, fcl, bch, bcl, orient;
+static uint16_t imageX, imageY;
+
+static const uint8_t init_commands[] = {
+ 4, 0xEF, 0x03, 0x80, 0x02,
+ 4, 0xCF, 0x00, 0XC1, 0X30,
+ 5, 0xED, 0x64, 0x03, 0X12, 0X81,
+ 4, 0xE8, 0x85, 0x00, 0x78,
+ 6, 0xCB, 0x39, 0x2C, 0x00, 0x34, 0x02,
+ 2, 0xF7, 0x20,
+ 3, 0xEA, 0x00, 0x00,
+ 2, ILI9341_PWCTR1, 0x23, // Power control
+ 2, ILI9341_PWCTR2, 0x10, // Power control
+ 3, ILI9341_VMCTR1, 0x3e, 0x28, // VCM control
+ 2, ILI9341_VMCTR2, 0x86, // VCM control2
+ 2, ILI9341_MADCTL, 0x48, // Memory Access Control
+ 2, ILI9341_PIXFMT, 0x55,
+ 3, ILI9341_FRMCTR1, 0x00, 0x18,
+ 4, ILI9341_DFUNCTR, 0x08, 0x82, 0x27, // Display Function Control
+ 2, 0xF2, 0x00, // Gamma Function Disable
+ 2, ILI9341_GAMMASET, 0x01, // Gamma curve selected
+ 16, ILI9341_GMCTRP1, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08,
+ 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00, // Set Gamma
+ 16, ILI9341_GMCTRN1, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07,
+ 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, // Set Gamma
+ 3, 0xb1, 0x00, 0x10, // FrameRate Control 119Hz
+ 0
+};
+
+/*############################# PUBLIC VARIABLES ##############################*/
+
+boolean display_writeToImage;
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+void display_waitFifoNotFull()
+{
+ uint32_t sr;
+ do {
+ sr = KINETISK_SPI0.SR;
+ if (sr & 0xF0) KINETISK_SPI0.POPR;
+ } while ((sr & (15 << 12)) > (3 << 12));
+}
+
+void display_waitFifoEmpty()
+{
+ uint32_t sr;
+ do {
+ sr = KINETISK_SPI0.SR;
+ if (sr & 0xF0) KINETISK_SPI0.POPR;
+ } while ((sr & 0xF0F0) > 0);
+}
+
+void display_waitTransmitComplete()
+{
+ while (!(KINETISK_SPI0.SR & SPI_SR_TCF));
+ KINETISK_SPI0.POPR;
+}
+
+void display_waitTransmitComplete(uint32_t mcr)
+{
+ while (1) {
+ uint32_t sr = KINETISK_SPI0.SR;
+ if (sr & SPI_SR_EOQF) break;
+ if (sr & 0xF0) KINETISK_SPI0.POPR;
+ }
+ KINETISK_SPI0.SR = SPI_SR_EOQF;
+ SPI0_MCR = mcr;
+ while (KINETISK_SPI0.SR & 0xF0) {
+ KINETISK_SPI0.POPR;
+ }
+}
+
+void display_writecommand_cont(uint8_t c)
+{
+ KINETISK_SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
+ display_waitFifoNotFull();
+}
+
+void display_writedata8_cont(uint8_t c)
+{
+ KINETISK_SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
+ display_waitFifoNotFull();
+}
+
+void display_writedata16_cont(uint16_t d)
+{
+ KINETISK_SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1) | SPI_PUSHR_CONT;
+ display_waitFifoNotFull();
+}
+
+void display_writecommand_last(uint8_t c)
+{
+ uint32_t mcr = SPI0_MCR;
+ KINETISK_SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ;
+ display_waitTransmitComplete(mcr);
+}
+
+void display_writedata8_last(uint8_t c)
+{
+ uint32_t mcr = SPI0_MCR;
+ KINETISK_SPI0.PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ;
+ display_waitTransmitComplete(mcr);
+}
+
+void display_writedata16_last(uint16_t d)
+{
+ uint32_t mcr = SPI0_MCR;
+ KINETISK_SPI0.PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1) | SPI_PUSHR_EOQ;
+ display_waitTransmitComplete(mcr);
+}
+
+void display_setAddr(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
+{
+ display_writecommand_cont(ILI9341_CASET);
+ display_writedata16_cont(x0);
+ display_writedata16_cont(x1);
+ display_writecommand_cont(ILI9341_PASET);
+ display_writedata16_cont(y0);
+ display_writedata16_cont(y1);
+}
+
+/* Read 8-bit command from the screen */
+uint8_t display_readcommand8(uint8_t c, uint8_t index)
+{
+ uint16_t wTimeout = 0xffff;
+ uint8_t r = 0;
+
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+ while (((KINETISK_SPI0.SR) & (15 << 12)) && (--wTimeout));
+
+ KINETISK_SPI0.SR = SPI_SR_TCF;
+ wTimeout = 0xffff;
+ while (!((KINETISK_SPI0.SR) & SPI_SR_TCF) && (--wTimeout));
+
+ wTimeout = 0x10;
+ while ((((KINETISK_SPI0.SR) >> 4) & 0xf) && (--wTimeout)) {
+ r = KINETISK_SPI0.POPR;
+ }
+
+ KINETISK_SPI0.PUSHR = 0xD9 | (pcs_command << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
+ KINETISK_SPI0.PUSHR = (0x10 + index) | (pcs_data << 16) | SPI_PUSHR_CTAS(0);
+ KINETISK_SPI0.PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
+
+ KINETISK_SPI0.PUSHR = 0 | (pcs_data << 16) | SPI_PUSHR_CTAS(0);
+
+ wTimeout = 0xffff;
+ while (((KINETISK_SPI0.SR) & (15 << 12)) && (--wTimeout));
+
+ KINETISK_SPI0.SR = SPI_SR_TCF;
+ wTimeout = 0xffff;
+ while (!((KINETISK_SPI0.SR) & SPI_SR_TCF) && (--wTimeout));
+
+ wTimeout = 0x10;
+ while ((((KINETISK_SPI0.SR) >> 4) & 0xf) && (--wTimeout)) {
+ r = KINETISK_SPI0.POPR;
+ }
+
+ SPI.endTransaction();
+ return r;
+}
+
+/* Set display rotation */
+void display_setRotation(uint8_t m)
+{
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+ display_writecommand_cont(ILI9341_MADCTL);
+ rotation = m % 4;
+ switch (rotation) {
+ case 0:
+ display_writedata8_last(MADCTL_MX | MADCTL_BGR);
+ orient = LANDSCAPE;
+ break;
+ case 1:
+ display_writedata8_last(MADCTL_MV | MADCTL_BGR);
+ orient = PORTRAIT;
+ break;
+ case 2:
+ display_writedata8_last(MADCTL_MY | MADCTL_BGR);
+ orient = LANDSCAPE;
+ break;
+ case 3:
+ display_writedata8_last(MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR);
+ orient = PORTRAIT;
+ break;
+ }
+ SPI.endTransaction();
+}
+
+/* Init the hardware LCD */
+byte display_InitLCD()
+{
+ //Set CS pin
+ if (SPI.pinIsChipSelect(CS, DC)) {
+ pcs_data = SPI.setCS(CS);
+ pcs_command = pcs_data | SPI.setCS(DC);
+ }
+ else {
+ pcs_data = 0;
+ pcs_command = 0;
+ return 0;
+ }
+
+ //Read the self-diagnostic flag
+ byte diag = display_readcommand8(ILI9341_RDSELFDIAG);
+
+ //Send the init commands
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+ const uint8_t *addr = init_commands;
+ while (1) {
+ uint8_t count = *addr++;
+ if (count-- == 0)
+ break;
+ display_writecommand_cont(*addr++);
+ while (count-- > 0) {
+ display_writedata8_cont(*addr++);
+ }
+ }
+ display_writecommand_last(ILI9341_SLPOUT);
+ SPI.endTransaction();
+
+ //Wait a short time
+ delay(120);
+
+ //Turn the display on
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+ display_writecommand_last(ILI9341_DISPON);
+ SPI.endTransaction();
+
+ //Init font & transparency
+ cfont.font = 0;
+ transparent = 0;
+
+ //Set the display rotation
+ display_setRotation(45);
+
+ //Disable write to image
+ display_writeToImage = 0;
+
+ //Return the diagnostic info
+ return diag;
+}
+
+/* Init the display module */
+void display_init()
+{
+ byte count = 0;
+ //Init the display
+ byte check = display_InitLCD();
+
+ //Status not okay, try again 10 times
+ while ((check != 0xE0) && (count < 10)) {
+ delay(10);
+ check = display_InitLCD();
+ count++;
+ }
+ //If it failed after 10 attemps, show diag
+ if (check != 0xE0)
+ setDiagnostic(diag_display);
+
+ //Read 180° rotation
+ byte read = EEPROM.read(eeprom_rotationVert);
+ if ((read == 0) || (read == 1))
+ rotationVert = read;
+ else
+ rotationVert = 0;
+}
+
+/* Set the xy coordinates */
+void display_setXY(word x1, word y1, word x2, word y2)
+{
+ if (orient == LANDSCAPE) {
+ swap(word, x1, y1);
+ swap(word, x2, y2);
+ y1 = 239 - y1;
+ y2 = 239 - y2;
+ swap(word, y1, y2);
+ }
+
+ //Write to the display
+ if (!display_writeToImage) {
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+ display_setAddr(x1, y1, x2, y2);
+ display_writecommand_last(ILI9341_RAMWR); // write to RAM
+ SPI.endTransaction();
+ }
+ //Write to the image buffer
+ else {
+ imageX = x1;
+ imageY = y1;
+ }
+}
+
+/* Clear the xy coordinates */
+void display_clrXY()
+{
+ if (orient == PORTRAIT)
+ display_setXY(0, 0, 319, 239);
+ else
+ display_setXY(0, 0, 239, 319);
+}
+
+/* Clear the screen */
+void display_clrScr()
+{
+ display_setXY(0, 0, 239, 319);
+}
+
+
+/* Draw a pixel */
+void display_drawPixel(int x, int y)
+{
+ //Out of borders, return
+ if ((x < 0) || (x >= 320) || (y < 0) || (y >= 240))
+ return;
+ //Send pixel coordinates and color to screen
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+ display_setAddr(x, y, x, y);
+ display_writecommand_cont(ILI9341_RAMWR);
+ display_writedata16_last(fch << 8 | fcl);
+ SPI.endTransaction();
+}
+
+/* Draw a horizontal line */
+void display_drawHLine(int x, int y, int l)
+{
+ //Clipping
+ if ((x >= 320) || (y >= 240))
+ return;
+ if ((x + l - 1) >= 320)
+ l = 320 - x;
+
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+ display_setAddr(x, y, x + l - 1, y);
+ display_writecommand_cont(ILI9341_RAMWR);
+ word color = (fch << 8 | fcl);
+ while (l-- > 1) {
+ display_writedata16_cont(color);
+ }
+ display_writedata16_last(color);
+ SPI.endTransaction();
+}
+
+/* Draw a vertical line */
+void display_drawVLine(int x, int y, int l)
+{
+ //Clipping
+ if ((x >= 320) || (y >= 240))
+ return;
+ if ((y + l - 1) >= 240)
+ l = 240 - y;
+
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+ display_setAddr(x, y, x, y + l - 1);
+ display_writecommand_cont(ILI9341_RAMWR);
+ word color = (fch << 8 | fcl);
+ while (l-- > 1) {
+ display_writedata16_cont(color);
+ }
+ display_writedata16_last(color);
+ SPI.endTransaction();
+}
+
+/* Set a specific pixel in that color */
+void display_setPixel(word color)
+{
+ uint32_t pos;
+
+ //Write to display
+ if (!display_writeToImage) {
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+ display_writedata16_last(color);
+ SPI.endTransaction();
+ }
+ //Write to buffer directly
+ else
+ {
+ //320x240 for Teensy 3.6
+ if ((teensyVersion == teensyVersion_new) && hqRes)
+ {
+ pos = ((imageY) * 320) + imageX;
+ if(pos < 76800)
+ bigBuffer[pos] = color;
+ }
+
+ //160x120 for Teensy 3.1 / 3.2
+ else
+ {
+ pos = ((imageY) * 160) + imageX;
+ if(pos < 19200)
+ smallBuffer[pos] = color;
+ }
+ }
+}
+
+/* Write the data to the LCD */
+void display_LCD_Write_DATA(char VH, char VL)
+{
+ display_setPixel((VH << 8) | VL);
+}
+
+/* Draw a line */
+void display_drawLine(int x1, int y1, int x2, int y2)
+{
+ //For buffer display on Teensy 3.1 / 3.2, half coordinates
+ if ((display_writeToImage) && ((teensyVersion == teensyVersion_old) || (!hqRes))) {
+ x1 = x1 / 2;
+ y1 = y1 / 2;
+ x2 = x2 / 2;
+ y2 = y2 / 2;
+ }
+
+ //Write to screen
+ if ((y1 == y2) && (!display_writeToImage))
+ display_drawHLine(x1, y1, x2 - x1);
+ else if ((x1 == x2) && (!display_writeToImage))
+ display_drawVLine(x1, y1, y2 - y1);
+ //Write to image buffer directly
+ else {
+ unsigned int dx = (x2 > x1 ? x2 - x1 : x1 - x2);
+ short xstep = x2 > x1 ? 1 : -1;
+ unsigned int dy = (y2 > y1 ? y2 - y1 : y1 - y2);
+ short ystep = y2 > y1 ? 1 : -1;
+ int col = x1, row = y1;
+
+ if (dx < dy) {
+ int t = -(dy >> 1);
+ while (1) {
+ display_setXY(col, row, col, row);
+ display_LCD_Write_DATA(fch, fcl);
+ if (row == y2)
+ return;
+ row += ystep;
+ t += dx;
+ if (t >= 0) {
+ col += xstep;
+ t -= dy;
+ }
+ }
+ }
+ else {
+ int t = -(dx >> 1);
+ while (1) {
+ display_setXY(col, row, col, row);
+ display_LCD_Write_DATA(fch, fcl);
+ if (col == x2)
+ return;
+ col += xstep;
+ t += dy;
+ if (t >= 0) {
+ row += ystep;
+ t -= dx;
+ }
+ }
+ }
+ }
+ display_clrXY();
+}
+
+/* Fill the screen by RGB565 color */
+void display_fillScr(word color)
+{
+ int x = 0;
+ int y = 0;
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+ display_setAddr(x, y, x + 319, y + 239);
+ display_writecommand_cont(ILI9341_RAMWR);
+ for (y = 240; y > 0; y--) {
+ for (x = 320; x > 1; x--) {
+ display_writedata16_cont(color);
+ }
+ display_writedata16_last(color);
+ }
+ SPI.endTransaction();
+}
+
+/* Fill the screen by separate RGB value */
+void display_fillScr(byte r, byte g, byte b)
+{
+ word color = ((r & 248) << 8 | (g & 252) << 3 | (b & 248) >> 3);
+ display_fillScr(color);
+}
+
+/* Draw an empty rectangle */
+void display_drawRect(int x1, int y1, int x2, int y2)
+{
+ if (x1 > x2) {
+ swap(int, x1, x2);
+ }
+ if (y1 > y2) {
+ swap(int, y1, y2);
+ }
+
+ display_drawHLine(x1, y1, x2 - x1);
+ display_drawHLine(x1, y2, x2 - x1);
+ display_drawVLine(x1, y1, y2 - y1);
+ display_drawVLine(x2, y1, y2 - y1);
+}
+
+/* Fill a rectangle */
+void display_fillRect(int x1, int y1, int x2, int y2)
+{
+ if (x1 > x2) {
+ swap(int, x1, x2);
+ }
+ if (y1 > y2) {
+ swap(int, y1, y2);
+ }
+
+ int w = x2 - x1;
+ int h = y2 - y1;
+
+ //Clipping
+ if ((x1 >= 320) || (y1 >= 240))
+ return;
+ if ((x1 + w - 1) >= 320)
+ w = 320 - x1;
+ if ((y1 + h - 1) >= 240)
+ h = 240 - y1;
+
+ //Send to display
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+ display_setAddr(x1, y1, x1 + w - 1, y1 + h - 1);
+ display_writecommand_cont(ILI9341_RAMWR);
+ word color = (fch << 8 | fcl);
+ for (int y = h; y > 0; y--) {
+ for (int x = w; x > 1; x--) {
+ display_writedata16_cont(color);
+ }
+ display_writedata16_last(color);
+ }
+ SPI.endTransaction();
+}
+
+/* Draw an empty round rectangle */
+void display_drawRoundRect(int x1, int y1, int x2, int y2)
+{
+ if (x1 > x2) {
+ swap(int, x1, x2);
+ }
+ if (y1 > y2) {
+ swap(int, y1, y2);
+ }
+ if ((x2 - x1) > 4 && (y2 - y1) > 4) {
+ display_drawPixel(x1 + 1, y1 + 1);
+ display_drawPixel(x2 - 1, y1 + 1);
+ display_drawPixel(x1 + 1, y2 - 1);
+ display_drawPixel(x2 - 1, y2 - 1);
+ display_drawHLine(x1 + 2, y1, x2 - x1 - 4);
+ display_drawHLine(x1 + 2, y2, x2 - x1 - 4);
+ display_drawVLine(x1, y1 + 2, y2 - y1 - 4);
+ display_drawVLine(x2, y1 + 2, y2 - y1 - 4);
+ }
+}
+
+/* Fill a round rectangle */
+void display_fillRoundRect(int x1, int y1, int x2, int y2)
+{
+ if (x1 > x2) {
+ swap(int, x1, x2);
+ }
+ if (y1 > y2) {
+ swap(int, y1, y2);
+ }
+
+ if ((x2 - x1) > 4 && (y2 - y1) > 4) {
+ for (int i = 0; i < ((y2 - y1) / 2) + 1; i++) {
+ switch (i) {
+ case 0:
+ display_drawHLine(x1 + 2, y1 + i, x2 - x1 - 4);
+ display_drawHLine(x1 + 2, y2 - i, x2 - x1 - 4);
+ break;
+ case 1:
+ display_drawHLine(x1 + 1, y1 + i, x2 - x1 - 2);
+ display_drawHLine(x1 + 1, y2 - i, x2 - x1 - 2);
+ break;
+ default:
+ display_drawHLine(x1, y1 + i, x2 - x1);
+ display_drawHLine(x1, y2 - i, x2 - x1);
+ }
+ }
+ }
+}
+
+/* Draw an empty circle */
+void display_drawCircle(int x, int y, int radius)
+{
+ //For buffer display on Teensy 3.1 / 3.2, half coordinates
+ if ((display_writeToImage) && ((teensyVersion == teensyVersion_old) || (!hqRes))) {
+ x = x / 2;
+ y = y / 2;
+ radius = radius / 2;
+ }
+
+ int f = 1 - radius;
+ int ddF_x = 1;
+ int ddF_y = -2 * radius;
+ int x1 = 0;
+ int y1 = radius;
+
+ display_setXY(x, y + radius, x, y + radius);
+ display_LCD_Write_DATA(fch, fcl);
+ display_setXY(x, y - radius, x, y - radius);
+ display_LCD_Write_DATA(fch, fcl);
+ display_setXY(x + radius, y, x + radius, y);
+ display_LCD_Write_DATA(fch, fcl);
+ display_setXY(x - radius, y, x - radius, y);
+ display_LCD_Write_DATA(fch, fcl);
+
+ while (x1 < y1) {
+ if (f >= 0) {
+ y1--;
+ ddF_y += 2;
+ f += ddF_y;
+ }
+ x1++;
+ ddF_x += 2;
+ f += ddF_x;
+ display_setXY(x + x1, y + y1, x + x1, y + y1);
+ display_LCD_Write_DATA(fch, fcl);
+ display_setXY(x - x1, y + y1, x - x1, y + y1);
+ display_LCD_Write_DATA(fch, fcl);
+ display_setXY(x + x1, y - y1, x + x1, y - y1);
+ display_LCD_Write_DATA(fch, fcl);
+ display_setXY(x - x1, y - y1, x - x1, y - y1);
+ display_LCD_Write_DATA(fch, fcl);
+ display_setXY(x + y1, y + x1, x + y1, y + x1);
+ display_LCD_Write_DATA(fch, fcl);
+ display_setXY(x - y1, y + x1, x - y1, y + x1);
+ display_LCD_Write_DATA(fch, fcl);
+ display_setXY(x + y1, y - x1, x + y1, y - x1);
+ display_LCD_Write_DATA(fch, fcl);
+ display_setXY(x - y1, y - x1, x - y1, y - x1);
+ display_LCD_Write_DATA(fch, fcl);
+ }
+ display_clrXY();
+}
+
+/* Fill a circle */
+void display_fillCircle(int x, int y, int radius)
+{
+ for (int y1 = -radius; y1 <= 0; y1++) {
+ for (int x1 = -radius; x1 <= 0; x1++) {
+ if (x1 * x1 + y1 * y1 <= radius * radius) {
+ display_drawHLine(x + x1, y + y1, 2 * (-x1));
+ display_drawHLine(x + x1, y - y1, 2 * (-x1));
+ break;
+ }
+ }
+ }
+}
+
+/* Set color to separate RGB values */
+void display_setColor(byte r, byte g, byte b)
+{
+ fch = ((r & 248) | g >> 5);
+ fcl = ((g & 28) << 3 | b >> 3);
+}
+
+/* Set color to RGB565 color */
+void display_setColor(word color)
+{
+ fch = byte(color >> 8);
+ fcl = byte(color & 0xFF);
+}
+
+/* Get current RGB565 color */
+word display_getColor()
+{
+ return (fch << 8) | fcl;
+}
+
+/* Set back color to separate RGB value */
+void display_setBackColor(byte r, byte g, byte b)
+{
+ bch = ((r & 248) | g >> 5);
+ bcl = ((g & 28) << 3 | b >> 3);
+ transparent = 0;
+}
+
+/* Set back color to RGB565 value */
+void display_setBackColor(uint32_t color)
+{
+ if (color == VGA_TRANSPARENT)
+ transparent = 1;
+ else {
+ bch = byte(color >> 8);
+ bcl = byte(color & 0xFF);
+ transparent = 0;
+ }
+}
+
+/* Get back color as RGB565 value */
+word display_getBackColor()
+{
+ return (bch << 8) | bcl;
+}
+
+/* Print a specific char */
+void display_printChar(byte c, int x, int y)
+{
+ byte i, ch;
+ word j;
+ word temp;
+
+ //For buffer display on Teensy 3.1 / 3.2, half coordinates
+ if ((display_writeToImage) && ((teensyVersion == teensyVersion_old) || (!hqRes))) {
+ x = x / 2;
+ y = y / 2;
+ }
+
+ //Not transparent
+ if (!transparent) {
+ if (orient == PORTRAIT) {
+ display_setXY(x, y, x + cfont.x_size - 1, y + cfont.y_size - 1);
+
+ temp = ((c - cfont.offset) * ((cfont.x_size / 8) * cfont.y_size))
+ + 4;
+ for (j = 0; j < ((cfont.x_size / 8) * cfont.y_size); j++) {
+ ch = pgm_read_byte(&cfont.font[temp]);
+ for (i = 0; i < 8; i++) {
+ if ((ch & (1 << (7 - i))) != 0) {
+ display_setPixel((fch << 8) | fcl);
+ }
+ else {
+ display_setPixel((bch << 8) | bcl);
+ }
+ }
+ temp++;
+ }
+ }
+ else {
+ temp = ((c - cfont.offset) * ((cfont.x_size / 8) * cfont.y_size))
+ + 4;
+
+ for (j = 0; j < ((cfont.x_size / 8) * cfont.y_size);
+ j += (cfont.x_size / 8)) {
+ display_setXY(x, y + (j / (cfont.x_size / 8)), x + cfont.x_size - 1,
+ y + (j / (cfont.x_size / 8)));
+ for (int zz = (cfont.x_size / 8) - 1; zz >= 0; zz--) {
+ ch = pgm_read_byte(&cfont.font[temp + zz]);
+ for (i = 0; i < 8; i++) {
+ if ((ch & (1 << i)) != 0) {
+ display_setPixel((fch << 8) | fcl);
+ }
+ else {
+ display_setPixel((bch << 8) | bcl);
+ }
+ }
+ }
+ temp += (cfont.x_size / 8);
+ }
+ }
+ }
+
+ //Transparent
+ else {
+ temp = ((c - cfont.offset) * ((cfont.x_size / 8) * cfont.y_size)) + 4;
+ for (j = 0; j < cfont.y_size; j++) {
+ for (int zz = 0; zz < (cfont.x_size / 8); zz++) {
+ ch = pgm_read_byte(&cfont.font[temp + zz]);
+ for (i = 0; i < 8; i++) {
+ display_setXY(x + i + (zz * 8), y + j, x + i + (zz * 8) + 1,
+ y + j + 1);
+
+ if ((ch & (1 << (7 - i))) != 0) {
+ display_setPixel((fch << 8) | fcl);
+ }
+ }
+ }
+ temp += (cfont.x_size / 8);
+ }
+ }
+
+ display_clrXY();
+}
+
+/* Get the font height */
+int display_getFontHeight()
+{
+ return (cfont.y_size);
+}
+
+/* Return the Glyph data for an individual character in the font*/
+boolean display_getCharPtr(byte c, propFont& fontChar)
+{
+ byte* tempPtr = cfont.font + 4; // point at data
+
+ do
+ {
+ fontChar.charCode = pgm_read_byte(tempPtr++);
+ fontChar.adjYOffset = pgm_read_byte(tempPtr++);
+ fontChar.width = pgm_read_byte(tempPtr++);
+ fontChar.height = pgm_read_byte(tempPtr++);
+ fontChar.xOffset = pgm_read_byte(tempPtr++);
+ fontChar.xOffset = fontChar.xOffset < 0x80 ? fontChar.xOffset : (0x100 - fontChar.xOffset);
+ fontChar.xDelta = pgm_read_byte(tempPtr++);
+ if (c != fontChar.charCode && fontChar.charCode != 0xFF)
+ {
+ if (fontChar.width != 0)
+ {
+ // packed bits
+ tempPtr += (((fontChar.width * fontChar.height) - 1) / 8) + 1;
+ }
+ }
+ } while (c != fontChar.charCode && fontChar.charCode != 0xFF);
+
+ fontChar.dataPtr = tempPtr;
+
+ return (fontChar.charCode != 0xFF);
+}
+
+/* Print a proportional char */
+int display_printProportionalChar(byte c, int x, int y)
+{
+ byte i, j;
+ byte ch = 0;
+ byte *tempPtr;
+
+ propFont fontChar;
+ if (!display_getCharPtr(c, fontChar))
+ {
+ return 0;
+ }
+
+ word fcolor = display_getColor();
+ if (!transparent)
+ {
+ int fontHeight = display_getFontHeight();
+ display_setColor(display_getBackColor());
+ display_fillRect(x, y, x + fontChar.xDelta + 1, y + fontHeight);
+ display_setColor(fcolor);
+ }
+
+ tempPtr = fontChar.dataPtr;
+
+ if (fontChar.width != 0)
+ {
+ byte mask = 0x80;
+ for (j = 0; j < fontChar.height; j++)
+ {
+ for (i = 0; i < fontChar.width; i++)
+ {
+ if (((i + (j*fontChar.width)) % 8) == 0)
+ {
+ mask = 0x80;
+ ch = pgm_read_byte(tempPtr++);
+ }
+
+ if ((ch & mask) != 0)
+ {
+ display_setXY(x + fontChar.xOffset + i, y + j + fontChar.adjYOffset,
+ x + fontChar.xOffset + i, y + j + fontChar.adjYOffset);
+ display_setPixel(fcolor);
+ }
+
+ mask >>= 1;
+ }
+ }
+ }
+ return fontChar.xDelta;
+}
+
+/* Rotate a proportional char */
+int display_rotatePropChar(byte c, int x, int y, int offset, int deg)
+{
+ propFont fontChar;
+
+ if (!display_getCharPtr(c, fontChar))
+ {
+ return 0;
+ }
+
+ byte ch = 0;
+ byte *tempPtr = fontChar.dataPtr;
+ double radian = deg * 0.0175;
+
+ word fcolor = display_getColor();
+
+ if (fontChar.width != 0)
+ {
+ byte mask = 0x80;
+ float cos_radian = cos(radian);
+ float sin_radian = sin(radian);
+ for (int j = 0; j < fontChar.height; j++)
+ {
+ for (int i = 0; i < fontChar.width; i++)
+ {
+ if (((i + (j*fontChar.width)) % 8) == 0)
+ {
+ mask = 0x80;
+ ch = pgm_read_byte(tempPtr++);
+ }
+
+ int newX = x + ((offset + i) * cos_radian - (j + fontChar.adjYOffset)*sin_radian);
+ int newY = y + ((j + fontChar.adjYOffset) * cos_radian + (offset + i) * sin_radian);
+ if ((ch & mask) != 0)
+ {
+ display_setXY(newX, newY, newX, newY);
+ display_setPixel(fcolor);
+ }
+ else
+ {
+ if (!transparent)
+ {
+ display_setXY(newX, newY, newX, newY);
+ display_setPixel(display_getBackColor());
+ }
+ }
+ mask >>= 1;
+ }
+ }
+ }
+
+ display_clrXY();
+
+ return fontChar.xDelta;
+}
+
+/* Rotate a char on the display */
+void display_rotateChar(byte c, int x, int y, int pos, int deg)
+{
+ byte i, j, ch;
+ word temp;
+ int newx, newy;
+ double radian;
+ radian = deg * 0.0175;
+
+ temp = ((c - cfont.offset) * ((cfont.x_size / 8) * cfont.y_size)) + 4;
+ for (j = 0; j < cfont.y_size; j++) {
+ for (int zz = 0; zz < (cfont.x_size / 8); zz++) {
+ ch = pgm_read_byte(&cfont.font[temp + zz]);
+ for (i = 0; i < 8; i++) {
+ newx = x
+ + (((i + (zz * 8) + (pos * cfont.x_size)) * cos(radian))
+ - ((j)* sin(radian)));
+ newy = y
+ + (((j)* cos(radian))
+ + ((i + (zz * 8) + (pos * cfont.x_size))
+ * sin(radian)));
+
+ display_setXY(newx, newy, newx + 1, newy + 1);
+
+ if ((ch & (1 << (7 - i))) != 0) {
+ display_setPixel((fch << 8) | fcl);
+ }
+ else {
+ if (!transparent)
+ display_setPixel((bch << 8) | bcl);
+ }
+ }
+ }
+ temp += (cfont.x_size / 8);
+ }
+ display_clrXY();
+}
+
+/* Print char array on the display */
+void display_print(char* st, int x, int y, int deg)
+{
+ int stl, i;
+
+ stl = strlen(st);
+
+ //For buffer display on Teensy 3.1 / 3.2, half coordinates
+ if ((display_writeToImage) && ((teensyVersion == teensyVersion_old) || (!hqRes))) {
+ x = x / 2;
+ y = y / 2;
+ }
+
+ if (orient == PORTRAIT) {
+ if (x == RIGHT)
+ x = 320 - (stl * cfont.x_size);
+ if (x == CENTER)
+ x = (320 - (stl * cfont.x_size)) / 2;
+ }
+ else {
+ if (x == RIGHT)
+ x = 240 - (stl * cfont.x_size);
+ if (x == CENTER)
+ x = (240 - (stl * cfont.x_size)) / 2;
+ }
+
+ int offset = 0;
+ for (i = 0; i < stl; i++)
+ {
+ if (deg == 0)
+ {
+ if (cfont.x_size == 0)
+ x += display_printProportionalChar(*st++, x, y) + 1;
+ else
+ {
+ display_printChar(*st++, x, y);
+ x += cfont.x_size;
+ }
+ }
+ else
+ {
+ if (cfont.x_size == 0)
+ offset += display_rotatePropChar(*st++, x, y, offset, deg);
+ else
+ display_rotateChar(*st++, x, y, i, deg);
+ }
+ }
+}
+
+/* Print a rotated string on the display */
+void display_print(String st, int x, int y, int deg)
+{
+ char buf[st.length() + 1];
+ st.toCharArray(buf, st.length() + 1);
+ display_print(buf, x, y, deg);
+}
+
+/* Print string on the display */
+void display_printC(String st, int x, int y, uint32_t color)
+{
+ char buf[st.length() + 1];
+ display_setColor(color);
+ st.toCharArray(buf, st.length() + 1);
+ display_print(buf, x, y, 0);
+}
+
+/* Print an integer */
+void display_printNumI(long num, int x, int y, int length, char filler)
+{
+ char buf[25];
+ char st[27];
+ boolean neg = 0;
+ int c = 0, f = 0;
+
+ if (num == 0) {
+ if (length != 0) {
+ for (c = 0; c < (length - 1); c++)
+ st[c] = filler;
+ st[c] = 48;
+ st[c + 1] = 0;
+ }
+ else {
+ st[0] = 48;
+ st[1] = 0;
+ }
+ }
+ else {
+ if (num < 0) {
+ neg = 1;
+ num = -num;
+ }
+
+ while (num > 0) {
+ buf[c] = 48 + (num % 10);
+ c++;
+ num = (num - (num % 10)) / 10;
+ }
+ buf[c] = 0;
+
+ if (neg) {
+ st[0] = 45;
+ }
+
+ if (length > (c + neg)) {
+ for (int i = 0; i < (length - c - neg); i++) {
+ st[i + neg] = filler;
+ f++;
+ }
+ }
+
+ for (int i = 0; i < c; i++) {
+ st[i + neg + f] = buf[c - i - 1];
+ }
+ st[c + neg + f] = 0;
+
+ }
+
+ display_print(st, x, y);
+}
+
+/* Helper method to convert a float*/
+void display_convertFloat(char* buf, double num, int width, byte prec)
+{
+ dtostrf(num, width, prec, buf);
+}
+
+/* Print a float */
+void display_printNumF(double num, byte dec, int x, int y, char divider, int length, char filler)
+{
+ char st[27];
+ boolean neg = 0;
+
+ if (dec < 1)
+ dec = 1;
+ else if (dec > 5)
+ dec = 5;
+
+ if (num < 0)
+ neg = 1;
+ display_convertFloat(st, num, length, dec);
+ if (divider != '.') {
+ for (uint16_t i = 0; i < sizeof(st); i++)
+ if (st[i] == '.')
+ st[i] = divider;
+ }
+
+ if (filler != ' ') {
+ if (neg) {
+ st[0] = '-';
+ for (uint16_t i = 1; i < sizeof(st); i++)
+ if ((st[i] == ' ') || (st[i] == '-'))
+ st[i] = filler;
+ }
+ else {
+ for (uint16_t i = 0; i < sizeof(st); i++)
+ if (st[i] == ' ')
+ st[i] = filler;
+ }
+ }
+
+ display_print(st, x, y);
+}
+
+/* Set a specific font */
+void display_setFont(const uint8_t* font)
+{
+ cfont.font = (uint8_t*) font;
+ cfont.x_size = fontbyte(0);
+ cfont.y_size = fontbyte(1);
+ cfont.offset = fontbyte(2);
+ cfont.numchars = fontbyte(3);
+}
+
+/* Get the current font */
+uint8_t* display_getFont()
+{
+ return cfont.font;
+}
+
+/* Get the x size of the current font */
+uint8_t display_getFontXsize()
+{
+ return cfont.x_size;
+}
+
+/* Get the y size of the current font */
+uint8_t display_getFontYsize()
+{
+ return cfont.y_size;
+}
+
+/* Draw a bitmap on the screen */
+void display_drawBitmap(int x, int y, int sx, int sy, unsigned short* data, int scale)
+{
+ unsigned int col;
+ int tx, ty, tsx, tsy, tc;
+ byte VH, VL;
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+
+ //Unscaled
+ if (scale == 1)
+ {
+ if (orient == PORTRAIT)
+ {
+
+ display_setXY(x, y, x + sx - 1, y + sy - 1);
+ for (tc = 0; tc < (sx*sy); tc++)
+ {
+ col = pgm_read_word(&data[tc]);
+ VH = col >> 8;
+ VL = col & 0xff;
+ display_writedata16_last((VH << 8) | VL);
+ }
+ display_setAddr(0, 0, 319, 239);
+ display_writecommand_last(ILI9341_RAMWR);
+
+ }
+ else
+ {
+ for (ty = 0; ty < sy; ty++)
+ {
+ display_setXY(x, y + ty, x + sx - 1, y + ty);
+ for (tx = sx - 1; tx >= 0; tx--)
+ {
+ col = pgm_read_word(&data[(ty*sx) + tx]);
+ VH = col >> 8;
+ VL = col & 0xff;
+ display_writedata16_last((VH << 8) | VL);
+ }
+ }
+ display_setAddr(0, 0, 239, 319);
+ display_writecommand_last(ILI9341_RAMWR); // write to RAM
+ }
+ }
+
+ //Scaled
+ else
+ {
+ if (orient == PORTRAIT)
+ {
+ for (ty = 0; ty < sy; ty++)
+ {
+ display_setAddr(x, y + (ty*scale), x + ((sx*scale) - 1), y + (ty*scale) + scale);
+ display_writecommand_last(ILI9341_RAMWR);
+ for (tsy = 0; tsy < scale; tsy++)
+ for (tx = 0; tx < sx; tx++)
+ {
+ col = pgm_read_word(&data[(ty*sx) + tx]);
+ for (tsx = 0; tsx < scale; tsx++) {
+ VH = col >> 8;
+ VL = col & 0xff;
+ display_writedata16_last((VH << 8) | VL);
+ }
+ }
+ }
+ display_setAddr(0, 0, 319, 239);
+ display_writecommand_last(ILI9341_RAMWR);
+
+ }
+ else
+ {
+ for (ty = 0; ty < sy; ty++)
+ {
+ for (tsy = 0; tsy < scale; tsy++)
+ {
+ display_setAddr(x, y + (ty*scale) + tsy, x + ((sx*scale) - 1), y + (ty*scale) + tsy);
+ display_writecommand_last(ILI9341_RAMWR);
+ for (tx = sx - 1; tx >= 0; tx--)
+ {
+ col = pgm_read_word(&data[(ty*sx) + tx]);
+ for (tsx = 0; tsx < scale; tsx++) {
+ VH = col >> 8;
+ VL = col & 0xff;
+ display_writedata16_last((VH << 8) | VL);
+ }
+ }
+ }
+ }
+ display_setAddr(0, 0, 239, 319);
+ display_writecommand_last(ILI9341_RAMWR);
+ }
+ }
+
+ SPI.endTransaction();
+}
+
+/* Print a rotated bitmap */
+void display_drawBitmap(int x, int y, int sx, int sy, unsigned short* data, int deg, int rox, int roy)
+{
+ unsigned int col;
+ int tx, ty, newx, newy;
+ double radian;
+ radian = deg*0.0175;
+
+ if (deg == 0)
+ display_drawBitmap(x, y, sx, sy, data);
+ else
+ {
+ for (ty = 0; ty < sy; ty++)
+ for (tx = 0; tx < sx; tx++)
+ {
+ col = pgm_read_word(&data[(ty*sx) + tx]);
+
+ newx = x + rox + (((tx - rox)*cos(radian)) - ((ty - roy)*sin(radian)));
+ newy = y + roy + (((ty - roy)*cos(radian)) + ((tx - rox)*sin(radian)));
+
+ display_setXY(newx, newy, newx, newy);
+ display_LCD_Write_DATA(col >> 8, col & 0xff);
+ }
+
+ }
+ display_clrXY();
+}
+
+/* Write a paletted bitmap with 2BPP */
+void display_writeRect2BPP(int16_t x, int16_t y, int16_t w, int16_t h, const uint8_t* pixels, const uint16_t* palette)
+{
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+ display_setAddr(x, y, x + w - 1, y + h - 1);
+ display_writecommand_cont(ILI9341_RAMWR);
+ for (y = h; y > 0; y--) {
+ for (x = w; x > 4; x -= 4) {
+ display_writedata16_cont(palette[((*pixels) >> 6) & 0x3]);
+ display_writedata16_cont(palette[((*pixels) >> 4) & 0x3]);
+ display_writedata16_cont(palette[((*pixels) >> 2) & 0x3]);
+ display_writedata16_cont(palette[(*pixels++) & 0x3]);
+ }
+ display_writedata16_cont(palette[((*pixels) >> 6) & 0x3]);
+ display_writedata16_cont(palette[((*pixels) >> 4) & 0x3]);
+ display_writedata16_cont(palette[((*pixels) >> 2) & 0x3]);
+ display_writedata16_last(palette[(*pixels++) & 0x3]);
+ }
+ SPI.endTransaction();
+}
+
+/* Write a paletted bitmap with 4BPP */
+void display_writeRect4BPP(int16_t x, int16_t y, int16_t w, int16_t h, const uint8_t* pixels, const uint16_t* palette)
+{
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+ display_setAddr(x, y, x + w - 1, y + h - 1);
+ display_writecommand_cont(ILI9341_RAMWR);
+ for (y = h; y > 0; y--) {
+ for (x = w; x > 2; x -= 2) {
+ display_writedata16_cont(palette[((*pixels) >> 4) & 0xF]);
+ display_writedata16_cont(palette[(*pixels++) & 0xF]);
+ }
+ display_writedata16_cont(palette[((*pixels) >> 4) & 0xF]);
+ display_writedata16_last(palette[(*pixels++) & 0xF]);
+ }
+ SPI.endTransaction();
+}
+
+/* Returns the string width in pixels */
+int display_getStringWidth(char* str)
+{
+ //Fixed font width
+ if (cfont.x_size != 0)
+ {
+ return (strlen(str) * cfont.x_size);
+ }
+
+ //Calculate the string width
+ int strWidth = 0;
+ while (*str != 0)
+ {
+ propFont fontChar;
+ boolean found = display_getCharPtr(*str, fontChar);
+
+ if (found && *str == fontChar.charCode)
+ {
+ strWidth += fontChar.xDelta + 1;
+ }
+
+ str++;
+ }
+
+ return strWidth;
+}
+
+/* Enter sleep mode */
+void display_enterSleepMode()
+{
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+ display_writecommand_last(ILI9341_SLPIN);
+ SPI.endTransaction();
+}
+
+/* Exit sleep mode */
+void display_exitSleepMode()
+{
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+ display_writecommand_last(ILI9341_SLPOUT);
+ SPI.endTransaction();
+}
+
+/* Read Pixel at x,y and get back 16-bit packed color */
+uint16_t display_readPixel(int16_t x, int16_t y)
+{
+ uint8_t r, g, b;
+
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+
+ display_setAddr(x, y, x, y);
+ display_writecommand_cont(ILI9341_RAMRD);
+ display_waitTransmitComplete();
+
+ KINETISK_SPI0.PUSHR = 0 | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
+ display_waitFifoEmpty();
+
+ KINETISK_SPI0.PUSHR = 0 | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
+ KINETISK_SPI0.PUSHR = 0 | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
+ KINETISK_SPI0.PUSHR = 0 | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ;
+
+ while ((KINETISK_SPI0.SR & SPI_SR_EOQF) == 0);
+ KINETISK_SPI0.SR = SPI_SR_EOQF;
+
+ KINETISK_SPI0.POPR;
+ r = KINETISK_SPI0.POPR;
+ g = KINETISK_SPI0.POPR;
+ b = KINETISK_SPI0.POPR;
+
+ SPI.endTransaction();
+ return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
+}
+
+/* Write RGB565 data to the screen */
+void display_writeScreen(unsigned short* pcolors, boolean small)
+{
+ SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE0));
+ display_setAddr(0, 0, 319, 239);
+ display_writecommand_cont(ILI9341_RAMWR);
+
+ //160x120 array, doubled
+ if (small) {
+ for (byte y = 120; y > 0; y--) {
+ for (byte x = 160; x > 1; x--) {
+ display_writedata16_cont(*pcolors);
+ display_writedata16_cont(*pcolors++);
+ }
+ display_writedata16_cont(*pcolors);
+ display_writedata16_last(*pcolors++);
+ pcolors = pcolors - 160;
+ for (byte x = 160; x > 1; x--) {
+ display_writedata16_cont(*pcolors);
+ display_writedata16_cont(*pcolors++);
+ }
+ display_writedata16_cont(*pcolors);
+ display_writedata16_last(*pcolors++);
+ }
+ }
+ //320x240 array
+ else
+ {
+ uint16_t *colors_end = &pcolors[76799];
+ uint16_t *colors_curr = pcolors;
+
+ // Quick write out the data;
+ while (colors_curr < colors_end) {
+ display_writedata16_cont(*colors_curr++);
+ }
+ display_writedata16_last(*colors_curr);
+ }
+
+ SPI.endTransaction();
+}
+
+/* Read multiple pixels from the screen */
+void display_readScreen(byte step, unsigned short* pcolors)
+{
+ uint8_t r, g, b;
+ uint16_t c = 19201;
+
+ SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
+
+ display_setAddr(0, (step * 60), 319, (step * 60) + 59);
+ display_writecommand_cont(ILI9341_RAMRD);
+ display_waitTransmitComplete();
+ KINETISK_SPI0.PUSHR = 0 | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT | SPI_PUSHR_EOQ;
+ while ((KINETISK_SPI0.SR & SPI_SR_EOQF) == 0);
+ KINETISK_SPI0.SR = SPI_SR_EOQF;
+ while ((KINETISK_SPI0.SR & 0xf0)) {
+ KINETISK_SPI0.POPR;
+ }
+ c *= 3;
+ while (c--) {
+ if (c) {
+ KINETISK_SPI0.PUSHR = 0 | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
+ }
+ else {
+ KINETISK_SPI0.PUSHR = 0 | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ;
+ }
+
+
+ if (c == 0) {
+ while ((KINETISK_SPI0.SR & SPI_SR_EOQF) == 0);
+ KINETISK_SPI0.SR = SPI_SR_EOQF;
+ }
+
+ if ((KINETISK_SPI0.SR & 0xf0) >= 0x30) {
+ r = KINETISK_SPI0.POPR;
+ g = KINETISK_SPI0.POPR;
+ b = KINETISK_SPI0.POPR;
+ *pcolors++ = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
+ }
+
+ while ((KINETISK_SPI0.SR & (15 << 12)) > (3 << 12));
+ }
+ SPI.endTransaction();
+}
+
+void display_HLine(int16_t x, int16_t y, int16_t w, uint16_t color)
+{
+ display_setAddr(x, y, x + w - 1, y);
+ display_writecommand_cont(ILI9341_RAMWR);
+ do {
+ display_writedata16_cont(color);
+ } while (--w > 0);
+}
+
+void display_VLine(int16_t x, int16_t y, int16_t h, uint16_t color)
+{
+ display_setAddr(x, y, x, y + h - 1);
+ display_writecommand_cont(ILI9341_RAMWR);
+ do {
+ display_writedata16_cont(color);
+ } while (--h > 0);
+}
+
+void display_Pixel(int16_t x, int16_t y, uint16_t color)
+{
+ display_setAddr(x, y, x, y);
+ display_writecommand_cont(ILI9341_RAMWR);
+ display_writedata16_cont(color);
+}
diff --git a/Firmware_V2/src/hardware/display/display.h b/Firmware_V2/src/hardware/display/display.h
new file mode 100644
index 0000000..1c40f46
--- /dev/null
+++ b/Firmware_V2/src/hardware/display/display.h
@@ -0,0 +1,128 @@
+/*
+*
+* Display - ILI9341 SPI Display Module
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef DISPLAY_H
+#define DISPLAY_H
+
+/*################# PUBLIC CONSTANTS, VARIABLES & DATA TYPES ##################*/
+
+#define LEFT 0
+#define RIGHT 9999
+#define CENTER 9998
+
+#define PORTRAIT 0
+#define LANDSCAPE 1
+
+#define VGA_BLACK 0x0000
+#define VGA_WHITE 0xFFFF
+#define VGA_RED 0xF800
+#define VGA_GREEN 0x0400
+#define VGA_BLUE 0x001F
+#define VGA_SILVER 0xC618
+#define VGA_GRAY 0x8410
+#define VGA_MAROON 0x8000
+#define VGA_YELLOW 0xFE40
+#define VGA_OLIVE 0x8400
+#define VGA_LIME 0x07E0
+#define VGA_AQUA 0xBE7F
+#define VGA_TEAL 0x0410
+#define VGA_NAVY 0x0010
+#define VGA_FUCHSIA 0xF81F
+#define VGA_PURPLE 0x8010
+#define VGA_TRANSPARENT 0xFFFFFFFF
+
+struct propFont
+{
+ byte charCode;
+ int adjYOffset;
+ int width;
+ int height;
+ int xOffset;
+ int xDelta;
+ byte* dataPtr;
+};
+
+extern boolean display_writeToImage;
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+void display_clrScr();
+void display_clrXY();
+void display_convertFloat(char* buf, double num, int width, byte prec);
+void display_drawBitmap(int x, int y, int sx, int sy, unsigned short* data, int scale = 1);
+void display_drawCircle(int x, int y, int radius);
+void display_drawHLine(int x, int y, int l);
+void display_drawLine(int x1, int y1, int x2, int y2);
+void display_drawPixel(int x, int y);
+void display_drawRect(int x1, int y1, int x2, int y2);
+void display_drawRoundRect(int x1, int y1, int x2, int y2);
+void display_drawVLine(int x, int y, int l);
+void display_enterSleepMode();
+void display_exitSleepMode();
+void display_fillCircle(int x, int y, int radius);
+void display_fillRect(int x1, int y1, int x2, int y2);
+void display_fillRoundRect(int x1, int y1, int x2, int y2);
+void display_fillScr(word color);
+void display_fillScr(byte r, byte g, byte b);
+word display_getBackColor();
+boolean display_getCharPtr(byte c, propFont& fontChar);
+word display_getColor();
+int display_getFontHeight();
+uint8_t* display_getFont();
+uint8_t display_getFontXsize();
+uint8_t display_getFontYsize();
+int display_getStringWidth(char* str);
+void display_HLine(int16_t x, int16_t y, int16_t w, uint16_t color);
+byte display_InitLCD();
+void display_init();
+void display_LCD_Write_DATA(char VH, char VL);
+void display_Pixel(int16_t x, int16_t y, uint16_t color);
+void display_printChar(byte c, int x, int y);
+void display_printC(String st, int x, int y, uint32_t color = VGA_BLACK);
+void display_printNumF(double num, byte dec, int x, int y, char divider = '.', int length = 0, char filler = ' ');
+void display_printNumI(long num, int x, int y, int length = 0, char filler = ' ');
+int display_printProportionalChar(byte c, int x, int y);
+void display_print(char* st, int x, int y, int deg = 0);
+void display_print(String st, int x, int y, int deg = 0);
+uint8_t display_readcommand8(uint8_t c, uint8_t index = 0);
+uint16_t display_readPixel(int16_t x, int16_t y);
+void display_readScreen(byte step, unsigned short* pcolors);
+void display_rotateChar(byte c, int x, int y, int pos, int deg);
+int display_rotatePropChar(byte c, int x, int y, int offset, int deg);
+void display_setAddr(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
+void display_setBackColor(byte r, byte g, byte b);
+void display_setBackColor(uint32_t color);
+void display_setColor(byte r, byte g, byte b);
+void display_setColor(word color);
+void display_setFont(const uint8_t* font);
+void display_setPixel(word color);
+void display_setRotation(uint8_t m);
+void display_setXY(word x1, word y1, word x2, word y2);
+void display_VLine(int16_t x, int16_t y, int16_t h, uint16_t color);
+void display_waitFifoEmpty();
+void display_waitFifoNotFull();
+void display_waitTransmitComplete();
+void display_writecommand_cont(uint8_t c);
+void display_writecommand_last(uint8_t c);
+void display_writedata16_cont(uint16_t d);
+void display_writedata16_last(uint16_t d);
+void display_writedata8_cont(uint8_t c);
+void display_writedata8_last(uint8_t c);
+void display_writeRect2BPP(int16_t x, int16_t y, int16_t w, int16_t h, const uint8_t* pixels, const uint16_t* palette);
+void display_writeRect4BPP(int16_t x, int16_t y, int16_t w, int16_t h, const uint8_t* pixels, const uint16_t* palette);
+void display_writeScreen(unsigned short* pcolors, boolean small);
+
+
+#endif /* DISPLAY_H */
diff --git a/Firmware_V2/src/hardware/display/fonts.cpp b/Firmware_V2/src/hardware/display/fonts.cpp
new file mode 100644
index 0000000..69fded5
--- /dev/null
+++ b/Firmware_V2/src/hardware/display/fonts.cpp
@@ -0,0 +1,518 @@
+/*
+*
+* Fonts
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+
+/*############################# PUBLIC VARIABLES ##############################*/
+
+/* Tiny Font */
+const uint8_t tinyFont[] =
+{
+ 0x00, 0x06, 0x00, 0x00,
+ // ' '
+ 0x20,0x05,0x00,0x00,0x00,0x04,
+ // '!'
+ 0x21,0x00,0x01,0x05,0x00,0x02,
+ 0xE8,
+ // '"'
+ 0x22,0x00,0x03,0x02,0x00,0x04,
+ 0xB4,
+ // '#'
+ 0x23,0x00,0x03,0x05,0x00,0x04,
+ 0xBE,0xFA,
+ // '$'
+ 0x24,0x00,0x03,0x05,0x00,0x04,
+ 0xFB,0xBE,
+ // '%'
+ 0x25,0x00,0x03,0x05,0x00,0x04,
+ 0x85,0x42,
+ // '&'
+ 0x26,0x00,0x03,0x05,0x00,0x04,
+ 0x5E,0x74,
+ // '''
+ 0x27,0x00,0x01,0x02,0x00,0x02,
+ 0xC0,
+ // '('
+ 0x28,0x00,0x02,0x05,0x00,0x03,
+ 0x6A,0x40,
+ // ')'
+ 0x29,0x00,0x02,0x05,0x00,0x03,
+ 0x95,0x80,
+ // '*'
+ 0x2A,0x01,0x03,0x03,0x00,0x04,
+ 0x55,0x00,
+ // '+'
+ 0x2B,0x01,0x03,0x03,0x00,0x04,
+ 0x5D,0x00,
+ // ','
+ 0x2C,0x03,0x02,0x02,0x00,0x03,
+ 0x70,
+ // '-'
+ 0x2D,0x02,0x03,0x01,0x00,0x04,
+ 0xE0,
+ // '.'
+ 0x2E,0x04,0x01,0x01,0x00,0x02,
+ 0x80,
+ // '/'
+ 0x2F,0x01,0x03,0x03,0x00,0x04,
+ 0x2A,0x00,
+ // '0'
+ 0x30,0x00,0x03,0x05,0x00,0x04,
+ 0xF6,0xDE,
+ // '1'
+ 0x31,0x00,0x03,0x05,0x00,0x04,
+ 0xC9,0x2E,
+ // '2'
+ 0x32,0x00,0x03,0x05,0x00,0x04,
+ 0xE7,0xCE,
+ // '3'
+ 0x33,0x00,0x03,0x05,0x00,0x04,
+ 0xE7,0x9E,
+ // '4'
+ 0x34,0x00,0x03,0x05,0x00,0x04,
+ 0xB7,0x92,
+ // '5'
+ 0x35,0x00,0x03,0x05,0x00,0x04,
+ 0xF3,0x9E,
+ // '6'
+ 0x36,0x00,0x03,0x05,0x00,0x04,
+ 0xF3,0xDE,
+ // '7'
+ 0x37,0x00,0x03,0x05,0x00,0x04,
+ 0xE4,0x92,
+ // '8'
+ 0x38,0x00,0x03,0x05,0x00,0x04,
+ 0xF7,0xDE,
+ // '9'
+ 0x39,0x00,0x03,0x05,0x00,0x04,
+ 0xF7,0x9E,
+ // ':'
+ 0x3A,0x01,0x01,0x03,0x00,0x02,
+ 0xA0,
+ // ';'
+ 0x3B,0x01,0x02,0x04,0x00,0x03,
+ 0x47,
+ // '<'
+ 0x3C,0x00,0x03,0x05,0x00,0x04,
+ 0x2A,0x22,
+ // '='
+ 0x3D,0x01,0x03,0x03,0x00,0x04,
+ 0xE3,0x80,
+ // '>'
+ 0x3E,0x00,0x03,0x05,0x00,0x04,
+ 0x88,0xA8,
+ // '?'
+ 0x3F,0x00,0x03,0x05,0x00,0x04,
+ 0xE5,0x84,
+ // '@'
+ 0x40,0x00,0x03,0x05,0x00,0x04,
+ 0xF6,0xCE,
+ // 'A'
+ 0x41,0x00,0x03,0x05,0x00,0x04,
+ 0xF7,0xDA,
+ // 'B'
+ 0x42,0x00,0x03,0x05,0x00,0x04,
+ 0xF7,0x5E,
+ // 'C'
+ 0x43,0x00,0x03,0x05,0x00,0x04,
+ 0xF2,0x4E,
+ // 'D'
+ 0x44,0x00,0x03,0x05,0x00,0x04,
+ 0xD6,0xDC,
+ // 'E'
+ 0x45,0x00,0x03,0x05,0x00,0x04,
+ 0xF3,0xCE,
+ // 'F'
+ 0x46,0x00,0x03,0x05,0x00,0x04,
+ 0xF3,0xC8,
+ // 'G'
+ 0x47,0x00,0x03,0x05,0x00,0x04,
+ 0xF2,0xDE,
+ // 'H'
+ 0x48,0x00,0x03,0x05,0x00,0x04,
+ 0xB7,0xDA,
+ // 'I'
+ 0x49,0x00,0x03,0x05,0x00,0x04,
+ 0xE9,0x2E,
+ // 'J'
+ 0x4A,0x00,0x03,0x05,0x00,0x04,
+ 0x24,0xDE,
+ // 'K'
+ 0x4B,0x00,0x03,0x05,0x00,0x04,
+ 0xB7,0x5A,
+ // 'L'
+ 0x4C,0x00,0x03,0x05,0x00,0x04,
+ 0x92,0x4E,
+ // 'M'
+ 0x4D,0x00,0x05,0x05,0x00,0x06,
+ 0xFD,0x6B,0x5A,0x80,
+ // 'N'
+ 0x4E,0x00,0x03,0x05,0x00,0x04,
+ 0xF6,0xDA,
+ // 'O'
+ 0x4F,0x00,0x03,0x05,0x00,0x04,
+ 0xF6,0xDE,
+ // 'P'
+ 0x50,0x00,0x03,0x05,0x00,0x04,
+ 0xF7,0xC8,
+ // 'Q'
+ 0x51,0x00,0x03,0x06,0x00,0x04,
+ 0xF6,0xDE,0x80,
+ // 'R'
+ 0x52,0x00,0x03,0x05,0x00,0x04,
+ 0xF7,0x5A,
+ // 'S'
+ 0x53,0x00,0x03,0x05,0x00,0x04,
+ 0xF3,0x9E,
+ // 'T'
+ 0x54,0x00,0x03,0x05,0x00,0x04,
+ 0xE9,0x24,
+ // 'U'
+ 0x55,0x00,0x03,0x05,0x00,0x04,
+ 0xB6,0xDE,
+ // 'V'
+ 0x56,0x00,0x03,0x05,0x00,0x04,
+ 0xB6,0xD4,
+ // 'W'
+ 0x57,0x00,0x05,0x05,0x00,0x06,
+ 0xAD,0x6B,0x5F,0x80,
+ // 'X'
+ 0x58,0x00,0x03,0x05,0x00,0x04,
+ 0xB5,0x5A,
+ // 'Y'
+ 0x59,0x00,0x03,0x05,0x00,0x04,
+ 0xB7,0xA4,
+ // 'Z'
+ 0x5A,0x00,0x03,0x05,0x00,0x04,
+ 0xE5,0x4E,
+ // '['
+ 0x5B,0x00,0x02,0x05,0x00,0x03,
+ 0xEA,0xC0,
+ // '\'
+ 0x5C,0x01,0x03,0x03,0x00,0x04,
+ 0x88,0x80,
+ // ']'
+ 0x5D,0x00,0x02,0x05,0x00,0x03,
+ 0xD5,0xC0,
+ // '^'
+ 0x5E,0x00,0x03,0x02,0x00,0x04,
+ 0x54,
+ // '_'
+ 0x5F,0x04,0x03,0x01,0x00,0x04,
+ 0xE0,
+ // '`'
+ 0x60,0x00,0x02,0x02,0x00,0x03,
+ 0x90,
+ // 'a'
+ 0x61,0x01,0x03,0x04,0x00,0x04,
+ 0x76,0xB0,
+ // 'b'
+ 0x62,0x00,0x03,0x05,0x00,0x04,
+ 0x9A,0xDC,
+ // 'c'
+ 0x63,0x01,0x03,0x04,0x00,0x04,
+ 0xF2,0x70,
+ // 'd'
+ 0x64,0x00,0x03,0x05,0x00,0x04,
+ 0x2E,0xD6,
+ // 'e'
+ 0x65,0x01,0x03,0x04,0x00,0x04,
+ 0x57,0x30,
+ // 'f'
+ 0x66,0x00,0x03,0x05,0x00,0x04,
+ 0x6B,0xA4,
+ // 'g'
+ 0x67,0x01,0x03,0x05,0x00,0x04,
+ 0xF7,0x9C,
+ // 'h'
+ 0x68,0x00,0x03,0x05,0x00,0x04,
+ 0x9A,0xDA,
+ // 'i'
+ 0x69,0x00,0x01,0x05,0x00,0x02,
+ 0xB8,
+ // 'j'
+ 0x6A,0x00,0x02,0x06,0x00,0x03,
+ 0x45,0x60,
+ // 'k'
+ 0x6B,0x00,0x03,0x05,0x00,0x04,
+ 0x97,0x5A,
+ // 'l'
+ 0x6C,0x00,0x02,0x05,0x00,0x03,
+ 0xD5,0x40,
+ // 'm'
+ 0x6D,0x01,0x05,0x04,0x00,0x06,
+ 0xFD,0x6B,0x50,
+ // 'n'
+ 0x6E,0x01,0x03,0x04,0x00,0x04,
+ 0xF6,0xD0,
+ // 'o'
+ 0x6F,0x01,0x03,0x04,0x00,0x04,
+ 0xF6,0xF0,
+ // 'p'
+ 0x70,0x01,0x03,0x05,0x00,0x04,
+ 0xD6,0xE8,
+ // 'q'
+ 0x71,0x01,0x03,0x05,0x00,0x04,
+ 0x76,0xB2,
+ // 'r'
+ 0x72,0x01,0x03,0x04,0x00,0x04,
+ 0xF6,0x40,
+ // 's'
+ 0x73,0x01,0x03,0x04,0x00,0x04,
+ 0x70,0xE0,
+ // 't'
+ 0x74,0x00,0x03,0x05,0x00,0x04,
+ 0x5D,0x26,
+ // 'u'
+ 0x75,0x01,0x03,0x04,0x00,0x04,
+ 0xB6,0xF0,
+ // 'v'
+ 0x76,0x01,0x03,0x04,0x00,0x04,
+ 0xB6,0xA0,
+ // 'w'
+ 0x77,0x01,0x05,0x04,0x00,0x06,
+ 0xAD,0x6B,0xF0,
+ // 'x'
+ 0x78,0x01,0x03,0x04,0x00,0x04,
+ 0xAA,0xD0,
+ // 'y'
+ 0x79,0x01,0x03,0x05,0x00,0x04,
+ 0xB7,0x9C,
+ // 'z'
+ 0x7A,0x01,0x03,0x04,0x00,0x04,
+ 0xE6,0x70,
+ // '{'
+ 0x7B,0x00,0x03,0x05,0x00,0x04,
+ 0x6B,0x26,
+ // '|'
+ 0x7C,0x00,0x01,0x05,0x00,0x02,
+ 0xF8,
+ // '}'
+ 0x7D,0x00,0x03,0x05,0x00,0x04,
+ 0xC9,0xAC,
+ // '~'
+ 0x7E,0x01,0x04,0x02,0x00,0x05,
+ 0x5A,
+ // Terminator
+ 0xFF
+};
+
+/* Small Font */
+const uint8_t smallFont[] = {
+ 0x08,0x0C,0x20,0x5F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //
+ 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, // !
+ 0x00,0x28,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "
+ 0x00,0x00,0x28,0x28,0xFC,0x28,0x50,0xFC,0x50,0x50,0x00,0x00, // #
+ 0x00,0x20,0x78,0xA8,0xA0,0x60,0x30,0x28,0xA8,0xF0,0x20,0x00, // $
+ 0x00,0x00,0x48,0xA8,0xB0,0x50,0x28,0x34,0x54,0x48,0x00,0x00, // %
+ 0x00,0x00,0x20,0x50,0x50,0x78,0xA8,0xA8,0x90,0x6C,0x00,0x00, // &
+ 0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // '
+ 0x00,0x04,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x04,0x00, // (
+ 0x00,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x00, // )
+ 0x00,0x00,0x00,0x20,0xA8,0x70,0x70,0xA8,0x20,0x00,0x00,0x00, // *
+ 0x00,0x00,0x20,0x20,0x20,0xF8,0x20,0x20,0x20,0x00,0x00,0x00, // +
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x80, // ,
+ 0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, // -
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, // .
+ 0x00,0x08,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x80,0x00, // /
+ 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, // 0
+ 0x00,0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, // 1
+ 0x00,0x00,0x70,0x88,0x88,0x10,0x20,0x40,0x80,0xF8,0x00,0x00, // 2
+ 0x00,0x00,0x70,0x88,0x08,0x30,0x08,0x08,0x88,0x70,0x00,0x00, // 3
+ 0x00,0x00,0x10,0x30,0x50,0x50,0x90,0x78,0x10,0x18,0x00,0x00, // 4
+ 0x00,0x00,0xF8,0x80,0x80,0xF0,0x08,0x08,0x88,0x70,0x00,0x00, // 5
+ 0x00,0x00,0x70,0x90,0x80,0xF0,0x88,0x88,0x88,0x70,0x00,0x00, // 6
+ 0x00,0x00,0xF8,0x90,0x10,0x20,0x20,0x20,0x20,0x20,0x00,0x00, // 7
+ 0x00,0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x88,0x70,0x00,0x00, // 8
+ 0x00,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x48,0x70,0x00,0x00, // 9
+ 0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x20,0x00,0x00, // :
+ 0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x20,0x00, // ;
+ 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00, // <
+ 0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, // =
+ 0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00, // >
+ 0x00,0x00,0x70,0x88,0x88,0x10,0x20,0x20,0x00,0x20,0x00,0x00, // ?
+ 0x00,0x00,0x70,0x88,0x98,0xA8,0xA8,0xB8,0x80,0x78,0x00,0x00, // @
+ 0x00,0x00,0x20,0x20,0x30,0x50,0x50,0x78,0x48,0xCC,0x00,0x00, // A
+ 0x00,0x00,0xF0,0x48,0x48,0x70,0x48,0x48,0x48,0xF0,0x00,0x00, // B
+ 0x00,0x00,0x78,0x88,0x80,0x80,0x80,0x80,0x88,0x70,0x00,0x00, // C
+ 0x00,0x00,0xF0,0x48,0x48,0x48,0x48,0x48,0x48,0xF0,0x00,0x00, // D
+ 0x00,0x00,0xF8,0x48,0x50,0x70,0x50,0x40,0x48,0xF8,0x00,0x00, // E
+ 0x00,0x00,0xF8,0x48,0x50,0x70,0x50,0x40,0x40,0xE0,0x00,0x00, // F
+ 0x00,0x00,0x38,0x48,0x80,0x80,0x9C,0x88,0x48,0x30,0x00,0x00, // G
+ 0x00,0x00,0xCC,0x48,0x48,0x78,0x48,0x48,0x48,0xCC,0x00,0x00, // H
+ 0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00, // I
+ 0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0xE0,0x00, // J
+ 0x00,0x00,0xEC,0x48,0x50,0x60,0x50,0x50,0x48,0xEC,0x00,0x00, // K
+ 0x00,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x44,0xFC,0x00,0x00, // L
+ 0x00,0x00,0xD8,0xD8,0xD8,0xD8,0xA8,0xA8,0xA8,0xA8,0x00,0x00, // M
+ 0x00,0x00,0xDC,0x48,0x68,0x68,0x58,0x58,0x48,0xE8,0x00,0x00, // N
+ 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, // O
+ 0x00,0x00,0xF0,0x48,0x48,0x70,0x40,0x40,0x40,0xE0,0x00,0x00, // P
+ 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0xE8,0x98,0x70,0x18,0x00, // Q
+ 0x00,0x00,0xF0,0x48,0x48,0x70,0x50,0x48,0x48,0xEC,0x00,0x00, // R
+ 0x00,0x00,0x78,0x88,0x80,0x60,0x10,0x08,0x88,0xF0,0x00,0x00, // S
+ 0x00,0x00,0xF8,0xA8,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, // T
+ 0x00,0x00,0xCC,0x48,0x48,0x48,0x48,0x48,0x48,0x30,0x00,0x00, // U
+ 0x00,0x00,0xCC,0x48,0x48,0x50,0x50,0x30,0x20,0x20,0x00,0x00, // V
+ 0x00,0x00,0xA8,0xA8,0xA8,0x70,0x50,0x50,0x50,0x50,0x00,0x00, // W
+ 0x00,0x00,0xD8,0x50,0x50,0x20,0x20,0x50,0x50,0xD8,0x00,0x00, // X
+ 0x00,0x00,0xD8,0x50,0x50,0x20,0x20,0x20,0x20,0x70,0x00,0x00, // Y
+ 0x00,0x00,0xF8,0x90,0x10,0x20,0x20,0x40,0x48,0xF8,0x00,0x00, // Z
+ 0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, // [
+ 0x00,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x00,0x00, //
+ 0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00, // ]
+ 0x00,0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ^
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, // _
+ 0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // '
+ 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x38,0x48,0x3C,0x00,0x00, // a
+ 0x00,0x00,0xC0,0x40,0x40,0x70,0x48,0x48,0x48,0x70,0x00,0x00, // b
+ 0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x40,0x40,0x38,0x00,0x00, // c
+ 0x00,0x00,0x18,0x08,0x08,0x38,0x48,0x48,0x48,0x3C,0x00,0x00, // d
+ 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x78,0x40,0x38,0x00,0x00, // e
+ 0x00,0x00,0x1C,0x20,0x20,0x78,0x20,0x20,0x20,0x78,0x00,0x00, // f
+ 0x00,0x00,0x00,0x00,0x00,0x3C,0x48,0x30,0x40,0x78,0x44,0x38, // g
+ 0x00,0x00,0xC0,0x40,0x40,0x70,0x48,0x48,0x48,0xEC,0x00,0x00, // h
+ 0x00,0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x70,0x00,0x00, // i
+ 0x00,0x00,0x10,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0xE0, // j
+ 0x00,0x00,0xC0,0x40,0x40,0x5C,0x50,0x70,0x48,0xEC,0x00,0x00, // k
+ 0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00, // l
+ 0x00,0x00,0x00,0x00,0x00,0xF0,0xA8,0xA8,0xA8,0xA8,0x00,0x00, // m
+ 0x00,0x00,0x00,0x00,0x00,0xF0,0x48,0x48,0x48,0xEC,0x00,0x00, // n
+ 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x48,0x48,0x30,0x00,0x00, // o
+ 0x00,0x00,0x00,0x00,0x00,0xF0,0x48,0x48,0x48,0x70,0x40,0xE0, // p
+ 0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x48,0x48,0x38,0x08,0x1C, // q
+ 0x00,0x00,0x00,0x00,0x00,0xD8,0x60,0x40,0x40,0xE0,0x00,0x00, // r
+ 0x00,0x00,0x00,0x00,0x00,0x78,0x40,0x30,0x08,0x78,0x00,0x00, // s
+ 0x00,0x00,0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x18,0x00,0x00, // t
+ 0x00,0x00,0x00,0x00,0x00,0xD8,0x48,0x48,0x48,0x3C,0x00,0x00, // u
+ 0x00,0x00,0x00,0x00,0x00,0xEC,0x48,0x50,0x30,0x20,0x00,0x00, // v
+ 0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x70,0x50,0x50,0x00,0x00, // w
+ 0x00,0x00,0x00,0x00,0x00,0xD8,0x50,0x20,0x50,0xD8,0x00,0x00, // x
+ 0x00,0x00,0x00,0x00,0x00,0xEC,0x48,0x50,0x30,0x20,0x20,0xC0, // y
+ 0x00,0x00,0x00,0x00,0x00,0x78,0x10,0x20,0x20,0x78,0x00,0x00, // z
+ 0x00,0x18,0x10,0x10,0x10,0x20,0x10,0x10,0x10,0x10,0x18,0x00, // {
+ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, // |
+ 0x00,0x60,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0x60,0x00, // }
+ 0x40,0xA4,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ~
+};
+
+/* Big Font */
+const uint8_t bigFont[] = {
+ 0x10,0x10,0x20,0x5F,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //
+ 0x00,0x00,0x00,0x00,0x07,0x00,0x0F,0x80,0x0F,0x80,0x0F,0x80,0x0F,0x80,0x0F,0x80,0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00, // !
+ 0x00,0x00,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x06,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "
+ 0x00,0x00,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x7F,0xFE,0x7F,0xFE,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x7F,0xFE,0x7F,0xFE,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x00,0x00, // #
+ 0x00,0x00,0x02,0x40,0x02,0x40,0x0F,0xF8,0x1F,0xF8,0x1A,0x40,0x1A,0x40,0x1F,0xF0,0x0F,0xF8,0x02,0x58,0x02,0x58,0x1F,0xF8,0x1F,0xF0,0x02,0x40,0x02,0x40,0x00,0x00, // $
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x10,0x0E,0x30,0x0E,0x70,0x00,0xE0,0x01,0xC0,0x03,0x80,0x07,0x00,0x0E,0x70,0x0C,0x70,0x08,0x70,0x00,0x00,0x00,0x00,0x00,0x00, // %
+ 0x00,0x00,0x00,0x00,0x0F,0x00,0x19,0x80,0x19,0x80,0x19,0x80,0x0F,0x00,0x0F,0x08,0x0F,0x98,0x19,0xF8,0x18,0xF0,0x18,0xE0,0x19,0xF0,0x0F,0x98,0x00,0x00,0x00,0x00, // &
+ 0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // '
+ 0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0xC0,0x03,0x80,0x07,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xF0,0x00,0x00,0x00,0x00, // (
+ 0x00,0x00,0x00,0x00,0x0F,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0xE0,0x01,0xC0,0x03,0x80,0x0F,0x00,0x00,0x00,0x00,0x00, // )
+ 0x00,0x00,0x00,0x00,0x01,0x80,0x11,0x88,0x09,0x90,0x07,0xE0,0x07,0xE0,0x3F,0xFC,0x3F,0xFC,0x07,0xE0,0x07,0xE0,0x09,0x90,0x11,0x88,0x01,0x80,0x00,0x00,0x00,0x00, // *
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x0F,0xF0,0x0F,0xF0,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // +
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x0E,0x00,0x00,0x00, // ,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xF8,0x1F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // -
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00, // ,
+ 0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x06,0x00,0x0E,0x00,0x1C,0x00,0x38,0x00,0x70,0x00,0xE0,0x01,0xC0,0x03,0x80,0x07,0x00,0x0E,0x00,0x1C,0x00,0x00,0x00,0x00,0x00, // /
+
+ 0x00,0x00,0x00,0x00,0x0F,0xF0,0x1C,0x38,0x1C,0x78,0x1C,0xF8,0x1C,0xF8,0x1D,0xB8,0x1D,0xB8,0x1F,0x38,0x1F,0x38,0x1E,0x38,0x1C,0x38,0x0F,0xF0,0x00,0x00,0x00,0x00, // 0
+ 0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x03,0x80,0x1F,0x80,0x1F,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x1F,0xF0,0x00,0x00,0x00,0x00, // 1
+ 0x00,0x00,0x00,0x00,0x0F,0xE0,0x1C,0x70,0x1C,0x38,0x00,0x38,0x00,0x70,0x00,0xE0,0x01,0xC0,0x03,0x80,0x07,0x00,0x0E,0x38,0x1C,0x38,0x1F,0xF8,0x00,0x00,0x00,0x00, // 2
+ 0x00,0x00,0x00,0x00,0x0F,0xE0,0x1C,0x70,0x1C,0x38,0x00,0x38,0x00,0x70,0x03,0xC0,0x03,0xC0,0x00,0x70,0x00,0x38,0x1C,0x38,0x1C,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // 3
+ 0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0xE0,0x03,0xE0,0x06,0xE0,0x0C,0xE0,0x18,0xE0,0x1F,0xF8,0x1F,0xF8,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x03,0xF8,0x00,0x00,0x00,0x00, // 4
+ 0x00,0x00,0x00,0x00,0x1F,0xF8,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1F,0xE0,0x1F,0xF0,0x00,0x78,0x00,0x38,0x1C,0x38,0x1C,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // 5
+ 0x00,0x00,0x00,0x00,0x03,0xE0,0x07,0x00,0x0E,0x00,0x1C,0x00,0x1C,0x00,0x1F,0xF0,0x1F,0xF8,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x0F,0xF0,0x00,0x00,0x00,0x00, // 6
+ 0x00,0x00,0x00,0x00,0x1F,0xFC,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x00,0x1C,0x00,0x38,0x00,0x70,0x00,0xE0,0x01,0xC0,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00, // 7
+ 0x00,0x00,0x00,0x00,0x0F,0xF0,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1F,0x38,0x07,0xE0,0x07,0xE0,0x1C,0xF8,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x0F,0xF0,0x00,0x00,0x00,0x00, // 8
+ 0x00,0x00,0x00,0x00,0x0F,0xF0,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1F,0xF8,0x0F,0xF8,0x00,0x38,0x00,0x38,0x00,0x70,0x00,0xE0,0x07,0xC0,0x00,0x00,0x00,0x00, // 9
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // :
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ;
+ 0x00,0x00,0x00,0x70,0x00,0xE0,0x01,0xC0,0x03,0x80,0x07,0x00,0x0E,0x00,0x1C,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x00, // <
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xFC,0x3F,0xFC,0x00,0x00,0x00,0x00,0x3F,0xFC,0x3F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // =
+ 0x00,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x70,0x00,0xE0,0x01,0xC0,0x03,0x80,0x07,0x00,0x0E,0x00,0x1C,0x00,0x00,0x00, // >
+ 0x00,0x00,0x03,0xC0,0x0F,0xF0,0x1E,0x78,0x18,0x38,0x00,0x38,0x00,0x70,0x00,0xE0,0x01,0xC0,0x01,0xC0,0x00,0x00,0x00,0x00,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x00,0x00, // ?
+
+ 0x00,0x00,0x0F,0xF8,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0xFC,0x1C,0xFC,0x1C,0xFC,0x1C,0xFC,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1F,0xF0,0x07,0xF8,0x00,0x00, // @
+ 0x00,0x00,0x00,0x00,0x03,0xC0,0x07,0xE0,0x0E,0x70,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1F,0xF8,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x00,0x00,0x00,0x00, // A
+ 0x00,0x00,0x00,0x00,0x1F,0xF0,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0F,0xF0,0x0F,0xF0,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1F,0xF0,0x00,0x00,0x00,0x00, // B
+ 0x00,0x00,0x00,0x00,0x07,0xF0,0x0E,0x38,0x1C,0x38,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x38,0x0E,0x38,0x07,0xF0,0x00,0x00,0x00,0x00, // C
+ 0x00,0x00,0x00,0x00,0x1F,0xE0,0x0E,0x70,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x70,0x1F,0xE0,0x00,0x00,0x00,0x00, // D
+ 0x00,0x00,0x00,0x00,0x1F,0xF8,0x0E,0x18,0x0E,0x08,0x0E,0x00,0x0E,0x30,0x0F,0xF0,0x0F,0xF0,0x0E,0x30,0x0E,0x00,0x0E,0x08,0x0E,0x18,0x1F,0xF8,0x00,0x00,0x00,0x00, // E
+ 0x00,0x00,0x00,0x00,0x1F,0xF8,0x0E,0x18,0x0E,0x08,0x0E,0x00,0x0E,0x30,0x0F,0xF0,0x0F,0xF0,0x0E,0x30,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x1F,0x00,0x00,0x00,0x00,0x00, // F
+ 0x00,0x00,0x00,0x00,0x07,0xF0,0x0E,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0xF8,0x1C,0x38,0x1C,0x38,0x0E,0x38,0x07,0xF8,0x00,0x00,0x00,0x00, // G
+ 0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1F,0xF0,0x1F,0xF0,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x00,0x00,0x00,0x00, // H
+ 0x00,0x00,0x00,0x00,0x0F,0xE0,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x0F,0xE0,0x00,0x00,0x00,0x00, // I
+ 0x00,0x00,0x00,0x00,0x01,0xFC,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x38,0x70,0x38,0x70,0x38,0x70,0x38,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // J
+ 0x00,0x00,0x00,0x00,0x1E,0x38,0x0E,0x38,0x0E,0x70,0x0E,0xE0,0x0F,0xC0,0x0F,0x80,0x0F,0x80,0x0F,0xC0,0x0E,0xE0,0x0E,0x70,0x0E,0x38,0x1E,0x38,0x00,0x00,0x00,0x00, // K
+ 0x00,0x00,0x00,0x00,0x1F,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x08,0x0E,0x18,0x0E,0x38,0x1F,0xF8,0x00,0x00,0x00,0x00, // L
+ 0x00,0x00,0x00,0x00,0x1C,0x1C,0x1E,0x3C,0x1F,0x7C,0x1F,0xFC,0x1F,0xFC,0x1D,0xDC,0x1C,0x9C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x00,0x00,0x00,0x00, // M
+ 0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x1C,0x1E,0x1C,0x1F,0x1C,0x1F,0x9C,0x1D,0xDC,0x1C,0xFC,0x1C,0x7C,0x1C,0x3C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x00,0x00,0x00,0x00, // N
+ 0x00,0x00,0x00,0x00,0x03,0xE0,0x07,0xF0,0x0E,0x38,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x0E,0x38,0x07,0xF0,0x03,0xE0,0x00,0x00,0x00,0x00, // O
+
+ 0x00,0x00,0x00,0x00,0x1F,0xF0,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0F,0xF0,0x0F,0xF0,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x1F,0x00,0x00,0x00,0x00,0x00, // P
+ 0x00,0x00,0x00,0x00,0x03,0xE0,0x0F,0x78,0x0E,0x38,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x7C,0x1C,0xFC,0x0F,0xF8,0x0F,0xF8,0x00,0x38,0x00,0xFC,0x00,0x00, // Q
+ 0x00,0x00,0x00,0x00,0x1F,0xF0,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0F,0xF0,0x0F,0xF0,0x0E,0x70,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1E,0x38,0x00,0x00,0x00,0x00, // R
+ 0x00,0x00,0x00,0x00,0x0F,0xF0,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x00,0x0F,0xE0,0x07,0xF0,0x00,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x0F,0xF0,0x00,0x00,0x00,0x00, // S
+ 0x00,0x00,0x00,0x00,0x1F,0xFC,0x19,0xCC,0x11,0xC4,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x07,0xF0,0x00,0x00,0x00,0x00, // T
+ 0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // U
+ 0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0E,0xE0,0x07,0xC0,0x03,0x80,0x00,0x00,0x00,0x00, // V
+ 0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x9C,0x1C,0x9C,0x1C,0x9C,0x0F,0xF8,0x0F,0xF8,0x07,0x70,0x07,0x70,0x00,0x00,0x00,0x00, // W
+ 0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0E,0xE0,0x07,0xC0,0x03,0x80,0x03,0x80,0x07,0xC0,0x0E,0xE0,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x00,0x00,0x00,0x00, // X
+ 0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0E,0xE0,0x07,0xC0,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x0F,0xE0,0x00,0x00,0x00,0x00, // Y
+ 0x00,0x00,0x00,0x00,0x1F,0xF8,0x1C,0x38,0x18,0x38,0x10,0x70,0x00,0xE0,0x01,0xC0,0x03,0x80,0x07,0x00,0x0E,0x08,0x1C,0x18,0x1C,0x38,0x1F,0xF8,0x00,0x00,0x00,0x00, // Z
+ 0x00,0x00,0x00,0x00,0x07,0xF0,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0xF0,0x00,0x00,0x00,0x00, // [
+ 0x00,0x00,0x00,0x00,0x10,0x00,0x18,0x00,0x1C,0x00,0x0E,0x00,0x07,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x00,0x70,0x00,0x38,0x00,0x1C,0x00,0x07,0x00,0x00,0x00,0x00, //
+ 0x00,0x00,0x00,0x00,0x07,0xF0,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x07,0xF0,0x00,0x00,0x00,0x00, // ]
+ 0x00,0x00,0x01,0x80,0x03,0xC0,0x07,0xE0,0x0E,0x70,0x1C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ^
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFF,0x7F,0xFF, // _
+
+ 0x00,0x00,0x00,0x00,0x1C,0x00,0x1C,0x00,0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // '
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xE0,0x00,0x70,0x00,0x70,0x0F,0xF0,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0F,0xD8,0x00,0x00,0x00,0x00, // a
+ 0x00,0x00,0x00,0x00,0x1E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0F,0xF0,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1B,0xF0,0x00,0x00,0x00,0x00, // b
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xE0,0x1C,0x70,0x1C,0x70,0x1C,0x00,0x1C,0x00,0x1C,0x70,0x1C,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // c
+ 0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x70,0x00,0x70,0x00,0x70,0x0F,0xF0,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0F,0xD8,0x00,0x00,0x00,0x00, // d
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xE0,0x1C,0x70,0x1C,0x70,0x1F,0xF0,0x1C,0x00,0x1C,0x70,0x1C,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // e
+ 0x00,0x00,0x00,0x00,0x03,0xE0,0x07,0x70,0x07,0x70,0x07,0x00,0x07,0x00,0x1F,0xE0,0x1F,0xE0,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x1F,0xC0,0x00,0x00,0x00,0x00, // f
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xD8,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0F,0xF0,0x07,0xF0,0x00,0x70,0x1C,0x70,0x0F,0xE0, // g
+ 0x00,0x00,0x00,0x00,0x1E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0xF0,0x0F,0x38,0x0F,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1E,0x38,0x00,0x00,0x00,0x00, // h
+ 0x00,0x00,0x00,0x00,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x00,0x00,0x0F,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x0F,0xF8,0x00,0x00,0x00,0x00, // i
+ 0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x00,0x03,0xF0,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x1C,0x70,0x0C,0xF0,0x07,0xE0, // j
+ 0x00,0x00,0x00,0x00,0x1E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x38,0x0E,0x70,0x0E,0xE0,0x0F,0xC0,0x0E,0xE0,0x0E,0x70,0x0E,0x38,0x1E,0x38,0x00,0x00,0x00,0x00, // k
+ 0x00,0x00,0x00,0x00,0x0F,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x0F,0xF8,0x00,0x00,0x00,0x00, // l
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xF8,0x1C,0x9C,0x1C,0x9C,0x1C,0x9C,0x1C,0x9C,0x1C,0x9C,0x1C,0x9C,0x1C,0x9C,0x00,0x00,0x00,0x00, // m
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xE0,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x00,0x00,0x00,0x00, // n
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xE0,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // o
+
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1B,0xF0,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0F,0xF0,0x0E,0x00,0x0E,0x00,0x1F,0x00, // p
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xB0,0x38,0xE0,0x38,0xE0,0x38,0xE0,0x38,0xE0,0x38,0xE0,0x1F,0xE0,0x00,0xE0,0x00,0xE0,0x01,0xF0, // q
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0xF0,0x0F,0xF8,0x0F,0x38,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x1F,0x00,0x00,0x00,0x00,0x00, // r
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xE0,0x1C,0x30,0x1C,0x30,0x0F,0x80,0x03,0xE0,0x18,0x70,0x18,0x70,0x0F,0xE0,0x00,0x00,0x00,0x00, // s
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0x07,0x00,0x1F,0xF0,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x70,0x07,0x70,0x03,0xE0,0x00,0x00,0x00,0x00, // t
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0F,0xD8,0x00,0x00,0x00,0x00, // u
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x1C,0x70,0x0E,0xE0,0x07,0xC0,0x03,0x80,0x00,0x00,0x00,0x00, // v
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x9C,0x1C,0x9C,0x0F,0xF8,0x07,0x70,0x07,0x70,0x00,0x00,0x00,0x00, // w
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0xE0,0x1C,0xE0,0x0F,0xC0,0x07,0x80,0x07,0x80,0x0F,0xC0,0x1C,0xE0,0x1C,0xE0,0x00,0x00,0x00,0x00, // x
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x07,0xF0,0x03,0xE0,0x00,0xE0,0x01,0xC0,0x1F,0x80, // y
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xE0,0x18,0xE0,0x11,0xC0,0x03,0x80,0x07,0x00,0x0E,0x20,0x1C,0x60,0x1F,0xE0,0x00,0x00,0x00,0x00, // z
+ 0x00,0x00,0x00,0x00,0x01,0xF8,0x03,0x80,0x03,0x80,0x03,0x80,0x07,0x00,0x1C,0x00,0x1C,0x00,0x07,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x01,0xF8,0x00,0x00,0x00,0x00, // {
+ 0x00,0x00,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x00,0x00, // |
+ 0x00,0x00,0x00,0x00,0x1F,0x80,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x00,0xE0,0x00,0x38,0x00,0x38,0x00,0xE0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x1F,0x80,0x00,0x00,0x00,0x00, // }
+ 0x00,0x00,0x00,0x00,0x1F,0x1C,0x3B,0x9C,0x39,0xDC,0x38,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 // ~
+};
diff --git a/Firmware_V2/src/hardware/display/fonts.h b/Firmware_V2/src/hardware/display/fonts.h
new file mode 100644
index 0000000..69ec572
--- /dev/null
+++ b/Firmware_V2/src/hardware/display/fonts.h
@@ -0,0 +1,25 @@
+/*
+*
+* Fonts
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef FONTS_H
+#define FONTS_H
+
+/*################# PUBLIC CONSTANTS, VARIABLES & DATA TYPES ##################*/
+
+extern const uint8_t tinyFont[];
+extern const uint8_t smallFont[];
+extern const uint8_t bigFont[];
+
+#endif /* FONTS_H */
diff --git a/Firmware_V2/src/hardware/hardware.cpp b/Firmware_V2/src/hardware/hardware.cpp
new file mode 100644
index 0000000..f2523ae
--- /dev/null
+++ b/Firmware_V2/src/hardware/hardware.cpp
@@ -0,0 +1,851 @@
+/*
+ *
+ * HARDWARE - Main hardware functions
+ *
+ * DIY-Thermocam Firmware
+ *
+ * GNU General Public License v3.0
+ *
+ * Copyright by Max Ritter
+ *
+ * http://www.diy-thermocam.net
+ * https://github.com/maxritter/DIY-Thermocam
+ *
+ */
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* Converts a float to four bytes */
+void floatToBytes(uint8_t* farray, float val)
+{
+ union
+ {
+ float f;
+ unsigned long ul;
+ } u;
+ u.f = val;
+ farray[0] = u.ul & 0x00FF;
+ farray[1] = (u.ul & 0xFF00) >> 8;
+ farray[2] = (u.ul & 0xFF0000) >> 16;
+ farray[3] = (u.ul & 0xFF000000) >> 24;
+}
+
+/* Converts four bytes back to float */
+float bytesToFloat(uint8_t* farray)
+{
+ union
+ {
+ float f;
+ unsigned long ul;
+ } u;
+ u.ul = (farray[3] << 24) | (farray[2] << 16) | (farray[1] << 8)
+ | (farray[0]);
+ return u.f;
+}
+
+/* Switch the SPI clockline to pin 14 */
+void startAltClockline(boolean sdStart)
+{
+ CORE_PIN13_CONFIG = PORT_PCR_MUX(1);
+ CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
+ if (sdStart)
+ sd.begin(pin_sd_cs, SPI_FULL_SPEED);
+}
+
+/* Switch the SPI clockline back to pin 13 */
+void endAltClockline()
+{
+ CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
+ CORE_PIN14_CONFIG = PORT_PCR_MUX(1);
+}
+
+/* Checks if the sd card is inserted for ThermocamV4 */
+boolean checkSDCard()
+{
+ //ThermocamV4 or DIY-Thermocam V2 - try init SD card
+ if ((mlx90614Version == mlx90614Version_old)
+ || (teensyVersion == teensyVersion_new))
+ return beginSD();
+
+ //All other do not need the check
+ return true;
+}
+
+/* Reads the adjust combined settings from EEPROM */
+void readAdjustCombined()
+{
+ //Adjust combined selection
+ byte adjCombPreset;
+ byte read = EEPROM.read(eeprom_adjCombPreset);
+ if ((read >= adjComb_preset1) && (read <= adjComb_preset3))
+ adjCombPreset = read;
+ else
+ adjCombPreset = adjComb_temporary;
+ //Adjust combined preset 1
+ if ((adjCombPreset == adjComb_preset1)
+ && (EEPROM.read(eeprom_adjComb1Set) == eeprom_setValue))
+ {
+ adjCombDown = EEPROM.read(eeprom_adjComb1Down);
+ adjCombLeft = EEPROM.read(eeprom_adjComb1Left);
+ adjCombRight = EEPROM.read(eeprom_adjComb1Right);
+ adjCombUp = EEPROM.read(eeprom_adjComb1Up);
+ adjCombAlpha = EEPROM.read(eeprom_adjComb1Alpha) / 100.0;
+ adjCombFactor = EEPROM.read(eeprom_adjComb1Factor) / 100.0;
+ }
+ //Adjust combined preset 2
+ else if ((adjCombPreset == adjComb_preset2)
+ && (EEPROM.read(eeprom_adjComb2Set) == eeprom_setValue))
+ {
+ adjCombDown = EEPROM.read(eeprom_adjComb2Down);
+ adjCombLeft = EEPROM.read(eeprom_adjComb2Left);
+ adjCombRight = EEPROM.read(eeprom_adjComb2Right);
+ adjCombUp = EEPROM.read(eeprom_adjComb2Up);
+ adjCombAlpha = EEPROM.read(eeprom_adjComb2Alpha) / 100.0;
+ adjCombFactor = EEPROM.read(eeprom_adjComb2Factor) / 100.0;
+ }
+ //Adjust combined preset 3
+ else if ((adjCombPreset == adjComb_preset3)
+ && (EEPROM.read(eeprom_adjComb3Set) == eeprom_setValue))
+ {
+ adjCombDown = EEPROM.read(eeprom_adjComb3Down);
+ adjCombLeft = EEPROM.read(eeprom_adjComb3Left);
+ adjCombRight = EEPROM.read(eeprom_adjComb3Right);
+ adjCombUp = EEPROM.read(eeprom_adjComb3Up);
+ adjCombAlpha = EEPROM.read(eeprom_adjComb3Alpha) / 100.0;
+ adjCombFactor = EEPROM.read(eeprom_adjComb3Factor) / 100.0;
+ }
+ //Load defaults
+ else
+ {
+ adjCombDown = 0;
+ adjCombUp = 0;
+ adjCombLeft = 0;
+ adjCombRight = 0;
+ adjCombAlpha = 0.5;
+ adjCombFactor = 1.0;
+ }
+ //Set factor to standard if invalid
+ if ((adjCombFactor < 0.7) || (adjCombFactor > 1.0))
+ adjCombFactor = 1.0;
+}
+
+/* Clears the whole EEPROM */
+void clearEEPROM()
+{
+ for (unsigned int i = 100; i < 250; i++)
+ EEPROM.write(i, 0);
+}
+
+/* Checks if a FW upgrade has been done */
+void checkFWUpgrade()
+{
+ //If the first start setup has not been completed, skip
+ if (checkFirstStart())
+ return;
+
+ //Read current FW version from EEPROM
+ byte eepromVersion = EEPROM.read(eeprom_fwVersion);
+
+ //Show message after firmware upgrade
+ if (eepromVersion != fwVersion)
+ {
+ //Upgrade from old Thermocam-V4 firmware
+ if ((mlx90614Version == mlx90614Version_old)
+ && (EEPROM.read(eeprom_liveHelper) != eeprom_setValue))
+ {
+ //Clear EEPROM
+ clearEEPROM();
+ //Show message and wait
+ showFullMessage((char*) "FW update completed, pls restart");
+ while (true)
+ ;
+ }
+ //Upgrade
+ if (fwVersion > eepromVersion)
+ {
+ //If coming from a firmware version smaller than 2.00, clear EEPROM
+ if (eepromVersion < 200)
+ clearEEPROM();
+
+ //Clear adjust combined settings when coming from FW smaller than 2.13
+ if (eepromVersion < 213)
+ {
+ EEPROM.write(eeprom_adjCombPreset, adjComb_temporary);
+ EEPROM.write(eeprom_adjComb1Set, 0);
+ EEPROM.write(eeprom_adjComb2Set, 0);
+ EEPROM.write(eeprom_adjComb3Set, 0);
+ }
+
+ //Clear temperature presets when coming from a FW smaller than 2.43
+ if (eepromVersion < 243)
+ {
+ EEPROM.write(eeprom_minMax1Set, 0);
+ EEPROM.write(eeprom_minMax2Set, 0);
+ EEPROM.write(eeprom_minMax3Set, 0);
+ EEPROM.write(eeprom_minMaxPreset, 0);
+ }
+
+ //Set Lepton3.5 gain mode to high for FW smaller than 2.47
+ if(eepromVersion < 247)
+ {
+ EEPROM.write(eeprom_lepton_3_5_gain, lepton_3_5_gain_high);
+ }
+
+ //Show upgrade completed message
+ showFullMessage((char*) "Update completed, restart device");
+ //Set EEPROM firmware version to current one
+ EEPROM.write(eeprom_fwVersion, fwVersion);
+ //Wait for hard-reset
+ while (true)
+ ;
+ }
+
+ //Show downgrade completed message
+ showFullMessage((char*) "Downgrade completed, restart device");
+ //Set EEPROM firmware version to current one
+ EEPROM.write(eeprom_fwVersion, fwVersion);
+ //Wait for hard-reset
+ while (true)
+ ;
+ }
+}
+
+/* Reads the calibration slope from EEPROM */
+void readCalibration()
+{
+ uint8_t farray[4];
+ //Read slope
+ for (int i = 0; i < 4; i++)
+ farray[i] = EEPROM.read(eeprom_calSlopeBase + i);
+ calSlope = bytesToFloat(farray);
+}
+
+/* Reads the old settings from EEPROM */
+void readEEPROM()
+{
+ byte read;
+ //Temperature format
+ read = EEPROM.read(eeprom_tempFormat);
+ if ((read == tempFormat_celcius) || (read == tempFormat_fahrenheit))
+ tempFormat = read;
+ else
+ tempFormat = tempFormat_celcius;
+ //Color scheme
+ read = EEPROM.read(eeprom_colorScheme);
+ if ((read >= 0) && (read <= (colorSchemeTotal - 1)))
+ colorScheme = read;
+ else
+ colorScheme = colorScheme_rainbow;
+ //Convert Enabled
+ read = EEPROM.read(eeprom_convertEnabled);
+ if ((read == false) || (read == true))
+ convertEnabled = read;
+ else
+ convertEnabled = false;
+ //Visual Enabled, only enable if camera is connected
+ read = EEPROM.read(eeprom_visualEnabled);
+ if (((read == false) || (read == true)) && checkDiagnostic(diag_camera))
+ visualEnabled = read;
+ else
+ visualEnabled = false;
+ //Battery Enabled
+ read = EEPROM.read(eeprom_batteryEnabled);
+ if ((read == false) || (read == true))
+ batteryEnabled = read;
+ else
+ batteryEnabled = false;
+ //Time Enabled
+ read = EEPROM.read(eeprom_timeEnabled);
+ if ((read == false) || (read == true))
+ timeEnabled = read;
+ else
+ timeEnabled = false;
+ //Date Enabled
+ read = EEPROM.read(eeprom_dateEnabled);
+ if ((read == false) || (read == true))
+ dateEnabled = read;
+ else
+ dateEnabled = false;
+ //Storage Enabled
+ read = EEPROM.read(eeprom_storageEnabled);
+ if ((read == false) || (read == true))
+ storageEnabled = read;
+ else
+ storageEnabled = false;
+ //Spot Enabled, only load when spot sensor is working
+ read = EEPROM.read(eeprom_spotEnabled);
+ if (((read == false) || (read == true)) && checkDiagnostic(diag_spot))
+ spotEnabled = read;
+ else
+ spotEnabled = false;
+ //Filter Type
+ read = EEPROM.read(eeprom_filterType);
+ if ((read == filterType_none) || (read == filterType_box)
+ || (read == filterType_gaussian))
+ filterType = read;
+ else
+ filterType = filterType_gaussian;
+ //Colorbar Enabled
+ read = EEPROM.read(eeprom_colorbarEnabled);
+ if ((read == false) || (read == true))
+ colorbarEnabled = read;
+ else
+ colorbarEnabled = true;
+ //Display Mode, only load when camera is connected
+ read = EEPROM.read(eeprom_displayMode);
+ if (((read == displayMode_thermal) || (read == displayMode_visual)
+ || (read == displayMode_combined)) && checkDiagnostic(diag_camera))
+ displayMode = read;
+ else
+ displayMode = displayMode_thermal;
+ //Text color
+ read = EEPROM.read(eeprom_textColor);
+ if ((read >= textColor_white) && (read <= textColor_blue))
+ textColor = read;
+ else
+ textColor = textColor_white;
+ //Horizontal mirroring
+ read = EEPROM.read(eeprom_rotationHorizont);
+ if ((read == false) || (read == true))
+ rotationHorizont = read;
+ else
+ rotationHorizont = false;
+ //Hot / cold mode
+ read = EEPROM.read(eeprom_hotColdMode);
+ if ((read >= hotColdMode_disabled) && (read <= hotColdMode_hot))
+ hotColdMode = read;
+ else
+ hotColdMode = hotColdMode_disabled;
+ //Hot / cold level and color
+ if (hotColdMode != hotColdMode_disabled)
+ {
+ hotColdLevel = ((EEPROM.read(eeprom_hotColdLevelHigh) << 8)
+ + EEPROM.read(eeprom_hotColdLevelLow));
+ hotColdColor = EEPROM.read(eeprom_hotColdColor);
+ }
+ //Calibration slope
+ read = EEPROM.read(eeprom_calSlopeSet);
+ if ((leptonVersion == leptonVersion_2_5_shutter)
+ || (leptonVersion == leptonVersion_3_5_shutter))
+ calSlope = lepton_get_resolution();
+ else if (read == eeprom_setValue)
+ readCalibration();
+ else
+ calSlope = cal_stdSlope;
+ //Min/Max Points
+ read = EEPROM.read(eeprom_minMaxPoints);
+ if ((read == minMaxPoints_disabled) || (read == minMaxPoints_min)
+ || (read == minMaxPoints_max) || (read == minMaxPoints_both))
+ minMaxPoints = read;
+ else
+ minMaxPoints = minMaxPoints_disabled;
+ //HQ res, V2 only
+ if (teensyVersion == teensyVersion_new)
+ {
+ read = EEPROM.read(eeprom_hqRes);
+ if ((read == false) || (read == true))
+ hqRes = read;
+ else
+ hqRes = true;
+
+ }
+ //Gain Mode, Lepton3.5 only
+ if (leptonVersion == leptonVersion_3_5_shutter)
+ {
+ read = EEPROM.read(eeprom_lepton_3_5_gain);
+ if (read == lepton_3_5_gain_high)
+ {
+ lepton_3_5_set_high_gain();
+ }
+ else if(read == lepton_3_5_gain_low)
+ {
+ lepton_3_5_set_low_gain();
+ }
+ else
+ {
+ lepton_3_5_set_high_gain();
+ }
+ }
+
+ //Align combined settings
+ readAdjustCombined();
+}
+
+/* Checks the specific device from the diagnostic variable */
+bool checkDiagnostic(byte device)
+{
+ //Returns false if the device does not work
+ return (diagnostic >> device) & 1;
+}
+
+/* Sets the status of a specific device from the diagnostic variable */
+void setDiagnostic(byte device)
+{
+ diagnostic &= ~(1 << device);
+}
+
+/* Checks for hardware issues */
+void checkHardware()
+{
+ //When returning from mass storage, do not check
+ if (EEPROM.read(eeprom_massStorage) == eeprom_setValue)
+ {
+ EEPROM.write(eeprom_massStorage, 0);
+ diagnostic = diag_ok;
+ }
+
+ //If the diagnostic is not okay show info
+ if (diagnostic != diag_ok)
+ showDiagnostic();
+
+ //If there is a problem with the visual camera, switch to thermal
+ if (!checkDiagnostic(diag_camera))
+ {
+ //We switch to thermal mode
+ displayMode = displayMode_thermal;
+ //And disable the visual image save
+ visualEnabled = false;
+ }
+}
+
+/* Stores the current calibration to EEPROM */
+void storeCalibration()
+{
+ uint8_t farray[4];
+ //Store slope
+ floatToBytes(farray, (float) calSlope);
+ for (int i = 0; i < 4; i++)
+ EEPROM.write(eeprom_calSlopeBase + i, (farray[i]));
+ EEPROM.write(eeprom_calSlopeSet, eeprom_setValue);
+}
+
+/* A method to check if the touch screen is pressed */
+boolean touchScreenPressed()
+{
+ //Check button status with debounce
+ touchDebouncer.update();
+ return touchDebouncer.read();
+}
+
+/* A method to check if the external button is pressed */
+boolean extButtonPressed()
+{
+ //Check button status with debounce
+ buttonDebouncer.update();
+ return buttonDebouncer.read();
+}
+
+/* Initialize the GPIO pins */
+void initGPIO()
+{
+ //Deactivate the laser for old HW
+ if (teensyVersion == teensyVersion_old)
+ {
+ pinMode(pin_laser, OUTPUT);
+ digitalWrite(pin_laser, LOW);
+ laserEnabled = false;
+ }
+ //Set the touch IRQ pin to input
+ pinMode(pin_touch_irq, INPUT);
+ //For Teensy 3.6, activate internal pulldown for button
+ if (teensyVersion == teensyVersion_new)
+ pinMode(pin_button, INPUT_PULLDOWN);
+ //Set button as input for Teensy 3.1/3.2
+ else
+ pinMode(pin_button, INPUT);
+ //Activate display backlight
+ pinMode(pin_lcd_backlight, OUTPUT);
+ digitalWrite(pin_lcd_backlight, HIGH);
+}
+
+/* Disables all Chip-Select lines on the SPI bus */
+void initSPI()
+{
+ pinMode(pin_lcd_dc, OUTPUT);
+ pinMode(pin_touch_cs, OUTPUT);
+ pinMode(pin_lepton_cs, OUTPUT);
+ pinMode(pin_sd_cs, OUTPUT);
+ pinMode(pin_lcd_cs, OUTPUT);
+ pinMode(pin_cam_cs, OUTPUT);
+ digitalWrite(pin_lcd_dc, HIGH);
+ digitalWrite(pin_touch_cs, HIGH);
+ digitalWrite(pin_lepton_cs, HIGH);
+ digitalWrite(pin_sd_cs, HIGH);
+ digitalWrite(pin_lcd_cs, HIGH);
+ digitalWrite(pin_cam_cs, HIGH);
+ SPI.begin();
+}
+
+/* Inits the I2C Bus */
+void initI2C()
+{
+ //Start the Bus
+ Wire.begin();
+ //Enable Timeout for Hardware start
+ Wire.setDefaultTimeout(1000);
+ //Use external pullups for new HW
+ if (teensyVersion == teensyVersion_new)
+ Wire.pinConfigure(I2C_PINS_18_19, I2C_PULLUP_EXT);
+ //Use internal pullups for old HW
+ else
+ Wire.pinConfigure(I2C_PINS_18_19, I2C_PULLUP_INT);
+}
+
+/* Init the Analog-Digital-Converter for the battery measure */
+void initADC()
+{
+ //Init ADC
+ batMeasure = new ADC();
+ //set number of averages
+ batMeasure->setAveraging(4);
+ //set bits of resolution
+ batMeasure->setResolution(12);
+ //change the conversion speed
+ batMeasure->setConversionSpeed(ADC_MED_SPEED);
+ //change the sampling speed
+ batMeasure->setSamplingSpeed(ADC_MED_SPEED);
+ //set battery pin as input
+ pinMode(pin_bat_measure, INPUT);
+}
+
+/* Init the buffer(s) */
+void initBuffer()
+{
+ //For Teensy 3.6, init 320x240 buffer
+ if (teensyVersion == teensyVersion_new)
+ bigBuffer = (uint16_t*) malloc(153600);
+
+ //Init 160x120 buffer for all devices
+ smallBuffer = (uint16_t*) malloc(38400);
+}
+
+/* Display the content of the small/big buffer on the screen */
+void displayBuffer()
+{
+ //Display 320x240 for Teensy 3.6
+ if ((teensyVersion == teensyVersion_new) && (hqRes))
+ display_writeScreen(bigBuffer, 0);
+ //160x120 for Teensy 3.1 / 3.2
+ else
+ display_writeScreen(smallBuffer, 1);
+}
+
+/* Detect which teensy version is used */
+void detectTeensyVersion()
+{
+ //Teensy 3.6 used in the DIY-Thermocam V2
+#if defined(__MK66FX1M0__)
+ teensyVersion = teensyVersion_new;
+ //Teensy 3.1 / 3.2 used in the old hardware generations
+#elif defined(__MK20DX256__)
+ teensyVersion = teensyVersion_old;
+#endif
+
+ //Set hardware version to detect V1/V2 over EEPROM
+ EEPROM.write(eeprom_teensyVersion, teensyVersion);
+}
+
+/* Sets the display rotation depending on the setting */
+void setDisplayRotation()
+{
+ if (rotationVert)
+ {
+ display_setRotation(135);
+ touch_setRotation(true);
+ }
+ else
+ {
+ display_setRotation(45);
+ touch_setRotation(false);
+ }
+}
+
+/* Reads the temperature limits from EEPROM */
+void readTempLimits()
+{
+ //Some variables to get started
+ byte minValueHigh, minValueLow, maxValueHigh, maxValueLow, minMaxComp;
+ bool found = false;
+
+ //Min / max selection
+ byte minMaxPreset;
+ byte read = EEPROM.read(eeprom_minMaxPreset);
+ if ((read >= minMax_preset1) && (read <= minMax_preset3))
+ minMaxPreset = read;
+ else
+ minMaxPreset = minMax_temporary;
+
+ //Min / max preset 1
+ if ((minMaxPreset == minMax_preset1)
+ && (EEPROM.read(eeprom_minMax1Set) == eeprom_setValue))
+ {
+ minValueHigh = eeprom_minValue1High;
+ minValueLow = eeprom_minValue1Low;
+ maxValueHigh = eeprom_maxValue1High;
+ maxValueLow = eeprom_maxValue1Low;
+ minMaxComp = eeprom_minMax1Comp;
+ found = true;
+ }
+ //Min / max preset 2
+ else if ((minMaxPreset == minMax_preset2)
+ && (EEPROM.read(eeprom_minMax2Set) == eeprom_setValue))
+ {
+ minValueHigh = eeprom_minValue2High;
+ minValueLow = eeprom_minValue2Low;
+ maxValueHigh = eeprom_maxValue2High;
+ maxValueLow = eeprom_maxValue2Low;
+ minMaxComp = eeprom_minMax2Comp;
+ found = true;
+ }
+ //Min / max preset 3
+ else if ((minMaxPreset == minMax_preset3)
+ && (EEPROM.read(eeprom_minMax3Set) == eeprom_setValue))
+ {
+ minValueHigh = eeprom_minValue3High;
+ minValueLow = eeprom_minValue3Low;
+ maxValueHigh = eeprom_maxValue3High;
+ maxValueLow = eeprom_maxValue3Low;
+ minMaxComp = eeprom_minMax3Comp;
+ found = true;
+ }
+
+ //Apply settings
+ if (found)
+ {
+ minValue =
+ ((EEPROM.read(minValueHigh) << 8) + EEPROM.read(minValueLow));
+ maxValue =
+ ((EEPROM.read(maxValueHigh) << 8) + EEPROM.read(maxValueLow));
+ uint8_t farray[4];
+ for (int i = 0; i < 4; i++)
+ farray[i] = EEPROM.read(minMaxComp + i);
+ calComp = bytesToFloat(farray);
+ autoMode = false;
+ }
+}
+
+/* Init the screen off timer */
+void initScreenOffTimer()
+{
+ byte read = EEPROM.read(eeprom_screenOffTime);
+ //Try to read from EEPROM
+ if ((read == screenOffTime_disabled) || (read == screenOffTime_5min)
+ || read == screenOffTime_20min)
+ {
+ screenOffTime = read;
+ //10 Minutes
+ if (screenOffTime == screenOffTime_5min)
+ screenOff.begin(300000, false);
+ //30 Minutes
+ else if (screenOffTime == screenOffTime_20min)
+ screenOff.begin(1200000, false);
+ //Disable marker
+ screenPressed = false;
+ }
+ else
+ screenOffTime = screenOffTime_disabled;
+}
+
+/* Get time from the RTC */
+time_t getTeensy3Time()
+{
+ return Teensy3Clock.get();
+}
+
+/* Init the time and correct it if required */
+void initRTC()
+{
+ //Get the time from the Teensy
+ setSyncProvider(getTeensy3Time);
+
+ //Check if year is lower than 2017
+ if ((year() < 2017) && (EEPROM.read(eeprom_firstStart) == eeprom_setValue))
+ {
+ showFullMessage((char*) "Empty coin cell battery");
+ delay(1000);
+ setTime(0, 0, 0, 1, 1, 2017);
+ Teensy3Clock.set(now());
+ }
+}
+
+/* Disable the screen backlight */
+void disableScreenLight()
+{
+ digitalWrite(pin_lcd_backlight, LOW);
+}
+
+/* Enables the screen backlight */
+void enableScreenLight()
+{
+ digitalWrite(pin_lcd_backlight, HIGH);
+}
+
+/* Checks if the screen backlight is on or off*/
+bool checkScreenLight()
+{
+ return digitalRead(pin_lcd_backlight);
+}
+
+/* Disable automatic FFC when saved in EEPROM */
+void checkNoFFC()
+{
+ //Set value found
+ if (EEPROM.read(eeprom_noShutter) == eeprom_setValue)
+ {
+ //Disable auto FFC mode
+ lepton_ffcMode(false);
+
+ //Set lepton shutter to none
+ leptonShutter = leptonShutter_none;
+ }
+}
+
+//Get the spot temperature from Lepton or MLX90614
+void getSpotTemp()
+{
+ //Get spot value from radiometric Lepton
+ if ((leptonVersion == leptonVersion_2_5_shutter)
+ || (leptonVersion == leptonVersion_3_5_shutter))
+ spotTemp = lepton_spotTemp();
+
+ //Get temperature from MLX90614
+ else
+ spotTemp = mlx90614_getTemp();
+
+ //Convert to Fahrenheit if required
+ if (tempFormat == tempFormat_fahrenheit)
+ spotTemp = celciusToFahrenheit(spotTemp);
+}
+
+/* Switches the laser on or off*/
+void toggleLaser(bool message)
+{
+ //Thermocam V4 or DIY-Thermocam V2 does not support this
+ if ((mlx90614Version == mlx90614Version_old)
+ || (teensyVersion == teensyVersion_new))
+ return;
+
+ //Laser enabled, switch off
+ if (laserEnabled)
+ {
+ digitalWrite(pin_laser, LOW);
+ laserEnabled = false;
+ if (message)
+ {
+ showFullMessage((char*) "Laser is now off", true);
+ delay(1000);
+ }
+ }
+ //Laser disabled, switch on
+ else
+ {
+ digitalWrite(pin_laser, HIGH);
+ laserEnabled = true;
+ if (message)
+ {
+ showFullMessage((char*) "Laser is now on", true);
+ delay(1000);
+ }
+ }
+}
+
+/* Toggle the display*/
+void toggleDisplay()
+{
+ showFullMessage((char*) "Screen goes off, touch to continue", true);
+ delay(1000);
+ disableScreenLight();
+ //Wait for touch press
+ while (!touch_touched())
+ ;
+ //Turning screen on
+ drawMainMenuBorder();
+ showFullMessage((char*) "Turning screen on..", true);
+ enableScreenLight();
+ delay(1000);
+}
+
+/* Check if the screen was pressed in the time period */
+bool screenOffCheck()
+{
+ //Timer exceeded
+ if ((screenOff.check()) && (screenOffTime != screenOffTime_disabled))
+ {
+ //No touch press in the last interval
+ if (screenPressed == false)
+ {
+ toggleDisplay();
+ screenOff.reset();
+ return true;
+ }
+ //Touch pressed, restart timer
+ screenPressed = false;
+ screenOff.reset();
+ return false;
+ }
+ return false;
+}
+
+/* Init the hardware */
+void initHardware()
+{
+ //Init UART
+ Serial.begin(115200);
+ //Detect teensy version
+ detectTeensyVersion();
+ //Init GPIO
+ initGPIO();
+ //Init SPI
+ initSPI();
+ //Init I2C
+ initI2C();
+ //Init ADC
+ initADC();
+ //Init display
+ display_init();
+ //Show bootscreen
+ bootScreen();
+ //Init touch
+ touch_init();
+ //Init camera
+ camera_init();
+ //Init lepton
+ lepton_init();
+ //Init spot sensor
+ mlx90614_init();
+ //Init SD card
+ initSD();
+ //Disable I2C timeout
+ Wire.setDefaultTimeout(0);
+ //Init screen off timer
+ initScreenOffTimer();
+ //Init the buffer(s)
+ initBuffer();
+ //Check battery for the first time
+ checkBattery(true);
+ //Init the realtime clock
+ initRTC();
+ //If no automatic FFC desired, disable it forever
+ checkNoFFC();
+}
diff --git a/Firmware_V2/src/hardware/hardware.h b/Firmware_V2/src/hardware/hardware.h
new file mode 100644
index 0000000..325b11b
--- /dev/null
+++ b/Firmware_V2/src/hardware/hardware.h
@@ -0,0 +1,59 @@
+/*
+*
+* HARDWARE - Main hardware functions
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef HARDWARE_H
+#define HARDWARE_H
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+float bytesToFloat(uint8_t* farray);
+void checkHardware();
+bool checkDiagnostic(byte device);
+void checkFWUpgrade();
+void checkNoFFC();
+bool checkScreenLight();
+boolean checkSDCard();
+void clearEEPROM();
+void detectTeensyVersion();
+void disableScreenLight();
+void displayBuffer();
+void enableScreenLight();
+void endAltClockline();
+boolean extButtonPressed();
+void floatToBytes(uint8_t* farray, float val);
+void getSpotTemp();
+time_t getTeensy3Time();
+void initADC();
+void initBuffer();
+void initGPIO();
+void initHardware();
+void initI2C();
+void initRTC();
+void initScreenOffTimer();
+void initSPI();
+void readAdjustCombined();
+void readCalibration();
+void readEEPROM();
+void readTempLimits();
+bool screenOffCheck();
+void setDiagnostic(byte device);
+void setDisplayRotation();
+void startAltClockline(boolean sdStart = false);
+void storeCalibration();
+void toggleDisplay();
+void toggleLaser(bool message = false);
+boolean touchScreenPressed();
+
+#endif /* HARDWARE_H */
diff --git a/Firmware_V2/src/hardware/lepton.cpp b/Firmware_V2/src/hardware/lepton.cpp
new file mode 100644
index 0000000..99bc819
--- /dev/null
+++ b/Firmware_V2/src/hardware/lepton.cpp
@@ -0,0 +1,809 @@
+/*
+ *
+ * LEPTON - Access the FLIR Lepton LWIR module
+ *
+ * DIY-Thermocam Firmware
+ *
+ * GNU General Public License v3.0
+ *
+ * Copyright by Max Ritter
+ *
+ * http://www.diy-thermocam.net
+ * https://github.com/maxritter/DIY-Thermocam
+ *
+ */
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*######################### STATIC DATA DECLARATIONS ##########################*/
+
+//Array to store one Lepton frame
+static byte leptonFrame[164];
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* Start Lepton SPI Transmission */
+void lepton_begin()
+{
+ //Start alternative clock line, except for old HW
+ if (mlx90614Version == mlx90614Version_new)
+ startAltClockline();
+
+ //For Teensy 3.1 / 3.2 and Lepton3 use this one
+ if ((teensyVersion == teensyVersion_old)
+ && ((leptonVersion == leptonVersion_3_0_shutter)
+ || (leptonVersion == leptonVersion_3_5_shutter)))
+ SPI.beginTransaction(SPISettings(30000000, MSBFIRST, SPI_MODE0));
+
+ //Otherwise use 20 Mhz maximum and SPI mode 1
+ else
+ SPI.beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE1));
+
+ //Start transfer - CS LOW
+ digitalWrite(pin_lepton_cs, LOW);
+}
+
+/* End Lepton SPI Transmission */
+void lepton_end()
+{
+ //End transfer - CS HIGH
+ digitalWriteFast(pin_lepton_cs, HIGH);
+
+ //End SPI Transaction
+ SPI.endTransaction();
+
+ //End alternative clock line, except for old HW
+ if (mlx90614Version == mlx90614Version_new)
+ endAltClockline();
+}
+
+/* Reset the SPI bus to re-initiate Lepton communication */
+void lepton_reset()
+{
+ lepton_end();
+ delay(186);
+ lepton_begin();
+}
+
+/* Store one package of 80 columns into RAM */
+bool savePackage(byte line, byte segment)
+{
+ //Go through the video pixels for one video line
+ for (int column = 0; column < 80; column++)
+ {
+ //Apply horizontal mirroring
+ if (rotationHorizont)
+ column = 79 - column;
+
+ //Make a 16-bit rawvalue from the lepton frame
+ uint16_t result = (uint16_t) (leptonFrame[2 * column + 4] << 8
+ | leptonFrame[2 * column + 5]);
+
+ //Discard horizontal mirroring
+ if (rotationHorizont)
+ column = 79 - column;
+
+ //Invalid value, return
+ if (result == 0)
+ {
+ return 0;
+ }
+
+ //Lepton2.x
+ if ((leptonVersion != leptonVersion_3_0_shutter)
+ && (leptonVersion != leptonVersion_3_5_shutter))
+ {
+ //Rotated or old hardware version
+ if (((mlx90614Version == mlx90614Version_old) && (!rotationVert))
+ || ((mlx90614Version == mlx90614Version_new)
+ && (rotationVert)))
+ {
+ smallBuffer[(line * 2 * 160) + (column * 2)] = result;
+ smallBuffer[(line * 2 * 160) + (column * 2) + 1] = result;
+ smallBuffer[(line * 2 * 160) + 160 + (column * 2)] = result;
+ smallBuffer[(line * 2 * 160) + 160 + (column * 2) + 1] = result;
+ }
+ //Non-rotated
+ else
+ {
+ smallBuffer[19199 - ((line * 2 * 160) + (column * 2))] = result;
+ smallBuffer[19199 - ((line * 2 * 160) + (column * 2) + 1)] =
+ result;
+ smallBuffer[19199 - ((line * 2 * 160) + 160 + (column * 2))] =
+ result;
+ smallBuffer[19199 - ((line * 2 * 160) + 160 + (column * 2) + 1)] =
+ result;
+ }
+ }
+
+ //Lepton3
+ else
+ {
+ //Non-rotated
+ if (!rotationVert)
+ {
+ switch (segment)
+ {
+ case 1:
+ if (rotationHorizont)
+ smallBuffer[19199
+ - (((line / 2) * 160) + ((1 - (line % 2)) * 80)
+ + (column))] = result;
+ else
+ smallBuffer[19199
+ - (((line / 2) * 160) + ((line % 2) * 80)
+ + (column))] = result;
+ break;
+ case 2:
+ if (rotationHorizont)
+ smallBuffer[14399
+ - (((line / 2) * 160) + ((1 - (line % 2)) * 80)
+ + (column))] = result;
+ else
+ smallBuffer[14399
+ - (((line / 2) * 160) + ((line % 2) * 80)
+ + (column))] = result;
+ break;
+ case 3:
+ if (rotationHorizont)
+ smallBuffer[9599
+ - (((line / 2) * 160) + ((1 - (line % 2)) * 80)
+ + (column))] = result;
+ else
+ smallBuffer[9599
+ - (((line / 2) * 160) + ((line % 2) * 80)
+ + (column))] = result;
+ break;
+ case 4:
+ if (rotationHorizont)
+ smallBuffer[4799
+ - (((line / 2) * 160) + ((1 - (line % 2)) * 80)
+ + (column))] = result;
+ else
+ smallBuffer[4799
+ - (((line / 2) * 160) + ((line % 2) * 80)
+ + (column))] = result;
+ break;
+ }
+ }
+ //Rotated
+ else
+ {
+ switch (segment)
+ {
+ case 1:
+ smallBuffer[((line / 2) * 160) + ((line % 2) * 80)
+ + (column)] = result;
+ break;
+ case 2:
+ smallBuffer[4800
+ + (((line / 2) * 160) + ((line % 2) * 80) + (column))] =
+ result;
+ break;
+ case 3:
+ smallBuffer[9600
+ + (((line / 2) * 160) + ((line % 2) * 80) + (column))] =
+ result;
+ break;
+ case 4:
+ smallBuffer[14400
+ + (((line / 2) * 160) + ((line % 2) * 80) + (column))] =
+ result;
+ break;
+ }
+ }
+ }
+
+ }
+
+ //Everything worked
+ return 1;
+}
+
+/* Get one line package from the Lepton */
+LeptonReadError lepton_getPackage(byte line, byte seg)
+{
+ //Receive one frame over SPI
+ SPI.transfer(leptonFrame, 164);
+
+ //Repeat as long as the frame is not valid, equals sync
+ if ((leptonFrame[0] & 0x0F) == 0x0F)
+ return DISCARD;
+
+ //Check if the line number matches the expected line
+ if (leptonFrame[1] != line)
+ return ROW_ERROR;
+
+ //For the Lepton3.x, check if the segment number matches
+ if ((line == 20)
+ && ((leptonVersion == leptonVersion_3_0_shutter)
+ || (leptonVersion == leptonVersion_3_5_shutter)))
+ {
+ byte segment = (leptonFrame[0] >> 4);
+ if (segment == 0)
+ return SEGMENT_INVALID;
+ if (segment != seg)
+ return SEGMENT_ERROR;
+ }
+
+ //Everything worked
+ return NONE;
+}
+
+/* Get one frame of raw values from the lepton */
+void lepton_getRawValues()
+{
+ byte line, error, segmentNumbers;
+
+ //Determine number of segments
+ if ((leptonVersion == leptonVersion_3_0_shutter)
+ || (leptonVersion == leptonVersion_3_5_shutter))
+ segmentNumbers = 4;
+ else
+ segmentNumbers = 1;
+
+ //Begin SPI Transmission
+ lepton_begin();
+
+ //Go through the segments
+ for (byte segment = 1; segment <= segmentNumbers; segment++)
+ {
+ //Reset error counter for each segment
+ error = 0;
+
+ //Go through one segment, equals 60 lines of 80 values
+ do
+ {
+ for (line = 0; line < 60; line++)
+ {
+ //Maximum error count
+ if (error == 255)
+ {
+ //If main menu should be entreed
+ if (showMenu == showMenu_desired)
+ {
+ lepton_end();
+ return;
+ }
+
+ //Reset segment
+ segment = 1;
+ //Reset error
+ error = 0;
+ //Reset Lepton SPI
+ lepton_reset();
+ //Restart at line 0
+ break;
+ }
+
+ //Get a package from the lepton
+ LeptonReadError retVal = lepton_getPackage(line, segment);
+
+ //If everythin worked, continue
+ if (retVal == NONE)
+ if (savePackage(line, segment))
+ continue;
+
+ //Raise lepton error
+ error++;
+
+ //Stabilize framerate
+ uint32_t time = micros();
+ while ((micros() - time) < 800)
+ __asm__ volatile ("nop");
+
+ //Restart at line 0
+ break;
+ }
+ } while (line != 60);
+ }
+
+ //End SPI Transmission
+ lepton_end();
+}
+
+/* Select I2C Register on the Lepton */
+void lepton_setReg(byte reg)
+{
+ Wire.beginTransmission(0x2A);
+ Wire.write(reg >> 8 & 0xff);
+ Wire.write(reg & 0xff);
+ Wire.endTransmission();
+}
+
+/* Read I2C Register on the lepton */
+int lepton_readReg(byte reg)
+{
+ uint16_t reading;
+ lepton_setReg(reg);
+ Wire.requestFrom(0x2A, 2);
+ reading = Wire.read();
+ reading = reading << 8;
+ reading |= Wire.read();
+ return reading;
+}
+
+/*
+ First reads the DATA Length Register (0x006)
+ Then reads the acutal DATA Registers:
+ DATA 0 Register, DATA 1 Register etc.
+
+ If the request length is smaller that the DATA Length it returns -1
+ */
+int lepton_i2c_read_data_register(byte *data, int data_length_request)
+{
+
+ int data_length_recv;
+ int data_read;
+ // Wait for execution of the command
+ while (lepton_readReg(0x2) & 0x01)
+ ;
+
+ // Read the data length (should be 4)
+ data_length_recv = lepton_readReg(0x6);
+
+ if (data_length_recv < data_length_request)
+ {
+ return -1;
+ }
+
+ Wire.requestFrom(0x2A, data_length_request);
+ data_read = Wire.readBytes(data, data_length_request);
+ Wire.endTransmission();
+ return data_read;
+}
+
+/*
+ First writes the actual DATA Registers (0x0008).
+ Then writes the DATA Length Register (0x006)
+ */
+byte lepton_i2c_write_data_register(byte *data, int length)
+{
+
+ // Wait for execution of the command
+ while (lepton_readReg(0x2) & 0x01)
+ ;
+
+ Wire.beginTransmission(0x2A);
+ // CCI/TWI Data Registers is at 0x0008
+ Wire.write(0x00);
+ Wire.write(0x08);
+ for (int i = 0; i < length; i++)
+ {
+ Wire.write(data[i]);
+ }
+ Wire.endTransmission();
+
+ // CCI/TWI Data Length Register is at 0x0006
+ Wire.beginTransmission(0x2A);
+ Wire.write(0x00);
+ Wire.write(0x06);
+ //Data length bytes
+ Wire.write((length >> 8) & 0xFF);
+ Wire.write(length & 0xFF);
+ return Wire.endTransmission();
+}
+
+/*
+ Write the command words (16-bit) via I2C
+ */
+byte lepton_i2c_execute_command(byte cmdbyte0, byte cmdbyte1)
+{
+ // Wait for execution of the command
+ while (lepton_readReg(0x2) & 0x01)
+ ;
+
+ Wire.beginTransmission(0x2A);
+ Wire.write(0x00);
+ Wire.write(0x04); //COMMANDID_REG
+ Wire.write(cmdbyte0);
+ Wire.write(cmdbyte1);
+ return Wire.endTransmission();
+}
+
+/* Trigger a flat-field-correction on the Lepton */
+bool lepton_ffc(bool message, bool switch_gain)
+{
+ //Show a message for main menu
+ if (message)
+ {
+ //When in manual temperature mode, a FFC is not possible
+ if ((!autoMode) && (!switch_gain))
+ {
+ showFullMessage((char*) "No FFC in manual mode", true);
+ delay(1000);
+ return false;
+ }
+ showFullMessage((char*) "Performing FFC..", true);
+ }
+
+ byte error;
+
+ if ((leptonVersion == leptonVersion_2_5_shutter)
+ || (leptonVersion == leptonVersion_3_5_shutter))
+ {
+ // For radiometric Lepton, send RAD FFC command
+ // RAD FFC Normalization Command
+ // 0x0E00 (SDK Module ID) + 0x2C (SDK Command ID) + 0x2 (RUN operation) + 0x4000 (Protection Bit) = 0x4E2E
+ error = lepton_i2c_execute_command(0x4E, 0x2E);
+ }
+ else
+ {
+ //For all others, send normal FFC command
+ // SYS Run FFC Normalization
+ // 0x0200 (SDK Module ID) + 0x40 (SDK Command ID) + 0x2 (RUN operation) + 0x0000 (Protection Bit) = 0x0242
+ error = lepton_i2c_execute_command(0x02, 0x42);
+ }
+
+ //Wait some time when in main menu
+ if (message)
+ delay(2000);
+
+ return error;
+}
+
+/* Get the spotmeter value on a radiometric lepton */
+float lepton_spotTemp()
+{
+ //Get RAD spotmeter value
+ Wire.beginTransmission(0x2A);
+ Wire.write(0x00);
+ Wire.write(0x04);
+ Wire.write(0x4E);
+ Wire.write(0xD0);
+ byte error = Wire.endTransmission();
+
+ //Lepton I2C error, set diagnostic
+ if (error != 0)
+ {
+ setDiagnostic(diag_spot);
+ return 0;
+ }
+
+ //Transfer the new package
+ Wire.beginTransmission(0x2A);
+ while (lepton_readReg(0x2) & 0x01)
+ ;
+ Wire.requestFrom(0x2A, lepton_readReg(0x6));
+ byte response[8];
+ Wire.readBytes(response, 8);
+ Wire.endTransmission();
+
+ //Calculate spot temperature in Kelvin
+ float spotTemp = (response[0] * 256.0) + response[1];
+ //Multiply by correction factor
+ if(gainMode == lepton_3_5_gain_high)
+ {
+ spotTemp *= 0.01;
+ }
+ else
+ {
+ spotTemp *= 0.1;
+ }
+ //Convert to celsius
+ spotTemp -= 273.15;
+
+ return spotTemp;
+}
+
+/* Set the shutter operation to manual/auto */
+void lepton_ffcMode(bool automatic)
+{
+ //If there is no shutter, return
+ if (leptonShutter == leptonShutter_none)
+ return;
+
+ //When enabling auto FFC, check for some factors
+ if ((automatic)
+ && ((hotColdMode != hotColdMode_disabled) || (autoMode == false)
+ || (limitsLocked == true)))
+ return;
+
+ //Contains the standard values for the FFC mode
+ byte package[] =
+ { automatic, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224,
+ 147, 4, 0, 0, 0, 0, 0, 44, 1, 52, 0 };
+
+ lepton_i2c_write_data_register(package, sizeof(package));
+
+ // SYS FFC Mode Control Command
+ // 0x0200 (SDK Module ID) + 0x3C (SDK Command ID) + 0x1 (SET operation) + 0x0000 (Protection Bit) = 0x023D
+ lepton_i2c_execute_command(0x02, 0x3D);
+
+ //Set shutter mode
+ if (automatic)
+ leptonShutter = leptonShutter_auto;
+ else
+ leptonShutter = leptonShutter_manual;
+}
+
+/* Checks the Lepton hardware revision */
+void lepton_version()
+{
+
+ // OEM FLIR Systems Part Number
+ // 0x0800 (SDK Module ID) + 0x1C (SDK Command ID) + 0x0 (GET operation) + 0x4000 (Protection Bit) = 0x481C
+ byte error = lepton_i2c_execute_command(0x48, 0x1C);
+
+ //Lepton I2C error, set diagnostic
+ if (error != 0)
+ {
+ setDiagnostic(diag_lep_conf);
+ leptonVersion = leptonVersion_2_0_noShutter;
+ return;
+ }
+
+ char leptonhw[33];
+ lepton_i2c_read_data_register((byte*) leptonhw, 32);
+
+ //Detected Lepton2 Non-Shuttered
+ if (strstr(leptonhw, "05-060340") != NULL)
+ {
+ leptonVersion = leptonVersion_2_0_noShutter;
+ leptonShutter = leptonShutter_none;
+ }
+
+ //Detected Lepton2 Shuttered
+ else if (strstr(leptonhw, "05-060950") != NULL)
+ {
+ leptonVersion = leptonVersion_2_0_shutter;
+ leptonShutter = leptonShutter_auto;
+ }
+
+ //Detected Lepton2.5 Shuttered (Radiometric)
+ else if (strstr(leptonhw, "05-070360") != NULL)
+ {
+ leptonVersion = leptonVersion_2_5_shutter;
+ leptonShutter = leptonShutter_autoRAD;
+ }
+
+ //Detected Lepton3 Shuttered
+ else if (strstr(leptonhw, "05-070620") != NULL)
+ {
+ leptonVersion = leptonVersion_3_0_shutter;
+ leptonShutter = leptonShutter_auto;
+ }
+
+ //Detected Lepton3.5 Shuttered (Radiometric)
+ else if (strstr(leptonhw, "05-070170") != NULL)
+ {
+ leptonVersion = leptonVersion_3_5_shutter;
+ leptonShutter = leptonShutter_autoRAD;
+ }
+
+ //Detected unknown Lepton2 No-Shutter
+ else
+ {
+ leptonVersion = leptonVersion_2_0_noShutter;
+ leptonShutter = leptonShutter_none;
+ }
+
+ //Write to EEPROM
+ EEPROM.write(eeprom_leptonVersion, leptonVersion);
+}
+
+/*
+ * Set the SYS Gain Mode
+ * 0: high mode (hardware default),
+ * 1: low mode,
+ * 2: auto mode
+ * The measurement range for the Lepton 3.5 is (see datasheet for details):
+ * High Gain Mode: -10 to +140 deg C
+ * Low Gain Mode: -10 to +450 deg C
+ *
+ */
+void lepton_set_sys_gain_mode(byte mode)
+{
+ if (mode > 2)
+ {
+ return;
+ }
+
+ //The enum value is the LSB of DATA0
+ byte data[4] =
+ { 0x00, mode, 0x00, 0x00 };
+ lepton_i2c_write_data_register(data, 4);
+
+ // Execute the SYS Gain Mode Set Command, so that the module applies the values
+ // 0x0200 (SDK Module ID) + 0x48 (SDK Command ID) + 0x1 (SET operation) + 0x0000 (Protection Bit) = 0x0249.
+ lepton_i2c_execute_command(0x02, 0x49);
+}
+
+/*
+ * Sets the SYS Gain Mode to high gain mode
+ */
+void lepton_set_sys_gain_high()
+{
+ lepton_set_sys_gain_mode(0x00);
+}
+
+/*
+ * Sets the SYS Gain Mode to low gain mode
+ */
+void lepton_set_sys_gain_low()
+{
+ lepton_set_sys_gain_mode(0x01);
+}
+
+/*
+ * Sets the SYS Gain Mode to auto mode
+ */
+void lepton_set_sys_gain_auto()
+{
+ lepton_set_sys_gain_mode(0x02);
+}
+
+/*
+ * Returns the SYS Gain Mode
+ * 0: high mode (hardware default),
+ * 1: low mode,
+ * 2: auto mode
+ * The measurement range for the Lepton 3.5 is (see datasheet for details):
+ * High Gain Mode: -10 to +140 deg C
+ * Low Gain Mode: -10 to +450 deg C
+ *
+ * Returns -1 if the gain mode could not be read
+ */
+int lepton_get_sys_gain_mode()
+{
+
+ byte data[4];
+
+ //SYS Gain Mode Get Command
+ // 0x0200 (SDK Module ID) + 0x48 (SDK Command ID) + 0x0 (GET operation) + 0x0000 (Protection Bit) = 0x0248.
+ lepton_i2c_execute_command(0x02, 0x48);
+ lepton_i2c_read_data_register(data, 4);
+
+ //The enum value is the LSB of DATA0
+ return data[1];
+}
+
+/*
+ * Returns the RAD T-Linear Resolution
+ * 0: 100
+ * 1: 10
+ */
+byte lepton_get_rad_tlinear_resolution()
+{
+
+ byte data[4];
+
+ // RAD T-Linear Resolution Get Command
+ // 0x0E00 (SDK Module ID) + 0xC4 (SDK Command ID) + 0x0 (GET operation) + 0x4000 (Protection Bit) = 0x4EC4.
+ lepton_i2c_execute_command(0x4E, 0xC4);
+ lepton_i2c_read_data_register(data, 4);
+
+ //The enum value is the LSB of DATA0
+ return data[1];
+}
+
+/*
+ * Returns the RAD T-Linear Resolution Factor as a float
+ * Returns -1 if the value could not be read
+ */
+float lepton_get_resolution()
+{
+ byte resolution = lepton_get_rad_tlinear_resolution();
+ if (resolution == 0)
+ {
+ return 0.1;
+ }
+ else
+ {
+ return 0.01;
+ }
+}
+
+/*
+ * Sets the RAD T-Linear Resolution
+ * resolution: 0 = factor 100
+ * resolution: 1 = factor 10
+ *
+ * You need to set this to factor 10 for temperature over 382.2 deg C
+ * The maximum temperature value of the 16-bit is 65535.
+ * For factor 100: The maximum is 655.35 Kelvin which equals to 655.35 - 273.15 = 382.2 deg C
+ * For factor 10: The maximum is 6553.5 Kelvin which equals to 6553.5 - 273.15 = 6280.35 deg C
+ */
+void lepton_set_rad_tlinear_resolution(byte resolution)
+{
+ if (resolution > 1)
+ {
+ return;
+ }
+
+ //The enum value is the LSB of DATA0
+ byte data[4] =
+ { 0x00, resolution, 0x00, 0x00 };
+ lepton_i2c_write_data_register(data, 4);
+
+ // RAD T-Linear Resolution Set Command
+ // 0x0E00 (SDK Module ID) + 0xC4 (SDK Command ID) + 0x1 (SET operation) + 0x4000 (Protection Bit) = 0x4EC5.
+ lepton_i2c_execute_command(0x4E, 0xC5);
+}
+
+/*
+ * Sets the RAD T-Linear Resolution to 10 (factor 0.1)
+ */
+void lepton_set_rad_tlinear_10()
+{
+ lepton_set_rad_tlinear_resolution(0);
+}
+
+/*
+ * Sets the RAD T-Linear Resolution to 100 (factor 0.01)
+ */
+void lepton_set_rad_tlinear_100()
+{
+ lepton_set_rad_tlinear_resolution(1);
+}
+
+/* Switch to low gain on Lepton3.5 (-10 to +450 deg C) */
+void lepton_3_5_set_low_gain()
+{
+ lepton_set_sys_gain_low();
+ lepton_set_rad_tlinear_10();
+ calSlope = 0.1;
+ gainMode = lepton_3_5_gain_low;
+}
+
+/* Switch to high gain on Lepton3.5 (-10 to +140 deg C) */
+void lepton_3_5_set_high_gain()
+{
+ lepton_set_sys_gain_high();
+ lepton_set_rad_tlinear_100();
+ calSlope = 0.01;
+ gainMode = lepton_3_5_gain_high;
+}
+
+/* Init the FLIR Lepton LWIR sensor */
+void lepton_init()
+{
+ //Check the Lepton HW Revision
+ lepton_version();
+
+ //For radiometric Lepton, set calibration to done
+ if ((leptonVersion == leptonVersion_2_5_shutter)
+ || (leptonVersion == leptonVersion_3_5_shutter))
+ calStatus = cal_standard;
+
+ //Otherwise init warmup timer
+ else
+ {
+ //Set the calibration timer
+ calTimer = millis();
+ //Set calibration status to warmup if not coming from mass storage
+ calStatus = cal_warmup;
+ }
+
+ //Set the compensation value to zero
+ calComp = 0;
+
+ //Activate auto mode
+ autoMode = true;
+ //Deactivate limits Locked
+ limitsLocked = false;
+
+ //Check if SPI works
+ lepton_begin();
+ do
+ {
+ SPI.transfer(leptonFrame, 164);
+ }
+ //Repeat as long as the frame is not valid, equals sync
+ while (((leptonFrame[0] & 0x0F) == 0x0F) && ((millis() - calTimer) < 1000));
+ lepton_end();
+
+ //If sync not received after a second, set diagnostic
+ if ((leptonFrame[0] & 0x0F) == 0x0F)
+ setDiagnostic(diag_lep_data);
+}
diff --git a/Firmware_V2/src/hardware/lepton.h b/Firmware_V2/src/hardware/lepton.h
new file mode 100644
index 0000000..72d4bf4
--- /dev/null
+++ b/Firmware_V2/src/hardware/lepton.h
@@ -0,0 +1,49 @@
+/*
+*
+* LEPTON - Access the FLIR Lepton LWIR module
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef LEPTON_H
+#define LEPTON_H
+
+/*################# PUBLIC CONSTANTS, VARIABLES & DATA TYPES ##################*/
+
+//Lepton frame error return
+enum LeptonReadError {
+ NONE, DISCARD, SEGMENT_ERROR, ROW_ERROR, SEGMENT_INVALID
+};
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+void lepton_begin();
+void lepton_end();
+bool lepton_ffc(bool message = false, bool switch_gain = false);
+void lepton_ffcMode(bool automatic);
+LeptonReadError lepton_getPackage(byte line, byte seg);
+void lepton_getRawValues();
+void lepton_init();
+int lepton_readReg(byte reg);
+void lepton_reset();
+void lepton_setReg(byte reg);
+float lepton_spotTemp();
+void lepton_version();
+bool savePackage(byte line, byte segment = 0);
+void lepton_set_sys_gain_high();
+void lepton_set_sys_gain_low();
+void lepton_set_sys_gain_auto();
+int lepton_get_sys_gain_mode();
+float lepton_get_resolution();
+void lepton_3_5_set_low_gain();
+void lepton_3_5_set_high_gain();
+
+#endif /* LEPTON_H */
diff --git a/Firmware_V2/src/hardware/massstorage.cpp b/Firmware_V2/src/hardware/massstorage.cpp
new file mode 100644
index 0000000..f18571f
--- /dev/null
+++ b/Firmware_V2/src/hardware/massstorage.cpp
@@ -0,0 +1,115 @@
+/*
+ *
+ * MASS STORAGE - Mass storage mode to connect the internal storage to the PC
+ *
+ * DIY-Thermocam Firmware
+ *
+ * GNU General Public License v3.0
+ *
+ * Copyright by Max Ritter
+ *
+ * http://www.diy-thermocam.net
+ * https://github.com/maxritter/DIY-Thermocam
+ *
+ */
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*################# DATA TYPES, CONSTANTS & MACRO DEFINITIONS #################*/
+
+#define CPU_RESTART_ADDR (uint32_t *)0xE000ED0C
+#define CPU_RESTART_VAL 0x5FA0004
+#define CPU_RESTART() (*CPU_RESTART_ADDR = CPU_RESTART_VAL);
+#define IS_JUMP_TO_OFFSET_FLAG_SET() (eeprom_read_byte(0x00) == 0xAE)
+#define CLEAR_JUMP_FLAG() eeprom_write_byte(0x00, 0)
+#define SET_JUMP_FLAG() eeprom_write_byte(0x00, 0xAE)
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+//The assembly code hook must be run inside a C, not C++ function
+
+/* Load stack pointer and program counter from start of new program */
+void jumpToApplicationAt0x38980() {
+ asm("movw r0, #0x8880");
+ asm("movt r0, #0x0003");
+ asm("ldr sp, [r0]");
+ asm("ldr pc, [r0, #4]");
+}
+
+/* Set peripherals back to reset conditions */
+void resetPeripherals() {
+ //Set (some of) USB back to normal
+ NVIC_DISABLE_IRQ(IRQ_USBOTG);
+ NVIC_CLEAR_PENDING(IRQ_USBOTG);
+ SIM_SCGC4 &= ~(SIM_SCGC4_USBOTG);
+
+ //Disable all GPIO interrupts
+ NVIC_DISABLE_IRQ(IRQ_PORTA);
+ NVIC_DISABLE_IRQ(IRQ_PORTB);
+ NVIC_DISABLE_IRQ(IRQ_PORTC);
+ NVIC_DISABLE_IRQ(IRQ_PORTD);
+ NVIC_DISABLE_IRQ(IRQ_PORTE);
+
+ //Set (some of) ADC1 back to normal
+ //Wait until calibration is complete
+ while (ADC1_SC3 & ADC_SC3_CAL)
+ ;
+ //Clear flag if calibration failed
+ if (ADC1_SC3 & 1 << 6)
+ ADC1_SC3 |= 1 << 6;
+
+ //Clear conversion complete flag (which could trigger ISR otherwise)
+ if (ADC1_SC1A & 1 << 7)
+ ADC1_SC1A |= 1 << 7;
+
+ //Set some clocks back to default/reset settings
+ MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(4);
+ SIM_CLKDIV1 = 0;
+ SIM_CLKDIV2 = 0;
+}
+
+/* Look for the condition that indicates we want to jump to the application with offset */
+void startup_late_hook(void) {
+ if (IS_JUMP_TO_OFFSET_FLAG_SET()) {
+ //Clear the condition
+ CLEAR_JUMP_FLAG();
+ //Set peripherals (mostly) back to normal then jump
+ __disable_irq();
+ resetPeripherals();
+ jumpToApplicationAt0x38980();
+ }
+}
+
+/* Jump to the mass storage section */
+void restartAndJumpToApp(void) {
+ SET_JUMP_FLAG();
+ CPU_RESTART()
+ ;
+}
+
+/* Go into mass storage mode */
+void massStorage() {
+ //Thermocam V4 or DIY-Thermocam V2 does not support this
+ if ((mlx90614Version == mlx90614Version_old) || (teensyVersion == teensyVersion_new))
+ return;
+
+ //Check if the user really wants to do it
+ if (!massStoragePrompt())
+ return;
+ //Show message
+ showFullMessage((char*) "Disconnect USB cable to return");
+ //Set marker
+ EEPROM.write(eeprom_massStorage, eeprom_setValue);
+ //Wait some time
+ delay(1500);
+ //Jump to mass storage mode
+ restartAndJumpToApp();
+}
diff --git a/Firmware_V2/src/hardware/massstorage.h b/Firmware_V2/src/hardware/massstorage.h
new file mode 100644
index 0000000..6035245
--- /dev/null
+++ b/Firmware_V2/src/hardware/massstorage.h
@@ -0,0 +1,27 @@
+/*
+*
+* MASS STORAGE - Mass storage mode to connect the internal storage to the PC
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef MASSSTORAGE_H
+#define MASSSTORAGE_H
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+void jumpToApplicationAt0x38980();
+void massStorage();
+void resetPeripherals();
+void restartAndJumpToApp(void);
+void startup_late_hook(void);
+
+#endif /* MASSSTORAGE_H */
diff --git a/Firmware_V2/src/hardware/mlx90614.cpp b/Firmware_V2/src/hardware/mlx90614.cpp
new file mode 100644
index 0000000..a042716
--- /dev/null
+++ b/Firmware_V2/src/hardware/mlx90614.cpp
@@ -0,0 +1,407 @@
+/*
+*
+* MLX90614 - Access the MLX90614 spot IR sensor
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*################# DATA TYPES, CONSTANTS & MACRO DEFINITIONS #################*/
+
+//Registers
+#define mlx90614_EEPROM 0x00
+#define mlx90614_RAM 0x5A
+#define mlx90614_AmbientTemp 0x06
+#define mlx90614_ObjectTemp 0x07
+#define mlx90614_toMax 0x20
+#define mlx90614_toMin 0x21
+#define mlx90614_PWMCTRL 0x22
+#define mlx90614_TaRange 0x23
+#define mlx90614_Emissivity 0x24
+#define mlx90614_Filter 0x25
+
+/*######################### STATIC DATA DECLARATIONS ##########################*/
+
+//CRC Table to calculate I2C PEC
+static const unsigned char mlx90614_crcTable[] = { 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D, 0x70, 0x77, 0x7E,
+0x79, 0x6C, 0x6B, 0x62, 0x65, 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF,
+0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD, 0xC7,
+0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
+0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D,
+0x0A, 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92,
+0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8, 0xDD,
+0xDA, 0xD3, 0xD4, 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, 0x19, 0x1E, 0x17, 0x10,
+0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78,
+0x7F, 0x6A, 0x6D, 0x64, 0x63, 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, 0xAE, 0xA9,
+0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6,
+0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3 };
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* Calculate CRC8 checksum for PEC */
+char mlx90614_crc8(byte buffer[], int len) {
+ unsigned char m_crc = 0;
+ int m_byte_count = 0;
+ for (int i = 0; i < len; i++) {
+ m_byte_count++;
+ m_crc = mlx90614_crcTable[m_crc ^ buffer[i]];
+ }
+ return m_crc;
+}
+
+/* Receive data from the RAM over I2C */
+uint16_t mlx90614_getRawData(boolean TaTo, boolean* check) {
+ // Store the two relevant bytes of data for temperature
+ byte dataLow, dataHigh;
+ Wire.beginTransmission(mlx90614_RAM);
+ //Measure Ambient Temp
+ if (TaTo)
+ Wire.send(mlx90614_AmbientTemp);
+ //Measure Object Temp
+ else {
+ Wire.send(mlx90614_ObjectTemp);
+ }
+ Wire.endTransmission(I2C_NOSTOP);
+ //Receive data
+ Wire.requestFrom(mlx90614_RAM, 3);
+ if (Wire.available() != 3)
+ *check = 0;
+ dataLow = Wire.read();
+ if (dataLow == -1)
+ *check = 0;
+ dataHigh = Wire.read();
+ if (dataHigh == -1)
+ *check = 0;
+ byte pec = Wire.read();
+ if (pec == -1)
+ *check = 0;
+ Wire.endTransmission();
+ //Convert data
+ uint16_t tempData = (((dataHigh & 0x007F) << 8) + dataLow);
+ return tempData;
+}
+
+/* Send data to the EEPROM over I2C*/
+void mlx90614_send(byte address, byte LSB, byte MSB) {
+ Wire.beginTransmission(mlx90614_EEPROM);
+ Wire.write(address);
+ Wire.write(LSB);
+ Wire.write(MSB);
+ byte msg[4] = { 0x00, address, LSB, MSB };
+ byte PEC = mlx90614_crc8(msg, 4);
+ Wire.write(PEC);
+ Wire.endTransmission();
+}
+
+/* Receive data from the EEPROM over I2C */
+uint16_t mlx90614_receive(byte address, byte* error) {
+ Wire.beginTransmission(mlx90614_EEPROM);
+ Wire.write(address);
+ Wire.endTransmission(I2C_NOSTOP);
+ Wire.requestFrom(mlx90614_EEPROM, 3);
+ byte LSB = Wire.read();
+ byte MSB = Wire.read();
+ Wire.read();
+ //Check if the transmission worked
+ if (error != NULL)
+ *error = Wire.endTransmission();
+ else
+ Wire.endTransmission();
+ //Calc 16-bit value and return
+ uint16_t regValue = (((MSB) << 8) + LSB);
+ return regValue;
+}
+
+/* Measures the ambient or object temperature */
+float mlx90614_measure(boolean TaTo, boolean* check) {
+ //Get the raw value from the sensor
+ uint16_t rawData = mlx90614_getRawData(TaTo, check);
+
+ //Convert to Kelvin
+ float tempData = (rawData * 0.02) - 0.01;
+
+ //Convert to Celsius
+ tempData -= 273.15;
+
+ //TaTo is one, check for ambient borders
+ if ((TaTo) && ((tempData < -40) || (tempData > 125)))
+ *check = false;
+
+ //TaTo is zero, check for object borders
+ else if ((tempData < -70) || (tempData > 380))
+ *check = false;
+
+ //Return temperature in Celsius
+ return tempData;
+}
+
+/* Set the maximum temp to 380°C */
+void mlx90614_setMax() {
+ byte count = 0;
+ do {
+ //Set it to zero first
+ mlx90614_send(mlx90614_toMax, 0x00, 0x00);
+ delay(100);
+ //Then write the new value
+ mlx90614_send(mlx90614_toMax, 0x23, 0xFF);
+ delay(100);
+ //If we failed after 10 retries, set error and continue
+ if (count == 10) {
+ setDiagnostic(diag_spot);
+ return;
+ }
+ count++;
+ } while (mlx90614_receive(mlx90614_toMax) != 65315);
+}
+
+/* Check if the maximum temp is 380°C */
+boolean mlx90614_checkMax() {
+ //Check if maximum temp setting is correct
+ if (mlx90614_receive(mlx90614_toMax) != 65315)
+ return 0;
+ //Everything was fine
+ return 1;
+}
+
+/* Set the minimum temp to -70°C */
+void mlx90614_setMin() {
+ byte count = 0;
+ do {
+ //Set it to zero first
+ mlx90614_send(mlx90614_toMin, 0x00, 0x00);
+ delay(100);
+ //Then write the new value
+ mlx90614_send(mlx90614_toMin, 0x5B, 0x4F);
+ delay(100);
+ //If we failed after 10 retries, set error and continue
+ if (count == 10) {
+ setDiagnostic(diag_spot);
+ return;
+ }
+ count++;
+ } while (mlx90614_receive(mlx90614_toMin) != 20315);
+}
+
+/* Check if the minimum temp is -70°C */
+boolean mlx90614_checkMin() {
+ //Check if minimum temp setting is correct
+ if (mlx90614_receive(mlx90614_toMin) != 20315)
+ return 0;
+ //Everything was fine
+ return 1;
+}
+
+/* Set the emissivity to 0.9 */
+void mlx90614_setEmissivity() {
+ byte count = 0;
+ do {
+ //Set it to zero first
+ mlx90614_send(mlx90614_Emissivity, 0x00, 0x00);
+ delay(100);
+ //Then write the new value
+ mlx90614_send(mlx90614_Emissivity, 0x66, 0xE6);
+ delay(100);
+ //If we failed after 10 retries, set error and continue
+ if (count == 10) {
+ setDiagnostic(diag_spot);
+ return;
+ }
+ count++;
+ } while (mlx90614_receive(mlx90614_Emissivity) != 58982);
+}
+
+/* Check if the emissivity is set to 0.9 */
+boolean mlx90614_checkEmissivity() {
+ //Check if emissivity setting is correct
+ if (mlx90614_receive(mlx90614_Emissivity) != 58982)
+ return 0;
+ //Everything was fine
+ return 1;
+}
+
+/* Check if the filter settings match for noise-reduction (50% IIR, max settling time) */
+void mlx90614_setFilter() {
+ byte MSB, LSB;
+ uint16_t filterSettings;
+ //Old MLX90614 with gain factor of 12.5
+ if (mlx90614Version == mlx90614Version_old) {
+ filterSettings = 40820;
+ MSB = 0x74;
+ LSB = 0x9F;
+ }
+
+ //New MLX90614 with gain factor of 100
+ else {
+ filterSettings = 46964;
+ MSB = 0x74;
+ LSB = 0xB7;
+ }
+ //Try to set the new filter settings
+ byte count = 0;
+ do {
+ //Set it to zero first
+ mlx90614_send(mlx90614_Filter, 0x00, 0x00);
+ delay(100);
+ //Then write the new value
+ mlx90614_send(mlx90614_Filter, MSB, LSB);
+ delay(100);
+ //If we failed after 10 retries, set error and continue
+ if (count == 10) {
+ setDiagnostic(diag_spot);
+ return;
+ }
+ count++;
+ } while (mlx90614_receive(mlx90614_Filter) != filterSettings);
+}
+
+/* Check if the filter settings match for fast measurement */
+boolean mlx90614_checkFilter() {
+ uint16_t filter = mlx90614_receive(mlx90614_Filter);
+ //Old MLX90614 with gain factor of 12.5
+ if ((mlx90614Version == mlx90614Version_old) && (filter != 40820))
+ return 0;
+ //New MLX90614 with gain factor of 100
+ else if ((mlx90614Version == mlx90614Version_new) && (filter != 46964))
+ return 0;
+ ///Everything was fine
+ return 1;
+}
+
+/* Read and return the ambient temperature */
+float mlx90614_getAmb() {
+ float ambTemp;
+ boolean check = 1;
+ byte count = 0;
+
+ //Repeat until valid value
+ do {
+ ambTemp = mlx90614_measure(1, &check);
+ //If we cannot connect,continue
+ if (count == 100)
+ return 0;
+ count++;
+ delay(10);
+ } while (check == 0);
+
+ //Return ambient temperature
+ return ambTemp;
+}
+
+/* Read and return the object temperature */
+float mlx90614_getTemp() {
+ float objTemp;
+ boolean check = 1;
+ byte count = 0;
+
+ //Repeat until valid value
+ do {
+ objTemp = mlx90614_measure(0, &check);
+ //If we cannot connect, continue
+ if (count == 100)
+ return 0;
+ count++;
+ delay(10);
+ } while (check == 0);
+
+ //Return object temperature
+ return objTemp;
+}
+
+/* Initializes the sensor */
+void mlx90614_init() {
+ byte error;
+
+ //For radiometric Lepton, do not init the MLX90614
+ if ((leptonVersion == leptonVersion_2_5_shutter) || (leptonVersion == leptonVersion_3_5_shutter)) {
+ mlx90614Version = mlx90614Version_new;
+ return;
+ }
+
+ //Get filter settings
+ uint16_t filter = mlx90614_receive(mlx90614_Filter, &error);
+
+ //If I2C connection is not working, set diagnostic
+ if (error != 0)
+ {
+ setDiagnostic(diag_spot);
+ return;
+ }
+
+ //Calc MLX90614 version
+ mlx90614Version = (filter >> 13) & 1;
+
+ //If first start has been completed before, do checks
+ if (EEPROM.read(eeprom_firstStart) == eeprom_setValue) {
+ //Check Filter Temp
+ if (mlx90614_checkFilter() == 0) {
+ mlx90614_setFilter();
+ setDiagnostic(diag_spot);
+ }
+ //Check Min Temp
+ if (mlx90614_checkMin() == 0) {
+ mlx90614_setMin();
+ setDiagnostic(diag_spot);
+ }
+ //Check Max Temp
+ if (mlx90614_checkMax() == 0) {
+ mlx90614_setMax();
+ setDiagnostic(diag_spot);
+ }
+ //Check Emissivity
+ if (mlx90614_checkEmissivity() == 0) {
+ mlx90614_setEmissivity();
+ setDiagnostic(diag_spot);
+ }
+ //Show message, if one of the settings had to be re-written
+ if (!checkDiagnostic(diag_spot)) {
+ showFullMessage((char*)"Spot EEPROM updated, restart device");
+ while (1);
+ }
+ }
+
+ //Check if the object temp is valid
+ boolean check = 1;
+ byte count = 0;
+ do {
+ mlx90614_measure(0, &check);
+ //If we cannot connect, set error and continue
+ if (count == 100) {
+ setDiagnostic(diag_spot);
+ break;
+ }
+ count++;
+ delay(10);
+ } while (check == 0);
+
+ //Check if the ambient temp is valid
+ check = 1;
+ count = 0;
+ do {
+ mlx90614_measure(1, &check);
+ //If we cannot connect, set error and continue
+ if (count == 100) {
+ setDiagnostic(diag_spot);
+ break;
+ }
+ count++;
+ delay(10);
+ } while (check == 0);
+}
diff --git a/Firmware_V2/src/hardware/mlx90614.h b/Firmware_V2/src/hardware/mlx90614.h
new file mode 100644
index 0000000..c069bcb
--- /dev/null
+++ b/Firmware_V2/src/hardware/mlx90614.h
@@ -0,0 +1,38 @@
+/*
+*
+* MLX90614 - Access the MLX90614 spot IR sensor
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef MLX90614_H
+#define MLX90614_H
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+boolean mlx90614_checkEmissivity();
+boolean mlx90614_checkFilter();
+boolean mlx90614_checkMax();
+boolean mlx90614_checkMin();
+char mlx90614_crc8(byte buffer[], int len);
+float mlx90614_getAmb();
+uint16_t mlx90614_getRawData(boolean TaTo, boolean* check);
+float mlx90614_getTemp();
+void mlx90614_init();
+float mlx90614_measure(boolean TaTo, boolean* check);
+uint16_t mlx90614_receive(byte address, byte* error = NULL);
+void mlx90614_send(byte address, byte LSB, byte MSB);
+void mlx90614_setEmissivity();
+void mlx90614_setFilter();
+void mlx90614_setMax();
+void mlx90614_setMin();
+
+#endif /* MLX90614_H */
diff --git a/Firmware_V2/src/hardware/sd.cpp b/Firmware_V2/src/hardware/sd.cpp
new file mode 100644
index 0000000..1c573db
--- /dev/null
+++ b/Firmware_V2/src/hardware/sd.cpp
@@ -0,0 +1,406 @@
+/*
+*
+* SD - Methods to access the internal SD storage
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/*######################### STATIC DATA DECLARATIONS ##########################*/
+
+//Card
+static uint32_t cardSizeBlocks;
+static uint16_t cardCapacityMB;
+//Cache for SD block
+static cache_t cache;
+//Fake disk geometry
+static uint8_t numberOfHeads;
+static uint8_t sectorsPerTrack;
+//MBR information
+static uint8_t partType;
+static uint32_t relSector;
+static uint32_t partSize;
+//FAT parameters
+static uint16_t reservedSectors;
+static uint8_t sectorsPerCluster;
+static uint32_t fatStart;
+static uint32_t fatSize;
+static uint32_t dataStart;
+//Cconstants for file system structure
+static uint16_t const BU16 = 128;
+static uint16_t const BU32 = 8192;
+//Strings needed in file system structures
+static char noName[] = "NO NAME ";
+static char fat16str[] = "FAT16 ";
+static char fat32str[] = "FAT32 ";
+
+/*######################## PUBLIC FUNCTION BODIES #############################*/
+
+/* Returns the free space on the card in KB */
+uint32_t getSDSpace() {
+ startAltClockline(true);
+ uint32_t freeKB = sd.vol()->freeClusterCount();
+ freeKB *= sd.vol()->blocksPerCluster() / 2;
+ endAltClockline();
+ return freeKB;
+}
+
+/* Returns the internal sd size in MB */
+uint16_t getCardSize() {
+ //Start Card
+ startAltClockline();
+ //Get card info
+ cardSizeBlocks = sd.card()->cardSize();
+ uint16_t cardSize = (cardSizeBlocks + 2047) / 2048;
+ //End Card
+ endAltClockline();
+ return cardSize;
+}
+
+//Refresh free space of the internal space
+void refreshFreeSpace() {
+ uint16_t cardSize = getCardSize();
+ if (cardSize != 0)
+ sdInfo = String((int)(getSDSpace() / 1024)) + "/" + String((int)(cardSize - 1)) + " MB";
+}
+
+/* Timestamp set for SDFat */
+void dateTime(uint16_t* date, uint16_t* time) {
+ // return date using FAT_DATE macro to format fields
+ *date = FAT_DATE(year(), month(), day());
+ // return time using FAT_TIME macro to format fields
+ *time = FAT_TIME(hour(), minute(), second());
+}
+
+/* Begin the SD card */
+bool beginSD()
+{
+ bool ret;
+
+ //Start alternative clockline
+ startAltClockline();
+
+ //Try to begin the SD card at full speed
+ ret = sd.begin(pin_sd_cs, SPI_FULL_SPEED);
+
+ //End alternative clockline
+ endAltClockline();
+
+ //Return result
+ return ret;
+}
+
+/* Initializes the SD card */
+void initSD() {
+ //Storage info string
+ sdInfo = " - / - MB";
+
+ //Check if the sd card works
+ if (beginSD())
+ refreshFreeSpace();
+
+ //Not working, set diagnosis on DIY-Thermocam V1 only
+ else if ((mlx90614Version == mlx90614Version_new) && (
+ teensyVersion == teensyVersion_old))
+ setDiagnostic(diag_sd);
+
+ //Set SD Timestamp to current time
+ SdFile::dateTimeCallback(dateTime);
+}
+
+/* Zero cache and optionally set the sector signature */
+void clearCache(uint8_t addSig) {
+ memset(&cache, 0, sizeof(cache));
+ if (addSig) {
+ cache.mbr.mbrSig0 = BOOTSIG0;
+ cache.mbr.mbrSig1 = BOOTSIG1;
+ }
+}
+
+/* Write cached block to the card */
+uint8_t writeCache(uint32_t lbn) {
+ return sd.card()->writeBlock(lbn, cache.data);
+}
+
+/* Return cylinder number for a logical block number */
+uint16_t lbnToCylinder(uint32_t lbn) {
+ return lbn / (numberOfHeads * sectorsPerTrack);
+}
+
+/* Return head number for a logical block number */
+uint8_t lbnToHead(uint32_t lbn) {
+ return (lbn % (numberOfHeads * sectorsPerTrack)) / sectorsPerTrack;
+}
+
+/* Return sector number for a logical block number */
+uint8_t lbnToSector(uint32_t lbn) {
+ return (lbn % sectorsPerTrack) + 1;
+}
+
+/* Format and write the Master Boot Record */
+void writeMbr() {
+ clearCache(true);
+ part_t* p = cache.mbr.part;
+ p->boot = 0;
+ uint16_t c = lbnToCylinder(relSector);
+ p->beginCylinderHigh = c >> 8;
+ p->beginCylinderLow = c & 0XFF;
+ p->beginHead = lbnToHead(relSector);
+ p->beginSector = lbnToSector(relSector);
+ p->type = partType;
+ uint32_t endLbn = relSector + partSize - 1;
+ c = lbnToCylinder(endLbn);
+ if (c <= 1023) {
+ p->endCylinderHigh = c >> 8;
+ p->endCylinderLow = c & 0XFF;
+ p->endHead = lbnToHead(endLbn);
+ p->endSector = lbnToSector(endLbn);
+ }
+ else {
+ // Too big flag, c = 1023, h = 254, s = 63
+ p->endCylinderHigh = 3;
+ p->endCylinderLow = 255;
+ p->endHead = 254;
+ p->endSector = 63;
+ }
+ p->firstSector = relSector;
+ p->totalSectors = partSize;
+ writeCache(0);
+}
+
+/* Zero FAT and root dir area on SD */
+void clearFatDir(uint32_t bgn, uint32_t count) {
+ clearCache(false);
+ sd.card()->writeStart(bgn, count);
+ for (uint32_t i = 0; i < count; i++) {
+ sd.card()->writeData(cache.data);
+ }
+ sd.card()->writeStop();
+}
+
+/* Generate serial number from card size and micros since boot */
+uint32_t volSerialNumber() {
+ return (cardSizeBlocks << 8) + micros();
+}
+
+/* Format with FAT16 file system for 2GB internal storage */
+void formatFAT16()
+{
+ uint32_t nc;
+ for (dataStart = 2 * BU16;; dataStart += BU16) {
+ nc = (cardSizeBlocks - dataStart) / sectorsPerCluster;
+ fatSize = (nc + 2 + 255) / 256;
+ uint32_t r = BU16 + 1 + 2 * fatSize + 32;
+ if (dataStart < r) {
+ continue;
+ }
+ relSector = dataStart - r + BU16;
+ break;
+ }
+ reservedSectors = 1;
+ fatStart = relSector + reservedSectors;
+ partSize = nc * sectorsPerCluster + 2 * fatSize + reservedSectors + 32;
+ if (partSize < 32680) {
+ partType = 0X01;
+ }
+ else if (partSize < 65536) {
+ partType = 0X04;
+ }
+ else {
+ partType = 0X06;
+ }
+ // write MBR
+ writeMbr();
+ clearCache(true);
+ fat_boot_t* pb = &cache.fbs;
+ pb->jump[0] = 0XEB;
+ pb->jump[1] = 0X00;
+ pb->jump[2] = 0X90;
+ for (uint8_t i = 0; i < sizeof(pb->oemId); i++) {
+ pb->oemId[i] = ' ';
+ }
+ pb->bytesPerSector = 512;
+ pb->sectorsPerCluster = sectorsPerCluster;
+ pb->reservedSectorCount = reservedSectors;
+ pb->fatCount = 2;
+ pb->rootDirEntryCount = 512;
+ pb->mediaType = 0XF8;
+ pb->sectorsPerFat16 = fatSize;
+ pb->sectorsPerTrack = sectorsPerTrack;
+ pb->headCount = numberOfHeads;
+ pb->hidddenSectors = relSector;
+ pb->totalSectors32 = partSize;
+ pb->driveNumber = 0X80;
+ pb->bootSignature = EXTENDED_BOOT_SIG;
+ pb->volumeSerialNumber = volSerialNumber();
+ memcpy(pb->volumeLabel, noName, sizeof(pb->volumeLabel));
+ memcpy(pb->fileSystemType, fat16str, sizeof(pb->fileSystemType));
+ // write partition boot sector
+ writeCache(relSector);
+ // clear FAT and root directory
+ clearFatDir(fatStart, dataStart - fatStart);
+ clearCache(false);
+ cache.fat16[0] = 0XFFF8;
+ cache.fat16[1] = 0XFFFF;
+ // write first block of FAT and backup for reserved clusters
+ writeCache(fatStart);
+ writeCache(fatStart + fatSize);
+}
+
+/* Format with FAT32 file system for SDHC cards */
+void formatFAT32()
+{
+ uint32_t nc;
+ relSector = BU32;
+ for (dataStart = 2 * BU32;; dataStart += BU32) {
+ nc = (cardSizeBlocks - dataStart) / sectorsPerCluster;
+ fatSize = (nc + 2 + 127) / 128;
+ uint32_t r = relSector + 9 + 2 * fatSize;
+ if (dataStart >= r) {
+ break;
+ }
+ }
+ reservedSectors = dataStart - relSector - 2 * fatSize;
+ fatStart = relSector + reservedSectors;
+ partSize = nc * sectorsPerCluster + dataStart - relSector;
+ // type depends on address of end sector
+ // max CHS has lbn = 16450560 = 1024*255*63
+ if ((relSector + partSize) <= 16450560) {
+ // FAT32
+ partType = 0X0B;
+ }
+ else {
+ // FAT32 with INT 13
+ partType = 0X0C;
+ }
+ writeMbr();
+ clearCache(true);
+ fat32_boot_t* pb = &cache.fbs32;
+ pb->jump[0] = 0XEB;
+ pb->jump[1] = 0X00;
+ pb->jump[2] = 0X90;
+ for (uint8_t i = 0; i < sizeof(pb->oemId); i++) {
+ pb->oemId[i] = ' ';
+ }
+ pb->bytesPerSector = 512;
+ pb->sectorsPerCluster = sectorsPerCluster;
+ pb->reservedSectorCount = reservedSectors;
+ pb->fatCount = 2;
+ pb->mediaType = 0XF8;
+ pb->sectorsPerTrack = sectorsPerTrack;
+ pb->headCount = numberOfHeads;
+ pb->hidddenSectors = relSector;
+ pb->totalSectors32 = partSize;
+ pb->sectorsPerFat32 = fatSize;
+ pb->fat32RootCluster = 2;
+ pb->fat32FSInfo = 1;
+ pb->fat32BackBootBlock = 6;
+ pb->driveNumber = 0X80;
+ pb->bootSignature = EXTENDED_BOOT_SIG;
+ pb->volumeSerialNumber = volSerialNumber();
+ memcpy(pb->volumeLabel, noName, sizeof(pb->volumeLabel));
+ memcpy(pb->fileSystemType, fat32str, sizeof(pb->fileSystemType));
+ // write partition boot sector and backup
+ writeCache(relSector);
+ writeCache(relSector + 6);
+ clearCache(true);
+ // write extra boot area and backup
+ writeCache(relSector + 2);
+ writeCache(relSector + 8);
+ fat32_fsinfo_t* pf = &cache.fsinfo;
+ pf->leadSignature = FSINFO_LEAD_SIG;
+ pf->structSignature = FSINFO_STRUCT_SIG;
+ pf->freeCount = 0XFFFFFFFF;
+ pf->nextFree = 0XFFFFFFFF;
+ // write FSINFO sector and backup
+ writeCache(relSector + 1);
+ writeCache(relSector + 7);
+ clearFatDir(fatStart, 2 * fatSize + sectorsPerCluster);
+ clearCache(false);
+ cache.fat32[0] = 0x0FFFFFF8;
+ cache.fat32[1] = 0x0FFFFFFF;
+ cache.fat32[2] = 0x0FFFFFFF;
+ // write first block of FAT and backup for reserved clusters
+ writeCache(fatStart);
+ writeCache(fatStart + fatSize);
+}
+
+/* Format the internal storage with FAT16*/
+void formatCard() {
+ //Start Card
+ startAltClockline();
+ //Get card info
+ cardSizeBlocks = sd.card()->cardSize();
+ cardCapacityMB = (cardSizeBlocks + 2047) / 2048;
+ if (cardCapacityMB <= 16) {
+ sectorsPerCluster = 2;
+ }
+ else if (cardCapacityMB <= 32) {
+ sectorsPerCluster = 4;
+ }
+ else if (cardCapacityMB <= 64) {
+ sectorsPerCluster = 8;
+ }
+ else if (cardCapacityMB <= 128) {
+ sectorsPerCluster = 16;
+ }
+ else if (cardCapacityMB <= 1024) {
+ sectorsPerCluster = 32;
+ }
+ else if (cardCapacityMB <= 32768) {
+ sectorsPerCluster = 64;
+ }
+ else {
+ sectorsPerCluster = 128;
+ }
+ // set fake disk geometry
+ sectorsPerTrack = cardCapacityMB <= 256 ? 32 : 63;
+ if (cardCapacityMB <= 16) {
+ numberOfHeads = 2;
+ }
+ else if (cardCapacityMB <= 32) {
+ numberOfHeads = 4;
+ }
+ else if (cardCapacityMB <= 128) {
+ numberOfHeads = 8;
+ }
+ else if (cardCapacityMB <= 504) {
+ numberOfHeads = 16;
+ }
+ else if (cardCapacityMB <= 1008) {
+ numberOfHeads = 32;
+ }
+ else if (cardCapacityMB <= 2016) {
+ numberOfHeads = 64;
+ }
+ else if (cardCapacityMB <= 4032) {
+ numberOfHeads = 128;
+ }
+ else {
+ numberOfHeads = 255;
+ }
+ //Format with FAT16 or FAT32
+ if (teensyVersion == teensyVersion_old)
+ formatFAT16();
+ else
+ formatFAT32();
+ //End SD
+ endAltClockline();
+}
diff --git a/Firmware_V2/src/hardware/sd.h b/Firmware_V2/src/hardware/sd.h
new file mode 100644
index 0000000..7111f7a
--- /dev/null
+++ b/Firmware_V2/src/hardware/sd.h
@@ -0,0 +1,39 @@
+/*
+*
+* SD - Methods to access the internal SD storage
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+#ifndef SD_H
+#define SD_H
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+bool beginSD();
+void clearCache(uint8_t addSig);
+void clearFatDir(uint32_t bgn, uint32_t count);
+void dateTime(uint16_t* date, uint16_t* time);
+void formatCard();
+void formatFAT16();
+void formatFAT32();
+uint16_t getCardSize();
+uint32_t getSDSpace();
+void initSD();
+uint16_t lbnToCylinder(uint32_t lbn);
+uint8_t lbnToHead(uint32_t lbn);
+uint8_t lbnToSector(uint32_t lbn);
+void refreshFreeSpace();
+uint32_t volSerialNumber();
+uint8_t writeCache(uint32_t lbn);
+void writeMbr();
+
+#endif /* SD_H */
diff --git a/Firmware_V2/src/hardware/touchscreen/ft6206_touchscreen.cpp b/Firmware_V2/src/hardware/touchscreen/ft6206_touchscreen.cpp
new file mode 100644
index 0000000..7cf4c9f
--- /dev/null
+++ b/Firmware_V2/src/hardware/touchscreen/ft6206_touchscreen.cpp
@@ -0,0 +1,97 @@
+/*
+ *
+ * FT6206 Touch controller
+ *
+ * DIY-Thermocam Firmware
+ *
+ * GNU General Public License v3.0
+ *
+ * Copyright by Max Ritter
+ *
+ * http://www.diy-thermocam.net
+ * https://github.com/maxritter/DIY-Thermocam
+ *
+ */
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include
+#include
+#include
+
+/*###################### PRIVATE FUNCTION BODIES ##############################*/
+
+boolean FT6206_Touchscreen::begin(uint8_t threshhold) {
+ writeRegister8(FT6206_REG_THRESHHOLD, threshhold);
+ if ((readRegister8(FT6206_REG_VENDID) != 17) || (readRegister8(FT6206_REG_CHIPID) != 54)) return false;
+ return true;
+}
+
+boolean FT6206_Touchscreen::touched(void) {
+ uint8_t n = readRegister8(FT6206_REG_NUMTOUCHES);
+ if ((n == 1) || (n == 2)) return true;
+ return false;
+}
+
+void FT6206_Touchscreen::readData(uint16_t *x, uint16_t *y) {
+ uint8_t i2cdat[16];
+ Wire.beginTransmission(FT6206_ADDR);
+ Wire.write((byte)0);
+ Wire.endTransmission();
+ Wire.beginTransmission(FT6206_ADDR);
+ Wire.requestFrom((byte)FT6206_ADDR, (byte)32);
+ for (uint8_t i = 0; i < 16; i++)
+ i2cdat[i] = Wire.read();
+ Wire.endTransmission();
+ touches = i2cdat[0x02];
+ if (touches > 2) {
+ touches = 0;
+ *x = *y = 0;
+ }
+ if (touches == 0) {
+ *x = *y = 0;
+ return;
+ }
+ for (uint8_t i = 0; i < 2; i++) {
+ touchX[i] = i2cdat[0x03 + i * 6] & 0x0F;
+ touchX[i] <<= 8;
+ touchX[i] |= i2cdat[0x04 + i * 6];
+ touchY[i] = i2cdat[0x05 + i * 6] & 0x0F;
+ touchY[i] <<= 8;
+ touchY[i] |= i2cdat[0x06 + i * 6];
+ touchID[i] = i2cdat[0x05 + i * 6] >> 4;
+ }
+ *x = touchY[0];
+ *y = touchX[0];
+ *y = map(*y, 0, 240, 240, 0);
+}
+
+TS_Point FT6206_Touchscreen::getPoint(void) {
+ uint16_t x, y;
+ readData(&x, &y);
+ if (rotated) {
+ y = map(y, 0, 240, 240, 0);
+ x = map(x, 0, 320, 320, 0);
+ }
+ return TS_Point(x, y, 1);
+}
+
+uint8_t FT6206_Touchscreen::readRegister8(uint8_t reg) {
+ uint8_t x;
+ Wire.beginTransmission(FT6206_ADDR);
+ Wire.write((byte)reg);
+ Wire.endTransmission();
+ Wire.beginTransmission(FT6206_ADDR);
+ Wire.requestFrom((byte)FT6206_ADDR, (byte)1);
+ x = Wire.read();
+ Wire.endTransmission();
+ return x;
+}
+
+void FT6206_Touchscreen::writeRegister8(uint8_t reg, uint8_t val) {
+ Wire.beginTransmission(FT6206_ADDR);
+ Wire.write((byte)reg);
+ Wire.write((byte)val);
+ Wire.endTransmission();
+}
diff --git a/Firmware_V2/src/hardware/touchscreen/ft6206_touchscreen.h b/Firmware_V2/src/hardware/touchscreen/ft6206_touchscreen.h
new file mode 100644
index 0000000..5ae0944
--- /dev/null
+++ b/Firmware_V2/src/hardware/touchscreen/ft6206_touchscreen.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * FT6206 Touch controller
+ *
+ * DIY-Thermocam Firmware
+ *
+ * GNU General Public License v3.0
+ *
+ * Copyright by Max Ritter
+ *
+ * http://www.diy-thermocam.net
+ * https://github.com/maxritter/DIY-Thermocam
+ *
+ */
+
+/*################# PUBLIC CONSTANTS, VARIABLES & DATA TYPES ##################*/
+
+#ifndef FT6206_TOUCHSCREEN_H
+#define FT6206_TOUCHSCREEN_H
+
+#define FT6206_ADDR 0x38
+#define FT6206_G_FT5201ID 0xA8
+#define FT6206_REG_NUMTOUCHES 0x02
+
+#define FT6206_NUM_X 0x33
+#define FT6206_NUM_Y 0x34
+#define FT6206_REG_MODE 0x00
+#define FT6206_REG_CALIBRATE 0x02
+#define FT6206_REG_WORKMODE 0x00
+#define FT6206_REG_FACTORYMODE 0x40
+#define FT6206_REG_THRESHHOLD 0x80
+#define FT6206_REG_POINTRATE 0x88
+#define FT6206_REG_FIRMVERS 0xA6
+#define FT6206_REG_CHIPID 0xA3
+#define FT6206_REG_VENDID 0xA8
+
+#define FT6206_DEFAULT_THRESSHOLD 128
+
+/*########################## PUBLIC PROCEDURES ################################*/
+
+class FT6206_Touchscreen {
+public:
+ boolean begin(uint8_t thresh = FT6206_DEFAULT_THRESSHOLD);
+ void writeRegister8(uint8_t reg, uint8_t val);
+ uint8_t readRegister8(uint8_t reg);
+ void readData(uint16_t *x, uint16_t *y);
+ boolean touched(void);
+ TS_Point getPoint(void);
+ bool rotated = false;
+private:
+ uint8_t touches;
+ uint16_t touchX[2], touchY[2], touchID[2];
+};
+
+#endif /* FT6206_TOUCHSCREEN_H */
diff --git a/Firmware_V2/src/hardware/touchscreen/touchscreen.cpp b/Firmware_V2/src/hardware/touchscreen/touchscreen.cpp
new file mode 100644
index 0000000..bc8c3c7
--- /dev/null
+++ b/Firmware_V2/src/hardware/touchscreen/touchscreen.cpp
@@ -0,0 +1,123 @@
+/*
+*
+* Touchscreen - FT6206 or XPT2046 controller
+*
+* DIY-Thermocam Firmware
+*
+* GNU General Public License v3.0
+*
+* Copyright by Max Ritter
+*
+* http://www.diy-thermocam.net
+* https://github.com/maxritter/DIY-Thermocam
+*
+*/
+
+/*################################# INCLUDES ##################################*/
+
+#include
+#include