mirror of
https://github.com/thooge/esp32-nmea2000-obp60.git
synced 2025-12-16 15:33:05 +01:00
Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a8cf34343f | |||
| c00a0ecbed | |||
| a16ee74b32 | |||
| 601d56ee49 | |||
| 9a04029cb4 | |||
| 22e3ca3875 | |||
| 8e72537286 | |||
| 494acbf0d0 | |||
| d7251eeb8a | |||
| c4406fd009 | |||
| 0097a1eb1e | |||
| c932724473 | |||
| 672a3843d1 | |||
| 1e0acf2a8f | |||
| 63ae42588f | |||
| cba21574cb | |||
| fbe6c1a9a5 | |||
| ae9334236b | |||
| 318a218470 | |||
| c6df6eac56 | |||
| 4513f9d7b0 | |||
| 2749f25d15 | |||
| 992348ce92 | |||
| 8695d3eeb5 | |||
| 54b4954797 | |||
| 1ada6e5a82 | |||
| 15ca3614ba | |||
| e5ca2a3a3d | |||
| cf305e9f5a | |||
| f823dadc6b | |||
| 2d47702627 | |||
| 15674543b6 | |||
| 0dd6b7c9cf | |||
| cbc0c09d65 | |||
| 1d05c2b5d4 | |||
| 38bdc4f577 | |||
| b8a31f2280 | |||
| 7cff3e62e6 | |||
| 39966098cc | |||
| 11a061d5a2 | |||
| 4600cb7228 | |||
| e89d1ac62e | |||
| 6fb5e01969 | |||
| 5c731bc662 | |||
| 25c2742f5b | |||
| 6479c7d711 | |||
| e287bfa72e | |||
| 5a652e2c19 | |||
| 5081f3a684 | |||
| 7de226b447 | |||
| f6e2fa7806 | |||
| d5b0af3b19 | |||
| aed389f3b2 | |||
| 32ba4a64ed | |||
|
|
7edd201daa | ||
| eb51092b23 | |||
| f4d88f1b8b | |||
| 08cd2ad4b1 | |||
| b50d82eff0 | |||
| 6ae4e195d6 | |||
| c5e346f4eb |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,3 +6,4 @@
|
|||||||
generated/*
|
generated/*
|
||||||
lib/generated
|
lib/generated
|
||||||
webinstall/token.php
|
webinstall/token.php
|
||||||
|
*~
|
||||||
|
|||||||
@@ -205,6 +205,11 @@ def generateCfg(inFile,outFile,impl):
|
|||||||
secret="false";
|
secret="false";
|
||||||
if item.get('type') == 'password':
|
if item.get('type') == 'password':
|
||||||
secret="true"
|
secret="true"
|
||||||
|
"""
|
||||||
|
PSRAM Allocator TODO Tests
|
||||||
|
new (heap_caps_malloc(sizeof(GwConfigInterface), MALLOC_CAP_SPIRAM))
|
||||||
|
"""
|
||||||
|
#data+=" new (heap_caps_malloc(sizeof(GwConfigInterface), MALLOC_CAP_SPIRAM)) GwConfigInterface(%s,\"%s\",%s);\n"%(name,item.get('default'),secret)
|
||||||
data+=" new GwConfigInterface(%s,\"%s\",%s);\n"%(name,item.get('default'),secret)
|
data+=" new GwConfigInterface(%s,\"%s\",%s);\n"%(name,item.get('default'),secret)
|
||||||
data+='}\n'
|
data+='}\n'
|
||||||
writeFileIfChanged(outFile,data)
|
writeFileIfChanged(outFile,data)
|
||||||
@@ -501,10 +506,12 @@ def prebuild(env):
|
|||||||
genereateUserTasks(os.path.join(outPath(), TASK_INCLUDE))
|
genereateUserTasks(os.path.join(outPath(), TASK_INCLUDE))
|
||||||
generateFile(os.path.join(basePath(),XDR_FILE),os.path.join(outPath(),XDR_INCLUDE),generateXdrMappings)
|
generateFile(os.path.join(basePath(),XDR_FILE),os.path.join(outPath(),XDR_INCLUDE),generateXdrMappings)
|
||||||
generateFile(os.path.join(basePath(),GROVE_CONFIG_IN),os.path.join(outPath(),GROVE_CONFIG),generateGroveDefs,inMode='r')
|
generateFile(os.path.join(basePath(),GROVE_CONFIG_IN),os.path.join(outPath(),GROVE_CONFIG),generateGroveDefs,inMode='r')
|
||||||
version="dev"+datetime.now().strftime("%Y%m%d")
|
version = "dev{}{}".format(datetime.now().strftime("%Y%m%d"), "-ext")
|
||||||
env.Append(CPPDEFINES=[('GWDEVVERSION',version)])
|
env.Append(CPPDEFINES=[('GWDEVVERSION',version)])
|
||||||
|
|
||||||
def cleangenerated(source, target, env):
|
def cleangenerated(source, target, env):
|
||||||
|
# TODO source / target order?
|
||||||
|
print("CLEAN: {} - {}".format(source, target))
|
||||||
od=outPath()
|
od=outPath()
|
||||||
if os.path.isdir(od):
|
if os.path.isdir(od):
|
||||||
print("#cleaning up %s"%od)
|
print("#cleaning up %s"%od)
|
||||||
@@ -514,7 +521,6 @@ def cleangenerated(source, target, env):
|
|||||||
fn=os.path.join(od,f)
|
fn=os.path.join(od,f)
|
||||||
os.unlink(f)
|
os.unlink(f)
|
||||||
|
|
||||||
|
|
||||||
print("#prescript...")
|
print("#prescript...")
|
||||||
prebuild(env)
|
prebuild(env)
|
||||||
board="PLATFORM_BOARD_%s"%env["BOARD"].replace("-","_").upper()
|
board="PLATFORM_BOARD_%s"%env["BOARD"].replace("-","_").upper()
|
||||||
|
|||||||
@@ -1,542 +0,0 @@
|
|||||||
print("running extra...")
|
|
||||||
import gzip
|
|
||||||
import shutil
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import inspect
|
|
||||||
import json
|
|
||||||
import glob
|
|
||||||
from datetime import datetime
|
|
||||||
import re
|
|
||||||
import pprint
|
|
||||||
from platformio.project.config import ProjectConfig
|
|
||||||
from platformio.project.exception import InvalidProjectConfError
|
|
||||||
|
|
||||||
Import("env")
|
|
||||||
#print(env.Dump())
|
|
||||||
OWN_FILE="extra_script.py"
|
|
||||||
GEN_DIR='lib/generated'
|
|
||||||
CFG_FILE='web/config.json'
|
|
||||||
XDR_FILE='web/xdrconfig.json'
|
|
||||||
INDEXJS="index.js"
|
|
||||||
INDEXCSS="index.css"
|
|
||||||
CFG_INCLUDE='GwConfigDefinitions.h'
|
|
||||||
CFG_INCLUDE_IMPL='GwConfigDefImpl.h'
|
|
||||||
XDR_INCLUDE='GwXdrTypeMappings.h'
|
|
||||||
TASK_INCLUDE='GwUserTasks.h'
|
|
||||||
GROVE_CONFIG="GwM5GroveGen.h"
|
|
||||||
GROVE_CONFIG_IN="lib/hardware/GwM5Grove.in"
|
|
||||||
EMBEDDED_INCLUDE="GwEmbeddedFiles.h"
|
|
||||||
|
|
||||||
def getEmbeddedFiles(env):
|
|
||||||
rt=[]
|
|
||||||
efiles=env.GetProjectOption("board_build.embed_files")
|
|
||||||
for f in efiles.split("\n"):
|
|
||||||
if f == '':
|
|
||||||
continue
|
|
||||||
rt.append(f)
|
|
||||||
return rt
|
|
||||||
|
|
||||||
def basePath():
|
|
||||||
#see: https://stackoverflow.com/questions/16771894/python-nameerror-global-name-file-is-not-defined
|
|
||||||
return os.path.dirname(inspect.getfile(lambda: None))
|
|
||||||
|
|
||||||
def outPath():
|
|
||||||
return os.path.join(basePath(),GEN_DIR)
|
|
||||||
def checkDir():
|
|
||||||
dn=outPath()
|
|
||||||
if not os.path.exists(dn):
|
|
||||||
os.makedirs(dn)
|
|
||||||
if not os.path.isdir(dn):
|
|
||||||
print("unable to create %s"%dn)
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def isCurrent(infile,outfile):
|
|
||||||
if os.path.exists(outfile):
|
|
||||||
otime=os.path.getmtime(outfile)
|
|
||||||
itime=os.path.getmtime(infile)
|
|
||||||
if (otime >= itime):
|
|
||||||
own=os.path.join(basePath(),OWN_FILE)
|
|
||||||
if os.path.exists(own):
|
|
||||||
owntime=os.path.getmtime(own)
|
|
||||||
if owntime > otime:
|
|
||||||
return False
|
|
||||||
print("%s is newer then %s, no need to recreate"%(outfile,infile))
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
def compressFile(inFile,outfile):
|
|
||||||
if isCurrent(inFile,outfile):
|
|
||||||
return
|
|
||||||
print("compressing %s"%inFile)
|
|
||||||
with open(inFile, 'rb') as f_in:
|
|
||||||
with gzip.open(outfile, 'wb') as f_out:
|
|
||||||
shutil.copyfileobj(f_in, f_out)
|
|
||||||
|
|
||||||
def generateFile(infile,outfile,callback,inMode='rb',outMode='w'):
|
|
||||||
if isCurrent(infile,outfile):
|
|
||||||
return
|
|
||||||
print("creating %s"%outfile)
|
|
||||||
oh=None
|
|
||||||
with open(infile,inMode) as ch:
|
|
||||||
with open(outfile,outMode) as oh:
|
|
||||||
try:
|
|
||||||
callback(ch,oh,inFile=infile)
|
|
||||||
oh.close()
|
|
||||||
except Exception as e:
|
|
||||||
try:
|
|
||||||
oh.close()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
os.unlink(outfile)
|
|
||||||
raise
|
|
||||||
|
|
||||||
def writeFileIfChanged(fileName,data):
|
|
||||||
if os.path.exists(fileName):
|
|
||||||
with open(fileName,"r") as ih:
|
|
||||||
old=ih.read()
|
|
||||||
ih.close()
|
|
||||||
if old == data:
|
|
||||||
return False
|
|
||||||
print("#generating %s"%fileName)
|
|
||||||
with open(fileName,"w") as oh:
|
|
||||||
oh.write(data)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def mergeConfig(base,other):
|
|
||||||
try:
|
|
||||||
customconfig = env.GetProjectOption("custom_config")
|
|
||||||
except InvalidProjectConfError:
|
|
||||||
customconfig = None
|
|
||||||
for bdir in other:
|
|
||||||
if customconfig and os.path.exists(os.path.join(bdir,customconfig)):
|
|
||||||
cname=os.path.join(bdir,customconfig)
|
|
||||||
print("merge custom config {}".format(cname))
|
|
||||||
with open(cname,'rb') as ah:
|
|
||||||
base += json.load(ah)
|
|
||||||
continue
|
|
||||||
cname=os.path.join(bdir,"config.json")
|
|
||||||
if os.path.exists(cname):
|
|
||||||
print("merge config %s"%cname)
|
|
||||||
with open(cname,'rb') as ah:
|
|
||||||
merge=json.load(ah)
|
|
||||||
base=base+merge
|
|
||||||
return base
|
|
||||||
|
|
||||||
def replaceTexts(data,replacements):
|
|
||||||
if replacements is None:
|
|
||||||
return data
|
|
||||||
if isinstance(data,str):
|
|
||||||
for k,v in replacements.items():
|
|
||||||
data=data.replace("$"+k,str(v))
|
|
||||||
return data
|
|
||||||
if isinstance(data,list):
|
|
||||||
rt=[]
|
|
||||||
for e in data:
|
|
||||||
rt.append(replaceTexts(e,replacements))
|
|
||||||
return rt
|
|
||||||
if isinstance(data,dict):
|
|
||||||
rt={}
|
|
||||||
for k,v in data.items():
|
|
||||||
rt[replaceTexts(k,replacements)]=replaceTexts(v,replacements)
|
|
||||||
return rt
|
|
||||||
return data
|
|
||||||
def expandConfig(config):
|
|
||||||
rt=[]
|
|
||||||
for item in config:
|
|
||||||
type=item.get('type')
|
|
||||||
if type != 'array':
|
|
||||||
rt.append(item)
|
|
||||||
continue
|
|
||||||
replacements=item.get('replace')
|
|
||||||
children=item.get('children')
|
|
||||||
name=item.get('name')
|
|
||||||
if name is None:
|
|
||||||
name="#unknown#"
|
|
||||||
if not isinstance(replacements,list):
|
|
||||||
raise Exception("missing replacements at array %s"%name)
|
|
||||||
for replace in replacements:
|
|
||||||
if children is not None:
|
|
||||||
for c in children:
|
|
||||||
rt.append(replaceTexts(c,replace))
|
|
||||||
return rt
|
|
||||||
|
|
||||||
def generateMergedConfig(inFile,outFile,addDirs=[]):
|
|
||||||
if not os.path.exists(inFile):
|
|
||||||
raise Exception("unable to read cfg file %s"%inFile)
|
|
||||||
data=""
|
|
||||||
with open(inFile,'rb') as ch:
|
|
||||||
config=json.load(ch)
|
|
||||||
config=mergeConfig(config,addDirs)
|
|
||||||
config=expandConfig(config)
|
|
||||||
data=json.dumps(config,indent=2)
|
|
||||||
writeFileIfChanged(outFile,data)
|
|
||||||
|
|
||||||
def generateCfg(inFile,outFile,impl):
|
|
||||||
if not os.path.exists(inFile):
|
|
||||||
raise Exception("unable to read cfg file %s"%inFile)
|
|
||||||
data=""
|
|
||||||
with open(inFile,'rb') as ch:
|
|
||||||
config=json.load(ch)
|
|
||||||
data+="//generated from %s\n"%inFile
|
|
||||||
l=len(config)
|
|
||||||
idx=0
|
|
||||||
if not impl:
|
|
||||||
data+='#include "GwConfigItem.h"\n'
|
|
||||||
data+='class GwConfigDefinitions{\n'
|
|
||||||
data+=' public:\n'
|
|
||||||
data+=' int getNumConfig() const{return %d;}\n'%(l)
|
|
||||||
for item in config:
|
|
||||||
n=item.get('name')
|
|
||||||
if n is None:
|
|
||||||
continue
|
|
||||||
if len(n) > 15:
|
|
||||||
raise Exception("%s: config names must be max 15 caracters"%n)
|
|
||||||
data+=' static constexpr const char* %s="%s";\n'%(n,n)
|
|
||||||
data+="};\n"
|
|
||||||
else:
|
|
||||||
data+='void GwConfigHandler::populateConfigs(GwConfigInterface **config){\n'
|
|
||||||
for item in config:
|
|
||||||
name=item.get('name')
|
|
||||||
if name is None:
|
|
||||||
continue
|
|
||||||
data+=' configs[%d]='%(idx)
|
|
||||||
idx+=1
|
|
||||||
secret="false";
|
|
||||||
if item.get('type') == 'password':
|
|
||||||
secret="true"
|
|
||||||
data+=" new GwConfigInterface(%s,\"%s\",%s);\n"%(name,item.get('default'),secret)
|
|
||||||
data+='}\n'
|
|
||||||
writeFileIfChanged(outFile,data)
|
|
||||||
|
|
||||||
def labelFilter(label):
|
|
||||||
return re.sub("[^a-zA-Z0-9]","",re.sub("\([0-9]*\)","",label))
|
|
||||||
def generateXdrMappings(fp,oh,inFile=''):
|
|
||||||
jdoc=json.load(fp)
|
|
||||||
oh.write("static GwXDRTypeMapping* typeMappings[]={\n")
|
|
||||||
first=True
|
|
||||||
for cat in jdoc:
|
|
||||||
item=jdoc[cat]
|
|
||||||
cid=item.get('id')
|
|
||||||
if cid is None:
|
|
||||||
continue
|
|
||||||
tc=item.get('type')
|
|
||||||
if tc is not None:
|
|
||||||
if first:
|
|
||||||
first=False
|
|
||||||
else:
|
|
||||||
oh.write(",\n")
|
|
||||||
oh.write(" new GwXDRTypeMapping(%d,0,%d) /*%s*/"%(cid,tc,cat))
|
|
||||||
fields=item.get('fields')
|
|
||||||
if fields is None:
|
|
||||||
continue
|
|
||||||
idx=0
|
|
||||||
for fe in fields:
|
|
||||||
if not isinstance(fe,dict):
|
|
||||||
continue
|
|
||||||
tc=fe.get('t')
|
|
||||||
id=fe.get('v')
|
|
||||||
if id is None:
|
|
||||||
id=idx
|
|
||||||
idx+=1
|
|
||||||
l=fe.get('l') or ''
|
|
||||||
if tc is None or id is None:
|
|
||||||
continue
|
|
||||||
if first:
|
|
||||||
first=False
|
|
||||||
else:
|
|
||||||
oh.write(",\n")
|
|
||||||
oh.write(" new GwXDRTypeMapping(%d,%d,%d) /*%s:%s*/"%(cid,id,tc,cat,l))
|
|
||||||
oh.write("\n")
|
|
||||||
oh.write("};\n")
|
|
||||||
for cat in jdoc:
|
|
||||||
item=jdoc[cat]
|
|
||||||
cid=item.get('id')
|
|
||||||
if cid is None:
|
|
||||||
continue
|
|
||||||
selectors=item.get('selector')
|
|
||||||
if selectors is not None:
|
|
||||||
for selector in selectors:
|
|
||||||
label=selector.get('l')
|
|
||||||
value=selector.get('v')
|
|
||||||
if label is not None and value is not None:
|
|
||||||
label=labelFilter(label)
|
|
||||||
define=("GWXDRSEL_%s_%s"%(cat,label)).upper()
|
|
||||||
oh.write(" #define %s %s\n"%(define,value))
|
|
||||||
fields=item.get('fields')
|
|
||||||
if fields is not None:
|
|
||||||
idx=0
|
|
||||||
for field in fields:
|
|
||||||
v=field.get('v')
|
|
||||||
if v is None:
|
|
||||||
v=idx
|
|
||||||
else:
|
|
||||||
v=int(v)
|
|
||||||
label=field.get('l')
|
|
||||||
if v is not None and label is not None:
|
|
||||||
define=("GWXDRFIELD_%s_%s"%(cat,labelFilter(label))).upper();
|
|
||||||
oh.write(" #define %s %s\n"%(define,str(v)))
|
|
||||||
idx+=1
|
|
||||||
|
|
||||||
class Grove:
|
|
||||||
def __init__(self,name) -> None:
|
|
||||||
self.name=name
|
|
||||||
def _ss(self,z=False):
|
|
||||||
if z:
|
|
||||||
return self.name
|
|
||||||
return self.name if self.name != 'Z' else ''
|
|
||||||
def _suffix(self):
|
|
||||||
return '_'+self.name if self.name != 'Z' else ''
|
|
||||||
def replace(self,line):
|
|
||||||
if line is None:
|
|
||||||
return line
|
|
||||||
return line.replace('$G$',self._ss()).replace('$Z$',self._ss(True)).replace('$GS$',self._suffix())
|
|
||||||
def generateGroveDefs(inh,outh,inFile=''):
|
|
||||||
GROVES=[Grove('Z'),Grove('A'),Grove('B'),Grove('C')]
|
|
||||||
definition=[]
|
|
||||||
started=False
|
|
||||||
def writeConfig():
|
|
||||||
for grove in GROVES:
|
|
||||||
for cl in definition:
|
|
||||||
outh.write(grove.replace(cl))
|
|
||||||
|
|
||||||
for line in inh:
|
|
||||||
if re.match(" *#GROVE",line):
|
|
||||||
started=True
|
|
||||||
if len(definition) > 0:
|
|
||||||
writeConfig()
|
|
||||||
definition=[]
|
|
||||||
continue
|
|
||||||
if started:
|
|
||||||
definition.append(line)
|
|
||||||
if len(definition) > 0:
|
|
||||||
writeConfig()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
userTaskDirs=[]
|
|
||||||
|
|
||||||
def getUserTaskDirs():
|
|
||||||
rt=[]
|
|
||||||
taskdirs=glob.glob(os.path.join( basePath(),'lib','*task*'))
|
|
||||||
for task in taskdirs:
|
|
||||||
rt.append(task)
|
|
||||||
return rt
|
|
||||||
|
|
||||||
def checkAndAdd(file,names,ilist):
|
|
||||||
if not file.endswith('.h'):
|
|
||||||
return
|
|
||||||
match=False
|
|
||||||
for cmp in names:
|
|
||||||
#print("##check %s<->%s"%(f.lower(),cmp))
|
|
||||||
if file.lower() == cmp:
|
|
||||||
match=True
|
|
||||||
if not match:
|
|
||||||
return
|
|
||||||
ilist.append(file)
|
|
||||||
def genereateUserTasks(outfile):
|
|
||||||
includes=[]
|
|
||||||
for task in userTaskDirs:
|
|
||||||
#print("##taskdir=%s"%task)
|
|
||||||
base=os.path.basename(task)
|
|
||||||
includeNames=[base.lower()+".h",'gw'+base.lower()+'.h']
|
|
||||||
for f in os.listdir(task):
|
|
||||||
checkAndAdd(f,includeNames,includes)
|
|
||||||
includeData=""
|
|
||||||
for i in includes:
|
|
||||||
print("#task include %s"%i)
|
|
||||||
includeData+="#include <%s>\n"%i
|
|
||||||
writeFileIfChanged(outfile,includeData)
|
|
||||||
|
|
||||||
def generateEmbedded(elist,outFile):
|
|
||||||
content=""
|
|
||||||
for entry in elist:
|
|
||||||
content+="EMBED_GZ_FILE(\"%s\",%s,\"%s\");\n"%entry
|
|
||||||
writeFileIfChanged(outFile,content)
|
|
||||||
|
|
||||||
def getContentType(fn):
|
|
||||||
if (fn.endswith('.gz')):
|
|
||||||
fn=fn[0:-3]
|
|
||||||
if (fn.endswith('html')):
|
|
||||||
return "text/html"
|
|
||||||
if (fn.endswith('json')):
|
|
||||||
return "application/json"
|
|
||||||
if (fn.endswith('js')):
|
|
||||||
return "text/javascript"
|
|
||||||
if (fn.endswith('css')):
|
|
||||||
return "text/css"
|
|
||||||
return "application/octet-stream"
|
|
||||||
|
|
||||||
|
|
||||||
def getLibs():
|
|
||||||
base=os.path.join(basePath(),"lib")
|
|
||||||
rt=[]
|
|
||||||
for sd in os.listdir(base):
|
|
||||||
if sd == '..':
|
|
||||||
continue
|
|
||||||
if sd == '.':
|
|
||||||
continue
|
|
||||||
fn=os.path.join(base,sd)
|
|
||||||
if os.path.isdir(fn):
|
|
||||||
rt.append(sd)
|
|
||||||
EXTRAS=['generated']
|
|
||||||
for e in EXTRAS:
|
|
||||||
if not e in rt:
|
|
||||||
rt.append(e)
|
|
||||||
return rt
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def joinFiles(target,pattern,dirlist):
|
|
||||||
flist=[]
|
|
||||||
for dir in dirlist:
|
|
||||||
fn=os.path.join(dir,pattern)
|
|
||||||
if os.path.exists(fn):
|
|
||||||
flist.append(fn)
|
|
||||||
current=False
|
|
||||||
if os.path.exists(target):
|
|
||||||
current=True
|
|
||||||
for f in flist:
|
|
||||||
if not isCurrent(f,target):
|
|
||||||
current=False
|
|
||||||
break
|
|
||||||
if current:
|
|
||||||
print("%s is up to date"%target)
|
|
||||||
return
|
|
||||||
print("creating %s"%target)
|
|
||||||
with gzip.open(target,"wb") as oh:
|
|
||||||
for fn in flist:
|
|
||||||
print("adding %s to %s"%(fn,target))
|
|
||||||
with open(fn,"rb") as rh:
|
|
||||||
shutil.copyfileobj(rh,oh)
|
|
||||||
|
|
||||||
|
|
||||||
OWNLIBS=getLibs()+["FS","WiFi"]
|
|
||||||
GLOBAL_INCLUDES=[]
|
|
||||||
|
|
||||||
def handleDeps(env):
|
|
||||||
#overwrite the GetProjectConfig
|
|
||||||
#to inject all our libs
|
|
||||||
oldGetProjectConfig=env.GetProjectConfig
|
|
||||||
def GetProjectConfigX(env):
|
|
||||||
rt=oldGetProjectConfig()
|
|
||||||
cenv="env:"+env['PIOENV']
|
|
||||||
libs=[]
|
|
||||||
for section,options in rt.as_tuple():
|
|
||||||
if section == cenv:
|
|
||||||
for key,values in options:
|
|
||||||
if key == 'lib_deps':
|
|
||||||
libs=values
|
|
||||||
|
|
||||||
mustUpdate=False
|
|
||||||
for lib in OWNLIBS:
|
|
||||||
if not lib in libs:
|
|
||||||
libs.append(lib)
|
|
||||||
mustUpdate=True
|
|
||||||
if mustUpdate:
|
|
||||||
update=[(cenv,[('lib_deps',libs)])]
|
|
||||||
rt.update(update)
|
|
||||||
return rt
|
|
||||||
env.AddMethod(GetProjectConfigX,"GetProjectConfig")
|
|
||||||
#store the list of all includes after we resolved
|
|
||||||
#the dependencies for our main project
|
|
||||||
#we will use them for all compilations afterwards
|
|
||||||
oldLibBuilder=env.ConfigureProjectLibBuilder
|
|
||||||
def ConfigureProjectLibBuilderX(env):
|
|
||||||
global GLOBAL_INCLUDES
|
|
||||||
project=oldLibBuilder()
|
|
||||||
#print("##ConfigureProjectLibBuilderX")
|
|
||||||
#pprint.pprint(project)
|
|
||||||
if project.depbuilders:
|
|
||||||
#print("##depbuilders %s"%",".join(map(lambda x: x.path,project.depbuilders)))
|
|
||||||
for db in project.depbuilders:
|
|
||||||
idirs=db.get_include_dirs()
|
|
||||||
for id in idirs:
|
|
||||||
if not id in GLOBAL_INCLUDES:
|
|
||||||
GLOBAL_INCLUDES.append(id)
|
|
||||||
return project
|
|
||||||
env.AddMethod(ConfigureProjectLibBuilderX,"ConfigureProjectLibBuilder")
|
|
||||||
def injectIncludes(env,node):
|
|
||||||
return env.Object(
|
|
||||||
node,
|
|
||||||
CPPPATH=env["CPPPATH"]+GLOBAL_INCLUDES
|
|
||||||
)
|
|
||||||
env.AddBuildMiddleware(injectIncludes)
|
|
||||||
|
|
||||||
|
|
||||||
def prebuild(env):
|
|
||||||
global userTaskDirs
|
|
||||||
print("#prebuild running")
|
|
||||||
if not checkDir():
|
|
||||||
sys.exit(1)
|
|
||||||
ldf_mode=env.GetProjectOption("lib_ldf_mode")
|
|
||||||
if ldf_mode == 'off':
|
|
||||||
print("##ldf off - own dependency handling")
|
|
||||||
handleDeps(env)
|
|
||||||
userTaskDirs=getUserTaskDirs()
|
|
||||||
mergedConfig=os.path.join(outPath(),os.path.basename(CFG_FILE))
|
|
||||||
generateMergedConfig(os.path.join(basePath(),CFG_FILE),mergedConfig,userTaskDirs)
|
|
||||||
compressFile(mergedConfig,mergedConfig+".gz")
|
|
||||||
generateCfg(mergedConfig,os.path.join(outPath(),CFG_INCLUDE),False)
|
|
||||||
generateCfg(mergedConfig,os.path.join(outPath(),CFG_INCLUDE_IMPL),True)
|
|
||||||
joinFiles(os.path.join(outPath(),INDEXJS+".gz"),INDEXJS,["web"]+userTaskDirs)
|
|
||||||
joinFiles(os.path.join(outPath(),INDEXCSS+".gz"),INDEXCSS,["web"]+userTaskDirs)
|
|
||||||
embedded=getEmbeddedFiles(env)
|
|
||||||
filedefs=[]
|
|
||||||
for ef in embedded:
|
|
||||||
print("#checking embedded file %s"%ef)
|
|
||||||
(dn,fn)=os.path.split(ef)
|
|
||||||
pureName=fn
|
|
||||||
if pureName.endswith('.gz'):
|
|
||||||
pureName=pureName[0:-3]
|
|
||||||
ct=getContentType(pureName)
|
|
||||||
usname=ef.replace('/','_').replace('.','_')
|
|
||||||
filedefs.append((pureName,usname,ct))
|
|
||||||
inFile=os.path.join(basePath(),"web",pureName)
|
|
||||||
if os.path.exists(inFile):
|
|
||||||
compressFile(inFile,ef)
|
|
||||||
else:
|
|
||||||
print("#WARNING: infile %s for %s not found"%(inFile,ef))
|
|
||||||
generateEmbedded(filedefs,os.path.join(outPath(),EMBEDDED_INCLUDE))
|
|
||||||
genereateUserTasks(os.path.join(outPath(), TASK_INCLUDE))
|
|
||||||
generateFile(os.path.join(basePath(),XDR_FILE),os.path.join(outPath(),XDR_INCLUDE),generateXdrMappings)
|
|
||||||
generateFile(os.path.join(basePath(),GROVE_CONFIG_IN),os.path.join(outPath(),GROVE_CONFIG),generateGroveDefs,inMode='r')
|
|
||||||
version="dev"+datetime.now().strftime("%Y%m%d")
|
|
||||||
env.Append(CPPDEFINES=[('GWDEVVERSION',version)])
|
|
||||||
|
|
||||||
def cleangenerated(source, target, env):
|
|
||||||
od=outPath()
|
|
||||||
if os.path.isdir(od):
|
|
||||||
print("#cleaning up %s"%od)
|
|
||||||
for f in os.listdir(od):
|
|
||||||
if f == "." or f == "..":
|
|
||||||
continue
|
|
||||||
fn=os.path.join(od,f)
|
|
||||||
os.unlink(f)
|
|
||||||
|
|
||||||
|
|
||||||
print("#prescript...")
|
|
||||||
prebuild(env)
|
|
||||||
board="PLATFORM_BOARD_%s"%env["BOARD"].replace("-","_").upper()
|
|
||||||
print("Board=#%s#"%board)
|
|
||||||
print("BuildFlags=%s"%(" ".join(env["BUILD_FLAGS"])))
|
|
||||||
env.Append(
|
|
||||||
LINKFLAGS=[ "-u", "custom_app_desc" ],
|
|
||||||
CPPDEFINES=[(board,"1")]
|
|
||||||
)
|
|
||||||
#script does not run on clean yet - maybe in the future
|
|
||||||
env.AddPostAction("clean",cleangenerated)
|
|
||||||
|
|
||||||
#look for extra task scripts and include them here
|
|
||||||
for taskdir in userTaskDirs:
|
|
||||||
script = os.path.join(taskdir, "extra_task.py")
|
|
||||||
if os.path.isfile(script):
|
|
||||||
taskname = os.path.basename(os.path.normpath(taskdir))
|
|
||||||
print("#extra task script for '{}'".format(taskname))
|
|
||||||
with open(script) as fh:
|
|
||||||
try:
|
|
||||||
code = compile(fh.read(), taskname, 'exec')
|
|
||||||
except SyntaxError:
|
|
||||||
print("#ERROR: script does not compile")
|
|
||||||
continue
|
|
||||||
exec(code)
|
|
||||||
@@ -1,518 +0,0 @@
|
|||||||
print("running extra...")
|
|
||||||
import gzip
|
|
||||||
import shutil
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import inspect
|
|
||||||
import json
|
|
||||||
import glob
|
|
||||||
from datetime import datetime
|
|
||||||
import re
|
|
||||||
import pprint
|
|
||||||
from platformio.project.config import ProjectConfig
|
|
||||||
|
|
||||||
|
|
||||||
Import("env")
|
|
||||||
#print(env.Dump())
|
|
||||||
OWN_FILE="extra_script.py"
|
|
||||||
GEN_DIR='lib/generated'
|
|
||||||
CFG_FILE='web/config.json'
|
|
||||||
XDR_FILE='web/xdrconfig.json'
|
|
||||||
INDEXJS="index.js"
|
|
||||||
INDEXCSS="index.css"
|
|
||||||
CFG_INCLUDE='GwConfigDefinitions.h'
|
|
||||||
CFG_INCLUDE_IMPL='GwConfigDefImpl.h'
|
|
||||||
XDR_INCLUDE='GwXdrTypeMappings.h'
|
|
||||||
TASK_INCLUDE='GwUserTasks.h'
|
|
||||||
GROVE_CONFIG="GwM5GroveGen.h"
|
|
||||||
GROVE_CONFIG_IN="lib/hardware/GwM5Grove.in"
|
|
||||||
EMBEDDED_INCLUDE="GwEmbeddedFiles.h"
|
|
||||||
|
|
||||||
def getEmbeddedFiles(env):
|
|
||||||
rt=[]
|
|
||||||
efiles=env.GetProjectOption("board_build.embed_files")
|
|
||||||
for f in efiles.split("\n"):
|
|
||||||
if f == '':
|
|
||||||
continue
|
|
||||||
rt.append(f)
|
|
||||||
return rt
|
|
||||||
|
|
||||||
def basePath():
|
|
||||||
#see: https://stackoverflow.com/questions/16771894/python-nameerror-global-name-file-is-not-defined
|
|
||||||
return os.path.dirname(inspect.getfile(lambda: None))
|
|
||||||
|
|
||||||
def outPath():
|
|
||||||
return os.path.join(basePath(),GEN_DIR)
|
|
||||||
def checkDir():
|
|
||||||
dn=outPath()
|
|
||||||
if not os.path.exists(dn):
|
|
||||||
os.makedirs(dn)
|
|
||||||
if not os.path.isdir(dn):
|
|
||||||
print("unable to create %s"%dn)
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def isCurrent(infile,outfile):
|
|
||||||
if os.path.exists(outfile):
|
|
||||||
otime=os.path.getmtime(outfile)
|
|
||||||
itime=os.path.getmtime(infile)
|
|
||||||
if (otime >= itime):
|
|
||||||
own=os.path.join(basePath(),OWN_FILE)
|
|
||||||
if os.path.exists(own):
|
|
||||||
owntime=os.path.getmtime(own)
|
|
||||||
if owntime > otime:
|
|
||||||
return False
|
|
||||||
print("%s is newer then %s, no need to recreate"%(outfile,infile))
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
def compressFile(inFile,outfile):
|
|
||||||
if isCurrent(inFile,outfile):
|
|
||||||
return
|
|
||||||
print("compressing %s"%inFile)
|
|
||||||
with open(inFile, 'rb') as f_in:
|
|
||||||
with gzip.open(outfile, 'wb') as f_out:
|
|
||||||
shutil.copyfileobj(f_in, f_out)
|
|
||||||
|
|
||||||
def generateFile(infile,outfile,callback,inMode='rb',outMode='w'):
|
|
||||||
if isCurrent(infile,outfile):
|
|
||||||
return
|
|
||||||
print("creating %s"%outfile)
|
|
||||||
oh=None
|
|
||||||
with open(infile,inMode) as ch:
|
|
||||||
with open(outfile,outMode) as oh:
|
|
||||||
try:
|
|
||||||
callback(ch,oh,inFile=infile)
|
|
||||||
oh.close()
|
|
||||||
except Exception as e:
|
|
||||||
try:
|
|
||||||
oh.close()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
os.unlink(outfile)
|
|
||||||
raise
|
|
||||||
|
|
||||||
def writeFileIfChanged(fileName,data):
|
|
||||||
if os.path.exists(fileName):
|
|
||||||
with open(fileName,"r") as ih:
|
|
||||||
old=ih.read()
|
|
||||||
ih.close()
|
|
||||||
if old == data:
|
|
||||||
return False
|
|
||||||
print("#generating %s"%fileName)
|
|
||||||
with open(fileName,"w") as oh:
|
|
||||||
oh.write(data)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def mergeConfig(base,other):
|
|
||||||
for bdir in other:
|
|
||||||
cname=os.path.join(bdir,"config.json")
|
|
||||||
if os.path.exists(cname):
|
|
||||||
print("merge config %s"%cname)
|
|
||||||
with open(cname,'rb') as ah:
|
|
||||||
merge=json.load(ah)
|
|
||||||
base=base+merge
|
|
||||||
return base
|
|
||||||
|
|
||||||
def replaceTexts(data,replacements):
|
|
||||||
if replacements is None:
|
|
||||||
return data
|
|
||||||
if isinstance(data,str):
|
|
||||||
for k,v in replacements.items():
|
|
||||||
data=data.replace("$"+k,str(v))
|
|
||||||
return data
|
|
||||||
if isinstance(data,list):
|
|
||||||
rt=[]
|
|
||||||
for e in data:
|
|
||||||
rt.append(replaceTexts(e,replacements))
|
|
||||||
return rt
|
|
||||||
if isinstance(data,dict):
|
|
||||||
rt={}
|
|
||||||
for k,v in data.items():
|
|
||||||
rt[replaceTexts(k,replacements)]=replaceTexts(v,replacements)
|
|
||||||
return rt
|
|
||||||
return data
|
|
||||||
def expandConfig(config):
|
|
||||||
rt=[]
|
|
||||||
for item in config:
|
|
||||||
type=item.get('type')
|
|
||||||
if type != 'array':
|
|
||||||
rt.append(item)
|
|
||||||
continue
|
|
||||||
replacements=item.get('replace')
|
|
||||||
children=item.get('children')
|
|
||||||
name=item.get('name')
|
|
||||||
if name is None:
|
|
||||||
name="#unknown#"
|
|
||||||
if not isinstance(replacements,list):
|
|
||||||
raise Exception("missing replacements at array %s"%name)
|
|
||||||
for replace in replacements:
|
|
||||||
if children is not None:
|
|
||||||
for c in children:
|
|
||||||
rt.append(replaceTexts(c,replace))
|
|
||||||
return rt
|
|
||||||
|
|
||||||
def generateMergedConfig(inFile,outFile,addDirs=[]):
|
|
||||||
if not os.path.exists(inFile):
|
|
||||||
raise Exception("unable to read cfg file %s"%inFile)
|
|
||||||
data=""
|
|
||||||
with open(inFile,'rb') as ch:
|
|
||||||
config=json.load(ch)
|
|
||||||
config=mergeConfig(config,addDirs)
|
|
||||||
config=expandConfig(config)
|
|
||||||
data=json.dumps(config,indent=2)
|
|
||||||
writeFileIfChanged(outFile,data)
|
|
||||||
|
|
||||||
def generateCfg(inFile,outFile,impl):
|
|
||||||
if not os.path.exists(inFile):
|
|
||||||
raise Exception("unable to read cfg file %s"%inFile)
|
|
||||||
data=""
|
|
||||||
with open(inFile,'rb') as ch:
|
|
||||||
config=json.load(ch)
|
|
||||||
data+="//generated from %s\n"%inFile
|
|
||||||
l=len(config)
|
|
||||||
idx=0
|
|
||||||
if not impl:
|
|
||||||
data+='#include "GwConfigItem.h"\n'
|
|
||||||
data+='class GwConfigDefinitions{\n'
|
|
||||||
data+=' public:\n'
|
|
||||||
data+=' int getNumConfig() const{return %d;}\n'%(l)
|
|
||||||
for item in config:
|
|
||||||
n=item.get('name')
|
|
||||||
if n is None:
|
|
||||||
continue
|
|
||||||
if len(n) > 15:
|
|
||||||
raise Exception("%s: config names must be max 15 caracters"%n)
|
|
||||||
data+=' static constexpr const char* %s="%s";\n'%(n,n)
|
|
||||||
data+="};\n"
|
|
||||||
else:
|
|
||||||
data+='void GwConfigHandler::populateConfigs(GwConfigInterface **config){\n'
|
|
||||||
for item in config:
|
|
||||||
name=item.get('name')
|
|
||||||
if name is None:
|
|
||||||
continue
|
|
||||||
data+=' configs[%d]='%(idx)
|
|
||||||
idx+=1
|
|
||||||
secret="false";
|
|
||||||
if item.get('type') == 'password':
|
|
||||||
secret="true"
|
|
||||||
data+=" new GwConfigInterface(%s,\"%s\",%s);\n"%(name,item.get('default'),secret)
|
|
||||||
data+='}\n'
|
|
||||||
writeFileIfChanged(outFile,data)
|
|
||||||
|
|
||||||
def labelFilter(label):
|
|
||||||
return re.sub("[^a-zA-Z0-9]","",re.sub("\([0-9]*\)","",label))
|
|
||||||
def generateXdrMappings(fp,oh,inFile=''):
|
|
||||||
jdoc=json.load(fp)
|
|
||||||
oh.write("static GwXDRTypeMapping* typeMappings[]={\n")
|
|
||||||
first=True
|
|
||||||
for cat in jdoc:
|
|
||||||
item=jdoc[cat]
|
|
||||||
cid=item.get('id')
|
|
||||||
if cid is None:
|
|
||||||
continue
|
|
||||||
tc=item.get('type')
|
|
||||||
if tc is not None:
|
|
||||||
if first:
|
|
||||||
first=False
|
|
||||||
else:
|
|
||||||
oh.write(",\n")
|
|
||||||
oh.write(" new GwXDRTypeMapping(%d,0,%d) /*%s*/"%(cid,tc,cat))
|
|
||||||
fields=item.get('fields')
|
|
||||||
if fields is None:
|
|
||||||
continue
|
|
||||||
idx=0
|
|
||||||
for fe in fields:
|
|
||||||
if not isinstance(fe,dict):
|
|
||||||
continue
|
|
||||||
tc=fe.get('t')
|
|
||||||
id=fe.get('v')
|
|
||||||
if id is None:
|
|
||||||
id=idx
|
|
||||||
idx+=1
|
|
||||||
l=fe.get('l') or ''
|
|
||||||
if tc is None or id is None:
|
|
||||||
continue
|
|
||||||
if first:
|
|
||||||
first=False
|
|
||||||
else:
|
|
||||||
oh.write(",\n")
|
|
||||||
oh.write(" new GwXDRTypeMapping(%d,%d,%d) /*%s:%s*/"%(cid,id,tc,cat,l))
|
|
||||||
oh.write("\n")
|
|
||||||
oh.write("};\n")
|
|
||||||
for cat in jdoc:
|
|
||||||
item=jdoc[cat]
|
|
||||||
cid=item.get('id')
|
|
||||||
if cid is None:
|
|
||||||
continue
|
|
||||||
selectors=item.get('selector')
|
|
||||||
if selectors is not None:
|
|
||||||
for selector in selectors:
|
|
||||||
label=selector.get('l')
|
|
||||||
value=selector.get('v')
|
|
||||||
if label is not None and value is not None:
|
|
||||||
label=labelFilter(label)
|
|
||||||
define=("GWXDRSEL_%s_%s"%(cat,label)).upper()
|
|
||||||
oh.write(" #define %s %s\n"%(define,value))
|
|
||||||
fields=item.get('fields')
|
|
||||||
if fields is not None:
|
|
||||||
idx=0
|
|
||||||
for field in fields:
|
|
||||||
v=field.get('v')
|
|
||||||
if v is None:
|
|
||||||
v=idx
|
|
||||||
else:
|
|
||||||
v=int(v)
|
|
||||||
label=field.get('l')
|
|
||||||
if v is not None and label is not None:
|
|
||||||
define=("GWXDRFIELD_%s_%s"%(cat,labelFilter(label))).upper();
|
|
||||||
oh.write(" #define %s %s\n"%(define,str(v)))
|
|
||||||
idx+=1
|
|
||||||
|
|
||||||
class Grove:
|
|
||||||
def __init__(self,name) -> None:
|
|
||||||
self.name=name
|
|
||||||
def _ss(self,z=False):
|
|
||||||
if z:
|
|
||||||
return self.name
|
|
||||||
return self.name if self.name is not 'Z' else ''
|
|
||||||
def _suffix(self):
|
|
||||||
return '_'+self.name if self.name is not 'Z' else ''
|
|
||||||
def replace(self,line):
|
|
||||||
if line is None:
|
|
||||||
return line
|
|
||||||
return line.replace('$G$',self._ss()).replace('$Z$',self._ss(True)).replace('$GS$',self._suffix())
|
|
||||||
def generateGroveDefs(inh,outh,inFile=''):
|
|
||||||
GROVES=[Grove('Z'),Grove('A'),Grove('B'),Grove('C')]
|
|
||||||
definition=[]
|
|
||||||
started=False
|
|
||||||
def writeConfig():
|
|
||||||
for grove in GROVES:
|
|
||||||
for cl in definition:
|
|
||||||
outh.write(grove.replace(cl))
|
|
||||||
|
|
||||||
for line in inh:
|
|
||||||
if re.match(" *#GROVE",line):
|
|
||||||
started=True
|
|
||||||
if len(definition) > 0:
|
|
||||||
writeConfig()
|
|
||||||
definition=[]
|
|
||||||
continue
|
|
||||||
if started:
|
|
||||||
definition.append(line)
|
|
||||||
if len(definition) > 0:
|
|
||||||
writeConfig()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
userTaskDirs=[]
|
|
||||||
|
|
||||||
def getUserTaskDirs():
|
|
||||||
rt=[]
|
|
||||||
taskdirs=glob.glob(os.path.join( basePath(),'lib','*task*'))
|
|
||||||
for task in taskdirs:
|
|
||||||
rt.append(task)
|
|
||||||
return rt
|
|
||||||
|
|
||||||
def checkAndAdd(file,names,ilist):
|
|
||||||
if not file.endswith('.h'):
|
|
||||||
return
|
|
||||||
match=False
|
|
||||||
for cmp in names:
|
|
||||||
#print("##check %s<->%s"%(f.lower(),cmp))
|
|
||||||
if file.lower() == cmp:
|
|
||||||
match=True
|
|
||||||
if not match:
|
|
||||||
return
|
|
||||||
ilist.append(file)
|
|
||||||
def genereateUserTasks(outfile):
|
|
||||||
includes=[]
|
|
||||||
for task in userTaskDirs:
|
|
||||||
#print("##taskdir=%s"%task)
|
|
||||||
base=os.path.basename(task)
|
|
||||||
includeNames=[base.lower()+".h",'gw'+base.lower()+'.h']
|
|
||||||
for f in os.listdir(task):
|
|
||||||
checkAndAdd(f,includeNames,includes)
|
|
||||||
includeData=""
|
|
||||||
for i in includes:
|
|
||||||
print("#task include %s"%i)
|
|
||||||
includeData+="#include <%s>\n"%i
|
|
||||||
writeFileIfChanged(outfile,includeData)
|
|
||||||
|
|
||||||
def generateEmbedded(elist,outFile):
|
|
||||||
content=""
|
|
||||||
for entry in elist:
|
|
||||||
content+="EMBED_GZ_FILE(\"%s\",%s,\"%s\");\n"%entry
|
|
||||||
writeFileIfChanged(outFile,content)
|
|
||||||
|
|
||||||
def getContentType(fn):
|
|
||||||
if (fn.endswith('.gz')):
|
|
||||||
fn=fn[0:-3]
|
|
||||||
if (fn.endswith('html')):
|
|
||||||
return "text/html"
|
|
||||||
if (fn.endswith('json')):
|
|
||||||
return "application/json"
|
|
||||||
if (fn.endswith('js')):
|
|
||||||
return "text/javascript"
|
|
||||||
if (fn.endswith('css')):
|
|
||||||
return "text/css"
|
|
||||||
return "application/octet-stream"
|
|
||||||
|
|
||||||
|
|
||||||
def getLibs():
|
|
||||||
base=os.path.join(basePath(),"lib")
|
|
||||||
rt=[]
|
|
||||||
for sd in os.listdir(base):
|
|
||||||
if sd == '..':
|
|
||||||
continue
|
|
||||||
if sd == '.':
|
|
||||||
continue
|
|
||||||
fn=os.path.join(base,sd)
|
|
||||||
if os.path.isdir(fn):
|
|
||||||
rt.append(sd)
|
|
||||||
EXTRAS=['generated']
|
|
||||||
for e in EXTRAS:
|
|
||||||
if not e in rt:
|
|
||||||
rt.append(e)
|
|
||||||
return rt
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def joinFiles(target,pattern,dirlist):
|
|
||||||
flist=[]
|
|
||||||
for dir in dirlist:
|
|
||||||
fn=os.path.join(dir,pattern)
|
|
||||||
if os.path.exists(fn):
|
|
||||||
flist.append(fn)
|
|
||||||
current=False
|
|
||||||
if os.path.exists(target):
|
|
||||||
current=True
|
|
||||||
for f in flist:
|
|
||||||
if not isCurrent(f,target):
|
|
||||||
current=False
|
|
||||||
break
|
|
||||||
if current:
|
|
||||||
print("%s is up to date"%target)
|
|
||||||
return
|
|
||||||
print("creating %s"%target)
|
|
||||||
with gzip.open(target,"wb") as oh:
|
|
||||||
for fn in flist:
|
|
||||||
print("adding %s to %s"%(fn,target))
|
|
||||||
with open(fn,"rb") as rh:
|
|
||||||
shutil.copyfileobj(rh,oh)
|
|
||||||
|
|
||||||
|
|
||||||
OWNLIBS=getLibs()+["FS","WiFi"]
|
|
||||||
GLOBAL_INCLUDES=[]
|
|
||||||
|
|
||||||
def handleDeps(env):
|
|
||||||
#overwrite the GetProjectConfig
|
|
||||||
#to inject all our libs
|
|
||||||
oldGetProjectConfig=env.GetProjectConfig
|
|
||||||
def GetProjectConfigX(env):
|
|
||||||
rt=oldGetProjectConfig()
|
|
||||||
cenv="env:"+env['PIOENV']
|
|
||||||
libs=[]
|
|
||||||
for section,options in rt.as_tuple():
|
|
||||||
if section == cenv:
|
|
||||||
for key,values in options:
|
|
||||||
if key == 'lib_deps':
|
|
||||||
libs=values
|
|
||||||
|
|
||||||
mustUpdate=False
|
|
||||||
for lib in OWNLIBS:
|
|
||||||
if not lib in libs:
|
|
||||||
libs.append(lib)
|
|
||||||
mustUpdate=True
|
|
||||||
if mustUpdate:
|
|
||||||
update=[(cenv,[('lib_deps',libs)])]
|
|
||||||
rt.update(update)
|
|
||||||
return rt
|
|
||||||
env.AddMethod(GetProjectConfigX,"GetProjectConfig")
|
|
||||||
#store the list of all includes after we resolved
|
|
||||||
#the dependencies for our main project
|
|
||||||
#we will use them for all compilations afterwards
|
|
||||||
oldLibBuilder=env.ConfigureProjectLibBuilder
|
|
||||||
def ConfigureProjectLibBuilderX(env):
|
|
||||||
global GLOBAL_INCLUDES
|
|
||||||
project=oldLibBuilder()
|
|
||||||
#print("##ConfigureProjectLibBuilderX")
|
|
||||||
#pprint.pprint(project)
|
|
||||||
if project.depbuilders:
|
|
||||||
#print("##depbuilders %s"%",".join(map(lambda x: x.path,project.depbuilders)))
|
|
||||||
for db in project.depbuilders:
|
|
||||||
idirs=db.get_include_dirs()
|
|
||||||
for id in idirs:
|
|
||||||
if not id in GLOBAL_INCLUDES:
|
|
||||||
GLOBAL_INCLUDES.append(id)
|
|
||||||
return project
|
|
||||||
env.AddMethod(ConfigureProjectLibBuilderX,"ConfigureProjectLibBuilder")
|
|
||||||
def injectIncludes(env,node):
|
|
||||||
return env.Object(
|
|
||||||
node,
|
|
||||||
CPPPATH=env["CPPPATH"]+GLOBAL_INCLUDES
|
|
||||||
)
|
|
||||||
env.AddBuildMiddleware(injectIncludes)
|
|
||||||
|
|
||||||
|
|
||||||
def prebuild(env):
|
|
||||||
global userTaskDirs
|
|
||||||
print("#prebuild running")
|
|
||||||
if not checkDir():
|
|
||||||
sys.exit(1)
|
|
||||||
ldf_mode=env.GetProjectOption("lib_ldf_mode")
|
|
||||||
if ldf_mode == 'off':
|
|
||||||
print("##ldf off - own dependency handling")
|
|
||||||
handleDeps(env)
|
|
||||||
userTaskDirs=getUserTaskDirs()
|
|
||||||
mergedConfig=os.path.join(outPath(),os.path.basename(CFG_FILE))
|
|
||||||
generateMergedConfig(os.path.join(basePath(),CFG_FILE),mergedConfig,userTaskDirs)
|
|
||||||
compressFile(mergedConfig,mergedConfig+".gz")
|
|
||||||
generateCfg(mergedConfig,os.path.join(outPath(),CFG_INCLUDE),False)
|
|
||||||
generateCfg(mergedConfig,os.path.join(outPath(),CFG_INCLUDE_IMPL),True)
|
|
||||||
joinFiles(os.path.join(outPath(),INDEXJS+".gz"),INDEXJS,["web"]+userTaskDirs)
|
|
||||||
joinFiles(os.path.join(outPath(),INDEXCSS+".gz"),INDEXCSS,["web"]+userTaskDirs)
|
|
||||||
embedded=getEmbeddedFiles(env)
|
|
||||||
filedefs=[]
|
|
||||||
for ef in embedded:
|
|
||||||
print("#checking embedded file %s"%ef)
|
|
||||||
(dn,fn)=os.path.split(ef)
|
|
||||||
pureName=fn
|
|
||||||
if pureName.endswith('.gz'):
|
|
||||||
pureName=pureName[0:-3]
|
|
||||||
ct=getContentType(pureName)
|
|
||||||
usname=ef.replace('/','_').replace('.','_')
|
|
||||||
filedefs.append((pureName,usname,ct))
|
|
||||||
inFile=os.path.join(basePath(),"web",pureName)
|
|
||||||
if os.path.exists(inFile):
|
|
||||||
compressFile(inFile,ef)
|
|
||||||
else:
|
|
||||||
print("#WARNING: infile %s for %s not found"%(inFile,ef))
|
|
||||||
generateEmbedded(filedefs,os.path.join(outPath(),EMBEDDED_INCLUDE))
|
|
||||||
genereateUserTasks(os.path.join(outPath(), TASK_INCLUDE))
|
|
||||||
generateFile(os.path.join(basePath(),XDR_FILE),os.path.join(outPath(),XDR_INCLUDE),generateXdrMappings)
|
|
||||||
generateFile(os.path.join(basePath(),GROVE_CONFIG_IN),os.path.join(outPath(),GROVE_CONFIG),generateGroveDefs,inMode='r')
|
|
||||||
version="dev"+datetime.now().strftime("%Y%m%d")
|
|
||||||
env.Append(CPPDEFINES=[('GWDEVVERSION',version)])
|
|
||||||
|
|
||||||
def cleangenerated(source, target, env):
|
|
||||||
od=outPath()
|
|
||||||
if os.path.isdir(od):
|
|
||||||
print("#cleaning up %s"%od)
|
|
||||||
for f in os.listdir(od):
|
|
||||||
if f == "." or f == "..":
|
|
||||||
continue
|
|
||||||
fn=os.path.join(od,f)
|
|
||||||
os.unlink(f)
|
|
||||||
|
|
||||||
|
|
||||||
print("#prescript...")
|
|
||||||
prebuild(env)
|
|
||||||
board="PLATFORM_BOARD_%s"%env["BOARD"].replace("-","_").upper()
|
|
||||||
print("Board=#%s#"%board)
|
|
||||||
print("BuildFlags=%s"%(" ".join(env["BUILD_FLAGS"])))
|
|
||||||
env.Append(
|
|
||||||
LINKFLAGS=[ "-u", "custom_app_desc" ],
|
|
||||||
CPPDEFINES=[(board,"1")]
|
|
||||||
)
|
|
||||||
#script does not run on clean yet - maybe in the future
|
|
||||||
env.AddPostAction("clean",cleangenerated)
|
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
#define _GWAPI_H
|
#define _GWAPI_H
|
||||||
#include "GwMessage.h"
|
#include "GwMessage.h"
|
||||||
#include "N2kMsg.h"
|
#include "N2kMsg.h"
|
||||||
|
#include "Nmea2kTwai.h"
|
||||||
#include "NMEA0183Msg.h"
|
#include "NMEA0183Msg.h"
|
||||||
#include "GWConfig.h"
|
#include "GWConfig.h"
|
||||||
#include "GwBoatData.h"
|
#include "GwBoatData.h"
|
||||||
@@ -23,6 +24,7 @@ class GwApi{
|
|||||||
bool formatSet=false;
|
bool formatSet=false;
|
||||||
public:
|
public:
|
||||||
double value=0;
|
double value=0;
|
||||||
|
String svalue="";
|
||||||
bool valid=false;
|
bool valid=false;
|
||||||
int source=-1;
|
int source=-1;
|
||||||
bool changed=false; //will be set by getBoatDataValues
|
bool changed=false; //will be set by getBoatDataValues
|
||||||
@@ -222,6 +224,7 @@ class GwApi{
|
|||||||
* accessing boat data must only be executed from within the main thread
|
* accessing boat data must only be executed from within the main thread
|
||||||
* you need to use the request pattern as shown in GwExampleTask.cpp
|
* you need to use the request pattern as shown in GwExampleTask.cpp
|
||||||
*/
|
*/
|
||||||
|
virtual Nmea2kTwai *getNMEA2000()=0;
|
||||||
virtual GwBoatData *getBoatData()=0;
|
virtual GwBoatData *getBoatData()=0;
|
||||||
virtual ~GwApi(){}
|
virtual ~GwApi(){}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,11 +2,6 @@
|
|||||||
#include <GwJsonDocument.h>
|
#include <GwJsonDocument.h>
|
||||||
#include <ArduinoJson/Json/TextFormatter.hpp>
|
#include <ArduinoJson/Json/TextFormatter.hpp>
|
||||||
#include "GWConfig.h"
|
#include "GWConfig.h"
|
||||||
#define GWTYPE_DOUBLE 1
|
|
||||||
#define GWTYPE_UINT32 2
|
|
||||||
#define GWTYPE_UINT16 3
|
|
||||||
#define GWTYPE_INT16 4
|
|
||||||
#define GWTYPE_USER 100
|
|
||||||
|
|
||||||
class GwBoatItemTypes
|
class GwBoatItemTypes
|
||||||
{
|
{
|
||||||
@@ -15,7 +10,9 @@ public:
|
|||||||
static int getType(const uint16_t &x) { return GWTYPE_UINT16; }
|
static int getType(const uint16_t &x) { return GWTYPE_UINT16; }
|
||||||
static int getType(const int16_t &x) { return GWTYPE_INT16; }
|
static int getType(const int16_t &x) { return GWTYPE_INT16; }
|
||||||
static int getType(const double &x) { return GWTYPE_DOUBLE; }
|
static int getType(const double &x) { return GWTYPE_DOUBLE; }
|
||||||
|
static int getType(const String &x) { return GWTYPE_STRING; }
|
||||||
static int getType(const GwSatInfoList &x) { return GWTYPE_USER + 1; }
|
static int getType(const GwSatInfoList &x) { return GWTYPE_USER + 1; }
|
||||||
|
static int getType(const GwAisTargetList &x) { return GWTYPE_USER + 1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
bool GwBoatItemBase::isValid(unsigned long now) const
|
bool GwBoatItemBase::isValid(unsigned long now) const
|
||||||
@@ -252,6 +249,10 @@ static void writeToString(GwTextWriter *writer, const int16_t &value)
|
|||||||
{
|
{
|
||||||
writer->writeInteger(value);
|
writer->writeInteger(value);
|
||||||
}
|
}
|
||||||
|
static void writeToString(GwTextWriter *writer, String value)
|
||||||
|
{
|
||||||
|
writer->writeString(value.c_str());
|
||||||
|
}
|
||||||
static void writeToString(GwTextWriter *writer, GwSatInfoList &value)
|
static void writeToString(GwTextWriter *writer, GwSatInfoList &value)
|
||||||
{
|
{
|
||||||
writer->writeInteger(value.getNumSats());
|
writer->writeInteger(value.getNumSats());
|
||||||
@@ -288,6 +289,8 @@ template class GwBoatItem<double>;
|
|||||||
template class GwBoatItem<uint32_t>;
|
template class GwBoatItem<uint32_t>;
|
||||||
template class GwBoatItem<uint16_t>;
|
template class GwBoatItem<uint16_t>;
|
||||||
template class GwBoatItem<int16_t>;
|
template class GwBoatItem<int16_t>;
|
||||||
|
template class GwBoatItem<String>;
|
||||||
|
|
||||||
void GwSatInfoList::houseKeeping(unsigned long ts)
|
void GwSatInfoList::houseKeeping(unsigned long ts)
|
||||||
{
|
{
|
||||||
if (ts == 0)
|
if (ts == 0)
|
||||||
@@ -301,6 +304,7 @@ void GwSatInfoList::houseKeeping(unsigned long ts)
|
|||||||
}),
|
}),
|
||||||
sats.end());
|
sats.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GwSatInfoList::update(GwSatInfo entry, unsigned long validTill)
|
void GwSatInfoList::update(GwSatInfo entry, unsigned long validTill)
|
||||||
{
|
{
|
||||||
entry.validTill = validTill;
|
entry.validTill = validTill;
|
||||||
@@ -343,6 +347,63 @@ void GwBoatDataSatList::toJsonDoc(GwJsonDocument *doc, unsigned long minTime)
|
|||||||
GwBoatItem<GwSatInfoList>::toJsonDoc(doc, minTime);
|
GwBoatItem<GwSatInfoList>::toJsonDoc(doc, minTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GwAisTargetList::houseKeeping(unsigned long ts)
|
||||||
|
{
|
||||||
|
if (ts == 0) {
|
||||||
|
ts = millis();
|
||||||
|
}
|
||||||
|
targets.erase(
|
||||||
|
std::remove_if(
|
||||||
|
targets.begin(),
|
||||||
|
targets.end(),
|
||||||
|
[ts, this](const GwAisTarget &target) {
|
||||||
|
return target.validTill < ts;
|
||||||
|
}
|
||||||
|
),
|
||||||
|
targets.end()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GwAisTargetList::update(GwAisTarget target, unsigned long validTill)
|
||||||
|
{
|
||||||
|
target.validTill = validTill;
|
||||||
|
for (auto it = targets.begin(); it != targets.end(); it++) {
|
||||||
|
if (it->mmsi == target.mmsi) {
|
||||||
|
*it = target;
|
||||||
|
houseKeeping();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
houseKeeping();
|
||||||
|
targets.push_back(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
GwBoatDataAisList::GwBoatDataAisList(String name, String formatInfo, GwBoatItemBase::TOType toType, GwBoatItemMap *map) : GwBoatItem<GwAisTargetList>(name, formatInfo, toType, map) {}
|
||||||
|
|
||||||
|
bool GwBoatDataAisList::update(GwAisTarget target, int source)
|
||||||
|
{
|
||||||
|
unsigned long now = millis();
|
||||||
|
if (isValid(now))
|
||||||
|
{
|
||||||
|
//priority handling
|
||||||
|
//sources with lower ids will win
|
||||||
|
//and we will not overwrite their value
|
||||||
|
if (lastUpdateSource < source)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastUpdateSource = source;
|
||||||
|
uls(now);
|
||||||
|
data.update(target, now+invalidTime);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void GwBoatDataAisList::toJsonDoc(GwJsonDocument *doc, unsigned long minTime)
|
||||||
|
{
|
||||||
|
data.houseKeeping();
|
||||||
|
GwBoatItem<GwAisTargetList>::toJsonDoc(doc, minTime);
|
||||||
|
}
|
||||||
|
|
||||||
GwBoatData::GwBoatData(GwLog *logger, GwConfigHandler *cfg)
|
GwBoatData::GwBoatData(GwLog *logger, GwConfigHandler *cfg)
|
||||||
{
|
{
|
||||||
this->logger = logger;
|
this->logger = logger;
|
||||||
@@ -512,6 +573,11 @@ bool convertToJson(const GwSatInfoList &si, JsonVariant &variant)
|
|||||||
return variant.set(si.getNumSats());
|
return variant.set(si.getNumSats());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool convertToJson(const GwAisTargetList &si, JsonVariant &variant)
|
||||||
|
{
|
||||||
|
return variant.set(si.getNumTargets());
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _UNDEF
|
#ifdef _UNDEF
|
||||||
#include <ArduinoJson/Json/TextFormatter.hpp>
|
#include <ArduinoJson/Json/TextFormatter.hpp>
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,13 @@
|
|||||||
#define GW_BOAT_VALUE_LEN 32
|
#define GW_BOAT_VALUE_LEN 32
|
||||||
#define GWSC(name) static constexpr const char* name=#name
|
#define GWSC(name) static constexpr const char* name=#name
|
||||||
|
|
||||||
|
#define GWTYPE_DOUBLE 1
|
||||||
|
#define GWTYPE_UINT32 2
|
||||||
|
#define GWTYPE_UINT16 3
|
||||||
|
#define GWTYPE_INT16 4
|
||||||
|
#define GWTYPE_STRING 5
|
||||||
|
#define GWTYPE_USER 100
|
||||||
|
|
||||||
//see https://github.com/wellenvogel/esp32-nmea2000/issues/44
|
//see https://github.com/wellenvogel/esp32-nmea2000/issues/44
|
||||||
//factor to convert from N2k/SI rad/s to current NMEA rad/min
|
//factor to convert from N2k/SI rad/s to current NMEA rad/min
|
||||||
#define ROT_WA_FACTOR 60
|
#define ROT_WA_FACTOR 60
|
||||||
@@ -58,6 +65,7 @@ class GwBoatItemBase{
|
|||||||
GWSC(formatRot);
|
GWSC(formatRot);
|
||||||
GWSC(formatDate);
|
GWSC(formatDate);
|
||||||
GWSC(formatTime);
|
GWSC(formatTime);
|
||||||
|
GWSC(formatName);
|
||||||
protected:
|
protected:
|
||||||
int type;
|
int type;
|
||||||
unsigned long lastSet=0;
|
unsigned long lastSet=0;
|
||||||
@@ -92,6 +100,7 @@ class GwBoatItemBase{
|
|||||||
virtual int getLastSource(){return lastUpdateSource;}
|
virtual int getLastSource(){return lastUpdateSource;}
|
||||||
virtual void refresh(unsigned long ts=0){uls(ts);}
|
virtual void refresh(unsigned long ts=0){uls(ts);}
|
||||||
virtual double getDoubleValue()=0;
|
virtual double getDoubleValue()=0;
|
||||||
|
virtual String getStringValue()=0;
|
||||||
String getName(){return name;}
|
String getName(){return name;}
|
||||||
const String & getFormat() const{return format;}
|
const String & getFormat() const{return format;}
|
||||||
virtual void setInvalidTime(GwConfigHandler *cfg);
|
virtual void setInvalidTime(GwConfigHandler *cfg);
|
||||||
@@ -120,7 +129,17 @@ template<class T> class GwBoatItem : public GwBoatItemBase{
|
|||||||
if (! isValid(millis())) return defaultv;
|
if (! isValid(millis())) return defaultv;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
virtual double getDoubleValue(){return (double)data;}
|
virtual double getDoubleValue(){
|
||||||
|
if constexpr (std::is_same<T, String>::value) {
|
||||||
|
return 0.0; // TODO any better ideas?
|
||||||
|
} else {
|
||||||
|
return (double)data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual String getStringValue(){
|
||||||
|
return (String)data;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void fillString();
|
virtual void fillString();
|
||||||
virtual void toJsonDoc(GwJsonDocument *doc, unsigned long minTime);
|
virtual void toJsonDoc(GwJsonDocument *doc, unsigned long minTime);
|
||||||
virtual int getLastSource(){return lastUpdateSource;}
|
virtual int getLastSource(){return lastUpdateSource;}
|
||||||
@@ -177,6 +196,55 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GwAisTarget {
|
||||||
|
public:
|
||||||
|
uint32_t mmsi;
|
||||||
|
char callsign[8];
|
||||||
|
char name[21];
|
||||||
|
uint8_t vesseltype;
|
||||||
|
double lat;
|
||||||
|
double lon;
|
||||||
|
float length;
|
||||||
|
float beam;
|
||||||
|
float sog;
|
||||||
|
float cog;
|
||||||
|
unsigned long validTill;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GwAisTargetList {
|
||||||
|
public:
|
||||||
|
static const GwBoatItemBase::TOType toType=GwBoatItemBase::TOType::ais;
|
||||||
|
std::vector<GwAisTarget> targets;
|
||||||
|
void houseKeeping(unsigned long ts=0);
|
||||||
|
void update(GwAisTarget target, unsigned long validTill);
|
||||||
|
int getNumTargets() const {
|
||||||
|
return targets.size();
|
||||||
|
}
|
||||||
|
GwAisTarget *getAt(int idx){
|
||||||
|
if (idx >= 0 && idx < targets.size()) return &targets.at(idx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
operator double(){ return getNumTargets();}
|
||||||
|
};
|
||||||
|
|
||||||
|
class GwBoatDataAisList : public GwBoatItem<GwAisTargetList> {
|
||||||
|
public:
|
||||||
|
GwBoatDataAisList(String name, String formatInfo, GwBoatItemBase::TOType toType, GwBoatItemMap *map = NULL);
|
||||||
|
bool update(GwAisTarget target, int source);
|
||||||
|
virtual void toJsonDoc(GwJsonDocument *doc, unsigned long minTime);
|
||||||
|
GwAisTarget *getAt(int idx) {
|
||||||
|
if (! isValid()) return NULL;
|
||||||
|
return data.getAt(idx);
|
||||||
|
}
|
||||||
|
int getNumTargets(){
|
||||||
|
if (! isValid()) return 0;
|
||||||
|
return data.getNumTargets();
|
||||||
|
}
|
||||||
|
virtual double getDoubleValue(){
|
||||||
|
return (double)(data.getNumTargets());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class GwBoatItemNameProvider
|
class GwBoatItemNameProvider
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -235,7 +303,9 @@ class GwBoatData{
|
|||||||
GWBOATDATA(double,XTE,formatXte) // cross track error
|
GWBOATDATA(double,XTE,formatXte) // cross track error
|
||||||
GWBOATDATA(double,WPLat,formatLatitude) // waypoint latitude
|
GWBOATDATA(double,WPLat,formatLatitude) // waypoint latitude
|
||||||
GWBOATDATA(double,WPLon,formatLongitude) // waypoint longitude
|
GWBOATDATA(double,WPLon,formatLongitude) // waypoint longitude
|
||||||
|
GWBOATDATA(String,WPName,formatName) // waypoint name
|
||||||
GWSPECBOATDATA(GwBoatDataSatList,SatInfo,GwSatInfoList::toType,formatFixed0);
|
GWSPECBOATDATA(GwBoatDataSatList,SatInfo,GwSatInfoList::toType,formatFixed0);
|
||||||
|
GWSPECBOATDATA(GwBoatDataAisList,AisTarget,GwAisTargetList::toType,formatFixed0);
|
||||||
public:
|
public:
|
||||||
GwBoatData(GwLog *logger, GwConfigHandler *cfg);
|
GwBoatData(GwLog *logger, GwConfigHandler *cfg);
|
||||||
~GwBoatData();
|
~GwBoatData();
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ GwUpdate::GwUpdate(GwLog *log, GwWebServer *webserver, PasswordChecker ckr)
|
|||||||
}
|
}
|
||||||
if (!param->hasError())
|
if (!param->hasError())
|
||||||
{
|
{
|
||||||
AsyncWebParameter *hash=request->getParam("_hash");
|
const AsyncWebParameter *hash=request->getParam("_hash");
|
||||||
if (! hash){
|
if (! hash){
|
||||||
hash=request->getParam("_hash",true);
|
hash=request->getParam("_hash",true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ void sendEmbeddedFile(String name,String contentType,AsyncWebServerRequest *requ
|
|||||||
std::map<String,EmbeddedFile*>::iterator it=embeddedFiles.find(name);
|
std::map<String,EmbeddedFile*>::iterator it=embeddedFiles.find(name);
|
||||||
if (it != embeddedFiles.end()){
|
if (it != embeddedFiles.end()){
|
||||||
EmbeddedFile* found=it->second;
|
EmbeddedFile* found=it->second;
|
||||||
AsyncWebServerResponse *response=request->beginResponse_P(200,contentType,found->start,found->len);
|
AsyncWebServerResponse *response=request->beginResponse(200, contentType, found->start, found->len);
|
||||||
response->addHeader(F("Content-Encoding"), F("gzip"));
|
response->addHeader(F("Content-Encoding"), F("gzip"));
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,6 +355,7 @@ private:
|
|||||||
AppendN2kRouteWPInfo(n2kMsg,destinationId,rmb.destID,rmb.latitude,rmb.longitude);
|
AppendN2kRouteWPInfo(n2kMsg,destinationId,rmb.destID,rmb.latitude,rmb.longitude);
|
||||||
send(n2kMsg,msg.sourceId);
|
send(n2kMsg,msg.sourceId);
|
||||||
}
|
}
|
||||||
|
boatData->WPName->update(String(rmb.destID), msg.sourceId);
|
||||||
}
|
}
|
||||||
void convertRMC(const SNMEA0183Msg &msg)
|
void convertRMC(const SNMEA0183Msg &msg)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger)
|
|||||||
|
|
||||||
instance = std::string(config->getString(calInstance, "---").c_str());
|
instance = std::string(config->getString(calInstance, "---").c_str());
|
||||||
if (instance == "---") {
|
if (instance == "---") {
|
||||||
LOG_DEBUG(GwLog::LOG, "no calibration data for instance no. %d", i + 1);
|
logger->logDebug(GwLog::LOG, "no calibration data for instance no. %d", i + 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
calibMap[instance] = { 0.0f, 1.0f, 1.0f, 0.0f, false };
|
calibMap[instance] = { 0.0f, 1.0f, 1.0f, 0.0f, false };
|
||||||
@@ -101,10 +101,10 @@ void CalibrationDataList::readConfig(GwConfigHandler* config, GwLog* logger)
|
|||||||
calibMap[instance].slope = slope;
|
calibMap[instance].slope = slope;
|
||||||
calibMap[instance].smooth = smooth;
|
calibMap[instance].smooth = smooth;
|
||||||
calibMap[instance].isCalibrated = false;
|
calibMap[instance].isCalibrated = false;
|
||||||
LOG_DEBUG(GwLog::LOG, "stored calibration data: %s, offset: %f, slope: %f, smoothing: %f", instance.c_str(),
|
logger->logDebug(GwLog::LOG, "calibration data: %s, offset: %f, slope: %f, smoothing: %f", instance.c_str(),
|
||||||
calibMap[instance].offset, calibMap[instance].slope, calibMap[instance].smooth);
|
calibMap[instance].offset, calibMap[instance].slope, calibMap[instance].smooth);
|
||||||
}
|
}
|
||||||
LOG_DEBUG(GwLog::LOG, "all calibration data read");
|
logger->logDebug(GwLog::LOG, "all calibration data read");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalibrationDataList::calibrateInstance(GwApi::BoatValue* boatDataValue, GwLog* logger)
|
void CalibrationDataList::calibrateInstance(GwApi::BoatValue* boatDataValue, GwLog* logger)
|
||||||
@@ -117,7 +117,7 @@ void CalibrationDataList::calibrateInstance(GwApi::BoatValue* boatDataValue, GwL
|
|||||||
std::string format = "";
|
std::string format = "";
|
||||||
|
|
||||||
if (calibMap.find(instance) == calibMap.end()) {
|
if (calibMap.find(instance) == calibMap.end()) {
|
||||||
LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s not found in calibration data list", instance.c_str());
|
logger->logDebug(GwLog::DEBUG, "BoatDataCalibration: %s not in calibration list", instance.c_str());
|
||||||
return;
|
return;
|
||||||
} else if (!boatDataValue->valid) { // no valid boat data value, so we don't want to apply calibration data
|
} else if (!boatDataValue->valid) { // no valid boat data value, so we don't want to apply calibration data
|
||||||
calibMap[instance].isCalibrated = false;
|
calibMap[instance].isCalibrated = false;
|
||||||
@@ -127,7 +127,7 @@ void CalibrationDataList::calibrateInstance(GwApi::BoatValue* boatDataValue, GwL
|
|||||||
slope = calibMap[instance].slope;
|
slope = calibMap[instance].slope;
|
||||||
dataValue = boatDataValue->value;
|
dataValue = boatDataValue->value;
|
||||||
format = boatDataValue->getFormat().c_str();
|
format = boatDataValue->getFormat().c_str();
|
||||||
LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: value: %f, format: %s", instance.c_str(), dataValue, format.c_str());
|
logger->logDebug(GwLog::DEBUG, "BoatDataCalibration: %s: value: %f, format: %s", instance.c_str(), dataValue, format.c_str());
|
||||||
|
|
||||||
if (format == "formatWind") { // instance is of type angle
|
if (format == "formatWind") { // instance is of type angle
|
||||||
dataValue = (dataValue * slope) + offset;
|
dataValue = (dataValue * slope) + offset;
|
||||||
@@ -156,7 +156,7 @@ void CalibrationDataList::calibrateInstance(GwApi::BoatValue* boatDataValue, GwL
|
|||||||
calibrationData.smoothInstance(boatDataValue, logger); // smooth the boat data value
|
calibrationData.smoothInstance(boatDataValue, logger); // smooth the boat data value
|
||||||
calibMap[instance].value = boatDataValue->value; // store the calibrated + smoothed value in the list
|
calibMap[instance].value = boatDataValue->value; // store the calibrated + smoothed value in the list
|
||||||
|
|
||||||
LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: Offset: %f, Slope: %f, Result: %f", instance.c_str(), offset, slope, calibMap[instance].value);
|
logger->logDebug(GwLog::DEBUG, "BoatDataCalibration: %s: Offset: %f, Slope: %f, Result: %f", instance.c_str(), offset, slope, calibMap[instance].value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +173,7 @@ void CalibrationDataList::smoothInstance(GwApi::BoatValue* boatDataValue, GwLog*
|
|||||||
if (!boatDataValue->valid) { // no valid boat data value, so we don't want to smoothen value
|
if (!boatDataValue->valid) { // no valid boat data value, so we don't want to smoothen value
|
||||||
return;
|
return;
|
||||||
} else if (calibMap.find(instance) == calibMap.end()) {
|
} else if (calibMap.find(instance) == calibMap.end()) {
|
||||||
LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: smooth factor for %s not found in calibration data list", instance.c_str());
|
logger->logDebug(GwLog::DEBUG, "BoatDataCalibration: smooth factor for %s not found in calibration list", instance.c_str());
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
smoothFactor = calibMap[instance].smooth;
|
smoothFactor = calibMap[instance].smooth;
|
||||||
@@ -184,8 +184,6 @@ void CalibrationDataList::smoothInstance(GwApi::BoatValue* boatDataValue, GwLog*
|
|||||||
}
|
}
|
||||||
lastValue[instance] = dataValue; // store the new value for next cycle; first time, store only the current value and return
|
lastValue[instance] = dataValue; // store the new value for next cycle; first time, store only the current value and return
|
||||||
boatDataValue->value = dataValue; // set the smoothed value to the boat data value
|
boatDataValue->value = dataValue; // set the smoothed value to the boat data value
|
||||||
|
|
||||||
LOG_DEBUG(GwLog::DEBUG, "BoatDataCalibration: %s: Smoothing factor: %f, Smoothed value: %f", instance.c_str(), smoothFactor, dataValue);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#ifndef _BOATDATACALIBRATION_H
|
#ifndef _BOATDATACALIBRATION_H
|
||||||
#define _BOATDATACALIBRATION_H
|
#define _BOATDATACALIBRATION_H
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "GwApi.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
|||||||
204
lib/obp60task/ConfigMenu.cpp
Normal file
204
lib/obp60task/ConfigMenu.cpp
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
/*
|
||||||
|
Menu system for online configuration
|
||||||
|
*/
|
||||||
|
#include "ConfigMenu.h"
|
||||||
|
|
||||||
|
ConfigMenuItem::ConfigMenuItem(String itemtype, String itemlabel, uint16_t itemval, String itemunit) {
|
||||||
|
if (! (itemtype == "int" or itemtype == "bool")) {
|
||||||
|
valtype = "int";
|
||||||
|
} else {
|
||||||
|
valtype = itemtype;
|
||||||
|
}
|
||||||
|
label = itemlabel;
|
||||||
|
min = 0;
|
||||||
|
max = std::numeric_limits<uint16_t>::max();
|
||||||
|
value = itemval;
|
||||||
|
unit = itemunit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigMenuItem::setRange(uint16_t valmin, uint16_t valmax, std::vector<uint16_t> valsteps) {
|
||||||
|
min = valmin;
|
||||||
|
max = valmax;
|
||||||
|
steps = valsteps;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool ConfigMenuItem::checkRange(uint16_t checkval) {
|
||||||
|
return (checkval >= min) and (checkval <= max);
|
||||||
|
}
|
||||||
|
|
||||||
|
String ConfigMenuItem::getLabel() {
|
||||||
|
return label;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16_t ConfigMenuItem::getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigMenuItem::setValue(uint16_t newval) {
|
||||||
|
if (valtype == "int") {
|
||||||
|
if (newval >= min and newval <= max) {
|
||||||
|
value = newval;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false; // out of range
|
||||||
|
} else if (valtype == "bool") {
|
||||||
|
value = (newval != 0) ? 1 : 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false; // invalid type
|
||||||
|
};
|
||||||
|
|
||||||
|
void ConfigMenuItem::incValue() {
|
||||||
|
// increase value by step
|
||||||
|
if (valtype == "int") {
|
||||||
|
if (value + step < max) {
|
||||||
|
value += step;
|
||||||
|
} else {
|
||||||
|
value = max;
|
||||||
|
}
|
||||||
|
} else if (valtype == "bool") {
|
||||||
|
value = !value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void ConfigMenuItem::decValue() {
|
||||||
|
// decrease value by step
|
||||||
|
if (valtype == "int") {
|
||||||
|
if (value - step > min) {
|
||||||
|
value -= step;
|
||||||
|
} else {
|
||||||
|
value = min;
|
||||||
|
}
|
||||||
|
} else if (valtype == "bool") {
|
||||||
|
value = !value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
String ConfigMenuItem::getUnit() {
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ConfigMenuItem::getStep() {
|
||||||
|
return step;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigMenuItem::setStep(uint16_t newstep) {
|
||||||
|
if (std::find(steps.begin(), steps.end(), newstep) == steps.end()) {
|
||||||
|
return; // invalid step: not in list of possible steps
|
||||||
|
}
|
||||||
|
step = newstep;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t ConfigMenuItem::getPos() {
|
||||||
|
return position;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ConfigMenuItem::setPos(int8_t newpos) {
|
||||||
|
position = newpos;
|
||||||
|
};
|
||||||
|
|
||||||
|
String ConfigMenuItem::getType() {
|
||||||
|
return valtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigMenu::ConfigMenu(String menutitle, uint16_t menu_x, uint16_t menu_y) {
|
||||||
|
title = menutitle;
|
||||||
|
x = menu_x;
|
||||||
|
y = menu_y;
|
||||||
|
};
|
||||||
|
|
||||||
|
ConfigMenuItem* ConfigMenu::addItem(String key, String label, String valtype, uint16_t val, String valunit) {
|
||||||
|
if (items.find(key) != items.end()) {
|
||||||
|
// duplicate keys not allowed
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
ConfigMenuItem *itm = new ConfigMenuItem(valtype, label, val, valunit);
|
||||||
|
items.insert(std::pair<String, ConfigMenuItem*>(key, itm));
|
||||||
|
// Append key to index, index starting with 0
|
||||||
|
int8_t ix = items.size() - 1;
|
||||||
|
index[ix] = key;
|
||||||
|
itm->setPos(ix);
|
||||||
|
return itm;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ConfigMenu::setItemDimension(uint16_t itemwidth, uint16_t itemheight) {
|
||||||
|
w = itemwidth;
|
||||||
|
h = itemheight;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ConfigMenu::setItemActive(String key) {
|
||||||
|
if (items.find(key) != items.end()) {
|
||||||
|
activeitem = items[key]->getPos();
|
||||||
|
} else {
|
||||||
|
activeitem = -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int8_t ConfigMenu::getActiveIndex() {
|
||||||
|
return activeitem;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigMenuItem* ConfigMenu::getActiveItem() {
|
||||||
|
if (activeitem < 0) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return items[index[activeitem]];
|
||||||
|
};
|
||||||
|
|
||||||
|
ConfigMenuItem* ConfigMenu::getItemByIndex(uint8_t ix) {
|
||||||
|
if (ix > index.size() - 1) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return items[index[ix]];
|
||||||
|
};
|
||||||
|
|
||||||
|
ConfigMenuItem* ConfigMenu::getItemByKey(String key) {
|
||||||
|
if (items.find(key) == items.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return items[key];
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t ConfigMenu::getItemCount() {
|
||||||
|
return items.size();
|
||||||
|
};
|
||||||
|
|
||||||
|
void ConfigMenu::goPrev() {
|
||||||
|
if (activeitem == 0) {
|
||||||
|
activeitem = items.size() - 1;
|
||||||
|
} else {
|
||||||
|
activeitem--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigMenu::goNext() {
|
||||||
|
if (activeitem == items.size() - 1) {
|
||||||
|
activeitem = 0;
|
||||||
|
} else {
|
||||||
|
activeitem++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Point ConfigMenu::getXY() {
|
||||||
|
return {static_cast<double>(x), static_cast<double>(y)};
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect ConfigMenu::getRect() {
|
||||||
|
return {static_cast<double>(x), static_cast<double>(y),
|
||||||
|
static_cast<double>(w), static_cast<double>(h)};
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect ConfigMenu::getItemRect(int8_t index) {
|
||||||
|
return {static_cast<double>(x), static_cast<double>(y + index * h),
|
||||||
|
static_cast<double>(w), static_cast<double>(h)};
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigMenu::setCallback(void (*callback)()) {
|
||||||
|
fptrCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigMenu::storeValues() {
|
||||||
|
if (fptrCallback) {
|
||||||
|
fptrCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
66
lib/obp60task/ConfigMenu.h
Normal file
66
lib/obp60task/ConfigMenu.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include "Graphics.h" // for Point and Rect
|
||||||
|
|
||||||
|
class ConfigMenuItem {
|
||||||
|
private:
|
||||||
|
String label;
|
||||||
|
uint16_t value;
|
||||||
|
String unit;
|
||||||
|
String valtype; // "int" | "bool"
|
||||||
|
uint16_t min;
|
||||||
|
uint16_t max;
|
||||||
|
std::vector<uint16_t> steps;
|
||||||
|
uint16_t step;
|
||||||
|
int8_t position; // counted fom 0
|
||||||
|
|
||||||
|
public:
|
||||||
|
ConfigMenuItem(String itemtype, String itemlabel, uint16_t itemval, String itemunit);
|
||||||
|
void setRange(uint16_t valmin, uint16_t valmax, std::vector<uint16_t> steps);
|
||||||
|
bool checkRange(uint16_t checkval);
|
||||||
|
String getLabel();
|
||||||
|
uint16_t getValue();
|
||||||
|
bool setValue(uint16_t newval);
|
||||||
|
void incValue();
|
||||||
|
void decValue();
|
||||||
|
String getUnit();
|
||||||
|
uint16_t getStep();
|
||||||
|
void setStep(uint16_t newstep);
|
||||||
|
int8_t getPos();
|
||||||
|
void setPos(int8_t newpos);
|
||||||
|
String getType();
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConfigMenu {
|
||||||
|
private:
|
||||||
|
String title;
|
||||||
|
std::map <String,ConfigMenuItem*> items;
|
||||||
|
std::map <uint8_t,String> index;
|
||||||
|
int8_t activeitem = -1; // refers to position of item
|
||||||
|
uint16_t x;
|
||||||
|
uint16_t y;
|
||||||
|
uint16_t w;
|
||||||
|
uint16_t h;
|
||||||
|
void (*fptrCallback)();
|
||||||
|
|
||||||
|
public:
|
||||||
|
ConfigMenu(String title, uint16_t menu_x, uint16_t menu_y);
|
||||||
|
ConfigMenuItem* addItem(String key, String label, String valtype, uint16_t val, String valunit);
|
||||||
|
void setItemDimension(uint16_t itemwidth, uint16_t itemheight);
|
||||||
|
int8_t getActiveIndex();
|
||||||
|
void setItemActive(String key);
|
||||||
|
ConfigMenuItem* getActiveItem();
|
||||||
|
ConfigMenuItem* getItemByIndex(uint8_t index);
|
||||||
|
ConfigMenuItem* getItemByKey(String key);
|
||||||
|
uint8_t getItemCount();
|
||||||
|
void goPrev();
|
||||||
|
void goNext();
|
||||||
|
Point getXY();
|
||||||
|
Rect getRect();
|
||||||
|
Rect getItemRect(int8_t index);
|
||||||
|
void setCallback(void (*callback)());
|
||||||
|
void storeValues();
|
||||||
|
};
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
Craete new page for OBP60
|
|
||||||
1. Create page under /lib/obp60task/PageXXXX.cpp
|
|
||||||
2. Set page name in PageXXXX.cpp on file name
|
|
||||||
3. Register new page in /lib/obp60task/obp60task.cpp line 242 (registerAllPages)
|
|
||||||
4. Add new page in /lib/obp60task/config.json for each page type or add new page to gen_set.py and run it to auto-generate the relevant section of config.json
|
|
||||||
|
|
||||||
25
lib/obp60task/Graphics.cpp
Normal file
25
lib/obp60task/Graphics.cpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
Generic graphics functions
|
||||||
|
|
||||||
|
*/
|
||||||
|
#include <math.h>
|
||||||
|
#include "Graphics.h"
|
||||||
|
|
||||||
|
Point rotatePoint(const Point& origin, const Point& p, double angle) {
|
||||||
|
// rotate poind around origin by degrees
|
||||||
|
Point rotated;
|
||||||
|
double phi = angle * M_PI / 180.0;
|
||||||
|
double dx = p.x - origin.x;
|
||||||
|
double dy = p.y - origin.y;
|
||||||
|
rotated.x = origin.x + cos(phi) * dx - sin(phi) * dy;
|
||||||
|
rotated.y = origin.y + sin(phi) * dx + cos(phi) * dy;
|
||||||
|
return rotated;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Point> rotatePoints(const Point& origin, const std::vector<Point>& pts, double angle) {
|
||||||
|
std::vector<Point> rotatedPoints;
|
||||||
|
for (const auto& p : pts) {
|
||||||
|
rotatedPoints.push_back(rotatePoint(origin, p, angle));
|
||||||
|
}
|
||||||
|
return rotatedPoints;
|
||||||
|
}
|
||||||
17
lib/obp60task/Graphics.h
Normal file
17
lib/obp60task/Graphics.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct Point {
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Rect {
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
double w;
|
||||||
|
double h;
|
||||||
|
};
|
||||||
|
|
||||||
|
Point rotatePoint(const Point& origin, const Point& p, double angle);
|
||||||
|
std::vector<Point> rotatePoints(const Point& origin, const std::vector<Point>& pts, double angle);
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#include <FreeRTOS.h>
|
#include <FreeRTOS.h>
|
||||||
#include "LedSpiTask.h"
|
#include "LedSpiTask.h"
|
||||||
#include "GwHardware.h"
|
#include "GwHardware.h"
|
||||||
@@ -14,6 +15,30 @@ https://controllerstech.com/ws2812-leds-using-spi/
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
String Color::toHex() {
|
||||||
|
char hexColor[8];
|
||||||
|
sprintf(hexColor, "#%02X%02X%02X", r, g, b);
|
||||||
|
return String(hexColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
String Color::toName() {
|
||||||
|
static std::map<int, String> const names = {
|
||||||
|
{0xff0000, "Red"},
|
||||||
|
{0x00ff00, "Green"},
|
||||||
|
{0x0000ff, "Blue",},
|
||||||
|
{0xff9900, "Orange"},
|
||||||
|
{0xffff00, "Yellow"},
|
||||||
|
{0x3366ff, "Aqua"},
|
||||||
|
{0xff0066, "Violet"},
|
||||||
|
{0xffffff, "White"}
|
||||||
|
};
|
||||||
|
int color = (r << 16) + (g << 8) + b;
|
||||||
|
auto it = names.find(color);
|
||||||
|
if (it == names.end()) {
|
||||||
|
return toHex();
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t mulcolor(uint8_t f1, uint8_t f2){
|
static uint8_t mulcolor(uint8_t f1, uint8_t f2){
|
||||||
uint16_t rt=f1;
|
uint16_t rt=f1;
|
||||||
@@ -59,12 +84,12 @@ static size_t ledsToBuffer(int numLeds,const Color *leds,uint8_t *buffer){
|
|||||||
bool prepareGpio(GwLog *logger, uint8_t pin){
|
bool prepareGpio(GwLog *logger, uint8_t pin){
|
||||||
esp_err_t err=gpio_set_direction((gpio_num_t)pin,GPIO_MODE_OUTPUT);
|
esp_err_t err=gpio_set_direction((gpio_num_t)pin,GPIO_MODE_OUTPUT);
|
||||||
if (err != ESP_OK){
|
if (err != ESP_OK){
|
||||||
LOG_DEBUG(GwLog::ERROR,"unable to set gpio mode for %d: %d",pin,(int)err);
|
logger->logDebug(GwLog::ERROR, "unable to set gpio mode for %d: %d", pin, (int)err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
err=gpio_set_level((gpio_num_t)pin,0);
|
err=gpio_set_level((gpio_num_t)pin,0);
|
||||||
if (err != ESP_OK){
|
if (err != ESP_OK){
|
||||||
LOG_DEBUG(GwLog::ERROR,"unable to set gpio level for %d: %d",pin,(int)err);
|
logger->logDebug(GwLog::ERROR, "unable to set gpio level for %d: %d", pin, (int)err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -90,7 +115,7 @@ bool prepareSpi(GwLog *logger,spi_host_device_t bus,spi_device_handle_t *device)
|
|||||||
};
|
};
|
||||||
esp_err_t err=spi_bus_initialize(bus,&buscfg,SPI_DMA_CH_AUTO);
|
esp_err_t err=spi_bus_initialize(bus,&buscfg,SPI_DMA_CH_AUTO);
|
||||||
if (err != ESP_OK){
|
if (err != ESP_OK){
|
||||||
LOG_DEBUG(GwLog::ERROR,"unable to initialize SPI bus %d,mosi=%d, error=%d",
|
logger->logDebug(GwLog::ERROR, "unable to initialize SPI bus %d,mosi=%d, error=%d",
|
||||||
(int)bus, -1, (int)err);
|
(int)bus, -1, (int)err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -109,7 +134,7 @@ bool prepareSpi(GwLog *logger,spi_host_device_t bus,spi_device_handle_t *device)
|
|||||||
};
|
};
|
||||||
err=spi_bus_add_device(bus,&devcfg,device);
|
err=spi_bus_add_device(bus,&devcfg,device);
|
||||||
if (err != ESP_OK){
|
if (err != ESP_OK){
|
||||||
LOG_DEBUG(GwLog::ERROR,"unable to add device to SPI bus %d,mosi=%d, error=%d",
|
logger->logDebug(GwLog::ERROR, "unable to add device to SPI bus %d,mosi=%d, error=%d",
|
||||||
(int)bus, -1, (int)err);
|
(int)bus, -1, (int)err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -117,7 +142,7 @@ bool prepareSpi(GwLog *logger,spi_host_device_t bus,spi_device_handle_t *device)
|
|||||||
//as we are the only ones using the bus we can safely acquire it forever
|
//as we are the only ones using the bus we can safely acquire it forever
|
||||||
err=spi_device_acquire_bus(*device,portMAX_DELAY);
|
err=spi_device_acquire_bus(*device,portMAX_DELAY);
|
||||||
if (err != ESP_OK){
|
if (err != ESP_OK){
|
||||||
LOG_DEBUG(GwLog::ERROR,"unable to acquire SPI bus %d,mosi=%d, error=%d",
|
logger->logDebug(GwLog::ERROR,"unable to acquire SPI bus %d,mosi=%d, error=%d",
|
||||||
(int)bus, -1, (int)err);
|
(int)bus, -1, (int)err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -148,7 +173,7 @@ bool sendToLeds(GwLog *logger, uint8_t pin, int numLeds, Color *leds, spi_host_d
|
|||||||
buffer = (uint8_t *)heap_caps_malloc(bufferSize, MALLOC_CAP_DMA|MALLOC_CAP_32BIT);
|
buffer = (uint8_t *)heap_caps_malloc(bufferSize, MALLOC_CAP_DMA|MALLOC_CAP_32BIT);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
{
|
{
|
||||||
LOG_DEBUG(GwLog::ERROR, "unable to allocate %d bytes of DMA buffer", (int)bufferSize);
|
logger->logDebug(GwLog::ERROR, "unable to allocate %d bytes of DMA buffer", (int)bufferSize);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,12 +194,12 @@ bool sendToLeds(GwLog *logger, uint8_t pin, int numLeds, Color *leds, spi_host_d
|
|||||||
int64_t end = esp_timer_get_time();
|
int64_t end = esp_timer_get_time();
|
||||||
if (ret != ESP_OK)
|
if (ret != ESP_OK)
|
||||||
{
|
{
|
||||||
LOG_DEBUG(GwLog::ERROR, "unable to send led data: %d", (int)ret);
|
logger->logDebug(GwLog::ERROR, "unable to send led data: %d", (int)ret);
|
||||||
rv = false;
|
rv = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_DEBUG(GwLog::DEBUG, "successfully send led data for %d leds, %lld us", numLeds, end - now);
|
logger->logDebug(GwLog::DEBUG, "successfully send led data for %d leds, %lld us", numLeds, end - now);
|
||||||
}
|
}
|
||||||
if (ownsBuffer)
|
if (ownsBuffer)
|
||||||
{
|
{
|
||||||
@@ -187,7 +212,7 @@ bool sendToLeds(GwLog *logger, uint8_t pin, int numLeds, Color *leds, spi_host_d
|
|||||||
void handleSpiLeds(void *param){
|
void handleSpiLeds(void *param){
|
||||||
LedTaskData *taskData=(LedTaskData*)param;
|
LedTaskData *taskData=(LedTaskData*)param;
|
||||||
GwLog *logger=taskData->api->getLogger();
|
GwLog *logger=taskData->api->getLogger();
|
||||||
LOG_DEBUG(GwLog::ERROR,"spi led task initialized");
|
logger->logDebug(GwLog::ERROR, "spi led task initialized");
|
||||||
spi_host_device_t bus=SPI3_HOST;
|
spi_host_device_t bus=SPI3_HOST;
|
||||||
bool spiValid=false;
|
bool spiValid=false;
|
||||||
LOG_DEBUG(GwLog::ERROR, "SpiLed task started");
|
LOG_DEBUG(GwLog::ERROR, "SpiLed task started");
|
||||||
@@ -209,14 +234,14 @@ void handleSpiLeds(void *param){
|
|||||||
LedInterface newLeds=taskData->getLedData();
|
LedInterface newLeds=taskData->getLedData();
|
||||||
if (first || current.backlightChanged(newLeds) || current.flasChanged(newLeds)){
|
if (first || current.backlightChanged(newLeds) || current.flasChanged(newLeds)){
|
||||||
first=false;
|
first=false;
|
||||||
LOG_DEBUG(GwLog::ERROR,"handle SPI leds");
|
logger->logDebug(GwLog::ERROR, "handle SPI leds");
|
||||||
if (current.backlightChanged(newLeds) || first){
|
if (current.backlightChanged(newLeds) || first){
|
||||||
LOG_DEBUG(GwLog::ERROR,"setting backlight r=%02d,g=%02d,b=%02d",
|
logger->logDebug(GwLog::ERROR, "setting backlight r=%02d,g=%02d,b=%02d",
|
||||||
newLeds.backlight[0].r,newLeds.backlight[0].g,newLeds.backlight[0].b);
|
newLeds.backlight[0].r,newLeds.backlight[0].g,newLeds.backlight[0].b);
|
||||||
sendToLeds(logger,OBP_BACKLIGHT_LED,newLeds.backlightLen(),newLeds.backlight,bus,device);
|
sendToLeds(logger,OBP_BACKLIGHT_LED,newLeds.backlightLen(),newLeds.backlight,bus,device);
|
||||||
}
|
}
|
||||||
if (current.flasChanged(newLeds) || first){
|
if (current.flasChanged(newLeds) || first){
|
||||||
LOG_DEBUG(GwLog::ERROR,"setting flashr=%02d,g=%02d,b=%02d",
|
logger->logDebug(GwLog::ERROR, "setting flashr=%02d,g=%02d,b=%02d",
|
||||||
newLeds.flash[0].r,newLeds.flash[0].g,newLeds.flash[0].b);
|
newLeds.flash[0].r,newLeds.flash[0].g,newLeds.flash[0].b);
|
||||||
sendToLeds(logger,OBP_FLASH_LED,newLeds.flashLen(),newLeds.flash,bus,device);
|
sendToLeds(logger,OBP_FLASH_LED,newLeds.flashLen(),newLeds.flash,bus,device);
|
||||||
}
|
}
|
||||||
@@ -228,5 +253,10 @@ void handleSpiLeds(void *param){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void createSpiLedTask(LedTaskData *param) {
|
void createSpiLedTask(LedTaskData *param) {
|
||||||
xTaskCreate(handleSpiLeds,"handleLeds",4000,param,3,NULL);
|
TaskHandle_t xHandle = NULL;
|
||||||
|
GwLog *logger = param->api->getLogger();
|
||||||
|
esp_err_t err = xTaskCreate(handleSpiLeds, "handleLeds", configMINIMAL_STACK_SIZE + 2048, param, 3, &xHandle);
|
||||||
|
if (err != pdPASS) {
|
||||||
|
logger->logDebug(GwLog::ERROR, "Failed to create spiled task! (err=%d)", err);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@@ -22,6 +22,8 @@ class Color{
|
|||||||
bool operator != (const Color &other) const{
|
bool operator != (const Color &other) const{
|
||||||
return ! equal(other);
|
return ! equal(other);
|
||||||
}
|
}
|
||||||
|
String toHex();
|
||||||
|
String toName();
|
||||||
};
|
};
|
||||||
|
|
||||||
static Color COLOR_GREEN=Color(0,255,0);
|
static Color COLOR_GREEN=Color(0,255,0);
|
||||||
|
|||||||
@@ -1,939 +0,0 @@
|
|||||||
const unsigned char gImage_Logo_OBP_400x300_sw[15000] = { /* 0X00,0X01,0X90,0X01,0X2C,0X01, */
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,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,0X40,
|
|
||||||
0X00,0X03,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,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X80,0X00,0X03,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,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X01,0X80,0X00,0X03,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,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X01,0X80,0X00,0X03,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X80,0X00,0X03,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X07,0X80,0X00,0X03,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X07,0X80,0X00,0X03,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0F,0X80,0X00,0X03,
|
|
||||||
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,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0X80,
|
|
||||||
0X00,0X03,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,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X3F,0X80,0X00,0X03,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,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X3F,0X80,0X00,0X03,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,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X7F,0X80,0X00,0X03,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0X80,0X00,0X03,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0X80,0X00,0X03,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XFF,0X80,0X00,0X03,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0X00,0X03,0XFF,0XFF,0XF8,0X00,0X00,0X0F,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,0X03,0XFF,0X80,0X00,0X03,
|
|
||||||
0XFF,0XFF,0XFF,0XF8,0X00,0X00,0X7F,0XFF,0XF8,0X00,0X00,0X00,0X3F,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,0X03,0XFF,0X80,
|
|
||||||
0X00,0X03,0XFF,0XFF,0XFF,0XE0,0X00,0X00,0X1F,0XFF,0XF8,0X00,0X00,0X00,0X07,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,0X07,
|
|
||||||
0XFF,0X80,0X00,0X03,0XFF,0XFF,0XFF,0X80,0X00,0X00,0X07,0XFF,0XF8,0X00,0X00,0X00,
|
|
||||||
0X03,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,0X0F,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X03,0XFF,0XF8,0X00,
|
|
||||||
0X00,0X00,0X01,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,0X1F,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XFE,0X00,0X00,0X00,0X00,0XFF,
|
|
||||||
0XF8,0X00,0X00,0X00,0X00,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,0X1F,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XFC,0X00,0X00,0X00,
|
|
||||||
0X00,0X7F,0XF8,0X00,0X00,0X00,0X00,0X7F,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,0X3F,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XF8,0X00,
|
|
||||||
0X00,0X00,0X00,0X7F,0XF8,0X00,0X00,0X00,0X00,0X7F,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,0X7F,0XFF,0X80,0X00,0X03,0XFF,0XFF,
|
|
||||||
0XF0,0X00,0X00,0X00,0X00,0X3F,0XF8,0X00,0X00,0X00,0X00,0X3F,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,0X7F,0XFF,0X80,0X00,0X03,
|
|
||||||
0XFF,0XFF,0XE0,0X00,0X00,0X00,0X00,0X1F,0XF8,0X00,0X1E,0X00,0X00,0X3F,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,0XFF,0XFF,0X80,
|
|
||||||
0X00,0X03,0XFF,0XFF,0XE0,0X00,0X0F,0XC0,0X00,0X1F,0XF8,0X00,0X1F,0XE0,0X00,0X3F,
|
|
||||||
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,0X01,0XFF,
|
|
||||||
0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X3F,0XF0,0X00,0X0F,0XF8,0X00,0X1F,0XF0,
|
|
||||||
0X00,0X3F,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,
|
|
||||||
0X01,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X7F,0XF8,0X00,0X0F,0XF8,0X00,
|
|
||||||
0X1F,0XF8,0X00,0X3F,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,0X03,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0XFF,0XFC,0X00,0X07,
|
|
||||||
0XF8,0X00,0X1F,0XF8,0X00,0X3F,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,0X07,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0X80,0X01,0XFF,0XFE,
|
|
||||||
0X00,0X07,0XF8,0X00,0X1F,0XF8,0X00,0X3F,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,0X0F,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0X80,0X01,
|
|
||||||
0XFF,0XFE,0X00,0X07,0XF8,0X00,0X1F,0XF8,0X00,0X3F,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,0X0F,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,
|
|
||||||
0X80,0X01,0XFF,0XFF,0X00,0X07,0XF8,0X00,0X1F,0XF8,0X00,0X3F,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,0X1F,0XFF,0XFF,0X80,0X00,0X03,
|
|
||||||
0XFF,0XFF,0X80,0X03,0XFF,0XFF,0X00,0X03,0XF8,0X00,0X1F,0XF0,0X00,0X3F,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,0X3F,0XFF,0XFF,0X80,
|
|
||||||
0X00,0X03,0XFF,0XFF,0X80,0X03,0XFF,0XFF,0X00,0X03,0XF8,0X00,0X1F,0XE0,0X00,0X3F,
|
|
||||||
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,0X3F,0XFF,
|
|
||||||
0XFF,0X80,0X00,0X03,0XFF,0XFF,0X00,0X03,0XFF,0XFF,0X00,0X03,0XF8,0X00,0X00,0X00,
|
|
||||||
0X00,0X3F,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,
|
|
||||||
0X7F,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0X00,0X03,0XFF,0XFF,0X00,0X03,0XF8,0X00,
|
|
||||||
0X00,0X00,0X00,0X7F,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,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0X00,0X03,0XFF,0XFF,0X00,0X03,
|
|
||||||
0XF8,0X00,0X00,0X00,0X00,0X7F,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,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0X00,0X03,0XFF,0XFF,
|
|
||||||
0X00,0X03,0XF8,0X00,0X00,0X00,0X00,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,0X01,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0X00,0X03,
|
|
||||||
0XFF,0XFF,0X00,0X03,0XF8,0X00,0X00,0X00,0X01,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,0X03,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,
|
|
||||||
0X00,0X03,0XFF,0XFF,0X00,0X03,0XF8,0X00,0X00,0X00,0X03,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,0X03,0XFF,0XFF,0XFF,0X80,0X00,0X03,
|
|
||||||
0XFF,0XFF,0X00,0X03,0XFF,0XFF,0X00,0X03,0XF8,0X00,0X00,0X00,0X07,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,0X07,0XFF,0XFF,0XFF,0X80,
|
|
||||||
0X00,0X03,0XFF,0XFF,0X00,0X03,0XFF,0XFF,0X00,0X03,0XF8,0X00,0X00,0X00,0X0F,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,0X0F,0XFF,0XFF,
|
|
||||||
0XFF,0X80,0X00,0X03,0XFF,0XFF,0X80,0X03,0XFF,0XFF,0X00,0X03,0XF8,0X00,0X00,0X00,
|
|
||||||
0X7F,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,0X1F,
|
|
||||||
0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0X80,0X03,0XFF,0XFF,0X00,0X07,0XF8,0X00,
|
|
||||||
0X1F,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,0X1F,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0X80,0X01,0XFF,0XFE,0X00,0X07,
|
|
||||||
0XF8,0X00,0X1F,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,0X3F,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0X80,0X01,0XFF,0XFE,
|
|
||||||
0X00,0X07,0XF8,0X00,0X1F,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,0X7F,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0X80,0X00,
|
|
||||||
0XFF,0XFC,0X00,0X07,0XF8,0X00,0X1F,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,0X7F,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,
|
|
||||||
0XC0,0X00,0XFF,0XFC,0X00,0X0F,0XF8,0X00,0X1F,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,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,
|
|
||||||
0XFF,0XFF,0XC0,0X00,0X3F,0XF8,0X00,0X0F,0XF8,0X00,0X1F,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,0X01,0XFF,0XFF,0XFF,0XFF,0X80,
|
|
||||||
0X00,0X03,0XFF,0XFF,0XE0,0X00,0X1F,0XE0,0X00,0X1F,0XF8,0X00,0X1F,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,0X03,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0X80,0X00,0X03,0XFF,0XFF,0XE0,0X00,0X00,0X00,0X00,0X1F,0XF8,0X00,0X1F,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,0X03,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,0X3F,0XF8,0X00,
|
|
||||||
0X1F,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,
|
|
||||||
0X07,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XF8,0X00,0X00,0X00,0X00,0X3F,
|
|
||||||
0XF8,0X00,0X1F,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,0X0F,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XF8,0X00,0X00,0X00,
|
|
||||||
0X00,0X7F,0XF8,0X00,0X1F,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,0X0F,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XFC,0X00,
|
|
||||||
0X00,0X00,0X00,0XFF,0XF8,0X00,0X1F,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,0X1F,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,
|
|
||||||
0XFE,0X00,0X00,0X00,0X01,0XFF,0XF8,0X00,0X1F,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,0X3F,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,
|
|
||||||
0XFF,0XFF,0XFF,0X80,0X00,0X00,0X03,0XFF,0XF8,0X00,0X1F,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,0X3F,0XFF,0XFF,0XFF,0XFF,0X80,
|
|
||||||
0X00,0X03,0XFF,0XFF,0XFF,0XC0,0X00,0X00,0X0F,0XFF,0XF8,0X00,0X1F,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,0X7F,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0X80,0X00,0X03,0XFF,0XFF,0XFF,0XF0,0X00,0X00,0X3F,0XFF,0XF8,0X00,0X1F,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,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XFF,0XFE,0X00,0X01,0XFF,0XFF,0XF8,0X00,
|
|
||||||
0X3F,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,0X01,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X01,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X03,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,
|
|
||||||
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,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0F,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,
|
|
||||||
0X00,0X03,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,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0X80,0X00,0X03,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,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0X80,0X00,0X03,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,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X3F,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X7F,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,
|
|
||||||
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,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,
|
|
||||||
0X00,0X03,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,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X03,0XFE,0X00,0X1F,0XFF,0XF8,
|
|
||||||
0X00,0X7F,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,0X07,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X03,0XFE,0X00,0X0F,
|
|
||||||
0XFF,0XF0,0X00,0X7F,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,0X0F,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X03,0XFE,
|
|
||||||
0X00,0X07,0XFF,0XF0,0X00,0X7F,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,
|
|
||||||
0X1F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,
|
|
||||||
0X03,0XFE,0X00,0X03,0XFF,0XF0,0X00,0X7F,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,0X1F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,
|
|
||||||
0X00,0X00,0X03,0XFE,0X00,0X03,0XFF,0XF0,0X00,0X7F,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,0X3F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,
|
|
||||||
0XC0,0X00,0X00,0X00,0X03,0XFE,0X00,0X01,0XFF,0XF0,0X00,0X7F,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,0X7F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,
|
|
||||||
0XFF,0XFF,0XC0,0X00,0X00,0X00,0X03,0XFE,0X00,0X00,0XFF,0XF0,0X00,0X7F,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,0X7F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,
|
|
||||||
0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X03,0XFE,0X00,0X00,0XFF,0XF0,0X00,0X7F,
|
|
||||||
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,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X03,0XFE,0X00,0X00,0X7F,0XF0,
|
|
||||||
0X00,0X7F,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,0X01,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X03,0XFE,0X00,0X00,
|
|
||||||
0X3F,0XF0,0X00,0X7F,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,0X01,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X01,0XFF,0XFF,0XFF,0XFE,
|
|
||||||
0X00,0X00,0X3F,0XF0,0X00,0X7F,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,0X03,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X01,0XFF,0XFF,
|
|
||||||
0XFF,0XFE,0X00,0X00,0X1F,0XF0,0X00,0X7F,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,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X01,
|
|
||||||
0XFF,0XFF,0XFF,0XFE,0X00,0X00,0X0F,0XF0,0X00,0X7F,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,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,
|
|
||||||
0XC0,0X01,0XFF,0XFF,0XFF,0XFE,0X00,0X00,0X0F,0XF0,0X00,0X7F,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,0X0F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,
|
|
||||||
0XFF,0XFF,0XC0,0X01,0XFF,0XFF,0XFF,0XFE,0X00,0X00,0X07,0XF0,0X00,0X7F,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,0X1F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,
|
|
||||||
0X00,0X03,0XFF,0XFF,0XC0,0X01,0XFF,0XFF,0XFF,0XFE,0X00,0X00,0X03,0XF0,0X00,0X7F,
|
|
||||||
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,0X3F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X01,0XFF,0XFF,0XFF,0XFE,0X00,0X00,0X03,0XF0,
|
|
||||||
0X00,0X7F,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,0X3F,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X07,0XFE,0X00,0X00,
|
|
||||||
0X01,0XF0,0X00,0X7F,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,0X7F,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X07,0XFE,
|
|
||||||
0X00,0X00,0X00,0XF0,0X00,0X7F,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,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,
|
|
||||||
0X07,0XFE,0X00,0X00,0X00,0XF0,0X00,0X7F,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,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,
|
|
||||||
0X00,0X00,0X07,0XFE,0X00,0X00,0X00,0X70,0X00,0X7F,0XFF,0XF8,0X00,0X00,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,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,
|
|
||||||
0XC0,0X00,0X00,0X00,0X07,0XFE,0X00,0X00,0X00,0X30,0X00,0X7F,0XFF,0XF8,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,
|
|
||||||
0XFF,0XFF,0XC0,0X00,0X00,0X00,0X07,0XFE,0X00,0X08,0X00,0X30,0X00,0X7F,0XFF,0XF8,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,
|
|
||||||
0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X07,0XFE,0X00,0X0C,0X00,0X10,0X00,0X7F,
|
|
||||||
0XFF,0XF8,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,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X07,0XFE,0X00,0X0C,0X00,0X00,
|
|
||||||
0X00,0X7F,0XFF,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0F,0XFF,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X07,0XFE,0X00,0X0E,
|
|
||||||
0X00,0X00,0X00,0X7F,0XFF,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X01,0XFF,0XFF,0XFF,0XFE,
|
|
||||||
0X00,0X0F,0X00,0X00,0X00,0X7F,0XFF,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X01,0XFF,0XFF,
|
|
||||||
0XFF,0XFE,0X00,0X0F,0X00,0X00,0X00,0X7F,0XFF,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X3F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X01,
|
|
||||||
0XFF,0XFF,0XFF,0XFE,0X00,0X0F,0X80,0X00,0X00,0X7F,0XFF,0XF8,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X7F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,
|
|
||||||
0XC0,0X01,0XFF,0XFF,0XFF,0XFE,0X00,0X0F,0XC0,0X00,0X00,0X7F,0XFF,0XF8,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X7F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,
|
|
||||||
0XFF,0XFF,0XC0,0X01,0XFF,0XFF,0XFF,0XFE,0X00,0X0F,0XC0,0X00,0X00,0X7F,0XFF,0XF8,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,
|
|
||||||
0X00,0X03,0XFF,0XFF,0XC0,0X01,0XFF,0XFF,0XFF,0XFE,0X00,0X0F,0XE0,0X00,0X00,0X7F,
|
|
||||||
0XFF,0XF8,0X00,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,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X01,0XFF,0XFF,0XFF,0XFE,0X00,0X0F,0XF0,0X00,
|
|
||||||
0X00,0X7F,0XFF,0XF8,0X00,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,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X01,0XFF,0XFF,0XFF,0XFE,0X00,0X0F,
|
|
||||||
0XF8,0X00,0X00,0X7F,0XFF,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0XFF,0XFF,0XFF,0XFE,
|
|
||||||
0X00,0X0F,0XF8,0X00,0X00,0X7F,0XFF,0XF8,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,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,
|
|
||||||
0X01,0XFE,0X00,0X0F,0XFC,0X00,0X00,0X7F,0XFF,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0F,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,
|
|
||||||
0X00,0X00,0X01,0XFE,0X00,0X0F,0XFE,0X00,0X00,0X7F,0XFF,0XF8,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X0F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,
|
|
||||||
0XC0,0X00,0X00,0X00,0X01,0XFE,0X00,0X0F,0XFE,0X00,0X00,0X7F,0XFF,0XF8,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X1F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,
|
|
||||||
0XFF,0XFF,0XC0,0X00,0X00,0X00,0X01,0XFE,0X00,0X0F,0XFF,0X00,0X00,0X7F,0XFF,0XF8,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X3F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,
|
|
||||||
0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X01,0XFE,0X00,0X0F,0XFF,0X80,0X00,0X7F,
|
|
||||||
0XFF,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X3F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X01,0XFE,0X00,0X0F,0XFF,0X80,
|
|
||||||
0X00,0X7F,0XFF,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X7F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X01,0XFE,0X00,0X0F,
|
|
||||||
0XFF,0XC0,0X00,0X7F,0XFF,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X01,0XFE,
|
|
||||||
0X00,0X0F,0XFF,0XE0,0X00,0X7F,0XFF,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,
|
|
||||||
0X01,0XFE,0X00,0X0F,0XFF,0XE0,0X00,0X7F,0XFF,0XF8,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,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X03,0XFF,0XFF,0XC0,0X00,
|
|
||||||
0X00,0X00,0X01,0XFE,0X00,0X1F,0XFF,0XF0,0X00,0X7F,0XFF,0XF8,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X03,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,0XF8,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,0XFF,0X80,0X00,0X03,
|
|
||||||
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,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X07,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,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X0F,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,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,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,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,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,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X3F,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,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X7F,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,0XF8,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X7F,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,0XF8,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,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,0XF8,
|
|
||||||
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,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X80,
|
|
||||||
0X00,0X03,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,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0X80,0X00,0X01,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,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0XC0,0X00,0X03,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,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,
|
|
||||||
0XFF,0XFE,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X40,0X00,0X0F,0XFF,0XE0,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X7E,0X00,0X00,0X00,0X00,0X00,0X00,0X02,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X03,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XC0,0X00,0X0F,0XFF,0XF8,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X7E,0X00,0X00,0X00,0X00,0X00,0X00,0X0E,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X00,0X00,0X07,0XC0,0X00,0X0F,
|
|
||||||
0XFF,0XFC,0X00,0X00,0X00,0X00,0X00,0X7E,0X00,0X00,0X00,0X00,0X00,0X00,0X3E,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XC0,0X00,0X00,0X00,0X00,0X00,0X0F,0XC0,
|
|
||||||
0X00,0X0F,0XFF,0XFE,0X00,0X00,0X00,0X00,0X00,0X7E,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X7E,0X00,0X00,0X00,0X00,0X00,0X00,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,
|
|
||||||
0X0F,0XC0,0X00,0X0F,0XFF,0XFE,0X00,0X00,0X00,0X00,0X00,0X7E,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0XFE,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XF8,0X1F,0XE0,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X0F,0XC0,0X00,0X0F,0XE0,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0XFE,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XF8,0X0F,0XE0,0X03,
|
|
||||||
0XE0,0X00,0X3F,0XE0,0X1F,0XC0,0X00,0X0F,0XE0,0X7F,0X00,0X0E,0X00,0X7E,0X00,0X00,
|
|
||||||
0X00,0X3F,0X00,0X01,0XFC,0X00,0XFE,0X00,0X3F,0XC0,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XF8,0X0F,
|
|
||||||
0XC0,0X1F,0XFC,0X00,0XFF,0XF8,0X7F,0XFC,0X00,0X0F,0XE0,0X7F,0X1F,0X9F,0X83,0XFF,
|
|
||||||
0X80,0X7E,0X01,0XFF,0XE0,0X07,0XFF,0X03,0XFF,0XE0,0XFF,0XF0,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,
|
|
||||||
0XF8,0X1F,0XC0,0X3F,0XFE,0X03,0XFF,0XFC,0X7F,0XFC,0X00,0X0F,0XE0,0X7F,0X1F,0XFF,
|
|
||||||
0X07,0XFF,0XE0,0X7E,0X03,0XFF,0XF0,0X1F,0XFF,0XC3,0XFF,0XE1,0XFF,0XF8,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X03,0XFF,0XFF,0X80,0X7F,0XFF,0X83,0XFF,0XFE,0X7F,0XFC,0X00,0X0F,0XE0,0XFF,
|
|
||||||
0X1F,0XFF,0X0F,0XFF,0XF0,0X7E,0X07,0XFF,0XF8,0X3F,0XFF,0XE3,0XFF,0XE3,0XFF,0XFC,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X03,0XFF,0XFF,0X00,0XFF,0XFF,0X87,0XF8,0XFE,0X7F,0XFC,0X00,0X0F,
|
|
||||||
0XFF,0XFE,0X1F,0XFE,0X1F,0XFF,0XF0,0X7E,0X0F,0XE3,0XF8,0X3F,0XFF,0XE3,0XFF,0XE3,
|
|
||||||
0XE1,0XFC,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0X01,0XFE,0X3F,0XC7,0XF0,0X7E,0X1F,0XC0,
|
|
||||||
0X00,0X0F,0XFF,0XFE,0X1F,0XF2,0X1F,0XC3,0XF8,0X7E,0X0F,0XC1,0XFC,0X7F,0X87,0XF0,
|
|
||||||
0XFE,0X07,0XE0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XC1,0XFC,0X1F,0XC0,0X00,0XFE,
|
|
||||||
0X0F,0XC0,0X00,0X0F,0XFF,0XFC,0X1F,0XE0,0X3F,0X83,0XF8,0X7E,0X1F,0XC0,0XFC,0X7F,
|
|
||||||
0X03,0X80,0XFE,0X03,0XFC,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XE1,0XFC,0X0F,0XC0,
|
|
||||||
0X07,0XFE,0X0F,0XC0,0X00,0X0F,0XFF,0XF8,0X1F,0XC0,0X3F,0X81,0XF8,0X7E,0X1F,0XC0,
|
|
||||||
0XFC,0X7E,0X00,0X00,0XFE,0X03,0XFF,0XE0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XF8,0X0F,0XE1,0XF8,
|
|
||||||
0X0F,0XC0,0XFF,0XFE,0X0F,0XC0,0X00,0X0F,0XFF,0XE0,0X1F,0XC0,0X3F,0X81,0XF8,0X7E,
|
|
||||||
0X1F,0XFF,0XFE,0X7E,0X00,0X00,0XFE,0X01,0XFF,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XF8,0X0F,
|
|
||||||
0XF1,0XF8,0X0F,0XC3,0XFF,0XFE,0X0F,0XC0,0X00,0X0F,0XE0,0X00,0X1F,0XC0,0X3F,0X01,
|
|
||||||
0XFC,0X7E,0X1F,0XFF,0XFE,0X7E,0X00,0X00,0XFE,0X00,0XFF,0XFC,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,
|
|
||||||
0XF8,0X0F,0XF1,0XF8,0X0F,0XC7,0XFC,0X7E,0X0F,0XC0,0X00,0X0F,0XE0,0X00,0X1F,0XC0,
|
|
||||||
0X3F,0X81,0XF8,0X7E,0X1F,0XFF,0XFE,0X7E,0X00,0X00,0XFE,0X00,0X3F,0XFC,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X03,0XF8,0X0F,0XF1,0XFC,0X1F,0XC7,0XF0,0X7E,0X0F,0XC0,0X00,0X0F,0XE0,0X00,
|
|
||||||
0X1F,0XC0,0X3F,0X81,0XF8,0X7E,0X1F,0XC0,0X00,0X7F,0X03,0XC0,0XFE,0X00,0X01,0XFE,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X03,0XFC,0X3F,0XF1,0XFC,0X1F,0XC7,0XE0,0X7E,0X0F,0XC0,0X00,0X0F,
|
|
||||||
0XE0,0X00,0X1F,0XC0,0X1F,0X83,0XF8,0X7E,0X1F,0XC0,0X00,0X7F,0X07,0XF0,0XFE,0X00,
|
|
||||||
0X60,0X7E,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XE0,0XFF,0X3F,0X87,0XE0,0XFE,0X0F,0XFC,
|
|
||||||
0X00,0X0F,0XE0,0X00,0X1F,0XC0,0X1F,0XE7,0XF0,0X7E,0X0F,0XE1,0XFC,0X7F,0XCF,0XF0,
|
|
||||||
0X7F,0XC7,0XF0,0X7E,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XE0,0XFF,0XFF,0X87,0XFF,0XFE,
|
|
||||||
0X0F,0XFC,0X00,0X0F,0XE0,0X00,0X1F,0XC0,0X0F,0XFF,0XF0,0X7E,0X0F,0XFF,0XF8,0X3F,
|
|
||||||
0XFF,0XE0,0X7F,0XC7,0XFF,0XFC,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XC0,0X7F,0XFF,0X07,
|
|
||||||
0XFF,0XFE,0X0F,0XFC,0X00,0X0F,0XE0,0X00,0X1F,0XC0,0X07,0XFF,0XE0,0X7E,0X07,0XFF,
|
|
||||||
0XF0,0X1F,0XFF,0XC0,0X7F,0XE3,0XFF,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0X80,0X1F,
|
|
||||||
0XFE,0X03,0XFF,0X3F,0X07,0XFC,0X00,0X0F,0XE0,0X00,0X1F,0XC0,0X03,0XFF,0XC0,0X7E,
|
|
||||||
0X03,0XFF,0XE0,0X0F,0XFF,0X80,0X3F,0XE1,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XF8,
|
|
||||||
0X00,0X07,0XF8,0X00,0XFC,0X3F,0X03,0XFC,0X00,0X0F,0XE0,0X00,0X1F,0XC0,0X00,0XFF,
|
|
||||||
0X00,0X7E,0X00,0XFF,0X80,0X03,0XFE,0X00,0X1F,0XE0,0X7F,0XC0,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0XFE,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X03,0XFE,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFE,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
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,0XFE,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,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,0XFC,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,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,0XFC,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XE0,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,};
|
|
||||||
@@ -1,939 +0,0 @@
|
|||||||
const unsigned char gImage_MFD_OBP60_400x300_sw[15000] = { /* 0X00,0X01,0X90,0X01,0X2C,0X01, */
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0XE0,0X3F,
|
|
||||||
0XC0,0X00,0X00,0X7E,0X00,0X40,0XFC,0X07,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X08,0X1F,0X80,0X00,0X00,0X00,0X00,0X00,0X07,0XFF,0XE0,0X0F,0XC0,0X00,0X00,0X00,
|
|
||||||
0X00,0X1F,0X80,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,
|
|
||||||
0XF0,0X3F,0XC0,0X00,0X00,0X7E,0X01,0XC0,0XFC,0X1F,0XF0,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X38,0X1F,0X80,0X00,0X00,0X00,0X00,0X00,0X07,0XFF,0XF8,0X0F,0XC0,0X00,
|
|
||||||
0X00,0X00,0X00,0X1F,0X80,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X1F,0XF0,0X7F,0XC0,0X00,0X00,0X7E,0X07,0XC0,0XFC,0X1F,0XF0,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0XF8,0X1F,0X80,0X00,0X00,0X00,0X00,0X00,0X07,0XFF,0XFC,0X0F,
|
|
||||||
0XC0,0X00,0X00,0X00,0X00,0X1F,0X80,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X1F,0XF0,0X7F,0XC0,0X00,0X00,0X7E,0X0F,0XC0,0XFC,0X3F,0XE0,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X01,0XF8,0X1F,0X80,0X00,0X00,0X00,0X00,0X00,0X07,0XFF,
|
|
||||||
0XFE,0X0F,0XC0,0X00,0X00,0X00,0X00,0X1F,0X80,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X1F,0XF0,0X7F,0XC0,0X00,0X00,0X7E,0X0F,0XC0,0X00,0X3F,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X07,0XFF,0XFE,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0X80,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0XF8,0X7F,0XC0,0X00,0X00,0X7E,0X0F,0XC0,
|
|
||||||
0X00,0X3F,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XF8,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X07,0XF0,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0X80,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0XF8,0XFF,0XC3,0XE0,0XF8,0X7E,
|
|
||||||
0X3F,0XF8,0XFC,0XFF,0XE7,0XC1,0XF0,0XF8,0XF8,0X01,0XFC,0X07,0XFF,0X1F,0X80,0X7F,
|
|
||||||
0X00,0XF8,0XF8,0X00,0X07,0XF0,0X7F,0X0F,0XC0,0X7F,0X80,0XF9,0XF0,0X1F,0X80,0XFF,
|
|
||||||
0X83,0XF0,0X3F,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0X78,0XF7,0XC3,0XE0,
|
|
||||||
0XF8,0X7E,0X3F,0XF8,0XFC,0XFF,0XE7,0XC1,0XF0,0XFB,0XFC,0X07,0XFF,0X07,0XFF,0X1F,
|
|
||||||
0X81,0XFF,0XC0,0XFB,0XFC,0X00,0X07,0XF0,0X3F,0X0F,0XC1,0XFF,0XE0,0XFB,0XFC,0X1F,
|
|
||||||
0X83,0XFF,0XE1,0XF8,0X3E,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0X78,0XF7,
|
|
||||||
0XC3,0XE0,0XF8,0X7E,0X3F,0XF8,0XFC,0XFF,0XE7,0XC1,0XF0,0XFF,0XFE,0X0F,0XFF,0XC7,
|
|
||||||
0XFF,0X1F,0X83,0XFF,0XE0,0XFF,0XFE,0X00,0X07,0XF0,0X3F,0X0F,0XC3,0XFF,0XF0,0XFF,
|
|
||||||
0XFE,0X1F,0X87,0XFF,0XF1,0XF8,0X3E,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,
|
|
||||||
0X7C,0XF7,0XC3,0XE0,0XF8,0X7E,0X3F,0XF8,0XFC,0XFF,0XE7,0XC1,0XF0,0XFF,0XFE,0X1F,
|
|
||||||
0XFF,0XC7,0XFF,0X1F,0X87,0XFF,0XF0,0XFF,0XFE,0X00,0X07,0XF0,0X3F,0X8F,0XC3,0XE3,
|
|
||||||
0XF0,0XFF,0XFE,0X1F,0X87,0XFF,0XF0,0XF8,0X7E,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X1F,0X3D,0XE7,0XC3,0XE0,0XF8,0X7E,0X0F,0XC0,0XFC,0X3F,0X07,0XC1,0XF0,0XFF,
|
|
||||||
0XFE,0X1F,0X87,0XE1,0XF8,0X1F,0X87,0XE3,0XF0,0XFF,0XFE,0X00,0X07,0XF0,0X3F,0X8F,
|
|
||||||
0XC3,0XE1,0X80,0XFC,0X7F,0X1F,0X87,0XC1,0XF0,0XFC,0X7C,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X1F,0X3D,0XE7,0XC3,0XE0,0XF8,0X7E,0X0F,0XC0,0XFC,0X3F,0X07,0XC1,
|
|
||||||
0XF0,0XFC,0X7E,0X3F,0X07,0X01,0XF8,0X1F,0X8F,0XC1,0XF8,0XFC,0X7E,0X00,0X07,0XF0,
|
|
||||||
0X3F,0X8F,0XC3,0XFC,0X00,0XFC,0X3F,0X1F,0X80,0X07,0XF0,0X7C,0X7C,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X1F,0X3F,0XE7,0XC3,0XE0,0XF8,0X7E,0X0F,0XC0,0XFC,0X3F,
|
|
||||||
0X07,0XC1,0XF0,0XFC,0X3E,0X3F,0X00,0X01,0XF8,0X1F,0X8F,0XC1,0XF8,0XFC,0X3E,0X00,
|
|
||||||
0X07,0XF0,0X3F,0X0F,0XC3,0XFF,0XE0,0XF8,0X3F,0X1F,0X80,0X7F,0XF0,0X7C,0XF8,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0X3F,0XE7,0XC3,0XE0,0XF8,0X7E,0X0F,0XC0,
|
|
||||||
0XFC,0X3F,0X07,0XC1,0XF0,0XF8,0X3E,0X3F,0X00,0X01,0XF8,0X1F,0X8F,0XC1,0XF8,0XF8,
|
|
||||||
0X3E,0X00,0X07,0XF0,0X3F,0X0F,0XC1,0XFF,0XF0,0XF8,0X3F,0X1F,0X83,0XFF,0XF0,0X7C,
|
|
||||||
0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0X1F,0XC7,0XC3,0XE1,0XF8,0X7E,
|
|
||||||
0X0F,0XC0,0XFC,0X3F,0X07,0XC3,0XF0,0XF8,0X3E,0X3F,0X00,0X01,0XF8,0X1F,0X8F,0XC1,
|
|
||||||
0XF8,0XF8,0X3E,0X00,0X07,0XF0,0X3F,0X0F,0XC0,0X7F,0XF8,0XF8,0X3F,0X1F,0X87,0XF1,
|
|
||||||
0XF0,0X3E,0XF8,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0X1F,0XC7,0XC3,0XF1,
|
|
||||||
0XF8,0X7E,0X0F,0XC0,0XFC,0X3F,0X07,0XE3,0XF0,0XF8,0X3E,0X3F,0X03,0X01,0XF8,0X1F,
|
|
||||||
0X8F,0XC1,0XF8,0XF8,0X3E,0X00,0X07,0XF0,0X7F,0X0F,0XC0,0X03,0XF8,0XFC,0X3F,0X1F,
|
|
||||||
0X8F,0XC1,0XF0,0X3F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0X1F,0XC7,
|
|
||||||
0XC3,0XFF,0XF8,0X7E,0X0F,0XC0,0XFC,0X3F,0X07,0XFF,0XF0,0XF8,0X3E,0X1F,0X87,0XE1,
|
|
||||||
0XF8,0X1F,0X87,0XE3,0XF0,0XF8,0X3E,0X00,0X07,0XFF,0XFE,0X0F,0XC0,0XE0,0XF8,0XFC,
|
|
||||||
0X7F,0X1F,0X8F,0XC3,0XF0,0X1F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,
|
|
||||||
0X1F,0XC7,0XC3,0XFF,0XF8,0X7E,0X0F,0XF8,0XFC,0X3F,0X07,0XFF,0XF0,0XF8,0X3E,0X1F,
|
|
||||||
0XFF,0XC1,0XFF,0X1F,0X87,0XFF,0XF0,0XF8,0X3E,0X00,0X07,0XFF,0XFE,0X0F,0XC7,0XE1,
|
|
||||||
0XF8,0XFF,0XFE,0X1F,0X8F,0XFF,0XF0,0X1F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X1F,0X0F,0X87,0XC3,0XFF,0XF8,0X7E,0X0F,0XF8,0XFC,0X3F,0X07,0XFF,0XF0,0XF8,
|
|
||||||
0X3E,0X0F,0XFF,0XC1,0XFF,0X1F,0X83,0XFF,0XE0,0XF8,0X3E,0X00,0X07,0XFF,0XFC,0X0F,
|
|
||||||
0XC3,0XFF,0XF0,0XFF,0XFE,0X1F,0X8F,0XFF,0XF0,0X1F,0XE0,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X1F,0X0F,0X87,0XC1,0XFE,0XF8,0X7E,0X07,0XF8,0XFC,0X3F,0X03,0XFD,
|
|
||||||
0XF0,0XF8,0X3E,0X07,0XFF,0X80,0XFF,0X1F,0X81,0XFF,0XC0,0XF8,0X3E,0X00,0X07,0XFF,
|
|
||||||
0XF8,0X0F,0XC3,0XFF,0XE0,0XFF,0XFC,0X1F,0X87,0XFD,0XF0,0X0F,0XE0,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X1F,0X0F,0X87,0XC0,0XF8,0XF8,0X7E,0X03,0XF8,0XFC,0X3F,
|
|
||||||
0X01,0XF1,0XF0,0XF8,0X3E,0X01,0XFE,0X00,0X7F,0X1F,0X80,0X7F,0X00,0XF8,0X3E,0X00,
|
|
||||||
0X07,0XFF,0XC0,0X0F,0XC0,0X7F,0X80,0XF9,0XF0,0X1F,0X81,0XF0,0XF8,0X0F,0XC0,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XF8,0X00,0X00,0X00,0X00,0X00,0X0F,
|
|
||||||
0XC0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XF8,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X0F,0XC0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XF8,0X00,0X00,
|
|
||||||
0X00,0X00,0X01,0XFF,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XF8,
|
|
||||||
0X00,0X00,0X00,0X00,0X01,0XFF,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0XF8,0X00,0X00,0X00,0X00,0X01,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0XF8,0X00,0X00,0X00,0X00,0X00,0XFC,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XF8,0X01,0XFF,0XFC,0X03,0XFF,0XF0,0X00,0XFC,
|
|
||||||
0X00,0X3F,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0XFE,0X01,0XFF,0XFF,0X03,0XFF,0XFC,
|
|
||||||
0X03,0XFF,0X00,0XFF,0XE0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,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,0X81,0XFF,0XFF,0X83,
|
|
||||||
0XFF,0XFE,0X07,0XFF,0X81,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,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,0XC1,0XFF,
|
|
||||||
0XFF,0X83,0XFF,0XFE,0X0F,0XFF,0XC3,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,
|
|
||||||
0XC1,0XFF,0XFF,0XC3,0XFF,0XFE,0X1F,0X8F,0XC3,0XF1,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,0X01,
|
|
||||||
0XFE,0X1F,0XE1,0XFC,0X1F,0XC3,0XF0,0X7F,0X1F,0X87,0X83,0XE0,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,0X01,0XFC,0X0F,0XE1,0XFC,0X1F,0X83,0XF0,0X3F,0X1F,0X00,0X07,0XE0,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,0X01,0XF8,0X07,0XE1,0XFC,0X1F,0X83,0XF0,0X3F,0X3F,0X3E,0X07,0XE0,
|
|
||||||
0XFC,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X03,0XF8,0X07,0XF1,0XFF,0XFF,0X03,0XF0,0X7F,0X3F,0X7F,
|
|
||||||
0X87,0XE0,0XFC,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XF8,0X07,0XF1,0XFF,0XFE,0X03,0XFF,0XFE,
|
|
||||||
0X3F,0XFF,0XC7,0XE0,0XFC,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XF8,0X07,0XF1,0XFF,0XFF,0X03,
|
|
||||||
0XFF,0XFE,0X3F,0XFF,0XC7,0XE0,0XFC,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XF8,0X07,0XF1,0XFF,
|
|
||||||
0XFF,0X83,0XFF,0XFC,0X3F,0X87,0XE7,0XE0,0XFC,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XF8,0X07,
|
|
||||||
0XF1,0XFF,0XFF,0XC3,0XFF,0XF8,0X3F,0X07,0XE7,0XE0,0XFC,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,
|
|
||||||
0XF8,0X07,0XE1,0XFC,0X0F,0XC3,0XFF,0XE0,0X3F,0X03,0XE7,0XE0,0XFC,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X01,0XFC,0X0F,0XE1,0XFC,0X0F,0XE3,0XF0,0X00,0X1F,0X03,0XE3,0XE0,0XFC,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X01,0XFE,0X1F,0XE1,0XFC,0X0F,0XE3,0XF0,0X00,0X1F,0X07,0XE3,0XE0,
|
|
||||||
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,0XFF,0XFF,0XC1,0XFF,0XFF,0XC3,0XF0,0X00,0X1F,0X87,
|
|
||||||
0XE3,0XF1,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,0X7F,0XFF,0XC1,0XFF,0XFF,0XC3,0XF0,0X00,
|
|
||||||
0X0F,0XFF,0XC1,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,0X7F,0XFF,0X81,0XFF,0XFF,0X83,
|
|
||||||
0XF0,0X00,0X07,0XFF,0X81,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0XFE,0X01,0XFF,
|
|
||||||
0XFF,0X83,0XF0,0X00,0X03,0XFF,0X00,0XFF,0XE0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,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,0XF8,
|
|
||||||
0X01,0XFF,0XFC,0X03,0XF0,0X00,0X00,0XFC,0X00,0X3F,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,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XF0,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X40,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0XC0,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XC0,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XC0,0X07,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XC0,0X07,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,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,0XC0,0X07,
|
|
||||||
0XFF,0XFC,0X07,0XFF,0X00,0X07,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,
|
|
||||||
0XC0,0X07,0XFF,0XE0,0X00,0XFF,0X00,0X00,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XC0,0X07,0XFF,0XC0,0X00,0X7F,0X00,0X00,0X7F,0XF0,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X1F,0XC0,0X07,0XFF,0X80,0X00,0X3F,0X00,0X00,0X3F,0XF0,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X1F,0XC0,0X07,0XFF,0X00,0X00,0X1F,0X00,0X00,0X1F,0XF0,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X3F,0XC0,0X07,0XFE,0X00,0XC0,0X0F,0X01,0XE0,
|
|
||||||
0X1F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,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,0XC0,0X07,0XFE,0X03,0XF0,0X0F,
|
|
||||||
0X01,0XF0,0X1F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XC0,0X07,0XFC,0X03,
|
|
||||||
0XF8,0X0F,0X01,0XF0,0X1F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XC0,0X07,
|
|
||||||
0XFC,0X07,0XF8,0X07,0X01,0XF0,0X1F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XFF,
|
|
||||||
0XC0,0X07,0XFC,0X07,0XFC,0X07,0X01,0XE0,0X1F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X03,0XFF,0XC0,0X07,0XFC,0X07,0XFC,0X07,0X00,0X00,0X3F,0XF0,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X03,0XFF,0XC0,0X07,0XFC,0X07,0XFC,0X07,0X00,0X00,0X3F,0XF0,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XC0,0X07,0XFC,0X07,0XFC,0X07,0X00,0X00,0X7F,0XF0,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XFF,0XC0,0X07,0XFC,0X07,0XFC,0X07,0X00,0X00,
|
|
||||||
0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
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,0XFF,0XC0,0X07,0XFC,0X07,0XF8,0X07,
|
|
||||||
0X01,0XDF,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0XFF,0XC0,0X07,0XFC,0X07,
|
|
||||||
0XF8,0X0F,0X01,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X3F,0XFF,0XC0,0X07,
|
|
||||||
0XFE,0X03,0XF8,0X0F,0X01,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,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,
|
|
||||||
0XC0,0X07,0XFE,0X00,0XE0,0X0F,0X01,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XC0,0X07,0XFF,0X00,0X00,0X1F,0X01,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0XFF,0XFF,0XC0,0X07,0XFF,0X00,0X00,0X3F,0X01,0XFF,0XFF,0XF0,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X01,0XFF,0XFF,0XC0,0X07,0XFF,0X80,0X00,0X7F,0X01,0XFF,0XFF,0XF0,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X01,0XFF,0XFF,0XC0,0X07,0XFF,0XE0,0X00,0XFF,0X01,0XFF,
|
|
||||||
0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XC0,0X07,0XFF,0XF8,0X03,0XFF,
|
|
||||||
0X01,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,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,0XC0,0X07,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,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,0XC0,0X07,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,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,0XFF,0XFF,
|
|
||||||
0XC0,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,
|
|
||||||
0XFF,0XFF,0XC0,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X3F,0XFF,0XFF,0XC0,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X3F,0XFF,0XFF,0XC0,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XFF,0XC0,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XC0,0X07,0XFE,0X00,0X00,0X78,
|
|
||||||
0X0F,0XF0,0X3F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XC0,0X07,0XFE,0X00,
|
|
||||||
0X00,0X78,0X07,0XF0,0X3F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0XFF,0XFF,0XFF,0XC0,0X07,
|
|
||||||
0XFE,0X00,0X00,0X78,0X07,0XF0,0X3F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XFF,
|
|
||||||
0XC0,0X07,0XFE,0X00,0X00,0X78,0X03,0XF0,0X3F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFF,
|
|
||||||
0XFF,0XFF,0XC0,0X07,0XFE,0X00,0X00,0X78,0X01,0XF0,0X3F,0XF0,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XC0,0X07,0XFE,0X03,0XFF,0XF8,0X01,0XF0,0X3F,0XF0,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XFF,0XFF,0XFF,0XC0,0X07,0XFE,0X03,0XFF,0XF8,0X00,0XF0,0X3F,0XF0,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X1F,0XFF,0XFF,0XFF,0XC0,0X07,0XFE,0X03,0XFF,0XF8,0X00,0X70,
|
|
||||||
0X3F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0XFF,0XFF,0XFF,0XC0,0X07,0XFE,0X00,0X00,0XF8,
|
|
||||||
0X00,0X70,0X3F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X3F,0XFF,0XFF,0XFF,0XC0,0X07,0XFE,0X00,
|
|
||||||
0X00,0XF8,0X00,0X30,0X3F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,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,0XFF,0XFF,0XC0,0X07,
|
|
||||||
0XFE,0X00,0X00,0XF8,0X00,0X10,0X3F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,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,0XFF,0XFF,
|
|
||||||
0XC0,0X07,0XFE,0X00,0X00,0XF8,0X00,0X10,0X3F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XC0,0X07,0XFE,0X00,0X00,0XF8,0X08,0X00,0X3F,0XF0,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XC0,0X07,0XFE,0X03,0XFF,0XF8,0X0C,0X00,0X3F,0XF0,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XC0,0X07,0XFE,0X03,0XFF,0XF8,0X0E,0X00,0X3F,0XF0,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X03,0XFF,0XFF,0XFF,0XFF,0XC0,0X07,0XFE,0X03,0XFF,0XF8,0X0E,0X00,
|
|
||||||
0X3F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XC0,0X07,0XFE,0X03,0XFF,0XF8,
|
|
||||||
0X0F,0X00,0X3F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XFF,0XFF,0XFF,0XFF,0XC0,0X07,0XFE,0X00,
|
|
||||||
0X00,0X78,0X0F,0X80,0X3F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,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,0XFF,0XFF,0XFF,0XFF,0XC0,0X07,
|
|
||||||
0XFE,0X00,0X00,0X78,0X0F,0X80,0X3F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X1F,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XC0,0X07,0XFE,0X00,0X00,0X78,0X0F,0XC0,0X3F,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X3F,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XC0,0X07,0XFE,0X00,0X00,0X78,0X0F,0XE0,0X3F,0XF0,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X3F,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XC0,0X07,0XFE,0X00,0X00,0X78,0X0F,0XE0,0X3F,0XF0,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XFF,0XFF,0XFF,0XC0,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0XFF,0XC0,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0XFF,0XC0,0X07,0XFF,0XFF,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,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,0XC0,0X07,0XFF,0XFF,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XFF,0XFF,0XFF,0XFF,0XFF,0XC0,0X07,
|
|
||||||
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,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,
|
|
||||||
0XC0,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,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,0XC0,0X07,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF0,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
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,0XF8,0X00,0X00,0X00,0X20,0X0F,0XE0,
|
|
||||||
0X00,0X00,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,0X07,0XFC,0X00,0X00,0X00,0X60,
|
|
||||||
0X0F,0XF8,0X00,0X00,0X38,0X00,0X00,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,0X00,0X00,0X00,0X00,0X00,0X07,0XFE,0X00,0X00,
|
|
||||||
0X00,0XE0,0X0F,0XF8,0X00,0X00,0X00,0X00,0X00,0X03,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,0X00,0X00,0X00,0X00,0X00,0X07,0X0E,
|
|
||||||
0X06,0X00,0XC0,0XE0,0X0E,0X3C,0X08,0X38,0X00,0X18,0X03,0X03,0X81,0XC0,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0X1E,0X1F,0X87,0XFB,0XF8,0X0E,0X3C,0XDC,0XFE,0X38,0X7F,0X0F,0XE7,0XE7,0XF0,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0XFC,0X3F,0XCF,0X3B,0XF8,0X0F,0XF8,0XF9,0XFF,0X38,0XE7,0X1F,0XE7,
|
|
||||||
0XE6,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,0X07,0XFE,0X78,0XE0,0X38,0XE0,0X0F,0XF8,0XE1,0XC7,0X39,0XE3,
|
|
||||||
0XBC,0X03,0X87,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0X0E,0X70,0XE3,0XF8,0XE0,0X0F,0XE0,0XE1,0XC7,
|
|
||||||
0X39,0XFF,0XB8,0X03,0X87,0XF0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
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,0X0F,0X70,0XEF,0X38,0XE0,0X0E,0X00,
|
|
||||||
0XE1,0XC7,0X39,0XFF,0XB8,0X03,0X81,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,0X07,0X1E,0X39,0XEE,0X38,0XE0,
|
|
||||||
0X0E,0X00,0XE1,0XC7,0X38,0XE0,0X3C,0XF3,0X80,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,0X07,0XFE,0X3F,0XCF,
|
|
||||||
0XF8,0XF0,0X0E,0X00,0XE0,0XFF,0X38,0XFF,0X1F,0XE3,0XEF,0X78,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,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,0XFC,
|
|
||||||
0X1F,0X87,0XD8,0XF8,0X0E,0X00,0XE0,0X7C,0X38,0X7E,0X0F,0XC1,0XE7,0XF0,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,0X00,0X78,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,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,
|
|
||||||
0X20,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
|
|
||||||
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,};
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
@@ -24,6 +25,7 @@
|
|||||||
#include "fonts/Ubuntu_Bold20pt8b.h"
|
#include "fonts/Ubuntu_Bold20pt8b.h"
|
||||||
#include "fonts/Ubuntu_Bold32pt8b.h"
|
#include "fonts/Ubuntu_Bold32pt8b.h"
|
||||||
#include "fonts/Atari16px8b.h" // Key label font
|
#include "fonts/Atari16px8b.h" // Key label font
|
||||||
|
#include "fonts/Atari6px8b.h" // Very small (6x6) font
|
||||||
|
|
||||||
// E-Ink Display
|
// E-Ink Display
|
||||||
#define GxEPD_WIDTH 400 // Display width
|
#define GxEPD_WIDTH 400 // Display width
|
||||||
@@ -32,30 +34,20 @@
|
|||||||
#ifdef DISPLAY_GDEW042T2
|
#ifdef DISPLAY_GDEW042T2
|
||||||
// Set display type and SPI pins for display
|
// Set display type and SPI pins for display
|
||||||
GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(OBP_SPI_CS, OBP_SPI_DC, OBP_SPI_RST, OBP_SPI_BUSY)); // GDEW042T2 400x300, UC8176 (IL0398)
|
GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(OBP_SPI_CS, OBP_SPI_DC, OBP_SPI_RST, OBP_SPI_BUSY)); // GDEW042T2 400x300, UC8176 (IL0398)
|
||||||
// Export display in new funktion
|
|
||||||
GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> & getdisplay(){return display;}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DISPLAY_GDEY042T81
|
#ifdef DISPLAY_GDEY042T81
|
||||||
// Set display type and SPI pins for display
|
// Set display type and SPI pins for display
|
||||||
GxEPD2_BW<GxEPD2_420_GDEY042T81, GxEPD2_420_GDEY042T81::HEIGHT> display(GxEPD2_420_GDEY042T81(OBP_SPI_CS, OBP_SPI_DC, OBP_SPI_RST, OBP_SPI_BUSY)); // GDEW042T2 400x300, UC8176 (IL0398)
|
GxEPD2_BW<GxEPD2_420_GDEY042T81, GxEPD2_420_GDEY042T81::HEIGHT> display(GxEPD2_420_GDEY042T81(OBP_SPI_CS, OBP_SPI_DC, OBP_SPI_RST, OBP_SPI_BUSY)); // GDEW042T2 400x300, UC8176 (IL0398)
|
||||||
// Export display in new funktion
|
|
||||||
GxEPD2_BW<GxEPD2_420_GDEY042T81, GxEPD2_420_GDEY042T81::HEIGHT> & getdisplay(){return display;}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DISPLAY_GYE042A87
|
#ifdef DISPLAY_GYE042A87
|
||||||
// Set display type and SPI pins for display
|
// Set display type and SPI pins for display
|
||||||
GxEPD2_BW<GxEPD2_420_GYE042A87, GxEPD2_420_GYE042A87::HEIGHT> display(GxEPD2_420_GYE042A87(OBP_SPI_CS, OBP_SPI_DC, OBP_SPI_RST, OBP_SPI_BUSY)); // GDEW042T2 400x300, UC8176 (IL0398)
|
GxEPD2_BW<GxEPD2_420_GYE042A87, GxEPD2_420_GYE042A87::HEIGHT> display(GxEPD2_420_GYE042A87(OBP_SPI_CS, OBP_SPI_DC, OBP_SPI_RST, OBP_SPI_BUSY)); // GDEW042T2 400x300, UC8176 (IL0398)
|
||||||
// Export display in new funktion
|
|
||||||
GxEPD2_BW<GxEPD2_420_GYE042A87, GxEPD2_420_GYE042A87::HEIGHT> & getdisplay(){return display;}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DISPLAY_SE0420NQ04
|
#ifdef DISPLAY_SE0420NQ04
|
||||||
// Set display type and SPI pins for display
|
// Set display type and SPI pins for display
|
||||||
GxEPD2_BW<GxEPD2_420_SE0420NQ04, GxEPD2_420_SE0420NQ04::HEIGHT> display(GxEPD2_420_SE0420NQ04(OBP_SPI_CS, OBP_SPI_DC, OBP_SPI_RST, OBP_SPI_BUSY)); // GDEW042T2 400x300, UC8176 (IL0398)
|
GxEPD2_BW<GxEPD2_420_SE0420NQ04, GxEPD2_420_SE0420NQ04::HEIGHT> display(GxEPD2_420_SE0420NQ04(OBP_SPI_CS, OBP_SPI_DC, OBP_SPI_RST, OBP_SPI_BUSY)); // GDEW042T2 400x300, UC8176 (IL0398)
|
||||||
// Export display in new funktion
|
|
||||||
GxEPD2_BW<GxEPD2_420_SE0420NQ04, GxEPD2_420_SE0420NQ04::HEIGHT> & getdisplay(){return display;}
|
|
||||||
#endif
|
#endif
|
||||||
|
gxepd2display *epd = &display;
|
||||||
|
|
||||||
// Horter I2C moduls
|
// Horter I2C moduls
|
||||||
PCF8574 pcf8574_Out(PCF8574_I2C_ADDR1); // First digital output modul PCF8574 from Horter
|
PCF8574 pcf8574_Out(PCF8574_I2C_ADDR1); // First digital output modul PCF8574 from Horter
|
||||||
@@ -64,7 +56,14 @@ PCF8574 pcf8574_Out(PCF8574_I2C_ADDR1); // First digital output modul PCF8574 fr
|
|||||||
Adafruit_FRAM_I2C fram;
|
Adafruit_FRAM_I2C fram;
|
||||||
bool hasFRAM = false;
|
bool hasFRAM = false;
|
||||||
|
|
||||||
|
// SD Card
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
sdmmc_card_t *sdcard;
|
||||||
|
#endif
|
||||||
|
bool hasSDCard = false;
|
||||||
|
|
||||||
// Global vars
|
// Global vars
|
||||||
|
bool heartbeat = false; // Heartbeat indicator with two different states
|
||||||
bool blinkingLED = false; // Enable / disable blinking flash LED
|
bool blinkingLED = false; // Enable / disable blinking flash LED
|
||||||
bool statusLED = false; // Actual status of flash LED on/off
|
bool statusLED = false; // Actual status of flash LED on/off
|
||||||
bool statusBacklightLED = false;// Actual status of flash LED on/off
|
bool statusBacklightLED = false;// Actual status of flash LED on/off
|
||||||
@@ -78,16 +77,19 @@ LedTaskData *ledTaskData=nullptr;
|
|||||||
|
|
||||||
void hardwareInit(GwApi *api)
|
void hardwareInit(GwApi *api)
|
||||||
{
|
{
|
||||||
|
GwLog *logger = api->getLogger();
|
||||||
|
GwConfigHandler *config = api->getConfig();
|
||||||
|
|
||||||
Wire.begin();
|
Wire.begin();
|
||||||
// Init PCF8574 digital outputs
|
// Init PCF8574 digital outputs
|
||||||
Wire.setClock(I2C_SPEED); // Set I2C clock on 10 kHz
|
Wire.setClock(I2C_SPEED); // Set I2C clock as defined
|
||||||
if(pcf8574_Out.begin()){ // Initialize PCF8574
|
if(pcf8574_Out.begin()){ // Initialize PCF8574
|
||||||
pcf8574_Out.write8(255); // Clear all outputs
|
pcf8574_Out.write8(255); // Clear all outputs
|
||||||
}
|
}
|
||||||
fram = Adafruit_FRAM_I2C();
|
fram = Adafruit_FRAM_I2C();
|
||||||
if (esp_reset_reason() == ESP_RST_POWERON) {
|
if (esp_reset_reason() == ESP_RST_POWERON) {
|
||||||
// help initialize FRAM
|
// help initialize FRAM
|
||||||
api->getLogger()->logDebug(GwLog::LOG,"Delaying I2C init for 250ms due to cold boot");
|
logger->logDebug(GwLog::LOG, "Delaying I2C init for 250ms due to cold boot");
|
||||||
delay(250);
|
delay(250);
|
||||||
}
|
}
|
||||||
// FRAM (e.g. MB85RC256V)
|
// FRAM (e.g. MB85RC256V)
|
||||||
@@ -99,11 +101,88 @@ void hardwareInit(GwApi *api)
|
|||||||
// Boot counter
|
// Boot counter
|
||||||
uint8_t framcounter = fram.read(0x0000);
|
uint8_t framcounter = fram.read(0x0000);
|
||||||
fram.write(0x0000, framcounter+1);
|
fram.write(0x0000, framcounter+1);
|
||||||
api->getLogger()->logDebug(GwLog::LOG,"FRAM detected: 0x%04x/0x%04x (counter=%d)", manufacturerID, productID, framcounter);
|
logger->logDebug(GwLog::LOG, "FRAM detected: 0x%04x/0x%04x (counter=%d)", manufacturerID, productID, framcounter);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
hasFRAM = false;
|
hasFRAM = false;
|
||||||
api->getLogger()->logDebug(GwLog::LOG,"NO FRAM detected");
|
logger->logDebug(GwLog::LOG, "NO FRAM detected");
|
||||||
|
}
|
||||||
|
// SD Card
|
||||||
|
hasSDCard = false;
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
if (config->getBool(config->useSDCard)) {
|
||||||
|
esp_err_t ret;
|
||||||
|
sdmmc_host_t host = SDSPI_HOST_DEFAULT();
|
||||||
|
host.slot = SPI3_HOST;
|
||||||
|
logger->logDebug(GwLog::DEBUG, "SDSPI_HOST: max_freq_khz=%d" , host.max_freq_khz);
|
||||||
|
spi_bus_config_t bus_cfg = {
|
||||||
|
.mosi_io_num = SD_SPI_MOSI,
|
||||||
|
.miso_io_num = SD_SPI_MISO,
|
||||||
|
.sclk_io_num = SD_SPI_CLK,
|
||||||
|
.quadwp_io_num = -1,
|
||||||
|
.quadhd_io_num = -1,
|
||||||
|
.max_transfer_sz = 4000,
|
||||||
|
};
|
||||||
|
ret = spi_bus_initialize((spi_host_device_t) host.slot, &bus_cfg, SDSPI_DEFAULT_DMA);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
logger->logDebug(GwLog::ERROR, "Failed to initialize SPI bus for SD card");
|
||||||
|
} else {
|
||||||
|
sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
|
||||||
|
slot_config.gpio_cs = SD_SPI_CS;
|
||||||
|
slot_config.host_id = (spi_host_device_t) host.slot;
|
||||||
|
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
|
||||||
|
.format_if_mount_failed = false,
|
||||||
|
.max_files = 5,
|
||||||
|
.allocation_unit_size = 16 * 1024
|
||||||
|
};
|
||||||
|
ret = esp_vfs_fat_sdspi_mount(MOUNT_POINT, &host, &slot_config, &mount_config, &sdcard);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
if (ret == ESP_FAIL) {
|
||||||
|
logger->logDebug(GwLog::ERROR, "Failed to mount SD card filesystem");
|
||||||
|
} else {
|
||||||
|
// ret == 263 could be not powered up yet
|
||||||
|
logger->logDebug(GwLog::ERROR, "Failed to initialize SD card (error #%d)", ret);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger->logDebug(GwLog::LOG, "SD card filesystem mounted at '%s'", MOUNT_POINT);
|
||||||
|
hasSDCard = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasSDCard) {
|
||||||
|
// read some stats
|
||||||
|
String features = "";
|
||||||
|
if (sdcard->is_mem) features += "MEM "; // Memory card
|
||||||
|
if (sdcard->is_sdio) features += "IO "; // IO Card
|
||||||
|
if (sdcard->is_mmc) features += "MMC "; // MMC Card
|
||||||
|
if (sdcard->is_ddr) features += "DDR ";
|
||||||
|
// if (sdcard->is_uhs1) features += "UHS-1 ";
|
||||||
|
// ext_csd. Extended information
|
||||||
|
// uint8_t rev, uint8_t power_class
|
||||||
|
logger->logDebug(GwLog::LOG, "SD card features: %s", features);
|
||||||
|
logger->logDebug(GwLog::LOG, "SD card size: %lluMB", ((uint64_t) sdcard->csd.capacity) * sdcard->csd.sector_size / (1024 * 1024));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void powerInit(String powermode) {
|
||||||
|
// Max Power | Only 5.0V | Min Power
|
||||||
|
if (powermode == "Max Power" || powermode == "Only 5.0V") {
|
||||||
|
#ifdef HARDWARE_V21
|
||||||
|
setPortPin(OBP_POWER_50, true); // Power on 5.0V rail
|
||||||
|
#endif
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
setPortPin(OBP_POWER_EPD, true);// Power on ePaper display
|
||||||
|
setPortPin(OBP_POWER_SD, true); // Power on SD card
|
||||||
|
#endif
|
||||||
|
} else { // Min Power
|
||||||
|
#ifdef HARDWARE_V21
|
||||||
|
setPortPin(OBP_POWER_50, false); // Power off 5.0V rail
|
||||||
|
#endif
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
setPortPin(OBP_POWER_EPD, false);// Power off ePaper display
|
||||||
|
setPortPin(OBP_POWER_SD, false); // Power off SD card
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,17 +213,17 @@ void deepSleep(CommonData &common){
|
|||||||
setFlashLED(false); // Flash LED Off
|
setFlashLED(false); // Flash LED Off
|
||||||
buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms
|
buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms
|
||||||
// Shutdown EInk display
|
// Shutdown EInk display
|
||||||
getdisplay().setFullWindow(); // Set full Refresh
|
epd->setFullWindow(); // Set full Refresh
|
||||||
getdisplay().fillScreen(common.bgcolor); // Clear screen
|
epd->fillScreen(common.bgcolor); // Clear screen
|
||||||
getdisplay().setTextColor(common.fgcolor);
|
epd->setTextColor(common.fgcolor);
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(85, 150);
|
epd->setCursor(85, 150);
|
||||||
getdisplay().print("Sleep Mode");
|
epd->print("Sleep Mode");
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(65, 175);
|
epd->setCursor(65, 175);
|
||||||
getdisplay().print("To wake up press key and wait 5s");
|
epd->print("To wake up press key and wait 5s");
|
||||||
getdisplay().nextPage(); // Update display contents
|
epd->nextPage(); // Update display contents
|
||||||
getdisplay().powerOff(); // Display power off
|
epd->powerOff(); // Display power off
|
||||||
setPortPin(OBP_POWER_50, false); // Power off ePaper display
|
setPortPin(OBP_POWER_50, false); // Power off ePaper display
|
||||||
// Stop system
|
// Stop system
|
||||||
esp_deep_sleep_start(); // Deep Sleep with weakup via touch pin
|
esp_deep_sleep_start(); // Deep Sleep with weakup via touch pin
|
||||||
@@ -158,18 +237,18 @@ void deepSleep(CommonData &common){
|
|||||||
setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off
|
setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off
|
||||||
setFlashLED(false); // Flash LED Off
|
setFlashLED(false); // Flash LED Off
|
||||||
// Shutdown EInk display
|
// Shutdown EInk display
|
||||||
getdisplay().setFullWindow(); // Set full Refresh
|
epd->setFullWindow(); // Set full Refresh
|
||||||
//getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
//epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
getdisplay().fillScreen(common.bgcolor); // Clear screen
|
epd->fillScreen(common.bgcolor); // Clear screen
|
||||||
getdisplay().setTextColor(common.fgcolor);
|
epd->setTextColor(common.fgcolor);
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(85, 150);
|
epd->setCursor(85, 150);
|
||||||
getdisplay().print("Sleep Mode");
|
epd->print("Sleep Mode");
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(65, 175);
|
epd->setCursor(65, 175);
|
||||||
getdisplay().print("To wake up press wheel and wait 5s");
|
epd->print("To wake up press wheel and wait 5s");
|
||||||
getdisplay().nextPage(); // Partial update
|
epd->nextPage(); // Partial update
|
||||||
getdisplay().powerOff(); // Display power off
|
epd->powerOff(); // Display power off
|
||||||
setPortPin(OBP_POWER_EPD, false); // Power off ePaper display
|
setPortPin(OBP_POWER_EPD, false); // Power off ePaper display
|
||||||
setPortPin(OBP_POWER_SD, false); // Power off SD card
|
setPortPin(OBP_POWER_SD, false); // Power off SD card
|
||||||
// Stop system
|
// Stop system
|
||||||
@@ -268,36 +347,29 @@ void setBuzzerPower(uint power){
|
|||||||
buzzerpower = power;
|
buzzerpower = power;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete xdr prefix from string
|
// Delete xdr prefix from string and optional limit length
|
||||||
String xdrDelete(String input){
|
String xdrDelete(String input, uint8_t maxlen) {
|
||||||
if (input.substring(0, 3) == "xdr") {
|
if (input.substring(0, 3) == "xdr") {
|
||||||
input = input.substring(3, input.length());
|
input = input.substring(3, input.length());
|
||||||
}
|
}
|
||||||
|
if (maxlen > 0) {
|
||||||
|
return input.substring(0, maxlen);
|
||||||
|
}
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
Point rotatePoint(const Point& origin, const Point& p, double angle) {
|
|
||||||
// rotate poind around origin by degrees
|
|
||||||
Point rotated;
|
|
||||||
double phi = angle * M_PI / 180.0;
|
|
||||||
double dx = p.x - origin.x;
|
|
||||||
double dy = p.y - origin.y;
|
|
||||||
rotated.x = origin.x + cos(phi) * dx - sin(phi) * dy;
|
|
||||||
rotated.y = origin.y + sin(phi) * dx + cos(phi) * dy;
|
|
||||||
return rotated;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Point> rotatePoints(const Point& origin, const std::vector<Point>& pts, double angle) {
|
|
||||||
std::vector<Point> rotatedPoints;
|
|
||||||
for (const auto& p : pts) {
|
|
||||||
rotatedPoints.push_back(rotatePoint(origin, p, angle));
|
|
||||||
}
|
|
||||||
return rotatedPoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fillPoly4(const std::vector<Point>& p4, uint16_t color) {
|
void fillPoly4(const std::vector<Point>& p4, uint16_t color) {
|
||||||
getdisplay().fillTriangle(p4[0].x, p4[0].y, p4[1].x, p4[1].y, p4[2].x, p4[2].y, color);
|
epd->fillTriangle(p4[0].x, p4[0].y, p4[1].x, p4[1].y, p4[2].x, p4[2].y, color);
|
||||||
getdisplay().fillTriangle(p4[0].x, p4[0].y, p4[2].x, p4[2].y, p4[3].x, p4[3].y, color);
|
epd->fillTriangle(p4[0].x, p4[0].y, p4[2].x, p4[2].y, p4[3].x, p4[3].y, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawPoly(const std::vector<Point>& points, uint16_t color) {
|
||||||
|
size_t polysize = points.size();
|
||||||
|
for (size_t i = 0; i < polysize - 1; i++) {
|
||||||
|
epd->drawLine(points[i].x, points[i].y, points[i+1].x, points[i+1].y, color);
|
||||||
|
}
|
||||||
|
// close path
|
||||||
|
epd->drawLine(points[polysize-1].x, points[polysize-1].y, points[0].x, points[0].y, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split string into words, whitespace separated
|
// Split string into words, whitespace separated
|
||||||
@@ -347,34 +419,51 @@ std::vector<String> wordwrap(String &line, uint16_t maxwidth) {
|
|||||||
void drawTextCenter(int16_t cx, int16_t cy, String text) {
|
void drawTextCenter(int16_t cx, int16_t cy, String text) {
|
||||||
int16_t x1, y1;
|
int16_t x1, y1;
|
||||||
uint16_t w, h;
|
uint16_t w, h;
|
||||||
getdisplay().getTextBounds(text, 0, 150, &x1, &y1, &w, &h);
|
epd->getTextBounds(text, 0, 150, &x1, &y1, &w, &h);
|
||||||
getdisplay().setCursor(cx - w / 2, cy + h / 2);
|
epd->setCursor(cx - w / 2, cy + h / 2);
|
||||||
getdisplay().print(text);
|
epd->print(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw right aligned text
|
// Draw right aligned text
|
||||||
void drawTextRalign(int16_t x, int16_t y, String text) {
|
void drawTextRalign(int16_t x, int16_t y, String text) {
|
||||||
int16_t x1, y1;
|
int16_t x1, y1;
|
||||||
uint16_t w, h;
|
uint16_t w, h;
|
||||||
getdisplay().getTextBounds(text, 0, 150, &x1, &y1, &w, &h);
|
epd->getTextBounds(text, 0, 150, &x1, &y1, &w, &h);
|
||||||
getdisplay().setCursor(x - w, y);
|
epd->setCursor(x - w, y);
|
||||||
getdisplay().print(text);
|
epd->print(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw text inside box, normal or inverted
|
||||||
|
void drawTextBoxed(Rect box, String text, uint16_t fg, uint16_t bg, bool inverted, bool border) {
|
||||||
|
if (inverted) {
|
||||||
|
epd->fillRect(box.x, box.y, box.w, box.h, fg);
|
||||||
|
epd->setTextColor(bg);
|
||||||
|
} else {
|
||||||
|
if (border) {
|
||||||
|
epd->fillRect(box.x + 1, box.y + 1, box.w - 2, box.h - 2, bg);
|
||||||
|
epd->drawRect(box.x, box.y, box.w, box.h, fg);
|
||||||
|
}
|
||||||
|
epd->setTextColor(fg);
|
||||||
|
}
|
||||||
|
uint16_t border_offset = box.h / 4; // 25% of box height
|
||||||
|
epd->setCursor(box.x + border_offset, box.y + box.h - border_offset);
|
||||||
|
epd->print(text);
|
||||||
|
epd->setTextColor(fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show a triangle for trend direction high (x, y is the left edge)
|
// Show a triangle for trend direction high (x, y is the left edge)
|
||||||
void displayTrendHigh(int16_t x, int16_t y, uint16_t size, uint16_t color){
|
void displayTrendHigh(int16_t x, int16_t y, uint16_t size, uint16_t color){
|
||||||
getdisplay().fillTriangle(x, y, x+size*2, y, x+size, y-size*2, color);
|
epd->fillTriangle(x, y, x+size*2, y, x+size, y-size*2, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show a triangle for trend direction low (x, y is the left edge)
|
// Show a triangle for trend direction low (x, y is the left edge)
|
||||||
void displayTrendLow(int16_t x, int16_t y, uint16_t size, uint16_t color){
|
void displayTrendLow(int16_t x, int16_t y, uint16_t size, uint16_t color){
|
||||||
getdisplay().fillTriangle(x, y, x+size*2, y, x+size, y+size*2, color);
|
epd->fillTriangle(x, y, x+size*2, y, x+size, y+size*2, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show header informations
|
// Show header informations
|
||||||
void displayHeader(CommonData &commonData, GwApi::BoatValue *date, GwApi::BoatValue *time, GwApi::BoatValue *hdop){
|
void displayHeader(CommonData &commonData, bool symbolmode, GwApi::BoatValue *date, GwApi::BoatValue *time, GwApi::BoatValue *hdop){
|
||||||
|
|
||||||
static bool heartbeat = false;
|
|
||||||
static unsigned long usbRxOld = 0;
|
static unsigned long usbRxOld = 0;
|
||||||
static unsigned long usbTxOld = 0;
|
static unsigned long usbTxOld = 0;
|
||||||
static unsigned long serRxOld = 0;
|
static unsigned long serRxOld = 0;
|
||||||
@@ -386,31 +475,65 @@ void displayHeader(CommonData &commonData, GwApi::BoatValue *date, GwApi::BoatVa
|
|||||||
static unsigned long n2kRxOld = 0;
|
static unsigned long n2kRxOld = 0;
|
||||||
static unsigned long n2kTxOld = 0;
|
static unsigned long n2kTxOld = 0;
|
||||||
|
|
||||||
|
uint16_t symbol_x = 2;
|
||||||
|
static const uint16_t symbol_offset = 20;
|
||||||
|
|
||||||
|
// TODO invert and get rid of the if
|
||||||
if(commonData.config->getBool(commonData.config->statusLine) == true){
|
if(commonData.config->getBool(commonData.config->statusLine) == true){
|
||||||
|
|
||||||
// Show status info
|
// Show status info
|
||||||
getdisplay().setTextColor(commonData.fgcolor);
|
epd->setTextColor(commonData.fgcolor);
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(0, 15);
|
epd->setCursor(0, 15);
|
||||||
if (commonData.status.wifiApOn) {
|
if (commonData.status.wifiApOn) {
|
||||||
getdisplay().print(" AP ");
|
if (symbolmode) {
|
||||||
|
epd->drawXBitmap(symbol_x, 1, iconmap["AP"], icon_width, icon_height, commonData.fgcolor);
|
||||||
|
symbol_x += symbol_offset;
|
||||||
|
} else {
|
||||||
|
epd->print(" AP ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// If receive new telegram data then display bus name
|
// If receive new telegram data then display bus name
|
||||||
if(commonData.status.tcpClRx != tcpClRxOld || commonData.status.tcpClTx != tcpClTxOld || commonData.status.tcpSerRx != tcpSerRxOld || commonData.status.tcpSerTx != tcpSerTxOld){
|
if(commonData.status.tcpClRx != tcpClRxOld || commonData.status.tcpClTx != tcpClTxOld || commonData.status.tcpSerRx != tcpSerRxOld || commonData.status.tcpSerTx != tcpSerTxOld){
|
||||||
getdisplay().print("TCP ");
|
if (symbolmode) {
|
||||||
|
epd->drawXBitmap(symbol_x, 1, iconmap["TCP"], icon_width, icon_height, commonData.fgcolor);
|
||||||
|
symbol_x += symbol_offset;
|
||||||
|
} else {
|
||||||
|
epd->print("TCP ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(commonData.status.n2kRx != n2kRxOld || commonData.status.n2kTx != n2kTxOld){
|
if(commonData.status.n2kRx != n2kRxOld || commonData.status.n2kTx != n2kTxOld){
|
||||||
getdisplay().print("N2K ");
|
if (symbolmode) {
|
||||||
|
epd->drawXBitmap(symbol_x, 1, iconmap["N2K"], icon_width, icon_height, commonData.fgcolor);
|
||||||
|
symbol_x += symbol_offset;
|
||||||
|
} else {
|
||||||
|
epd->print("N2K ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(commonData.status.serRx != serRxOld || commonData.status.serTx != serTxOld){
|
if(commonData.status.serRx != serRxOld || commonData.status.serTx != serTxOld){
|
||||||
getdisplay().print("183 ");
|
if (symbolmode) {
|
||||||
|
epd->drawXBitmap(symbol_x, 1, iconmap["0183"], icon_width, icon_height, commonData.fgcolor);
|
||||||
|
symbol_x += symbol_offset;
|
||||||
|
} else {
|
||||||
|
epd->print("183 ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(commonData.status.usbRx != usbRxOld || commonData.status.usbTx != usbTxOld){
|
if(commonData.status.usbRx != usbRxOld || commonData.status.usbTx != usbTxOld){
|
||||||
getdisplay().print("USB ");
|
if (symbolmode) {
|
||||||
|
epd->drawXBitmap(symbol_x, 1, iconmap["USB"], icon_width, icon_height, commonData.fgcolor);
|
||||||
|
symbol_x += symbol_offset;
|
||||||
|
} else {
|
||||||
|
epd->print("USB ");
|
||||||
}
|
}
|
||||||
double gpshdop = formatValue(hdop, commonData).value;
|
}
|
||||||
|
double gpshdop = commonData.fmt->formatValue(hdop, commonData).value;
|
||||||
if(commonData.config->getString(commonData.config->useGPS) != "off" && gpshdop <= commonData.config->getInt(commonData.config->hdopAccuracy) && hdop->valid == true){
|
if(commonData.config->getString(commonData.config->useGPS) != "off" && gpshdop <= commonData.config->getInt(commonData.config->hdopAccuracy) && hdop->valid == true){
|
||||||
getdisplay().print("GPS");
|
if (symbolmode) {
|
||||||
|
epd->drawXBitmap(symbol_x, 1, iconmap["GPS"], icon_width, icon_height, commonData.fgcolor);
|
||||||
|
symbol_x += symbol_offset;
|
||||||
|
} else {
|
||||||
|
epd->print("GPS");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Save old telegram counter
|
// Save old telegram counter
|
||||||
tcpClRxOld = commonData.status.tcpClRx;
|
tcpClRxOld = commonData.status.tcpClRx;
|
||||||
@@ -427,26 +550,26 @@ void displayHeader(CommonData &commonData, GwApi::BoatValue *date, GwApi::BoatVa
|
|||||||
#ifdef HARDWARE_V21
|
#ifdef HARDWARE_V21
|
||||||
// Display key lock status
|
// Display key lock status
|
||||||
if (commonData.keylock) {
|
if (commonData.keylock) {
|
||||||
getdisplay().drawXBitmap(170, 1, lock_bits, icon_width, icon_height, commonData.fgcolor);
|
epd->drawXBitmap(170, 1, lock_bits, icon_width, icon_height, commonData.fgcolor);
|
||||||
} else {
|
} else {
|
||||||
getdisplay().drawXBitmap(166, 1, swipe_bits, swipe_width, swipe_height, commonData.fgcolor);
|
epd->drawXBitmap(166, 1, swipe_bits, swipe_width, swipe_height, commonData.fgcolor);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef LIPO_ACCU_1200
|
#ifdef LIPO_ACCU_1200
|
||||||
if (commonData.data.BatteryChargeStatus == 1) {
|
if (commonData.data.BatteryChargeStatus == 1) {
|
||||||
getdisplay().drawXBitmap(170, 1, battery_loading_bits, battery_width, battery_height, commonData.fgcolor);
|
epd->drawXBitmap(170, 1, battery_loading_bits, battery_width, battery_height, commonData.fgcolor);
|
||||||
} else {
|
} else {
|
||||||
#ifdef VOLTAGE_SENSOR
|
#ifdef VOLTAGE_SENSOR
|
||||||
if (commonData.data.batteryLevelLiPo < 10) {
|
if (commonData.data.batteryLevelLiPo < 10) {
|
||||||
getdisplay().drawXBitmap(170, 1, battery_0_bits, battery_width, battery_height, commonData.fgcolor);
|
epd->drawXBitmap(170, 1, battery_0_bits, battery_width, battery_height, commonData.fgcolor);
|
||||||
} else if (commonData.data.batteryLevelLiPo < 25) {
|
} else if (commonData.data.batteryLevelLiPo < 25) {
|
||||||
getdisplay().drawXBitmap(170, 1, battery_25_bits, battery_width, battery_height, commonData.fgcolor);
|
epd->drawXBitmap(170, 1, battery_25_bits, battery_width, battery_height, commonData.fgcolor);
|
||||||
} else if (commonData.data.batteryLevelLiPo < 50) {
|
} else if (commonData.data.batteryLevelLiPo < 50) {
|
||||||
getdisplay().drawXBitmap(170, 1, battery_50_bits, battery_width, battery_height, commonData.fgcolor);
|
epd->drawXBitmap(170, 1, battery_50_bits, battery_width, battery_height, commonData.fgcolor);
|
||||||
} else if (commonData.data.batteryLevelLiPo < 75) {
|
} else if (commonData.data.batteryLevelLiPo < 75) {
|
||||||
getdisplay().drawXBitmap(170, 1, battery_75_bits, battery_width, battery_height, commonData.fgcolor);
|
epd->drawXBitmap(170, 1, battery_75_bits, battery_width, battery_height, commonData.fgcolor);
|
||||||
} else {
|
} else {
|
||||||
getdisplay().drawXBitmap(170, 1, battery_100_bits, battery_width, battery_height, commonData.fgcolor);
|
epd->drawXBitmap(170, 1, battery_100_bits, battery_width, battery_height, commonData.fgcolor);
|
||||||
}
|
}
|
||||||
#endif // VOLTAGE_SENSOR
|
#endif // VOLTAGE_SENSOR
|
||||||
}
|
}
|
||||||
@@ -454,33 +577,33 @@ void displayHeader(CommonData &commonData, GwApi::BoatValue *date, GwApi::BoatVa
|
|||||||
|
|
||||||
// Heartbeat as page number
|
// Heartbeat as page number
|
||||||
if (heartbeat) {
|
if (heartbeat) {
|
||||||
getdisplay().setTextColor(commonData.bgcolor);
|
epd->setTextColor(commonData.bgcolor);
|
||||||
getdisplay().fillRect(201, 0, 23, 19, commonData.fgcolor);
|
epd->fillRect(201, 0, 23, 19, commonData.fgcolor);
|
||||||
} else {
|
} else {
|
||||||
getdisplay().setTextColor(commonData.fgcolor);
|
epd->setTextColor(commonData.fgcolor);
|
||||||
getdisplay().drawRect(201, 0, 23, 19, commonData.fgcolor);
|
epd->drawRect(201, 0, 23, 19, commonData.fgcolor);
|
||||||
}
|
}
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
drawTextCenter(211, 9, String(commonData.data.actpage));
|
drawTextCenter(211, 9, String(commonData.data.actpage));
|
||||||
heartbeat = !heartbeat;
|
heartbeat = !heartbeat;
|
||||||
|
|
||||||
// Date and time
|
// Date and time
|
||||||
String fmttype = commonData.config->getString(commonData.config->dateFormat);
|
fmtDate fmttype = commonData.fmt->getDateFormat(commonData.config->getString(commonData.config->dateFormat));
|
||||||
String timesource = commonData.config->getString(commonData.config->timeSource);
|
String timesource = commonData.config->getString(commonData.config->timeSource);
|
||||||
double tz = commonData.config->getString(commonData.config->timeZone).toDouble();
|
double tz = commonData.config->getString(commonData.config->timeZone).toDouble();
|
||||||
getdisplay().setTextColor(commonData.fgcolor);
|
epd->setTextColor(commonData.fgcolor);
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(230, 15);
|
epd->setCursor(230, 15);
|
||||||
if (timesource == "RTC" or timesource == "iRTC") {
|
if (timesource == "RTC" or timesource == "iRTC") {
|
||||||
// TODO take DST into account
|
// TODO take DST into account
|
||||||
if (commonData.data.rtcValid) {
|
if (commonData.data.rtcValid) {
|
||||||
time_t tv = mktime(&commonData.data.rtcTime) + (int)(tz * 3600);
|
time_t tv = mktime(&commonData.data.rtcTime) + (int)(tz * 3600);
|
||||||
struct tm *local_tm = localtime(&tv);
|
struct tm *local_tm = localtime(&tv);
|
||||||
getdisplay().print(formatTime('m', local_tm->tm_hour, local_tm->tm_min, 0));
|
epd->print(formatTime(fmtTime::MMHH, local_tm->tm_hour, local_tm->tm_min, 0));
|
||||||
getdisplay().print(" ");
|
epd->print(" ");
|
||||||
getdisplay().print(formatDate(fmttype, local_tm->tm_year + 1900, local_tm->tm_mon + 1, local_tm->tm_mday));
|
epd->print(formatDate(fmttype, local_tm->tm_year + 1900, local_tm->tm_mon + 1, local_tm->tm_mday));
|
||||||
getdisplay().print(" ");
|
epd->print(" ");
|
||||||
getdisplay().print(tz == 0 ? "UTC" : "LOT");
|
epd->print(tz == 0 ? "UTC" : "LOT");
|
||||||
} else {
|
} else {
|
||||||
drawTextRalign(396, 15, "RTC invalid");
|
drawTextRalign(396, 15, "RTC invalid");
|
||||||
}
|
}
|
||||||
@@ -488,18 +611,18 @@ void displayHeader(CommonData &commonData, GwApi::BoatValue *date, GwApi::BoatVa
|
|||||||
else if (timesource == "GPS") {
|
else if (timesource == "GPS") {
|
||||||
// Show date and time if date present
|
// Show date and time if date present
|
||||||
if(date->valid == true){
|
if(date->valid == true){
|
||||||
String acttime = formatValue(time, commonData).svalue;
|
String acttime = commonData.fmt->formatValue(time, commonData).svalue;
|
||||||
acttime = acttime.substring(0, 5);
|
acttime = acttime.substring(0, 5);
|
||||||
String actdate = formatValue(date, commonData).svalue;
|
String actdate = commonData.fmt->formatValue(date, commonData).svalue;
|
||||||
getdisplay().print(acttime);
|
epd->print(acttime);
|
||||||
getdisplay().print(" ");
|
epd->print(" ");
|
||||||
getdisplay().print(actdate);
|
epd->print(actdate);
|
||||||
getdisplay().print(" ");
|
epd->print(" ");
|
||||||
getdisplay().print(tz == 0 ? "UTC" : "LOT");
|
epd->print(tz == 0 ? "UTC" : "LOT");
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if(commonData.config->getBool(commonData.config->useSimuData) == true){
|
if(commonData.config->getBool(commonData.config->useSimuData) == true){
|
||||||
getdisplay().print("12:00 01.01.2024 LOT");
|
epd->print("12:00 01.01.2024 LOT");
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
drawTextRalign(396, 15, "No GPS data");
|
drawTextRalign(396, 15, "No GPS data");
|
||||||
@@ -507,15 +630,15 @@ void displayHeader(CommonData &commonData, GwApi::BoatValue *date, GwApi::BoatVa
|
|||||||
}
|
}
|
||||||
} // timesource == "GPS"
|
} // timesource == "GPS"
|
||||||
else {
|
else {
|
||||||
getdisplay().print("No time source");
|
epd->print("No time source");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void displayFooter(CommonData &commonData) {
|
void displayFooter(CommonData &commonData) {
|
||||||
|
|
||||||
getdisplay().setFont(&Atari16px);
|
epd->setFont(&Atari16px);
|
||||||
getdisplay().setTextColor(commonData.fgcolor);
|
epd->setTextColor(commonData.fgcolor);
|
||||||
|
|
||||||
#ifdef HARDWARE_V21
|
#ifdef HARDWARE_V21
|
||||||
// Frame around key icon area
|
// Frame around key icon area
|
||||||
@@ -524,14 +647,14 @@ void displayFooter(CommonData &commonData) {
|
|||||||
const uint16_t top = 280;
|
const uint16_t top = 280;
|
||||||
const uint16_t bottom = 299;
|
const uint16_t bottom = 299;
|
||||||
// horizontal stub lines
|
// horizontal stub lines
|
||||||
getdisplay().drawLine(commonData.keydata[0].x, top, commonData.keydata[0].x+10, top, commonData.fgcolor);
|
epd->drawLine(commonData.keydata[0].x, top, commonData.keydata[0].x+10, top, commonData.fgcolor);
|
||||||
for (int i = 1; i <= 5; i++) {
|
for (int i = 1; i <= 5; i++) {
|
||||||
getdisplay().drawLine(commonData.keydata[i].x-10, top, commonData.keydata[i].x+10, top, commonData.fgcolor);
|
epd->drawLine(commonData.keydata[i].x-10, top, commonData.keydata[i].x+10, top, commonData.fgcolor);
|
||||||
}
|
}
|
||||||
getdisplay().drawLine(commonData.keydata[5].x + commonData.keydata[5].w - 10, top, commonData.keydata[5].x + commonData.keydata[5].w + 1, top, commonData.fgcolor);
|
epd->drawLine(commonData.keydata[5].x + commonData.keydata[5].w - 10, top, commonData.keydata[5].x + commonData.keydata[5].w + 1, top, commonData.fgcolor);
|
||||||
// vertical key separators
|
// vertical key separators
|
||||||
for (int i = 0; i <= 4; i++) {
|
for (int i = 0; i <= 4; i++) {
|
||||||
getdisplay().drawLine(commonData.keydata[i].x + commonData.keydata[i].w, top, commonData.keydata[i].x + commonData.keydata[i].w, bottom, commonData.fgcolor);
|
epd->drawLine(commonData.keydata[i].x + commonData.keydata[i].w, top, commonData.keydata[i].x + commonData.keydata[i].w, bottom, commonData.fgcolor);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
uint16_t x, y;
|
uint16_t x, y;
|
||||||
@@ -542,7 +665,7 @@ void displayFooter(CommonData &commonData) {
|
|||||||
if (iconmap.find(icon_name) != iconmap.end()) {
|
if (iconmap.find(icon_name) != iconmap.end()) {
|
||||||
x = commonData.keydata[i].x + (commonData.keydata[i].w - icon_width) / 2;
|
x = commonData.keydata[i].x + (commonData.keydata[i].w - icon_width) / 2;
|
||||||
y = commonData.keydata[i].y + (commonData.keydata[i].h - icon_height) / 2;
|
y = commonData.keydata[i].y + (commonData.keydata[i].h - icon_height) / 2;
|
||||||
getdisplay().drawXBitmap(x, y, iconmap[icon_name], icon_width, icon_height, commonData.fgcolor);
|
epd->drawXBitmap(x, y, iconmap[icon_name], icon_width, icon_height, commonData.fgcolor);
|
||||||
} else {
|
} else {
|
||||||
// icon is missing, use name instead
|
// icon is missing, use name instead
|
||||||
x = commonData.keydata[i].x + commonData.keydata[i].w / 2;
|
x = commonData.keydata[i].x + commonData.keydata[i].w / 2;
|
||||||
@@ -557,8 +680,8 @@ void displayFooter(CommonData &commonData) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
getdisplay().setCursor(65, 295);
|
epd->setCursor(65, 295);
|
||||||
getdisplay().print("Press 1 and 6 fast to unlock keys");
|
epd->print("Press 1 and 6 fast to unlock keys");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef BOARD_OBP40S3
|
#ifdef BOARD_OBP40S3
|
||||||
@@ -569,21 +692,21 @@ void displayFooter(CommonData &commonData) {
|
|||||||
uint16_t x0 = (GxEPD_WIDTH - w) / 2 + r * 2;
|
uint16_t x0 = (GxEPD_WIDTH - w) / 2 + r * 2;
|
||||||
for (int i = 0; i < commonData.data.maxpage; i++) {
|
for (int i = 0; i < commonData.data.maxpage; i++) {
|
||||||
if (i == (commonData.data.actpage - 1)) {
|
if (i == (commonData.data.actpage - 1)) {
|
||||||
getdisplay().fillCircle(x0 + i * (r * 2 + space), 290, r, commonData.fgcolor);
|
epd->fillCircle(x0 + i * (r * 2 + space), 290, r, commonData.fgcolor);
|
||||||
} else {
|
} else {
|
||||||
getdisplay().drawCircle(x0 + i * (r * 2 + space), 290, r, commonData.fgcolor);
|
epd->drawCircle(x0 + i * (r * 2 + space), 290, r, commonData.fgcolor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// key indicators
|
// key indicators
|
||||||
// left side = top key "menu"
|
// left side = top key "menu"
|
||||||
getdisplay().drawLine(0, 280, 10, 280, commonData.fgcolor);
|
epd->drawLine(0, 280, 10, 280, commonData.fgcolor);
|
||||||
getdisplay().drawLine(55, 280, 65, 280, commonData.fgcolor);
|
epd->drawLine(55, 280, 65, 280, commonData.fgcolor);
|
||||||
getdisplay().drawLine(65, 280, 65, 299, commonData.fgcolor);
|
epd->drawLine(65, 280, 65, 299, commonData.fgcolor);
|
||||||
drawTextCenter(33, 291, commonData.keydata[0].label);
|
drawTextCenter(33, 291, commonData.keydata[0].label);
|
||||||
// right side = bottom key "exit"
|
// right side = bottom key "exit"
|
||||||
getdisplay().drawLine(390, 280, 399, 280, commonData.fgcolor);
|
epd->drawLine(390, 280, 399, 280, commonData.fgcolor);
|
||||||
getdisplay().drawLine(335, 280, 345, 280, commonData.fgcolor);
|
epd->drawLine(335, 280, 345, 280, commonData.fgcolor);
|
||||||
getdisplay().drawLine(335, 280, 335, 399, commonData.fgcolor);
|
epd->drawLine(335, 280, 335, 399, commonData.fgcolor);
|
||||||
drawTextCenter(366, 291, commonData.keydata[1].label);
|
drawTextCenter(366, 291, commonData.keydata[1].label);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -596,31 +719,31 @@ void displayAlarm(CommonData &commonData) {
|
|||||||
const uint16_t w = 300;
|
const uint16_t w = 300;
|
||||||
const uint16_t h = 150;
|
const uint16_t h = 150;
|
||||||
|
|
||||||
getdisplay().setFont(&Atari16px);
|
epd->setFont(&Atari16px);
|
||||||
getdisplay().setTextColor(commonData.fgcolor);
|
epd->setTextColor(commonData.fgcolor);
|
||||||
|
|
||||||
// overlay
|
// overlay
|
||||||
getdisplay().drawRect(x, y, w, h, commonData.fgcolor);
|
epd->drawRect(x, y, w, h, commonData.fgcolor);
|
||||||
getdisplay().fillRect(x + 1, y + 1, w - 1, h - 1, commonData.bgcolor);
|
epd->fillRect(x + 1, y + 1, w - 1, h - 1, commonData.bgcolor);
|
||||||
getdisplay().drawRect(x + 3, y + 3, w - 5, h - 5, commonData.fgcolor);
|
epd->drawRect(x + 3, y + 3, w - 5, h - 5, commonData.fgcolor);
|
||||||
|
|
||||||
// exclamation icon in left top corner
|
// exclamation icon in left top corner
|
||||||
getdisplay().drawXBitmap(x + 16, y + 16, exclamation_bits, exclamation_width, exclamation_height, commonData.fgcolor);
|
epd->drawXBitmap(x + 16, y + 16, exclamation_bits, exclamation_width, exclamation_height, commonData.fgcolor);
|
||||||
|
|
||||||
// title
|
// title
|
||||||
getdisplay().setCursor(x + 64, y + 30);
|
epd->setCursor(x + 64, y + 30);
|
||||||
getdisplay().print("A L A R M");
|
epd->print("A L A R M");
|
||||||
getdisplay().setCursor(x + 64, y + 48);
|
epd->setCursor(x + 64, y + 48);
|
||||||
getdisplay().print("#" + commonData.alarm.id);
|
epd->print("#" + commonData.alarm.id);
|
||||||
getdisplay().print(" from ");
|
epd->print(" from ");
|
||||||
getdisplay().print(commonData.alarm.source);
|
epd->print(commonData.alarm.source);
|
||||||
|
|
||||||
// message, but maximum 4 lines
|
// message, but maximum 4 lines
|
||||||
std::vector<String> lines = wordwrap (commonData.alarm.message, w - 16 - 8 / 8);
|
std::vector<String> lines = wordwrap (commonData.alarm.message, w - 16 - 8 / 8);
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (const auto& l : lines) {
|
for (const auto& l : lines) {
|
||||||
getdisplay().setCursor(x + 16, y + 80 + n);
|
epd->setCursor(x + 16, y + 80 + n);
|
||||||
getdisplay().print(l);
|
epd->print(l);
|
||||||
n += 16;
|
n += 16;
|
||||||
if (n > 64) {
|
if (n > 64) {
|
||||||
break;
|
break;
|
||||||
@@ -713,20 +836,20 @@ void batteryGraphic(uint x, uint y, float percent, int pcolor, int bcolor){
|
|||||||
}
|
}
|
||||||
// Battery corpus 100x80 with fill level
|
// Battery corpus 100x80 with fill level
|
||||||
int level = int((100.0 - percent) * (80-(2*t)) / 100.0);
|
int level = int((100.0 - percent) * (80-(2*t)) / 100.0);
|
||||||
getdisplay().fillRect(xb, yb, 100, 80, pcolor);
|
epd->fillRect(xb, yb, 100, 80, pcolor);
|
||||||
if(percent < 99){
|
if(percent < 99){
|
||||||
getdisplay().fillRect(xb+t, yb+t, 100-(2*t), level, bcolor);
|
epd->fillRect(xb+t, yb+t, 100-(2*t), level, bcolor);
|
||||||
}
|
}
|
||||||
// Plus pol 20x15
|
// Plus pol 20x15
|
||||||
int xp = xb + 20;
|
int xp = xb + 20;
|
||||||
int yp = yb - 15 + t;
|
int yp = yb - 15 + t;
|
||||||
getdisplay().fillRect(xp, yp, 20, 15, pcolor);
|
epd->fillRect(xp, yp, 20, 15, pcolor);
|
||||||
getdisplay().fillRect(xp+t, yp+t, 20-(2*t), 15-(2*t), bcolor);
|
epd->fillRect(xp+t, yp+t, 20-(2*t), 15-(2*t), bcolor);
|
||||||
// Minus pol 20x15
|
// Minus pol 20x15
|
||||||
int xm = xb + 60;
|
int xm = xb + 60;
|
||||||
int ym = yb -15 + t;
|
int ym = yb -15 + t;
|
||||||
getdisplay().fillRect(xm, ym, 20, 15, pcolor);
|
epd->fillRect(xm, ym, 20, 15, pcolor);
|
||||||
getdisplay().fillRect(xm+t, ym+t, 20-(2*t), 15-(2*t), bcolor);
|
epd->fillRect(xm+t, ym+t, 20-(2*t), 15-(2*t), bcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Solar graphic with fill level
|
// Solar graphic with fill level
|
||||||
@@ -738,17 +861,17 @@ void solarGraphic(uint x, uint y, int pcolor, int bcolor){
|
|||||||
int percent = 0;
|
int percent = 0;
|
||||||
// Solar corpus 100x80
|
// Solar corpus 100x80
|
||||||
int level = int((100.0 - percent) * (80-(2*t)) / 100.0);
|
int level = int((100.0 - percent) * (80-(2*t)) / 100.0);
|
||||||
getdisplay().fillRect(xb, yb, 100, 80, pcolor);
|
epd->fillRect(xb, yb, 100, 80, pcolor);
|
||||||
if(percent < 99){
|
if(percent < 99){
|
||||||
getdisplay().fillRect(xb+t, yb+t, 100-(2*t), level, bcolor);
|
epd->fillRect(xb+t, yb+t, 100-(2*t), level, bcolor);
|
||||||
}
|
}
|
||||||
// Draw horizontel lines
|
// Draw horizontel lines
|
||||||
getdisplay().fillRect(xb, yb+28-t, 100, t, pcolor);
|
epd->fillRect(xb, yb+28-t, 100, t, pcolor);
|
||||||
getdisplay().fillRect(xb, yb+54-t, 100, t, pcolor);
|
epd->fillRect(xb, yb+54-t, 100, t, pcolor);
|
||||||
// Draw vertical lines
|
// Draw vertical lines
|
||||||
getdisplay().fillRect(xb+19+t, yb, t, 80, pcolor);
|
epd->fillRect(xb+19+t, yb, t, 80, pcolor);
|
||||||
getdisplay().fillRect(xb+39+2*t, yb, t, 80, pcolor);
|
epd->fillRect(xb+39+2*t, yb, t, 80, pcolor);
|
||||||
getdisplay().fillRect(xb+59+3*t, yb, t, 80, pcolor);
|
epd->fillRect(xb+59+3*t, yb, t, 80, pcolor);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -760,13 +883,13 @@ void generatorGraphic(uint x, uint y, int pcolor, int bcolor){
|
|||||||
int t = 4; // Line thickness
|
int t = 4; // Line thickness
|
||||||
|
|
||||||
// Generator corpus with radius 45
|
// Generator corpus with radius 45
|
||||||
getdisplay().fillCircle(xb, yb, 45, pcolor);
|
epd->fillCircle(xb, yb, 45, pcolor);
|
||||||
getdisplay().fillCircle(xb, yb, 41, bcolor);
|
epd->fillCircle(xb, yb, 41, bcolor);
|
||||||
// Insert G
|
// Insert G
|
||||||
getdisplay().setTextColor(pcolor);
|
epd->setTextColor(pcolor);
|
||||||
getdisplay().setFont(&Ubuntu_Bold32pt8b);
|
epd->setFont(&Ubuntu_Bold32pt8b);
|
||||||
getdisplay().setCursor(xb-22, yb+20);
|
epd->setCursor(xb-22, yb+20);
|
||||||
getdisplay().print("G");
|
epd->print("G");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to handle HTTP image request
|
// Function to handle HTTP image request
|
||||||
@@ -780,7 +903,7 @@ void doImageRequest(GwApi *api, int *pageno, const PageStruct pages[MAX_PAGE_NUM
|
|||||||
|
|
||||||
logger->logDebug(GwLog::LOG,"handle image request [%s]: %s", imgformat, filename);
|
logger->logDebug(GwLog::LOG,"handle image request [%s]: %s", imgformat, filename);
|
||||||
|
|
||||||
uint8_t *fb = getdisplay().getBuffer(); // EPD framebuffer
|
uint8_t *fb = epd->getBuffer(); // EPD framebuffer
|
||||||
std::vector<uint8_t> imageBuffer; // image in webserver transferbuffer
|
std::vector<uint8_t> imageBuffer; // image in webserver transferbuffer
|
||||||
String mimetype;
|
String mimetype;
|
||||||
|
|
||||||
@@ -803,7 +926,7 @@ void doImageRequest(GwApi *api, int *pageno, const PageStruct pages[MAX_PAGE_NUM
|
|||||||
createPBM(fb, &imageBuffer, GxEPD_WIDTH, GxEPD_HEIGHT);
|
createPBM(fb, &imageBuffer, GxEPD_WIDTH, GxEPD_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncWebServerResponse *response = request->beginResponse_P(200, mimetype, (const uint8_t*)imageBuffer.data(), imageBuffer.size());
|
AsyncWebServerResponse *response = request->beginResponse(200, mimetype, (const uint8_t*)imageBuffer.data(), imageBuffer.size());
|
||||||
response->addHeader("Content-Disposition", "inline; filename=" + filename);
|
response->addHeader("Content-Disposition", "inline; filename=" + filename);
|
||||||
request->send(response);
|
request->send(response);
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,21 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#ifndef _OBP60EXTENSIONPORT_H
|
#ifndef _OBP60EXTENSIONPORT_H
|
||||||
#define _OBP60EXTENSIONPORT_H
|
#define _OBP60EXTENSIONPORT_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "OBP60Hardware.h"
|
#include "OBP60Hardware.h"
|
||||||
|
#include "OBP60Formatter.h"
|
||||||
#include "LedSpiTask.h"
|
#include "LedSpiTask.h"
|
||||||
|
#include "Graphics.h"
|
||||||
#include <GxEPD2_BW.h> // E-paper lib V2
|
#include <GxEPD2_BW.h> // E-paper lib V2
|
||||||
#include <Adafruit_FRAM_I2C.h> // I2C FRAM
|
#include <Adafruit_FRAM_I2C.h> // I2C FRAM
|
||||||
|
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
#include "esp_vfs_fat.h"
|
||||||
|
#include "sdmmc_cmd.h"
|
||||||
|
#define MOUNT_POINT "/sdcard"
|
||||||
|
#endif
|
||||||
|
|
||||||
// FRAM address reservations 32kB: 0x0000 - 0x7FFF
|
// FRAM address reservations 32kB: 0x0000 - 0x7FFF
|
||||||
// 0x0000 - 0x03ff: single variables
|
// 0x0000 - 0x03ff: single variables
|
||||||
#define FRAM_PAGE_NO 0x0002
|
#define FRAM_PAGE_NO 0x0002
|
||||||
@@ -15,6 +24,7 @@
|
|||||||
#define FRAM_VOLTAGE_AVG 0x000A
|
#define FRAM_VOLTAGE_AVG 0x000A
|
||||||
#define FRAM_VOLTAGE_TREND 0x000B
|
#define FRAM_VOLTAGE_TREND 0x000B
|
||||||
#define FRAM_VOLTAGE_MODE 0x000C
|
#define FRAM_VOLTAGE_MODE 0x000C
|
||||||
|
// Wind page
|
||||||
#define FRAM_WIND_SIZE 0x000D
|
#define FRAM_WIND_SIZE 0x000D
|
||||||
#define FRAM_WIND_SRC 0x000E
|
#define FRAM_WIND_SRC 0x000E
|
||||||
#define FRAM_WIND_MODE 0x000F
|
#define FRAM_WIND_MODE 0x000F
|
||||||
@@ -24,6 +34,12 @@
|
|||||||
|
|
||||||
extern Adafruit_FRAM_I2C fram;
|
extern Adafruit_FRAM_I2C fram;
|
||||||
extern bool hasFRAM;
|
extern bool hasFRAM;
|
||||||
|
extern bool hasSDCard;
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
extern sdmmc_card_t *sdcard;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern bool heartbeat;
|
||||||
|
|
||||||
// Fonts declarations for display (#includes see OBP60Extensions.cpp)
|
// Fonts declarations for display (#includes see OBP60Extensions.cpp)
|
||||||
extern const GFXfont DSEG7Classic_BoldItalic16pt7b;
|
extern const GFXfont DSEG7Classic_BoldItalic16pt7b;
|
||||||
@@ -39,42 +55,37 @@ extern const GFXfont Ubuntu_Bold16pt8b;
|
|||||||
extern const GFXfont Ubuntu_Bold20pt8b;
|
extern const GFXfont Ubuntu_Bold20pt8b;
|
||||||
extern const GFXfont Ubuntu_Bold32pt8b;
|
extern const GFXfont Ubuntu_Bold32pt8b;
|
||||||
extern const GFXfont Atari16px;
|
extern const GFXfont Atari16px;
|
||||||
|
extern const GFXfont Atari6px;
|
||||||
|
|
||||||
// Global functions
|
// Global functions
|
||||||
#ifdef DISPLAY_GDEW042T2
|
#ifdef DISPLAY_GDEW042T2
|
||||||
GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> & getdisplay();
|
typedef GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> gxepd2display;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DISPLAY_GDEY042T81
|
#ifdef DISPLAY_GDEY042T81
|
||||||
GxEPD2_BW<GxEPD2_420_GDEY042T81, GxEPD2_420_GDEY042T81::HEIGHT> & getdisplay();
|
typedef GxEPD2_BW<GxEPD2_420_GDEY042T81, GxEPD2_420_GDEY042T81::HEIGHT> gxepd2display;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DISPLAY_GYE042A87
|
#ifdef DISPLAY_GYE042A87
|
||||||
GxEPD2_BW<GxEPD2_420_GYE042A87, GxEPD2_420_GYE042A87::HEIGHT> & getdisplay();
|
typedef GxEPD2_BW<GxEPD2_420_GYE042A87, GxEPD2_420_GYE042A87::HEIGHT> gxepd2display;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DISPLAY_SE0420NQ04
|
#ifdef DISPLAY_SE0420NQ04
|
||||||
GxEPD2_BW<GxEPD2_420_SE0420NQ04, GxEPD2_420_SE0420NQ04::HEIGHT> & getdisplay();
|
typedef GxEPD2_BW<GxEPD2_420_SE0420NQ04, GxEPD2_420_SE0420NQ04::HEIGHT> gxepd2display;
|
||||||
#endif
|
#endif
|
||||||
|
extern gxepd2display *epd;
|
||||||
|
|
||||||
// Page display return values
|
// Page display return values
|
||||||
#define PAGE_OK 0 // all ok, do nothing
|
#define PAGE_OK 0 // all ok, do nothing
|
||||||
#define PAGE_UPDATE 1 // page wants display to update
|
#define PAGE_UPDATE 1 // page wants display to update
|
||||||
#define PAGE_HIBERNATE 2 // page wants displey to hibernate
|
#define PAGE_HIBERNATE 2 // page wants displey to hibernate
|
||||||
|
|
||||||
struct Point {
|
|
||||||
double x;
|
|
||||||
double y;
|
|
||||||
};
|
|
||||||
Point rotatePoint(const Point& origin, const Point& p, double angle);
|
|
||||||
std::vector<Point> rotatePoints(const Point& origin, const std::vector<Point>& pts, double angle);
|
|
||||||
void fillPoly4(const std::vector<Point>& p4, uint16_t color);
|
void fillPoly4(const std::vector<Point>& p4, uint16_t color);
|
||||||
|
void drawPoly(const std::vector<Point>& points, uint16_t color);
|
||||||
|
|
||||||
void deepSleep(CommonData &common);
|
void deepSleep(CommonData &common);
|
||||||
|
|
||||||
uint8_t getLastPage();
|
uint8_t getLastPage();
|
||||||
|
|
||||||
void hardwareInit(GwApi *api);
|
void hardwareInit(GwApi *api);
|
||||||
|
void powerInit(String powermode);
|
||||||
|
|
||||||
void setPortPin(uint pin, bool value); // Set port pin for extension port
|
void setPortPin(uint pin, bool value); // Set port pin for extension port
|
||||||
|
|
||||||
@@ -92,15 +103,16 @@ void setBlinkingLED(bool on); // Set blinking flash LED active
|
|||||||
void buzzer(uint frequency, uint duration); // Buzzer function
|
void buzzer(uint frequency, uint duration); // Buzzer function
|
||||||
void setBuzzerPower(uint power); // Set buzzer power
|
void setBuzzerPower(uint power); // Set buzzer power
|
||||||
|
|
||||||
String xdrDelete(String input); // Delete xdr prefix from string
|
String xdrDelete(String input, uint8_t maxlen = 0); // Delete xdr prefix from string and optional limit length
|
||||||
|
|
||||||
void drawTextCenter(int16_t cx, int16_t cy, String text);
|
void drawTextCenter(int16_t cx, int16_t cy, String text);
|
||||||
void drawTextRalign(int16_t x, int16_t y, String text);
|
void drawTextRalign(int16_t x, int16_t y, String text);
|
||||||
|
void drawTextBoxed(Rect box, String text, uint16_t fg, uint16_t bg, bool inverted, bool border);
|
||||||
|
|
||||||
void displayTrendHigh(int16_t x, int16_t y, uint16_t size, uint16_t color);
|
void displayTrendHigh(int16_t x, int16_t y, uint16_t size, uint16_t color);
|
||||||
void displayTrendLow(int16_t x, int16_t y, uint16_t size, uint16_t color);
|
void displayTrendLow(int16_t x, int16_t y, uint16_t size, uint16_t color);
|
||||||
|
|
||||||
void displayHeader(CommonData &commonData, GwApi::BoatValue *date, GwApi::BoatValue *time, GwApi::BoatValue *hdop); // Draw display header
|
void displayHeader(CommonData &commonData, bool symbolmode, GwApi::BoatValue *date, GwApi::BoatValue *time, GwApi::BoatValue *hdop); // Draw display header
|
||||||
void displayFooter(CommonData &commonData);
|
void displayFooter(CommonData &commonData);
|
||||||
void displayAlarm(CommonData &commonData);
|
void displayAlarm(CommonData &commonData);
|
||||||
|
|
||||||
@@ -148,24 +160,62 @@ static unsigned char fram_bits[] PROGMEM = {
|
|||||||
0xff, 0xff, 0xf8, 0x1f, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f,
|
0xff, 0xff, 0xf8, 0x1f, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f,
|
||||||
0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f };
|
0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f };
|
||||||
|
|
||||||
|
// Header symbols
|
||||||
|
|
||||||
static unsigned char ap_bits[] PROGMEM= {
|
static unsigned char ap_bits[] PROGMEM= {
|
||||||
0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0xc2, 0x21, 0x30, 0x06, 0x08, 0x08,
|
0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0xc2, 0x21, 0x30, 0x06, 0x08, 0x08,
|
||||||
0xc0, 0x01, 0x20, 0x02, 0x00, 0x00, 0x80, 0x00, 0xc0, 0x01, 0xc0, 0x01,
|
0xc0, 0x01, 0x20, 0x02, 0x00, 0x00, 0x80, 0x00, 0xc0, 0x01, 0xc0, 0x01,
|
||||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00 };
|
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00 };
|
||||||
|
|
||||||
static unsigned char dish_bits[] PROGMEM = {
|
static unsigned char gps_bits[] PROGMEM = {
|
||||||
0x3c, 0x00, 0x42, 0x18, 0xfa, 0x1b, 0x02, 0x04, 0x02, 0x0a, 0x02, 0x09,
|
0x3c, 0x00, 0x42, 0x18, 0xfa, 0x1b, 0x02, 0x04, 0x02, 0x0a, 0x02, 0x09,
|
||||||
0x82, 0x08, 0x06, 0x0a, 0x0e, 0x1b, 0x9c, 0x2b, 0x38, 0x2b, 0x74, 0x20,
|
0x82, 0x08, 0x06, 0x0a, 0x0e, 0x1b, 0x9c, 0x2b, 0x38, 0x2b, 0x74, 0x20,
|
||||||
0xec, 0x1f, 0x1c, 0x00, 0xf4, 0x00, 0xfe, 0x03 };
|
0xec, 0x1f, 0x1c, 0x00, 0xf4, 0x00, 0xfe, 0x03 };
|
||||||
|
|
||||||
|
static unsigned char nmea_bits[] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x22, 0x21, 0x26, 0x33, 0x26, 0x33, 0x2a, 0x2d, 0x32, 0x2d,
|
||||||
|
0x32, 0x21, 0x22, 0x21, 0x00, 0x00, 0x3c, 0x0c, 0x04, 0x0c, 0x04, 0x12,
|
||||||
|
0x3c, 0x12, 0x04, 0x1e, 0x04, 0x21, 0x3c, 0x21 };
|
||||||
|
|
||||||
|
static unsigned char n2k_bits[] PROGMEM = {
|
||||||
|
0xe0, 0x07, 0x18, 0x18, 0x04, 0x20, 0x02, 0x40, 0x32, 0x4c, 0x31, 0x8c,
|
||||||
|
0x01, 0x80, 0x81, 0x81, 0x81, 0x81, 0x01, 0x80, 0x31, 0x8c, 0x32, 0x4c,
|
||||||
|
0x02, 0x40, 0x04, 0x20, 0x98, 0x19, 0xe0, 0x07 };
|
||||||
|
|
||||||
|
static unsigned char tcp_bits[] PROGMEM = {
|
||||||
|
0x00, 0x00, 0xe0, 0x03, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0xe0, 0x03,
|
||||||
|
0x80, 0x00, 0x80, 0x00, 0xff, 0xff, 0x08, 0x10, 0x08, 0x10, 0x3e, 0x7c,
|
||||||
|
0x22, 0x44, 0x22, 0x44, 0x22, 0x44, 0x3e, 0x7c };
|
||||||
|
|
||||||
|
static unsigned char usb_bits[] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x92, 0x39, 0x52, 0x4a, 0x52, 0x48, 0x92, 0x39, 0x12, 0x4a,
|
||||||
|
0x52, 0x4a, 0x8c, 0x39, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x04, 0x20,
|
||||||
|
0xf4, 0x2f, 0x04, 0x20, 0xf8, 0x1f, 0x00, 0x00 };
|
||||||
|
|
||||||
|
static unsigned char sdcard_bits[] PROGMEM = {
|
||||||
|
0xf8, 0x07, 0x0c, 0x08, 0x04, 0x08, 0xc4, 0x09, 0x24, 0x1a, 0xe4, 0x13,
|
||||||
|
0x04, 0x20, 0x24, 0x21, 0xa4, 0x12, 0x44, 0x12, 0x04, 0x20, 0x04, 0x20,
|
||||||
|
0xc4, 0x23, 0x34, 0x2c, 0xd8, 0x1b, 0x00, 0x00 };
|
||||||
|
|
||||||
|
static unsigned char bluetooth_bits[] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x22, 0x21, 0x26, 0x33, 0x26, 0x33, 0x2a, 0x2d, 0x32, 0x2d,
|
||||||
|
0x32, 0x21, 0x22, 0x21, 0x00, 0x00, 0x3c, 0x0c, 0x04, 0x0c, 0x04, 0x12,
|
||||||
|
0x3c, 0x12, 0x04, 0x1e, 0x04, 0x21, 0x3c, 0x21 };
|
||||||
|
|
||||||
static std::map<String, unsigned char *> iconmap = {
|
static std::map<String, unsigned char *> iconmap = {
|
||||||
{"LEFT", left_bits},
|
{"LEFT", left_bits},
|
||||||
{"RIGHT", right_bits},
|
{"RIGHT", right_bits},
|
||||||
{"LOCK", lock_bits},
|
{"LOCK", lock_bits},
|
||||||
{"PLUS", plus_bits},
|
{"PLUS", plus_bits},
|
||||||
{"MINUS", minus_bits},
|
{"MINUS", minus_bits},
|
||||||
{"DISH", dish_bits},
|
{"GPS", gps_bits},
|
||||||
{"AP", ap_bits}
|
{"AP", ap_bits},
|
||||||
|
{"0183", nmea_bits},
|
||||||
|
{"N2K", n2k_bits},
|
||||||
|
{"TCP", tcp_bits},
|
||||||
|
{"USB", usb_bits},
|
||||||
|
{"SDCARD", sdcard_bits},
|
||||||
|
{"BLUE", bluetooth_bits}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Battery
|
// Battery
|
||||||
|
|||||||
@@ -3,72 +3,79 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "GwApi.h"
|
#include "GwApi.h"
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
|
#include "OBP60Formatter.h"
|
||||||
|
|
||||||
// ToDo
|
// ToDo
|
||||||
// simulation data
|
// simulation data
|
||||||
// hold values by missing data
|
// hold values by missing data
|
||||||
|
|
||||||
String formatDate(String fmttype, uint16_t year, uint8_t month, uint8_t day) {
|
Formatter::Formatter(GwConfigHandler *config) {
|
||||||
char buffer[12];
|
// Load configuration values
|
||||||
if (fmttype == "GB") {
|
// TODO do not use strings but enums, see header file
|
||||||
snprintf(buffer, 12, "%02d/%02d/%04d", day , month, year);
|
stimeZone = config->getString(config->timeZone);
|
||||||
}
|
timeZone = stimeZone.toDouble();
|
||||||
else if (fmttype == "US") {
|
lengthFormat = config->getString(config->lengthFormat);
|
||||||
snprintf(buffer, 12, "%02d/%02d/%04d", month, day, year);
|
distanceFormat = config->getString(config->distanceFormat);
|
||||||
}
|
speedFormat = config->getString(config->speedFormat);
|
||||||
else if (fmttype == "ISO") {
|
windspeedFormat = config->getString(config->windspeedFormat);
|
||||||
snprintf(buffer, 12, "%04d-%02d-%02d", year, month, day);
|
tempFormat = config->getString(config->tempFormat);
|
||||||
}
|
dateFormat = config->getString(config->dateFormat);
|
||||||
else {
|
dateFmt = getDateFormat(dateFormat);
|
||||||
snprintf(buffer, 12, "%02d.%02d.%04d", day, month, year);
|
usesimudata = config->getBool(config->useSimuData);
|
||||||
}
|
precision = config->getString(config->valueprecision);
|
||||||
return String(buffer);
|
|
||||||
|
if (precision == "1") {
|
||||||
|
fmt_dec_1 = "%3.1f";
|
||||||
|
fmt_dec_10 = "%3.0f";
|
||||||
|
fmt_dec_100 = "%3.0f";
|
||||||
|
} else {
|
||||||
|
fmt_dec_1 = "%3.2f";
|
||||||
|
fmt_dec_10 = "%3.1f";
|
||||||
|
fmt_dec_100 = "%3.0f";
|
||||||
}
|
}
|
||||||
|
|
||||||
String formatTime(char fmttype, uint8_t hour, uint8_t minute, uint8_t second) {
|
|
||||||
// fmttype: s: with seconds, m: only minutes
|
|
||||||
char buffer[10];
|
|
||||||
if (fmttype == 'm') {
|
|
||||||
snprintf(buffer, 10, "%02d:%02d", hour , minute);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
snprintf(buffer, 10, "%02d:%02d:%02d", hour, minute, second);
|
|
||||||
}
|
|
||||||
return String(buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String formatLatitude(double lat) {
|
fmtType Formatter::stringToFormat(const char* formatStr) {
|
||||||
float degree = abs(int(lat));
|
auto it = formatMap.find(formatStr);
|
||||||
float minute = abs((lat - int(lat)) * 60);
|
if (it != formatMap.end()) {
|
||||||
return String(degree, 0) + "\x90 " + String(minute, 4) + "' " + ((lat > 0) ? "N" : "S");
|
return it->second;
|
||||||
|
}
|
||||||
|
return fmtType::XDR_G; // generic as default
|
||||||
}
|
}
|
||||||
|
|
||||||
String formatLongitude(double lon) {
|
fmtDate Formatter::getDateFormat(String sformat) {
|
||||||
float degree = abs(int(lon));
|
if (sformat == "DE") {
|
||||||
float minute = abs((lon - int(lon)) * 60);
|
return fmtDate::DE;
|
||||||
return String(degree, 0) + "\x90 " + String(minute, 4) + "' " + ((lon > 0) ? "E" : "W");
|
}
|
||||||
|
if (sformat == "GB") {
|
||||||
|
return fmtDate::GB;
|
||||||
|
}
|
||||||
|
if (sformat == "US") {
|
||||||
|
return fmtDate::US;
|
||||||
|
}
|
||||||
|
return fmtDate::ISO; // default
|
||||||
}
|
}
|
||||||
|
|
||||||
FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
fmtTime Formatter::getTimeFormat(String sformat) {
|
||||||
|
if (sformat == "MMHH") {
|
||||||
|
return fmtTime::MMHH;
|
||||||
|
}
|
||||||
|
if (sformat == "MMHHSS") {
|
||||||
|
return fmtTime::MMHHSS;
|
||||||
|
}
|
||||||
|
return fmtTime::MMHH; // default
|
||||||
|
}
|
||||||
|
|
||||||
|
FormattedData Formatter::formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
||||||
GwLog *logger = commondata.logger;
|
GwLog *logger = commondata.logger;
|
||||||
FormattedData result;
|
FormattedData result;
|
||||||
static int dayoffset = 0;
|
static int dayoffset = 0;
|
||||||
double rawvalue = 0;
|
double rawvalue = 0;
|
||||||
|
|
||||||
// Load configuration values
|
|
||||||
String stimeZone = commondata.config->getString(commondata.config->timeZone); // [UTC -14.00...+12.00]
|
|
||||||
double timeZone = stimeZone.toDouble();
|
|
||||||
String lengthFormat = commondata.config->getString(commondata.config->lengthFormat); // [m|ft]
|
|
||||||
String distanceFormat = commondata.config->getString(commondata.config->distanceFormat); // [m|km|nm]
|
|
||||||
String speedFormat = commondata.config->getString(commondata.config->speedFormat); // [m/s|km/h|kn]
|
|
||||||
String windspeedFormat = commondata.config->getString(commondata.config->windspeedFormat); // [m/s|km/h|kn|bft]
|
|
||||||
String tempFormat = commondata.config->getString(commondata.config->tempFormat); // [K|°C|°F]
|
|
||||||
String dateFormat = commondata.config->getString(commondata.config->dateFormat); // [DE|GB|US]
|
|
||||||
bool usesimudata = commondata.config->getBool(commondata.config->useSimuData); // [on|off]
|
|
||||||
|
|
||||||
// If boat value not valid
|
// If boat value not valid
|
||||||
if (! value->valid && !usesimudata){
|
if (! value->valid && !usesimudata){
|
||||||
result.svalue = "---";
|
result.svalue = placeholder;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,12 +118,7 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
else{
|
else{
|
||||||
snprintf(buffer, bsize, "01.01.2022");
|
snprintf(buffer, bsize, "01.01.2022");
|
||||||
}
|
}
|
||||||
if(timeZone == 0){
|
result.unit = ((timeZone == 0) ? "UTC" : "LOT");
|
||||||
result.unit = "UTC";
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
result.unit = "LOT";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//########################################################
|
//########################################################
|
||||||
else if(value->getFormat() == "formatTime"){
|
else if(value->getFormat() == "formatTime"){
|
||||||
@@ -146,12 +148,7 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
snprintf(buffer, bsize, "11:36:%02i", int(sec));
|
snprintf(buffer, bsize, "11:36:%02i", int(sec));
|
||||||
lasttime = millis();
|
lasttime = millis();
|
||||||
}
|
}
|
||||||
if(timeZone == 0){
|
result.unit = ((timeZone == 0) ? "UTC" : "LOT");
|
||||||
result.unit = "UTC";
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
result.unit = "LOT";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//########################################################
|
//########################################################
|
||||||
else if (value->getFormat() == "formatFixed0"){
|
else if (value->getFormat() == "formatFixed0"){
|
||||||
@@ -206,13 +203,13 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
result.unit = "m/s";
|
result.unit = "m/s";
|
||||||
}
|
}
|
||||||
if(speed < 10) {
|
if(speed < 10) {
|
||||||
snprintf(buffer,bsize,"%3.2f",speed);
|
snprintf(buffer, bsize, fmt_dec_1, speed);
|
||||||
}
|
}
|
||||||
if(speed >= 10 && speed < 100){
|
else if (speed < 100) {
|
||||||
snprintf(buffer,bsize,"%3.1f",speed);
|
snprintf(buffer, bsize, fmt_dec_10, speed);
|
||||||
}
|
}
|
||||||
if(speed >= 100){
|
else {
|
||||||
snprintf(buffer,bsize,"%3.0f",speed);
|
snprintf(buffer, bsize, fmt_dec_100, speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//########################################################
|
//########################################################
|
||||||
@@ -238,40 +235,40 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
if (speed < 0.3) {
|
if (speed < 0.3) {
|
||||||
speed = 0;
|
speed = 0;
|
||||||
}
|
}
|
||||||
if(speed >=0.3 && speed < 1.5){
|
else if (speed < 1.5) {
|
||||||
speed = 1;
|
speed = 1;
|
||||||
}
|
}
|
||||||
if(speed >=1.5 && speed < 3.3){
|
else if (speed < 3.3) {
|
||||||
speed = 2;
|
speed = 2;
|
||||||
}
|
}
|
||||||
if(speed >=3.3 && speed < 5.4){
|
else if (speed < 5.4) {
|
||||||
speed = 3;
|
speed = 3;
|
||||||
}
|
}
|
||||||
if(speed >=5.4 && speed < 7.9){
|
else if (speed < 7.9) {
|
||||||
speed = 4;
|
speed = 4;
|
||||||
}
|
}
|
||||||
if(speed >=7.9 && speed < 10.7){
|
else if (speed < 10.7) {
|
||||||
speed = 5;
|
speed = 5;
|
||||||
}
|
}
|
||||||
if(speed >=10.7 && speed < 13.8){
|
else if (speed < 13.8) {
|
||||||
speed = 6;
|
speed = 6;
|
||||||
}
|
}
|
||||||
if(speed >=13.8 && speed < 17.1){
|
else if (speed < 17.1) {
|
||||||
speed = 7;
|
speed = 7;
|
||||||
}
|
}
|
||||||
if(speed >=17.1 && speed < 20.7){
|
else if (speed < 20.7) {
|
||||||
speed = 8;
|
speed = 8;
|
||||||
}
|
}
|
||||||
if(speed >=20.7 && speed < 24.4){
|
else if (speed < 24.4) {
|
||||||
speed = 9;
|
speed = 9;
|
||||||
}
|
}
|
||||||
if(speed >=24.4 && speed < 28.4){
|
else if (speed < 28.4) {
|
||||||
speed = 10;
|
speed = 10;
|
||||||
}
|
}
|
||||||
if(speed >=28.4 && speed < 32.6){
|
else if (speed < 32.6) {
|
||||||
speed = 11;
|
speed = 11;
|
||||||
}
|
}
|
||||||
if(speed >=32.6){
|
else {
|
||||||
speed = 12;
|
speed = 12;
|
||||||
}
|
}
|
||||||
result.unit = "bft";
|
result.unit = "bft";
|
||||||
@@ -285,13 +282,13 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (speed < 10){
|
if (speed < 10){
|
||||||
snprintf(buffer,bsize,"%3.2f",speed);
|
snprintf(buffer, bsize, fmt_dec_1, speed);
|
||||||
}
|
}
|
||||||
if(speed >= 10 && speed < 100){
|
else if (speed < 100){
|
||||||
snprintf(buffer,bsize,"%3.1f",speed);
|
snprintf(buffer, bsize, fmt_dec_10, speed);
|
||||||
}
|
}
|
||||||
if(speed >= 100){
|
else {
|
||||||
snprintf(buffer,bsize,"%3.0f",speed);
|
snprintf(buffer, bsize, fmt_dec_100, speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -311,13 +308,13 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
if (rotation < -100){
|
if (rotation < -100){
|
||||||
rotation = -99;
|
rotation = -99;
|
||||||
}
|
}
|
||||||
if(rotation > 100){
|
else if (rotation > 100){
|
||||||
rotation = 99;
|
rotation = 99;
|
||||||
}
|
}
|
||||||
if (rotation > -10 && rotation < 10){
|
if (rotation > -10 && rotation < 10){
|
||||||
snprintf(buffer, bsize, "%3.2f", rotation);
|
snprintf(buffer, bsize, "%3.2f", rotation);
|
||||||
}
|
}
|
||||||
if(rotation <= -10 || rotation >= 10){
|
else {
|
||||||
snprintf(buffer, bsize, "%3.0f", rotation);
|
snprintf(buffer, bsize, "%3.0f", rotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,10 +334,13 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
dop = 99.9;
|
dop = 99.9;
|
||||||
}
|
}
|
||||||
if (dop < 10){
|
if (dop < 10){
|
||||||
snprintf(buffer,bsize,"%3.2f",dop);
|
snprintf(buffer, bsize, fmt_dec_1, dop);
|
||||||
}
|
}
|
||||||
if(dop >= 10 && dop < 100){
|
else if(dop < 100){
|
||||||
snprintf(buffer,bsize,"%3.1f",dop);
|
snprintf(buffer, bsize, fmt_dec_10, dop);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
snprintf(buffer, bsize, fmt_dec_100, dop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//########################################################
|
//########################################################
|
||||||
@@ -352,12 +352,7 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
String latdir = "";
|
String latdir = "";
|
||||||
float degree = abs(int(lat));
|
float degree = abs(int(lat));
|
||||||
float minute = abs((lat - int(lat)) * 60);
|
float minute = abs((lat - int(lat)) * 60);
|
||||||
if(lat > 0){
|
latdir = (lat > 0) ? "N" : "S";
|
||||||
latdir = "N";
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
latdir = "S";
|
|
||||||
}
|
|
||||||
latitude = String(degree,0) + "\x90 " + String(minute,4) + "' " + latdir;
|
latitude = String(degree,0) + "\x90 " + String(minute,4) + "' " + latdir;
|
||||||
result.unit = "";
|
result.unit = "";
|
||||||
strcpy(buffer, latitude.c_str());
|
strcpy(buffer, latitude.c_str());
|
||||||
@@ -376,12 +371,7 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
String londir = "";
|
String londir = "";
|
||||||
float degree = abs(int(lon));
|
float degree = abs(int(lon));
|
||||||
float minute = abs((lon - int(lon)) * 60);
|
float minute = abs((lon - int(lon)) * 60);
|
||||||
if(lon > 0){
|
londir = (lon > 0) ? "E" : "W";
|
||||||
londir = "E";
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
londir = "W";
|
|
||||||
}
|
|
||||||
longitude = String(degree,0) + "\x90 " + String(minute,4) + "' " + londir;
|
longitude = String(degree,0) + "\x90 " + String(minute,4) + "' " + londir;
|
||||||
result.unit = "";
|
result.unit = "";
|
||||||
strcpy(buffer, longitude.c_str());
|
strcpy(buffer, longitude.c_str());
|
||||||
@@ -403,40 +393,49 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
depth = rawvalue;
|
depth = rawvalue;
|
||||||
}
|
}
|
||||||
if(String(lengthFormat) == "ft"){
|
if(String(lengthFormat) == "ft"){
|
||||||
depth = depth * 3.28084;
|
depth = depth * 3.28084; // TODO use global defined factor
|
||||||
result.unit = "ft";
|
result.unit = "ft";
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
result.unit = "m";
|
result.unit = "m";
|
||||||
}
|
}
|
||||||
if (depth < 10) {
|
if (depth < 10) {
|
||||||
snprintf(buffer,bsize,"%3.2f",depth);
|
snprintf(buffer, bsize, fmt_dec_1, depth);
|
||||||
}
|
}
|
||||||
if(depth >= 10 && depth < 100){
|
else if (depth < 100){
|
||||||
snprintf(buffer,bsize,"%3.1f",depth);
|
snprintf(buffer, bsize, fmt_dec_10, depth);
|
||||||
}
|
}
|
||||||
if(depth >= 100){
|
else {
|
||||||
snprintf(buffer,bsize,"%3.0f",depth);
|
snprintf(buffer, bsize, fmt_dec_100, depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//########################################################
|
//########################################################
|
||||||
else if (value->getFormat() == "formatXte"){
|
else if (value->getFormat() == "formatXte"){
|
||||||
double xte = 0;
|
double xte = 0;
|
||||||
if (!usesimudata) {
|
if (usesimudata == false) {
|
||||||
xte = abs(value->value);
|
xte = value->value;
|
||||||
rawvalue = value->value;
|
rawvalue = value->value;
|
||||||
} else {
|
} else {
|
||||||
rawvalue = 6.0 + float(random(0, 4));
|
rawvalue = 6.0 + float(random(0, 4));
|
||||||
xte = rawvalue;
|
xte = rawvalue;
|
||||||
}
|
}
|
||||||
if (xte >= 100) {
|
if (distanceFormat == "km") {
|
||||||
snprintf(buffer,bsize,"%3.0f",value->value);
|
xte = xte * 0.001;
|
||||||
} else if (xte >= 10) {
|
result.unit = "km";
|
||||||
snprintf(buffer,bsize,"%3.1f",value->value);
|
} else if (distanceFormat == "nm") {
|
||||||
} else {
|
xte = xte * 0.000539957; // TODO use global defined factor
|
||||||
snprintf(buffer,bsize,"%3.2f",value->value);
|
|
||||||
}
|
|
||||||
result.unit = "nm";
|
result.unit = "nm";
|
||||||
|
} else {
|
||||||
|
result.unit = "m";
|
||||||
|
}
|
||||||
|
if (xte < 10) {
|
||||||
|
snprintf(buffer, bsize, "%3.2f", xte);
|
||||||
|
} else if (xte < 100) {
|
||||||
|
snprintf(buffer,bsize,"%3.1f",xte);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
snprintf(buffer, bsize, "%3.0f", xte);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//########################################################
|
//########################################################
|
||||||
else if (value->getFormat() == "kelvinToC"){
|
else if (value->getFormat() == "kelvinToC"){
|
||||||
@@ -461,13 +460,13 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
result.unit = "K";
|
result.unit = "K";
|
||||||
}
|
}
|
||||||
if (temp < 10) {
|
if (temp < 10) {
|
||||||
snprintf(buffer,bsize,"%3.2f",temp);
|
snprintf(buffer, bsize, fmt_dec_1, temp);
|
||||||
}
|
}
|
||||||
if(temp >= 10 && temp < 100){
|
else if (temp < 100) {
|
||||||
snprintf(buffer,bsize,"%3.1f",temp);
|
snprintf(buffer, bsize, fmt_dec_10, temp);
|
||||||
}
|
}
|
||||||
if(temp >= 100){
|
else {
|
||||||
snprintf(buffer,bsize,"%3.0f",temp);
|
snprintf(buffer, bsize, fmt_dec_100, temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//########################################################
|
//########################################################
|
||||||
@@ -486,20 +485,20 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
result.unit = "km";
|
result.unit = "km";
|
||||||
}
|
}
|
||||||
else if (String(distanceFormat) == "nm") {
|
else if (String(distanceFormat) == "nm") {
|
||||||
distance = distance * 0.000539957;
|
distance = distance * 0.000539957; // TODO use global defined factor
|
||||||
result.unit = "nm";
|
result.unit = "nm";
|
||||||
}
|
}
|
||||||
else{;
|
else {
|
||||||
result.unit = "m";
|
result.unit = "m";
|
||||||
}
|
}
|
||||||
if (distance < 10){
|
if (distance < 10){
|
||||||
snprintf(buffer,bsize,"%3.2f",distance);
|
snprintf(buffer, bsize, fmt_dec_1, distance);
|
||||||
}
|
}
|
||||||
if(distance >= 10 && distance < 100){
|
else if (distance < 100){
|
||||||
snprintf(buffer,bsize,"%3.1f",distance);
|
snprintf(buffer, bsize, fmt_dec_10, distance);
|
||||||
}
|
}
|
||||||
if(distance >= 100){
|
else {
|
||||||
snprintf(buffer,bsize,"%3.0f",distance);
|
snprintf(buffer, bsize, fmt_dec_100, distance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//########################################################
|
//########################################################
|
||||||
@@ -547,10 +546,10 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
voltage = rawvalue;
|
voltage = rawvalue;
|
||||||
}
|
}
|
||||||
if (voltage < 10) {
|
if (voltage < 10) {
|
||||||
snprintf(buffer,bsize,"%3.2f",voltage);
|
snprintf(buffer, bsize, fmt_dec_1, voltage);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
snprintf(buffer,bsize,"%3.1f",voltage);
|
snprintf(buffer, bsize, fmt_dec_10, voltage);
|
||||||
}
|
}
|
||||||
result.unit = "V";
|
result.unit = "V";
|
||||||
}
|
}
|
||||||
@@ -566,13 +565,13 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
current = rawvalue;
|
current = rawvalue;
|
||||||
}
|
}
|
||||||
if (current < 10) {
|
if (current < 10) {
|
||||||
snprintf(buffer,bsize,"%3.2f",current);
|
snprintf(buffer, bsize, fmt_dec_1, current);
|
||||||
}
|
}
|
||||||
if(current >= 10 && current < 100){
|
else if(current < 100) {
|
||||||
snprintf(buffer,bsize,"%3.1f",current);
|
snprintf(buffer, bsize, fmt_dec_10, current);
|
||||||
}
|
}
|
||||||
if(current >= 100){
|
else {
|
||||||
snprintf(buffer,bsize,"%3.0f",current);
|
snprintf(buffer, bsize, fmt_dec_100, current);
|
||||||
}
|
}
|
||||||
result.unit = "A";
|
result.unit = "A";
|
||||||
}
|
}
|
||||||
@@ -588,13 +587,13 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
temperature = rawvalue;
|
temperature = rawvalue;
|
||||||
}
|
}
|
||||||
if (temperature < 10) {
|
if (temperature < 10) {
|
||||||
snprintf(buffer,bsize,"%3.2f",temperature);
|
snprintf(buffer, bsize, fmt_dec_1, temperature);
|
||||||
}
|
}
|
||||||
if(temperature >= 10 && temperature < 100){
|
else if (temperature < 100) {
|
||||||
snprintf(buffer,bsize,"%3.1f",temperature);
|
snprintf(buffer, bsize, fmt_dec_10, temperature);
|
||||||
}
|
}
|
||||||
if(temperature >= 100){
|
else {
|
||||||
snprintf(buffer,bsize,"%3.0f",temperature);
|
snprintf(buffer, bsize, fmt_dec_100, temperature);
|
||||||
}
|
}
|
||||||
result.unit = "Deg C";
|
result.unit = "Deg C";
|
||||||
}
|
}
|
||||||
@@ -610,13 +609,13 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
temperature = rawvalue;
|
temperature = rawvalue;
|
||||||
}
|
}
|
||||||
if (temperature < 10) {
|
if (temperature < 10) {
|
||||||
snprintf(buffer,bsize,"%3.2f",temperature);
|
snprintf(buffer, bsize, fmt_dec_1, temperature);
|
||||||
}
|
}
|
||||||
if(temperature >= 10 && temperature < 100){
|
else if(temperature < 100) {
|
||||||
snprintf(buffer,bsize,"%3.1f",temperature);
|
snprintf(buffer, bsize, fmt_dec_10, temperature);
|
||||||
}
|
}
|
||||||
if(temperature >= 100){
|
else {
|
||||||
snprintf(buffer,bsize,"%3.0f",temperature);
|
snprintf(buffer, bsize, fmt_dec_100, temperature);
|
||||||
}
|
}
|
||||||
result.unit = "Deg C";
|
result.unit = "Deg C";
|
||||||
}
|
}
|
||||||
@@ -632,13 +631,13 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
humidity = rawvalue;
|
humidity = rawvalue;
|
||||||
}
|
}
|
||||||
if (humidity < 10) {
|
if (humidity < 10) {
|
||||||
snprintf(buffer,bsize,"%3.2f",humidity);
|
snprintf(buffer, bsize, fmt_dec_1, humidity);
|
||||||
}
|
}
|
||||||
if(humidity >= 10 && humidity < 100){
|
else if(humidity < 100) {
|
||||||
snprintf(buffer,bsize,"%3.1f",humidity);
|
snprintf(buffer, bsize, fmt_dec_10, humidity);
|
||||||
}
|
}
|
||||||
if(humidity >= 100){
|
else {
|
||||||
snprintf(buffer,bsize,"%3.0f",humidity);
|
snprintf(buffer, bsize, fmt_dec_100, humidity);
|
||||||
}
|
}
|
||||||
result.unit = "%";
|
result.unit = "%";
|
||||||
}
|
}
|
||||||
@@ -654,13 +653,13 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
volume = rawvalue;
|
volume = rawvalue;
|
||||||
}
|
}
|
||||||
if (volume < 10) {
|
if (volume < 10) {
|
||||||
snprintf(buffer,bsize,"%3.2f",volume);
|
snprintf(buffer, bsize, fmt_dec_1, volume);
|
||||||
}
|
}
|
||||||
if(volume >= 10 && volume < 100){
|
else if (volume < 100) {
|
||||||
snprintf(buffer,bsize,"%3.1f",volume);
|
snprintf(buffer, bsize, fmt_dec_10, volume);
|
||||||
}
|
}
|
||||||
if(volume >= 100){
|
else if (volume >= 100) {
|
||||||
snprintf(buffer,bsize,"%3.0f",volume);
|
snprintf(buffer, bsize, fmt_dec_100, volume);
|
||||||
}
|
}
|
||||||
result.unit = "%";
|
result.unit = "%";
|
||||||
}
|
}
|
||||||
@@ -676,13 +675,13 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
volume = rawvalue;
|
volume = rawvalue;
|
||||||
}
|
}
|
||||||
if (volume < 10) {
|
if (volume < 10) {
|
||||||
snprintf(buffer,bsize,"%3.2f",volume);
|
snprintf(buffer, bsize, fmt_dec_1, volume);
|
||||||
}
|
}
|
||||||
if(volume >= 10 && volume < 100){
|
else if (volume < 100) {
|
||||||
snprintf(buffer,bsize,"%3.1f",volume);
|
snprintf(buffer, bsize, fmt_dec_10, volume);
|
||||||
}
|
}
|
||||||
if(volume >= 100){
|
else {
|
||||||
snprintf(buffer,bsize,"%3.0f",volume);
|
snprintf(buffer, bsize, fmt_dec_100, volume);
|
||||||
}
|
}
|
||||||
result.unit = "l";
|
result.unit = "l";
|
||||||
}
|
}
|
||||||
@@ -698,13 +697,13 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
flow = rawvalue;
|
flow = rawvalue;
|
||||||
}
|
}
|
||||||
if (flow < 10) {
|
if (flow < 10) {
|
||||||
snprintf(buffer,bsize,"%3.2f",flow);
|
snprintf(buffer, bsize, fmt_dec_1, flow);
|
||||||
}
|
}
|
||||||
if(flow >= 10 && flow < 100){
|
else if (flow < 100) {
|
||||||
snprintf(buffer,bsize,"%3.1f",flow);
|
snprintf(buffer, bsize, fmt_dec_10, flow);
|
||||||
}
|
}
|
||||||
if(flow >= 100){
|
else {
|
||||||
snprintf(buffer,bsize,"%3.0f",flow);
|
snprintf(buffer, bsize, fmt_dec_100, flow);
|
||||||
}
|
}
|
||||||
result.unit = "l/min";
|
result.unit = "l/min";
|
||||||
}
|
}
|
||||||
@@ -712,7 +711,7 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
else if (value->getFormat() == "formatXdr:G:"){
|
else if (value->getFormat() == "formatXdr:G:"){
|
||||||
double generic = 0;
|
double generic = 0;
|
||||||
if (usesimudata == false) {
|
if (usesimudata == false) {
|
||||||
generic = value->value; // Value in l/min
|
generic = value->value;
|
||||||
rawvalue = value->value;
|
rawvalue = value->value;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -720,13 +719,13 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
generic = rawvalue;
|
generic = rawvalue;
|
||||||
}
|
}
|
||||||
if (generic < 10) {
|
if (generic < 10) {
|
||||||
snprintf(buffer,bsize,"%3.2f",generic);
|
snprintf(buffer, bsize, fmt_dec_1, generic);
|
||||||
}
|
}
|
||||||
if(generic >= 10 && generic < 100){
|
else if (generic < 100) {
|
||||||
snprintf(buffer,bsize,"%3.1f",generic);
|
snprintf(buffer, bsize, fmt_dec_10, generic);
|
||||||
}
|
}
|
||||||
if(generic >= 100){
|
else {
|
||||||
snprintf(buffer,bsize,"%3.0f",generic);
|
snprintf(buffer, bsize, fmt_dec_100, generic);
|
||||||
}
|
}
|
||||||
result.unit = "";
|
result.unit = "";
|
||||||
}
|
}
|
||||||
@@ -742,13 +741,13 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
dplace = rawvalue;
|
dplace = rawvalue;
|
||||||
}
|
}
|
||||||
if (dplace < 10) {
|
if (dplace < 10) {
|
||||||
snprintf(buffer,bsize,"%3.2f",dplace);
|
snprintf(buffer, bsize, fmt_dec_1, dplace);
|
||||||
}
|
}
|
||||||
if(dplace >= 10 && dplace < 100){
|
else if (dplace < 100) {
|
||||||
snprintf(buffer,bsize,"%3.1f",dplace);
|
snprintf(buffer, bsize, fmt_dec_10, dplace);
|
||||||
}
|
}
|
||||||
if(dplace >= 100){
|
else {
|
||||||
snprintf(buffer,bsize,"%3.0f",dplace);
|
snprintf(buffer, bsize, fmt_dec_100, dplace);
|
||||||
}
|
}
|
||||||
result.unit = "%";
|
result.unit = "%";
|
||||||
}
|
}
|
||||||
@@ -784,13 +783,13 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
rpm = rawvalue;
|
rpm = rawvalue;
|
||||||
}
|
}
|
||||||
if (rpm < 10) {
|
if (rpm < 10) {
|
||||||
snprintf(buffer,bsize,"%3.2f",rpm);
|
snprintf(buffer, bsize, fmt_dec_1, rpm);
|
||||||
}
|
}
|
||||||
if(rpm >= 10 && rpm < 100){
|
else if (rpm < 100) {
|
||||||
snprintf(buffer,bsize,"%3.1f",rpm);
|
snprintf(buffer, bsize, fmt_dec_10, rpm);
|
||||||
}
|
}
|
||||||
if(rpm >= 100){
|
else {
|
||||||
snprintf(buffer,bsize,"%3.0f",rpm);
|
snprintf(buffer, bsize, fmt_dec_100, rpm);
|
||||||
}
|
}
|
||||||
result.unit = "rpm";
|
result.unit = "rpm";
|
||||||
}
|
}
|
||||||
@@ -799,13 +798,13 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
//########################################################
|
//########################################################
|
||||||
else {
|
else {
|
||||||
if (value->value < 10) {
|
if (value->value < 10) {
|
||||||
snprintf(buffer,bsize,"%3.2f",value->value);
|
snprintf(buffer, bsize, fmt_dec_1, value->value);
|
||||||
}
|
}
|
||||||
if(value->value >= 10 && value->value < 100){
|
else if (value->value < 100) {
|
||||||
snprintf(buffer,bsize,"%3.1f",value->value);
|
snprintf(buffer, bsize, fmt_dec_10, value->value);
|
||||||
}
|
}
|
||||||
if(value->value >= 100){
|
else {
|
||||||
snprintf(buffer,bsize,"%3.0f",value->value);
|
snprintf(buffer, bsize, fmt_dec_100, value->value);
|
||||||
}
|
}
|
||||||
result.unit = "";
|
result.unit = "";
|
||||||
}
|
}
|
||||||
@@ -815,4 +814,49 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String formatDate(fmtDate fmttype, uint16_t year, uint8_t month, uint8_t day) {
|
||||||
|
char buffer[12];
|
||||||
|
if (fmttype == fmtDate::GB) {
|
||||||
|
snprintf(buffer, 12, "%02d/%02d/%04d", day , month, year);
|
||||||
|
}
|
||||||
|
else if (fmttype == fmtDate::US) {
|
||||||
|
snprintf(buffer, 12, "%02d/%02d/%04d", month, day, year);
|
||||||
|
}
|
||||||
|
else if (fmttype == fmtDate::ISO) {
|
||||||
|
snprintf(buffer, 12, "%04d-%02d-%02d", year, month, day);
|
||||||
|
}
|
||||||
|
else if (fmttype == fmtDate::DE) {
|
||||||
|
snprintf(buffer, 12, "%02d.%02d.%04d", day, month, year);
|
||||||
|
} else {
|
||||||
|
snprintf(buffer, 12, "%04d-%02d-%02d", year, month, day);
|
||||||
|
}
|
||||||
|
return String(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
String formatTime(fmtTime fmttype, uint8_t hour, uint8_t minute, uint8_t second) {
|
||||||
|
char buffer[10];
|
||||||
|
if (fmttype == fmtTime::MMHH) {
|
||||||
|
snprintf(buffer, 10, "%02d:%02d", hour , minute);
|
||||||
|
}
|
||||||
|
else if (fmttype == fmtTime::MMHHSS) {
|
||||||
|
snprintf(buffer, 10, "%02d:%02d:%02d", hour, minute, second);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
snprintf(buffer, 10, "%02d%02d%02d", hour, minute, second);
|
||||||
|
}
|
||||||
|
return String(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
String formatLatitude(double lat) {
|
||||||
|
float degree = abs(int(lat));
|
||||||
|
float minute = abs((lat - int(lat)) * 60);
|
||||||
|
return String(degree, 0) + "\x90 " + String(minute, 4) + "' " + ((lat > 0) ? "N" : "S");
|
||||||
|
}
|
||||||
|
|
||||||
|
String formatLongitude(double lon) {
|
||||||
|
float degree = abs(int(lon));
|
||||||
|
float minute = abs((lon - int(lon)) * 60);
|
||||||
|
return String(degree, 0) + "\x90 " + String(minute, 4) + "' " + ((lon > 0) ? "E" : "W");
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
172
lib/obp60task/OBP60Formatter.h
Normal file
172
lib/obp60task/OBP60Formatter.h
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#ifndef _OBP60FORMATTER_H
|
||||||
|
#define _OBP60FORMATTER_H
|
||||||
|
|
||||||
|
#include "GwApi.h"
|
||||||
|
#include "Pagedata.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
XDR types
|
||||||
|
A Angular displacement
|
||||||
|
C Temperature
|
||||||
|
D Linear displacement
|
||||||
|
F Frequency
|
||||||
|
G Generic
|
||||||
|
H Humidity
|
||||||
|
I Current
|
||||||
|
L Salinity
|
||||||
|
N Force
|
||||||
|
P Pressure
|
||||||
|
R Flow
|
||||||
|
S Switch or valve
|
||||||
|
T Tachometer
|
||||||
|
U Voltage
|
||||||
|
V Volume
|
||||||
|
|
||||||
|
XDR units
|
||||||
|
A Ampere
|
||||||
|
B Bar
|
||||||
|
C Celsius
|
||||||
|
D Degrees
|
||||||
|
H Hertz
|
||||||
|
I Liter per second?
|
||||||
|
M Meter / Cubic meter
|
||||||
|
N Newton
|
||||||
|
P Percent
|
||||||
|
R RPM
|
||||||
|
V Volt
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum class fmtType {
|
||||||
|
// Formatter names as defined in BoatItemBase
|
||||||
|
COURSE,
|
||||||
|
KNOTS,
|
||||||
|
WIND,
|
||||||
|
LATITUDE,
|
||||||
|
LONGITUDE,
|
||||||
|
XTE,
|
||||||
|
FIXED0,
|
||||||
|
DEPTH,
|
||||||
|
DOP, // dilution of precision
|
||||||
|
ROT,
|
||||||
|
DATE,
|
||||||
|
TIME,
|
||||||
|
NAME,
|
||||||
|
|
||||||
|
kelvinToC, // TODO not a format but conversion
|
||||||
|
mtr2nm, // TODO not a format but conversion
|
||||||
|
|
||||||
|
// XDR Formatter names
|
||||||
|
XDR_PP, // pressure percent
|
||||||
|
XDR_PB, // pressure bar
|
||||||
|
XDR_UV, // voltage volt
|
||||||
|
XDR_IA, // current ampere
|
||||||
|
XDR_CK, // temperature kelvin
|
||||||
|
XDR_CC, // temperature celsius
|
||||||
|
XDR_HP, // humidity percent
|
||||||
|
XDR_VP, // volume percent
|
||||||
|
XDR_VM, // volume cubic meters
|
||||||
|
XDR_RI, // flow liter per second?
|
||||||
|
XDR_G, // generic
|
||||||
|
XDR_AP, // angle percent
|
||||||
|
XDR_AD, // angle degrees
|
||||||
|
XDR_TR // tachometer rpm
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hint: String is not supported
|
||||||
|
static std::unordered_map<const char*, fmtType> formatMap PROGMEM = {
|
||||||
|
{"formatCourse", fmtType::COURSE},
|
||||||
|
{"formatKnots", fmtType::KNOTS},
|
||||||
|
{"formatWind", fmtType::WIND},
|
||||||
|
{"formatLatitude", fmtType::LATITUDE},
|
||||||
|
{"formatLongitude", fmtType::LONGITUDE},
|
||||||
|
{"formatXte", fmtType::XTE},
|
||||||
|
{"formatFixed0", fmtType::FIXED0},
|
||||||
|
{"formatDepth", fmtType::DEPTH},
|
||||||
|
{"formatDop", fmtType::DOP},
|
||||||
|
{"formatRot", fmtType::ROT},
|
||||||
|
{"formatDate", fmtType::DATE},
|
||||||
|
{"formatTime", fmtType::TIME},
|
||||||
|
{"formatName", fmtType::NAME},
|
||||||
|
{"kelvinToC", fmtType::kelvinToC},
|
||||||
|
{"mtr2nm", fmtType::mtr2nm},
|
||||||
|
{"formatXdr:P:P", fmtType::XDR_PP},
|
||||||
|
{"formatXdr:P:B", fmtType::XDR_PB},
|
||||||
|
{"formatXdr:U:V", fmtType::XDR_UV},
|
||||||
|
{"formatXdr:I:A", fmtType::XDR_IA},
|
||||||
|
{"formatXdr:C:K", fmtType::XDR_CK},
|
||||||
|
{"formatXdr:C:C", fmtType::XDR_CC},
|
||||||
|
{"formatXdr:H:P", fmtType::XDR_HP},
|
||||||
|
{"formatXdr:V:P", fmtType::XDR_VP},
|
||||||
|
{"formatXdr:V:M", fmtType::XDR_VM},
|
||||||
|
{"formatXdr:R:I", fmtType::XDR_RI},
|
||||||
|
{"formatXdr:G:", fmtType::XDR_G},
|
||||||
|
{"formatXdr:A:P", fmtType::XDR_AP},
|
||||||
|
{"formatXdr:A:D", fmtType::XDR_AD},
|
||||||
|
{"formatXdr:T:R", fmtType::XDR_TR}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Possible formats as scoped enums
|
||||||
|
enum class fmtDate {DE, GB, US, ISO};
|
||||||
|
enum class fmtTime {MMHH, MMHHSS};
|
||||||
|
enum class fmtLength {METER, FEET, FATHOM, CABLE};
|
||||||
|
enum class fmtDepth {METER, FEET, FATHOM};
|
||||||
|
enum class fmtWind {KMH, MS, KN, BFT};
|
||||||
|
enum class fmtCourse {DEG, RAD};
|
||||||
|
enum class fmtRot {DEGS, RADS};
|
||||||
|
enum class fmtXte {M, KM, NM, CABLE};
|
||||||
|
enum class fmtPress {PA, BAR};
|
||||||
|
enum class fmtTemp {KELVIN, CELSUIS, FAHRENHEIT};
|
||||||
|
|
||||||
|
// Conversion factors
|
||||||
|
#define CONV_M_FT 3.2808399 // meter too feet
|
||||||
|
#define CONV_M_FM 0.5468 // meter to fathom
|
||||||
|
#define CONV_M_CBL 0.0053961182483768 // meter to cable
|
||||||
|
#define CONV_CBL_FT 608 // cable to feet
|
||||||
|
#define CONV_FM_FT 6 // fathom to feet
|
||||||
|
|
||||||
|
// Structure for formatted boat values
|
||||||
|
typedef struct {
|
||||||
|
double value;
|
||||||
|
String svalue;
|
||||||
|
String unit;
|
||||||
|
} FormattedData;
|
||||||
|
|
||||||
|
// Formatter for boat values
|
||||||
|
class Formatter {
|
||||||
|
private:
|
||||||
|
String stimeZone = "0";
|
||||||
|
double timeZone = 0.0; // [UTC -14.00...+12.00]
|
||||||
|
String lengthFormat = "m"; // [m|ft]
|
||||||
|
String distanceFormat = "nm"; // [m|km|nm]
|
||||||
|
String speedFormat = "kn"; // [m/s|km/h|kn]
|
||||||
|
String windspeedFormat = "kn"; // [m/s|km/h|kn|bft]
|
||||||
|
String tempFormat = "C"; // [K|°C|°F]
|
||||||
|
String dateFormat = "ISO"; // [DE|GB|US|ISO]
|
||||||
|
fmtDate dateFmt;
|
||||||
|
bool usesimudata = false; // [on|off]
|
||||||
|
|
||||||
|
String precision = "2"; // [1|2]
|
||||||
|
const char* fmt_dec_1;
|
||||||
|
const char* fmt_dec_10;
|
||||||
|
const char* fmt_dec_100;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Formatter(GwConfigHandler *config);
|
||||||
|
fmtType stringToFormat(const char* formatStr);
|
||||||
|
fmtDate getDateFormat(String sformat);
|
||||||
|
fmtTime getTimeFormat(String sformat);
|
||||||
|
FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata);
|
||||||
|
String placeholder = "---";
|
||||||
|
};
|
||||||
|
|
||||||
|
// Standard format functions without class and overhead
|
||||||
|
String formatDate(fmtDate fmttype, uint16_t year, uint8_t month, uint8_t day);
|
||||||
|
String formatTime(fmtTime fmttype, uint8_t hour, uint8_t minute, uint8_t second);
|
||||||
|
String formatLatitude(double lat);
|
||||||
|
String formatLongitude(double lon);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
// Direction pin for RS485 NMEA0183
|
// Direction pin for RS485 NMEA0183
|
||||||
#define OBP_DIRECTION_PIN 8
|
#define OBP_DIRECTION_PIN 8
|
||||||
// I2C
|
// I2C
|
||||||
#define I2C_SPEED 10000UL // 10kHz clock speed on I2C bus
|
#define I2C_SPEED 100000UL // 100kHz clock speed on I2C bus
|
||||||
#define OBP_I2C_SDA 21
|
#define OBP_I2C_SDA 21
|
||||||
#define OBP_I2C_SCL 38
|
#define OBP_I2C_SCL 38
|
||||||
// DS1388 RTC
|
// DS1388 RTC
|
||||||
@@ -120,10 +120,10 @@
|
|||||||
#define SHOW_TIME 6000 // Show time in [ms] for logo and WiFi QR code
|
#define SHOW_TIME 6000 // Show time in [ms] for logo and WiFi QR code
|
||||||
#define FULL_REFRESH_TIME 600 // Refresh cycle time in [s][600...3600] for full display update (very important healcy function)
|
#define FULL_REFRESH_TIME 600 // Refresh cycle time in [s][600...3600] for full display update (very important healcy function)
|
||||||
// SPI SD-Card
|
// SPI SD-Card
|
||||||
#define SD_SPI_CS 10
|
#define SD_SPI_CS GPIO_NUM_10
|
||||||
#define SD_SPI_MOSI 40
|
#define SD_SPI_MOSI GPIO_NUM_40
|
||||||
#define SD_SPI_CLK 39
|
#define SD_SPI_CLK GPIO_NUM_39
|
||||||
#define SD_SPI_MISO 13
|
#define SD_SPI_MISO GPIO_NUM_13
|
||||||
|
|
||||||
// GPS (NEO-6M, NEO-M8N, ATGM336H)
|
// GPS (NEO-6M, NEO-M8N, ATGM336H)
|
||||||
#define OBP_GPS_RX 19
|
#define OBP_GPS_RX 19
|
||||||
|
|||||||
@@ -26,20 +26,20 @@ void qrWiFi(String ssid, String passwd, uint16_t fgcolor, uint16_t bgcolor){
|
|||||||
// Each horizontal module
|
// Each horizontal module
|
||||||
for (uint8_t x = 0; x < qrcode.size; x++) {
|
for (uint8_t x = 0; x < qrcode.size; x++) {
|
||||||
if(qrcode_getModule(&qrcode, x, y)){
|
if(qrcode_getModule(&qrcode, x, y)){
|
||||||
getdisplay().fillRect(box_x, box_y, box_s, box_s, fgcolor);
|
epd->fillRect(box_x, box_y, box_s, box_s, fgcolor);
|
||||||
} else {
|
} else {
|
||||||
getdisplay().fillRect(box_x, box_y, box_s, box_s, bgcolor);
|
epd->fillRect(box_x, box_y, box_s, box_s, bgcolor);
|
||||||
}
|
}
|
||||||
box_x = box_x + box_s;
|
box_x = box_x + box_s;
|
||||||
}
|
}
|
||||||
box_y = box_y + box_s;
|
box_y = box_y + box_s;
|
||||||
box_x = init_x;
|
box_x = init_x;
|
||||||
}
|
}
|
||||||
getdisplay().setFont(&Ubuntu_Bold32pt8b);
|
epd->setFont(&Ubuntu_Bold32pt8b);
|
||||||
getdisplay().setTextColor(fgcolor);
|
epd->setTextColor(fgcolor);
|
||||||
getdisplay().setCursor(140, 285);
|
epd->setCursor(140, 285);
|
||||||
getdisplay().print("WiFi");
|
epd->print("WiFi");
|
||||||
getdisplay().nextPage(); // Full Refresh
|
epd->nextPage(); // Full Refresh
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,147 @@
|
|||||||
#include "OBPDataOperations.h"
|
#include "OBPDataOperations.h"
|
||||||
|
|
||||||
|
// --- Class HstryBuf ---------------
|
||||||
|
// Init history buffers for selected boat data
|
||||||
|
void HstryBuf::init(BoatValueList* boatValues, GwLog *log) {
|
||||||
|
|
||||||
|
logger = log;
|
||||||
|
|
||||||
|
int hstryUpdFreq = 1000; // Update frequency for history buffers in ms
|
||||||
|
int hstryMinVal = 0; // Minimum value for these history buffers
|
||||||
|
twdHstryMax = 6283; // Max value for wind direction (TWD, AWD) in rad [0...2*PI], shifted by 1000 for 3 decimals
|
||||||
|
twsHstryMax = 65000; // Max value for wind speed (TWS, AWS) in m/s [0..65], shifted by 1000 for 3 decimals
|
||||||
|
awdHstryMax = twdHstryMax;
|
||||||
|
awsHstryMax = twsHstryMax;
|
||||||
|
twdHstryMin = hstryMinVal;
|
||||||
|
twsHstryMin = hstryMinVal;
|
||||||
|
awdHstryMin = hstryMinVal;
|
||||||
|
awsHstryMin = hstryMinVal;
|
||||||
|
const double DBL_MAX = std::numeric_limits<double>::max();
|
||||||
|
|
||||||
|
// Initialize history buffers with meta data
|
||||||
|
hstryBufList.twdHstry->setMetaData("TWD", "formatCourse", hstryUpdFreq, hstryMinVal, twdHstryMax);
|
||||||
|
hstryBufList.twsHstry->setMetaData("TWS", "formatKnots", hstryUpdFreq, hstryMinVal, twsHstryMax);
|
||||||
|
hstryBufList.awdHstry->setMetaData("AWD", "formatCourse", hstryUpdFreq, hstryMinVal, twdHstryMax);
|
||||||
|
hstryBufList.awsHstry->setMetaData("AWS", "formatKnots", hstryUpdFreq, hstryMinVal, twsHstryMax);
|
||||||
|
|
||||||
|
// create boat values for history data types, if they don't exist yet
|
||||||
|
twdBVal = boatValues->findValueOrCreate(hstryBufList.twdHstry->getName());
|
||||||
|
twsBVal = boatValues->findValueOrCreate(hstryBufList.twsHstry->getName());
|
||||||
|
twaBVal = boatValues->findValueOrCreate("TWA");
|
||||||
|
awdBVal = boatValues->findValueOrCreate(hstryBufList.awdHstry->getName());
|
||||||
|
awsBVal = boatValues->findValueOrCreate(hstryBufList.awsHstry->getName());
|
||||||
|
|
||||||
|
if (!awdBVal->valid) { // AWD usually does not exist
|
||||||
|
awdBVal->setFormat(hstryBufList.awdHstry->getFormat());
|
||||||
|
awdBVal->value = DBL_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
// collect boat values for true wind calculation
|
||||||
|
awaBVal = boatValues->findValueOrCreate("AWA");
|
||||||
|
hdtBVal = boatValues->findValueOrCreate("HDT");
|
||||||
|
hdmBVal = boatValues->findValueOrCreate("HDM");
|
||||||
|
varBVal = boatValues->findValueOrCreate("VAR");
|
||||||
|
cogBVal = boatValues->findValueOrCreate("COG");
|
||||||
|
sogBVal = boatValues->findValueOrCreate("SOG");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle history buffers for TWD, TWS, AWD, AWS
|
||||||
|
//void HstryBuf::handleHstryBuf(GwApi* api, BoatValueList* boatValues, bool useSimuData) {
|
||||||
|
void HstryBuf::handleHstryBuf(bool useSimuData) {
|
||||||
|
|
||||||
|
static int16_t twd = 20; //initial value only relevant if we use simulation data
|
||||||
|
static uint16_t tws = 20; //initial value only relevant if we use simulation data
|
||||||
|
static double awd, aws, hdt = 20; //initial value only relevant if we use simulation data
|
||||||
|
GwApi::BoatValue *calBVal; // temp variable just for data calibration -> we don't want to calibrate the original data here
|
||||||
|
|
||||||
|
LOG_DEBUG(GwLog::DEBUG,"obp60task handleHstryBuf: TWD_isValid? %d, twdBVal: %.1f, twaBVal: %.1f, twsBVal: %.1f", twdBVal->valid, twdBVal->value * RAD_TO_DEG,
|
||||||
|
twaBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852);
|
||||||
|
|
||||||
|
if (twdBVal->valid) {
|
||||||
|
calBVal = new GwApi::BoatValue("TWD"); // temporary solution for calibration of history buffer values
|
||||||
|
calBVal->setFormat(twdBVal->getFormat());
|
||||||
|
calBVal->value = twdBVal->value;
|
||||||
|
calBVal->valid = twdBVal->valid;
|
||||||
|
calibrationData.calibrateInstance(calBVal, logger); // Check if boat data value is to be calibrated
|
||||||
|
twd = static_cast<int16_t>(std::round(calBVal->value * 1000.0));
|
||||||
|
if (twd >= twdHstryMin && twd <= twdHstryMax) {
|
||||||
|
hstryBufList.twdHstry->add(twd);
|
||||||
|
}
|
||||||
|
delete calBVal;
|
||||||
|
calBVal = nullptr;
|
||||||
|
} else if (useSimuData) {
|
||||||
|
twd += random(-20, 20);
|
||||||
|
twd = WindUtils::to360(twd);
|
||||||
|
hstryBufList.twdHstry->add(static_cast<int16_t>(DegToRad(twd) * 1000.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (twsBVal->valid) {
|
||||||
|
calBVal = new GwApi::BoatValue("TWS"); // temporary solution for calibration of history buffer values
|
||||||
|
calBVal->setFormat(twsBVal->getFormat());
|
||||||
|
calBVal->value = twsBVal->value;
|
||||||
|
calBVal->valid = twsBVal->valid;
|
||||||
|
calibrationData.calibrateInstance(calBVal, logger); // Check if boat data value is to be calibrated
|
||||||
|
tws = static_cast<uint16_t>(std::round(calBVal->value * 1000));
|
||||||
|
if (tws >= twsHstryMin && tws <= twsHstryMax) {
|
||||||
|
hstryBufList.twsHstry->add(tws);
|
||||||
|
}
|
||||||
|
delete calBVal;
|
||||||
|
calBVal = nullptr;
|
||||||
|
} else if (useSimuData) {
|
||||||
|
tws += random(-5000, 5000); // TWS value in m/s; expands to 3 decimals
|
||||||
|
tws = constrain(tws, 0, 25000); // Limit TWS to [0..25] m/s
|
||||||
|
hstryBufList.twsHstry->add(tws);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (awaBVal->valid) {
|
||||||
|
if (hdtBVal->valid) {
|
||||||
|
hdt = hdtBVal->value; // Use HDT if available
|
||||||
|
} else {
|
||||||
|
hdt = WindUtils::calcHDT(&hdmBVal->value, &varBVal->value, &cogBVal->value, &sogBVal->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
awd = awaBVal->value + hdt;
|
||||||
|
awd = WindUtils::to2PI(awd);
|
||||||
|
calBVal = new GwApi::BoatValue("AWD"); // temporary solution for calibration of history buffer values
|
||||||
|
calBVal->value = awd;
|
||||||
|
calBVal->setFormat(awdBVal->getFormat());
|
||||||
|
calBVal->valid = true;
|
||||||
|
calibrationData.calibrateInstance(calBVal, logger); // Check if boat data value is to be calibrated
|
||||||
|
awdBVal->value = calBVal->value;
|
||||||
|
awdBVal->valid = true;
|
||||||
|
awd = std::round(calBVal->value * 1000.0);
|
||||||
|
if (awd >= awdHstryMin && awd <= awdHstryMax) {
|
||||||
|
hstryBufList.awdHstry->add(static_cast<int16_t>(awd));
|
||||||
|
}
|
||||||
|
delete calBVal;
|
||||||
|
calBVal = nullptr;
|
||||||
|
} else if (useSimuData) {
|
||||||
|
awd += random(-20, 20);
|
||||||
|
awd = WindUtils::to360(awd);
|
||||||
|
hstryBufList.awdHstry->add(static_cast<int16_t>(DegToRad(awd) * 1000.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (awsBVal->valid) {
|
||||||
|
calBVal = new GwApi::BoatValue("AWS"); // temporary solution for calibration of history buffer values
|
||||||
|
calBVal->setFormat(awsBVal->getFormat());
|
||||||
|
calBVal->value = awsBVal->value;
|
||||||
|
calBVal->valid = awsBVal->valid;
|
||||||
|
calibrationData.calibrateInstance(calBVal, logger); // Check if boat data value is to be calibrated
|
||||||
|
aws = std::round(calBVal->value * 1000);
|
||||||
|
if (aws >= awsHstryMin && aws <= awsHstryMax) {
|
||||||
|
hstryBufList.awsHstry->add(static_cast<uint16_t>(aws));
|
||||||
|
}
|
||||||
|
delete calBVal;
|
||||||
|
calBVal = nullptr;
|
||||||
|
} else if (useSimuData) {
|
||||||
|
aws += random(-5000, 5000); // TWS value in m/s; expands to 1 decimal
|
||||||
|
aws = constrain(aws, 0, 25000); // Limit TWS to [0..25] m/s
|
||||||
|
hstryBufList.awsHstry->add(aws);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// --- Class HstryBuf ---------------
|
||||||
|
|
||||||
|
// --- Class WindUtils --------------
|
||||||
double WindUtils::to2PI(double a)
|
double WindUtils::to2PI(double a)
|
||||||
{
|
{
|
||||||
a = fmod(a, 2 * M_PI);
|
a = fmod(a, 2 * M_PI);
|
||||||
@@ -68,13 +210,28 @@ void WindUtils::calcTwdSA(const double* AWA, const double* AWS,
|
|||||||
double awd = *AWA + *HDT;
|
double awd = *AWA + *HDT;
|
||||||
awd = to2PI(awd);
|
awd = to2PI(awd);
|
||||||
double stw = -*STW;
|
double stw = -*STW;
|
||||||
// Serial.println("\ncalcTwdSA: AWA: " + String(*AWA) + ", AWS: " + String(*AWS) + ", CTW: " + String(*CTW) + ", STW: " + String(*STW) + ", HDT: " + String(*HDT));
|
|
||||||
addPolar(&awd, AWS, CTW, &stw, TWD, TWS);
|
addPolar(&awd, AWS, CTW, &stw, TWD, TWS);
|
||||||
|
|
||||||
// Normalize TWD and TWA to 0-360°
|
// Normalize TWD and TWA to 0-360°
|
||||||
*TWD = to2PI(*TWD);
|
*TWD = to2PI(*TWD);
|
||||||
*TWA = toPI(*TWD - *HDT);
|
*TWA = toPI(*TWD - *HDT);
|
||||||
// Serial.println("calcTwdSA: TWD: " + String(*TWD) + ", TWS: " + String(*TWS));
|
}
|
||||||
|
|
||||||
|
double WindUtils::calcHDT(const double* hdmVal, const double* varVal, const double* cogVal, const double* sogVal)
|
||||||
|
{
|
||||||
|
double hdt;
|
||||||
|
double minSogVal = 0.1; // SOG below this value (m/s) is assumed to be data noise from GPS sensor
|
||||||
|
|
||||||
|
if (*hdmVal != DBL_MAX) {
|
||||||
|
hdt = *hdmVal + (*varVal != DBL_MAX ? *varVal : 0.0); // Use corrected HDM if HDT is not available (or just HDM if VAR is not available)
|
||||||
|
hdt = to2PI(hdt);
|
||||||
|
} else if (*cogVal != DBL_MAX && *sogVal >= minSogVal) {
|
||||||
|
hdt = *cogVal; // Use COG as fallback if HDT and HDM are not available, and SOG is not data noise
|
||||||
|
} else {
|
||||||
|
hdt = DBL_MAX; // Cannot calculate HDT without valid HDM or HDM+VAR or COG
|
||||||
|
}
|
||||||
|
|
||||||
|
return hdt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal,
|
bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal,
|
||||||
@@ -83,38 +240,32 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal,
|
|||||||
{
|
{
|
||||||
double stw, hdt, ctw;
|
double stw, hdt, ctw;
|
||||||
double twd, tws, twa;
|
double twd, tws, twa;
|
||||||
static const double DBL_MIN = std::numeric_limits<double>::lowest();
|
double minSogVal = 0.1; // SOG below this value (m/s) is assumed to be data noise from GPS sensor
|
||||||
|
|
||||||
if (*hdtVal != DBL_MIN) {
|
if (*hdtVal != DBL_MAX) {
|
||||||
hdt = *hdtVal; // Use HDT if available
|
hdt = *hdtVal; // Use HDT if available
|
||||||
} else {
|
} else {
|
||||||
if (*hdmVal != DBL_MIN && *varVal != DBL_MIN) {
|
hdt = calcHDT(hdmVal, varVal, cogVal, sogVal);
|
||||||
hdt = *hdmVal + *varVal; // Use corrected HDM if HDT is not available
|
|
||||||
hdt = to2PI(hdt);
|
|
||||||
} else if (*cogVal != DBL_MIN) {
|
|
||||||
hdt = *cogVal; // Use COG as fallback if HDT and HDM are not available
|
|
||||||
} else {
|
|
||||||
return false; // Cannot calculate without valid HDT or HDM+VAR or COG
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*cogVal != DBL_MIN) {
|
if (*cogVal != DBL_MAX && *sogVal >= minSogVal) { // if SOG is data noise, we don't trust COG
|
||||||
ctw = *cogVal; // Use COG as CTW if available
|
|
||||||
// ctw = *cogVal + ((*cogVal - hdt) / 2); // Estimate CTW from COG
|
ctw = *cogVal; // Use COG for CTW if available
|
||||||
} else {
|
} else {
|
||||||
ctw = hdt; // 2nd approximation for CTW; hdt must exist if we reach this part of the code
|
ctw = hdt; // 2nd approximation for CTW; hdt must exist if we reach this part of the code
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*stwVal != DBL_MIN) {
|
if (*stwVal != DBL_MAX) {
|
||||||
stw = *stwVal; // Use STW if available
|
stw = *stwVal; // Use STW if available
|
||||||
} else if (*sogVal != DBL_MIN) {
|
} else if (*sogVal != DBL_MAX) {
|
||||||
stw = *sogVal;
|
stw = *sogVal;
|
||||||
} else {
|
} else {
|
||||||
// If STW and SOG are not available, we cannot calculate true wind
|
// If STW and SOG are not available, we cannot calculate true wind
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// Serial.println("\ncalcTrueWind: HDT: " + String(hdt) + ", CTW: " + String(ctw) + ", STW: " + String(stw));
|
||||||
|
|
||||||
if ((*awaVal == DBL_MIN) || (*awsVal == DBL_MIN)) {
|
if ((*awaVal == DBL_MAX) || (*awsVal == DBL_MAX)) {
|
||||||
// Cannot calculate true wind without valid AWA, AWS; other checks are done earlier
|
// Cannot calculate true wind without valid AWA, AWS; other checks are done earlier
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@@ -127,31 +278,45 @@ bool WindUtils::calcTrueWind(const double* awaVal, const double* awsVal,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HstryBuf::fillWndBufSimData(tBoatHstryData& hstryBufs)
|
// Calculate true wind data and add to obp60task boat data list
|
||||||
// Fill most part of TWD and TWS history buffer with simulated data
|
bool WindUtils::addTrueWind(GwApi* api, BoatValueList* boatValues, GwLog* log) {
|
||||||
{
|
|
||||||
double value = 20.0;
|
GwLog* logger = log;
|
||||||
int16_t value2 = 0;
|
|
||||||
for (int i = 0; i < 900; i++) {
|
double awaVal, awsVal, cogVal, stwVal, sogVal, hdtVal, hdmVal, varVal;
|
||||||
value += random(-20, 20);
|
double twd, tws, twa;
|
||||||
value = WindUtils::to360(value);
|
bool isCalculated = false;
|
||||||
value2 = static_cast<int16_t>(value * DEG_TO_RAD * 1000);
|
|
||||||
hstryBufs.twdHstry->add(value2);
|
awaVal = awaBVal->valid ? awaBVal->value : DBL_MAX;
|
||||||
|
awsVal = awsBVal->valid ? awsBVal->value : DBL_MAX;
|
||||||
|
cogVal = cogBVal->valid ? cogBVal->value : DBL_MAX;
|
||||||
|
stwVal = stwBVal->valid ? stwBVal->value : DBL_MAX;
|
||||||
|
sogVal = sogBVal->valid ? sogBVal->value : DBL_MAX;
|
||||||
|
hdtVal = hdtBVal->valid ? hdtBVal->value : DBL_MAX;
|
||||||
|
hdmVal = hdmBVal->valid ? hdmBVal->value : DBL_MAX;
|
||||||
|
varVal = varBVal->valid ? varBVal->value : DBL_MAX;
|
||||||
|
LOG_DEBUG(GwLog::DEBUG,"obp60task addTrueWind: AWA %.1f, AWS %.1f, COG %.1f, STW %.1f, SOG %.2f, HDT %.1f, HDM %.1f, VAR %.1f", awaBVal->value * RAD_TO_DEG, awsBVal->value * 3.6 / 1.852,
|
||||||
|
cogBVal->value * RAD_TO_DEG, stwBVal->value * 3.6 / 1.852, sogBVal->value * 3.6 / 1.852, hdtBVal->value * RAD_TO_DEG, hdmBVal->value * RAD_TO_DEG, varBVal->value * RAD_TO_DEG);
|
||||||
|
|
||||||
|
isCalculated = calcTrueWind(&awaVal, &awsVal, &cogVal, &stwVal, &sogVal, &hdtVal, &hdmVal, &varVal, &twd, &tws, &twa);
|
||||||
|
|
||||||
|
if (isCalculated) { // Replace values only, if successfully calculated and not already available
|
||||||
|
if (!twdBVal->valid) {
|
||||||
|
twdBVal->value = twd;
|
||||||
|
twdBVal->valid = true;
|
||||||
|
}
|
||||||
|
if (!twsBVal->valid) {
|
||||||
|
twsBVal->value = tws;
|
||||||
|
twsBVal->valid = true;
|
||||||
|
}
|
||||||
|
if (!twaBVal->valid) {
|
||||||
|
twaBVal->value = twa;
|
||||||
|
twaBVal->valid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LOG_DEBUG(GwLog::DEBUG,"obp60task addTrueWind: isCalculated %d, TWD %.1f, TWA %.1f, TWS %.1f", isCalculated, twdBVal->value * RAD_TO_DEG,
|
||||||
|
twaBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852);
|
||||||
|
|
||||||
/* double genTwdSimDat()
|
return isCalculated;
|
||||||
{
|
}
|
||||||
simTwd += random(-20, 20);
|
// --- Class WindUtils --------------
|
||||||
if (simTwd < 0.0)
|
|
||||||
simTwd += 360.0;
|
|
||||||
if (simTwd >= 360.0)
|
|
||||||
simTwd -= 360.0;
|
|
||||||
|
|
||||||
int16_t z = static_cast<int16_t>(DegToRad(simTwd) * 1000.0);
|
|
||||||
pageData.boatHstry.twdHstry->add(z); // Fill the buffer with some test data
|
|
||||||
|
|
||||||
simTws += random(-200, 150) / 10.0; // TWS value in knots
|
|
||||||
simTws = constrain(simTws, 0.0f, 50.0f); // Ensure TWS is between 0 and 50 knots
|
|
||||||
twsValue = simTws;
|
|
||||||
}*/
|
|
||||||
|
|||||||
@@ -1,36 +1,90 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "GwApi.h"
|
#include <N2kMessages.h>
|
||||||
#include "OBPRingBuffer.h"
|
#include "OBPRingBuffer.h"
|
||||||
#include <Arduino.h>
|
#include "BoatDataCalibration.h" // Functions lib for data instance calibration
|
||||||
|
#include "obp60task.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
RingBuffer<int16_t>* twdHstry;
|
RingBuffer<int16_t>* twdHstry;
|
||||||
RingBuffer<int16_t>* twsHstry;
|
RingBuffer<uint16_t>* twsHstry;
|
||||||
|
RingBuffer<int16_t>* awdHstry;
|
||||||
|
RingBuffer<uint16_t>* awsHstry;
|
||||||
} tBoatHstryData; // Holds pointers to all history buffers for boat data
|
} tBoatHstryData; // Holds pointers to all history buffers for boat data
|
||||||
|
|
||||||
class HstryBuf {
|
class HstryBuf {
|
||||||
|
private:
|
||||||
|
GwLog *logger;
|
||||||
|
|
||||||
|
RingBuffer<int16_t> twdHstry; // Circular buffer to store true wind direction values
|
||||||
|
RingBuffer<uint16_t> twsHstry; // Circular buffer to store true wind speed values (TWS)
|
||||||
|
RingBuffer<int16_t> awdHstry; // Circular buffer to store apparant wind direction values
|
||||||
|
RingBuffer<uint16_t> awsHstry; // Circular buffer to store apparant xwind speed values (AWS)
|
||||||
|
int16_t twdHstryMin; // Min value for wind direction (TWD) in history buffer
|
||||||
|
int16_t twdHstryMax; // Max value for wind direction (TWD) in history buffer
|
||||||
|
uint16_t twsHstryMin;
|
||||||
|
uint16_t twsHstryMax;
|
||||||
|
int16_t awdHstryMin;
|
||||||
|
int16_t awdHstryMax;
|
||||||
|
uint16_t awsHstryMin;
|
||||||
|
uint16_t awsHstryMax;
|
||||||
|
|
||||||
|
// boat values for buffers and for true wind calculation
|
||||||
|
GwApi::BoatValue *twdBVal, *twsBVal, *twaBVal, *awdBVal, *awsBVal;
|
||||||
|
GwApi::BoatValue *awaBVal, *hdtBVal, *hdmBVal, *varBVal, *cogBVal, *sogBVal;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void fillWndBufSimData(tBoatHstryData& hstryBufs); // Fill most part of the TWD and TWS history buffer with simulated data
|
tBoatHstryData hstryBufList;
|
||||||
|
|
||||||
|
HstryBuf(){
|
||||||
|
hstryBufList = {&twdHstry, &twsHstry, &awdHstry, &awsHstry}; // Generate history buffers of zero size
|
||||||
|
};
|
||||||
|
HstryBuf(int size) {
|
||||||
|
hstryBufList = {&twdHstry, &twsHstry, &awdHstry, &awsHstry};
|
||||||
|
hstryBufList.twdHstry->resize(960); // store 960 TWD values for 16 minutes history
|
||||||
|
hstryBufList.twsHstry->resize(960);
|
||||||
|
hstryBufList.awdHstry->resize(960);
|
||||||
|
hstryBufList.awsHstry->resize(960);
|
||||||
|
};
|
||||||
|
void init(BoatValueList* boatValues, GwLog *log);
|
||||||
|
void handleHstryBuf(bool useSimuData);
|
||||||
};
|
};
|
||||||
|
|
||||||
class WindUtils {
|
class WindUtils {
|
||||||
|
private:
|
||||||
|
GwApi::BoatValue *twdBVal, *twsBVal, *twaBVal;
|
||||||
|
GwApi::BoatValue *awaBVal, *awsBVal, *cogBVal, *stwBVal, *sogBVal, *hdtBVal, *hdmBVal, *varBVal;
|
||||||
|
static constexpr double DBL_MAX = std::numeric_limits<double>::max();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
WindUtils(BoatValueList* boatValues){
|
||||||
|
twdBVal = boatValues->findValueOrCreate("TWD");
|
||||||
|
twsBVal = boatValues->findValueOrCreate("TWS");
|
||||||
|
twaBVal = boatValues->findValueOrCreate("TWA");
|
||||||
|
awaBVal = boatValues->findValueOrCreate("AWA");
|
||||||
|
awsBVal = boatValues->findValueOrCreate("AWS");
|
||||||
|
cogBVal = boatValues->findValueOrCreate("COG");
|
||||||
|
stwBVal = boatValues->findValueOrCreate("STW");
|
||||||
|
sogBVal = boatValues->findValueOrCreate("SOG");
|
||||||
|
hdtBVal = boatValues->findValueOrCreate("HDT");
|
||||||
|
hdmBVal = boatValues->findValueOrCreate("HDM");
|
||||||
|
varBVal = boatValues->findValueOrCreate("VAR");
|
||||||
|
};
|
||||||
static double to2PI(double a);
|
static double to2PI(double a);
|
||||||
static double toPI(double a);
|
static double toPI(double a);
|
||||||
static double to360(double a);
|
static double to360(double a);
|
||||||
static double to180(double a);
|
static double to180(double a);
|
||||||
static void toCart(const double* phi, const double* r, double* x, double* y);
|
void toCart(const double* phi, const double* r, double* x, double* y);
|
||||||
static void toPol(const double* x, const double* y, double* phi, double* r);
|
void toPol(const double* x, const double* y, double* phi, double* r);
|
||||||
static void addPolar(const double* phi1, const double* r1,
|
void addPolar(const double* phi1, const double* r1,
|
||||||
const double* phi2, const double* r2,
|
const double* phi2, const double* r2,
|
||||||
double* phi, double* r);
|
double* phi, double* r);
|
||||||
static void calcTwdSA(const double* AWA, const double* AWS,
|
void calcTwdSA(const double* AWA, const double* AWS,
|
||||||
const double* CTW, const double* STW, const double* HDT,
|
const double* CTW, const double* STW, const double* HDT,
|
||||||
double* TWD, double* TWS, double* TWA);
|
double* TWD, double* TWS, double* TWA);
|
||||||
static bool calcTrueWind(const double* awaVal, const double* awsVal,
|
static double calcHDT(const double* hdmVal, const double* varVal, const double* cogVal, const double* sogVal);
|
||||||
|
bool calcTrueWind(const double* awaVal, const double* awsVal,
|
||||||
const double* cogVal, const double* stwVal, const double* sogVal, const double* hdtVal,
|
const double* cogVal, const double* stwVal, const double* sogVal, const double* hdtVal,
|
||||||
const double* hdmVal, const double* varVal, double* twdVal, double* twsVal, double* twaVal);
|
const double* hdmVal, const double* varVal, double* twdVal, double* twsVal, double* twaVal);
|
||||||
|
bool addTrueWind(GwApi* api, BoatValueList* boatValues, GwLog *log);
|
||||||
};
|
};
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
#ifndef _OBP60FUNCTIONS_H
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#define _OBP60FUNCTIONS_H
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "OBP60Hardware.h"
|
#include "OBP60Hardware.h"
|
||||||
|
#include "OBP60Extensions.h" // for buzzer
|
||||||
|
#include "OBPKeyboardTask.h"
|
||||||
|
|
||||||
// Global vars
|
// Global vars
|
||||||
|
|
||||||
@@ -60,7 +61,7 @@ void initKeys(CommonData &commonData) {
|
|||||||
|
|
||||||
#ifdef HARDWARE_V21
|
#ifdef HARDWARE_V21
|
||||||
// Keypad functions for original OBP60 hardware
|
// Keypad functions for original OBP60 hardware
|
||||||
int readKeypad(GwLog* logger, uint thSensitivity, bool use_syspage) {
|
int readKeypad(GwLog* logger, uint thSensitivity) {
|
||||||
|
|
||||||
// Touch sensor values
|
// Touch sensor values
|
||||||
// 35000 - Not touched
|
// 35000 - Not touched
|
||||||
@@ -286,6 +287,7 @@ void initKeys(CommonData &commonData) {
|
|||||||
}
|
}
|
||||||
// Copy keycode
|
// Copy keycode
|
||||||
keycodeold = keycode;
|
keycodeold = keycode;
|
||||||
|
// 100% Task-CPU RLY?
|
||||||
while(readSensorpads() > 0){} // Wait for pad release
|
while(readSensorpads() > 0){} // Wait for pad release
|
||||||
delay(keydelay);
|
delay(keydelay);
|
||||||
}
|
}
|
||||||
@@ -300,4 +302,40 @@ void initKeys(CommonData &commonData) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void keyboardTask(void *param) {
|
||||||
|
|
||||||
|
// params needed:
|
||||||
|
// queue
|
||||||
|
// logger
|
||||||
|
// sensitivity
|
||||||
|
// use_syspage for deep sleep activation
|
||||||
|
|
||||||
|
KbTaskData *data = (KbTaskData *)param;
|
||||||
|
|
||||||
|
int keycode = 0;
|
||||||
|
data->logger->logDebug(GwLog::LOG, "Start keyboard task");
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
keycode = readKeypad(data->logger, data->sensitivity, data->use_syspage);
|
||||||
|
#else
|
||||||
|
keycode = readKeypad(data->logger, data->sensitivity);
|
||||||
|
#endif
|
||||||
|
//send a key event
|
||||||
|
if (keycode != 0) {
|
||||||
|
xQueueSend(data->queue, &keycode, 0);
|
||||||
|
data->logger->logDebug(GwLog::LOG,"kbtask: send keycode: %d", keycode);
|
||||||
|
}
|
||||||
|
delay(20); // 50Hz update rate (20ms)
|
||||||
|
}
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void createKeyboardTask(KbTaskData *param) {
|
||||||
|
TaskHandle_t xHandle = NULL;
|
||||||
|
if (xTaskCreate(keyboardTask, "keyboard", configMINIMAL_STACK_SIZE + 1024, param, configMAX_PRIORITIES-1, &xHandle) != pdPASS) {
|
||||||
|
param->logger->logDebug(GwLog::ERROR, "Failed to create keyboard task!");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
16
lib/obp60task/OBPKeyboardTask.h
Normal file
16
lib/obp60task/OBPKeyboardTask.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#pragma once
|
||||||
|
#include "GwLog.h"
|
||||||
|
#include "Pagedata.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
QueueHandle_t queue;
|
||||||
|
GwLog* logger = nullptr;
|
||||||
|
uint sensitivity = 100;
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
bool use_syspage = true;
|
||||||
|
#endif
|
||||||
|
} KbTaskData;
|
||||||
|
|
||||||
|
void initKeys(CommonData &commonData);
|
||||||
|
void createKeyboardTask(KbTaskData *param);
|
||||||
@@ -9,29 +9,34 @@
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class RingBuffer {
|
class RingBuffer {
|
||||||
private:
|
private:
|
||||||
mutable SemaphoreHandle_t bufLocker;
|
std::vector<T> buffer; // THE buffer vector
|
||||||
std::vector<T> buffer;
|
|
||||||
size_t capacity;
|
size_t capacity;
|
||||||
size_t head; // Points to the next insertion position
|
size_t head; // Points to the next insertion position
|
||||||
size_t first; // Points to the first (oldest) valid element
|
size_t first; // Points to the first (oldest) valid element
|
||||||
size_t last; // Points to the last (newest) valid element
|
size_t last; // Points to the last (newest) valid element
|
||||||
size_t count; // Number of valid elements currently in buffer
|
size_t count; // Number of valid elements currently in buffer
|
||||||
bool is_Full; // Indicates that all buffer elements are used and ringing is in use
|
bool is_Full; // Indicates that all buffer elements are used and ringing is in use
|
||||||
T MIN_VAL; // lowest possible value of buffer
|
T MIN_VAL; // lowest possible value of buffer of type <T>
|
||||||
T MAX_VAL; // highest possible value of buffer of type <T>
|
T MAX_VAL; // highest possible value of buffer of type <T> -> indicates invalid value in buffer
|
||||||
|
mutable SemaphoreHandle_t bufLocker;
|
||||||
|
|
||||||
// metadata for buffer
|
// metadata for buffer
|
||||||
String dataName; // Name of boat data in buffer
|
String dataName; // Name of boat data in buffer
|
||||||
String dataFmt; // Format of boat data in buffer
|
String dataFmt; // Format of boat data in buffer
|
||||||
int updFreq; // Update frequency in milliseconds
|
int updFreq; // Update frequency in milliseconds
|
||||||
T smallest; // Value range of buffer: smallest value
|
T smallest; // Value range of buffer: smallest value; needs to be => MIN_VAL
|
||||||
T largest; // Value range of buffer: biggest value
|
T largest; // Value range of buffer: biggest value; needs to be < MAX_VAL, since MAX_VAL indicates invalid entries
|
||||||
|
|
||||||
|
void initCommon();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
RingBuffer();
|
||||||
RingBuffer(size_t size);
|
RingBuffer(size_t size);
|
||||||
void setMetaData(String name, String format, int updateFrequency, T minValue, T maxValue); // Set meta data for buffer
|
void setMetaData(String name, String format, int updateFrequency, T minValue, T maxValue); // Set meta data for buffer
|
||||||
bool getMetaData(String& name, String& format, int& updateFrequency, T& minValue, T& maxValue); // Get meta data of buffer
|
bool getMetaData(String& name, String& format, int& updateFrequency, T& minValue, T& maxValue); // Get meta data of buffer
|
||||||
|
bool getMetaData(String& name, String& format);
|
||||||
String getName() const; // Get buffer name
|
String getName() const; // Get buffer name
|
||||||
|
String getFormat() const; // Get buffer data format
|
||||||
void add(const T& value); // Add a new value to buffer
|
void add(const T& value); // Add a new value to buffer
|
||||||
T get(size_t index) const; // Get value at specific position (0-based index from oldest to newest)
|
T get(size_t index) const; // Get value at specific position (0-based index from oldest to newest)
|
||||||
T getFirst() const; // Get the first (oldest) value in buffer
|
T getFirst() const; // Get the first (oldest) value in buffer
|
||||||
@@ -50,9 +55,10 @@ public:
|
|||||||
size_t getLastIdx() const; // Get the index of newest value in buffer
|
size_t getLastIdx() const; // Get the index of newest value in buffer
|
||||||
bool isEmpty() const; // Check if buffer is empty
|
bool isEmpty() const; // Check if buffer is empty
|
||||||
bool isFull() const; // Check if buffer is full
|
bool isFull() const; // Check if buffer is full
|
||||||
T getMinVal() const; // Get lowest possible value for buffer; used for initialized buffer data
|
T getMinVal() const; // Get lowest possible value for buffer
|
||||||
T getMaxVal() const; // Get highest possible value for buffer
|
T getMaxVal() const; // Get highest possible value for buffer; used for unset/invalid buffer data
|
||||||
void clear(); // Clear buffer
|
void clear(); // Clear buffer
|
||||||
|
void resize(size_t size); // Delete buffer and set new size
|
||||||
T operator[](size_t index) const; // Operator[] for convenient access (same as get())
|
T operator[](size_t index) const; // Operator[] for convenient access (same as get())
|
||||||
std::vector<T> getAllValues() const; // Get all current values as a vector
|
std::vector<T> getAllValues() const; // Get all current values as a vector
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,30 @@
|
|||||||
#include "OBPRingBuffer.h"
|
#include "OBPRingBuffer.h"
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void RingBuffer<T>::initCommon() {
|
||||||
|
MIN_VAL = std::numeric_limits<T>::lowest();
|
||||||
|
MAX_VAL = std::numeric_limits<T>::max();
|
||||||
|
dataName = "";
|
||||||
|
dataFmt = "";
|
||||||
|
updFreq = -1;
|
||||||
|
smallest = MIN_VAL;
|
||||||
|
largest = MAX_VAL;
|
||||||
|
bufLocker = xSemaphoreCreateMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
RingBuffer<T>::RingBuffer()
|
||||||
|
: capacity(0)
|
||||||
|
, head(0)
|
||||||
|
, first(0)
|
||||||
|
, last(0)
|
||||||
|
, count(0)
|
||||||
|
, is_Full(false)
|
||||||
|
{
|
||||||
|
initCommon();
|
||||||
|
// <buffer> stays empty
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
RingBuffer<T>::RingBuffer(size_t size)
|
RingBuffer<T>::RingBuffer(size_t size)
|
||||||
: capacity(size)
|
: capacity(size)
|
||||||
@@ -9,23 +34,8 @@ RingBuffer<T>::RingBuffer(size_t size)
|
|||||||
, count(0)
|
, count(0)
|
||||||
, is_Full(false)
|
, is_Full(false)
|
||||||
{
|
{
|
||||||
bufLocker = xSemaphoreCreateMutex();
|
initCommon();
|
||||||
|
buffer.resize(size, MAX_VAL); // MAX_VAL indicate invalid values
|
||||||
if (size == 0) {
|
|
||||||
// return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
MIN_VAL = std::numeric_limits<T>::lowest();
|
|
||||||
MAX_VAL = std::numeric_limits<T>::max();
|
|
||||||
dataName = "";
|
|
||||||
dataFmt = "";
|
|
||||||
updFreq = -1;
|
|
||||||
smallest = MIN_VAL;
|
|
||||||
largest = MAX_VAL;
|
|
||||||
|
|
||||||
buffer.resize(size, MIN_VAL);
|
|
||||||
|
|
||||||
// return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specify meta data of buffer content
|
// Specify meta data of buffer content
|
||||||
@@ -57,6 +67,20 @@ bool RingBuffer<T>::getMetaData(String& name, String& format, int& updateFrequen
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get meta data of buffer content
|
||||||
|
template <typename T>
|
||||||
|
bool RingBuffer<T>::getMetaData(String& name, String& format)
|
||||||
|
{
|
||||||
|
if (dataName == "" || dataFmt == "") {
|
||||||
|
return false; // Meta data not set
|
||||||
|
}
|
||||||
|
|
||||||
|
GWSYNCHRONIZED(&bufLocker);
|
||||||
|
name = dataName;
|
||||||
|
format = dataFmt;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Get buffer name
|
// Get buffer name
|
||||||
template <typename T>
|
template <typename T>
|
||||||
String RingBuffer<T>::getName() const
|
String RingBuffer<T>::getName() const
|
||||||
@@ -64,13 +88,20 @@ String RingBuffer<T>::getName() const
|
|||||||
return dataName;
|
return dataName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get buffer data format
|
||||||
|
template <typename T>
|
||||||
|
String RingBuffer<T>::getFormat() const
|
||||||
|
{
|
||||||
|
return dataFmt;
|
||||||
|
}
|
||||||
|
|
||||||
// Add a new value to buffer
|
// Add a new value to buffer
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void RingBuffer<T>::add(const T& value)
|
void RingBuffer<T>::add(const T& value)
|
||||||
{
|
{
|
||||||
GWSYNCHRONIZED(&bufLocker);
|
GWSYNCHRONIZED(&bufLocker);
|
||||||
if (value < smallest || value > largest) {
|
if (value < smallest || value > largest) {
|
||||||
buffer[head] = MIN_VAL; // Store MIN_VAL if value is out of range
|
buffer[head] = MAX_VAL; // Store MAX_VAL if value is out of range
|
||||||
} else {
|
} else {
|
||||||
buffer[head] = value;
|
buffer[head] = value;
|
||||||
}
|
}
|
||||||
@@ -94,7 +125,7 @@ T RingBuffer<T>::get(size_t index) const
|
|||||||
{
|
{
|
||||||
GWSYNCHRONIZED(&bufLocker);
|
GWSYNCHRONIZED(&bufLocker);
|
||||||
if (isEmpty() || index < 0 || index >= count) {
|
if (isEmpty() || index < 0 || index >= count) {
|
||||||
return MIN_VAL;
|
return MAX_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t realIndex = (first + index) % capacity;
|
size_t realIndex = (first + index) % capacity;
|
||||||
@@ -113,7 +144,7 @@ template <typename T>
|
|||||||
T RingBuffer<T>::getFirst() const
|
T RingBuffer<T>::getFirst() const
|
||||||
{
|
{
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return MIN_VAL;
|
return MAX_VAL;
|
||||||
}
|
}
|
||||||
return get(0);
|
return get(0);
|
||||||
}
|
}
|
||||||
@@ -123,7 +154,7 @@ template <typename T>
|
|||||||
T RingBuffer<T>::getLast() const
|
T RingBuffer<T>::getLast() const
|
||||||
{
|
{
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return MIN_VAL;
|
return MAX_VAL;
|
||||||
}
|
}
|
||||||
return get(count - 1);
|
return get(count - 1);
|
||||||
}
|
}
|
||||||
@@ -133,14 +164,14 @@ template <typename T>
|
|||||||
T RingBuffer<T>::getMin() const
|
T RingBuffer<T>::getMin() const
|
||||||
{
|
{
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return MIN_VAL;
|
return MAX_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
T minVal = MAX_VAL;
|
T minVal = MAX_VAL;
|
||||||
T value;
|
T value;
|
||||||
for (size_t i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
value = get(i);
|
value = get(i);
|
||||||
if (value < minVal && value != MIN_VAL) {
|
if (value < minVal && value != MAX_VAL) {
|
||||||
minVal = value;
|
minVal = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,7 +183,7 @@ template <typename T>
|
|||||||
T RingBuffer<T>::getMin(size_t amount) const
|
T RingBuffer<T>::getMin(size_t amount) const
|
||||||
{
|
{
|
||||||
if (isEmpty() || amount <= 0) {
|
if (isEmpty() || amount <= 0) {
|
||||||
return MIN_VAL;
|
return MAX_VAL;
|
||||||
}
|
}
|
||||||
if (amount > count)
|
if (amount > count)
|
||||||
amount = count;
|
amount = count;
|
||||||
@@ -161,7 +192,7 @@ T RingBuffer<T>::getMin(size_t amount) const
|
|||||||
T value;
|
T value;
|
||||||
for (size_t i = 0; i < amount; i++) {
|
for (size_t i = 0; i < amount; i++) {
|
||||||
value = get(count - 1 - i);
|
value = get(count - 1 - i);
|
||||||
if (value < minVal && value != MIN_VAL) {
|
if (value < minVal && value != MAX_VAL) {
|
||||||
minVal = value;
|
minVal = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -173,14 +204,14 @@ template <typename T>
|
|||||||
T RingBuffer<T>::getMax() const
|
T RingBuffer<T>::getMax() const
|
||||||
{
|
{
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return MIN_VAL;
|
return MAX_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
T maxVal = MIN_VAL;
|
T maxVal = MIN_VAL;
|
||||||
T value;
|
T value;
|
||||||
for (size_t i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
value = get(i);
|
value = get(i);
|
||||||
if (value > maxVal && value != MIN_VAL) {
|
if (value > maxVal && value != MAX_VAL) {
|
||||||
maxVal = value;
|
maxVal = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,7 +223,7 @@ template <typename T>
|
|||||||
T RingBuffer<T>::getMax(size_t amount) const
|
T RingBuffer<T>::getMax(size_t amount) const
|
||||||
{
|
{
|
||||||
if (isEmpty() || amount <= 0) {
|
if (isEmpty() || amount <= 0) {
|
||||||
return MIN_VAL;
|
return MAX_VAL;
|
||||||
}
|
}
|
||||||
if (amount > count)
|
if (amount > count)
|
||||||
amount = count;
|
amount = count;
|
||||||
@@ -201,7 +232,7 @@ T RingBuffer<T>::getMax(size_t amount) const
|
|||||||
T value;
|
T value;
|
||||||
for (size_t i = 0; i < amount; i++) {
|
for (size_t i = 0; i < amount; i++) {
|
||||||
value = get(count - 1 - i);
|
value = get(count - 1 - i);
|
||||||
if (value > maxVal && value != MIN_VAL) {
|
if (value > maxVal && value != MAX_VAL) {
|
||||||
maxVal = value;
|
maxVal = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -213,7 +244,7 @@ template <typename T>
|
|||||||
T RingBuffer<T>::getMid() const
|
T RingBuffer<T>::getMid() const
|
||||||
{
|
{
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return MIN_VAL;
|
return MAX_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (getMin() + getMax()) / static_cast<T>(2);
|
return (getMin() + getMax()) / static_cast<T>(2);
|
||||||
@@ -224,7 +255,7 @@ template <typename T>
|
|||||||
T RingBuffer<T>::getMid(size_t amount) const
|
T RingBuffer<T>::getMid(size_t amount) const
|
||||||
{
|
{
|
||||||
if (isEmpty() || amount <= 0) {
|
if (isEmpty() || amount <= 0) {
|
||||||
return MIN_VAL;
|
return MAX_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (amount > count)
|
if (amount > count)
|
||||||
@@ -238,7 +269,7 @@ template <typename T>
|
|||||||
T RingBuffer<T>::getMedian() const
|
T RingBuffer<T>::getMedian() const
|
||||||
{
|
{
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return MIN_VAL;
|
return MAX_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a temporary vector with current valid elements
|
// Create a temporary vector with current valid elements
|
||||||
@@ -267,7 +298,7 @@ template <typename T>
|
|||||||
T RingBuffer<T>::getMedian(size_t amount) const
|
T RingBuffer<T>::getMedian(size_t amount) const
|
||||||
{
|
{
|
||||||
if (isEmpty() || amount <= 0) {
|
if (isEmpty() || amount <= 0) {
|
||||||
return MIN_VAL;
|
return MAX_VAL;
|
||||||
}
|
}
|
||||||
if (amount > count)
|
if (amount > count)
|
||||||
amount = count;
|
amount = count;
|
||||||
@@ -335,14 +366,14 @@ bool RingBuffer<T>::isFull() const
|
|||||||
return is_Full;
|
return is_Full;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get lowest possible value for buffer; used for non-set buffer data
|
// Get lowest possible value for buffer
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T RingBuffer<T>::getMinVal() const
|
T RingBuffer<T>::getMinVal() const
|
||||||
{
|
{
|
||||||
return MIN_VAL;
|
return MIN_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get highest possible value for buffer
|
// Get highest possible value for buffer; used for unset/invalid buffer data
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T RingBuffer<T>::getMaxVal() const
|
T RingBuffer<T>::getMaxVal() const
|
||||||
{
|
{
|
||||||
@@ -361,6 +392,22 @@ void RingBuffer<T>::clear()
|
|||||||
is_Full = false;
|
is_Full = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete buffer and set new size
|
||||||
|
template <typename T>
|
||||||
|
void RingBuffer<T>::resize(size_t newSize)
|
||||||
|
{
|
||||||
|
GWSYNCHRONIZED(&bufLocker);
|
||||||
|
capacity = newSize;
|
||||||
|
head = 0;
|
||||||
|
first = 0;
|
||||||
|
last = 0;
|
||||||
|
count = 0;
|
||||||
|
is_Full = false;
|
||||||
|
|
||||||
|
buffer.clear();
|
||||||
|
buffer.resize(newSize, MAX_VAL);
|
||||||
|
}
|
||||||
|
|
||||||
// Get all current values as a vector
|
// Get all current values as a vector
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector<T> RingBuffer<T>::getAllValues() const
|
std::vector<T> RingBuffer<T>::getAllValues() const
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
#include <Adafruit_Sensor.h> // Adafruit Lib for sensors
|
#include <Adafruit_Sensor.h> // Adafruit Lib for sensors
|
||||||
#include <Adafruit_BME280.h> // Adafruit Lib for BME280
|
#include <Adafruit_BME280.h> // Adafruit Lib for BME280
|
||||||
@@ -568,6 +569,11 @@ void sensorTask(void *param){
|
|||||||
// Send data from environment sensor all 2s
|
// Send data from environment sensor all 2s
|
||||||
if(millis() > starttime6 + 2000){
|
if(millis() > starttime6 + 2000){
|
||||||
starttime6 = millis();
|
starttime6 = millis();
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
UBaseType_t stackfree = uxTaskGetStackHighWaterMark(NULL);
|
||||||
|
api->getLogger()->logDebug(GwLog::LOG, "obpSensortask Stack=%d", stackfree);
|
||||||
|
|
||||||
unsigned char TempSource = 2; // Inside temperature
|
unsigned char TempSource = 2; // Inside temperature
|
||||||
unsigned char PressureSource = 0; // Atmospheric pressure
|
unsigned char PressureSource = 0; // Atmospheric pressure
|
||||||
unsigned char HumiditySource = 0; // Inside humidity
|
unsigned char HumiditySource = 0; // Inside humidity
|
||||||
@@ -785,8 +791,12 @@ void sensorTask(void *param){
|
|||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void createSensorTask(SharedData *shared) {
|
void createSensorTask(SharedData *shared) {
|
||||||
xTaskCreate(sensorTask,"readSensors",10000,shared,3,NULL);
|
TaskHandle_t xHandle = NULL;
|
||||||
|
GwLog *logger = shared->api->getLogger();
|
||||||
|
esp_err_t err = xTaskCreate(sensorTask, "readSensors", configMINIMAL_STACK_SIZE + 8192, shared, 3, &xHandle);
|
||||||
|
if ( err != pdPASS) {
|
||||||
|
logger->logDebug(GwLog::ERROR, "Failed to create sensor task! (err=%d)", err);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "GwSynchronized.h"
|
#include "GwSynchronized.h"
|
||||||
#include "GwApi.h"
|
#include "GwApi.h"
|
||||||
|
|||||||
178
lib/obp60task/PageAIS.cpp
Normal file
178
lib/obp60task/PageAIS.cpp
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
|
#include "Pagedata.h"
|
||||||
|
#include "OBP60Extensions.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
AIS Overview
|
||||||
|
- circle with certain range, e.g. 5nm
|
||||||
|
- AIS-Targets in range with speed and heading
|
||||||
|
- perhaps collision alarm
|
||||||
|
Data: LAT LON SOG HDT
|
||||||
|
|
||||||
|
Feature possibilities
|
||||||
|
- switch between North up / Heading up
|
||||||
|
- filter
|
||||||
|
- zoom
|
||||||
|
- special vessel symbols
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PageAIS : public Page
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
int scale = 5; // Radius of display circle in nautical miles
|
||||||
|
|
||||||
|
bool alarm = false;
|
||||||
|
bool alarm_enabled = false;
|
||||||
|
int alarm_range = 3;
|
||||||
|
|
||||||
|
char mode = 'N'; // (N)ormal, (C)onfig
|
||||||
|
|
||||||
|
void displayModeNormal(PageData &pageData) {
|
||||||
|
|
||||||
|
// TBD Boatvalues: ...
|
||||||
|
|
||||||
|
logger->logDebug(GwLog::DEBUG,"Drawing at PageAIS");
|
||||||
|
|
||||||
|
Point c = {200, 150}; // center = current boat position
|
||||||
|
uint16_t r = 125;
|
||||||
|
|
||||||
|
const std::vector<Point> pts_boat = { // polygon lines
|
||||||
|
{c.x - 5, c.y},
|
||||||
|
{c.x - 5, c.y - 10},
|
||||||
|
{c.x, c.y - 16},
|
||||||
|
{c.x + 5, c.y - 10},
|
||||||
|
{c.x + 5, c.y}
|
||||||
|
};
|
||||||
|
drawPoly(pts_boat, commonData->fgcolor);
|
||||||
|
|
||||||
|
// Title and corner value headings
|
||||||
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(8, 48);
|
||||||
|
epd->print("AIS");
|
||||||
|
|
||||||
|
// zoom scale
|
||||||
|
epd->drawLine(c.x + 10, c.y, c.x + r - 4, c.y, commonData->fgcolor);
|
||||||
|
// arrow left
|
||||||
|
epd->drawLine(c.x + 10, c.y, c.x + 16, c.y - 4, commonData->fgcolor);
|
||||||
|
epd->drawLine(c.x + 10, c.y, c.x + 16, c.y + 4, commonData->fgcolor);
|
||||||
|
// arrow right
|
||||||
|
epd->drawLine(c.x + r - 4, c.y, c.x + r - 10, c.y - 4, commonData->fgcolor);
|
||||||
|
epd->drawLine(c.x + r - 4, c.y, c.x + r - 10, c.y + 4, commonData->fgcolor);
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
drawTextCenter(c.x + r / 2, c.y + 8, String(scale) + "nm");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayModeConfig() {
|
||||||
|
|
||||||
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(8, 48);
|
||||||
|
epd->print("AIS configuration");
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
// TODO menu
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
PageAIS(CommonData &common) : Page(common)
|
||||||
|
{
|
||||||
|
logger->logDebug(GwLog::LOG, "Instantiate PageAIS");
|
||||||
|
alarm_range = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupKeys(){
|
||||||
|
Page::setupKeys();
|
||||||
|
commonData->keydata[0].label = "MODE";
|
||||||
|
commonData->keydata[1].label = "ALARM";
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
int handleKey(int key){
|
||||||
|
if (key == 1) { // Switch between normal and config mode
|
||||||
|
if (mode == 'N') {
|
||||||
|
mode = 'C';
|
||||||
|
} else {
|
||||||
|
mode = 'N';
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (key == 11) { // Code for keylock
|
||||||
|
commonData->keylock = !commonData->keylock;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
int handleKey(int key) {
|
||||||
|
if (key == 1) { // Switch between normal and config mode
|
||||||
|
if (mode == 'N') {
|
||||||
|
mode = 'C';
|
||||||
|
} else {
|
||||||
|
mode = 'N';
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (key == 11) { // Code for keylock
|
||||||
|
commonData->keylock = !commonData->keylock;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData) {
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int displayPage(PageData &pageData){
|
||||||
|
|
||||||
|
// Logging boat values
|
||||||
|
logger->logDebug(GwLog::LOG, "Drawing at PageAIS; Mode=%c", mode);
|
||||||
|
|
||||||
|
// Set display in partial refresh mode
|
||||||
|
epd->setPartialWindow(0, 0, epd->width(), epd->height());
|
||||||
|
|
||||||
|
if (mode == 'N') {
|
||||||
|
displayModeNormal(pageData);
|
||||||
|
} else if (mode == 'C') {
|
||||||
|
displayModeConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
return PAGE_UPDATE;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static Page *createPage(CommonData &common){
|
||||||
|
return new PageAIS(common);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* with the code below we make this page known to the PageTask
|
||||||
|
* we give it a type (name) that can be selected in the config
|
||||||
|
* we define which function is to be called
|
||||||
|
* and we provide the number of user parameters we expect
|
||||||
|
* this will be number of BoatValue pointers in pageData.values
|
||||||
|
*/
|
||||||
|
PageDescription registerPageAIS(
|
||||||
|
"AIS", // Page name
|
||||||
|
createPage, // Action
|
||||||
|
0, // Number of bus values depends on selection in Web configuration
|
||||||
|
{"LAT", "LON", "SOG", "HDT"}, // Names of bus values undepends on selection in Web configuration (refer GwBoatData.h)
|
||||||
|
true // Show display header on/off
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
432
lib/obp60task/PageAnchor.cpp
Normal file
432
lib/obp60task/PageAnchor.cpp
Normal file
@@ -0,0 +1,432 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
|
#include "Pagedata.h"
|
||||||
|
#include "OBP60Extensions.h"
|
||||||
|
#include "ConfigMenu.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Anchor overview with additional associated data
|
||||||
|
This page is in experimental stage so be warned!
|
||||||
|
North is up.
|
||||||
|
|
||||||
|
Boatdata used
|
||||||
|
DBS - Water depth
|
||||||
|
HDT - Boat heading
|
||||||
|
AWS - Wind strength; Boat not moving so we assume AWS=TWS and AWD=TWD
|
||||||
|
AWD - Wind direction
|
||||||
|
LAT/LON - Boat position, current
|
||||||
|
HDOP - Position error
|
||||||
|
|
||||||
|
This is the fist page to contain a configuration page with
|
||||||
|
data entry option.
|
||||||
|
Also it will make use of the new alarm function.
|
||||||
|
|
||||||
|
Data
|
||||||
|
Anchor position lat/lon
|
||||||
|
Depth at anchor position
|
||||||
|
Chain length used
|
||||||
|
Boat position current
|
||||||
|
Depth at boat position
|
||||||
|
Boat heading
|
||||||
|
Wind direction
|
||||||
|
Wind strength
|
||||||
|
Alarm j/n
|
||||||
|
Alarm radius
|
||||||
|
GPS position error
|
||||||
|
Timestamp while dropping anchor
|
||||||
|
|
||||||
|
Drop / raise function in device OBP40 has to be done inside
|
||||||
|
config mode because of limited number of buttons.
|
||||||
|
|
||||||
|
Save position in FRAM
|
||||||
|
Alarm: gps fix lost
|
||||||
|
switch unit feet/meter
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define anchor_width 16
|
||||||
|
#define anchor_height 16
|
||||||
|
static unsigned char anchor_bits[] = {
|
||||||
|
0x80, 0x01, 0x40, 0x02, 0x40, 0x02, 0x80, 0x01, 0xf0, 0x0f, 0x80, 0x01,
|
||||||
|
0x80, 0x01, 0x88, 0x11, 0x8c, 0x31, 0x8e, 0x71, 0x84, 0x21, 0x86, 0x61,
|
||||||
|
0x86, 0x61, 0xfc, 0x3f, 0xf8, 0x1f, 0x80, 0x01 };
|
||||||
|
|
||||||
|
class PageAnchor : public Page
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
String lengthformat;
|
||||||
|
|
||||||
|
int scale = 50; // Radius of display circle in meter
|
||||||
|
|
||||||
|
bool alarm = false;
|
||||||
|
bool alarm_enabled = false;
|
||||||
|
uint8_t alarm_range;
|
||||||
|
|
||||||
|
uint8_t chain_length;
|
||||||
|
uint8_t chain;
|
||||||
|
|
||||||
|
bool anchor_set = false;
|
||||||
|
double anchor_lat;
|
||||||
|
double anchor_lon;
|
||||||
|
double anchor_depth;
|
||||||
|
int anchor_ts; // time stamp anchor dropped
|
||||||
|
|
||||||
|
char mode = 'N'; // (N)ormal, (C)onfig
|
||||||
|
int8_t editmode = -1; // marker for menu/edit/set function
|
||||||
|
|
||||||
|
ConfigMenu *menu;
|
||||||
|
|
||||||
|
void displayModeNormal(PageData &pageData) {
|
||||||
|
|
||||||
|
// Boatvalues: DBS, HDT, AWS, AWD, LAT, LON, HDOP
|
||||||
|
GwApi::BoatValue *bv_dbs = pageData.values[0]; // DBS
|
||||||
|
String sval_dbs = commonData->fmt->formatValue(bv_dbs, *commonData).svalue;
|
||||||
|
String sunit_dbs = commonData->fmt->formatValue(bv_dbs, *commonData).unit;
|
||||||
|
GwApi::BoatValue *bv_hdt = pageData.values[1]; // HDT
|
||||||
|
String sval_hdt = commonData->fmt->formatValue(bv_hdt, *commonData).svalue;
|
||||||
|
GwApi::BoatValue *bv_aws = pageData.values[2]; // AWS
|
||||||
|
String sval_aws = commonData->fmt->formatValue(bv_aws, *commonData).svalue;
|
||||||
|
String sunit_aws = commonData->fmt->formatValue(bv_aws, *commonData).unit;
|
||||||
|
GwApi::BoatValue *bv_awd = pageData.values[3]; // AWD
|
||||||
|
String sval_awd = commonData->fmt->formatValue(bv_awd, *commonData).svalue;
|
||||||
|
GwApi::BoatValue *bv_lat = pageData.values[4]; // LAT
|
||||||
|
String sval_lat = commonData->fmt->formatValue(bv_lat, *commonData).svalue;
|
||||||
|
GwApi::BoatValue *bv_lon = pageData.values[5]; // LON
|
||||||
|
String sval_lon = commonData->fmt->formatValue(bv_lon, *commonData).svalue;
|
||||||
|
GwApi::BoatValue *bv_hdop = pageData.values[6]; // HDOP
|
||||||
|
String sval_hdop = commonData->fmt->formatValue(bv_hdop, *commonData).svalue;
|
||||||
|
String sunit_hdop = commonData->fmt->formatValue(bv_hdop, *commonData).unit;
|
||||||
|
|
||||||
|
logger->logDebug(GwLog::DEBUG, "Drawing at PageAnchor; DBS=%f, HDT=%f, AWS=%f", bv_dbs->value, bv_hdt->value, bv_aws->value);
|
||||||
|
|
||||||
|
Point c = {200, 150}; // center = anchor position
|
||||||
|
uint16_t r = 125;
|
||||||
|
|
||||||
|
Point b = {200, 180}; // boat position while dropping anchor
|
||||||
|
|
||||||
|
const std::vector<Point> pts_boat = { // polygon lines
|
||||||
|
{b.x - 5, b.y},
|
||||||
|
{b.x - 5, b.y - 10},
|
||||||
|
{b.x, b.y - 16},
|
||||||
|
{b.x + 5, b.y - 10},
|
||||||
|
{b.x + 5, b.y}
|
||||||
|
};
|
||||||
|
//rotatePoints und dann Linien zeichnen
|
||||||
|
// TODO rotate boat according to current heading
|
||||||
|
//drawPoly(rotatePoints(c, pts, RadToDeg(value2)), commonData->fgcolor);
|
||||||
|
drawPoly(pts_boat, commonData->fgcolor);
|
||||||
|
|
||||||
|
// Draw wind arrow
|
||||||
|
const std::vector<Point> pts_wind = {
|
||||||
|
{c.x, c.y - r + 25},
|
||||||
|
{c.x - 12, c.y - r - 4},
|
||||||
|
{c.x, c.y - r + 6},
|
||||||
|
{c.x + 12, c.y - r - 4}
|
||||||
|
};
|
||||||
|
if (bv_awd->valid) {
|
||||||
|
fillPoly4(rotatePoints(c, pts_wind, bv_awd->value), commonData->fgcolor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Title and corner value headings
|
||||||
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(8, 48);
|
||||||
|
epd->print("Anchor");
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold10pt8b);
|
||||||
|
epd->setCursor(8, 200);
|
||||||
|
epd->print("Depth");
|
||||||
|
drawTextRalign(392, 38, "Chain");
|
||||||
|
drawTextRalign(392, 200, "Wind");
|
||||||
|
|
||||||
|
// Units
|
||||||
|
epd->setCursor(8, 272);
|
||||||
|
epd->print(sunit_dbs);
|
||||||
|
drawTextRalign(392, 272, sunit_aws);
|
||||||
|
drawTextRalign(392, 100, lengthformat); // chain unit not implemented
|
||||||
|
|
||||||
|
// Corner values
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
epd->setCursor(8, 70);
|
||||||
|
epd->print("Alarm: ");
|
||||||
|
epd->print(alarm_enabled ? "On" : "Off");
|
||||||
|
|
||||||
|
epd->setCursor(8, 90);
|
||||||
|
epd->print("HDOP");
|
||||||
|
epd->setCursor(8, 106);
|
||||||
|
if (bv_hdop->valid) {
|
||||||
|
epd->print(round(bv_hdop->value), 0);
|
||||||
|
epd->print(sunit_hdop);
|
||||||
|
} else {
|
||||||
|
epd->print("n/a");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Values
|
||||||
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
|
// Current chain used
|
||||||
|
epd->setCursor(328, 85);
|
||||||
|
epd->print("27");
|
||||||
|
|
||||||
|
// Depth
|
||||||
|
epd->setCursor(8, 250);
|
||||||
|
epd->print(sval_dbs);
|
||||||
|
// Wind
|
||||||
|
epd->setCursor(328, 250);
|
||||||
|
epd->print(sval_aws);
|
||||||
|
|
||||||
|
epd->drawCircle(c.x, c.y, r, commonData->fgcolor);
|
||||||
|
epd->drawCircle(c.x, c.y, r + 1, commonData->fgcolor);
|
||||||
|
|
||||||
|
// zoom scale
|
||||||
|
epd->drawLine(c.x + 10, c.y, c.x + r - 4, c.y, commonData->fgcolor);
|
||||||
|
// arrow left
|
||||||
|
epd->drawLine(c.x + 10, c.y, c.x + 16, c.y - 4, commonData->fgcolor);
|
||||||
|
epd->drawLine(c.x + 10, c.y, c.x + 16, c.y + 4, commonData->fgcolor);
|
||||||
|
// arrow right
|
||||||
|
epd->drawLine(c.x + r - 4, c.y, c.x + r - 10, c.y - 4, commonData->fgcolor);
|
||||||
|
epd->drawLine(c.x + r - 4, c.y, c.x + r - 10, c.y + 4, commonData->fgcolor);
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
drawTextCenter(c.x + r / 2, c.y + 8, String(scale) + "m");
|
||||||
|
|
||||||
|
// alarm range circle
|
||||||
|
if (alarm_enabled) {
|
||||||
|
// alarm range in meter has to be smaller than the scale in meter
|
||||||
|
// r and r_range are pixel values
|
||||||
|
uint16_t r_range = int(alarm_range * r / scale);
|
||||||
|
logger->logDebug(GwLog::LOG, "Drawing at PageAnchor; Alarm range = %d", r_range);
|
||||||
|
epd->drawCircle(c.x, c.y, r_range, commonData->fgcolor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw anchor symbol (as bitmap)
|
||||||
|
epd->drawXBitmap(c.x - anchor_width / 2, c.y - anchor_height / 2,
|
||||||
|
anchor_bits, anchor_width, anchor_height, commonData->fgcolor);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayModeConfig() {
|
||||||
|
|
||||||
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(8, 48);
|
||||||
|
epd->print("Anchor configuration");
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// show lat/lon for anchor pos
|
||||||
|
// show lat/lon for boat pos
|
||||||
|
// show distance anchor <-> boat
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
for (int i = 0 ; i < menu->getItemCount(); i++) {
|
||||||
|
ConfigMenuItem *itm = menu->getItemByIndex(i);
|
||||||
|
if (!itm) {
|
||||||
|
logger->logDebug(GwLog::ERROR, "Menu item not found: %d", i);
|
||||||
|
} else {
|
||||||
|
Rect r = menu->getItemRect(i);
|
||||||
|
bool inverted = (i == menu->getActiveIndex());
|
||||||
|
drawTextBoxed(r, itm->getLabel(), commonData->fgcolor, commonData->bgcolor, inverted, false);
|
||||||
|
if (inverted and editmode > 0) {
|
||||||
|
// triangle as edit marker
|
||||||
|
epd->fillTriangle(r.x + r.w + 20, r.y, r.x + r.w + 30, r.y + r.h / 2, r.x + r.w + 20, r.y + r.h, commonData->fgcolor);
|
||||||
|
}
|
||||||
|
epd->setCursor(r.x + r.w + 40, r.y + r.h - 4);
|
||||||
|
if (itm->getType() == "int") {
|
||||||
|
epd->print(itm->getValue());
|
||||||
|
epd->print(itm->getUnit());
|
||||||
|
} else {
|
||||||
|
epd->print(itm->getValue() == 0 ? "No" : "Yes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
PageAnchor(CommonData &common) : Page(common)
|
||||||
|
{
|
||||||
|
logger->logDebug(GwLog::LOG, "Instantiate PageAnchor");
|
||||||
|
|
||||||
|
// preload configuration data
|
||||||
|
lengthformat = config->getString(config->lengthFormat);
|
||||||
|
chain_length = config->getInt(config->chainLength);
|
||||||
|
|
||||||
|
chain = 0;
|
||||||
|
anchor_set = false;
|
||||||
|
alarm_range = 30;
|
||||||
|
|
||||||
|
// Initialize config menu
|
||||||
|
menu = new ConfigMenu("Options", 40, 80);
|
||||||
|
menu->setItemDimension(150, 20);
|
||||||
|
|
||||||
|
ConfigMenuItem *newitem;
|
||||||
|
newitem = menu->addItem("chain", "Chain out", "int", 0, "m");
|
||||||
|
if (! newitem) {
|
||||||
|
// Demo: in case of failure exit here, should never be happen
|
||||||
|
logger->logDebug(GwLog::ERROR, "Menu item creation failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
newitem->setRange(0, 200, {1, 5, 10});
|
||||||
|
newitem = menu->addItem("chainmax", "Chain max", "int", chain_length, "m");
|
||||||
|
newitem->setRange(0, 200, {1, 5, 10});
|
||||||
|
newitem = menu->addItem("zoom", "Zoom", "int", 50, "m");
|
||||||
|
newitem->setRange(0, 200, {1, });
|
||||||
|
newitem = menu->addItem("range", "Alarm range", "int", 40, "m");
|
||||||
|
newitem->setRange(0, 200, {1, 5, 10});
|
||||||
|
newitem = menu->addItem("alat", "Adjust anchor lat.", "int", 0, "m");
|
||||||
|
newitem->setRange(0, 200, {1, 5, 10});
|
||||||
|
newitem = menu->addItem("alon", "Adjust anchor lon.", "int", 0, "m");
|
||||||
|
newitem->setRange(0, 200, {1, 5, 10});
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
// Intodruced here because of missing keys for OBP40
|
||||||
|
newitem = menu->addItem("anchor", "Anchor down", "bool", 0, "");
|
||||||
|
#endif
|
||||||
|
menu->setItemActive("zoom");
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupKeys(){
|
||||||
|
Page::setupKeys();
|
||||||
|
commonData->keydata[0].label = "MODE";
|
||||||
|
commonData->keydata[1].label = "ALARM";
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
int handleKey(int key){
|
||||||
|
if (key == 1) { // Switch between normal and config mode
|
||||||
|
if (mode == 'N') {
|
||||||
|
mode = 'C';
|
||||||
|
} else {
|
||||||
|
mode = 'N';
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (mode == 'N') {
|
||||||
|
if (key == 2) { // Toggle alarm
|
||||||
|
alarm_enabled = !alarm_enabled;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else { // Config mode
|
||||||
|
if (key == 3) {
|
||||||
|
// menu down
|
||||||
|
menu->goNext();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (key == 4) {
|
||||||
|
// menu up
|
||||||
|
menu->goPrev();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (key == 11) { // Code for keylock
|
||||||
|
commonData->keylock = !commonData->keylock;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
int handleKey(int key){
|
||||||
|
if (key == 1) { // Switch between normal and config mode
|
||||||
|
if (mode == 'N') {
|
||||||
|
mode = 'C';
|
||||||
|
commonData->keydata[1].label = "EDIT";
|
||||||
|
} else {
|
||||||
|
mode = 'N';
|
||||||
|
commonData->keydata[1].label = "ALARM";
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (mode == 'N') {
|
||||||
|
if (key == 2) { // Toggle alarm
|
||||||
|
alarm_enabled = !alarm_enabled;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else { // Config mode
|
||||||
|
// TODO different code for OBP40 / OBP60
|
||||||
|
if (key == 9) {
|
||||||
|
// menu down
|
||||||
|
if (editmode > 0) {
|
||||||
|
// decrease item value
|
||||||
|
menu->getActiveItem()->decValue();
|
||||||
|
} else {
|
||||||
|
menu->goNext();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (key == 10) {
|
||||||
|
// menu up or value up
|
||||||
|
if (editmode > 0) {
|
||||||
|
// increase item value
|
||||||
|
menu->getActiveItem()->incValue();
|
||||||
|
} else {
|
||||||
|
menu->goPrev();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (key == 2) {
|
||||||
|
// enter / leave edit mode for current menu item
|
||||||
|
if (editmode > 0) {
|
||||||
|
commonData->keydata[1].label = "EDIT";
|
||||||
|
editmode = 0;
|
||||||
|
} else {
|
||||||
|
commonData->keydata[1].label = "SET";
|
||||||
|
editmode = 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (key == 11) { // Code for keylock
|
||||||
|
commonData->keylock = !commonData->keylock;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData){
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int displayPage(PageData &pageData){
|
||||||
|
|
||||||
|
// Logging boat values
|
||||||
|
logger->logDebug(GwLog::LOG, "Drawing at PageAnchor; Mode=%c", mode);
|
||||||
|
|
||||||
|
// Set display in partial refresh mode
|
||||||
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
|
if (mode == 'N') {
|
||||||
|
displayModeNormal(pageData);
|
||||||
|
} else if (mode == 'C') {
|
||||||
|
displayModeConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
return PAGE_UPDATE;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static Page *createPage(CommonData &common){
|
||||||
|
return new PageAnchor(common);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* with the code below we make this page known to the PageTask
|
||||||
|
* we give it a type (name) that can be selected in the config
|
||||||
|
* we define which function is to be called
|
||||||
|
* and we provide the number of user parameters we expect
|
||||||
|
* this will be number of BoatValue pointers in pageData.values
|
||||||
|
*/
|
||||||
|
PageDescription registerPageAnchor(
|
||||||
|
"Anchor", // Page name
|
||||||
|
createPage, // Action
|
||||||
|
0, // Number of bus values depends on selection in Web configuration
|
||||||
|
{"DBS", "HDT", "AWS", "AWD", "LAT", "LON", "HDOP"}, // Names of bus values undepends on selection in Web configuration (refer GwBoatData.h)
|
||||||
|
true // Show display header on/off
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
138
lib/obp60task/PageAutopilot.cpp
Normal file
138
lib/obp60task/PageAutopilot.cpp
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
|
#include "Pagedata.h"
|
||||||
|
#include "OBP60Extensions.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Autopilot
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PageAutopilot : public Page
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
char mode = 'N'; // (N)ormal, (C)onfig
|
||||||
|
|
||||||
|
void displayModeNormal(PageData &pageData) {
|
||||||
|
|
||||||
|
// TBD Boatvalues: ...
|
||||||
|
|
||||||
|
logger->logDebug(GwLog::DEBUG, "Drawing at PageAutopilot");
|
||||||
|
|
||||||
|
// Title and corner value headings
|
||||||
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(8, 48);
|
||||||
|
epd->print("Autopilot");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayModeConfig() {
|
||||||
|
|
||||||
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(8, 48);
|
||||||
|
epd->print("Autopilot configuration");
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
// TODO menu
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
PageAutopilot(CommonData &common) : Page(common)
|
||||||
|
{
|
||||||
|
logger->logDebug(GwLog::LOG, "Instantiate PageAutopilot");
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupKeys() {
|
||||||
|
Page::setupKeys();
|
||||||
|
commonData->keydata[0].label = "MODE";
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
int handleKey(int key) {
|
||||||
|
if (key == 1) { // Switch between normal and config mode
|
||||||
|
if (mode == 'N') {
|
||||||
|
mode = 'C';
|
||||||
|
} else {
|
||||||
|
mode = 'N';
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (key == 11) { // Code for keylock
|
||||||
|
commonData->keylock = !commonData->keylock;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
int handleKey(int key){
|
||||||
|
if (key == 1) { // Switch between normal and config mode
|
||||||
|
if (mode == 'N') {
|
||||||
|
mode = 'C';
|
||||||
|
commonData->keydata[1].label = "EDIT";
|
||||||
|
} else {
|
||||||
|
mode = 'N';
|
||||||
|
commonData->keydata[1].label = "ALARM";
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (key == 11) { // Code for keylock
|
||||||
|
commonData->keylock = !commonData->keylock;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData){
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int displayPage(PageData &pageData){
|
||||||
|
|
||||||
|
// Logging boat values
|
||||||
|
logger->logDebug(GwLog::LOG, "Drawing at PageAutopilot; Mode=%c", mode);
|
||||||
|
|
||||||
|
// Set display in partial refresh mode
|
||||||
|
epd->setPartialWindow(0, 0, epd->width(), epd->height());
|
||||||
|
|
||||||
|
if (mode == 'N') {
|
||||||
|
displayModeNormal(pageData);
|
||||||
|
} else if (mode == 'C') {
|
||||||
|
displayModeConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
return PAGE_UPDATE;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static Page *createPage(CommonData &common){
|
||||||
|
return new PageAutopilot(common);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* with the code below we make this page known to the PageTask
|
||||||
|
* we give it a type (name) that can be selected in the config
|
||||||
|
* we define which function is to be called
|
||||||
|
* and we provide the number of user parameters we expect
|
||||||
|
* this will be number of BoatValue pointers in pageData.values
|
||||||
|
*/
|
||||||
|
PageDescription registerPageAutopilot(
|
||||||
|
"Autopilot", // Page name
|
||||||
|
createPage, // Action
|
||||||
|
0, // Number of bus values depends on selection in Web configuration
|
||||||
|
{}, // Names of bus values undepends on selection in Web configuration (refer GwBoatData.h)
|
||||||
|
false // Show display header on/off
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
@@ -5,13 +6,21 @@
|
|||||||
|
|
||||||
class PageBME280 : public Page
|
class PageBME280 : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String tempformat;
|
||||||
|
String useenvsensor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageBME280(CommonData &common){
|
PageBME280(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageBME280");
|
logger->logDebug(GwLog::LOG, "Instantiate PageBME280");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
tempformat = config->getString(config->tempFormat);
|
||||||
|
useenvsensor = config->getString(config->useEnvSensor);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key){
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -21,8 +30,6 @@ class PageBME280 : public Page
|
|||||||
}
|
}
|
||||||
|
|
||||||
int displayPage(PageData &pageData){
|
int displayPage(PageData &pageData){
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
double value1 = 0;
|
double value1 = 0;
|
||||||
double value2 = 0;
|
double value2 = 0;
|
||||||
@@ -31,13 +38,6 @@ class PageBME280 : public Page
|
|||||||
String svalue2 = "";
|
String svalue2 = "";
|
||||||
String svalue3 = "";
|
String svalue3 = "";
|
||||||
|
|
||||||
// Get config data
|
|
||||||
String tempformat = config->getString(config->tempFormat);
|
|
||||||
bool simulation = config->getBool(config->useSimuData);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
String useenvsensor = config->getString(config->useEnvSensor);
|
|
||||||
|
|
||||||
// Get sensor values #1
|
// Get sensor values #1
|
||||||
String name1 = "Temp"; // Value name
|
String name1 = "Temp"; // Value name
|
||||||
name1 = name1.substring(0, 6); // String length limit for value name
|
name1 = name1.substring(0, 6); // String length limit for value name
|
||||||
@@ -99,82 +99,82 @@ class PageBME280 : public Page
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Logging boat values
|
// Logging boat values
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageBME280, %s: %f, %s: %f, %s: %f", name1.c_str(), value1, name2.c_str(), value2, name3.c_str(), value3);
|
logger->logDebug(GwLog::LOG, "Drawing at PageBME280, %s: %f, %s: %f, %s: %f", name1.c_str(), value1, name2.c_str(), value2, name3.c_str(), value3);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 1 ################
|
// ############### Value 1 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 55);
|
epd->setCursor(20, 55);
|
||||||
getdisplay().print(name1); // Page name
|
epd->print(name1); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 90);
|
epd->setCursor(20, 90);
|
||||||
getdisplay().print(unit1); // Unit
|
epd->print(unit1); // Unit
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic30pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic30pt7b);
|
||||||
getdisplay().setCursor(180, 90);
|
epd->setCursor(180, 90);
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
getdisplay().print(svalue1); // Real value as formated string
|
epd->print(svalue1); // Real value as formated string
|
||||||
|
|
||||||
// ############### Horizontal Line ################
|
// ############### Horizontal Line ################
|
||||||
|
|
||||||
// Horizontal line 3 pix
|
// Horizontal line 3 pix
|
||||||
getdisplay().fillRect(0, 105, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, 105, 400, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 2 ################
|
// ############### Value 2 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 145);
|
epd->setCursor(20, 145);
|
||||||
getdisplay().print(name2); // Page name
|
epd->print(name2); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 180);
|
epd->setCursor(20, 180);
|
||||||
getdisplay().print(unit2); // Unit
|
epd->print(unit2); // Unit
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic30pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic30pt7b);
|
||||||
getdisplay().setCursor(180, 180);
|
epd->setCursor(180, 180);
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
getdisplay().print(svalue2); // Real value as formated string
|
epd->print(svalue2); // Real value as formated string
|
||||||
|
|
||||||
// ############### Horizontal Line ################
|
// ############### Horizontal Line ################
|
||||||
|
|
||||||
// Horizontal line 3 pix
|
// Horizontal line 3 pix
|
||||||
getdisplay().fillRect(0, 195, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, 195, 400, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 3 ################
|
// ############### Value 3 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 235);
|
epd->setCursor(20, 235);
|
||||||
getdisplay().print(name3); // Page name
|
epd->print(name3); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 270);
|
epd->setCursor(20, 270);
|
||||||
getdisplay().print(unit3); // Unit
|
epd->print(unit3); // Unit
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic30pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic30pt7b);
|
||||||
getdisplay().setCursor(140, 270);
|
epd->setCursor(140, 270);
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
getdisplay().print(svalue3); // Real value as formated string
|
epd->print(svalue3); // Real value as formated string
|
||||||
|
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
};
|
};
|
||||||
|
|||||||
238
lib/obp60task/PageBarograph.cpp
Normal file
238
lib/obp60task/PageBarograph.cpp
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Barograph WIP
|
||||||
|
* - Zoom feature
|
||||||
|
* - Saves data in FRAM if available
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Pagedata.h"
|
||||||
|
#include "OBP60Extensions.h"
|
||||||
|
|
||||||
|
class PageBarograph : public Page
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool keylock = false;
|
||||||
|
bool has_fram = false;
|
||||||
|
String flashLED;
|
||||||
|
String useenvsensor;
|
||||||
|
|
||||||
|
char source = 'I'; // (I)nternal, e(X)ternal
|
||||||
|
const int series[5] = {75, 150, 300, 600, 900};
|
||||||
|
const int zoom[5] = {1, 2, 3, 6, 12};
|
||||||
|
int zoomindex = 4;
|
||||||
|
uint16_t data[336] = {0}; // current data to display
|
||||||
|
|
||||||
|
// y-axis
|
||||||
|
uint16_t vmin;
|
||||||
|
uint16_t vmax;
|
||||||
|
uint16_t scalemin = 1000;
|
||||||
|
uint16_t scalemax = 1020;
|
||||||
|
uint16_t scalestep = 5;
|
||||||
|
int hist1 = 0; // one hour trend
|
||||||
|
int hist3 = 0; // three hours trend
|
||||||
|
|
||||||
|
long refresh = 0; // millis
|
||||||
|
|
||||||
|
void loadData() {
|
||||||
|
// Transfer data from history to page buffer,
|
||||||
|
// set y-axis according to data
|
||||||
|
int i = zoom[zoomindex];
|
||||||
|
|
||||||
|
// get min and max values of measured data
|
||||||
|
vmin = data[0];
|
||||||
|
vmax = data[0];
|
||||||
|
for (int x = 0; x < 336; x++) {
|
||||||
|
if (data[x] != 0) {
|
||||||
|
if (data[x] < vmin) {
|
||||||
|
vmin = data[x];
|
||||||
|
} else if (data[x] > vmax) {
|
||||||
|
vmax = data[x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate y-axis scale
|
||||||
|
uint16_t diff = vmax - vmin;
|
||||||
|
if (diff < 20) {
|
||||||
|
scalestep = 5;
|
||||||
|
} else if (diff < 40) {
|
||||||
|
scalestep = 10;
|
||||||
|
} else {
|
||||||
|
scalestep = 15;
|
||||||
|
}
|
||||||
|
scalemin = vmin - (vmin % scalestep);
|
||||||
|
scalemax = vmax + scalestep - (vmax % scalestep);
|
||||||
|
|
||||||
|
// TODO implement history buffer
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
PageBarograph(CommonData &common): Page(common)
|
||||||
|
{
|
||||||
|
logger->logDebug(GwLog::LOG, "Instantiate PageBarograph");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
useenvsensor = config->getString(common.config->useEnvSensor);
|
||||||
|
// possible values for internal sensor
|
||||||
|
static std::vector<String> sensorList = {
|
||||||
|
"BME280", "BMP280", "BMP180", "BMP085", "HTU21", "SHT21"
|
||||||
|
};
|
||||||
|
if (std::find(sensorList.begin(), sensorList.end(), useenvsensor) != sensorList.end()) {
|
||||||
|
source = 'I';
|
||||||
|
} else {
|
||||||
|
// "off" means user external data if available
|
||||||
|
source = 'X';
|
||||||
|
}
|
||||||
|
//common.logger->logDebug(GwLog::LOG,"Source=%s (%s)", source, useenvsensor);
|
||||||
|
loadData(); // initial load
|
||||||
|
}
|
||||||
|
|
||||||
|
int handleKey(int key) {
|
||||||
|
if (key == 1) {
|
||||||
|
// zoom in
|
||||||
|
if (zoomindex > 0) {
|
||||||
|
zoomindex -= 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (key == 2) {
|
||||||
|
// zoom out
|
||||||
|
if (zoomindex < sizeof(zoom)) {
|
||||||
|
zoomindex += 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (key == 11) {
|
||||||
|
keylock = !keylock;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData) {
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int displayPage(PageData &pageData) {
|
||||||
|
|
||||||
|
// Logging boat values
|
||||||
|
logger->logDebug(GwLog::LOG, "Drawing at PageBarograph");
|
||||||
|
|
||||||
|
// Draw page
|
||||||
|
//***********************************************************
|
||||||
|
|
||||||
|
// Set display in partial refresh mode
|
||||||
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
|
// Frames
|
||||||
|
epd->fillRect(0, 75, 400, 2, commonData->fgcolor); // fillRect: x, y, w, h
|
||||||
|
epd->fillRect(130, 20, 2, 55, commonData->fgcolor);
|
||||||
|
epd->fillRect(270, 20, 2, 55, commonData->fgcolor);
|
||||||
|
epd->fillRect(325, 20, 2, 55, commonData->fgcolor);
|
||||||
|
|
||||||
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
if (source == 'I') {
|
||||||
|
drawTextCenter(360, 40, useenvsensor);
|
||||||
|
} else {
|
||||||
|
drawTextCenter(360, 40, "ext.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trend
|
||||||
|
drawTextCenter(295, 62, "0.0");
|
||||||
|
|
||||||
|
// Alarm placeholder
|
||||||
|
drawTextCenter(70, 62, "Alarm Off");
|
||||||
|
|
||||||
|
// Zoom
|
||||||
|
int datastep = series[zoomindex];
|
||||||
|
String fmt;
|
||||||
|
if (datastep > 120) {
|
||||||
|
if (datastep % 60 == 0) {
|
||||||
|
fmt = String(datastep / 60.0, 0) + " min";
|
||||||
|
} else {
|
||||||
|
fmt = String(datastep / 60.0, 1) + " min";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt = String(datastep) + " s";
|
||||||
|
}
|
||||||
|
drawTextCenter(360, 62, fmt);
|
||||||
|
|
||||||
|
// Current measurement
|
||||||
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
|
drawTextCenter(200, 40, String(commonData->data.airPressure / 100, 1));
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
drawTextCenter(200, 62, "hPa"); // Unit
|
||||||
|
|
||||||
|
// Diagram
|
||||||
|
const int xstep = 48; // x-axis-grid
|
||||||
|
const int x0 = 350; // origin
|
||||||
|
const int y0 = 270;
|
||||||
|
const int w = 7 * 48;
|
||||||
|
const int h = 180;
|
||||||
|
|
||||||
|
// epd->drawRect(x0 - w, y0 - h, w, h, commonData->fgcolor);
|
||||||
|
|
||||||
|
// x-axis are hours
|
||||||
|
for (int i = 1; i <= 6; i++) {
|
||||||
|
String label = String(-1 * zoom[zoomindex] * i);
|
||||||
|
epd->drawLine(x0 - i * xstep, y0, x0 - i * xstep, y0 - h, commonData->fgcolor);
|
||||||
|
drawTextCenter(x0 - i * xstep, y0 - 10, label);
|
||||||
|
}
|
||||||
|
|
||||||
|
// y-axis
|
||||||
|
epd->drawLine(x0 + 5, y0, x0 + 5, y0 - h, commonData->fgcolor); // drawLine: x1, y1, x2, y2
|
||||||
|
epd->drawLine(x0 - w, y0, x0 - w, y0 - h, commonData->fgcolor);
|
||||||
|
epd->drawLine(x0 - w - 5, y0, x0 - w - 5, y0 - h, commonData->fgcolor);
|
||||||
|
epd->drawLine(x0, y0, x0, y0 - h, commonData->fgcolor);
|
||||||
|
|
||||||
|
int16_t dy = 9; // px for one hPa
|
||||||
|
int16_t y = y0;
|
||||||
|
int16_t ys = scalemin;
|
||||||
|
while (y >= y0 - h) {
|
||||||
|
if (y % scalestep == 0) {
|
||||||
|
// big step, show label and long line
|
||||||
|
epd->setCursor(x0 + 10, y + 5);
|
||||||
|
epd->print(String(ys));
|
||||||
|
epd->drawLine(x0 + 5, y, x0 - w - 5, y, commonData->fgcolor);
|
||||||
|
} else {
|
||||||
|
// small step, only short lines left and right
|
||||||
|
epd->drawLine(x0 + 5, y, x0, y, commonData->fgcolor);
|
||||||
|
epd->drawLine(x0 - w - 5, y, x0 - w, y, commonData->fgcolor);
|
||||||
|
}
|
||||||
|
y -= dy;
|
||||||
|
ys += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PAGE_UPDATE;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static Page* createPage(CommonData &common){
|
||||||
|
return new PageBarograph(common);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* with the code below we make this page known to the PageTask
|
||||||
|
* we give it a type (name) that can be selected in the config
|
||||||
|
* we define which function is to be called
|
||||||
|
* and we provide the number of user parameters we expect
|
||||||
|
* this will be number of BoatValue pointers in pageData.values
|
||||||
|
*/
|
||||||
|
PageDescription registerPageBarograph(
|
||||||
|
"Barograph", // Page name
|
||||||
|
createPage, // Action
|
||||||
|
0, // No bus values needed
|
||||||
|
true // Show display header on/off
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
@@ -5,20 +6,25 @@
|
|||||||
|
|
||||||
class PageBattery : public Page
|
class PageBattery : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String powsensor1;
|
||||||
int average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s
|
int average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageBattery(CommonData &common){
|
PageBattery(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageBattery");
|
logger->logDebug(GwLog::LOG, "Instantiate PageBattery");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
String powsensor1 = config->getString(config->usePowSensor1);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupKeys(){
|
void setupKeys(){
|
||||||
Page::setupKeys();
|
Page::setupKeys();
|
||||||
commonData->keydata[0].label = "AVG";
|
commonData->keydata[0].label = "AVG";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key){
|
||||||
// Change average
|
// Change average
|
||||||
if(key == 1){
|
if(key == 1){
|
||||||
average ++;
|
average ++;
|
||||||
@@ -34,9 +40,17 @@ class PageBattery : public Page
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData) {
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
int displayPage(PageData &pageData){
|
int displayPage(PageData &pageData){
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
// Old values for hold function
|
// Old values for hold function
|
||||||
double value1 = 0;
|
double value1 = 0;
|
||||||
@@ -49,14 +63,6 @@ class PageBattery : public Page
|
|||||||
static String svalue3old = "";
|
static String svalue3old = "";
|
||||||
static String unit3old = "";
|
static String unit3old = "";
|
||||||
|
|
||||||
// Get config data
|
|
||||||
String lengthformat = config->getString(config->lengthFormat);
|
|
||||||
// bool simulation = config->getBool(config->useSimuData);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
String powsensor1 = config->getString(config->usePowSensor1);
|
|
||||||
bool simulation = config->getBool(config->useSimuData);
|
|
||||||
|
|
||||||
// Get voltage value
|
// Get voltage value
|
||||||
String name1 = "VBat"; // Value name
|
String name1 = "VBat"; // Value name
|
||||||
if(String(powsensor1) == "INA219" || String(powsensor1) == "INA226"){
|
if(String(powsensor1) == "INA219" || String(powsensor1) == "INA226"){
|
||||||
@@ -145,147 +151,141 @@ class PageBattery : public Page
|
|||||||
String svalue3 = String(value3); // Formatted value as string including unit conversion and switching decimal places
|
String svalue3 = String(value3); // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit3 = "W"; // Unit of value
|
String unit3 = "W"; // Unit of value
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
|
||||||
if(String(flashLED) == "Limit Violation"){
|
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logging boat values
|
// Logging boat values
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageBattery, %s: %f, %s: %f, %s: %f, Avg: %d", name1.c_str(), value1, name2.c_str(), value2, name3.c_str(), value3, average);
|
logger->logDebug(GwLog::LOG, "Drawing at PageBattery, %s: %f, %s: %f, %s: %f, Avg: %d", name1.c_str(), value1, name2.c_str(), value2, name3.c_str(), value3, average);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
// Show average settings
|
// Show average settings
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
switch (average) {
|
switch (average) {
|
||||||
case 0:
|
case 0:
|
||||||
getdisplay().setCursor(60, 90);
|
epd->setCursor(60, 90);
|
||||||
getdisplay().print("Avg: 1s");
|
epd->print("Avg: 1s");
|
||||||
getdisplay().setCursor(60, 180);
|
epd->setCursor(60, 180);
|
||||||
getdisplay().print("Avg: 1s");
|
epd->print("Avg: 1s");
|
||||||
getdisplay().setCursor(60, 270);
|
epd->setCursor(60, 270);
|
||||||
getdisplay().print("Avg: 1s");
|
epd->print("Avg: 1s");
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
getdisplay().setCursor(60, 90);
|
epd->setCursor(60, 90);
|
||||||
getdisplay().print("Avg: 10s");
|
epd->print("Avg: 10s");
|
||||||
getdisplay().setCursor(60, 180);
|
epd->setCursor(60, 180);
|
||||||
getdisplay().print("Avg: 10s");
|
epd->print("Avg: 10s");
|
||||||
getdisplay().setCursor(60, 270);
|
epd->setCursor(60, 270);
|
||||||
getdisplay().print("Avg: 10s");
|
epd->print("Avg: 10s");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
getdisplay().setCursor(60, 90);
|
epd->setCursor(60, 90);
|
||||||
getdisplay().print("Avg: 60s");
|
epd->print("Avg: 60s");
|
||||||
getdisplay().setCursor(60, 180);
|
epd->setCursor(60, 180);
|
||||||
getdisplay().print("Avg: 60s");
|
epd->print("Avg: 60s");
|
||||||
getdisplay().setCursor(60, 270);
|
epd->setCursor(60, 270);
|
||||||
getdisplay().print("Avg: 60s");
|
epd->print("Avg: 60s");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
getdisplay().setCursor(60, 90);
|
epd->setCursor(60, 90);
|
||||||
getdisplay().print("Avg: 300s");
|
epd->print("Avg: 300s");
|
||||||
getdisplay().setCursor(60, 180);
|
epd->setCursor(60, 180);
|
||||||
getdisplay().print("Avg: 300s");
|
epd->print("Avg: 300s");
|
||||||
getdisplay().setCursor(60, 270);
|
epd->setCursor(60, 270);
|
||||||
getdisplay().print("Avg: 300s");
|
epd->print("Avg: 300s");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
getdisplay().setCursor(60, 90);
|
epd->setCursor(60, 90);
|
||||||
getdisplay().print("Avg: 1s");
|
epd->print("Avg: 1s");
|
||||||
getdisplay().setCursor(60, 180);
|
epd->setCursor(60, 180);
|
||||||
getdisplay().print("Avg: 1s");
|
epd->print("Avg: 1s");
|
||||||
getdisplay().setCursor(60, 270);
|
epd->setCursor(60, 270);
|
||||||
getdisplay().print("Avg: 1s");
|
epd->print("Avg: 1s");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ############### Value 1 ################
|
// ############### Value 1 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 55);
|
epd->setCursor(20, 55);
|
||||||
getdisplay().print(name1); // Value name
|
epd->print(name1); // Value name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 90);
|
epd->setCursor(20, 90);
|
||||||
getdisplay().print(unit1); // Unit
|
epd->print(unit1); // Unit
|
||||||
|
|
||||||
// Show value
|
// Show value
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic30pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic30pt7b);
|
||||||
getdisplay().setCursor(180, 90);
|
epd->setCursor(180, 90);
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(String(powsensor1) != "off"){
|
if(String(powsensor1) != "off"){
|
||||||
getdisplay().print(value1,2); // Real value as formated string
|
epd->print(value1,2); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print("---"); // No sensor data (sensor is off)
|
epd->print(commonData->fmt->placeholder); // No sensor data (sensor is off)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ############### Horizontal Line ################
|
// ############### Horizontal Line ################
|
||||||
|
|
||||||
// Horizontal line 3 pix
|
// Horizontal line 3 pix
|
||||||
getdisplay().fillRect(0, 105, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, 105, 400, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 2 ################
|
// ############### Value 2 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 145);
|
epd->setCursor(20, 145);
|
||||||
getdisplay().print(name2); // Value name
|
epd->print(name2); // Value name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 180);
|
epd->setCursor(20, 180);
|
||||||
getdisplay().print(unit2); // Unit
|
epd->print(unit2); // Unit
|
||||||
|
|
||||||
// Show value
|
// Show value
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic30pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic30pt7b);
|
||||||
getdisplay().setCursor(180, 180);
|
epd->setCursor(180, 180);
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(String(powsensor1) != "off"){
|
if(String(powsensor1) != "off"){
|
||||||
getdisplay().print(value2,1); // Real value as formated string
|
epd->print(value2,1); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print("---"); // No sensor data (sensor is off)
|
epd->print(commonData->fmt->placeholder); // No sensor data (sensor is off)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ############### Horizontal Line ################
|
// ############### Horizontal Line ################
|
||||||
|
|
||||||
// Horizontal line 3 pix
|
// Horizontal line 3 pix
|
||||||
getdisplay().fillRect(0, 195, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, 195, 400, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 3 ################
|
// ############### Value 3 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 235);
|
epd->setCursor(20, 235);
|
||||||
getdisplay().print(name3); // Value name
|
epd->print(name3); // Value name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 270);
|
epd->setCursor(20, 270);
|
||||||
getdisplay().print(unit3); // Unit
|
epd->print(unit3); // Unit
|
||||||
|
|
||||||
// Show value
|
// Show value
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic30pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic30pt7b);
|
||||||
getdisplay().setCursor(180, 270);
|
epd->setCursor(180, 270);
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(String(powsensor1) != "off"){
|
if(String(powsensor1) != "off"){
|
||||||
getdisplay().print(value3,1); // Real value as formated string
|
epd->print(value3,1); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print("---"); // No sensor data (sensor is off)
|
epd->print(commonData->fmt->placeholder); // No sensor data (sensor is off)
|
||||||
}
|
}
|
||||||
|
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
@@ -6,23 +7,34 @@
|
|||||||
|
|
||||||
class PageBattery2 : public Page
|
class PageBattery2 : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String batVoltage;
|
||||||
|
int batCapacity;
|
||||||
|
String batType;
|
||||||
|
String powerSensor;
|
||||||
bool init = false; // Marker for init done
|
bool init = false; // Marker for init done
|
||||||
int average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s
|
int average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s
|
||||||
bool trend = true; // Trend indicator [0|1], 0=off, 1=on
|
bool trend = true; // Trend indicator [0|1], 0=off, 1=on
|
||||||
double raw = 0;
|
double raw = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageBattery2(CommonData &common){
|
PageBattery2(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageBattery2");
|
logger->logDebug(GwLog::LOG, "Instantiate PageBattery2");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
batVoltage = config->getString(config->batteryVoltage);
|
||||||
|
batCapacity = config->getInt(config->batteryCapacity);
|
||||||
|
batType = config->getString(config->batteryType);
|
||||||
|
powerSensor = config->getString(config->usePowSensor1);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupKeys(){
|
void setupKeys(){
|
||||||
Page::setupKeys();
|
Page::setupKeys();
|
||||||
commonData->keydata[0].label = "AVG";
|
commonData->keydata[0].label = "AVG";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key) {
|
||||||
// Change average
|
// Change average
|
||||||
if(key == 1){
|
if(key == 1){
|
||||||
average ++;
|
average ++;
|
||||||
@@ -44,11 +56,7 @@ public:
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
int displayPage(PageData &pageData)
|
int displayPage(PageData &pageData) {
|
||||||
{
|
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
// Polynominal coefficients second order for battery energy level calculation
|
// Polynominal coefficients second order for battery energy level calculation
|
||||||
// index 0 = Pb, 1 = Gel, 2 = AGM, 3 = LiFePo4
|
// index 0 = Pb, 1 = Gel, 2 = AGM, 3 = LiFePo4
|
||||||
float x0[4] = {+3082.5178, +1656.1571, +1316.8766, +14986.9336}; // Offset
|
float x0[4] = {+3082.5178, +1656.1571, +1316.8766, +14986.9336}; // Offset
|
||||||
@@ -57,16 +65,6 @@ public:
|
|||||||
int batPercentage = 0; // Battery level
|
int batPercentage = 0; // Battery level
|
||||||
float batRange = 0; // Range in hours
|
float batRange = 0; // Range in hours
|
||||||
|
|
||||||
// Get config data
|
|
||||||
bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String batVoltage = config->getString(config->batteryVoltage);
|
|
||||||
int batCapacity = config->getInt(config->batteryCapacity);
|
|
||||||
String batType = config->getString(config->batteryType);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
String powerSensor = config->getString(config->usePowSensor1);
|
|
||||||
|
|
||||||
double value1 = 0; // Battery voltage
|
double value1 = 0; // Battery voltage
|
||||||
double value2 = 0; // Battery current
|
double value2 = 0; // Battery current
|
||||||
double value3 = 0; // Battery power consumption
|
double value3 = 0; // Battery power consumption
|
||||||
@@ -142,149 +140,133 @@ public:
|
|||||||
if(batRange > 99) batRange = 99;
|
if(batRange > 99) batRange = 99;
|
||||||
|
|
||||||
// Optical warning by limit violation
|
// Optical warning by limit violation
|
||||||
if(String(flashLED) == "Limit Violation"){
|
if (flashLED == "Limit Violation") {
|
||||||
// Limits for Pb battery
|
bool violation = false;
|
||||||
if(String(batType) == "Pb" && (raw < 11.8 || raw > 14.8)){
|
if (batType == "Pb") {
|
||||||
|
violation = (raw < 11.8 || raw > 14.8);
|
||||||
|
} else if (batType == "Gel") {
|
||||||
|
violation = (raw < 11.8 || raw > 14.4);
|
||||||
|
} else if (batType == "AGM") {
|
||||||
|
violation = (raw < 11.8 || raw > 14.7);
|
||||||
|
} else if (batType == "LiFePo4") {
|
||||||
|
violation = (raw < 12.0 || raw > 14.6);
|
||||||
|
}
|
||||||
|
if (violation) {
|
||||||
setBlinkingLED(true);
|
setBlinkingLED(true);
|
||||||
}
|
} else {
|
||||||
if(String(batType) == "Pb" && (raw >= 11.8 && raw <= 14.8)){
|
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
|
||||||
// Limits for Gel battery
|
|
||||||
if(String(batType) == "Gel" && (raw < 11.8 || raw > 14.4)){
|
|
||||||
setBlinkingLED(true);
|
|
||||||
}
|
|
||||||
if(String(batType) == "Gel" && (raw >= 11.8 && raw <= 14.4)){
|
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
|
||||||
// Limits for AGM battery
|
|
||||||
if(String(batType) == "AGM" && (raw < 11.8 || raw > 14.7)){
|
|
||||||
setBlinkingLED(true);
|
|
||||||
}
|
|
||||||
if(String(batType) == "AGM" && (raw >= 11.8 && raw <= 14.7)){
|
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
|
||||||
// Limits for LiFePo4 battery
|
|
||||||
if(String(batType) == "LiFePo4" && (raw < 12.0 || raw > 14.6)){
|
|
||||||
setBlinkingLED(true);
|
|
||||||
}
|
|
||||||
if(String(batType) == "LiFePo4" && (raw >= 12.0 && raw <= 14.6)){
|
|
||||||
setBlinkingLED(false);
|
setBlinkingLED(false);
|
||||||
setFlashLED(false);
|
setFlashLED(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logging voltage value
|
// Logging voltage value
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageBattery2, Type:%s %s:=%f", batType.c_str(), name1.c_str(), raw);
|
logger->logDebug(GwLog::LOG, "Drawing at PageBattery2, Type:%s %s:=%f", batType.c_str(), name1.c_str(), raw);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(10, 65);
|
epd->setCursor(10, 65);
|
||||||
getdisplay().print("Bat.");
|
epd->print("Bat.");
|
||||||
|
|
||||||
// Show battery type
|
// Show battery type
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(90, 65);
|
epd->setCursor(90, 65);
|
||||||
getdisplay().print(batType);
|
epd->print(batType);
|
||||||
|
|
||||||
// Show voltage type
|
// Show voltage type
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(10, 140);
|
epd->setCursor(10, 140);
|
||||||
int bvoltage = 0;
|
int bvoltage = 0;
|
||||||
if(String(batVoltage) == "12V") bvoltage = 12;
|
if(String(batVoltage) == "12V") bvoltage = 12;
|
||||||
else bvoltage = 24;
|
else bvoltage = 24;
|
||||||
getdisplay().print(bvoltage);
|
epd->print(bvoltage);
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().print("V");
|
epd->print("V");
|
||||||
|
|
||||||
// Show battery capacity
|
// Show battery capacity
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(10, 200);
|
epd->setCursor(10, 200);
|
||||||
if(batCapacity <= 999) getdisplay().print(batCapacity, 0);
|
if(batCapacity <= 999) epd->print(batCapacity, 0);
|
||||||
if(batCapacity > 999) getdisplay().print(float(batCapacity/1000.0), 1);
|
if(batCapacity > 999) epd->print(float(batCapacity/1000.0), 1);
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
if(batCapacity <= 999) getdisplay().print("Ah");
|
if(batCapacity <= 999) epd->print("Ah");
|
||||||
if(batCapacity > 999) getdisplay().print("kAh");
|
if(batCapacity > 999) epd->print("kAh");
|
||||||
|
|
||||||
// Show info
|
// Show info
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(10, 235);
|
epd->setCursor(10, 235);
|
||||||
getdisplay().print("Installed");
|
epd->print("Installed");
|
||||||
getdisplay().setCursor(10, 255);
|
epd->setCursor(10, 255);
|
||||||
getdisplay().print("Battery Type");
|
epd->print("Battery Type");
|
||||||
|
|
||||||
// Show battery with fill level
|
// Show battery with fill level
|
||||||
batteryGraphic(150, 45, batPercentage, commonData->fgcolor, commonData->bgcolor);
|
batteryGraphic(150, 45, batPercentage, commonData->fgcolor, commonData->bgcolor);
|
||||||
|
|
||||||
// Show average settings
|
// Show average settings
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(150, 145);
|
epd->setCursor(150, 145);
|
||||||
switch (average) {
|
switch (average) {
|
||||||
case 0:
|
case 0:
|
||||||
getdisplay().print("Avg: 1s");
|
epd->print("Avg: 1s");
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
getdisplay().print("Avg: 10s");
|
epd->print("Avg: 10s");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
getdisplay().print("Avg: 60s");
|
epd->print("Avg: 60s");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
getdisplay().print("Avg: 300s");
|
epd->print("Avg: 300s");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
getdisplay().print("Avg: 1s");
|
epd->print("Avg: 1s");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show fill level in percent
|
// Show fill level in percent
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(150, 200);
|
epd->setCursor(150, 200);
|
||||||
getdisplay().print(batPercentage);
|
epd->print(batPercentage);
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().print("%");
|
epd->print("%");
|
||||||
|
|
||||||
// Show time to full discharge
|
// Show time to full discharge
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(150, 260);
|
epd->setCursor(150, 260);
|
||||||
if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){
|
if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){
|
||||||
if(batRange < 9.9) getdisplay().print(batRange, 1);
|
if(batRange < 9.9) epd->print(batRange, 1);
|
||||||
else getdisplay().print(batRange, 0);
|
else epd->print(batRange, 0);
|
||||||
}
|
}
|
||||||
else getdisplay().print("--");
|
else epd->print("--");
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().print("h");
|
epd->print("h");
|
||||||
|
|
||||||
// Show sensor type info
|
// Show sensor type info
|
||||||
String i2cAddr = "";
|
String i2cAddr = "";
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(270, 60);
|
epd->setCursor(270, 60);
|
||||||
if(powerSensor == "off") getdisplay().print("Internal");
|
if(powerSensor == "off") epd->print("Internal");
|
||||||
if(powerSensor == "INA219"){
|
if(powerSensor == "INA219"){
|
||||||
getdisplay().print("INA219");
|
epd->print("INA219");
|
||||||
}
|
}
|
||||||
if(powerSensor == "INA226"){
|
if(powerSensor == "INA226"){
|
||||||
getdisplay().print("INA226");
|
epd->print("INA226");
|
||||||
i2cAddr = " (0x" + String(INA226_I2C_ADDR1, HEX) + ")";
|
i2cAddr = " (0x" + String(INA226_I2C_ADDR1, HEX) + ")";
|
||||||
}
|
}
|
||||||
getdisplay().print(i2cAddr);
|
epd->print(i2cAddr);
|
||||||
getdisplay().setCursor(270, 80);
|
epd->setCursor(270, 80);
|
||||||
getdisplay().print("Sensor Modul");
|
epd->print("Sensor Modul");
|
||||||
|
|
||||||
// Reading bus data or using simulation data
|
// Reading bus data or using simulation data
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(260, 140);
|
epd->setCursor(260, 140);
|
||||||
if(simulation == true){
|
if(simulation == true){
|
||||||
if(batVoltage == "12V"){
|
if(batVoltage == "12V"){
|
||||||
value1 = 12.0;
|
value1 = 12.0;
|
||||||
@@ -293,46 +275,50 @@ public:
|
|||||||
value1 = 24.0;
|
value1 = 24.0;
|
||||||
}
|
}
|
||||||
value1 += float(random(0, 5)) / 10; // Simulation data
|
value1 += float(random(0, 5)) / 10; // Simulation data
|
||||||
getdisplay().print(value1,1);
|
epd->print(value1,1);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// Check for valid real data, display also if hold values activated
|
// Check for valid real data, display also if hold values activated
|
||||||
if(valid1 == true || holdvalues == true){
|
if(valid1 == true || holdvalues == true){
|
||||||
// Resolution switching
|
// Resolution switching
|
||||||
if(value1 <= 9.9) getdisplay().print(value1, 2);
|
if(value1 <= 9.9) epd->print(value1, 2);
|
||||||
if(value1 > 9.9 && value1 <= 99.9)getdisplay().print(value1, 1);
|
if(value1 > 9.9 && value1 <= 99.9)epd->print(value1, 1);
|
||||||
if(value1 > 99.9) getdisplay().print(value1, 0);
|
if(value1 > 99.9) epd->print(value1, 0);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print("---"); // Missing bus data
|
epd->print(commonData->fmt->placeholder); // Missing bus data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().print("V");
|
epd->print("V");
|
||||||
|
|
||||||
// Show actual current in A
|
// Show actual current in A
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(260, 200);
|
epd->setCursor(260, 200);
|
||||||
if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){
|
if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){
|
||||||
if(value2 <= 9.9) getdisplay().print(value2, 2);
|
if(value2 <= 9.9) epd->print(value2, 2);
|
||||||
if(value2 > 9.9 && value2 <= 99.9)getdisplay().print(value2, 1);
|
if(value2 > 9.9 && value2 <= 99.9)epd->print(value2, 1);
|
||||||
if(value2 > 99.9) getdisplay().print(value2, 0);
|
if(value2 > 99.9) epd->print(value2, 0);
|
||||||
}
|
}
|
||||||
else getdisplay().print("---");
|
else {
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->print(commonData->fmt->placeholder);
|
||||||
getdisplay().print("A");
|
}
|
||||||
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
|
epd->print("A");
|
||||||
|
|
||||||
// Show actual consumption in W
|
// Show actual consumption in W
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(260, 260);
|
epd->setCursor(260, 260);
|
||||||
if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){
|
if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){
|
||||||
if(value3 <= 9.9) getdisplay().print(value3, 2);
|
if(value3 <= 9.9) epd->print(value3, 2);
|
||||||
if(value3 > 9.9 && value3 <= 99.9)getdisplay().print(value3, 1);
|
if(value3 > 9.9 && value3 <= 99.9)epd->print(value3, 1);
|
||||||
if(value3 > 99.9) getdisplay().print(value3, 0);
|
if(value3 > 99.9) epd->print(value3, 0);
|
||||||
}
|
}
|
||||||
else getdisplay().print("---");
|
else {
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->print(commonData->fmt->placeholder);
|
||||||
getdisplay().print("W");
|
}
|
||||||
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
|
epd->print("W");
|
||||||
|
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
@@ -16,7 +17,8 @@
|
|||||||
|
|
||||||
class PageClock : public Page
|
class PageClock : public Page
|
||||||
{
|
{
|
||||||
bool simulation = false;
|
private:
|
||||||
|
fmtDate dateformat;
|
||||||
int simtime;
|
int simtime;
|
||||||
bool keylock = false;
|
bool keylock = false;
|
||||||
char source = 'R'; // time source (R)TC | (G)PS | (N)TP
|
char source = 'R'; // time source (R)TC | (G)PS | (N)TP
|
||||||
@@ -28,18 +30,28 @@ double homelon;
|
|||||||
bool homevalid = false; // homelat and homelon are valid
|
bool homevalid = false; // homelat and homelon are valid
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageClock(CommonData &common){
|
PageClock(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageClock");
|
logger->logDebug(GwLog::LOG, "Instantiate PageClock");
|
||||||
simulation = common.config->getBool(common.config->useSimuData);
|
|
||||||
timezone = common.config->getString(common.config->timeZone).toDouble();
|
// Get config data
|
||||||
homelat = common.config->getString(common.config->homeLAT).toDouble();
|
dateformat = common.fmt->getDateFormat(config->getString(config->dateFormat));
|
||||||
homelon = common.config->getString(common.config->homeLON).toDouble();
|
timezone = config->getString(config->timeZone).toDouble();
|
||||||
|
homelat = config->getString(config->homeLAT).toDouble();
|
||||||
|
homelon = config->getString(config->homeLON).toDouble();
|
||||||
homevalid = homelat >= -180.0 and homelat <= 180 and homelon >= -90.0 and homelon <= 90.0;
|
homevalid = homelat >= -180.0 and homelat <= 180 and homelon >= -90.0 and homelon <= 90.0;
|
||||||
simtime = 38160; // time value 11:36
|
simtime = 38160; // time value 11:36
|
||||||
|
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// WIP time source
|
||||||
|
String use_rtc = config->getString(config->useRTC);
|
||||||
|
if (use_rtc == "off") {
|
||||||
|
source = 'G';
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupKeys(){
|
void setupKeys(){
|
||||||
Page::setupKeys();
|
Page::setupKeys();
|
||||||
commonData->keydata[0].label = "SRC";
|
commonData->keydata[0].label = "SRC";
|
||||||
commonData->keydata[1].label = "MODE";
|
commonData->keydata[1].label = "MODE";
|
||||||
@@ -47,7 +59,7 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Key functions
|
// Key functions
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key){
|
||||||
// Time source
|
// Time source
|
||||||
if (key == 1) {
|
if (key == 1) {
|
||||||
if (source == 'G') {
|
if (source == 'G') {
|
||||||
@@ -85,10 +97,17 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
int displayPage(PageData &pageData)
|
void displayNew(PageData &pageData) {
|
||||||
{
|
#ifdef BOARD_OBP60S3
|
||||||
GwConfigHandler *config = commonData->config;
|
// Clear optical warning
|
||||||
GwLog *logger = commonData->logger;
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int displayPage(PageData &pageData) {
|
||||||
|
|
||||||
static String svalue1old = "";
|
static String svalue1old = "";
|
||||||
static String unit1old = "";
|
static String unit1old = "";
|
||||||
@@ -100,16 +119,10 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
static String svalue5old = "";
|
static String svalue5old = "";
|
||||||
static String svalue6old = "";
|
static String svalue6old = "";
|
||||||
|
|
||||||
double value1 = 0;
|
double value1 = 0; // GPS time
|
||||||
double value2 = 0;
|
double value2 = 0; // GPS date FIXME date defined as uint32_t!
|
||||||
double value3 = 0;
|
double value3 = 0; // HDOP
|
||||||
|
bool gpsvalid = false;
|
||||||
// Get config data
|
|
||||||
String lengthformat = config->getString(config->lengthFormat);
|
|
||||||
String dateformat = config->getString(config->dateFormat);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
|
|
||||||
// Get boat values for GPS time
|
// Get boat values for GPS time
|
||||||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
||||||
@@ -122,8 +135,8 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
value1 = simtime++; // Simulation data for time value 11:36 in seconds
|
value1 = simtime++; // Simulation data for time value 11:36 in seconds
|
||||||
} // Other simulation data see OBP60Formatter.cpp
|
} // Other simulation data see OBP60Formatter.cpp
|
||||||
bool valid1 = bvalue1->valid; // Valid information
|
bool valid1 = bvalue1->valid; // Valid information
|
||||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue1 = commonData->fmt->formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
String unit1 = commonData->fmt->formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||||
if(valid1 == true){
|
if(valid1 == true){
|
||||||
svalue1old = svalue1; // Save old value
|
svalue1old = svalue1; // Save old value
|
||||||
unit1old = unit1; // Save old unit
|
unit1old = unit1; // Save old unit
|
||||||
@@ -135,8 +148,8 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
name2 = name2.substring(0, 6); // String length limit for value name
|
name2 = name2.substring(0, 6); // String length limit for value name
|
||||||
value2 = bvalue2->value; // Value as double in SI unit
|
value2 = bvalue2->value; // Value as double in SI unit
|
||||||
bool valid2 = bvalue2->valid; // Valid information
|
bool valid2 = bvalue2->valid; // Valid information
|
||||||
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue2 = commonData->fmt->formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
String unit2 = commonData->fmt->formatValue(bvalue2, *commonData).unit; // Unit of value
|
||||||
if(valid2 == true){
|
if(valid2 == true){
|
||||||
svalue2old = svalue2; // Save old value
|
svalue2old = svalue2; // Save old value
|
||||||
unit2old = unit2; // Save old unit
|
unit2old = unit2; // Save old unit
|
||||||
@@ -148,13 +161,16 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
name3 = name3.substring(0, 6); // String length limit for value name
|
name3 = name3.substring(0, 6); // String length limit for value name
|
||||||
value3 = bvalue3->value; // Value as double in SI unit
|
value3 = bvalue3->value; // Value as double in SI unit
|
||||||
bool valid3 = bvalue3->valid; // Valid information
|
bool valid3 = bvalue3->valid; // Valid information
|
||||||
String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue3 = commonData->fmt->formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value
|
String unit3 = commonData->fmt->formatValue(bvalue3, *commonData).unit; // Unit of value
|
||||||
if(valid3 == true){
|
if(valid3 == true){
|
||||||
svalue3old = svalue3; // Save old value
|
svalue3old = svalue3; // Save old value
|
||||||
unit3old = unit3; // Save old unit
|
unit3old = unit3; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GPS date and time are valid and can be used
|
||||||
|
gpsvalid = (valid1 && valid2 && valid3);
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
// Optical warning by limit violation (unused)
|
||||||
if(String(flashLED) == "Limit Violation"){
|
if(String(flashLED) == "Limit Violation"){
|
||||||
setBlinkingLED(false);
|
setBlinkingLED(false);
|
||||||
@@ -163,108 +179,108 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
|
|
||||||
// Logging boat values
|
// Logging boat values
|
||||||
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageClock, %s:%f, %s:%f", name1.c_str(), value1, name2.c_str(), value2);
|
logger->logDebug(GwLog::LOG, "Drawing at PageClock, %s:%f, %s:%f, %s:%f", name1.c_str(), value1, name2.c_str(), value2, name3.c_str(), value3);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
time_t tv = mktime(&commonData->data.rtcTime) + timezone * 3600;
|
time_t tv = mktime(&commonData->data.rtcTime) + timezone * 3600;
|
||||||
struct tm *local_tm = localtime(&tv);
|
struct tm *local_tm = localtime(&tv);
|
||||||
|
|
||||||
// Show values GPS date
|
// Show values GPS date
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(10, 65);
|
epd->setCursor(10, 65);
|
||||||
if (holdvalues == false) {
|
if (holdvalues == false) {
|
||||||
if (source == 'G') {
|
if (source == 'G') {
|
||||||
// GPS value
|
// GPS value
|
||||||
getdisplay().print(svalue2);
|
epd->print(svalue2);
|
||||||
} else if (commonData->data.rtcValid) {
|
} else if (commonData->data.rtcValid) {
|
||||||
// RTC value
|
// RTC value
|
||||||
if (tz == 'L') {
|
if (tz == 'L') {
|
||||||
getdisplay().print(formatDate(dateformat, local_tm->tm_year + 1900, local_tm->tm_mon + 1, local_tm->tm_mday));
|
epd->print(formatDate(dateformat, local_tm->tm_year + 1900, local_tm->tm_mon + 1, local_tm->tm_mday));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
getdisplay().print(formatDate(dateformat, commonData->data.rtcTime.tm_year + 1900, commonData->data.rtcTime.tm_mon + 1, commonData->data.rtcTime.tm_mday));
|
epd->print(formatDate(dateformat, commonData->data.rtcTime.tm_year + 1900, commonData->data.rtcTime.tm_mon + 1, commonData->data.rtcTime.tm_mday));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
getdisplay().print("---");
|
epd->print(commonData->fmt->placeholder);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
getdisplay().print(svalue2old);
|
epd->print(svalue2old);
|
||||||
}
|
}
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(10, 95);
|
epd->setCursor(10, 95);
|
||||||
getdisplay().print("Date"); // Name
|
epd->print("Date"); // Name
|
||||||
|
|
||||||
// Horizintal separator left
|
// Horizintal separator left
|
||||||
getdisplay().fillRect(0, 149, 60, 3, commonData->fgcolor);
|
epd->fillRect(0, 149, 60, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// Show values GPS time
|
// Show values GPS time
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(10, 250);
|
epd->setCursor(10, 250);
|
||||||
if (holdvalues == false) {
|
if (holdvalues == false) {
|
||||||
if (source == 'G') {
|
if (source == 'G') {
|
||||||
getdisplay().print(svalue1); // Value
|
epd->print(svalue1); // Value
|
||||||
}
|
}
|
||||||
else if (commonData->data.rtcValid) {
|
else if (commonData->data.rtcValid) {
|
||||||
if (tz == 'L') {
|
if (tz == 'L') {
|
||||||
getdisplay().print(formatTime('s', local_tm->tm_hour, local_tm->tm_min, local_tm->tm_sec));
|
epd->print(formatTime(fmtTime::MMHHSS, local_tm->tm_hour, local_tm->tm_min, local_tm->tm_sec));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
getdisplay().print(formatTime('s', commonData->data.rtcTime.tm_hour, commonData->data.rtcTime.tm_min, commonData->data.rtcTime.tm_sec));
|
epd->print(formatTime(fmtTime::MMHHSS, commonData->data.rtcTime.tm_hour, commonData->data.rtcTime.tm_min, commonData->data.rtcTime.tm_sec));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
getdisplay().print("---");
|
epd->print(commonData->fmt->placeholder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
getdisplay().print(svalue1old);
|
epd->print(svalue1old);
|
||||||
}
|
}
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(10, 220);
|
epd->setCursor(10, 220);
|
||||||
getdisplay().print("Time"); // Name
|
epd->print("Time"); // Name
|
||||||
|
|
||||||
// Show values sunrise
|
// Show values sunrise
|
||||||
String sunrise = "---";
|
String sunrise = commonData->fmt->placeholder;
|
||||||
if ((valid1 and valid2 and valid3 == true) or (homevalid and commonData->data.rtcValid)) {
|
if (((source == 'G') and gpsvalid) or (homevalid and commonData->data.rtcValid)) {
|
||||||
sunrise = String(commonData->sundata.sunriseHour) + ":" + String(commonData->sundata.sunriseMinute + 100).substring(1);
|
sunrise = String(commonData->sundata.sunriseHour) + ":" + String(commonData->sundata.sunriseMinute + 100).substring(1);
|
||||||
svalue5old = sunrise;
|
svalue5old = sunrise;
|
||||||
} else if (simulation) {
|
} else if (simulation) {
|
||||||
sunrise = String("06:42");
|
sunrise = String("06:42");
|
||||||
}
|
}
|
||||||
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(335, 65);
|
epd->setCursor(335, 65);
|
||||||
if(holdvalues == false) getdisplay().print(sunrise); // Value
|
if(holdvalues == false) epd->print(sunrise); // Value
|
||||||
else getdisplay().print(svalue5old);
|
else epd->print(svalue5old);
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(335, 95);
|
epd->setCursor(335, 95);
|
||||||
getdisplay().print("SunR"); // Name
|
epd->print("SunR"); // Name
|
||||||
|
|
||||||
// Horizintal separator right
|
// Horizintal separator right
|
||||||
getdisplay().fillRect(340, 149, 80, 3, commonData->fgcolor);
|
epd->fillRect(340, 149, 80, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// Show values sunset
|
// Show values sunset
|
||||||
String sunset = "---";
|
String sunset = commonData->fmt->placeholder;
|
||||||
if ((valid1 and valid2 and valid3 == true) or (homevalid and commonData->data.rtcValid)) {
|
if (((source == 'G') and gpsvalid) or (homevalid and commonData->data.rtcValid)) {
|
||||||
sunset = String(commonData->sundata.sunsetHour) + ":" + String(commonData->sundata.sunsetMinute + 100).substring(1);
|
sunset = String(commonData->sundata.sunsetHour) + ":" + String(commonData->sundata.sunsetMinute + 100).substring(1);
|
||||||
svalue6old = sunset;
|
svalue6old = sunset;
|
||||||
} else if (simulation) {
|
} else if (simulation) {
|
||||||
sunset = String("21:03");
|
sunset = String("21:03");
|
||||||
}
|
}
|
||||||
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(335, 250);
|
epd->setCursor(335, 250);
|
||||||
if(holdvalues == false) getdisplay().print(sunset); // Value
|
if(holdvalues == false) epd->print(sunset); // Value
|
||||||
else getdisplay().print(svalue6old);
|
else epd->print(svalue6old);
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(335, 220);
|
epd->setCursor(335, 220);
|
||||||
getdisplay().print("SunS"); // Name
|
epd->print("SunS"); // Name
|
||||||
|
|
||||||
//*******************************************************************************************
|
//*******************************************************************************************
|
||||||
|
|
||||||
@@ -272,8 +288,8 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
int rInstrument = 110; // Radius of clock
|
int rInstrument = 110; // Radius of clock
|
||||||
float pi = 3.141592;
|
float pi = 3.141592;
|
||||||
|
|
||||||
getdisplay().fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle
|
epd->fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle
|
||||||
getdisplay().fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle
|
epd->fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle
|
||||||
|
|
||||||
for(int i=0; i<360; i=i+1)
|
for(int i=0; i<360; i=i+1)
|
||||||
{
|
{
|
||||||
@@ -301,11 +317,11 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
// Print text centered on position x, y
|
// Print text centered on position x, y
|
||||||
int16_t x1, y1; // Return values of getTextBounds
|
int16_t x1, y1; // Return values of getTextBounds
|
||||||
uint16_t w, h; // Return values of getTextBounds
|
uint16_t w, h; // Return values of getTextBounds
|
||||||
getdisplay().getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string
|
epd->getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string
|
||||||
getdisplay().setCursor(x-w/2, y+h/2);
|
epd->setCursor(x-w/2, y+h/2);
|
||||||
if(i % 30 == 0){
|
if(i % 30 == 0){
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().print(ii);
|
epd->print(ii);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw sub scale with dots
|
// Draw sub scale with dots
|
||||||
@@ -314,7 +330,7 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
if(i % 6 == 0){
|
if(i % 6 == 0){
|
||||||
float x1c = 200 + rInstrument*sin(i/180.0*pi);
|
float x1c = 200 + rInstrument*sin(i/180.0*pi);
|
||||||
float y1c = 150 - rInstrument*cos(i/180.0*pi);
|
float y1c = 150 - rInstrument*cos(i/180.0*pi);
|
||||||
getdisplay().fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor);
|
epd->fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor);
|
||||||
sinx=sin(i/180.0*pi);
|
sinx=sin(i/180.0*pi);
|
||||||
cosx=cos(i/180.0*pi);
|
cosx=cos(i/180.0*pi);
|
||||||
}
|
}
|
||||||
@@ -326,31 +342,31 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
float xx2 = +dx;
|
float xx2 = +dx;
|
||||||
float yy1 = -(rInstrument-10);
|
float yy1 = -(rInstrument-10);
|
||||||
float yy2 = -(rInstrument+10);
|
float yy2 = -(rInstrument+10);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),
|
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),
|
||||||
200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print Unit in clock
|
// Print Unit in clock
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(175, 110);
|
epd->setCursor(175, 110);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(tz == 'L' ? "LOT" : "UTC");
|
epd->print(tz == 'L' ? "LOT" : "UTC");
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit2old); // date unit
|
epd->print(unit2old); // date unit
|
||||||
}
|
}
|
||||||
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(185, 190);
|
epd->setCursor(185, 190);
|
||||||
if (source == 'G') {
|
if (source == 'G') {
|
||||||
getdisplay().print("GPS");
|
epd->print("GPS");
|
||||||
} else {
|
} else {
|
||||||
getdisplay().print("RTC");
|
epd->print("RTC");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clock values
|
// Clock values
|
||||||
@@ -380,7 +396,7 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
if (hour > 12) {
|
if (hour > 12) {
|
||||||
hour -= 12.0;
|
hour -= 12.0;
|
||||||
}
|
}
|
||||||
LOG_DEBUG(GwLog::DEBUG,"... PageClock, value1: %f hour: %f minute:%f", value1, hour, minute);
|
logger->logDebug(GwLog::DEBUG, "... PageClock, value1: %f hour: %f minute:%f", value1, hour, minute);
|
||||||
|
|
||||||
// Draw hour pointer
|
// Draw hour pointer
|
||||||
float startwidth = 8; // Start width of pointer
|
float startwidth = 8; // Start width of pointer
|
||||||
@@ -393,7 +409,7 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
float xx2 = startwidth;
|
float xx2 = startwidth;
|
||||||
float yy1 = -startwidth;
|
float yy1 = -startwidth;
|
||||||
float yy2 = -(rInstrument * 0.5);
|
float yy2 = -(rInstrument * 0.5);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
||||||
// Inverted pointer
|
// Inverted pointer
|
||||||
@@ -403,7 +419,7 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
float ix2 = -endwidth;
|
float ix2 = -endwidth;
|
||||||
float iy1 = -(rInstrument * 0.5);
|
float iy1 = -(rInstrument * 0.5);
|
||||||
float iy2 = -endwidth;
|
float iy2 = -endwidth;
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1),
|
epd->fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1),
|
||||||
200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1),
|
200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1),
|
||||||
200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor);
|
||||||
}
|
}
|
||||||
@@ -419,7 +435,7 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
float xx2 = startwidth;
|
float xx2 = startwidth;
|
||||||
float yy1 = -startwidth;
|
float yy1 = -startwidth;
|
||||||
float yy2 = -(rInstrument - 15);
|
float yy2 = -(rInstrument - 15);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
||||||
// Inverted pointer
|
// Inverted pointer
|
||||||
@@ -429,14 +445,14 @@ bool homevalid = false; // homelat and homelon are valid
|
|||||||
float ix2 = -endwidth;
|
float ix2 = -endwidth;
|
||||||
float iy1 = -(rInstrument - 15);
|
float iy1 = -(rInstrument - 15);
|
||||||
float iy2 = -endwidth;
|
float iy2 = -endwidth;
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1),
|
epd->fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1),
|
||||||
200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1),
|
200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1),
|
||||||
200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Center circle
|
// Center circle
|
||||||
getdisplay().fillCircle(200, 150, startwidth + 6, commonData->bgcolor);
|
epd->fillCircle(200, 150, startwidth + 6, commonData->bgcolor);
|
||||||
getdisplay().fillCircle(200, 150, startwidth + 4, commonData->fgcolor);
|
epd->fillCircle(200, 150, startwidth + 4, commonData->fgcolor);
|
||||||
|
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
@@ -24,24 +25,24 @@ const float Compass_LineDelta = 8.0;// compass band: 1deg = 5 Pixels, 10deg = 50
|
|||||||
|
|
||||||
class PageCompass : public Page
|
class PageCompass : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
int WhichDataCompass = ShowHDM;
|
int WhichDataCompass = ShowHDM;
|
||||||
int WhichDataDisplay = ShowHDM;
|
int WhichDataDisplay = ShowHDM;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageCompass(CommonData &common){
|
PageCompass(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageCompass");
|
logger->logDebug(GwLog::LOG, "Instantiate PageCompass");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupKeys(){
|
void setupKeys(){
|
||||||
Page::setupKeys();
|
Page::setupKeys();
|
||||||
commonData->keydata[0].label = "CMP";
|
commonData->keydata[0].label = "CMP";
|
||||||
commonData->keydata[1].label = "SRC";
|
commonData->keydata[1].label = "SRC";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key){
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
|
|
||||||
if (key == 1) {
|
if (key == 1) {
|
||||||
WhichDataCompass += 1;
|
WhichDataCompass += 1;
|
||||||
if ( WhichDataCompass > ShowCOG)
|
if ( WhichDataCompass > ShowCOG)
|
||||||
@@ -53,7 +54,6 @@ class PageCompass : public Page
|
|||||||
if (WhichDataDisplay > ShowDBS)
|
if (WhichDataDisplay > ShowDBS)
|
||||||
WhichDataDisplay = ShowHDM;
|
WhichDataDisplay = ShowHDM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == 11) {
|
if (key == 11) {
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
return 0; // Commit the key
|
return 0; // Commit the key
|
||||||
@@ -61,21 +61,22 @@ class PageCompass : public Page
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData) {
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
int displayPage(PageData &pageData) {
|
int displayPage(PageData &pageData) {
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
// Old values for hold function
|
// Old values for hold function
|
||||||
static String OldDataText[HowManyValues] = {"", "", "","", "", ""};
|
static String OldDataText[HowManyValues] = {"", "", "","", "", ""};
|
||||||
static String OldDataUnits[HowManyValues] = {"", "", "","", "", ""};
|
static String OldDataUnits[HowManyValues] = {"", "", "","", "", ""};
|
||||||
|
|
||||||
// Get config data
|
|
||||||
String lengthformat = config->getString(config->lengthFormat);
|
|
||||||
// bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
|
|
||||||
GwApi::BoatValue *bvalue;
|
GwApi::BoatValue *bvalue;
|
||||||
String DataName[HowManyValues];
|
String DataName[HowManyValues];
|
||||||
double DataValue[HowManyValues];
|
double DataValue[HowManyValues];
|
||||||
@@ -87,21 +88,15 @@ class PageCompass : public Page
|
|||||||
|
|
||||||
for (int i = 0; i < HowManyValues; i++){
|
for (int i = 0; i < HowManyValues; i++){
|
||||||
bvalue = pageData.values[i];
|
bvalue = pageData.values[i];
|
||||||
TheFormattedData = formatValue(bvalue, *commonData);
|
TheFormattedData = commonData->fmt->formatValue(bvalue, *commonData);
|
||||||
DataName[i] = xdrDelete(bvalue->getName());
|
DataName[i] = xdrDelete(bvalue->getName());
|
||||||
DataName[i] = DataName[i].substring(0, 6); // String length limit for value name
|
DataName[i] = DataName[i].substring(0, 6); // String length limit for value name
|
||||||
DataUnits[i] = formatValue(bvalue, *commonData).unit;
|
DataUnits[i] = commonData->fmt->formatValue(bvalue, *commonData).unit;
|
||||||
DataText[i] = TheFormattedData.svalue; // Formatted value as string including unit conversion and switching decimal places
|
DataText[i] = TheFormattedData.svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
DataValue[i] = TheFormattedData.value; // Value as double in SI unit
|
DataValue[i] = TheFormattedData.value; // Value as double in SI unit
|
||||||
DataValid[i] = bvalue->valid;
|
DataValid[i] = bvalue->valid;
|
||||||
DataFormat[i] = bvalue->getFormat(); // Unit of value
|
DataFormat[i] = bvalue->getFormat(); // Unit of value
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageCompass: %d %s %f %s %s", i, DataName[i], DataValue[i], DataFormat[i], DataText[i] );
|
logger->logDebug(GwLog::LOG, "Drawing at PageCompass: %d %s %f %s %s", i, DataName[i], DataValue[i], DataFormat[i], DataText[i] );
|
||||||
}
|
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
|
||||||
if(String(flashLED) == "Limit Violation"){
|
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bvalue == NULL) return PAGE_OK; // WTF why this statement?
|
if (bvalue == NULL) return PAGE_OK; // WTF why this statement?
|
||||||
@@ -109,27 +104,27 @@ class PageCompass : public Page
|
|||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
// Horizontal line 2 pix top & bottom
|
// Horizontal line 2 pix top & bottom
|
||||||
// Print data on top half
|
// Print data on top half
|
||||||
getdisplay().fillRect(0, 130, 400, 2, commonData->fgcolor);
|
epd->fillRect(0, 130, 400, 2, commonData->fgcolor);
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(10, 70);
|
epd->setCursor(10, 70);
|
||||||
getdisplay().print(DataName[WhichDataDisplay]); // Page name
|
epd->print(DataName[WhichDataDisplay]); // Page name
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(10, 120);
|
epd->setCursor(10, 120);
|
||||||
getdisplay().print(DataUnits[WhichDataDisplay]);
|
epd->print(DataUnits[WhichDataDisplay]);
|
||||||
getdisplay().setCursor(190, 120);
|
epd->setCursor(190, 120);
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic42pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic42pt7b);
|
||||||
|
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(DataText[WhichDataDisplay]); // Real value as formated string
|
epd->print(DataText[WhichDataDisplay]); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(OldDataText[WhichDataDisplay]); // Old value as formated string
|
epd->print(OldDataText[WhichDataDisplay]); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(DataValid[WhichDataDisplay] == true){
|
if(DataValid[WhichDataDisplay] == true){
|
||||||
OldDataText[WhichDataDisplay] = DataText[WhichDataDisplay]; // Save the old value
|
OldDataText[WhichDataDisplay] = DataText[WhichDataDisplay]; // Save the old value
|
||||||
@@ -148,14 +143,14 @@ class PageCompass : public Page
|
|||||||
char buffer[bsize+1];
|
char buffer[bsize+1];
|
||||||
buffer[0]=0;
|
buffer[0]=0;
|
||||||
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().setCursor(10, Compass_Y0-60);
|
epd->setCursor(10, Compass_Y0-60);
|
||||||
getdisplay().print(DataName[WhichDataCompass]); // Page name
|
epd->print(DataName[WhichDataCompass]); // Page name
|
||||||
|
|
||||||
|
|
||||||
// Draw compass base line and pointer
|
// Draw compass base line and pointer
|
||||||
getdisplay().fillRect(0, Compass_Y0, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, Compass_Y0, 400, 3, commonData->fgcolor);
|
||||||
getdisplay().fillTriangle(Compass_X0,Compass_Y0-40,Compass_X0-10,Compass_Y0-80,Compass_X0+10,Compass_Y0-80,commonData->fgcolor);
|
epd->fillTriangle(Compass_X0,Compass_Y0-40,Compass_X0-10,Compass_Y0-80,Compass_X0+10,Compass_Y0-80,commonData->fgcolor);
|
||||||
// Draw trendlines
|
// Draw trendlines
|
||||||
for ( int i = 1; i < abs(TheTrend) / 2; i++){
|
for ( int i = 1; i < abs(TheTrend) / 2; i++){
|
||||||
int x1;
|
int x1;
|
||||||
@@ -164,7 +159,7 @@ class PageCompass : public Page
|
|||||||
else
|
else
|
||||||
x1 = Compass_X0 - 20 * ( i + 1 );
|
x1 = Compass_X0 - 20 * ( i + 1 );
|
||||||
|
|
||||||
getdisplay().fillRect(x1, Compass_Y0 -55, 10, 6, commonData->fgcolor);
|
epd->fillRect(x1, Compass_Y0 -55, 10, 6, commonData->fgcolor);
|
||||||
}
|
}
|
||||||
// Central line + satellite lines
|
// Central line + satellite lines
|
||||||
double NextSector = round(TheAngle / ( M_PI / 9 )) * ( M_PI / 9 ); // Get the next 20degree value
|
double NextSector = round(TheAngle / ( M_PI / 9 )) * ( M_PI / 9 ); // Get the next 20degree value
|
||||||
@@ -174,28 +169,28 @@ class PageCompass : public Page
|
|||||||
for ( int i = 0; i <=4; i++ ){
|
for ( int i = 0; i <=4; i++ ){
|
||||||
int x0;
|
int x0;
|
||||||
x0 = Compass_X0 + Delta_X + 2 * i * 5 * Compass_LineDelta;
|
x0 = Compass_X0 + Delta_X + 2 * i * 5 * Compass_LineDelta;
|
||||||
getdisplay().fillRect(x0-2, Compass_Y0 - 2 * Compass_LineLength, 5, 2 * Compass_LineLength, commonData->fgcolor);
|
epd->fillRect(x0-2, Compass_Y0 - 2 * Compass_LineLength, 5, 2 * Compass_LineLength, commonData->fgcolor);
|
||||||
x0 = Compass_X0 + Delta_X + ( 2 * i + 1 ) * 5 * Compass_LineDelta;
|
x0 = Compass_X0 + Delta_X + ( 2 * i + 1 ) * 5 * Compass_LineDelta;
|
||||||
getdisplay().fillRect(x0-1, Compass_Y0 - Compass_LineLength, 3, Compass_LineLength, commonData->fgcolor);
|
epd->fillRect(x0-1, Compass_Y0 - Compass_LineLength, 3, Compass_LineLength, commonData->fgcolor);
|
||||||
|
|
||||||
x0 = Compass_X0 + Delta_X - 2 * i * 5 * Compass_LineDelta;
|
x0 = Compass_X0 + Delta_X - 2 * i * 5 * Compass_LineDelta;
|
||||||
getdisplay().fillRect(x0-2, Compass_Y0 - 2 * Compass_LineLength, 5, 2 * Compass_LineLength, commonData->fgcolor);
|
epd->fillRect(x0-2, Compass_Y0 - 2 * Compass_LineLength, 5, 2 * Compass_LineLength, commonData->fgcolor);
|
||||||
x0 = Compass_X0 + Delta_X - ( 2 * i + 1 ) * 5 * Compass_LineDelta;
|
x0 = Compass_X0 + Delta_X - ( 2 * i + 1 ) * 5 * Compass_LineDelta;
|
||||||
getdisplay().fillRect(x0-1, Compass_Y0 - Compass_LineLength, 3, Compass_LineLength, commonData->fgcolor);
|
epd->fillRect(x0-1, Compass_Y0 - Compass_LineLength, 3, Compass_LineLength, commonData->fgcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
getdisplay().fillRect(0, Compass_Y0, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, Compass_Y0, 400, 3, commonData->fgcolor);
|
||||||
// Add the numbers to the compass band
|
// Add the numbers to the compass band
|
||||||
int x0;
|
int x0;
|
||||||
float AngleToDisplay = NextSector * 180.0 / M_PI;
|
float AngleToDisplay = NextSector * 180.0 / M_PI;
|
||||||
|
|
||||||
x0 = Compass_X0 + Delta_X;
|
x0 = Compass_X0 + Delta_X;
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic16pt7b);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
getdisplay().setCursor(x0 - 40, Compass_Y0 + 40);
|
epd->setCursor(x0 - 40, Compass_Y0 + 40);
|
||||||
snprintf(buffer,bsize,"%03.0f", AngleToDisplay);
|
snprintf(buffer,bsize,"%03.0f", AngleToDisplay);
|
||||||
getdisplay().print(buffer);
|
epd->print(buffer);
|
||||||
AngleToDisplay += 20;
|
AngleToDisplay += 20;
|
||||||
if ( AngleToDisplay >= 360.0 )
|
if ( AngleToDisplay >= 360.0 )
|
||||||
AngleToDisplay -= 360.0;
|
AngleToDisplay -= 360.0;
|
||||||
@@ -208,7 +203,7 @@ class PageCompass : public Page
|
|||||||
|
|
||||||
x0 = Compass_X0 + Delta_X + 4 * 5 * Compass_LineDelta;
|
x0 = Compass_X0 + Delta_X + 4 * 5 * Compass_LineDelta;
|
||||||
do {
|
do {
|
||||||
getdisplay().setCursor(x0 - 40, Compass_Y0 + 40);
|
epd->setCursor(x0 - 40, Compass_Y0 + 40);
|
||||||
snprintf(buffer,bsize,"%03.0f", AngleToDisplay);
|
snprintf(buffer,bsize,"%03.0f", AngleToDisplay);
|
||||||
// Quick and dirty way to prevent wrapping text in next line
|
// Quick and dirty way to prevent wrapping text in next line
|
||||||
if ( ( x0 - 40 ) > 380 )
|
if ( ( x0 - 40 ) > 380 )
|
||||||
@@ -218,7 +213,7 @@ class PageCompass : public Page
|
|||||||
else if ( ( x0 - 40 ) > 325 )
|
else if ( ( x0 - 40 ) > 325 )
|
||||||
buffer[2] = 0;
|
buffer[2] = 0;
|
||||||
|
|
||||||
getdisplay().print(buffer);
|
epd->print(buffer);
|
||||||
|
|
||||||
AngleToDisplay -= 20;
|
AngleToDisplay -= 20;
|
||||||
if ( AngleToDisplay < 0 )
|
if ( AngleToDisplay < 0 )
|
||||||
@@ -230,8 +225,8 @@ class PageCompass : public Page
|
|||||||
// x_test += 2;
|
// x_test += 2;
|
||||||
|
|
||||||
// snprintf(buffer,bsize,"%03d", x_test);
|
// snprintf(buffer,bsize,"%03d", x_test);
|
||||||
// getdisplay().setCursor(x_test, Compass_Y0 - 60);
|
// epd->setCursor(x_test, Compass_Y0 - 60);
|
||||||
// getdisplay().print(buffer);
|
// epd->print(buffer);
|
||||||
// if ( x_test > 390)
|
// if ( x_test > 390)
|
||||||
// x_test = 320;
|
// x_test = 320;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
@@ -5,13 +6,19 @@
|
|||||||
|
|
||||||
class PageDST810 : public Page
|
class PageDST810 : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String lengthformat;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageDST810(CommonData &common){
|
PageDST810(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageDST810");
|
logger->logDebug(GwLog::LOG, "Instantiate PageDST810");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
lengthformat = config->getString(config->lengthFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key) {
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -21,8 +28,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int displayPage(PageData &pageData) {
|
int displayPage(PageData &pageData) {
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
// Old values for hold function
|
// Old values for hold function
|
||||||
static String svalue1old = "";
|
static String svalue1old = "";
|
||||||
@@ -34,21 +39,14 @@ public:
|
|||||||
static String svalue4old = "";
|
static String svalue4old = "";
|
||||||
static String unit4old = "";
|
static String unit4old = "";
|
||||||
|
|
||||||
// Get config data
|
|
||||||
String lengthformat = config->getString(config->lengthFormat);
|
|
||||||
// bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
|
|
||||||
// Get boat values #1
|
// Get boat values #1
|
||||||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
||||||
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
||||||
name1 = name1.substring(0, 6); // String length limit for value name
|
name1 = name1.substring(0, 6); // String length limit for value name
|
||||||
double value1 = bvalue1->value; // Value as double in SI unit
|
double value1 = bvalue1->value; // Value as double in SI unit
|
||||||
bool valid1 = bvalue1->valid; // Valid information
|
bool valid1 = bvalue1->valid; // Valid information
|
||||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue1 = commonData->fmt->formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
String unit1 = commonData->fmt->formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #2
|
// Get boat values #2
|
||||||
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list (only one value by PageOneValue)
|
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list (only one value by PageOneValue)
|
||||||
@@ -56,8 +54,8 @@ public:
|
|||||||
name2 = name2.substring(0, 6); // String length limit for value name
|
name2 = name2.substring(0, 6); // String length limit for value name
|
||||||
double value2 = bvalue2->value; // Value as double in SI unit
|
double value2 = bvalue2->value; // Value as double in SI unit
|
||||||
bool valid2 = bvalue2->valid; // Valid information
|
bool valid2 = bvalue2->valid; // Valid information
|
||||||
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue2 = commonData->fmt->formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
String unit2 = commonData->fmt->formatValue(bvalue2, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #3
|
// Get boat values #3
|
||||||
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue)
|
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue)
|
||||||
@@ -65,8 +63,8 @@ public:
|
|||||||
name3 = name3.substring(0, 6); // String length limit for value name
|
name3 = name3.substring(0, 6); // String length limit for value name
|
||||||
double value3 = bvalue3->value; // Value as double in SI unit
|
double value3 = bvalue3->value; // Value as double in SI unit
|
||||||
bool valid3 = bvalue3->valid; // Valid information
|
bool valid3 = bvalue3->valid; // Valid information
|
||||||
String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue3 = commonData->fmt->formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value
|
String unit3 = commonData->fmt->formatValue(bvalue3, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #4
|
// Get boat values #4
|
||||||
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Second element in list (only one value by PageOneValue)
|
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Second element in list (only one value by PageOneValue)
|
||||||
@@ -74,8 +72,8 @@ public:
|
|||||||
name4 = name4.substring(0, 6); // String length limit for value name
|
name4 = name4.substring(0, 6); // String length limit for value name
|
||||||
double value4 = bvalue4->value; // Value as double in SI unit
|
double value4 = bvalue4->value; // Value as double in SI unit
|
||||||
bool valid4 = bvalue4->valid; // Valid information
|
bool valid4 = bvalue4->valid; // Valid information
|
||||||
String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue4 = commonData->fmt->formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit4 = formatValue(bvalue4, *commonData).unit; // Unit of value
|
String unit4 = commonData->fmt->formatValue(bvalue4, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
// Optical warning by limit violation (unused)
|
||||||
if(String(flashLED) == "Limit Violation"){
|
if(String(flashLED) == "Limit Violation"){
|
||||||
@@ -85,43 +83,43 @@ public:
|
|||||||
|
|
||||||
// Logging boat values
|
// Logging boat values
|
||||||
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageDST810, %s: %f, %s: %f, %s: %f, %s: %f", name1.c_str(), value1, name2.c_str(), value2, name3.c_str(), value3, name4.c_str(), value4);
|
logger->logDebug(GwLog::LOG, "Drawing at PageDST810, %s: %f, %s: %f, %s: %f, %s: %f", name1.c_str(), value1, name2.c_str(), value2, name3.c_str(), value3, name4.c_str(), value4);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 1 ################
|
// ############### Value 1 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 55);
|
epd->setCursor(20, 55);
|
||||||
getdisplay().print("Depth"); // Page name
|
epd->print("Depth"); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 90);
|
epd->setCursor(20, 90);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit1); // Unit
|
epd->print(unit1); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit1old);
|
epd->print(unit1old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set font
|
// Set font
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic30pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic30pt7b);
|
||||||
getdisplay().setCursor(180, 90);
|
epd->setCursor(180, 90);
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue1); // Real value as formated string
|
epd->print(svalue1); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue1old); // Old value as formated string
|
epd->print(svalue1old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid1 == true){
|
if(valid1 == true){
|
||||||
svalue1old = svalue1; // Save the old value
|
svalue1old = svalue1; // Save the old value
|
||||||
@@ -131,35 +129,35 @@ public:
|
|||||||
// ############### Horizontal Line ################
|
// ############### Horizontal Line ################
|
||||||
|
|
||||||
// Horizontal line 3 pix
|
// Horizontal line 3 pix
|
||||||
getdisplay().fillRect(0, 105, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, 105, 400, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 2 ################
|
// ############### Value 2 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 145);
|
epd->setCursor(20, 145);
|
||||||
getdisplay().print("Speed"); // Page name
|
epd->print("Speed"); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 180);
|
epd->setCursor(20, 180);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit2); // Unit
|
epd->print(unit2); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit2old);
|
epd->print(unit2old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setfont
|
// Setfont
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic30pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic30pt7b);
|
||||||
getdisplay().setCursor(180, 180);
|
epd->setCursor(180, 180);
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue2); // Real value as formated string
|
epd->print(svalue2); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue2old); // Old value as formated string
|
epd->print(svalue2old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid2 == true){
|
if(valid2 == true){
|
||||||
svalue2old = svalue2; // Save the old value
|
svalue2old = svalue2; // Save the old value
|
||||||
@@ -169,35 +167,35 @@ public:
|
|||||||
// ############### Horizontal Line ################
|
// ############### Horizontal Line ################
|
||||||
|
|
||||||
// Horizontal line 3 pix
|
// Horizontal line 3 pix
|
||||||
getdisplay().fillRect(0, 195, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, 195, 400, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 3 ################
|
// ############### Value 3 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 220);
|
epd->setCursor(20, 220);
|
||||||
getdisplay().print("Log"); // Page name
|
epd->print("Log"); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(20, 240);
|
epd->setCursor(20, 240);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit3); // Unit
|
epd->print(unit3); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit3old);
|
epd->print(unit3old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set font
|
// Set font
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(80, 270);
|
epd->setCursor(80, 270);
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue3); // Real value as formated string
|
epd->print(svalue3); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue3old); // Old value as formated string
|
epd->print(svalue3old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid3 == true){
|
if(valid3 == true){
|
||||||
svalue3old = svalue3; // Save the old value
|
svalue3old = svalue3; // Save the old value
|
||||||
@@ -207,35 +205,35 @@ public:
|
|||||||
// ############### Vertical Line ################
|
// ############### Vertical Line ################
|
||||||
|
|
||||||
// Vertical line 3 pix
|
// Vertical line 3 pix
|
||||||
getdisplay().fillRect(200, 195, 3, 75, commonData->fgcolor);
|
epd->fillRect(200, 195, 3, 75, commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 4 ################
|
// ############### Value 4 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(220, 220);
|
epd->setCursor(220, 220);
|
||||||
getdisplay().print("Temp"); // Page name
|
epd->print("Temp"); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(220, 240);
|
epd->setCursor(220, 240);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit4); // Unit
|
epd->print(unit4); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit4old);
|
epd->print(unit4old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set font
|
// Set font
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(280, 270);
|
epd->setCursor(280, 270);
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue4); // Real value as formated string
|
epd->print(svalue4); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue4old); // Old value as formated string
|
epd->print(svalue4old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid4 == true){
|
if(valid4 == true){
|
||||||
svalue4old = svalue4; // Save the old value
|
svalue4old = svalue4; // Save the old value
|
||||||
|
|||||||
145
lib/obp60task/PageEPropulsion.cpp
Normal file
145
lib/obp60task/PageEPropulsion.cpp
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
|
#include "Pagedata.h"
|
||||||
|
#include "OBP60Extensions.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Electric propulsion
|
||||||
|
|
||||||
|
- Current, voltage, power
|
||||||
|
- 12, 24, 48 etc. Voltage
|
||||||
|
- rpm
|
||||||
|
- throttle position
|
||||||
|
- controller state
|
||||||
|
- error codes
|
||||||
|
- temperature engine, controller, batteries
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PageEPropulsion : public Page
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
char mode = 'N'; // (N)ormal, (C)onfig
|
||||||
|
|
||||||
|
void displayModeNormal(PageData &pageData) {
|
||||||
|
|
||||||
|
// TBD Boatvalues: ...
|
||||||
|
|
||||||
|
logger->logDebug(GwLog::DEBUG, "Drawing at PageEPropulsion");
|
||||||
|
|
||||||
|
// Title and corner value headings
|
||||||
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(8, 48);
|
||||||
|
epd->print("Electric propulsion");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayModeConfig() {
|
||||||
|
|
||||||
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(8, 48);
|
||||||
|
epd->print("EPropulsion configuration");
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
// TODO menu
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
PageEPropulsion(CommonData &common) : Page(common)
|
||||||
|
{
|
||||||
|
logger->logDebug(GwLog::LOG,"Instantiate PageEPropulsion");
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupKeys(){
|
||||||
|
Page::setupKeys();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
int handleKey(int key){
|
||||||
|
if (key == 1) { // Switch between normal and config mode
|
||||||
|
if (mode == 'N') {
|
||||||
|
mode = 'C';
|
||||||
|
} else {
|
||||||
|
mode = 'N';
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (key == 11) { // Code for keylock
|
||||||
|
commonData->keylock = !commonData->keylock;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
int handleKey(int key){
|
||||||
|
if (key == 1) { // Switch between normal and config mode
|
||||||
|
if (mode == 'N') {
|
||||||
|
mode = 'C';
|
||||||
|
commonData->keydata[1].label = "EDIT";
|
||||||
|
} else {
|
||||||
|
mode = 'N';
|
||||||
|
commonData->keydata[1].label = "ALARM";
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (key == 11) { // Code for keylock
|
||||||
|
commonData->keylock = !commonData->keylock;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData){
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int displayPage(PageData &pageData){
|
||||||
|
|
||||||
|
// Logging boat values
|
||||||
|
logger->logDebug(GwLog::LOG,"Drawing at PageEPropulsion; Mode=%c", mode);
|
||||||
|
|
||||||
|
// Set display in partial refresh mode
|
||||||
|
epd->setPartialWindow(0, 0, epd->width(), epd->height());
|
||||||
|
|
||||||
|
if (mode == 'N') {
|
||||||
|
displayModeNormal(pageData);
|
||||||
|
} else if (mode == 'C') {
|
||||||
|
displayModeConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
return PAGE_UPDATE;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static Page *createPage(CommonData &common){
|
||||||
|
return new PageEPropulsion(common);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* with the code below we make this page known to the PageTask
|
||||||
|
* we give it a type (name) that can be selected in the config
|
||||||
|
* we define which function is to be called
|
||||||
|
* and we provide the number of user parameters we expect
|
||||||
|
* this will be number of BoatValue pointers in pageData.values
|
||||||
|
*/
|
||||||
|
PageDescription registerPageEPropulsion(
|
||||||
|
"EPropulsion", // Page name
|
||||||
|
createPage, // Action
|
||||||
|
0, // Number of bus values depends on selection in Web configuration
|
||||||
|
{}, // Names of bus values undepends on selection in Web configuration (refer GwBoatData.h)
|
||||||
|
true // Show display header on/off
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
@@ -66,25 +67,22 @@ static unsigned char fish_bits[] = {
|
|||||||
|
|
||||||
class PageFluid : public Page
|
class PageFluid : public Page
|
||||||
{
|
{
|
||||||
bool simulation = false;
|
private:
|
||||||
double simgoto;
|
double simgoto;
|
||||||
double simval;
|
double simval;
|
||||||
double simstep;
|
double simstep;
|
||||||
bool holdvalues = false;
|
|
||||||
int fluidtype;
|
int fluidtype;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageFluid(CommonData &common){
|
PageFluid(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageFluid");
|
logger->logDebug(GwLog::LOG, "Instantiate PageFluid");
|
||||||
simulation = common.config->getBool(common.config->useSimuData);
|
|
||||||
holdvalues = common.config->getBool(common.config->holdvalues);
|
|
||||||
simval = double(random(0, 100));
|
simval = double(random(0, 100));
|
||||||
simgoto = double(random(0, 100));
|
simgoto = double(random(0, 100));
|
||||||
simstep = (simgoto - simval) / 20.0;
|
simstep = (simgoto - simval) / 20.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key) {
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -93,27 +91,22 @@ class PageFluid : public Page
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void displayNew(PageData &pageData){
|
void displayNew(PageData &pageData) {
|
||||||
fluidtype = commonData->config->getInt("page" + String(pageData.pageNumber) + "fluid", 0);
|
fluidtype = config->getInt("page" + String(pageData.pageNumber) + "fluid", 0);
|
||||||
commonData->logger->logDebug(GwLog::LOG,"New PageFluid: fluidtype=%d", fluidtype);
|
logger->logDebug(GwLog::LOG, "New PageFluid: fluidtype=%d", fluidtype);
|
||||||
}
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
int displayPage(PageData &pageData){
|
if (flashLED == "Limit Violation") {
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
// Old values for hold function
|
|
||||||
static double value1old;
|
|
||||||
|
|
||||||
// Get config data
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
|
||||||
if(String(flashLED) == "Limit Violation"){
|
|
||||||
setBlinkingLED(false);
|
setBlinkingLED(false);
|
||||||
setFlashLED(false);
|
setFlashLED(false);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int displayPage(PageData &pageData) {
|
||||||
|
|
||||||
|
// Old values for hold function
|
||||||
|
static double value1old;
|
||||||
|
|
||||||
GwApi::BoatValue *bvalue1 = pageData.values[0];
|
GwApi::BoatValue *bvalue1 = pageData.values[0];
|
||||||
String name1 = bvalue1->getName();
|
String name1 = bvalue1->getName();
|
||||||
@@ -132,23 +125,23 @@ class PageFluid : public Page
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Logging boat values
|
// Logging boat values
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageFluid: value=%f", bvalue1->value);
|
logger->logDebug(GwLog::LOG, "Drawing at PageFluid: value=%f", bvalue1->value);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height());
|
epd->setPartialWindow(0, 0, epd->width(), epd->height());
|
||||||
|
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
// descriptions
|
// descriptions
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 60);
|
epd->setCursor(20, 60);
|
||||||
getdisplay().print("Fluid");
|
epd->print("Fluid");
|
||||||
|
|
||||||
getdisplay().setCursor(300, 60);
|
epd->setCursor(300, 60);
|
||||||
getdisplay().print(xdrDelete(name1).substring(0, 6));
|
epd->print(xdrDelete(name1).substring(0, 6));
|
||||||
|
|
||||||
// analog instrument
|
// analog instrument
|
||||||
// scale from -120 to 120
|
// scale from -120 to 120
|
||||||
@@ -158,11 +151,11 @@ class PageFluid : public Page
|
|||||||
uint8_t r = 110;
|
uint8_t r = 110;
|
||||||
|
|
||||||
// circular frame
|
// circular frame
|
||||||
getdisplay().drawCircle(c.x, c.y, r+5, commonData->fgcolor);
|
epd->drawCircle(c.x, c.y, r+5, commonData->fgcolor);
|
||||||
getdisplay().fillCircle(c.x, c.y, r+2, commonData->fgcolor);
|
epd->fillCircle(c.x, c.y, r+2, commonData->fgcolor);
|
||||||
getdisplay().fillCircle(c.x, c.y, r-1, commonData->bgcolor);
|
epd->fillCircle(c.x, c.y, r-1, commonData->bgcolor);
|
||||||
// center of pointer as dot
|
// center of pointer as dot
|
||||||
getdisplay().fillCircle(c.x, c.y, 8, commonData->fgcolor);
|
epd->fillCircle(c.x, c.y, 8, commonData->fgcolor);
|
||||||
|
|
||||||
// value down centered
|
// value down centered
|
||||||
char buffer[6];
|
char buffer[6];
|
||||||
@@ -176,32 +169,32 @@ class PageFluid : public Page
|
|||||||
// draw symbol (as bitmap)
|
// draw symbol (as bitmap)
|
||||||
switch (fluidtype) {
|
switch (fluidtype) {
|
||||||
case 0:
|
case 0:
|
||||||
getdisplay().drawXBitmap(c.x-8, c.y-50, fuel_bits, fuel_width, fuel_height, commonData->fgcolor);
|
epd->drawXBitmap(c.x-8, c.y-50, fuel_bits, fuel_width, fuel_height, commonData->fgcolor);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
getdisplay().drawXBitmap(c.x-8, c.y-50, water_bits, water_width, water_height, commonData->fgcolor);
|
epd->drawXBitmap(c.x-8, c.y-50, water_bits, water_width, water_height, commonData->fgcolor);
|
||||||
break;
|
break;
|
||||||
case 2: // gray water no symbol yet
|
case 2: // gray water no symbol yet
|
||||||
// getdisplay().drawXBitmap(c.x-8, c.y-50, gray_bits, gray_width, gray_height, commonData->fgcolor);
|
// epd->drawXBitmap(c.x-8, c.y-50, gray_bits, gray_width, gray_height, commonData->fgcolor);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
getdisplay().drawXBitmap(c.x-8, c.y-50, fish_bits, fish_width, fish_height, commonData->fgcolor);
|
epd->drawXBitmap(c.x-8, c.y-50, fish_bits, fish_width, fish_height, commonData->fgcolor);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
getdisplay().drawXBitmap(c.x-8, c.y-50, oil_bits, oil_width, oil_height, commonData->fgcolor);
|
epd->drawXBitmap(c.x-8, c.y-50, oil_bits, oil_width, oil_height, commonData->fgcolor);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
getdisplay().drawXBitmap(c.x-8, c.y-50, waste_bits, waste_width, waste_height, commonData->fgcolor);
|
epd->drawXBitmap(c.x-8, c.y-50, waste_bits, waste_width, waste_height, commonData->fgcolor);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
getdisplay().drawXBitmap(c.x-8, c.y-50, gasoline_bits, gasoline_width, gasoline_height, commonData->fgcolor);
|
epd->drawXBitmap(c.x-8, c.y-50, gasoline_bits, gasoline_width, gasoline_height, commonData->fgcolor);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Point p, pr;
|
Point p, pr;
|
||||||
|
|
||||||
// scale texts
|
// scale texts
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
p = {c.x, c.y - r + 30};
|
p = {c.x, c.y - r + 30};
|
||||||
drawTextCenter(p.x, p.y, "1/2");
|
drawTextCenter(p.x, p.y, "1/2");
|
||||||
pr = rotatePoint(c, p, -60);
|
pr = rotatePoint(c, p, -60);
|
||||||
@@ -210,7 +203,7 @@ class PageFluid : public Page
|
|||||||
drawTextCenter(pr.x, pr.y, "3/4");
|
drawTextCenter(pr.x, pr.y, "3/4");
|
||||||
|
|
||||||
// empty and full
|
// empty and full
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
p = rotatePoint(c, {c.x, c.y - r + 30}, -130);
|
p = rotatePoint(c, {c.x, c.y - r + 30}, -130);
|
||||||
drawTextCenter(p.x, p.y, "E");
|
drawTextCenter(p.x, p.y, "E");
|
||||||
p = rotatePoint(c, {c.x, c.y - r + 30}, 130);
|
p = rotatePoint(c, {c.x, c.y - r + 30}, 130);
|
||||||
@@ -236,7 +229,7 @@ class PageFluid : public Page
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
p = rotatePoint(c, {c.x, c.y - r + 10}, angle);
|
p = rotatePoint(c, {c.x, c.y - r + 10}, angle);
|
||||||
getdisplay().fillCircle(p.x, p.y, 3, commonData->fgcolor);
|
epd->fillCircle(p.x, p.y, 3, commonData->fgcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// pointer
|
// pointer
|
||||||
@@ -249,7 +242,7 @@ class PageFluid : public Page
|
|||||||
};
|
};
|
||||||
fillPoly4(rotatePoints(c, pts, -120 + fluidlevel * 2.4), commonData->fgcolor);
|
fillPoly4(rotatePoints(c, pts, -120 + fluidlevel * 2.4), commonData->fgcolor);
|
||||||
// Pointer axis is white
|
// Pointer axis is white
|
||||||
getdisplay().fillCircle(c.x, c.y, 6, commonData->bgcolor);
|
epd->fillCircle(c.x, c.y, 6, commonData->bgcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
|
|||||||
@@ -1,18 +1,28 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
#include "OBP60Extensions.h"
|
#include "OBP60Extensions.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
#include "BoatDataCalibration.h"
|
#include "BoatDataCalibration.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class PageFourValues : public Page
|
class PageFourValues : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String lengthformat;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageFourValues(CommonData &common){
|
PageFourValues(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageFourValues");
|
logger->logDebug(GwLog::LOG, "Instantiate PageFourValues");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
lengthformat = config->getString(config->lengthFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key){
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -21,9 +31,17 @@ class PageFourValues : public Page
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData) {
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
int displayPage(PageData &pageData){
|
int displayPage(PageData &pageData){
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
// Old values for hold function
|
// Old values for hold function
|
||||||
static String svalue1old = "";
|
static String svalue1old = "";
|
||||||
@@ -35,108 +53,103 @@ class PageFourValues : public Page
|
|||||||
static String svalue4old = "";
|
static String svalue4old = "";
|
||||||
static String unit4old = "";
|
static String unit4old = "";
|
||||||
|
|
||||||
// Get config data
|
|
||||||
String lengthformat = config->getString(config->lengthFormat);
|
|
||||||
// bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
|
|
||||||
// Get boat values #1
|
// Get boat values #1
|
||||||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
||||||
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
||||||
name1 = name1.substring(0, 6); // String length limit for value name
|
name1 = name1.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value1 = bvalue1->value; // Value as double in SI unit
|
double value1 = bvalue1->value; // Value as double in SI unit
|
||||||
bool valid1 = bvalue1->valid; // Valid information
|
bool valid1 = bvalue1->valid; // Valid information
|
||||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue1 = commonData->fmt->formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
String unit1 = commonData->fmt->formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #2
|
// Get boat values #2
|
||||||
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
|
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
|
||||||
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
||||||
name2 = name2.substring(0, 6); // String length limit for value name
|
name2 = name2.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value2 = bvalue2->value; // Value as double in SI unit
|
double value2 = bvalue2->value; // Value as double in SI unit
|
||||||
bool valid2 = bvalue2->valid; // Valid information
|
bool valid2 = bvalue2->valid; // Valid information
|
||||||
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue2 = commonData->fmt->formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
String unit2 = commonData->fmt->formatValue(bvalue2, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #3
|
// Get boat values #3
|
||||||
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list
|
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list
|
||||||
String name3 = xdrDelete(bvalue3->getName()); // Value name
|
String name3 = xdrDelete(bvalue3->getName()); // Value name
|
||||||
name3 = name3.substring(0, 6); // String length limit for value name
|
name3 = name3.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value3 = bvalue3->value; // Value as double in SI unit
|
double value3 = bvalue3->value; // Value as double in SI unit
|
||||||
bool valid3 = bvalue3->valid; // Valid information
|
bool valid3 = bvalue3->valid; // Valid information
|
||||||
String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue3 = commonData->fmt->formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value
|
String unit3 = commonData->fmt->formatValue(bvalue3, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #4
|
// Get boat values #4
|
||||||
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Fourth element in list
|
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Fourth element in list
|
||||||
String name4 = xdrDelete(bvalue4->getName()); // Value name
|
String name4 = xdrDelete(bvalue4->getName()); // Value name
|
||||||
name4 = name4.substring(0, 6); // String length limit for value name
|
name4 = name4.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue4, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue4, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value4 = bvalue4->value; // Value as double in SI unit
|
double value4 = bvalue4->value; // Value as double in SI unit
|
||||||
bool valid4 = bvalue4->valid; // Valid information
|
bool valid4 = bvalue4->valid; // Valid information
|
||||||
String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue4 = commonData->fmt->formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit4 = formatValue(bvalue4, *commonData).unit; // Unit of value
|
String unit4 = commonData->fmt->formatValue(bvalue4, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
|
||||||
if(String(flashLED) == "Limit Violation"){
|
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logging boat values
|
// Logging boat values
|
||||||
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageFourValues, %s: %f, %s: %f, %s: %f, %s: %f", name1.c_str(), value1, name2.c_str(), value2, name3.c_str(), value3, name4.c_str(), value4);
|
logger->logDebug(GwLog::LOG, "Drawing at PageFourValues, %s: %f, %s: %f, %s: %f, %s: %f", name1.c_str(), value1, name2.c_str(), value2, name3.c_str(), value3, name4.c_str(), value4);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 1 ################
|
// ############### Value 1 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().setCursor(20, 45);
|
epd->setCursor(20, 45);
|
||||||
getdisplay().print(name1); // Page name
|
epd->print(name1); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(20, 65);
|
epd->setCursor(20, 65);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit1); // Unit
|
epd->print(unit1); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit1old);
|
epd->print(unit1old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
if(bvalue1->getFormat() == "formatLatitude" || bvalue1->getFormat() == "formatLongitude"){
|
if(bvalue1->getFormat() == "formatLatitude" || bvalue1->getFormat() == "formatLongitude"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(120, 55);
|
epd->setCursor(120, 55);
|
||||||
}
|
}
|
||||||
else if(bvalue1->getFormat() == "formatTime" || bvalue1->getFormat() == "formatDate"){
|
else if(bvalue1->getFormat() == "formatTime" || bvalue1->getFormat() == "formatDate"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(150, 58);
|
epd->setCursor(150, 58);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(180, 65);
|
epd->setCursor(180, 65);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue1); // Real value as formated string
|
epd->print(svalue1); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue1old); // Old value as formated string
|
epd->print(svalue1old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid1 == true){
|
if(valid1 == true){
|
||||||
svalue1old = svalue1; // Save the old value
|
svalue1old = svalue1; // Save the old value
|
||||||
@@ -146,45 +159,45 @@ class PageFourValues : public Page
|
|||||||
// ############### Horizontal Line ################
|
// ############### Horizontal Line ################
|
||||||
|
|
||||||
// Horizontal line 3 pix
|
// Horizontal line 3 pix
|
||||||
getdisplay().fillRect(0, 80, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, 80, 400, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 2 ################
|
// ############### Value 2 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().setCursor(20, 113);
|
epd->setCursor(20, 113);
|
||||||
getdisplay().print(name2); // Page name
|
epd->print(name2); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(20, 133);
|
epd->setCursor(20, 133);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit2); // Unit
|
epd->print(unit2); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit2old);
|
epd->print(unit2old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
if(bvalue2->getFormat() == "formatLatitude" || bvalue2->getFormat() == "formatLongitude"){
|
if(bvalue2->getFormat() == "formatLatitude" || bvalue2->getFormat() == "formatLongitude"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(120, 123);
|
epd->setCursor(120, 123);
|
||||||
}
|
}
|
||||||
else if(bvalue2->getFormat() == "formatTime" || bvalue2->getFormat() == "formatDate"){
|
else if(bvalue2->getFormat() == "formatTime" || bvalue2->getFormat() == "formatDate"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(150, 123);
|
epd->setCursor(150, 123);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(180, 133);
|
epd->setCursor(180, 133);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue2); // Real value as formated string
|
epd->print(svalue2); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue2old); // Old value as formated string
|
epd->print(svalue2old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid2 == true){
|
if(valid2 == true){
|
||||||
svalue2old = svalue2; // Save the old value
|
svalue2old = svalue2; // Save the old value
|
||||||
@@ -194,45 +207,45 @@ class PageFourValues : public Page
|
|||||||
// ############### Horizontal Line ################
|
// ############### Horizontal Line ################
|
||||||
|
|
||||||
// Horizontal line 3 pix
|
// Horizontal line 3 pix
|
||||||
getdisplay().fillRect(0, 146, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, 146, 400, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 3 ################
|
// ############### Value 3 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().setCursor(20, 181);
|
epd->setCursor(20, 181);
|
||||||
getdisplay().print(name3); // Page name
|
epd->print(name3); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(20, 201);
|
epd->setCursor(20, 201);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit3); // Unit
|
epd->print(unit3); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit3old);
|
epd->print(unit3old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
if(bvalue3->getFormat() == "formatLatitude" || bvalue3->getFormat() == "formatLongitude"){
|
if(bvalue3->getFormat() == "formatLatitude" || bvalue3->getFormat() == "formatLongitude"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(120, 191);
|
epd->setCursor(120, 191);
|
||||||
}
|
}
|
||||||
else if(bvalue3->getFormat() == "formatTime" || bvalue3->getFormat() == "formatDate"){
|
else if(bvalue3->getFormat() == "formatTime" || bvalue3->getFormat() == "formatDate"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(150, 191);
|
epd->setCursor(150, 191);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(180, 201);
|
epd->setCursor(180, 201);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue3); // Real value as formated string
|
epd->print(svalue3); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue3old); // Old value as formated string
|
epd->print(svalue3old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid3 == true){
|
if(valid3 == true){
|
||||||
svalue3old = svalue3; // Save the old value
|
svalue3old = svalue3; // Save the old value
|
||||||
@@ -242,45 +255,45 @@ class PageFourValues : public Page
|
|||||||
// ############### Horizontal Line ################
|
// ############### Horizontal Line ################
|
||||||
|
|
||||||
// Horizontal line 3 pix
|
// Horizontal line 3 pix
|
||||||
getdisplay().fillRect(0, 214, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, 214, 400, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 4 ################
|
// ############### Value 4 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().setCursor(20, 249);
|
epd->setCursor(20, 249);
|
||||||
getdisplay().print(name4); // Page name
|
epd->print(name4); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(20, 269);
|
epd->setCursor(20, 269);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit4); // Unit
|
epd->print(unit4); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit4old);
|
epd->print(unit4old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
if(bvalue4->getFormat() == "formatLatitude" || bvalue4->getFormat() == "formatLongitude"){
|
if(bvalue4->getFormat() == "formatLatitude" || bvalue4->getFormat() == "formatLongitude"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(120, 259);
|
epd->setCursor(120, 259);
|
||||||
}
|
}
|
||||||
else if(bvalue4->getFormat() == "formatTime" || bvalue4->getFormat() == "formatDate"){
|
else if(bvalue4->getFormat() == "formatTime" || bvalue4->getFormat() == "formatDate"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(150, 259);
|
epd->setCursor(150, 259);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(180, 269);
|
epd->setCursor(180, 269);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue4); // Real value as formated string
|
epd->print(svalue4); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue4old); // Old value as formated string
|
epd->print(svalue4old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid4 == true){
|
if(valid4 == true){
|
||||||
svalue4old = svalue4; // Save the old value
|
svalue4old = svalue4; // Save the old value
|
||||||
@@ -289,6 +302,11 @@ class PageFourValues : public Page
|
|||||||
|
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void leavePage(PageData &pageData) {
|
||||||
|
logger->logDebug(GwLog::LOG, "Leaving PageFourvalues");
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static Page *createPage(CommonData &common){
|
static Page *createPage(CommonData &common){
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
@@ -6,13 +7,19 @@
|
|||||||
|
|
||||||
class PageFourValues2 : public Page
|
class PageFourValues2 : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String lengthformat;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageFourValues2(CommonData &common){
|
PageFourValues2(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageFourValues2");
|
logger->logDebug(GwLog::LOG, "Instantiate PageFourValues2");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
lengthformat = config->getString(config->lengthFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key) {
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock; // Toggle keylock
|
commonData->keylock = !commonData->keylock; // Toggle keylock
|
||||||
@@ -21,9 +28,17 @@ class PageFourValues2 : public Page
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData) {
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
int displayPage(PageData &pageData) {
|
int displayPage(PageData &pageData) {
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
// Old values for hold function
|
// Old values for hold function
|
||||||
static String svalue1old = "";
|
static String svalue1old = "";
|
||||||
@@ -35,108 +50,103 @@ class PageFourValues2 : public Page
|
|||||||
static String svalue4old = "";
|
static String svalue4old = "";
|
||||||
static String unit4old = "";
|
static String unit4old = "";
|
||||||
|
|
||||||
// Get config data
|
|
||||||
String lengthformat = config->getString(config->lengthFormat);
|
|
||||||
// bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
|
|
||||||
// Get boat values #1
|
// Get boat values #1
|
||||||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
||||||
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
||||||
name1 = name1.substring(0, 6); // String length limit for value name
|
name1 = name1.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value1 = bvalue1->value; // Value as double in SI unit
|
double value1 = bvalue1->value; // Value as double in SI unit
|
||||||
bool valid1 = bvalue1->valid; // Valid information
|
bool valid1 = bvalue1->valid; // Valid information
|
||||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue1 = commonData->fmt->formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
String unit1 = commonData->fmt->formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #2
|
// Get boat values #2
|
||||||
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list (only one value by PageOneValue)
|
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list (only one value by PageOneValue)
|
||||||
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
||||||
name2 = name2.substring(0, 6); // String length limit for value name
|
name2 = name2.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value2 = bvalue2->value; // Value as double in SI unit
|
double value2 = bvalue2->value; // Value as double in SI unit
|
||||||
bool valid2 = bvalue2->valid; // Valid information
|
bool valid2 = bvalue2->valid; // Valid information
|
||||||
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue2 = commonData->fmt->formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
String unit2 = commonData->fmt->formatValue(bvalue2, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #3
|
// Get boat values #3
|
||||||
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue)
|
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Second element in list (only one value by PageOneValue)
|
||||||
String name3 = xdrDelete(bvalue3->getName()); // Value name
|
String name3 = xdrDelete(bvalue3->getName()); // Value name
|
||||||
name3 = name3.substring(0, 6); // String length limit for value name
|
name3 = name3.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value3 = bvalue3->value; // Value as double in SI unit
|
double value3 = bvalue3->value; // Value as double in SI unit
|
||||||
bool valid3 = bvalue3->valid; // Valid information
|
bool valid3 = bvalue3->valid; // Valid information
|
||||||
String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue3 = commonData->fmt->formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value
|
String unit3 = commonData->fmt->formatValue(bvalue3, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #4
|
// Get boat values #4
|
||||||
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Second element in list (only one value by PageOneValue)
|
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Second element in list (only one value by PageOneValue)
|
||||||
String name4 = xdrDelete(bvalue4->getName()); // Value name
|
String name4 = xdrDelete(bvalue4->getName()); // Value name
|
||||||
name4 = name4.substring(0, 6); // String length limit for value name
|
name4 = name4.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue4, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue4, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value4 = bvalue4->value; // Value as double in SI unit
|
double value4 = bvalue4->value; // Value as double in SI unit
|
||||||
bool valid4 = bvalue4->valid; // Valid information
|
bool valid4 = bvalue4->valid; // Valid information
|
||||||
String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue4 = commonData->fmt->formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit4 = formatValue(bvalue4, *commonData).unit; // Unit of value
|
String unit4 = commonData->fmt->formatValue(bvalue4, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
|
||||||
if(String(flashLED) == "Limit Violation"){
|
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logging boat values
|
// Logging boat values
|
||||||
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageFourValues2, %s: %f, %s: %f, %s: %f, %s: %f", name1.c_str(), value1, name2.c_str(), value2, name3.c_str(), value3, name4.c_str(), value4);
|
logger->logDebug(GwLog::LOG, "Drawing at PageFourValues2, %s: %f, %s: %f, %s: %f, %s: %f", name1.c_str(), value1, name2.c_str(), value2, name3.c_str(), value3, name4.c_str(), value4);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 1 ################
|
// ############### Value 1 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 55);
|
epd->setCursor(20, 55);
|
||||||
getdisplay().print(name1); // Page name
|
epd->print(name1); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 90);
|
epd->setCursor(20, 90);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit1); // Unit
|
epd->print(unit1); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit1old);
|
epd->print(unit1old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
if(bvalue1->getFormat() == "formatLatitude" || bvalue1->getFormat() == "formatLongitude"){
|
if(bvalue1->getFormat() == "formatLatitude" || bvalue1->getFormat() == "formatLongitude"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(100, 90);
|
epd->setCursor(100, 90);
|
||||||
}
|
}
|
||||||
else if(bvalue1->getFormat() == "formatTime" || bvalue1->getFormat() == "formatDate"){
|
else if(bvalue1->getFormat() == "formatTime" || bvalue1->getFormat() == "formatDate"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(180, 77);
|
epd->setCursor(180, 77);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic30pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic30pt7b);
|
||||||
getdisplay().setCursor(180, 90);
|
epd->setCursor(180, 90);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue1); // Real value as formated string
|
epd->print(svalue1); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue1old); // Old value as formated string
|
epd->print(svalue1old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid1 == true){
|
if(valid1 == true){
|
||||||
svalue1old = svalue1; // Save the old value
|
svalue1old = svalue1; // Save the old value
|
||||||
@@ -146,45 +156,45 @@ class PageFourValues2 : public Page
|
|||||||
// ############### Horizontal Line ################
|
// ############### Horizontal Line ################
|
||||||
|
|
||||||
// Horizontal line 3 pix
|
// Horizontal line 3 pix
|
||||||
getdisplay().fillRect(0, 105, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, 105, 400, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 2 ################
|
// ############### Value 2 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 145);
|
epd->setCursor(20, 145);
|
||||||
getdisplay().print(name2); // Page name
|
epd->print(name2); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 180);
|
epd->setCursor(20, 180);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit2); // Unit
|
epd->print(unit2); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit2old);
|
epd->print(unit2old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
if(bvalue2->getFormat() == "formatLatitude" || bvalue2->getFormat() == "formatLongitude"){
|
if(bvalue2->getFormat() == "formatLatitude" || bvalue2->getFormat() == "formatLongitude"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(100, 180);
|
epd->setCursor(100, 180);
|
||||||
}
|
}
|
||||||
else if(bvalue2->getFormat() == "formatTime" || bvalue2->getFormat() == "formatDate"){
|
else if(bvalue2->getFormat() == "formatTime" || bvalue2->getFormat() == "formatDate"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(180, 158);
|
epd->setCursor(180, 158);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic30pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic30pt7b);
|
||||||
getdisplay().setCursor(180, 180);
|
epd->setCursor(180, 180);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue2); // Real value as formated string
|
epd->print(svalue2); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue2old); // Old value as formated string
|
epd->print(svalue2old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid2 == true){
|
if(valid2 == true){
|
||||||
svalue2old = svalue2; // Save the old value
|
svalue2old = svalue2; // Save the old value
|
||||||
@@ -194,45 +204,45 @@ class PageFourValues2 : public Page
|
|||||||
// ############### Horizontal Line ################
|
// ############### Horizontal Line ################
|
||||||
|
|
||||||
// Horizontal line 3 pix
|
// Horizontal line 3 pix
|
||||||
getdisplay().fillRect(0, 195, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, 195, 400, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 3 ################
|
// ############### Value 3 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 220);
|
epd->setCursor(20, 220);
|
||||||
getdisplay().print(name3); // Page name
|
epd->print(name3); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(20, 240);
|
epd->setCursor(20, 240);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit3); // Unit
|
epd->print(unit3); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit3old);
|
epd->print(unit3old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
if(bvalue3->getFormat() == "formatLatitude" || bvalue3->getFormat() == "formatLongitude"){
|
if(bvalue3->getFormat() == "formatLatitude" || bvalue3->getFormat() == "formatLongitude"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(50, 240);
|
epd->setCursor(50, 240);
|
||||||
}
|
}
|
||||||
else if(bvalue3->getFormat() == "formatTime" || bvalue3->getFormat() == "formatDate"){
|
else if(bvalue3->getFormat() == "formatTime" || bvalue3->getFormat() == "formatDate"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(100, 240);
|
epd->setCursor(100, 240);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(80, 270);
|
epd->setCursor(80, 270);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue3); // Real value as formated string
|
epd->print(svalue3); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue3old); // Old value as formated string
|
epd->print(svalue3old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid3 == true){
|
if(valid3 == true){
|
||||||
svalue3old = svalue3; // Save the old value
|
svalue3old = svalue3; // Save the old value
|
||||||
@@ -242,45 +252,45 @@ class PageFourValues2 : public Page
|
|||||||
// ############### Vertical Line ################
|
// ############### Vertical Line ################
|
||||||
|
|
||||||
// Vertical line 3 pix
|
// Vertical line 3 pix
|
||||||
getdisplay().fillRect(200, 195, 3, 75, commonData->fgcolor);
|
epd->fillRect(200, 195, 3, 75, commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 4 ################
|
// ############### Value 4 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(220, 220);
|
epd->setCursor(220, 220);
|
||||||
getdisplay().print(name4); // Page name
|
epd->print(name4); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(220, 240);
|
epd->setCursor(220, 240);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit4); // Unit
|
epd->print(unit4); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit4old);
|
epd->print(unit4old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
if(bvalue4->getFormat() == "formatLatitude" || bvalue4->getFormat() == "formatLongitude"){
|
if(bvalue4->getFormat() == "formatLatitude" || bvalue4->getFormat() == "formatLongitude"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(250, 240);
|
epd->setCursor(250, 240);
|
||||||
}
|
}
|
||||||
else if(bvalue4->getFormat() == "formatTime" || bvalue4->getFormat() == "formatDate"){
|
else if(bvalue4->getFormat() == "formatTime" || bvalue4->getFormat() == "formatDate"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(300, 240);
|
epd->setCursor(300, 240);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(280, 270);
|
epd->setCursor(280, 270);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue4); // Real value as formated string
|
epd->print(svalue4); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue4old); // Old value as formated string
|
epd->print(svalue4old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid4 == true){
|
if(valid4 == true){
|
||||||
svalue4old = svalue4; // Save the old value
|
svalue4old = svalue4; // Save the old value
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
@@ -6,12 +7,23 @@
|
|||||||
|
|
||||||
class PageGenerator : public Page
|
class PageGenerator : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String batVoltage;
|
||||||
|
int genPower;
|
||||||
|
String powerSensor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageGenerator(CommonData &common){
|
PageGenerator(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageGenerator");
|
logger->logDebug(GwLog::LOG, "Instantiate PageGenerator");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
batVoltage = config->getString(config->batteryVoltage);
|
||||||
|
genPower = config->getInt(config->genPower);
|
||||||
|
powerSensor = config->getString(config->usePowSensor3);
|
||||||
}
|
}
|
||||||
virtual int handleKey(int key){
|
|
||||||
|
int handleKey(int key){
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -20,19 +32,7 @@ public:
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
int displayPage(PageData &pageData)
|
int displayPage(PageData &pageData) {
|
||||||
{
|
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
// Get config data
|
|
||||||
bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String batVoltage = config->getString(config->batteryVoltage);
|
|
||||||
int genPower = config->getInt(config->genPower);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
String powerSensor = config->getString(config->usePowSensor3);
|
|
||||||
|
|
||||||
double value1 = 0; // Solar voltage
|
double value1 = 0; // Solar voltage
|
||||||
double value2 = 0; // Solar current
|
double value2 = 0; // Solar current
|
||||||
@@ -60,100 +60,95 @@ public:
|
|||||||
bool valid1 = true;
|
bool valid1 = true;
|
||||||
|
|
||||||
// Optical warning by limit violation
|
// Optical warning by limit violation
|
||||||
if(String(flashLED) == "Limit Violation"){
|
if (flashLED == "Limit Violation") {
|
||||||
// Over voltage
|
// Over voltage?
|
||||||
if(value1 > 14.8 && batVoltage == "12V"){
|
if (batVoltage == "12V") {
|
||||||
setBlinkingLED(true);
|
setBlinkingLED(value1 > 14.8);
|
||||||
}
|
} else if (batVoltage == "24V") {
|
||||||
if(value1 <= 14.8 && batVoltage == "12V"){
|
setBlinkingLED(value1 > 29.6);
|
||||||
setBlinkingLED(false);
|
} else {
|
||||||
}
|
|
||||||
if(value1 > 29.6 && batVoltage == "24V"){
|
|
||||||
setBlinkingLED(true);
|
|
||||||
}
|
|
||||||
if(value1 <= 29.6 && batVoltage == "24V"){
|
|
||||||
setBlinkingLED(false);
|
setBlinkingLED(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logging voltage value
|
// Logging voltage value
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageGenerator, Type:%iW %s:=%f", genPower, name1.c_str(), value1);
|
logger->logDebug(GwLog::LOG, "Drawing at PageGenerator, Type:%iW %s:=%f", genPower, name1.c_str(), value1);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(10, 65);
|
epd->setCursor(10, 65);
|
||||||
getdisplay().print("Power");
|
epd->print("Power");
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(12, 82);
|
epd->setCursor(12, 82);
|
||||||
getdisplay().print("Generator");
|
epd->print("Generator");
|
||||||
|
|
||||||
// Show voltage type
|
// Show voltage type
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(10, 140);
|
epd->setCursor(10, 140);
|
||||||
int bvoltage = 0;
|
int bvoltage = 0;
|
||||||
if(String(batVoltage) == "12V") bvoltage = 12;
|
if(String(batVoltage) == "12V") bvoltage = 12;
|
||||||
else bvoltage = 24;
|
else bvoltage = 24;
|
||||||
getdisplay().print(bvoltage);
|
epd->print(bvoltage);
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().print("V");
|
epd->print("V");
|
||||||
|
|
||||||
// Show solar power
|
// Show solar power
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(10, 200);
|
epd->setCursor(10, 200);
|
||||||
if(genPower <= 999) getdisplay().print(genPower, 0);
|
if(genPower <= 999) epd->print(genPower, 0);
|
||||||
if(genPower > 999) getdisplay().print(float(genPower/1000.0), 1);
|
if(genPower > 999) epd->print(float(genPower/1000.0), 1);
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
if(genPower <= 999) getdisplay().print("W");
|
if(genPower <= 999) epd->print("W");
|
||||||
if(genPower > 999) getdisplay().print("kW");
|
if(genPower > 999) epd->print("kW");
|
||||||
|
|
||||||
// Show info
|
// Show info
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(10, 235);
|
epd->setCursor(10, 235);
|
||||||
getdisplay().print("Installed");
|
epd->print("Installed");
|
||||||
getdisplay().setCursor(10, 255);
|
epd->setCursor(10, 255);
|
||||||
getdisplay().print("Power Modul");
|
epd->print("Power Modul");
|
||||||
|
|
||||||
// Show generator
|
// Show generator
|
||||||
generatorGraphic(200, 95, commonData->fgcolor, commonData->bgcolor);
|
generatorGraphic(200, 95, commonData->fgcolor, commonData->bgcolor);
|
||||||
|
|
||||||
// Show load level in percent
|
// Show load level in percent
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(150, 200);
|
epd->setCursor(150, 200);
|
||||||
getdisplay().print(genPercentage);
|
epd->print(genPercentage);
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().print("%");
|
epd->print("%");
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(150, 235);
|
epd->setCursor(150, 235);
|
||||||
getdisplay().print("Load");
|
epd->print("Load");
|
||||||
|
|
||||||
// Show sensor type info
|
// Show sensor type info
|
||||||
String i2cAddr = "";
|
String i2cAddr = "";
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(270, 60);
|
epd->setCursor(270, 60);
|
||||||
if(powerSensor == "off") getdisplay().print("Internal");
|
if(powerSensor == "off") epd->print("Internal");
|
||||||
if(powerSensor == "INA219"){
|
if(powerSensor == "INA219"){
|
||||||
getdisplay().print("INA219");
|
epd->print("INA219");
|
||||||
i2cAddr = " (0x" + String(INA219_I2C_ADDR3, HEX) + ")";
|
i2cAddr = " (0x" + String(INA219_I2C_ADDR3, HEX) + ")";
|
||||||
}
|
}
|
||||||
if(powerSensor == "INA226"){
|
if(powerSensor == "INA226"){
|
||||||
getdisplay().print("INA226");
|
epd->print("INA226");
|
||||||
i2cAddr = " (0x" + String(INA226_I2C_ADDR3, HEX) + ")";
|
i2cAddr = " (0x" + String(INA226_I2C_ADDR3, HEX) + ")";
|
||||||
}
|
}
|
||||||
getdisplay().print(i2cAddr);
|
epd->print(i2cAddr);
|
||||||
getdisplay().setCursor(270, 80);
|
epd->setCursor(270, 80);
|
||||||
getdisplay().print("Sensor Modul");
|
epd->print("Sensor Modul");
|
||||||
|
|
||||||
// Reading bus data or using simulation data
|
// Reading bus data or using simulation data
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(260, 140);
|
epd->setCursor(260, 140);
|
||||||
if(simulation == true){
|
if(simulation == true){
|
||||||
if(batVoltage == "12V"){
|
if(batVoltage == "12V"){
|
||||||
value1 = 12.0;
|
value1 = 12.0;
|
||||||
@@ -162,46 +157,59 @@ public:
|
|||||||
value1 = 24.0;
|
value1 = 24.0;
|
||||||
}
|
}
|
||||||
value1 += float(random(0, 5)) / 10; // Simulation data
|
value1 += float(random(0, 5)) / 10; // Simulation data
|
||||||
getdisplay().print(value1,1);
|
epd->print(value1,1);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// Check for valid real data, display also if hold values activated
|
// Check for valid real data, display also if hold values activated
|
||||||
if(valid1 == true || holdvalues == true){
|
if(valid1 == true || holdvalues == true){
|
||||||
// Resolution switching
|
// Resolution switching
|
||||||
if(value1 <= 9.9) getdisplay().print(value1, 2);
|
if(value1 <= 9.9) epd->print(value1, 2);
|
||||||
if(value1 > 9.9 && value1 <= 99.9)getdisplay().print(value1, 1);
|
if(value1 > 9.9 && value1 <= 99.9)epd->print(value1, 1);
|
||||||
if(value1 > 99.9) getdisplay().print(value1, 0);
|
if(value1 > 99.9) epd->print(value1, 0);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print("---"); // Missing bus data
|
epd->print(commonData->fmt->placeholder); // Missing bus data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().print("V");
|
epd->print("V");
|
||||||
|
|
||||||
// Show actual current in A
|
// Show actual current in A
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(260, 200);
|
epd->setCursor(260, 200);
|
||||||
if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){
|
if ((powerSensor == "INA219" || powerSensor == "INA226") && (simulation == false)) {
|
||||||
if(value2 <= 9.9) getdisplay().print(value2, 2);
|
// TODO use formatter for this?
|
||||||
if(value2 > 9.9 && value2 <= 99.9)getdisplay().print(value2, 1);
|
if (value2 <= 9.9) {
|
||||||
if(value2 > 99.9) getdisplay().print(value2, 0);
|
epd->print(value2, 2);
|
||||||
|
} else if (value2 <= 99.9) {
|
||||||
|
epd->print(value2, 1);
|
||||||
|
} else {
|
||||||
|
epd->print(value2, 0);
|
||||||
}
|
}
|
||||||
else getdisplay().print("---");
|
}
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
else {
|
||||||
getdisplay().print("A");
|
epd->print(commonData->fmt->placeholder);
|
||||||
|
}
|
||||||
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
|
epd->print("A");
|
||||||
|
|
||||||
// Show actual consumption in W
|
// Show actual consumption in W
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(260, 260);
|
epd->setCursor(260, 260);
|
||||||
if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){
|
if ((powerSensor == "INA219" || powerSensor == "INA226") && (simulation == false)) {
|
||||||
if(value3 <= 9.9) getdisplay().print(value3, 2);
|
if(value3 <= 9.9) {
|
||||||
if(value3 > 9.9 && value3 <= 99.9)getdisplay().print(value3, 1);
|
epd->print(value3, 2);
|
||||||
if(value3 > 99.9) getdisplay().print(value3, 0);
|
} else if (value3 <= 99.9) {
|
||||||
|
epd->print(value3, 1);
|
||||||
|
} else {
|
||||||
|
epd->print(value3, 0);
|
||||||
}
|
}
|
||||||
else getdisplay().print("---");
|
}
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
else {
|
||||||
getdisplay().print("W");
|
epd->print(commonData->fmt->placeholder);
|
||||||
|
}
|
||||||
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
|
epd->print("W");
|
||||||
|
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
@@ -5,14 +6,24 @@
|
|||||||
|
|
||||||
class PageKeelPosition : public Page
|
class PageKeelPosition : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String lengthformat;
|
||||||
|
String rotsensor;
|
||||||
|
String rotfunction;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageKeelPosition(CommonData &common){
|
PageKeelPosition(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageKeelPosition");
|
logger->logDebug(GwLog::LOG, "Instantiate PageKeelPosition");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
lengthformat = config->getString(config->lengthFormat);
|
||||||
|
rotsensor = config->getString(config->useRotSensor);
|
||||||
|
rotfunction = config->getString(config->rotFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Key functions
|
// Key functions
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key){
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -21,23 +32,21 @@ public:
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
int displayPage(PageData &pageData)
|
void displayNew(PageData &pageData) {
|
||||||
{
|
#ifdef BOARD_OBP60S3
|
||||||
GwConfigHandler *config = commonData->config;
|
// Clear optical warning
|
||||||
GwLog *logger = commonData->logger;
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int displayPage(PageData &pageData) {
|
||||||
|
|
||||||
double value1 = 0;
|
double value1 = 0;
|
||||||
double value1old = 0;
|
double value1old = 0;
|
||||||
|
|
||||||
// Get config data
|
|
||||||
String lengthformat = config->getString(config->lengthFormat);
|
|
||||||
bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
String rotsensor = config->getString(config->useRotSensor);
|
|
||||||
String rotfunction = config->getString(config->rotFunction);
|
|
||||||
|
|
||||||
// Get boat values for Keel position
|
// Get boat values for Keel position
|
||||||
bool valid1 = commonData->data.validRotAngle; // Valid information
|
bool valid1 = commonData->data.validRotAngle; // Valid information
|
||||||
if(simulation == false && rotsensor == "AS5600" && rotfunction == "Keel"){
|
if(simulation == false && rotsensor == "AS5600" && rotfunction == "Keel"){
|
||||||
@@ -55,20 +64,14 @@ public:
|
|||||||
value1old = value1; // Save old value
|
value1old = value1; // Save old value
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
|
||||||
if(String(flashLED) == "Limit Violation"){
|
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logging boat values
|
// Logging boat values
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageKeelPosition, Keel:%f", value1);
|
logger->logDebug(GwLog::LOG, "Drawing at PageKeelPosition, Keel:%f", value1);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
//*******************************************************************************************
|
//*******************************************************************************************
|
||||||
|
|
||||||
@@ -76,9 +79,9 @@ public:
|
|||||||
int rInstrument = 110; // Radius of KeelPosition
|
int rInstrument = 110; // Radius of KeelPosition
|
||||||
float pi = 3.141592;
|
float pi = 3.141592;
|
||||||
|
|
||||||
getdisplay().fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle
|
epd->fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle
|
||||||
getdisplay().fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle
|
epd->fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle
|
||||||
getdisplay().fillRect(0, 30, 400, 122, commonData->bgcolor); // Delete half top circle
|
epd->fillRect(0, 30, 400, 122, commonData->bgcolor); // Delete half top circle
|
||||||
|
|
||||||
for(int i=90; i<=270; i=i+10)
|
for(int i=90; i<=270; i=i+10)
|
||||||
{
|
{
|
||||||
@@ -105,17 +108,17 @@ public:
|
|||||||
// Print text centered on position x, y
|
// Print text centered on position x, y
|
||||||
int16_t x1, y1; // Return values of getTextBounds
|
int16_t x1, y1; // Return values of getTextBounds
|
||||||
uint16_t w, h; // Return values of getTextBounds
|
uint16_t w, h; // Return values of getTextBounds
|
||||||
getdisplay().getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string
|
epd->getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string
|
||||||
getdisplay().setCursor(x-w/2, y+h/2);
|
epd->setCursor(x-w/2, y+h/2);
|
||||||
if(i % 30 == 0){
|
if(i % 30 == 0){
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().print(ii);
|
epd->print(ii);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw sub scale with dots
|
// Draw sub scale with dots
|
||||||
float x1c = 200 + rInstrument*sin(i/180.0*pi);
|
float x1c = 200 + rInstrument*sin(i/180.0*pi);
|
||||||
float y1c = 150 - rInstrument*cos(i/180.0*pi);
|
float y1c = 150 - rInstrument*cos(i/180.0*pi);
|
||||||
getdisplay().fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor);
|
epd->fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor);
|
||||||
float sinx=sin(i/180.0*pi);
|
float sinx=sin(i/180.0*pi);
|
||||||
float cosx=cos(i/180.0*pi);
|
float cosx=cos(i/180.0*pi);
|
||||||
|
|
||||||
@@ -126,10 +129,10 @@ public:
|
|||||||
float xx2 = +dx;
|
float xx2 = +dx;
|
||||||
float yy1 = -(rInstrument-10);
|
float yy1 = -(rInstrument-10);
|
||||||
float yy2 = -(rInstrument+10);
|
float yy2 = -(rInstrument+10);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),
|
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),
|
||||||
200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor);
|
||||||
}
|
}
|
||||||
@@ -163,7 +166,7 @@ public:
|
|||||||
float xx2 = startwidth;
|
float xx2 = startwidth;
|
||||||
float yy1 = -startwidth;
|
float yy1 = -startwidth;
|
||||||
float yy2 = -(rInstrument * 0.6);
|
float yy2 = -(rInstrument * 0.6);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
||||||
// Inverted pointer
|
// Inverted pointer
|
||||||
@@ -173,36 +176,36 @@ public:
|
|||||||
float ix2 = -endwidth;
|
float ix2 = -endwidth;
|
||||||
float iy1 = -(rInstrument * 0.6);
|
float iy1 = -(rInstrument * 0.6);
|
||||||
float iy2 = -endwidth;
|
float iy2 = -endwidth;
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1),
|
epd->fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1),
|
||||||
200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1),
|
200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1),
|
||||||
200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor);
|
||||||
|
|
||||||
// Draw counterweight
|
// Draw counterweight
|
||||||
getdisplay().fillCircle(200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2), 5, commonData->fgcolor);
|
epd->fillCircle(200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2), 5, commonData->fgcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Center circle
|
// Center circle
|
||||||
getdisplay().fillCircle(200, 140, startwidth + 22, commonData->bgcolor);
|
epd->fillCircle(200, 140, startwidth + 22, commonData->bgcolor);
|
||||||
getdisplay().fillCircle(200, 140, startwidth + 20, commonData->fgcolor); // Boat circle
|
epd->fillCircle(200, 140, startwidth + 20, commonData->fgcolor); // Boat circle
|
||||||
getdisplay().fillRect(200 - 30, 140 - 30, 2 * 30, 30, commonData->bgcolor); // Delete half top of boat circle
|
epd->fillRect(200 - 30, 140 - 30, 2 * 30, 30, commonData->bgcolor); // Delete half top of boat circle
|
||||||
getdisplay().fillRect(150, 150, 100, 4, commonData->fgcolor); // Water line
|
epd->fillRect(150, 150, 100, 4, commonData->fgcolor); // Water line
|
||||||
|
|
||||||
// Print label
|
// Print label
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().setCursor(100, 70);
|
epd->setCursor(100, 70);
|
||||||
getdisplay().print("Keel Position"); // Label
|
epd->print("Keel Position"); // Label
|
||||||
|
|
||||||
if((rotsensor == "AS5600" && rotfunction == "Keel" && (valid1 == true || holdvalues == true)) || simulation == true){
|
if((rotsensor == "AS5600" && rotfunction == "Keel" && (valid1 == true || holdvalues == true)) || simulation == true){
|
||||||
// Print Unit of keel position
|
// Print Unit of keel position
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(175, 110);
|
epd->setCursor(175, 110);
|
||||||
getdisplay().print(unit1); // Unit
|
epd->print(unit1); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// Print Unit of keel position
|
// Print Unit of keel position
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(145, 110);
|
epd->setCursor(145, 110);
|
||||||
getdisplay().print("No sensor data"); // Info missing sensor
|
epd->print("No sensor data"); // Info missing sensor
|
||||||
}
|
}
|
||||||
|
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
|
|||||||
@@ -1,18 +1,28 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
#include "OBP60Extensions.h"
|
#include "OBP60Extensions.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
#include "BoatDataCalibration.h"
|
#include "BoatDataCalibration.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class PageOneValue : public Page
|
class PageOneValue : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String lengthformat;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageOneValue(CommonData &common){
|
PageOneValue(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageOneValue");
|
logger->logDebug(GwLog::LOG, "Instantiate PageOneValue");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
lengthformat = config->getString(config->lengthFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key) {
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -21,83 +31,81 @@ class PageOneValue : public Page
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData) {
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
int displayPage(PageData &pageData) {
|
int displayPage(PageData &pageData) {
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
// Old values for hold function
|
// Old values for hold function
|
||||||
static String svalue1old = "";
|
static String svalue1old = "";
|
||||||
static String unit1old = "";
|
static String unit1old = "";
|
||||||
|
|
||||||
// Get config data
|
|
||||||
String lengthformat = config->getString(config->lengthFormat);
|
|
||||||
// bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
|
|
||||||
// Get boat values
|
// Get boat values
|
||||||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
||||||
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
||||||
name1 = name1.substring(0, 6); // String length limit for value name
|
name1 = name1.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value1 = bvalue1->value; // Value as double in SI unit
|
double value1 = bvalue1->value; // Value as double in SI unit
|
||||||
bool valid1 = bvalue1->valid; // Valid information
|
bool valid1 = bvalue1->valid; // Valid information
|
||||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue1 = commonData->fmt->formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
String unit1 = commonData->fmt->formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
|
||||||
if(String(flashLED) == "Limit Violation"){
|
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logging boat values
|
// Logging boat values
|
||||||
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageOneValue, %s: %f", name1.c_str(), value1);
|
logger->logDebug(GwLog::LOG, "Drawing at PageOneValue, %s: %f", name1.c_str(), value1);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
/// Set display in partial refresh mode
|
/// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
getdisplay().setFont(&Ubuntu_Bold32pt8b);
|
epd->setFont(&Ubuntu_Bold32pt8b);
|
||||||
getdisplay().setCursor(20, 100);
|
epd->setCursor(20, 100);
|
||||||
getdisplay().print(name1); // Page name
|
epd->print(name1); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(270, 100);
|
epd->setCursor(270, 100);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit1); // Unit
|
epd->print(unit1); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit1old);
|
epd->print(unit1old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
if(bvalue1->getFormat() == "formatLatitude" || bvalue1->getFormat() == "formatLongitude"){
|
if(bvalue1->getFormat() == "formatLatitude" || bvalue1->getFormat() == "formatLongitude"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 180);
|
epd->setCursor(20, 180);
|
||||||
}
|
}
|
||||||
else if(bvalue1->getFormat() == "formatTime" || bvalue1->getFormat() == "formatDate"){
|
else if(bvalue1->getFormat() == "formatTime" || bvalue1->getFormat() == "formatDate"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold32pt8b);
|
epd->setFont(&Ubuntu_Bold32pt8b);
|
||||||
getdisplay().setCursor(20, 200);
|
epd->setCursor(20, 200);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic60pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic60pt7b);
|
||||||
getdisplay().setCursor(20, 240);
|
epd->setCursor(20, 240);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue1); // Real value as formated string
|
epd->print(svalue1); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue1old); // Old value as formated string
|
epd->print(svalue1old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid1 == true){
|
if(valid1 == true){
|
||||||
svalue1old = svalue1; // Save the old value
|
svalue1old = svalue1; // Save the old value
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
@@ -5,14 +6,30 @@
|
|||||||
|
|
||||||
class PageRollPitch : public Page
|
class PageRollPitch : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String lengthformat;
|
||||||
|
int rolllimit;
|
||||||
|
String roffset;
|
||||||
|
double rolloffset;
|
||||||
|
String poffset;
|
||||||
|
double pitchoffset;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageRollPitch(CommonData &common){
|
PageRollPitch(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageRollPitch");
|
logger->logDebug(GwLog::LOG, "Instantiate PageRollPitch");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
String lengthformat = config->getString(config->lengthFormat);
|
||||||
|
rolllimit = config->getInt(config->rollLimit);
|
||||||
|
roffset = config->getString(config->rollOffset);
|
||||||
|
rolloffset = roffset.toFloat() / 360 * (2 * M_PI);
|
||||||
|
poffset = config->getString(config->pitchOffset);
|
||||||
|
pitchoffset = poffset.toFloat() / 360 * (2 * M_PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Key functions
|
// Key functions
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key){
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -22,8 +39,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int displayPage(PageData &pageData) {
|
int displayPage(PageData &pageData) {
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
double value1 = 0;
|
double value1 = 0;
|
||||||
double value2 = 0;
|
double value2 = 0;
|
||||||
@@ -32,19 +47,6 @@ public:
|
|||||||
String svalue2 = "";
|
String svalue2 = "";
|
||||||
String svalue2old = "";
|
String svalue2old = "";
|
||||||
|
|
||||||
|
|
||||||
// Get config data
|
|
||||||
String lengthformat = config->getString(config->lengthFormat);
|
|
||||||
bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
int rolllimit = config->getInt(config->rollLimit);
|
|
||||||
String roffset = config->getString(config->rollOffset);
|
|
||||||
double rolloffset = roffset.toFloat()/360*(2*M_PI);
|
|
||||||
String poffset = config->getString(config->pitchOffset);
|
|
||||||
double pitchoffset = poffset.toFloat()/360*(2*M_PI);
|
|
||||||
|
|
||||||
// Get boat values for roll
|
// Get boat values for roll
|
||||||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (xdrRoll)
|
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (xdrRoll)
|
||||||
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
||||||
@@ -97,71 +99,70 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Optical warning by limit violation
|
// Optical warning by limit violation
|
||||||
if(String(flashLED) == "Limit Violation"){
|
if (flashLED == "Limit Violation") {
|
||||||
// Limits for roll
|
// Limits for roll
|
||||||
if (value1*360/(2*M_PI) >= -1*rolllimit && value1*360/(2*M_PI) <= rolllimit) {
|
if (value1*360/(2*M_PI) >= -1*rolllimit && value1*360/(2*M_PI) <= rolllimit) {
|
||||||
setBlinkingLED(false);
|
setBlinkingLED(false);
|
||||||
setFlashLED(false);
|
setFlashLED(false);
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
setBlinkingLED(true);
|
setBlinkingLED(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logging boat values
|
// Logging boat values
|
||||||
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageRollPitch, %s:%f, %s:%f", name1.c_str(), value1, name2.c_str(), value2);
|
logger->logDebug(GwLog::LOG, "Drawing at PageRollPitch, %s:%f, %s:%f", name1.c_str(), value1, name2.c_str(), value2);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
// Show roll limit
|
// Show roll limit
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(10, 65);
|
epd->setCursor(10, 65);
|
||||||
getdisplay().print(rolllimit); // Value
|
epd->print(rolllimit); // Value
|
||||||
//getdisplay().print(svalue1); // Value
|
//epd->print(svalue1); // Value
|
||||||
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(10, 95);
|
epd->setCursor(10, 95);
|
||||||
getdisplay().print("Limit"); // Name
|
epd->print("Limit"); // Name
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(10, 115);
|
epd->setCursor(10, 115);
|
||||||
getdisplay().print("DEG");
|
epd->print("DEG");
|
||||||
|
|
||||||
// Horizintal separator left
|
// Horizintal separator left
|
||||||
getdisplay().fillRect(0, 149, 60, 3, commonData->fgcolor);
|
epd->fillRect(0, 149, 60, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// Show roll value
|
// Show roll value
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(10, 270);
|
epd->setCursor(10, 270);
|
||||||
if(holdvalues == false) getdisplay().print(svalue1); // Value
|
if(holdvalues == false) epd->print(svalue1); // Value
|
||||||
else getdisplay().print(svalue1old);
|
else epd->print(svalue1old);
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(10, 220);
|
epd->setCursor(10, 220);
|
||||||
getdisplay().print(name1); // Name
|
epd->print(name1); // Name
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(10, 190);
|
epd->setCursor(10, 190);
|
||||||
getdisplay().print("Deg");
|
epd->print("Deg");
|
||||||
|
|
||||||
// Horizintal separator right
|
// Horizintal separator right
|
||||||
getdisplay().fillRect(340, 149, 80, 3, commonData->fgcolor);
|
epd->fillRect(340, 149, 80, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// Show pitch value
|
// Show pitch value
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(295, 270);
|
epd->setCursor(295, 270);
|
||||||
if(holdvalues == false) getdisplay().print(svalue2); // Value
|
if(holdvalues == false) epd->print(svalue2); // Value
|
||||||
else getdisplay().print(svalue2old);
|
else epd->print(svalue2old);
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(335, 220);
|
epd->setCursor(335, 220);
|
||||||
getdisplay().print(name2); // Name
|
epd->print(name2); // Name
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(335, 190);
|
epd->setCursor(335, 190);
|
||||||
getdisplay().print("Deg");
|
epd->print("Deg");
|
||||||
|
|
||||||
//*******************************************************************************************
|
//*******************************************************************************************
|
||||||
|
|
||||||
@@ -169,8 +170,8 @@ public:
|
|||||||
int rInstrument = 100; // Radius of instrument
|
int rInstrument = 100; // Radius of instrument
|
||||||
float pi = 3.141592;
|
float pi = 3.141592;
|
||||||
|
|
||||||
getdisplay().fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle
|
epd->fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle
|
||||||
getdisplay().fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle
|
epd->fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle
|
||||||
|
|
||||||
for(int i=0; i<360; i=i+10)
|
for(int i=0; i<360; i=i+10)
|
||||||
{
|
{
|
||||||
@@ -194,17 +195,17 @@ public:
|
|||||||
// Print text centered on position x, y
|
// Print text centered on position x, y
|
||||||
int16_t x1, y1; // Return values of getTextBounds
|
int16_t x1, y1; // Return values of getTextBounds
|
||||||
uint16_t w, h; // Return values of getTextBounds
|
uint16_t w, h; // Return values of getTextBounds
|
||||||
getdisplay().getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string
|
epd->getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string
|
||||||
getdisplay().setCursor(x-w/2, y+h/2);
|
epd->setCursor(x-w/2, y+h/2);
|
||||||
if(i % 20 == 0){
|
if(i % 20 == 0){
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().print(ii);
|
epd->print(ii);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw sub scale with dots
|
// Draw sub scale with dots
|
||||||
float x1c = 200 + rInstrument*sin(i/180.0*M_PI);
|
float x1c = 200 + rInstrument*sin(i/180.0*M_PI);
|
||||||
float y1c = 150 - rInstrument*cos(i/180.0*M_PI);
|
float y1c = 150 - rInstrument*cos(i/180.0*M_PI);
|
||||||
getdisplay().fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor);
|
epd->fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor);
|
||||||
float sinx=sin(i/180.0*M_PI);
|
float sinx=sin(i/180.0*M_PI);
|
||||||
float cosx=cos(i/180.0*M_PI);
|
float cosx=cos(i/180.0*M_PI);
|
||||||
|
|
||||||
@@ -215,10 +216,10 @@ public:
|
|||||||
float xx2 = +dx;
|
float xx2 = +dx;
|
||||||
float yy1 = -(rInstrument-10);
|
float yy1 = -(rInstrument-10);
|
||||||
float yy2 = -(rInstrument+10);
|
float yy2 = -(rInstrument+10);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),
|
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),
|
||||||
200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor);
|
||||||
}
|
}
|
||||||
@@ -239,7 +240,7 @@ public:
|
|||||||
float xx2 = startwidth;
|
float xx2 = startwidth;
|
||||||
float yy1 = -startwidth;
|
float yy1 = -startwidth;
|
||||||
float yy2 = -(rInstrument * 0.7);
|
float yy2 = -(rInstrument * 0.7);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
||||||
// Inverted pointer
|
// Inverted pointer
|
||||||
@@ -249,28 +250,28 @@ public:
|
|||||||
float ix2 = -endwidth;
|
float ix2 = -endwidth;
|
||||||
float iy1 = -(rInstrument * 0.7);
|
float iy1 = -(rInstrument * 0.7);
|
||||||
float iy2 = -endwidth;
|
float iy2 = -endwidth;
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1),
|
epd->fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1),
|
||||||
200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1),
|
200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1),
|
||||||
200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor);
|
||||||
|
|
||||||
// Draw counterweight
|
// Draw counterweight
|
||||||
getdisplay().fillCircle(200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2), 5, commonData->fgcolor);
|
epd->fillCircle(200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2), 5, commonData->fgcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Center circle
|
// Center circle
|
||||||
getdisplay().fillCircle(200, 150, startwidth + 22, commonData->bgcolor);
|
epd->fillCircle(200, 150, startwidth + 22, commonData->bgcolor);
|
||||||
getdisplay().fillCircle(200, 150, startwidth + 20, commonData->fgcolor); // Boat circle
|
epd->fillCircle(200, 150, startwidth + 20, commonData->fgcolor); // Boat circle
|
||||||
int x0 = 200;
|
int x0 = 200;
|
||||||
int y0 = 150;
|
int y0 = 150;
|
||||||
int x1 = x0 + 50*cos(value1);
|
int x1 = x0 + 50*cos(value1);
|
||||||
int y1 = y0 + 50*sin(value1);
|
int y1 = y0 + 50*sin(value1);
|
||||||
int x2 = x0 + 50*cos(value1 - pi/2);
|
int x2 = x0 + 50*cos(value1 - pi/2);
|
||||||
int y2 = y0 + 50*sin(value1 - pi/2);
|
int y2 = y0 + 50*sin(value1 - pi/2);
|
||||||
getdisplay().fillTriangle(x0, y0, x1, y1, x2, y2, commonData->bgcolor); // Clear half top side of boat circle (right triangle)
|
epd->fillTriangle(x0, y0, x1, y1, x2, y2, commonData->bgcolor); // Clear half top side of boat circle (right triangle)
|
||||||
x1 = x0 + 50*cos(value1 + pi);
|
x1 = x0 + 50*cos(value1 + pi);
|
||||||
y1 = y0 + 50*sin(value1 + pi);
|
y1 = y0 + 50*sin(value1 + pi);
|
||||||
getdisplay().fillTriangle(x0, y0, x1, y1, x2, y2, commonData->bgcolor); // Clear half top side of boat circle (left triangle)
|
epd->fillTriangle(x0, y0, x1, y1, x2, y2, commonData->bgcolor); // Clear half top side of boat circle (left triangle)
|
||||||
getdisplay().fillRect(150, 160, 100, 4, commonData->fgcolor); // Water line
|
epd->fillRect(150, 160, 100, 4, commonData->fgcolor); // Water line
|
||||||
|
|
||||||
// Draw roll pointer
|
// Draw roll pointer
|
||||||
startwidth = 4; // Start width of pointer
|
startwidth = 4; // Start width of pointer
|
||||||
@@ -283,7 +284,7 @@ public:
|
|||||||
float xx2 = startwidth;
|
float xx2 = startwidth;
|
||||||
float yy1 = -startwidth;
|
float yy1 = -startwidth;
|
||||||
float yy2 = -(rInstrument - 15);
|
float yy2 = -(rInstrument - 15);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
||||||
// Inverted pointer
|
// Inverted pointer
|
||||||
@@ -293,15 +294,15 @@ public:
|
|||||||
float ix2 = -endwidth;
|
float ix2 = -endwidth;
|
||||||
float iy1 = -(rInstrument - 15);
|
float iy1 = -(rInstrument - 15);
|
||||||
float iy2 = -endwidth;
|
float iy2 = -endwidth;
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1),
|
epd->fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1),
|
||||||
200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1),
|
200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1),
|
||||||
200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// Print sensor info
|
// Print sensor info
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(145, 200);
|
epd->setCursor(145, 200);
|
||||||
getdisplay().print("No sensor data"); // Info missing sensor
|
epd->print("No sensor data"); // Info missing sensor
|
||||||
}
|
}
|
||||||
|
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
|
|||||||
@@ -1,19 +1,29 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
#include "OBP60Extensions.h"
|
#include "OBP60Extensions.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
#include "BoatDataCalibration.h"
|
#include "BoatDataCalibration.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class PageRudderPosition : public Page
|
class PageRudderPosition : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String lengthformat;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageRudderPosition(CommonData &common){
|
PageRudderPosition(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Show PageRudderPosition");
|
logger->logDebug(GwLog::LOG, "Instantiate PageRudderPosition");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
String lengthformat = config->getString(config->lengthFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Key functions
|
// Key functions
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key) {
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -22,69 +32,64 @@ public:
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData) {
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
int displayPage(PageData &pageData) {
|
int displayPage(PageData &pageData) {
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
static String unit1old = "";
|
static String unit1old = "";
|
||||||
double value1 = 0.1;
|
double value1 = 0.1;
|
||||||
double value1old = 0.1;
|
double value1old = 0.1;
|
||||||
|
|
||||||
// Get config data
|
|
||||||
String lengthformat = config->getString(config->lengthFormat);
|
|
||||||
bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
|
|
||||||
// Get boat values for rudder position
|
// Get boat values for rudder position
|
||||||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list
|
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list
|
||||||
String name1 = bvalue1->getName().c_str(); // Value name
|
String name1 = bvalue1->getName().c_str(); // Value name
|
||||||
name1 = name1.substring(0, 6); // String length limit for value name
|
name1 = name1.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
value1 = bvalue1->value; // Raw value without unit convertion
|
value1 = bvalue1->value; // Raw value without unit convertion
|
||||||
bool valid1 = bvalue1->valid; // Valid information
|
bool valid1 = bvalue1->valid; // Valid information
|
||||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue1 = commonData->fmt->formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
String unit1 = commonData->fmt->formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
if (valid1 == true) {
|
if (valid1 == true) {
|
||||||
value1old = value1; // Save old value
|
value1old = value1; // Save old value
|
||||||
unit1old = unit1; // Save old unit
|
unit1old = unit1; // Save old unit
|
||||||
} else {
|
} else {
|
||||||
if (simulation == true) {
|
if (simulation == true) {
|
||||||
value1 = (3 + float(random(0, 50)) / 10.0)/360*2*PI;
|
value1 = (3 + float(random(0, 50)) / 10.0) / 360 * 2 * M_PI;
|
||||||
unit1 = "Deg";
|
unit1 = "Deg";
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
value1 = 0;
|
value1 = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
// Log boat values
|
||||||
if(String(flashLED) == "Limit Violation"){
|
logger->logDebug(GwLog::LOG, "Drawing at PageRudderPosition, %s:%f", name1.c_str(), value1);
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logging boat values
|
|
||||||
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageRudderPosition, %s:%f", name1.c_str(), value1);
|
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
//*******************************************************************************************
|
//*******************************************************************************************
|
||||||
|
|
||||||
// Draw RudderPosition
|
// Draw RudderPosition
|
||||||
int rInstrument = 110; // Radius of RudderPosition
|
int rInstrument = 110; // Radius of RudderPosition
|
||||||
float pi = 3.141592;
|
const float pi = 3.141592;
|
||||||
|
|
||||||
getdisplay().fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle
|
epd->fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle
|
||||||
getdisplay().fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle
|
epd->fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle
|
||||||
getdisplay().fillRect(0, 30, 400, 122, commonData->bgcolor); // Delete half top circle
|
epd->fillRect(0, 30, 400, 122, commonData->bgcolor); // Delete half top circle
|
||||||
|
|
||||||
for(int i=90; i<=270; i=i+10)
|
for(int i=90; i<=270; i=i+10)
|
||||||
{
|
{
|
||||||
@@ -92,8 +97,7 @@ public:
|
|||||||
float x = 200 + (rInstrument-30)*sin(i/180.0*pi); // x-coordinate dots
|
float x = 200 + (rInstrument-30)*sin(i/180.0*pi); // x-coordinate dots
|
||||||
float y = 150 - (rInstrument-30)*cos(i/180.0*pi); // y-coordinate cots
|
float y = 150 - (rInstrument-30)*cos(i/180.0*pi); // y-coordinate cots
|
||||||
const char *ii = " ";
|
const char *ii = " ";
|
||||||
switch (i)
|
switch (i) {
|
||||||
{
|
|
||||||
case 0: ii=" "; break; // Use a blank for a empty scale value
|
case 0: ii=" "; break; // Use a blank for a empty scale value
|
||||||
case 30 : ii=" "; break;
|
case 30 : ii=" "; break;
|
||||||
case 60 : ii=" "; break;
|
case 60 : ii=" "; break;
|
||||||
@@ -112,17 +116,17 @@ public:
|
|||||||
// Print text centered on position x, y
|
// Print text centered on position x, y
|
||||||
int16_t x1, y1; // Return values of getTextBounds
|
int16_t x1, y1; // Return values of getTextBounds
|
||||||
uint16_t w, h; // Return values of getTextBounds
|
uint16_t w, h; // Return values of getTextBounds
|
||||||
getdisplay().getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string
|
epd->getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string
|
||||||
getdisplay().setCursor(x-w/2, y+h/2);
|
epd->setCursor(x-w/2, y+h/2);
|
||||||
if(i % 30 == 0){
|
if(i % 30 == 0){
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().print(ii);
|
epd->print(ii);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw sub scale with dots
|
// Draw sub scale with dots
|
||||||
float x1c = 200 + rInstrument*sin(i/180.0*pi);
|
float x1c = 200 + rInstrument*sin(i/180.0*pi);
|
||||||
float y1c = 150 - rInstrument*cos(i/180.0*pi);
|
float y1c = 150 - rInstrument*cos(i/180.0*pi);
|
||||||
getdisplay().fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor);
|
epd->fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor);
|
||||||
float sinx=sin(i/180.0*pi);
|
float sinx=sin(i/180.0*pi);
|
||||||
float cosx=cos(i/180.0*pi);
|
float cosx=cos(i/180.0*pi);
|
||||||
|
|
||||||
@@ -133,10 +137,10 @@ public:
|
|||||||
float xx2 = +dx;
|
float xx2 = +dx;
|
||||||
float yy1 = -(rInstrument-10);
|
float yy1 = -(rInstrument-10);
|
||||||
float yy2 = -(rInstrument+10);
|
float yy2 = -(rInstrument+10);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),
|
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),
|
||||||
200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor);
|
||||||
}
|
}
|
||||||
@@ -144,28 +148,28 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Print label
|
// Print label
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().setCursor(80, 70);
|
epd->setCursor(80, 70);
|
||||||
getdisplay().print("Rudder Position"); // Label
|
epd->print("Rudder Position"); // Label
|
||||||
|
|
||||||
// Print Unit in RudderPosition
|
// Print Unit in RudderPosition
|
||||||
if(valid1 == true || simulation == true){
|
if(valid1 == true || simulation == true){
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(175, 110);
|
epd->setCursor(175, 110);
|
||||||
getdisplay().print(unit1); // Unit
|
epd->print(unit1); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(175, 110);
|
epd->setCursor(175, 110);
|
||||||
getdisplay().print(unit1old); // Unit
|
epd->print(unit1old); // Unit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// Print Unit of keel position
|
// Print Unit of keel position
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(145, 110);
|
epd->setCursor(145, 110);
|
||||||
getdisplay().print("No sensor data"); // Info missing sensor
|
epd->print("No sensor data"); // Info missing sensor
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate rudder position
|
// Calculate rudder position
|
||||||
@@ -188,7 +192,7 @@ public:
|
|||||||
float xx2 = startwidth;
|
float xx2 = startwidth;
|
||||||
float yy1 = -startwidth;
|
float yy1 = -startwidth;
|
||||||
float yy2 = -(rInstrument * 0.5);
|
float yy2 = -(rInstrument * 0.5);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
||||||
// Inverted pointer
|
// Inverted pointer
|
||||||
@@ -198,14 +202,14 @@ public:
|
|||||||
float ix2 = -endwidth;
|
float ix2 = -endwidth;
|
||||||
float iy1 = -(rInstrument * 0.5);
|
float iy1 = -(rInstrument * 0.5);
|
||||||
float iy2 = -endwidth;
|
float iy2 = -endwidth;
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1),
|
epd->fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1),
|
||||||
200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1),
|
200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1),
|
||||||
200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Center circle
|
// Center circle
|
||||||
getdisplay().fillCircle(200, 150, startwidth + 6, commonData->bgcolor);
|
epd->fillCircle(200, 150, startwidth + 6, commonData->bgcolor);
|
||||||
getdisplay().fillCircle(200, 150, startwidth + 4, commonData->fgcolor);
|
epd->fillCircle(200, 150, startwidth + 4, commonData->fgcolor);
|
||||||
|
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
#include "OBP60Extensions.h"
|
#include "OBP60Extensions.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
#include "BoatDataCalibration.h"
|
#include "BoatDataCalibration.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
const int SixValues_x1 = 5;
|
const int SixValues_x1 = 5;
|
||||||
const int SixValues_DeltaX = 200;
|
const int SixValues_DeltaX = 200;
|
||||||
@@ -15,12 +19,12 @@ const int HowManyValues = 6;
|
|||||||
class PageSixValues : public Page
|
class PageSixValues : public Page
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PageSixValues(CommonData &common){
|
PageSixValues(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageSixValues");
|
logger->logDebug(GwLog::LOG, "Instantiate PageSixValues");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key) {
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -29,10 +33,17 @@ class PageSixValues : public Page
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
int displayPage(PageData &pageData){
|
void displayNew(PageData &pageData) {
|
||||||
GwConfigHandler *config = commonData->config;
|
#ifdef BOARD_OBP60S3
|
||||||
GwLog *logger = commonData->logger;
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int displayPage(PageData &pageData) {
|
||||||
|
|
||||||
// Old values for hold function
|
// Old values for hold function
|
||||||
static String OldDataText[HowManyValues] = {"", "", "", "", "", ""};
|
static String OldDataText[HowManyValues] = {"", "", "", "", "", ""};
|
||||||
@@ -57,33 +68,29 @@ class PageSixValues : public Page
|
|||||||
bvalue = pageData.values[i];
|
bvalue = pageData.values[i];
|
||||||
DataName[i] = xdrDelete(bvalue->getName());
|
DataName[i] = xdrDelete(bvalue->getName());
|
||||||
DataName[i] = DataName[i].substring(0, 6); // String length limit for value name
|
DataName[i] = DataName[i].substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
DataValue[i] = bvalue->value; // Value as double in SI unit
|
DataValue[i] = bvalue->value; // Value as double in SI unit
|
||||||
DataValid[i] = bvalue->valid;
|
DataValid[i] = bvalue->valid;
|
||||||
DataText[i] = formatValue(bvalue, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
DataText[i] = commonData->fmt->formatValue(bvalue, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
DataUnits[i] = formatValue(bvalue, *commonData).unit;
|
DataUnits[i] = commonData->fmt->formatValue(bvalue, *commonData).unit;
|
||||||
DataFormat[i] = bvalue->getFormat(); // Unit of value
|
DataFormat[i] = bvalue->getFormat(); // Unit of value
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
|
||||||
if(String(flashLED) == "Limit Violation"){
|
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bvalue == NULL) return PAGE_OK; // WTF why this statement?
|
if (bvalue == NULL) return PAGE_OK; // WTF why this statement?
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
for (int i = 0; i < ( HowManyValues / 2 ); i++) {
|
for (int i = 0; i < ( HowManyValues / 2 ); i++) {
|
||||||
if (i < (HowManyValues / 2) - 1) { // Don't draw horizontal line after last line of values -> standard design
|
if (i < (HowManyValues / 2) - 1) { // Don't draw horizontal line after last line of values -> standard design
|
||||||
// Horizontal line 3 pix
|
// Horizontal line 3 pix
|
||||||
getdisplay().fillRect(0, SixValues_y1+(i+1)*SixValues_DeltaY, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, SixValues_y1+(i+1)*SixValues_DeltaY, 400, 3, commonData->fgcolor);
|
||||||
}
|
}
|
||||||
for (int j = 0; j < 2; j++) {
|
for (int j = 0; j < 2; j++) {
|
||||||
int ValueIndex = i * 2 + j;
|
int ValueIndex = i * 2 + j;
|
||||||
@@ -92,67 +99,67 @@ class PageSixValues : public Page
|
|||||||
LOG_DEBUG(GwLog::LOG, "Drawing at PageSixValue: %d %s %f %s", ValueIndex, DataName[ValueIndex], DataValue[ValueIndex], DataFormat[ValueIndex]);
|
LOG_DEBUG(GwLog::LOG, "Drawing at PageSixValue: %d %s %f %s", ValueIndex, DataName[ValueIndex], DataValue[ValueIndex], DataFormat[ValueIndex]);
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(x0, y0+25);
|
epd->setCursor(x0, y0+25);
|
||||||
getdisplay().print(DataName[ValueIndex]); // Page name
|
epd->print(DataName[ValueIndex]); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(x0, y0+72);
|
epd->setCursor(x0, y0+72);
|
||||||
if (holdvalues == false) {
|
if (holdvalues == false) {
|
||||||
getdisplay().print(DataUnits[ValueIndex]); // Unit
|
epd->print(DataUnits[ValueIndex]); // Unit
|
||||||
}
|
} else {
|
||||||
else{
|
epd->print(OldDataUnits[ValueIndex]);
|
||||||
getdisplay().print(OldDataUnits[ValueIndex]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
if (DataFormat[ValueIndex] == "formatLatitude" || DataFormat[ValueIndex] == "formatLongitude") {
|
if (DataFormat[ValueIndex] == "formatLatitude" || DataFormat[ValueIndex] == "formatLongitude") {
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(x0+10, y0+60);
|
epd->setCursor(x0+10, y0+60);
|
||||||
}
|
}
|
||||||
else if (DataFormat[ValueIndex] == "formatTime" || DataFormat[ValueIndex] == "formatDate") {
|
else if (DataFormat[ValueIndex] == "formatTime" || DataFormat[ValueIndex] == "formatDate") {
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().setCursor(x0+20,y0+55);
|
epd->setCursor(x0+20,y0+55);
|
||||||
}
|
}
|
||||||
// pressure in hPa
|
// pressure in hPa
|
||||||
else if (DataFormat[ValueIndex] == "formatXdr:P:P") {
|
else if (DataFormat[ValueIndex] == "formatXdr:P:P") {
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic26pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic26pt7b);
|
||||||
getdisplay().setCursor(x0+5, y0+70);
|
epd->setCursor(x0+5, y0+70);
|
||||||
}
|
}
|
||||||
// RPM
|
// RPM
|
||||||
else if (DataFormat[ValueIndex] == "formatXdr:T:R") {
|
else if (DataFormat[ValueIndex] == "formatXdr:T:R") {
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic16pt7b);
|
||||||
getdisplay().setCursor(x0+25, y0+70);
|
epd->setCursor(x0+25, y0+70);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic26pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic26pt7b);
|
||||||
if ( DataText[ValueIndex][0] == '-' )
|
if (DataText[ValueIndex][0] == '-' ) {
|
||||||
getdisplay().setCursor(x0+25, y0+70);
|
epd->setCursor(x0+25, y0+70);
|
||||||
else
|
} else {
|
||||||
getdisplay().setCursor(x0+65, y0+70);
|
epd->setCursor(x0+65, y0+70);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if (holdvalues == false) {
|
if (holdvalues == false) {
|
||||||
getdisplay().print(DataText[ValueIndex]); // Real value as formated string
|
epd->print(DataText[ValueIndex]); // Real value as formated string
|
||||||
}
|
} else{
|
||||||
else{
|
epd->print(OldDataText[ValueIndex]); // Old value as formated string
|
||||||
getdisplay().print(OldDataText[ValueIndex]); // Old value as formated string
|
|
||||||
}
|
}
|
||||||
if (DataValid[ValueIndex] == true) {
|
if (DataValid[ValueIndex] == true) {
|
||||||
OldDataText[ValueIndex] = DataText[ValueIndex]; // Save the old value
|
OldDataText[ValueIndex] = DataText[ValueIndex]; // Save the old value
|
||||||
OldDataUnits[ValueIndex] = DataUnits[ValueIndex]; // Save the old unit
|
OldDataUnits[ValueIndex] = DataUnits[ValueIndex]; // Save the old unit
|
||||||
}
|
}
|
||||||
}
|
} // for j
|
||||||
// Vertical line 3 pix
|
// Vertical line 3 pix
|
||||||
getdisplay().fillRect(SixValues_x1+SixValues_DeltaX-8, SixValues_y1+i*SixValues_DeltaY, 3, SixValues_DeltaY, commonData->fgcolor);
|
epd->fillRect(SixValues_x1+SixValues_DeltaX-8, SixValues_y1+i*SixValues_DeltaY, 3, SixValues_DeltaY, commonData->fgcolor);
|
||||||
}
|
} // for i
|
||||||
|
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static Page *createPage(CommonData &common){
|
static Page *createPage(CommonData &common){
|
||||||
return new PageSixValues(common);
|
return new PageSixValues(common);
|
||||||
}/**
|
}/**
|
||||||
|
|||||||
196
lib/obp60task/PageSkyView.cpp
Normal file
196
lib/obp60task/PageSkyView.cpp
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
|
#include "Pagedata.h"
|
||||||
|
#include "OBP60Extensions.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm> // for vector sorting
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SkyView / Satellites
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PageSkyView : public Page
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
GwBoatData *bd;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PageSkyView(CommonData &common) : Page(common)
|
||||||
|
{
|
||||||
|
// task name access is for example purpose only
|
||||||
|
TaskHandle_t currentTaskHandle = xTaskGetCurrentTaskHandle();
|
||||||
|
const char* taskName = pcTaskGetName(currentTaskHandle);
|
||||||
|
logger->logDebug(GwLog::LOG, "Instantiate PageSkyView in task '%s'", taskName);
|
||||||
|
}
|
||||||
|
|
||||||
|
int handleKey(int key) {
|
||||||
|
// return 0 to mark the key handled completely
|
||||||
|
// return the key to allow further action
|
||||||
|
if (key == 11) {
|
||||||
|
commonData->keylock = !commonData->keylock;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData) {
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
bd = pageData.api->getBoatData();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Comparator function to sort by SNR
|
||||||
|
static bool compareBySNR(const GwSatInfo& a, const GwSatInfo& b) {
|
||||||
|
return a.SNR > b.SNR; // Sort in descending order
|
||||||
|
}
|
||||||
|
|
||||||
|
int displayPage(PageData &pageData) {
|
||||||
|
|
||||||
|
std::vector<GwSatInfo> sats;
|
||||||
|
int nSat = bd->SatInfo->getNumSats();
|
||||||
|
|
||||||
|
logger->logDebug(GwLog::LOG, "Drawing at PageSkyView, %d satellites", nSat);
|
||||||
|
|
||||||
|
for (int i = 0; i < nSat; i++) {
|
||||||
|
sats.push_back(*bd->SatInfo->getAt(i));
|
||||||
|
}
|
||||||
|
std::sort(sats.begin(), sats.end(), compareBySNR);
|
||||||
|
|
||||||
|
// Draw page
|
||||||
|
//***********************************************************
|
||||||
|
|
||||||
|
// Set display in partial refresh mode
|
||||||
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
|
// current position
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
|
||||||
|
|
||||||
|
GwApi::BoatValue *bv_lat = pageData.values[0];
|
||||||
|
String sv_lat = commonData->fmt->formatValue(bv_lat, *commonData).svalue;
|
||||||
|
//epd->setCursor(300, 40);
|
||||||
|
//epd->print(sv_lat);
|
||||||
|
|
||||||
|
GwApi::BoatValue *bv_lon = pageData.values[1];
|
||||||
|
String sv_lon = commonData->fmt->formatValue(bv_lon, *commonData).svalue;
|
||||||
|
//epd->setCursor(300, 60);
|
||||||
|
//epd->print(sv_lon);
|
||||||
|
|
||||||
|
GwApi::BoatValue *bv_hdop = pageData.values[2];
|
||||||
|
String sv_hdop = commonData->fmt->formatValue(bv_hdop, *commonData).svalue;
|
||||||
|
//epd->setCursor(300, 80);
|
||||||
|
//epd->print(sv_hdop);
|
||||||
|
|
||||||
|
// sky view
|
||||||
|
Point c = {130, 148};
|
||||||
|
uint16_t r = 125;
|
||||||
|
uint16_t r1 = r / 2;
|
||||||
|
|
||||||
|
epd->fillCircle(c.x, c.y, r, commonData->bgcolor);
|
||||||
|
epd->drawCircle(c.x, c.y, r + 1, commonData->fgcolor);
|
||||||
|
epd->drawCircle(c.x, c.y, r + 2, commonData->fgcolor);
|
||||||
|
epd->drawCircle(c.x, c.y, r1, commonData->fgcolor);
|
||||||
|
|
||||||
|
// separation lines
|
||||||
|
epd->drawLine(c.x - r, c.y, c.x + r, c.y, commonData->fgcolor);
|
||||||
|
epd->drawLine(c.x, c.y - r, c.x, c.y + r, commonData->fgcolor);
|
||||||
|
Point p = {c.x, c.y - r};
|
||||||
|
Point p1, p2;
|
||||||
|
p1 = rotatePoint(c, p, 45);
|
||||||
|
p2 = rotatePoint(c, p, 45 + 180);
|
||||||
|
epd->drawLine(p1.x, p1.y, p2.x, p2.y, commonData->fgcolor);
|
||||||
|
p1 = rotatePoint(c, p, -45);
|
||||||
|
p2 = rotatePoint(c, p, -45 + 180);
|
||||||
|
epd->drawLine(p1.x, p1.y, p2.x, p2.y, commonData->fgcolor);
|
||||||
|
|
||||||
|
// directions
|
||||||
|
|
||||||
|
int16_t x1, y1;
|
||||||
|
uint16_t w, h;
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
|
||||||
|
epd->getTextBounds("N", 0, 150, &x1, &y1, &w, &h);
|
||||||
|
epd->setCursor(c.x - w / 2, c.y - r + h + 2);
|
||||||
|
epd->print("N");
|
||||||
|
|
||||||
|
epd->getTextBounds("S", 0, 150, &x1, &y1, &w, &h);
|
||||||
|
epd->setCursor(c.x - w / 2, c.y + r - 2);
|
||||||
|
epd->print("S");
|
||||||
|
|
||||||
|
epd->getTextBounds("E", 0, 150, &x1, &y1, &w, &h);
|
||||||
|
epd->setCursor(c.x + r - w - 2, c.y + h / 2);
|
||||||
|
epd->print("E");
|
||||||
|
|
||||||
|
epd->getTextBounds("W", 0, 150, &x1, &y1, &w, &h);
|
||||||
|
epd->setCursor(c.x - r + 2 , c.y + h / 2);
|
||||||
|
epd->print("W");
|
||||||
|
|
||||||
|
// show satellites in "map"
|
||||||
|
epd->setFont(&Atari6px);
|
||||||
|
for (int i = 0; i < nSat; i++) {
|
||||||
|
float arad = sats[i].Azimut * M_PI / 180.0;
|
||||||
|
float erad = sats[i].Elevation * M_PI / 180.0;
|
||||||
|
uint16_t x = c.x + sin(arad) * erad * r;
|
||||||
|
uint16_t y = c.y + cos(arad) * erad * r;
|
||||||
|
epd->drawRect(x-4, y-4, 8, 8, commonData->fgcolor);
|
||||||
|
// Add Sat number
|
||||||
|
epd->setCursor(x+5, y);
|
||||||
|
char buffer[3];
|
||||||
|
snprintf(buffer, 3, "%02d", static_cast<int>(sats[i].PRN));
|
||||||
|
epd->print(String(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signal / Noise bars
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
epd->setCursor(325, 34);
|
||||||
|
epd->print("SNR");
|
||||||
|
epd->drawRect(270, 20, 125, 257, commonData->fgcolor);
|
||||||
|
int maxsat = std::min(nSat, 12);
|
||||||
|
for (int i = 0; i < maxsat; i++) {
|
||||||
|
uint16_t y = 29 + (i + 1) * 20;
|
||||||
|
epd->setCursor(276, y);
|
||||||
|
char buffer[3];
|
||||||
|
snprintf(buffer, 3, "%02d", static_cast<int>(sats[i].PRN));
|
||||||
|
epd->print(String(buffer));
|
||||||
|
epd->drawRect(305, y-12, 85, 14, commonData->fgcolor);
|
||||||
|
epd->setCursor(315, y);
|
||||||
|
// TODO SNR as number or as bar via mode key?
|
||||||
|
if (sats[i].SNR <= 100) {
|
||||||
|
// epd->print(sats[i].SNR);
|
||||||
|
epd->fillRect(307, y-10, int(81 * sats[i].SNR / 100.0), 10, commonData->fgcolor);
|
||||||
|
} else {
|
||||||
|
epd->print("n/a");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PAGE_UPDATE;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static Page* createPage(CommonData &common){
|
||||||
|
return new PageSkyView(common);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* with the code below we make this page known to the PageTask
|
||||||
|
* we give it a type (name) that can be selected in the config
|
||||||
|
* we define which function is to be called
|
||||||
|
* and we provide the number of user parameters we expect
|
||||||
|
* this will be number of BoatValue pointers in pageData.values
|
||||||
|
*/
|
||||||
|
PageDescription registerPageSkyView(
|
||||||
|
"SkyView", // Page name
|
||||||
|
createPage, // Action
|
||||||
|
0, // Number of bus values depends on selection in Web configuration
|
||||||
|
{"LAT", "LON", "HDOP"}, // Bus values we need in the page
|
||||||
|
true // Show display header on/off
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
@@ -6,12 +7,23 @@
|
|||||||
|
|
||||||
class PageSolar : public Page
|
class PageSolar : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String batVoltage;
|
||||||
|
int solPower;
|
||||||
|
String powerSensor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageSolar(CommonData &common){
|
PageSolar(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageSolar");
|
logger->logDebug(GwLog::LOG, "Instantiate PageSolar");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
String batVoltage = config->getString(config->batteryVoltage);
|
||||||
|
int solPower = config->getInt(config->solarPower);
|
||||||
|
String powerSensor = config->getString(config->usePowSensor2);
|
||||||
}
|
}
|
||||||
virtual int handleKey(int key){
|
|
||||||
|
int handleKey(int key){
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -21,17 +33,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int displayPage(PageData &pageData) {
|
int displayPage(PageData &pageData) {
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
// Get config data
|
|
||||||
bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String batVoltage = config->getString(config->batteryVoltage);
|
|
||||||
int solPower = config->getInt(config->solarPower);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
String powerSensor = config->getString(config->usePowSensor2);
|
|
||||||
|
|
||||||
double value1 = 0; // Solar voltage
|
double value1 = 0; // Solar voltage
|
||||||
double value2 = 0; // Solar current
|
double value2 = 0; // Solar current
|
||||||
@@ -59,97 +60,92 @@ public:
|
|||||||
bool valid1 = true;
|
bool valid1 = true;
|
||||||
|
|
||||||
// Optical warning by limit violation
|
// Optical warning by limit violation
|
||||||
if(String(flashLED) == "Limit Violation"){
|
if (flashLED == "Limit Violation") {
|
||||||
// Over voltage
|
// Over voltage?
|
||||||
if(value1 > 14.8 && batVoltage == "12V"){
|
if (batVoltage == "12V") {
|
||||||
setBlinkingLED(true);
|
setBlinkingLED(value1 > 14.8);
|
||||||
}
|
} else if (batVoltage == "24V") {
|
||||||
if(value1 <= 14.8 && batVoltage == "12V"){
|
setBlinkingLED(value1 > 29.6);
|
||||||
setBlinkingLED(false);
|
} else {
|
||||||
}
|
|
||||||
if(value1 > 29.6 && batVoltage == "24V"){
|
|
||||||
setBlinkingLED(true);
|
|
||||||
}
|
|
||||||
if(value1 <= 29.6 && batVoltage == "24V"){
|
|
||||||
setBlinkingLED(false);
|
setBlinkingLED(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logging voltage value
|
// Logging voltage value
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageSolar, Type:%iW %s:=%f", solPower, name1.c_str(), value1);
|
logger->logDebug(GwLog::LOG, "Drawing at PageSolar, Type:%iW %s:=%f", solPower, name1.c_str(), value1);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(10, 65);
|
epd->setCursor(10, 65);
|
||||||
getdisplay().print("Solar");
|
epd->print("Solar");
|
||||||
|
|
||||||
// Show voltage type
|
// Show voltage type
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(10, 140);
|
epd->setCursor(10, 140);
|
||||||
int bvoltage = 0;
|
int bvoltage = 0;
|
||||||
if(String(batVoltage) == "12V") bvoltage = 12;
|
if(String(batVoltage) == "12V") bvoltage = 12;
|
||||||
else bvoltage = 24;
|
else bvoltage = 24;
|
||||||
getdisplay().print(bvoltage);
|
epd->print(bvoltage);
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().print("V");
|
epd->print("V");
|
||||||
|
|
||||||
// Show solar power
|
// Show solar power
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(10, 200);
|
epd->setCursor(10, 200);
|
||||||
if(solPower <= 999) getdisplay().print(solPower, 0);
|
if(solPower <= 999) epd->print(solPower, 0);
|
||||||
if(solPower > 999) getdisplay().print(float(solPower/1000.0), 1);
|
if(solPower > 999) epd->print(float(solPower/1000.0), 1);
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
if(solPower <= 999) getdisplay().print("W");
|
if(solPower <= 999) epd->print("W");
|
||||||
if(solPower > 999) getdisplay().print("kW");
|
if(solPower > 999) epd->print("kW");
|
||||||
|
|
||||||
// Show info
|
// Show info
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(10, 235);
|
epd->setCursor(10, 235);
|
||||||
getdisplay().print("Installed");
|
epd->print("Installed");
|
||||||
getdisplay().setCursor(10, 255);
|
epd->setCursor(10, 255);
|
||||||
getdisplay().print("Solar Modul");
|
epd->print("Solar Modul");
|
||||||
|
|
||||||
// Show solar panel
|
// Show solar panel
|
||||||
solarGraphic(150, 45, commonData->fgcolor, commonData->bgcolor);
|
solarGraphic(150, 45, commonData->fgcolor, commonData->bgcolor);
|
||||||
|
|
||||||
// Show load level in percent
|
// Show load level in percent
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(150, 200);
|
epd->setCursor(150, 200);
|
||||||
getdisplay().print(solPercentage);
|
epd->print(solPercentage);
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().print("%");
|
epd->print("%");
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(150, 235);
|
epd->setCursor(150, 235);
|
||||||
getdisplay().print("Load");
|
epd->print("Load");
|
||||||
|
|
||||||
// Show sensor type info
|
// Show sensor type info
|
||||||
String i2cAddr = "";
|
String i2cAddr = "";
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(270, 60);
|
epd->setCursor(270, 60);
|
||||||
if(powerSensor == "off") getdisplay().print("Internal");
|
if(powerSensor == "off") epd->print("Internal");
|
||||||
if(powerSensor == "INA219"){
|
if(powerSensor == "INA219"){
|
||||||
getdisplay().print("INA219");
|
epd->print("INA219");
|
||||||
i2cAddr = " (0x" + String(INA219_I2C_ADDR2, HEX) + ")";
|
i2cAddr = " (0x" + String(INA219_I2C_ADDR2, HEX) + ")";
|
||||||
}
|
}
|
||||||
if(powerSensor == "INA226"){
|
if(powerSensor == "INA226"){
|
||||||
getdisplay().print("INA226");
|
epd->print("INA226");
|
||||||
i2cAddr = " (0x" + String(INA226_I2C_ADDR2, HEX) + ")";
|
i2cAddr = " (0x" + String(INA226_I2C_ADDR2, HEX) + ")";
|
||||||
}
|
}
|
||||||
getdisplay().print(i2cAddr);
|
epd->print(i2cAddr);
|
||||||
getdisplay().setCursor(270, 80);
|
epd->setCursor(270, 80);
|
||||||
getdisplay().print("Sensor Modul");
|
epd->print("Sensor Modul");
|
||||||
|
|
||||||
// Reading bus data or using simulation data
|
// Reading bus data or using simulation data
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(260, 140);
|
epd->setCursor(260, 140);
|
||||||
if(simulation == true){
|
if(simulation == true){
|
||||||
if(batVoltage == "12V"){
|
if(batVoltage == "12V"){
|
||||||
value1 = 12.0;
|
value1 = 12.0;
|
||||||
@@ -158,46 +154,62 @@ public:
|
|||||||
value1 = 24.0;
|
value1 = 24.0;
|
||||||
}
|
}
|
||||||
value1 += float(random(0, 5)) / 10; // Simulation data
|
value1 += float(random(0, 5)) / 10; // Simulation data
|
||||||
getdisplay().print(value1,1);
|
epd->print(value1,1);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// Check for valid real data, display also if hold values activated
|
// Check for valid real data, display also if hold values activated
|
||||||
if(valid1 == true || holdvalues == true){
|
if(valid1 == true || holdvalues == true){
|
||||||
// Resolution switching
|
// Resolution switching
|
||||||
if(value1 <= 9.9) getdisplay().print(value1, 2);
|
if (value1 <= 9.9) {
|
||||||
if(value1 > 9.9 && value1 <= 99.9)getdisplay().print(value1, 1);
|
epd->print(value1, 2);
|
||||||
if(value1 > 99.9) getdisplay().print(value1, 0);
|
} else if (value1 <= 99.9) {
|
||||||
|
epd->print(value1, 1);
|
||||||
|
} else {
|
||||||
|
epd->print(value1, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
getdisplay().print("---"); // Missing bus data
|
epd->print(commonData->fmt->placeholder); // Missing bus data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().print("V");
|
epd->print("V");
|
||||||
|
|
||||||
// Show actual current in A
|
// Show actual current in A
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(260, 200);
|
epd->setCursor(260, 200);
|
||||||
if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){
|
if ((powerSensor == "INA219" || powerSensor == "INA226") && (simulation == false)) {
|
||||||
if(value2 <= 9.9) getdisplay().print(value2, 2);
|
if (value2 <= 9.9) {
|
||||||
if(value2 > 9.9 && value2 <= 99.9)getdisplay().print(value2, 1);
|
epd->print(value2, 2);
|
||||||
if(value2 > 99.9) getdisplay().print(value2, 0);
|
} else if (value2 <= 99.9) {
|
||||||
|
epd->print(value2, 1);
|
||||||
|
} else {
|
||||||
|
epd->print(value2, 0);
|
||||||
}
|
}
|
||||||
else getdisplay().print("---");
|
}
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
else {
|
||||||
getdisplay().print("A");
|
epd->print(commonData->fmt->placeholder);
|
||||||
|
}
|
||||||
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
|
epd->print("A");
|
||||||
|
|
||||||
// Show actual consumption in W
|
// Show actual consumption in W
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(260, 260);
|
epd->setCursor(260, 260);
|
||||||
if((powerSensor == "INA219" || powerSensor == "INA226") && simulation == false){
|
if ((powerSensor == "INA219" || powerSensor == "INA226") && (simulation == false)) {
|
||||||
if(value3 <= 9.9) getdisplay().print(value3, 2);
|
if (value3 <= 9.9) {
|
||||||
if(value3 > 9.9 && value3 <= 99.9)getdisplay().print(value3, 1);
|
epd->print(value3, 2);
|
||||||
if(value3 > 99.9) getdisplay().print(value3, 0);
|
} else if (value3 <= 99.9) {
|
||||||
|
epd->print(value3, 1);
|
||||||
|
} else {
|
||||||
|
epd->print(value3, 0);
|
||||||
}
|
}
|
||||||
else getdisplay().print("---");
|
}
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
else {
|
||||||
getdisplay().print("W");
|
epd->print(commonData->fmt->placeholder);
|
||||||
|
}
|
||||||
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
|
epd->print("W");
|
||||||
|
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,14 +1,38 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special system page, called directly with fast key sequence 5,4
|
||||||
|
* Out of normal page order.
|
||||||
|
* Consists of some sub-pages with following content:
|
||||||
|
* 1. Hard and software information
|
||||||
|
* 2. System settings
|
||||||
|
* 3. System configuration: running and NVRAM
|
||||||
|
* 4. NMEA2000 device list if NMEA2000 enabled
|
||||||
|
* 5. SD Card information if available
|
||||||
|
*
|
||||||
|
* TODO
|
||||||
|
* - setCpuFrequencyMhz(80|160|240);
|
||||||
|
* - Accesspoint / ! Änderung im Gatewaycode erforderlich?
|
||||||
|
* if (! isApActive()) {
|
||||||
|
* wifiSSID = config->getString(config->wifiSSID);
|
||||||
|
* wifiPass = config->getString(config->wifiPass);
|
||||||
|
* wifiSoftAP(wifiSSID, wifiPass);
|
||||||
|
* }
|
||||||
|
* - Power mode
|
||||||
|
* powerInit(powermode);
|
||||||
|
*/
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
#include "OBP60Extensions.h"
|
#include "OBP60Extensions.h"
|
||||||
|
#include "ConfigMenu.h"
|
||||||
#include "images/logo64.xbm"
|
#include "images/logo64.xbm"
|
||||||
#include <esp32/clk.h>
|
#include <esp32/clk.h>
|
||||||
#include "qrcode.h"
|
#include "qrcode.h"
|
||||||
|
#include "Nmea2kTwai.h"
|
||||||
|
|
||||||
#ifdef BOARD_OBP40S3
|
#ifdef BOARD_OBP40S3
|
||||||
#include <SD.h>
|
#include "dirent.h"
|
||||||
#include <FS.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define STRINGIZE_IMPL(x) #x
|
#define STRINGIZE_IMPL(x) #x
|
||||||
@@ -19,20 +43,18 @@
|
|||||||
#define DISPLAYINFO STRINGIZE(EPDTYPE)
|
#define DISPLAYINFO STRINGIZE(EPDTYPE)
|
||||||
#define GXEPD2INFO STRINGIZE(GXEPD2VERS)
|
#define GXEPD2INFO STRINGIZE(GXEPD2VERS)
|
||||||
|
|
||||||
/*
|
#define N2K_INACTIVE_AGE 30000
|
||||||
* Special system page, called directly with fast key sequence 5,4
|
|
||||||
* Out of normal page order.
|
|
||||||
* Consists of some sub-pages with following content:
|
|
||||||
* 1. Hard and software information
|
|
||||||
* 2. System settings
|
|
||||||
* 3. NMEA2000 device list
|
|
||||||
*/
|
|
||||||
|
|
||||||
class PageSystem : public Page
|
class PageSystem : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
// NVRAM config options
|
||||||
|
String flashLED;
|
||||||
|
|
||||||
|
// Generic data access
|
||||||
|
|
||||||
uint64_t chipid;
|
uint64_t chipid;
|
||||||
bool simulation;
|
bool use_sdcard;
|
||||||
bool sdcard;
|
|
||||||
String buzzer_mode;
|
String buzzer_mode;
|
||||||
uint8_t buzzer_power;
|
uint8_t buzzer_power;
|
||||||
String cpuspeed;
|
String cpuspeed;
|
||||||
@@ -47,36 +69,526 @@ String rot_sensor;
|
|||||||
double homelat;
|
double homelat;
|
||||||
double homelon;
|
double homelon;
|
||||||
|
|
||||||
char mode = 'N'; // (N)ormal, (S)ettings, (D)evice list, (C)ard
|
Nmea2kTwai *NMEA2000;
|
||||||
|
unsigned long n2kRxOld = 0; // to detect bus activity
|
||||||
|
unsigned long n2kTxOld = 0;
|
||||||
|
long n2k_ts = 0; // timestamp of last activity
|
||||||
|
bool n2k_active = false;
|
||||||
|
|
||||||
|
char mode = 'N'; // (N)ormal, (S)ettings, (C)onfiguration, (D)evice list, c(A)rd
|
||||||
|
int8_t editmode = -1; // marker for menu/edit/set function
|
||||||
|
|
||||||
|
ConfigMenu *menu;
|
||||||
|
|
||||||
|
void incMode() {
|
||||||
|
if (mode == 'N') { // Normal
|
||||||
|
mode = 'S';
|
||||||
|
} else if (mode == 'S') { // Settings
|
||||||
|
mode = 'C';
|
||||||
|
} else if (mode == 'C') { // Config
|
||||||
|
mode = 'D';
|
||||||
|
} else if (mode == 'D') { // Device list
|
||||||
|
if (hasSDCard) {
|
||||||
|
mode = 'A'; // SD-Card
|
||||||
|
} else {
|
||||||
|
mode = 'N';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mode = 'N';
|
||||||
|
}
|
||||||
|
if (hasFRAM) fram.write(FRAM_SYSTEM_MODE, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void decMode() {
|
||||||
|
if (mode == 'N') {
|
||||||
|
if (hasSDCard) {
|
||||||
|
mode = 'A';
|
||||||
|
} else {
|
||||||
|
mode = 'D';
|
||||||
|
}
|
||||||
|
} else if (mode == 'S') { // Settings
|
||||||
|
mode = 'N';
|
||||||
|
} else if (mode == 'C') { // Config
|
||||||
|
mode = 'S';
|
||||||
|
} else if (mode == 'D') { // Device list
|
||||||
|
mode = 'C';
|
||||||
|
} else {
|
||||||
|
mode = 'D';
|
||||||
|
}
|
||||||
|
if (hasFRAM) fram.write(FRAM_SYSTEM_MODE, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayModeNormal() {
|
||||||
|
// Default system page view
|
||||||
|
|
||||||
|
uint16_t y0 = 155;
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(8, 48);
|
||||||
|
epd->print("System information");
|
||||||
|
|
||||||
|
epd->drawXBitmap(320, 25, logo64_bits, logo64_width, logo64_height, commonData->fgcolor);
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
|
||||||
|
char ssid[13];
|
||||||
|
snprintf(ssid, 13, "%04X%08X", (uint16_t)(chipid >> 32), (uint32_t)chipid);
|
||||||
|
displayBarcode(String(ssid), 320, 200, 2);
|
||||||
|
epd->setCursor(8, 70);
|
||||||
|
epd->print(String("MCUDEVICE-") + String(ssid));
|
||||||
|
|
||||||
|
epd->setCursor(8, 95);
|
||||||
|
epd->print("Firmware version: ");
|
||||||
|
epd->setCursor(150, 95);
|
||||||
|
epd->print(VERSINFO);
|
||||||
|
|
||||||
|
epd->setCursor(8, 113);
|
||||||
|
epd->print("Board version: ");
|
||||||
|
epd->setCursor(150, 113);
|
||||||
|
epd->print(BOARDINFO);
|
||||||
|
epd->print(String(" HW ") + String(PCBINFO));
|
||||||
|
|
||||||
|
epd->setCursor(8, 131);
|
||||||
|
epd->print("Display version: ");
|
||||||
|
epd->setCursor(150, 131);
|
||||||
|
epd->print(DISPLAYINFO);
|
||||||
|
epd->print("; GxEPD2 v");
|
||||||
|
epd->print(GXEPD2INFO);
|
||||||
|
|
||||||
|
epd->setCursor(8, 265);
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
epd->print("Press STBY to enter deep sleep mode");
|
||||||
|
#endif
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
epd->print("Press wheel to enter deep sleep mode");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Flash memory size
|
||||||
|
uint32_t flash_size = ESP.getFlashChipSize();
|
||||||
|
epd->setCursor(8, y0);
|
||||||
|
epd->print("FLASH:");
|
||||||
|
epd->setCursor(90, y0);
|
||||||
|
epd->print(String(flash_size / 1024) + String(" kB"));
|
||||||
|
|
||||||
|
// PSRAM memory size
|
||||||
|
uint32_t psram_size = ESP.getPsramSize();
|
||||||
|
epd->setCursor(8, y0 + 16);
|
||||||
|
epd->print("PSRAM:");
|
||||||
|
epd->setCursor(90, y0 + 16);
|
||||||
|
epd->print(String(psram_size / 1024) + String(" kB"));
|
||||||
|
|
||||||
|
// FRAM available / status
|
||||||
|
epd->setCursor(8, y0 + 32);
|
||||||
|
epd->print("FRAM:");
|
||||||
|
epd->setCursor(90, y0 + 32);
|
||||||
|
epd->print(hasFRAM ? "available" : "not found");
|
||||||
|
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
// SD-Card
|
||||||
|
epd->setCursor(8, y0 + 48);
|
||||||
|
epd->print("SD-Card:");
|
||||||
|
epd->setCursor(90, y0 + 48);
|
||||||
|
if (hasSDCard) {
|
||||||
|
uint64_t cardsize = ((uint64_t) sdcard->csd.capacity) * sdcard->csd.sector_size / (1024 * 1024);
|
||||||
|
epd->printf("%llu MB", cardsize);
|
||||||
|
if (!use_sdcard) {
|
||||||
|
epd->print(" (disabled)");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
epd->print("off");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Uptime
|
||||||
|
int64_t uptime = esp_timer_get_time() / 1000000;
|
||||||
|
String uptime_unit;
|
||||||
|
if (uptime < 120) {
|
||||||
|
uptime_unit = " seconds";
|
||||||
|
} else {
|
||||||
|
if (uptime < 2 * 3600) {
|
||||||
|
uptime /= 60;
|
||||||
|
uptime_unit = " minutes";
|
||||||
|
} else if (uptime < 2 * 3600 * 24) {
|
||||||
|
uptime /= 3600;
|
||||||
|
uptime_unit = " hours";
|
||||||
|
} else {
|
||||||
|
uptime /= 86400;
|
||||||
|
uptime_unit = " days";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
epd->setCursor(8, y0 + 80);
|
||||||
|
epd->print("Uptime:");
|
||||||
|
epd->setCursor(90, y0 + 80);
|
||||||
|
epd->print(uptime);
|
||||||
|
epd->print(uptime_unit);
|
||||||
|
|
||||||
|
// CPU speed config / active
|
||||||
|
epd->setCursor(202, y0);
|
||||||
|
epd->print("CPU speed:");
|
||||||
|
epd->setCursor(300, y0);
|
||||||
|
epd->print(cpuspeed);
|
||||||
|
epd->print(" / ");
|
||||||
|
int cpu_freq = esp_clk_cpu_freq() / 1000000;
|
||||||
|
epd->print(String(cpu_freq));
|
||||||
|
|
||||||
|
// total RAM free
|
||||||
|
int Heap_free = esp_get_free_heap_size();
|
||||||
|
epd->setCursor(202, y0 + 16);
|
||||||
|
epd->print("Total free:");
|
||||||
|
epd->setCursor(300, y0 + 16);
|
||||||
|
epd->print(String(Heap_free));
|
||||||
|
|
||||||
|
// RAM free for task
|
||||||
|
UBaseType_t RAM_free = uxTaskGetStackHighWaterMark(NULL);
|
||||||
|
epd->setCursor(202, y0 + 32);
|
||||||
|
epd->print("Task free:");
|
||||||
|
epd->setCursor(300, y0 + 32);
|
||||||
|
epd->print(String(RAM_free));
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayModeConfig() {
|
||||||
|
// Configuration interface
|
||||||
|
|
||||||
|
uint16_t x0 = 16;
|
||||||
|
uint16_t y0 = 80;
|
||||||
|
uint16_t dy = 20;
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(8, 48);
|
||||||
|
epd->print("System configuration");
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
|
||||||
|
/*epd->setCursor(x0, y0);
|
||||||
|
epd->print("CPU speed: 80 | 160 | 240");
|
||||||
|
epd->setCursor(x0, y0 + 1 * dy);
|
||||||
|
epd->print("Power mode: Max | 5V | Min");
|
||||||
|
epd->setCursor(x0, y0 + 2 * dy);
|
||||||
|
epd->print("Accesspoint: On | Off");
|
||||||
|
|
||||||
|
// TODO Change NVRAM-preferences settings here
|
||||||
|
epd->setCursor(x0, y0 + 4 * dy);
|
||||||
|
epd->print("Simulation: On | Off"); */
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
for (int i = 0 ; i < menu->getItemCount(); i++) {
|
||||||
|
ConfigMenuItem *itm = menu->getItemByIndex(i);
|
||||||
|
if (!itm) {
|
||||||
|
logger->logDebug(GwLog::ERROR, "Menu item not found: %d", i);
|
||||||
|
} else {
|
||||||
|
Rect r = menu->getItemRect(i);
|
||||||
|
bool inverted = (i == menu->getActiveIndex());
|
||||||
|
drawTextBoxed(r, itm->getLabel(), commonData->fgcolor, commonData->bgcolor, inverted, false);
|
||||||
|
if (inverted and editmode > 0) {
|
||||||
|
// triangle as edit marker
|
||||||
|
epd->fillTriangle(r.x + r.w + 20, r.y, r.x + r.w + 30, r.y + r.h / 2, r.x + r.w + 20, r.y + r.h, commonData->fgcolor);
|
||||||
|
}
|
||||||
|
epd->setCursor(r.x + r.w + 40, r.y + r.h - 4);
|
||||||
|
if (itm->getType() == "int") {
|
||||||
|
epd->print(itm->getValue());
|
||||||
|
epd->print(itm->getUnit());
|
||||||
|
} else {
|
||||||
|
epd->print(itm->getValue() == 0 ? "No" : "Yes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayModeSettings() {
|
||||||
|
// View some of the current settings
|
||||||
|
|
||||||
|
const uint16_t x0 = 8;
|
||||||
|
const uint16_t y0 = 72;
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(x0, 48);
|
||||||
|
epd->print("System settings");
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
|
||||||
|
// left column
|
||||||
|
epd->setCursor(x0, y0);
|
||||||
|
epd->print("Simulation:");
|
||||||
|
epd->setCursor(120, y0);
|
||||||
|
epd->print(simulation ? "on" : "off");
|
||||||
|
|
||||||
|
epd->setCursor(x0, y0 + 16);
|
||||||
|
epd->print("Environment:");
|
||||||
|
epd->setCursor(120, y0 + 16);
|
||||||
|
epd->print(env_module);
|
||||||
|
|
||||||
|
epd->setCursor(x0, y0 + 32);
|
||||||
|
epd->print("Buzzer:");
|
||||||
|
epd->setCursor(120, y0 + 32);
|
||||||
|
epd->print(buzzer_mode);
|
||||||
|
|
||||||
|
epd->setCursor(x0, y0 + 64);
|
||||||
|
epd->print("GPS:");
|
||||||
|
epd->setCursor(120, y0 + 64);
|
||||||
|
epd->print(gps_module);
|
||||||
|
|
||||||
|
epd->setCursor(x0, y0 + 80);
|
||||||
|
epd->print("RTC:");
|
||||||
|
epd->setCursor(120, y0 + 80);
|
||||||
|
epd->print(rtc_module);
|
||||||
|
|
||||||
|
epd->setCursor(x0, y0 + 96);
|
||||||
|
epd->print("Wifi:");
|
||||||
|
epd->setCursor(120, y0 + 96);
|
||||||
|
epd->print(commonData->status.wifiApOn ? "on" : "off");
|
||||||
|
|
||||||
|
// Home location
|
||||||
|
epd->setCursor(x0, y0 + 128);
|
||||||
|
epd->print("Home Lat.:");
|
||||||
|
drawTextRalign(230, y0 + 128, formatLatitude(homelat));
|
||||||
|
epd->setCursor(x0, y0 + 144);
|
||||||
|
epd->print("Home Lon.:");
|
||||||
|
drawTextRalign(230, y0 + 144, formatLongitude(homelon));
|
||||||
|
|
||||||
|
// right column
|
||||||
|
epd->setCursor(202, y0);
|
||||||
|
epd->print("Batt. sensor:");
|
||||||
|
epd->setCursor(320, y0);
|
||||||
|
epd->print(batt_sensor);
|
||||||
|
|
||||||
|
// Solar sensor
|
||||||
|
epd->setCursor(202, y0 + 16);
|
||||||
|
epd->print("Solar sensor:");
|
||||||
|
epd->setCursor(320, y0 + 16);
|
||||||
|
epd->print(solar_sensor);
|
||||||
|
|
||||||
|
// Generator sensor
|
||||||
|
epd->setCursor(202, y0 + 32);
|
||||||
|
epd->print("Gen. sensor:");
|
||||||
|
epd->setCursor(320, y0 + 32);
|
||||||
|
epd->print(gen_sensor);
|
||||||
|
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Backlight infos
|
||||||
|
epd->setCursor(202, y0 + 64);
|
||||||
|
epd->print("Backlight:");
|
||||||
|
epd->setCursor(320, y0 + 64);
|
||||||
|
epd->printf("%d%%", commonData->backlight.brightness);
|
||||||
|
// TODO test function with OBP60 device
|
||||||
|
epd->setCursor(202, y0 + 80);
|
||||||
|
epd->print("Bl color:");
|
||||||
|
epd->setCursor(320, y0 + 80);
|
||||||
|
epd->print(commonData->backlight.color.toName());
|
||||||
|
epd->setCursor(202, y0 + 96);
|
||||||
|
epd->print("Bl mode:");
|
||||||
|
epd->setCursor(320, y0 + 96);
|
||||||
|
epd->print(commonData->backlight.mode);
|
||||||
|
// TODO Buzzer mode and power
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Gyro sensor
|
||||||
|
// WIP / FEATURE
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayModeSDCard() {
|
||||||
|
// SD card info
|
||||||
|
uint16_t x0 = 20;
|
||||||
|
uint16_t y0 = 72;
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(8, 48);
|
||||||
|
epd->print("SD card info");
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
epd->setCursor(x0, y0);
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// This mode should not be callable by devices without card hardware
|
||||||
|
// In case of accidential reaching this, display a friendly message
|
||||||
|
epd->print("This mode is not indended to be reached!\n");
|
||||||
|
epd->print("There's nothing to see here. Move on.");
|
||||||
|
#endif
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
/* TODO identify card as OBP-Card:
|
||||||
|
magic.dat
|
||||||
|
version.dat
|
||||||
|
readme.txt
|
||||||
|
BAK/
|
||||||
|
CHARTS/
|
||||||
|
DATA/
|
||||||
|
IMAGES/
|
||||||
|
LOGS/
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Simple test for magic file in root
|
||||||
|
epd->setCursor(x0, y0 + 16);
|
||||||
|
const char* file_magic = MOUNT_POINT "/magic.dat";
|
||||||
|
logger->logDebug(GwLog::LOG, "Test magicfile: %s", file_magic);
|
||||||
|
struct stat st;
|
||||||
|
if (stat(file_magic, &st) == 0) {
|
||||||
|
epd->printf("Magicfile %s exists", file_magic);
|
||||||
|
} else {
|
||||||
|
epd->printf("Magicfile %s not found", file_magic);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Root directory check
|
||||||
|
DIR* dir = opendir(MOUNT_POINT);
|
||||||
|
int dy = 0;
|
||||||
|
if (dir != NULL) {
|
||||||
|
logger->logDebug(GwLog::LOG, "Root directory: %s", MOUNT_POINT);
|
||||||
|
struct dirent* entry;
|
||||||
|
while (((entry = readdir(dir)) != NULL) and (dy < 140)) {
|
||||||
|
epd->setCursor(x0, y0 + 64 + dy);
|
||||||
|
epd->print(entry->d_name);
|
||||||
|
// type 1 is file, type 2 is dir
|
||||||
|
if (entry->d_type == 2) {
|
||||||
|
epd->print("/");
|
||||||
|
}
|
||||||
|
dy += 20;
|
||||||
|
logger->logDebug(GwLog::LOG, " %s type %d", entry->d_name, entry->d_type);
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
} else {
|
||||||
|
logger->logDebug(GwLog::LOG, "Failed to open root directory");
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to load example pbm file
|
||||||
|
// TODO create PBM load function in imglib
|
||||||
|
String filepath = MOUNT_POINT "/IMAGES/icon-settings2.pbm";
|
||||||
|
const char* file_img = filepath.c_str();
|
||||||
|
FILE* fh = fopen(file_img, "r");
|
||||||
|
if (fh != NULL) {
|
||||||
|
logger->logDebug(GwLog::LOG, "Open file for reading: %s", file_img);
|
||||||
|
|
||||||
|
char magic[3];
|
||||||
|
char buffer[80];
|
||||||
|
|
||||||
|
// 2 Byte Magic: P1=ASCII, P4=Binary
|
||||||
|
fgets(magic, sizeof(magic), fh);
|
||||||
|
if (strcmp(magic, "P1") != 0) {
|
||||||
|
logger->logDebug(GwLog::LOG, "Not a valid PBM file of type P1 (%s)", magic);
|
||||||
|
} else {
|
||||||
|
uint16_t width = 0;
|
||||||
|
uint16_t height = 0;
|
||||||
|
while (fgets(buffer, sizeof(buffer), fh)) {
|
||||||
|
// logger->logDebug(GwLog::LOG, "%s", buffer);
|
||||||
|
if (buffer[0] == '#') {
|
||||||
|
continue; // skip comment
|
||||||
|
}
|
||||||
|
if (sscanf(buffer, "%d %d", &width, &height) == 2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger->logDebug(GwLog::LOG, "Image: %dx%d", width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*size_t bytesRead = fread(buffer, sizeof(char), sizeof(buffer) - 1, fh);
|
||||||
|
buffer[bytesRead] = '\0'; // Null-terminate the string
|
||||||
|
if (bytesRead > 0) {
|
||||||
|
logger->logDebug(GwLog::LOG, "Read %d bytes", bytesRead);
|
||||||
|
logger->logDebug(GwLog::LOG, ">%s<", buffer);
|
||||||
|
} */
|
||||||
|
|
||||||
|
/* WIP
|
||||||
|
// Read pixel data and pack into the buffer
|
||||||
|
for (int i = 0; i < width * height; i++) {
|
||||||
|
int pixel;
|
||||||
|
fscanf(file, "%d", &pixel);
|
||||||
|
|
||||||
|
// Calculate the byte index and bit position
|
||||||
|
int byteIndex = i / 8;
|
||||||
|
int bitPosition = 7 - (i % 8); // Store MSB first
|
||||||
|
|
||||||
|
// Set the corresponding bit in the byte
|
||||||
|
if (pixel == 1) {
|
||||||
|
buffer[byteIndex] |= (1 << bitPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
fclose(fh);
|
||||||
|
// epd->drawXBitmap(20, 200, buffer, width, height, commonData.fgcolor);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayModeDevicelist(bool bus_active) {
|
||||||
|
// NMEA2000 device list
|
||||||
|
|
||||||
|
// TODO Check if NMEA2000 enabled globally
|
||||||
|
// if disabled this page should not be shown
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(8, 48);
|
||||||
|
epd->print("NMEA2000 device list");
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
epd->setCursor(20, 80);
|
||||||
|
epd->print("RxD: ");
|
||||||
|
epd->print(String(commonData->status.n2kRx));
|
||||||
|
epd->setCursor(20, 100);
|
||||||
|
epd->print("TxD: ");
|
||||||
|
epd->print(String(commonData->status.n2kTx));
|
||||||
|
|
||||||
|
// show bus activity
|
||||||
|
epd->setCursor(20, 120);
|
||||||
|
epd->print("Bus: ");
|
||||||
|
epd->print(bus_active ? "active" : "inactive");
|
||||||
|
|
||||||
|
epd->setCursor(20, 140);
|
||||||
|
epd->printf("N2k source address: %d", NMEA2000->GetN2kSource());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void storeConfig() {
|
||||||
|
menu->storeValues();
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageSystem(CommonData &common){
|
PageSystem(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageSystem");
|
logger->logDebug(GwLog::LOG, "Instantiate PageSystem");
|
||||||
if (hasFRAM) {
|
if (hasFRAM) {
|
||||||
mode = fram.read(FRAM_SYSTEM_MODE);
|
mode = fram.read(FRAM_SYSTEM_MODE);
|
||||||
|
logger->logDebug(GwLog::LOG, "Loaded mode '%c' from FRAM", mode);
|
||||||
}
|
}
|
||||||
|
flashLED = config->getString(config->flashLED);
|
||||||
|
|
||||||
chipid = ESP.getEfuseMac();
|
chipid = ESP.getEfuseMac();
|
||||||
simulation = common.config->getBool(common.config->useSimuData);
|
|
||||||
#ifdef BOARD_OBP40S3
|
#ifdef BOARD_OBP40S3
|
||||||
sdcard = common.config->getBool(common.config->useSDCard);
|
use_sdcard = config->getBool(config->useSDCard);
|
||||||
#endif
|
#endif
|
||||||
buzzer_mode = common.config->getString(common.config->buzzerMode);
|
buzzer_mode = config->getString(config->buzzerMode);
|
||||||
buzzer_mode.toLowerCase();
|
buzzer_mode.toLowerCase();
|
||||||
buzzer_power = common.config->getInt(common.config->buzzerPower);
|
buzzer_power = config->getInt(config->buzzerPower);
|
||||||
cpuspeed = common.config->getString(common.config->cpuSpeed);
|
cpuspeed = config->getString(config->cpuSpeed);
|
||||||
env_module = common.config->getString(common.config->useEnvSensor);
|
env_module = config->getString(config->useEnvSensor);
|
||||||
rtc_module = common.config->getString(common.config->useRTC);
|
rtc_module = config->getString(config->useRTC);
|
||||||
gps_module = common.config->getString(common.config->useGPS);
|
gps_module = config->getString(config->useGPS);
|
||||||
batt_sensor = common.config->getString(common.config->usePowSensor1);
|
batt_sensor = config->getString(config->usePowSensor1);
|
||||||
solar_sensor = common.config->getString(common.config->usePowSensor2);
|
solar_sensor = config->getString(config->usePowSensor2);
|
||||||
gen_sensor = common.config->getString(common.config->usePowSensor3);
|
gen_sensor = config->getString(config->usePowSensor3);
|
||||||
rot_sensor = common.config->getString(common.config->useRotSensor);
|
rot_sensor = config->getString(config->useRotSensor);
|
||||||
homelat = common.config->getString(common.config->homeLAT).toDouble();
|
homelat = config->getString(config->homeLAT).toDouble();
|
||||||
homelon = common.config->getString(common.config->homeLON).toDouble();
|
homelon = config->getString(config->homeLON).toDouble();
|
||||||
|
|
||||||
|
// CPU speed: 80 | 160 | 240
|
||||||
|
// Power mode: Max | 5V | Min
|
||||||
|
// Accesspoint: On | Off
|
||||||
|
|
||||||
|
// TODO Change NVRAM-preferences settings here
|
||||||
|
// epd->setCursor(x0, y0 + 4 * dy);
|
||||||
|
// epd->print("Simulation: On | Off");
|
||||||
|
|
||||||
|
// Initialize config menu
|
||||||
|
menu = new ConfigMenu("Options", 40, 80);
|
||||||
|
menu->setItemDimension(150, 20);
|
||||||
|
|
||||||
|
ConfigMenuItem *newitem;
|
||||||
|
newitem = menu->addItem("accesspoint", "Accesspoint", "bool", 0, "");
|
||||||
|
newitem = menu->addItem("simulation", "Simulation", "on/off", 0, "");
|
||||||
|
menu->setItemActive("accesspoint");
|
||||||
|
|
||||||
|
// Create info-file if not exists
|
||||||
|
// TODO
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupKeys(){
|
void setupKeys() {
|
||||||
commonData->keydata[0].label = "EXIT";
|
commonData->keydata[0].label = "EXIT";
|
||||||
commonData->keydata[1].label = "MODE";
|
commonData->keydata[1].label = "MODE";
|
||||||
commonData->keydata[2].label = "";
|
commonData->keydata[2].label = "";
|
||||||
@@ -85,25 +597,12 @@ public:
|
|||||||
commonData->keydata[5].label = "ILUM";
|
commonData->keydata[5].label = "ILUM";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key) {
|
||||||
// do *NOT* handle key #1 this handled by obp60task as exit
|
// do *NOT* handle key #1 this handled by obp60task as exit
|
||||||
// Switch display mode
|
// Switch display mode
|
||||||
commonData->logger->logDebug(GwLog::LOG, "System keyboard handler");
|
logger->logDebug(GwLog::LOG, "System keyboard handler");
|
||||||
if (key == 2) {
|
if (key == 2) {
|
||||||
if (mode == 'N') {
|
incMode();
|
||||||
mode = 'S';
|
|
||||||
} else if (mode == 'S') {
|
|
||||||
mode = 'D';
|
|
||||||
} else if (mode == 'D') {
|
|
||||||
if (sdcard) {
|
|
||||||
mode = 'C';
|
|
||||||
} else {
|
|
||||||
mode = 'N';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mode = 'N';
|
|
||||||
}
|
|
||||||
if (hasFRAM) fram.write(FRAM_SYSTEM_MODE, mode);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#ifdef BOARD_OBP60S3
|
#ifdef BOARD_OBP60S3
|
||||||
@@ -117,6 +616,7 @@ public:
|
|||||||
}
|
}
|
||||||
// standby / deep sleep
|
// standby / deep sleep
|
||||||
if (key == 5) {
|
if (key == 5) {
|
||||||
|
logger->logDebug(GwLog::LOG, "System going into deep sleep mode...");
|
||||||
deepSleep(*commonData);
|
deepSleep(*commonData);
|
||||||
}
|
}
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
@@ -126,12 +626,18 @@ public:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef BOARD_OBP40S3
|
#ifdef BOARD_OBP40S3
|
||||||
// grab cursor keys to disable page navigation
|
// use cursor keys for local mode navigation
|
||||||
if (key == 9 or key == 10) {
|
if (key == 9) {
|
||||||
|
incMode();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (key == 10) {
|
||||||
|
decMode();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// standby / deep sleep
|
// standby / deep sleep
|
||||||
if (key == 12) {
|
if (key == 12) {
|
||||||
|
logger->logDebug(GwLog::LOG, "System going into deep sleep mode...");
|
||||||
deepSleep(*commonData);
|
deepSleep(*commonData);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -155,7 +661,7 @@ public:
|
|||||||
for (uint8_t j = 0; j < qrcode.size; j++) {
|
for (uint8_t j = 0; j < qrcode.size; j++) {
|
||||||
for (uint8_t i = 0; i < qrcode.size; i++) {
|
for (uint8_t i = 0; i < qrcode.size; i++) {
|
||||||
if (qrcode_getModule(&qrcode, i, j)) {
|
if (qrcode_getModule(&qrcode, i, j)) {
|
||||||
getdisplay().fillRect(x, y, s, s, commonData->fgcolor);
|
epd->fillRect(x, y, s, s, commonData->fgcolor);
|
||||||
}
|
}
|
||||||
x += s;
|
x += s;
|
||||||
}
|
}
|
||||||
@@ -164,233 +670,56 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int displayPage(PageData &pageData){
|
void displayNew(PageData &pageData) {
|
||||||
GwConfigHandler *config = commonData->config;
|
#ifdef BOARD_OBP60S3
|
||||||
GwLog *logger = commonData->logger;
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
// Get config data
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
|
||||||
if(String(flashLED) == "Limit Violation"){
|
|
||||||
setBlinkingLED(false);
|
setBlinkingLED(false);
|
||||||
setFlashLED(false);
|
setFlashLED(false);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
// Get references from API
|
||||||
|
logger->logDebug(GwLog::LOG, "New page display: PageSystem");
|
||||||
|
NMEA2000 = pageData.api->getNMEA2000();
|
||||||
|
};
|
||||||
|
|
||||||
// Logging boat values
|
int displayPage(PageData &pageData) {
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageSystem");
|
|
||||||
|
|
||||||
// Draw page
|
// Logging page information
|
||||||
//***********************************************************
|
logger->logDebug(GwLog::LOG, "Drawing at PageSystem, Mode=%c", mode);
|
||||||
|
|
||||||
uint16_t x0 = 8; // left column
|
|
||||||
uint16_t y0 = 48; // data table starts here
|
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height());
|
||||||
|
|
||||||
if (mode == 'N') {
|
// call current system page
|
||||||
|
switch (mode) {
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
case 'N':
|
||||||
getdisplay().setCursor(8, 48);
|
displayModeNormal();
|
||||||
getdisplay().print("System Information");
|
break;
|
||||||
|
case 'S':
|
||||||
getdisplay().drawXBitmap(320, 25, logo64_bits, logo64_width, logo64_height, commonData->fgcolor);
|
displayModeSettings();
|
||||||
|
break;
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
case 'C':
|
||||||
y0 = 155;
|
displayModeConfig();
|
||||||
|
break;
|
||||||
char ssid[13];
|
case 'A':
|
||||||
snprintf(ssid, 13, "%04X%08X", (uint16_t)(chipid >> 32), (uint32_t)chipid);
|
displayModeSDCard();
|
||||||
displayBarcode(String(ssid), 320, 200, 2);
|
break;
|
||||||
getdisplay().setCursor(8, 70);
|
case 'D':
|
||||||
getdisplay().print(String("MCUDEVICE-") + String(ssid));
|
// check bus status
|
||||||
|
if (commonData->status.n2kRx != n2kRxOld || commonData->status.n2kTx != n2kTxOld) {
|
||||||
getdisplay().setCursor(8, 95);
|
n2kRxOld = commonData->status.n2kRx;
|
||||||
getdisplay().print("Firmware version: ");
|
n2kTxOld = commonData->status.n2kTx;
|
||||||
getdisplay().setCursor(150, 95);
|
n2k_ts = millis();
|
||||||
getdisplay().print(VERSINFO);
|
|
||||||
|
|
||||||
getdisplay().setCursor(8, 113);
|
|
||||||
getdisplay().print("Board version: ");
|
|
||||||
getdisplay().setCursor(150, 113);
|
|
||||||
getdisplay().print(BOARDINFO);
|
|
||||||
getdisplay().print(String(" HW ") + String(PCBINFO));
|
|
||||||
|
|
||||||
getdisplay().setCursor(8, 131);
|
|
||||||
getdisplay().print("Display version: ");
|
|
||||||
getdisplay().setCursor(150, 131);
|
|
||||||
getdisplay().print(DISPLAYINFO);
|
|
||||||
getdisplay().print("; GxEPD2 v");
|
|
||||||
getdisplay().print(GXEPD2INFO);
|
|
||||||
|
|
||||||
getdisplay().setCursor(8, 265);
|
|
||||||
#ifdef BOARD_OBP60S3
|
|
||||||
getdisplay().print("Press STBY to enter deep sleep mode");
|
|
||||||
#endif
|
|
||||||
#ifdef BOARD_OBP40S3
|
|
||||||
getdisplay().print("Press wheel to enter deep sleep mode");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Flash memory size
|
|
||||||
uint32_t flash_size = ESP.getFlashChipSize();
|
|
||||||
getdisplay().setCursor(8, y0);
|
|
||||||
getdisplay().print("FLASH:");
|
|
||||||
getdisplay().setCursor(90, y0);
|
|
||||||
getdisplay().print(String(flash_size / 1024) + String(" kB"));
|
|
||||||
|
|
||||||
// PSRAM memory size
|
|
||||||
uint32_t psram_size = ESP.getPsramSize();
|
|
||||||
getdisplay().setCursor(8, y0 + 16);
|
|
||||||
getdisplay().print("PSRAM:");
|
|
||||||
getdisplay().setCursor(90, y0 + 16);
|
|
||||||
getdisplay().print(String(psram_size / 1024) + String(" kB"));
|
|
||||||
|
|
||||||
// FRAM available / status
|
|
||||||
getdisplay().setCursor(8, y0 + 32);
|
|
||||||
getdisplay().print("FRAM:");
|
|
||||||
getdisplay().setCursor(90, y0 + 32);
|
|
||||||
getdisplay().print(hasFRAM ? "available" : "not found");
|
|
||||||
|
|
||||||
#ifdef BOARD_OBP40S3
|
|
||||||
// SD-Card
|
|
||||||
getdisplay().setCursor(8, y0 + 48);
|
|
||||||
getdisplay().print("SD-Card:");
|
|
||||||
getdisplay().setCursor(90, y0 + 48);
|
|
||||||
if (sdcard) {
|
|
||||||
uint64_t cardsize = SD.cardSize() / (1024 * 1024);
|
|
||||||
getdisplay().print(String(cardsize) + String(" MB"));
|
|
||||||
} else {
|
} else {
|
||||||
getdisplay().print("off");
|
n2k_active = (millis() - n2k_ts <= N2K_INACTIVE_AGE);
|
||||||
}
|
}
|
||||||
#endif
|
displayModeDevicelist(n2k_active);
|
||||||
|
break;
|
||||||
// CPU speed config / active
|
|
||||||
getdisplay().setCursor(202, y0);
|
|
||||||
getdisplay().print("CPU speed:");
|
|
||||||
getdisplay().setCursor(300, y0);
|
|
||||||
getdisplay().print(cpuspeed);
|
|
||||||
getdisplay().print(" / ");
|
|
||||||
int cpu_freq = esp_clk_cpu_freq() / 1000000;
|
|
||||||
getdisplay().print(String(cpu_freq));
|
|
||||||
|
|
||||||
// total RAM free
|
|
||||||
int Heap_free = esp_get_free_heap_size();
|
|
||||||
getdisplay().setCursor(202, y0 + 16);
|
|
||||||
getdisplay().print("Total free:");
|
|
||||||
getdisplay().setCursor(300, y0 + 16);
|
|
||||||
getdisplay().print(String(Heap_free));
|
|
||||||
|
|
||||||
// RAM free for task
|
|
||||||
int RAM_free = uxTaskGetStackHighWaterMark(NULL);
|
|
||||||
getdisplay().setCursor(202, y0 + 32);
|
|
||||||
getdisplay().print("Task free:");
|
|
||||||
getdisplay().setCursor(300, y0 + 32);
|
|
||||||
getdisplay().print(String(RAM_free));
|
|
||||||
|
|
||||||
} else if (mode == 'S') {
|
|
||||||
// Settings
|
|
||||||
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
|
||||||
getdisplay().setCursor(x0, 48);
|
|
||||||
getdisplay().print("System settings");
|
|
||||||
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
|
||||||
x0 = 8;
|
|
||||||
y0 = 72;
|
|
||||||
|
|
||||||
// left column
|
|
||||||
getdisplay().setCursor(x0, y0);
|
|
||||||
getdisplay().print("Simulation:");
|
|
||||||
getdisplay().setCursor(120, y0);
|
|
||||||
getdisplay().print(simulation ? "on" : "off");
|
|
||||||
|
|
||||||
getdisplay().setCursor(x0, y0 + 16);
|
|
||||||
getdisplay().print("Environment:");
|
|
||||||
getdisplay().setCursor(120, y0 + 16);
|
|
||||||
getdisplay().print(env_module);
|
|
||||||
|
|
||||||
getdisplay().setCursor(x0, y0 + 32);
|
|
||||||
getdisplay().print("Buzzer:");
|
|
||||||
getdisplay().setCursor(120, y0 + 32);
|
|
||||||
getdisplay().print(buzzer_mode);
|
|
||||||
|
|
||||||
getdisplay().setCursor(x0, y0 + 64);
|
|
||||||
getdisplay().print("GPS:");
|
|
||||||
getdisplay().setCursor(120, y0 + 64);
|
|
||||||
getdisplay().print(gps_module);
|
|
||||||
|
|
||||||
getdisplay().setCursor(x0, y0 + 80);
|
|
||||||
getdisplay().print("RTC:");
|
|
||||||
getdisplay().setCursor(120, y0 + 80);
|
|
||||||
getdisplay().print(rtc_module);
|
|
||||||
|
|
||||||
getdisplay().setCursor(x0, y0 + 96);
|
|
||||||
getdisplay().print("Wifi:");
|
|
||||||
getdisplay().setCursor(120, y0 + 96);
|
|
||||||
getdisplay().print(commonData->status.wifiApOn ? "on" : "off");
|
|
||||||
|
|
||||||
// Home location
|
|
||||||
getdisplay().setCursor(x0, y0 + 128);
|
|
||||||
getdisplay().print("Home Lat.:");
|
|
||||||
getdisplay().setCursor(120, y0 + 128);
|
|
||||||
getdisplay().print(formatLatitude(homelat));
|
|
||||||
getdisplay().setCursor(x0, y0 + 144);
|
|
||||||
getdisplay().print("Home Lon.:");
|
|
||||||
getdisplay().setCursor(120, y0 + 144);
|
|
||||||
getdisplay().print(formatLongitude(homelon));
|
|
||||||
|
|
||||||
// right column
|
|
||||||
getdisplay().setCursor(202, y0);
|
|
||||||
getdisplay().print("Batt. sensor:");
|
|
||||||
getdisplay().setCursor(320, y0);
|
|
||||||
getdisplay().print(batt_sensor);
|
|
||||||
|
|
||||||
// Solar sensor
|
|
||||||
getdisplay().setCursor(202, y0 + 16);
|
|
||||||
getdisplay().print("Solar sensor:");
|
|
||||||
getdisplay().setCursor(320, y0 + 16);
|
|
||||||
getdisplay().print(solar_sensor);
|
|
||||||
|
|
||||||
// Generator sensor
|
|
||||||
getdisplay().setCursor(202, y0 + 32);
|
|
||||||
getdisplay().print("Gen. sensor:");
|
|
||||||
getdisplay().setCursor(320, y0 + 32);
|
|
||||||
getdisplay().print(gen_sensor);
|
|
||||||
|
|
||||||
// Gyro sensor
|
|
||||||
|
|
||||||
} else if (mode == 'C') {
|
|
||||||
// Card info
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
|
||||||
getdisplay().setCursor(8, 48);
|
|
||||||
getdisplay().print("SD Card info");
|
|
||||||
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
|
||||||
|
|
||||||
x0 = 20;
|
|
||||||
y0 = 72;
|
|
||||||
getdisplay().setCursor(x0, y0);
|
|
||||||
getdisplay().print("Work in progress...");
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// NMEA2000 device list
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
|
||||||
getdisplay().setCursor(8, 48);
|
|
||||||
getdisplay().print("NMEA2000 device list");
|
|
||||||
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
|
||||||
getdisplay().setCursor(20, 80);
|
|
||||||
getdisplay().print("RxD: ");
|
|
||||||
getdisplay().print(String(commonData->status.n2kRx));
|
|
||||||
getdisplay().setCursor(20, 100);
|
|
||||||
getdisplay().print("TxD: ");
|
|
||||||
getdisplay().print(String(commonData->status.n2kTx));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update display
|
// Update display
|
||||||
getdisplay().nextPage(); // Partial update (fast)
|
epd->nextPage(); // Partial update (fast)
|
||||||
return PAGE_OK;
|
return PAGE_OK;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,18 +1,28 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
#include "OBP60Extensions.h"
|
#include "OBP60Extensions.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
#include "BoatDataCalibration.h"
|
#include "BoatDataCalibration.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class PageThreeValues : public Page
|
class PageThreeValues : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String lengthformat;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageThreeValues(CommonData &common){
|
PageThreeValues(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageThreeValue");
|
logger->logDebug(GwLog::LOG, "Instantiate PageThreeValue");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
lengthformat = config->getString(config->lengthFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key){
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -21,9 +31,17 @@ class PageThreeValues : public Page
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData) {
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
int displayPage(PageData &pageData) {
|
int displayPage(PageData &pageData) {
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
// Old values for hold function
|
// Old values for hold function
|
||||||
static String svalue1old = "";
|
static String svalue1old = "";
|
||||||
@@ -33,97 +51,92 @@ class PageThreeValues : public Page
|
|||||||
static String svalue3old = "";
|
static String svalue3old = "";
|
||||||
static String unit3old = "";
|
static String unit3old = "";
|
||||||
|
|
||||||
// Get config data
|
|
||||||
String lengthformat = config->getString(config->lengthFormat);
|
|
||||||
// bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
|
|
||||||
// Get boat values #1
|
// Get boat values #1
|
||||||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
||||||
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
||||||
name1 = name1.substring(0, 6); // String length limit for value name
|
name1 = name1.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value1 = bvalue1->value; // Value as double in SI unit
|
double value1 = bvalue1->value; // Value as double in SI unit
|
||||||
bool valid1 = bvalue1->valid; // Valid information
|
bool valid1 = bvalue1->valid; // Valid information
|
||||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue1 = commonData->fmt->formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
String unit1 = commonData->fmt->formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #2
|
// Get boat values #2
|
||||||
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
|
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
|
||||||
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
||||||
name2 = name2.substring(0, 6); // String length limit for value name
|
name2 = name2.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value2 = bvalue2->value; // Value as double in SI unit
|
double value2 = bvalue2->value; // Value as double in SI unit
|
||||||
bool valid2 = bvalue2->valid; // Valid information
|
bool valid2 = bvalue2->valid; // Valid information
|
||||||
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue2 = commonData->fmt->formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
String unit2 = commonData->fmt->formatValue(bvalue2, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #3
|
// Get boat values #3
|
||||||
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list
|
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list
|
||||||
String name3 = xdrDelete(bvalue3->getName()); // Value name
|
String name3 = xdrDelete(bvalue3->getName()); // Value name
|
||||||
name3 = name3.substring(0, 6); // String length limit for value name
|
name3 = name3.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value3 = bvalue3->value; // Value as double in SI unit
|
double value3 = bvalue3->value; // Value as double in SI unit
|
||||||
bool valid3 = bvalue3->valid; // Valid information
|
bool valid3 = bvalue3->valid; // Valid information
|
||||||
String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue3 = commonData->fmt->formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value
|
String unit3 = commonData->fmt->formatValue(bvalue3, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
// Log boat values
|
||||||
if(String(flashLED) == "Limit Violation"){
|
logger->logDebug(GwLog::LOG, "Drawing at PageThreeValues, %s: %f, %s: %f, %s: %f",
|
||||||
setBlinkingLED(false);
|
name1.c_str(), value1,
|
||||||
setFlashLED(false);
|
name2.c_str(), value2,
|
||||||
}
|
name3.c_str(), value3);
|
||||||
|
|
||||||
// Logging boat values
|
|
||||||
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageThreeValues, %s: %f, %s: %f, %s: %f", name1.c_str(), value1, name2.c_str(), value2, name3.c_str(), value3);
|
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
/// Set display in partial refresh mode
|
/// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
// ############### Value 1 ################
|
// ############### Value 1 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 55);
|
epd->setCursor(20, 55);
|
||||||
getdisplay().print(name1); // Page name
|
epd->print(name1); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 90);
|
epd->setCursor(20, 90);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit1); // Unit
|
epd->print(unit1); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit1old);
|
epd->print(unit1old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
if(bvalue1->getFormat() == "formatLatitude" || bvalue1->getFormat() == "formatLongitude"){
|
if(bvalue1->getFormat() == "formatLatitude" || bvalue1->getFormat() == "formatLongitude"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(50, 90);
|
epd->setCursor(50, 90);
|
||||||
}
|
}
|
||||||
else if(bvalue1->getFormat() == "formatTime" || bvalue1->getFormat() == "formatDate"){
|
else if(bvalue1->getFormat() == "formatTime" || bvalue1->getFormat() == "formatDate"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(170, 68);
|
epd->setCursor(170, 68);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic30pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic30pt7b);
|
||||||
getdisplay().setCursor(180, 90);
|
epd->setCursor(180, 90);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue1); // Real value as formated string
|
epd->print(svalue1); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue1old); // Old value as formated string
|
epd->print(svalue1old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid1 == true){
|
if(valid1 == true){
|
||||||
svalue1old = svalue1; // Save the old value
|
svalue1old = svalue1; // Save the old value
|
||||||
@@ -133,45 +146,45 @@ class PageThreeValues : public Page
|
|||||||
// ############### Horizontal Line ################
|
// ############### Horizontal Line ################
|
||||||
|
|
||||||
// Horizontal line 3 pix
|
// Horizontal line 3 pix
|
||||||
getdisplay().fillRect(0, 105, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, 105, 400, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 2 ################
|
// ############### Value 2 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 145);
|
epd->setCursor(20, 145);
|
||||||
getdisplay().print(name2); // Page name
|
epd->print(name2); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 180);
|
epd->setCursor(20, 180);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit2); // Unit
|
epd->print(unit2); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit2old);
|
epd->print(unit2old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
if(bvalue2->getFormat() == "formatLatitude" || bvalue2->getFormat() == "formatLongitude"){
|
if(bvalue2->getFormat() == "formatLatitude" || bvalue2->getFormat() == "formatLongitude"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(50, 180);
|
epd->setCursor(50, 180);
|
||||||
}
|
}
|
||||||
else if(bvalue2->getFormat() == "formatTime" || bvalue2->getFormat() == "formatDate"){
|
else if(bvalue2->getFormat() == "formatTime" || bvalue2->getFormat() == "formatDate"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(170, 158);
|
epd->setCursor(170, 158);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic30pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic30pt7b);
|
||||||
getdisplay().setCursor(180, 180);
|
epd->setCursor(180, 180);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue2); // Real value as formated string
|
epd->print(svalue2); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue2old); // Old value as formated string
|
epd->print(svalue2old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid2 == true){
|
if(valid2 == true){
|
||||||
svalue2old = svalue2; // Save the old value
|
svalue2old = svalue2; // Save the old value
|
||||||
@@ -181,45 +194,45 @@ class PageThreeValues : public Page
|
|||||||
// ############### Horizontal Line ################
|
// ############### Horizontal Line ################
|
||||||
|
|
||||||
// Horizontal line 3 pix
|
// Horizontal line 3 pix
|
||||||
getdisplay().fillRect(0, 195, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, 195, 400, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 3 ################
|
// ############### Value 3 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 235);
|
epd->setCursor(20, 235);
|
||||||
getdisplay().print(name3); // Page name
|
epd->print(name3); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 270);
|
epd->setCursor(20, 270);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit3); // Unit
|
epd->print(unit3); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit3old);
|
epd->print(unit3old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
if(bvalue3->getFormat() == "formatLatitude" || bvalue3->getFormat() == "formatLongitude"){
|
if(bvalue3->getFormat() == "formatLatitude" || bvalue3->getFormat() == "formatLongitude"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(50, 270);
|
epd->setCursor(50, 270);
|
||||||
}
|
}
|
||||||
else if(bvalue3->getFormat() == "formatTime" || bvalue3->getFormat() == "formatDate"){
|
else if(bvalue3->getFormat() == "formatTime" || bvalue3->getFormat() == "formatDate"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(170, 248);
|
epd->setCursor(170, 248);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic30pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic30pt7b);
|
||||||
getdisplay().setCursor(180, 270);
|
epd->setCursor(180, 270);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue3); // Real value as formated string
|
epd->print(svalue3); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue3old); // Old value as formated string
|
epd->print(svalue3old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid3 == true){
|
if(valid3 == true){
|
||||||
svalue3old = svalue3; // Save the old value
|
svalue3old = svalue3; // Save the old value
|
||||||
|
|||||||
121
lib/obp60task/PageTracker.cpp
Normal file
121
lib/obp60task/PageTracker.cpp
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
|
#include "Pagedata.h"
|
||||||
|
#include "OBP60Extensions.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Tracker
|
||||||
|
- standalone with SD card backend
|
||||||
|
- standalone with server backend
|
||||||
|
- Regatta Hero integration
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PageTracker : public Page
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
char mode = 'N'; // (N)ormal, (C)onfig
|
||||||
|
|
||||||
|
void displayModeNormal(PageData &pageData) {
|
||||||
|
|
||||||
|
// TBD Boatvalues: ...
|
||||||
|
|
||||||
|
logger->logDebug(GwLog::DEBUG,"Drawing at PageTracker");
|
||||||
|
|
||||||
|
// Title
|
||||||
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(8, 48);
|
||||||
|
epd->print("Tracker");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayModeConfig() {
|
||||||
|
|
||||||
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(8, 48);
|
||||||
|
epd->print("Tracker configuration");
|
||||||
|
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
PageTracker(CommonData &common) : Page(common)
|
||||||
|
{
|
||||||
|
logger->logDebug(GwLog::LOG, "Instantiate PageTracker");
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupKeys(){
|
||||||
|
Page::setupKeys();
|
||||||
|
commonData->keydata[0].label = "START";
|
||||||
|
commonData->keydata[1].label = "STOP";
|
||||||
|
}
|
||||||
|
|
||||||
|
int handleKey(int key){
|
||||||
|
if (key == 1) { // Switch between normal and config mode
|
||||||
|
if (mode == 'N') {
|
||||||
|
mode = 'C';
|
||||||
|
} else {
|
||||||
|
mode = 'N';
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (key == 11) {
|
||||||
|
commonData->keylock = !commonData->keylock;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData) {
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int displayPage(PageData &pageData){
|
||||||
|
|
||||||
|
// Logging boat values
|
||||||
|
logger->logDebug(GwLog::LOG, "Drawing at PageTracker; Mode=%c", mode);
|
||||||
|
|
||||||
|
// Set display in partial refresh mode
|
||||||
|
epd->setPartialWindow(0, 0, epd->width(), epd->height());
|
||||||
|
|
||||||
|
if (mode == 'N') {
|
||||||
|
displayModeNormal(pageData);
|
||||||
|
} else if (mode == 'C') {
|
||||||
|
displayModeConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
return PAGE_UPDATE;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static Page *createPage(CommonData &common){
|
||||||
|
return new PageTracker(common);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* with the code below we make this page known to the PageTask
|
||||||
|
* we give it a type (name) that can be selected in the config
|
||||||
|
* we define which function is to be called
|
||||||
|
* and we provide the number of user parameters we expect
|
||||||
|
* this will be number of BoatValue pointers in pageData.values
|
||||||
|
*/
|
||||||
|
PageDescription registerPageTracker(
|
||||||
|
"Tracker", // Page name
|
||||||
|
createPage, // Action
|
||||||
|
0, // Number of bus values depends on selection in Web configuration
|
||||||
|
{"LAT", "LON"}, // Names of bus values undepends on selection in Web configuration (refer GwBoatData.h)
|
||||||
|
true // Show display header on/off
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,18 +1,28 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
#include "OBP60Extensions.h"
|
#include "OBP60Extensions.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
#include "BoatDataCalibration.h"
|
#include "BoatDataCalibration.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class PageTwoValues : public Page
|
class PageTwoValues : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String lengthformat;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageTwoValues(CommonData &common){
|
PageTwoValues(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageTwoValue");
|
logger->logDebug(GwLog::LOG, "Instantiate PageTwoValue");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
lengthformat = config->getString(config->lengthFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key){
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -21,9 +31,17 @@ class PageTwoValues : public Page
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData) {
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
int displayPage(PageData &pageData) {
|
int displayPage(PageData &pageData) {
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
// Old values for hold function
|
// Old values for hold function
|
||||||
static String svalue1old = "";
|
static String svalue1old = "";
|
||||||
@@ -31,87 +49,79 @@ class PageTwoValues : public Page
|
|||||||
static String svalue2old = "";
|
static String svalue2old = "";
|
||||||
static String unit2old = "";
|
static String unit2old = "";
|
||||||
|
|
||||||
// Get config data
|
|
||||||
String lengthformat = config->getString(config->lengthFormat);
|
|
||||||
// bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
|
|
||||||
// Get boat values #1
|
// Get boat values #1
|
||||||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
||||||
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
||||||
name1 = name1.substring(0, 6); // String length limit for value name
|
name1 = name1.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value1 = bvalue1->value; // Value as double in SI unit
|
double value1 = bvalue1->value; // Value as double in SI unit
|
||||||
bool valid1 = bvalue1->valid; // Valid information
|
bool valid1 = bvalue1->valid; // Valid information
|
||||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue1 = commonData->fmt->formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
String unit1 = commonData->fmt->formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values #2
|
// Get boat values #2
|
||||||
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
|
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
|
||||||
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
||||||
name2 = name2.substring(0, 6); // String length limit for value name
|
name2 = name2.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value2 = bvalue2->value; // Value as double in SI unit
|
double value2 = bvalue2->value; // Value as double in SI unit
|
||||||
bool valid2 = bvalue2->valid; // Valid information
|
bool valid2 = bvalue2->valid; // Valid information
|
||||||
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue2 = commonData->fmt->formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
String unit2 = commonData->fmt->formatValue(bvalue2, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
|
||||||
if(String(flashLED) == "Limit Violation"){
|
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logging boat values
|
// Logging boat values
|
||||||
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageTwoValues, %s: %f, %s: %f", name1.c_str(), value1, name2.c_str(), value2);
|
logger->logDebug(GwLog::LOG, "Drawing at PageTwoValues, %s: %f, %s: %f", name1.c_str(), value1, name2.c_str(), value2);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
// ############### Value 1 ################
|
// ############### Value 1 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 80);
|
epd->setCursor(20, 80);
|
||||||
getdisplay().print(name1); // Page name
|
epd->print(name1); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 130);
|
epd->setCursor(20, 130);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit1); // Unit
|
epd->print(unit1); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit1old);
|
epd->print(unit1old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
if(bvalue1->getFormat() == "formatLatitude" || bvalue1->getFormat() == "formatLongitude"){
|
if(bvalue1->getFormat() == "formatLatitude" || bvalue1->getFormat() == "formatLongitude"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(50, 130);
|
epd->setCursor(50, 130);
|
||||||
}
|
}
|
||||||
else if(bvalue1->getFormat() == "formatTime" || bvalue1->getFormat() == "formatDate"){
|
else if(bvalue1->getFormat() == "formatTime" || bvalue1->getFormat() == "formatDate"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(170, 105);
|
epd->setCursor(170, 105);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic42pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic42pt7b);
|
||||||
getdisplay().setCursor(180, 130);
|
epd->setCursor(180, 130);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue1); // Real value as formated string
|
epd->print(svalue1); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue1old); // Old value as formated string
|
epd->print(svalue1old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid1 == true){
|
if(valid1 == true){
|
||||||
svalue1old = svalue1; // Save the old value
|
svalue1old = svalue1; // Save the old value
|
||||||
@@ -121,45 +131,45 @@ class PageTwoValues : public Page
|
|||||||
// ############### Horizontal Line ################
|
// ############### Horizontal Line ################
|
||||||
|
|
||||||
// Horizontal line 3 pix
|
// Horizontal line 3 pix
|
||||||
getdisplay().fillRect(0, 145, 400, 3, commonData->fgcolor);
|
epd->fillRect(0, 145, 400, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// ############### Value 2 ################
|
// ############### Value 2 ################
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 190);
|
epd->setCursor(20, 190);
|
||||||
getdisplay().print(name2); // Page name
|
epd->print(name2); // Page name
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(20, 240);
|
epd->setCursor(20, 240);
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(unit2); // Unit
|
epd->print(unit2); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(unit2old);
|
epd->print(unit2old);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch font if format for any values
|
// Switch font if format for any values
|
||||||
if(bvalue2->getFormat() == "formatLatitude" || bvalue2->getFormat() == "formatLongitude"){
|
if(bvalue2->getFormat() == "formatLatitude" || bvalue2->getFormat() == "formatLongitude"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(50, 240);
|
epd->setCursor(50, 240);
|
||||||
}
|
}
|
||||||
else if(bvalue2->getFormat() == "formatTime" || bvalue2->getFormat() == "formatDate"){
|
else if(bvalue2->getFormat() == "formatTime" || bvalue2->getFormat() == "formatDate"){
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(170, 215);
|
epd->setCursor(170, 215);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic42pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic42pt7b);
|
||||||
getdisplay().setCursor(180, 240);
|
epd->setCursor(180, 240);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show bus data
|
// Show bus data
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue2); // Real value as formated string
|
epd->print(svalue2); // Real value as formated string
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue2old); // Old value as formated string
|
epd->print(svalue2old); // Old value as formated string
|
||||||
}
|
}
|
||||||
if(valid2 == true){
|
if(valid2 == true){
|
||||||
svalue2old = svalue2; // Save the old value
|
svalue2old = svalue2; // Save the old value
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
@@ -6,6 +7,9 @@
|
|||||||
|
|
||||||
class PageVoltage : public Page
|
class PageVoltage : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String batVoltage;
|
||||||
|
String batType;
|
||||||
bool init = false; // Marker for init done
|
bool init = false; // Marker for init done
|
||||||
uint8_t average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s
|
uint8_t average = 0; // Average type [0...3], 0=off, 1=10s, 2=60s, 3=300s
|
||||||
bool trend = true; // Trend indicator [0|1], 0=off, 1=on
|
bool trend = true; // Trend indicator [0|1], 0=off, 1=on
|
||||||
@@ -13,9 +17,14 @@ double raw = 0;
|
|||||||
char mode = 'D'; // display mode (A)nalog | (D)igital
|
char mode = 'D'; // display mode (A)nalog | (D)igital
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageVoltage(CommonData &common){
|
PageVoltage(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageVoltage");
|
logger->logDebug(GwLog::LOG, "Instantiate PageVoltage");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
batVoltage = config->getString(config->batteryVoltage);
|
||||||
|
batType = config->getString(config->batteryType);
|
||||||
|
|
||||||
if (hasFRAM) {
|
if (hasFRAM) {
|
||||||
average = fram.read(FRAM_VOLTAGE_AVG);
|
average = fram.read(FRAM_VOLTAGE_AVG);
|
||||||
trend = fram.read(FRAM_VOLTAGE_TREND);
|
trend = fram.read(FRAM_VOLTAGE_TREND);
|
||||||
@@ -23,14 +32,18 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupKeys(){
|
~PageVoltage(){
|
||||||
|
logger->logDebug(GwLog::LOG, "Destroy PageVoltage");
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupKeys() {
|
||||||
Page::setupKeys();
|
Page::setupKeys();
|
||||||
commonData->keydata[0].label = "AVG";
|
commonData->keydata[0].label = "AVG";
|
||||||
commonData->keydata[1].label = "MODE";
|
commonData->keydata[1].label = "MODE";
|
||||||
commonData->keydata[4].label = "TRD";
|
commonData->keydata[4].label = "TRD";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key) {
|
||||||
// Change average
|
// Change average
|
||||||
if(key == 1){
|
if(key == 1){
|
||||||
average ++;
|
average ++;
|
||||||
@@ -66,51 +79,41 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void printAvg(int avg, uint16_t x, uint16_t y, bool prefix) {
|
void printAvg(int avg, uint16_t x, uint16_t y, bool prefix) {
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(x, y);
|
epd->setCursor(x, y);
|
||||||
if (prefix) {
|
if (prefix) {
|
||||||
getdisplay().print("Avg: ");
|
epd->print("Avg: ");
|
||||||
}
|
}
|
||||||
switch (average) {
|
switch (average) {
|
||||||
case 0:
|
case 0:
|
||||||
getdisplay().print("1s");
|
epd->print("1s");
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
getdisplay().print("10s");
|
epd->print("10s");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
getdisplay().print("60s");
|
epd->print("60s");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
getdisplay().print("300s");
|
epd->print("300s");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
getdisplay().print("1s");
|
epd->print("1s");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void printVoltageSymbol(uint16_t x, uint16_t y, uint16_t color) {
|
void printVoltageSymbol(uint16_t x, uint16_t y, uint16_t color) {
|
||||||
getdisplay().setFont(&Ubuntu_Bold16pt8b);
|
epd->setFont(&Ubuntu_Bold16pt8b);
|
||||||
getdisplay().setCursor(x, y);
|
epd->setCursor(x, y);
|
||||||
getdisplay().print("V");
|
epd->print("V");
|
||||||
getdisplay().fillRect(x, y + 6, 22, 3, color);
|
epd->fillRect(x, y + 6, 22, 3, color);
|
||||||
getdisplay().fillRect(x, y + 11, 6, 3, color);
|
epd->fillRect(x, y + 11, 6, 3, color);
|
||||||
getdisplay().fillRect(x + 8, y + 11, 6, 3, color);
|
epd->fillRect(x + 8, y + 11, 6, 3, color);
|
||||||
getdisplay().fillRect(x + 16, y + 11, 6, 3, color);
|
epd->fillRect(x + 16, y + 11, 6, 3, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
int displayPage(PageData &pageData) {
|
int displayPage(PageData &pageData) {
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
// Get config data
|
|
||||||
bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String batVoltage = config->getString(config->batteryVoltage);
|
|
||||||
String batType = config->getString(config->batteryType);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
|
|
||||||
double value1 = 0;
|
double value1 = 0;
|
||||||
double valueTrend = 0; // Average over 10 values
|
double valueTrend = 0; // Average over 10 values
|
||||||
@@ -151,92 +154,76 @@ public:
|
|||||||
bool valid1 = true;
|
bool valid1 = true;
|
||||||
|
|
||||||
// Optical warning by limit violation
|
// Optical warning by limit violation
|
||||||
if(String(flashLED) == "Limit Violation"){
|
if (flashLED == "Limit Violation") {
|
||||||
// Limits for Pb battery
|
bool violation = false;
|
||||||
if(String(batType) == "Pb" && (raw < 11.8 || raw > 14.8)){
|
if (batType == "Pb") {
|
||||||
|
violation = (raw < 11.8 || raw > 14.8);
|
||||||
|
} else if (batType == "Gel") {
|
||||||
|
violation = (raw < 11.8 || raw > 14.4);
|
||||||
|
} else if (batType == "AGM") {
|
||||||
|
violation = (raw < 11.8 || raw > 14.7);
|
||||||
|
} else if (batType == "LiFePo4") {
|
||||||
|
violation = (raw < 12.0 || raw > 14.6);
|
||||||
|
}
|
||||||
|
if (violation) {
|
||||||
setBlinkingLED(true);
|
setBlinkingLED(true);
|
||||||
}
|
} else {
|
||||||
if(String(batType) == "Pb" && (raw >= 11.8 && raw <= 14.8)){
|
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
|
||||||
// Limits for Gel battery
|
|
||||||
if(String(batType) == "Gel" && (raw < 11.8 || raw > 14.4)){
|
|
||||||
setBlinkingLED(true);
|
|
||||||
}
|
|
||||||
if(String(batType) == "Gel" && (raw >= 11.8 && raw <= 14.4)){
|
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
|
||||||
// Limits for AGM battery
|
|
||||||
if(String(batType) == "AGM" && (raw < 11.8 || raw > 14.7)){
|
|
||||||
setBlinkingLED(true);
|
|
||||||
}
|
|
||||||
if(String(batType) == "AGM" && (raw >= 11.8 && raw <= 14.7)){
|
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
|
||||||
// Limits for LiFePo4 battery
|
|
||||||
if(String(batType) == "LiFePo4" && (raw < 12.0 || raw > 14.6)){
|
|
||||||
setBlinkingLED(true);
|
|
||||||
}
|
|
||||||
if(String(batType) == "LiFePo4" && (raw >= 12.0 && raw <= 14.6)){
|
|
||||||
setBlinkingLED(false);
|
setBlinkingLED(false);
|
||||||
setFlashLED(false);
|
setFlashLED(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logging voltage value
|
// Logging voltage value
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageVoltage, Type:%s %s:=%f", batType, name1.c_str(), raw);
|
logger->logDebug(GwLog::LOG, "Drawing at PageVoltage, Type:%s %s:=%f", batType, name1.c_str(), raw);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
if (mode == 'D') {
|
if (mode == 'D') {
|
||||||
// Display mode digital
|
// Display mode digital
|
||||||
|
|
||||||
// Show name
|
// Show name
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
getdisplay().setFont(&Ubuntu_Bold32pt8b);
|
epd->setFont(&Ubuntu_Bold32pt8b);
|
||||||
getdisplay().setCursor(20, 100);
|
epd->setCursor(20, 100);
|
||||||
getdisplay().print(name1); // Value name
|
epd->print(name1); // Value name
|
||||||
|
|
||||||
#if defined BOARD_OBP40S3 && defined LIPO_ACCU_1200 && defined VOLTAGE_SENSOR
|
#if defined BOARD_OBP40S3 && defined LIPO_ACCU_1200 && defined VOLTAGE_SENSOR
|
||||||
// Show charge status
|
// Show charge status
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(185, 100);
|
epd->setCursor(185, 100);
|
||||||
if(commonData->data.BatteryChargeStatus == true){
|
if(commonData->data.BatteryChargeStatus == true){
|
||||||
getdisplay().print("Charge");
|
epd->print("Charge");
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print("Discharge");
|
epd->print("Discharge");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Show unit
|
// Show unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(270, 100);
|
epd->setCursor(270, 100);
|
||||||
getdisplay().print("V");
|
epd->print("V");
|
||||||
|
|
||||||
// Show battery type
|
// Show battery type
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(295, 100);
|
epd->setCursor(295, 100);
|
||||||
#ifdef BOARD_OBP60S3
|
#ifdef BOARD_OBP60S3
|
||||||
getdisplay().print(batType);
|
epd->print(batType);
|
||||||
#endif
|
#endif
|
||||||
#if defined BOARD_OBP40S3 && defined LIPO_ACCU_1200 && defined VOLTAGE_SENSOR
|
#if defined BOARD_OBP40S3 && defined LIPO_ACCU_1200 && defined VOLTAGE_SENSOR
|
||||||
getdisplay().print("LiPo");
|
epd->print("LiPo");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Show average settings
|
// Show average settings
|
||||||
printAvg(average, 320, 84, true);
|
printAvg(average, 320, 84, true);
|
||||||
|
|
||||||
// Reading bus data or using simulation data
|
// Reading bus data or using simulation data
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic60pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic60pt7b);
|
||||||
getdisplay().setCursor(20, 240);
|
epd->setCursor(20, 240);
|
||||||
if(simulation == true){
|
if(simulation == true){
|
||||||
if(batVoltage == "12V"){
|
if(batVoltage == "12V"){
|
||||||
value1 = 12.0;
|
value1 = 12.0;
|
||||||
@@ -245,30 +232,30 @@ public:
|
|||||||
value1 = 24.0;
|
value1 = 24.0;
|
||||||
}
|
}
|
||||||
value1 += float(random(0, 5)) / 10; // Simulation data
|
value1 += float(random(0, 5)) / 10; // Simulation data
|
||||||
getdisplay().print(value1,1);
|
epd->print(value1,1);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// Check for valid real data, display also if hold values activated
|
// Check for valid real data, display also if hold values activated
|
||||||
if(valid1 == true || holdvalues == true){
|
if(valid1 == true || holdvalues == true){
|
||||||
// Resolution switching
|
// Resolution switching
|
||||||
if(value1 < 10){
|
if(value1 < 10){
|
||||||
getdisplay().print(value1,2);
|
epd->print(value1,2);
|
||||||
}
|
}
|
||||||
if(value1 >= 10 && value1 < 100){
|
if(value1 >= 10 && value1 < 100){
|
||||||
getdisplay().print(value1,1);
|
epd->print(value1,1);
|
||||||
}
|
}
|
||||||
if(value1 >= 100){
|
if(value1 >= 100){
|
||||||
getdisplay().print(value1,0);
|
epd->print(value1,0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print("---"); // Missing bus data
|
epd->print(commonData->fmt->placeholder); // Missing bus data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show trend indicator
|
// Show trend indicator
|
||||||
if(trend == true){
|
if(trend == true){
|
||||||
getdisplay().fillRect(315, 183, 35, 4, commonData->fgcolor); // Draw separator
|
epd->fillRect(315, 183, 35, 4, commonData->fgcolor); // Draw separator
|
||||||
if(int(raw * 10) > int(valueTrend * 10)){
|
if(int(raw * 10) > int(valueTrend * 10)){
|
||||||
displayTrendHigh(320, 174, 11, commonData->fgcolor); // Show high indicator
|
displayTrendHigh(320, 174, 11, commonData->fgcolor); // Show high indicator
|
||||||
}
|
}
|
||||||
@@ -289,9 +276,9 @@ public:
|
|||||||
std::vector<Point> pts;
|
std::vector<Point> pts;
|
||||||
|
|
||||||
// Instrument
|
// Instrument
|
||||||
getdisplay().drawCircleHelper(c.x, c.y, r + 2, 0x01, commonData->fgcolor);
|
epd->drawCircleHelper(c.x, c.y, r + 2, 0x01, commonData->fgcolor);
|
||||||
getdisplay().drawCircleHelper(c.x, c.y, r + 1, 0x01, commonData->fgcolor);
|
epd->drawCircleHelper(c.x, c.y, r + 1, 0x01, commonData->fgcolor);
|
||||||
getdisplay().drawCircleHelper(c.x, c.y, r , 0x01, commonData->fgcolor);
|
epd->drawCircleHelper(c.x, c.y, r , 0x01, commonData->fgcolor);
|
||||||
|
|
||||||
// Scale
|
// Scale
|
||||||
// angle to voltage scale mapping
|
// angle to voltage scale mapping
|
||||||
@@ -304,7 +291,7 @@ public:
|
|||||||
{c.x - r + 12, c.y + 1},
|
{c.x - r + 12, c.y + 1},
|
||||||
{c.x - r, c.y + 1}
|
{c.x - r, c.y + 1}
|
||||||
};
|
};
|
||||||
getdisplay().setFont(&Ubuntu_Bold10pt8b);
|
epd->setFont(&Ubuntu_Bold10pt8b);
|
||||||
for (int angle = 3; angle < 90; angle += 3) {
|
for (int angle = 3; angle < 90; angle += 3) {
|
||||||
if (angle % 15 == 0) {
|
if (angle % 15 == 0) {
|
||||||
fillPoly4(rotatePoints(c, pts, angle), commonData->fgcolor);
|
fillPoly4(rotatePoints(c, pts, angle), commonData->fgcolor);
|
||||||
@@ -314,7 +301,7 @@ public:
|
|||||||
else {
|
else {
|
||||||
p1 = rotatePoint(c, {c.x - r, c.y}, angle);
|
p1 = rotatePoint(c, {c.x - r, c.y}, angle);
|
||||||
p2 = rotatePoint(c, {c.x - r + 6, c.y}, angle);
|
p2 = rotatePoint(c, {c.x - r + 6, c.y}, angle);
|
||||||
getdisplay().drawLine(p1.x, p1.y, p2.x, p2.y, commonData->fgcolor);
|
epd->drawLine(p1.x, p1.y, p2.x, p2.y, commonData->fgcolor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,31 +341,31 @@ public:
|
|||||||
fillPoly4(rotatePoints(c, pts, angle), commonData->fgcolor);
|
fillPoly4(rotatePoints(c, pts, angle), commonData->fgcolor);
|
||||||
|
|
||||||
// base
|
// base
|
||||||
getdisplay().fillCircle(c.x, c.y, 7, commonData->fgcolor);
|
epd->fillCircle(c.x, c.y, 7, commonData->fgcolor);
|
||||||
getdisplay().fillCircle(c.x, c.y, 4, commonData->bgcolor);
|
epd->fillCircle(c.x, c.y, 4, commonData->bgcolor);
|
||||||
|
|
||||||
// Symbol
|
// Symbol
|
||||||
printVoltageSymbol(40, 60, commonData->fgcolor);
|
printVoltageSymbol(40, 60, commonData->fgcolor);
|
||||||
|
|
||||||
// Additional information at right side
|
// Additional information at right side
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(300, 60);
|
epd->setCursor(300, 60);
|
||||||
getdisplay().print("Source:");
|
epd->print("Source:");
|
||||||
getdisplay().setCursor(300, 80);
|
epd->setCursor(300, 80);
|
||||||
getdisplay().print(name1);
|
epd->print(name1);
|
||||||
|
|
||||||
getdisplay().setCursor(300, 110);
|
epd->setCursor(300, 110);
|
||||||
getdisplay().print("Type:");
|
epd->print("Type:");
|
||||||
getdisplay().setCursor(300, 130);
|
epd->setCursor(300, 130);
|
||||||
getdisplay().print(batType);
|
epd->print(batType);
|
||||||
|
|
||||||
getdisplay().setCursor(300, 160);
|
epd->setCursor(300, 160);
|
||||||
getdisplay().print("Avg:");
|
epd->print("Avg:");
|
||||||
printAvg(average, 300, 180, false);
|
printAvg(average, 300, 180, false);
|
||||||
|
|
||||||
// FRAM indicator
|
// FRAM indicator
|
||||||
if (hasFRAM) {
|
if (hasFRAM) {
|
||||||
getdisplay().drawXBitmap(300, 240, fram_bits, icon_width, icon_height, commonData->fgcolor);
|
epd->drawXBitmap(300, 240, fram_bits, icon_width, icon_height, commonData->fgcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
@@ -13,16 +14,17 @@
|
|||||||
|
|
||||||
class PageWhite : public Page
|
class PageWhite : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
char mode = 'W'; // display mode (W)hite | (L)ogo | (M)FD logo
|
char mode = 'W'; // display mode (W)hite | (L)ogo | (M)FD logo
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageWhite(CommonData &common){
|
PageWhite(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageWhite");
|
logger->logDebug(GwLog::LOG, "Instantiate PageWhite");
|
||||||
refreshtime = 15000;
|
refreshtime = 15000;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int handleKey(int key) {
|
int handleKey(int key) {
|
||||||
// Change display mode
|
// Change display mode
|
||||||
if (key == 1) {
|
if (key == 1) {
|
||||||
if (mode == 'W') {
|
if (mode == 'W') {
|
||||||
@@ -37,21 +39,20 @@ public:
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
int displayPage(PageData &pageData){
|
void displayNew(PageData &pageData) {
|
||||||
GwConfigHandler *config = commonData->config;
|
#ifdef BOARD_OBP60S3
|
||||||
GwLog *logger = commonData->logger;
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
// Get config data
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
|
||||||
if(String(flashLED) == "Limit Violation"){
|
|
||||||
setBlinkingLED(false);
|
setBlinkingLED(false);
|
||||||
setFlashLED(false);
|
setFlashLED(false);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int displayPage(PageData &pageData) {
|
||||||
|
|
||||||
// Logging boat values
|
// Logging boat values
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageWhite");
|
logger->logDebug(GwLog::LOG, "Drawing at PageWhite");
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
@@ -61,19 +62,19 @@ public:
|
|||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
if (mode == 'W') {
|
if (mode == 'W') {
|
||||||
getdisplay().setFullWindow();
|
epd->setFullWindow();
|
||||||
} else {
|
} else {
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == 'L') {
|
if (mode == 'L') {
|
||||||
getdisplay().drawXBitmap(0, 0, OBP_400x300_bits, OBP_400x300_width, OBP_400x300_height, commonData->fgcolor);
|
epd->drawXBitmap(0, 0, OBP_400x300_bits, OBP_400x300_width, OBP_400x300_height, commonData->fgcolor);
|
||||||
} else if (mode == 'M') {
|
} else if (mode == 'M') {
|
||||||
#ifdef BOARD_OBP60S3
|
#ifdef BOARD_OBP60S3
|
||||||
getdisplay().drawXBitmap(0, 0, OBP60_400x300_bits, OBP60_400x300_width, OBP60_400x300_height, commonData->fgcolor);
|
epd->drawXBitmap(0, 0, OBP60_400x300_bits, OBP60_400x300_width, OBP60_400x300_height, commonData->fgcolor);
|
||||||
#endif
|
#endif
|
||||||
#ifdef BOARD_OBP40S3
|
#ifdef BOARD_OBP40S3
|
||||||
getdisplay().drawXBitmap(0, 0, OBP40_400x300_bits, OBP40_400x300_width, OBP40_400x300_height, commonData->fgcolor);
|
epd->drawXBitmap(0, 0, OBP40_400x300_bits, OBP40_400x300_width, OBP40_400x300_height, commonData->fgcolor);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
#include "OBP60Extensions.h"
|
#include "OBP60Extensions.h"
|
||||||
#include "N2kMessages.h"
|
#include "N2kMessages.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
#include "BoatDataCalibration.h"
|
#include "BoatDataCalibration.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define front_width 120
|
#define front_width 120
|
||||||
#define front_height 162
|
#define front_height 162
|
||||||
@@ -214,15 +218,21 @@ static unsigned char front_bits[] PROGMEM = {
|
|||||||
|
|
||||||
class PageWind : public Page
|
class PageWind : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String lengthformat;
|
||||||
bool keylock = false; // Keylock
|
bool keylock = false; // Keylock
|
||||||
int8_t lp = 80; // Pointer length
|
int8_t lp = 80; // Pointer length
|
||||||
char mode = 'N'; // page mode (N)ormal | (L)ens | e(X)ample
|
char mode = 'N'; // page mode (N)ormal | (L)ens | e(X)ample
|
||||||
char source = 'A'; // data source (A)pparent | (T)rue
|
char source = 'A'; // data source (A)pparent | (T)rue
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageWind(CommonData &common){
|
PageWind(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageWind");
|
logger->logDebug(GwLog::LOG, "Instantiate PageWind");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
lengthformat = config->getString(config->lengthFormat);
|
||||||
|
|
||||||
if (hasFRAM) {
|
if (hasFRAM) {
|
||||||
lp = fram.read(FRAM_WIND_SIZE);
|
lp = fram.read(FRAM_WIND_SIZE);
|
||||||
source = fram.read(FRAM_WIND_SRC);
|
source = fram.read(FRAM_WIND_SRC);
|
||||||
@@ -230,7 +240,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupKeys(){
|
void setupKeys() {
|
||||||
Page::setupKeys();
|
Page::setupKeys();
|
||||||
commonData->keydata[0].label = "MODE";
|
commonData->keydata[0].label = "MODE";
|
||||||
if (mode == 'X') {
|
if (mode == 'X') {
|
||||||
@@ -242,7 +252,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Key functions
|
// Key functions
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key) {
|
||||||
|
|
||||||
if(key == 1){ // Mode switch
|
if(key == 1){ // Mode switch
|
||||||
if(mode == 'N'){
|
if(mode == 'N'){
|
||||||
@@ -296,23 +306,23 @@ public:
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
int displayPage(PageData &pageData)
|
void displayNew(PageData &pageData) {
|
||||||
{
|
#ifdef BOARD_OBP60S3
|
||||||
GwConfigHandler *config = commonData->config;
|
// Clear optical warning
|
||||||
GwLog *logger = commonData->logger;
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int displayPage(PageData &pageData) {
|
||||||
|
|
||||||
static String svalue1old = "";
|
static String svalue1old = "";
|
||||||
static String unit1old = "";
|
static String unit1old = "";
|
||||||
static String svalue2old = "";
|
static String svalue2old = "";
|
||||||
static String unit2old = "";
|
static String unit2old = "";
|
||||||
|
|
||||||
// Get config data
|
|
||||||
String lengthformat = config->getString(config->lengthFormat);
|
|
||||||
bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
|
|
||||||
GwApi::BoatValue *bvalue1; // Value 1 for speed on top
|
GwApi::BoatValue *bvalue1; // Value 1 for speed on top
|
||||||
GwApi::BoatValue *bvalue2; // Value 2 for angle on bottom
|
GwApi::BoatValue *bvalue2; // Value 2 for angle on bottom
|
||||||
|
|
||||||
@@ -324,11 +334,13 @@ public:
|
|||||||
}
|
}
|
||||||
String name1 = bvalue1->getName().c_str(); // Value name
|
String name1 = bvalue1->getName().c_str(); // Value name
|
||||||
name1 = name1.substring(0, 6); // String length limit for value name
|
name1 = name1.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value1 = bvalue1->value; // Value as double in SI unit
|
double value1 = bvalue1->value; // Value as double in SI unit
|
||||||
// bool valid1 = bvalue1->valid; // Valid information
|
// bool valid1 = bvalue1->valid; // Valid information
|
||||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue1 = commonData->fmt->formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
String unit1 = commonData->fmt->formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Get boat values for angle (AWD/TWD)
|
// Get boat values for angle (AWD/TWD)
|
||||||
if (source == 'A') {
|
if (source == 'A') {
|
||||||
@@ -338,74 +350,70 @@ public:
|
|||||||
}
|
}
|
||||||
String name2 = bvalue2->getName().c_str(); // Value name
|
String name2 = bvalue2->getName().c_str(); // Value name
|
||||||
name2 = name2.substring(0, 6); // String length limit for value name
|
name2 = name2.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value2 = bvalue2->value; // Value as double in SI unit
|
double value2 = bvalue2->value; // Value as double in SI unit
|
||||||
// bool valid2 = bvalue2->valid; // Valid information
|
// bool valid2 = bvalue2->valid; // Valid information
|
||||||
if (simulation) {
|
if (simulation) {
|
||||||
value2 = 0.62731; // some random value
|
value2 = 0.62731; // some random value
|
||||||
}
|
}
|
||||||
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue2 = commonData->fmt->formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
String unit2 = commonData->fmt->formatValue(bvalue2, *commonData).unit; // Unit of value
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
|
||||||
if(String(flashLED) == "Limit Violation"){
|
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logging boat values
|
// Logging boat values
|
||||||
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageWind, %s:%f, %s:%f", name1.c_str(), value1, name2.c_str(), value2);
|
logger->logDebug(GwLog::LOG, "Drawing at PageWind, %s:%f, %s:%f", name1.c_str(), value1, name2.c_str(), value2);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
|
|
||||||
if (mode == 'X') {
|
if (mode == 'X') {
|
||||||
// Original example code with scaling circle
|
// Original example code with scaling circle
|
||||||
|
|
||||||
// Show values AWS/TWS
|
// Show values AWS/TWS
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 50);
|
epd->setCursor(20, 50);
|
||||||
getdisplay().print(name1); // Value name
|
epd->print(name1); // Value name
|
||||||
getdisplay().print(": ");
|
epd->print(": ");
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue1); // Value
|
epd->print(svalue1); // Value
|
||||||
getdisplay().print(" ");
|
epd->print(" ");
|
||||||
getdisplay().print(unit1); // Unit
|
epd->print(unit1); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue1old); // Value old
|
epd->print(svalue1old); // Value old
|
||||||
getdisplay().print(" ");
|
epd->print(" ");
|
||||||
getdisplay().print(unit1old); // Unit old
|
epd->print(unit1old); // Unit old
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show values AWD/TWD
|
// Show values AWD/TWD
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(20, 260);
|
epd->setCursor(20, 260);
|
||||||
getdisplay().print(name2); // Value name
|
epd->print(name2); // Value name
|
||||||
getdisplay().print(": ");
|
epd->print(": ");
|
||||||
if(holdvalues == false){
|
if(holdvalues == false){
|
||||||
getdisplay().print(svalue2); // Value
|
epd->print(svalue2); // Value
|
||||||
getdisplay().print(" ");
|
epd->print(" ");
|
||||||
getdisplay().print(unit2); // Unit
|
epd->print(unit2); // Unit
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print(svalue2old); // Value old
|
epd->print(svalue2old); // Value old
|
||||||
getdisplay().print(" ");
|
epd->print(" ");
|
||||||
getdisplay().print(unit2old); // Unit old
|
epd->print(unit2old); // Unit old
|
||||||
}
|
}
|
||||||
|
|
||||||
Point c = {200, 145};
|
Point c = {200, 145};
|
||||||
|
|
||||||
// Draw instrument
|
// Draw instrument
|
||||||
getdisplay().fillCircle(c.x, c.y, lp + 5, commonData->fgcolor);
|
epd->fillCircle(c.x, c.y, lp + 5, commonData->fgcolor);
|
||||||
getdisplay().fillCircle(c.x, c.y, lp + 1, commonData->bgcolor);
|
epd->fillCircle(c.x, c.y, lp + 1, commonData->bgcolor);
|
||||||
|
|
||||||
// Wind pointer
|
// Wind pointer
|
||||||
if (bvalue2->valid or simulation) {
|
if (bvalue2->valid or simulation) {
|
||||||
@@ -420,7 +428,7 @@ public:
|
|||||||
};
|
};
|
||||||
fillPoly4(rotatePoints(c, pts, RadToDeg(value2)), commonData->fgcolor);
|
fillPoly4(rotatePoints(c, pts, RadToDeg(value2)), commonData->fgcolor);
|
||||||
} else {
|
} else {
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
drawTextCenter(c.x, c.y, "no data");
|
drawTextCenter(c.x, c.y, "no data");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,7 +446,7 @@ public:
|
|||||||
};
|
};
|
||||||
int angle;
|
int angle;
|
||||||
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
|
||||||
// starbord
|
// starbord
|
||||||
// text with line
|
// text with line
|
||||||
@@ -453,7 +461,7 @@ public:
|
|||||||
for (int i = 30; i < 138; i += 6) {
|
for (int i = 30; i < 138; i += 6) {
|
||||||
if (i % 15 != 0) {
|
if (i % 15 != 0) {
|
||||||
p = rotatePoint(c, {c.x, c.y - r + 5}, i);
|
p = rotatePoint(c, {c.x, c.y - r + 5}, i);
|
||||||
getdisplay().fillCircle(p.x, p.y, 2, commonData->fgcolor);
|
epd->fillCircle(p.x, p.y, 2, commonData->fgcolor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,17 +478,17 @@ public:
|
|||||||
for (int i = 228; i < 330; i += 6) {
|
for (int i = 228; i < 330; i += 6) {
|
||||||
if (i % 15 != 0) {
|
if (i % 15 != 0) {
|
||||||
p = rotatePoint(c, {c.x, c.y - r + 5}, i);
|
p = rotatePoint(c, {c.x, c.y - r + 5}, i);
|
||||||
getdisplay().fillCircle(p.x, p.y, 2, commonData->fgcolor);
|
epd->fillCircle(p.x, p.y, 2, commonData->fgcolor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// data source
|
// data source
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(8, 50);
|
epd->setCursor(8, 50);
|
||||||
if (source == 'A') {
|
if (source == 'A') {
|
||||||
getdisplay().print("APP");
|
epd->print("APP");
|
||||||
} else {
|
} else {
|
||||||
getdisplay().print("TRUE");
|
epd->print("TRUE");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wind pointer (angle)
|
// Wind pointer (angle)
|
||||||
@@ -500,7 +508,7 @@ public:
|
|||||||
alpha *= -1;
|
alpha *= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
getdisplay().fillCircle(c.x, c.y, 8, commonData->fgcolor);
|
epd->fillCircle(c.x, c.y, 8, commonData->fgcolor);
|
||||||
pts = {
|
pts = {
|
||||||
{c.x - 1, c.y - (r - 20)},
|
{c.x - 1, c.y - (r - 20)},
|
||||||
{c.x + 1, c.y - (r - 20)},
|
{c.x + 1, c.y - (r - 20)},
|
||||||
@@ -508,39 +516,39 @@ public:
|
|||||||
{c.x - 6, c.y + 15}
|
{c.x - 6, c.y + 15}
|
||||||
};
|
};
|
||||||
fillPoly4(rotatePoints(c, pts, alpha), commonData->fgcolor);
|
fillPoly4(rotatePoints(c, pts, alpha), commonData->fgcolor);
|
||||||
getdisplay().fillCircle(c.x, c.y, 6, commonData->bgcolor);
|
epd->fillCircle(c.x, c.y, 6, commonData->bgcolor);
|
||||||
} else {
|
} else {
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
drawTextCenter(c.x, c.y, "no data");
|
drawTextCenter(c.x, c.y, "no data");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wind speed as decimal number
|
// Wind speed as decimal number
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(150, 250);
|
epd->setCursor(150, 250);
|
||||||
if (holdvalues == false) {
|
if (holdvalues == false) {
|
||||||
getdisplay().print(svalue1);
|
epd->print(svalue1);
|
||||||
} else {
|
} else {
|
||||||
getdisplay().print(svalue1old);
|
epd->print(svalue1old);
|
||||||
}
|
}
|
||||||
// unit
|
// unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(220, 265);
|
epd->setCursor(220, 265);
|
||||||
getdisplay().print("kts");
|
epd->print("kts");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Normal mode
|
// Normal mode
|
||||||
|
|
||||||
// data source
|
// data source
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(8, 50);
|
epd->setCursor(8, 50);
|
||||||
if (source == 'A') {
|
if (source == 'A') {
|
||||||
getdisplay().print("APP");
|
epd->print("APP");
|
||||||
} else {
|
} else {
|
||||||
getdisplay().print("TRUE");
|
epd->print("TRUE");
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw ship front symbol (as bitmap)
|
// draw ship front symbol (as bitmap)
|
||||||
getdisplay().drawXBitmap(140, 30, front_bits, front_width, front_height, commonData->fgcolor);
|
epd->drawXBitmap(140, 30, front_bits, front_width, front_height, commonData->fgcolor);
|
||||||
|
|
||||||
Point c = {200, 155};
|
Point c = {200, 155};
|
||||||
uint16_t r = 150;
|
uint16_t r = 150;
|
||||||
@@ -565,7 +573,7 @@ public:
|
|||||||
for (int i = 30; i < 150; i += 10) {
|
for (int i = 30; i < 150; i += 10) {
|
||||||
if (i % 30 != 0) {
|
if (i % 30 != 0) {
|
||||||
p = rotatePoint(c, {c.x, c.y - r + 5}, i);
|
p = rotatePoint(c, {c.x, c.y - r + 5}, i);
|
||||||
getdisplay().fillCircle(p.x, p.y, 3, commonData->fgcolor);
|
epd->fillCircle(p.x, p.y, 3, commonData->fgcolor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -582,27 +590,27 @@ public:
|
|||||||
for (int i = 210; i < 340; i += 10) {
|
for (int i = 210; i < 340; i += 10) {
|
||||||
if (i % 30 != 0) {
|
if (i % 30 != 0) {
|
||||||
p = rotatePoint(c, {c.x, c.y - r + 5}, i);
|
p = rotatePoint(c, {c.x, c.y - r + 5}, i);
|
||||||
getdisplay().fillCircle(p.x, p.y, 3, commonData->fgcolor);
|
epd->fillCircle(p.x, p.y, 3, commonData->fgcolor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wind speed as decimal number
|
// Wind speed as decimal number
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(150, 250);
|
epd->setCursor(150, 250);
|
||||||
if (holdvalues == false) {
|
if (holdvalues == false) {
|
||||||
getdisplay().print(svalue1);
|
epd->print(svalue1);
|
||||||
} else {
|
} else {
|
||||||
getdisplay().print(svalue1old);
|
epd->print(svalue1old);
|
||||||
}
|
}
|
||||||
// unit
|
// unit
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(220, 265);
|
epd->setCursor(220, 265);
|
||||||
getdisplay().print("kts");
|
epd->print("kts");
|
||||||
|
|
||||||
// Wind pointer (angle)
|
// Wind pointer (angle)
|
||||||
if (bvalue2->valid or simulation) {
|
if (bvalue2->valid or simulation) {
|
||||||
float alpha = RadToDeg(value2);
|
float alpha = RadToDeg(value2);
|
||||||
getdisplay().fillCircle(c.x, c.y, 8, commonData->fgcolor);
|
epd->fillCircle(c.x, c.y, 8, commonData->fgcolor);
|
||||||
pts = {
|
pts = {
|
||||||
{c.x - 1, c.y - (r - 20)},
|
{c.x - 1, c.y - (r - 20)},
|
||||||
{c.x + 1, c.y - (r - 20)},
|
{c.x + 1, c.y - (r - 20)},
|
||||||
@@ -610,9 +618,9 @@ public:
|
|||||||
{c.x - 6, c.y + 15}
|
{c.x - 6, c.y + 15}
|
||||||
};
|
};
|
||||||
fillPoly4(rotatePoints(c, pts, alpha), commonData->fgcolor);
|
fillPoly4(rotatePoints(c, pts, alpha), commonData->fgcolor);
|
||||||
getdisplay().fillCircle(c.x, c.y, 6, commonData->bgcolor);
|
epd->fillCircle(c.x, c.y, 6, commonData->bgcolor);
|
||||||
} else {
|
} else {
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
drawTextCenter(c.x, c.y, "no data");
|
drawTextCenter(c.x, c.y, "no data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,53 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "BoatDataCalibration.h"
|
#include "Pagedata.h"
|
||||||
#include "OBP60Extensions.h"
|
#include "OBP60Extensions.h"
|
||||||
#include "OBPRingBuffer.h"
|
#include "OBPRingBuffer.h"
|
||||||
#include "Pagedata.h"
|
#include "OBPDataOperations.h"
|
||||||
|
#include "BoatDataCalibration.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
static const double radToDeg = 180.0 / M_PI; // Conversion factor from radians to degrees
|
static const double radToDeg = 180.0 / M_PI; // Conversion factor from radians to degrees
|
||||||
|
|
||||||
|
// Get maximum difference of last <amount> of TWD ringbuffer values to center chart; returns "0" if data is not valid
|
||||||
|
int getCntr(const RingBuffer<int16_t>& windDirHstry, size_t amount)
|
||||||
|
{
|
||||||
|
const int MAX_VAL = windDirHstry.getMaxVal();
|
||||||
|
size_t count = windDirHstry.getCurrentSize();
|
||||||
|
|
||||||
|
if (windDirHstry.isEmpty() || amount <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (amount > count)
|
||||||
|
amount = count;
|
||||||
|
|
||||||
|
uint16_t midWndDir, minWndDir, maxWndDir = 0;
|
||||||
|
int wndCenter = 0;
|
||||||
|
|
||||||
|
midWndDir = windDirHstry.getMid(amount);
|
||||||
|
if (midWndDir != MAX_VAL) {
|
||||||
|
midWndDir = midWndDir / 1000.0 * radToDeg;
|
||||||
|
wndCenter = int((midWndDir + (midWndDir >= 0 ? 5 : -5)) / 10) * 10; // Set new center value; round to nearest 10 degree value
|
||||||
|
minWndDir = windDirHstry.getMin(amount) / 1000.0 * radToDeg;
|
||||||
|
maxWndDir = windDirHstry.getMax(amount) / 1000.0 * radToDeg;
|
||||||
|
if ((maxWndDir - minWndDir) > 180 && !(minWndDir > maxWndDir)) { // if wind range is > 180 and no 0° crossover, adjust wndCenter to smaller wind range end
|
||||||
|
wndCenter = WindUtils::to360(wndCenter + 180);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wndCenter;
|
||||||
|
}
|
||||||
|
|
||||||
// Get maximum difference of last <amount> of TWD ringbuffer values to center chart
|
// Get maximum difference of last <amount> of TWD ringbuffer values to center chart
|
||||||
int getRng(const RingBuffer<int16_t>& windDirHstry, int center, size_t amount)
|
int getRng(const RingBuffer<int16_t>& windDirHstry, int center, size_t amount)
|
||||||
{
|
{
|
||||||
int minVal = windDirHstry.getMinVal();
|
int minVal = windDirHstry.getMinVal();
|
||||||
|
const int MAX_VAL = windDirHstry.getMaxVal();
|
||||||
size_t count = windDirHstry.getCurrentSize();
|
size_t count = windDirHstry.getCurrentSize();
|
||||||
// size_t capacity = windDirHstry.getCapacity();
|
|
||||||
// size_t last = windDirHstry.getLastIdx();
|
|
||||||
|
|
||||||
if (windDirHstry.isEmpty() || amount <= 0) {
|
if (windDirHstry.isEmpty() || amount <= 0) {
|
||||||
return minVal;
|
return MAX_VAL;
|
||||||
}
|
}
|
||||||
if (amount > count)
|
if (amount > count)
|
||||||
amount = count;
|
amount = count;
|
||||||
@@ -27,11 +57,10 @@ int getRng(const RingBuffer<int16_t>& windDirHstry, int center, size_t amount)
|
|||||||
int maxRng = minVal;
|
int maxRng = minVal;
|
||||||
// Start from the newest value (last) and go backwards x times
|
// Start from the newest value (last) and go backwards x times
|
||||||
for (size_t i = 0; i < amount; i++) {
|
for (size_t i = 0; i < amount; i++) {
|
||||||
// value = windDirHstry.get(((last - i) % capacity + capacity) % capacity);
|
|
||||||
value = windDirHstry.get(count - 1 - i);
|
value = windDirHstry.get(count - 1 - i);
|
||||||
|
|
||||||
if (value == minVal) {
|
if (value == MAX_VAL) {
|
||||||
continue;
|
continue; // ignore invalid values
|
||||||
}
|
}
|
||||||
|
|
||||||
value = value / 1000.0 * radToDeg;
|
value = value / 1000.0 * radToDeg;
|
||||||
@@ -43,36 +72,39 @@ int getRng(const RingBuffer<int16_t>& windDirHstry, int center, size_t amount)
|
|||||||
maxRng = 180;
|
maxRng = 180;
|
||||||
}
|
}
|
||||||
|
|
||||||
return maxRng;
|
return (maxRng != minVal ? maxRng : MAX_VAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ****************************************************************
|
// ****************************************************************
|
||||||
class PageWindPlot : public Page {
|
class PageWindPlot : public Page {
|
||||||
|
private:
|
||||||
bool keylock = false; // Keylock
|
bool keylock = false; // Keylock
|
||||||
char chrtMode = 'D'; // Chart mode: 'D' for TWD, 'S' for TWS, 'B' for both
|
char chrtMode = 'D'; // Chart mode: 'D' for TWD, 'S' for TWS, 'B' for both
|
||||||
|
bool showTruW = true; // Show true wind or apparant wind in chart area
|
||||||
|
bool oldShowTruW = false; // remember recent user selection of wind data type
|
||||||
|
|
||||||
int dataIntv = 1; // Update interval for wind history chart:
|
int dataIntv = 1; // Update interval for wind history chart:
|
||||||
// (1)|(2)|(3)|(4) seconds for approx. 4, 8, 12, 16 min. history chart
|
// (1)|(2)|(3)|(4) seconds for approx. 4, 8, 12, 16 min. history chart
|
||||||
bool showTWS = true; // Show TWS value in chart area
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageWindPlot(CommonData& common)
|
PageWindPlot(CommonData& common) : Page(common)
|
||||||
{
|
{
|
||||||
commonData = &common;
|
logger->logDebug(GwLog::LOG, "Instantiate PageWindPlot");
|
||||||
common.logger->logDebug(GwLog::LOG, "Instantiate PageWindPlot");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupKeys()
|
void setupKeys() {
|
||||||
{
|
|
||||||
Page::setupKeys();
|
Page::setupKeys();
|
||||||
// commonData->keydata[0].label = "MODE";
|
// commonData->keydata[0].label = "MODE";
|
||||||
|
#if defined BOARD_OBP60S3
|
||||||
|
commonData->keydata[1].label = "SRC";
|
||||||
|
commonData->keydata[4].label = "INTV";
|
||||||
|
#elif defined BOARD_OBP40S3
|
||||||
commonData->keydata[1].label = "INTV";
|
commonData->keydata[1].label = "INTV";
|
||||||
commonData->keydata[4].label = "TWS";
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Key functions
|
// Key functions
|
||||||
virtual int handleKey(int key)
|
int handleKey(int key) {
|
||||||
{
|
|
||||||
// Set chart mode TWD | TWS -> to be implemented
|
// Set chart mode TWD | TWS -> to be implemented
|
||||||
if (key == 1) {
|
if (key == 1) {
|
||||||
if (chrtMode == 'D') {
|
if (chrtMode == 'D') {
|
||||||
@@ -85,8 +117,18 @@ public:
|
|||||||
return 0; // Commit the key
|
return 0; // Commit the key
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set interval for wind history chart update time
|
#if defined BOARD_OBP60S3
|
||||||
|
// Set data source TRUE | APP
|
||||||
if (key == 2) {
|
if (key == 2) {
|
||||||
|
showTruW = !showTruW;
|
||||||
|
return 0; // Commit the key
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set interval for wind history chart update time (interval)
|
||||||
|
if (key == 5) {
|
||||||
|
#elif defined BOARD_OBP40S3
|
||||||
|
if (key == 2) {
|
||||||
|
#endif
|
||||||
if (dataIntv == 1) {
|
if (dataIntv == 1) {
|
||||||
dataIntv = 2;
|
dataIntv = 2;
|
||||||
} else if (dataIntv == 2) {
|
} else if (dataIntv == 2) {
|
||||||
@@ -99,12 +141,6 @@ public:
|
|||||||
return 0; // Commit the key
|
return 0; // Commit the key
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch TWS on/off
|
|
||||||
if (key == 5) {
|
|
||||||
showTWS = !showTWS;
|
|
||||||
return 0; // Commit the key
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keylock function
|
// Keylock function
|
||||||
if (key == 11) { // Code for keylock
|
if (key == 11) { // Code for keylock
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -113,32 +149,47 @@ public:
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
int displayPage(PageData& pageData)
|
void displayNew(PageData &pageData) {
|
||||||
{
|
#ifdef BOARD_OBP60S3
|
||||||
GwConfigHandler* config = commonData->config;
|
// Clear optical warning
|
||||||
GwLog* logger = commonData->logger;
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
String wndSrc; // Wind source true/apparant wind - preselection for OBP40
|
||||||
|
|
||||||
float twsValue; // TWS value in chart area
|
wndSrc = commonData->config->getString("page" + String(pageData.pageNumber) + "wndsrc");
|
||||||
static String twdName, twdUnit; // TWD name and unit
|
if (wndSrc =="True wind") {
|
||||||
static int updFreq; // Update frequency for TWD
|
showTruW = true;
|
||||||
static int16_t twdLowest, twdHighest; // TWD range
|
} else {
|
||||||
// static int16_t twdBufMinVal; // lowest possible twd buffer value; used for non-set data
|
showTruW = false; // Wind source is apparant wind
|
||||||
|
}
|
||||||
|
commonData->logger->logDebug(GwLog::LOG,"New PageWindPlot: wind source=%s", wndSrc);
|
||||||
|
#endif
|
||||||
|
oldShowTruW = !showTruW; // makes wind source being initialized at initial page call
|
||||||
|
}
|
||||||
|
|
||||||
// current boat data values; TWD only for validation test, TWS for display of current value
|
int displayPage(PageData& pageData) {
|
||||||
|
|
||||||
|
static RingBuffer<int16_t>* wdHstry; // Wind direction data buffer
|
||||||
|
static RingBuffer<uint16_t>* wsHstry; // Wind speed data buffer
|
||||||
|
static String wdName, wdFormat; // Wind direction name and format
|
||||||
|
static String wsName, wsFormat; // Wind speed name and format
|
||||||
|
static int16_t wdMAX_VAL; // Max. value of wd history buffer, indicating invalid values
|
||||||
|
float wsValue; // Wind speed value in chart area
|
||||||
|
String wsUnit; // Wind speed unit in chart area
|
||||||
|
static GwApi::BoatValue* wsBVal = new GwApi::BoatValue("TWS"); // temp BoatValue for wind speed unit identification; required by OBP60Formater
|
||||||
|
|
||||||
|
// current boat data values; TWD/AWD only for validation test
|
||||||
const int numBoatData = 2;
|
const int numBoatData = 2;
|
||||||
GwApi::BoatValue* bvalue;
|
GwApi::BoatValue* bvalue;
|
||||||
String BDataName[numBoatData];
|
|
||||||
double BDataValue[numBoatData];
|
|
||||||
bool BDataValid[numBoatData];
|
bool BDataValid[numBoatData];
|
||||||
String BDataText[numBoatData];
|
|
||||||
String BDataUnit[numBoatData];
|
|
||||||
String BDataFormat[numBoatData];
|
|
||||||
|
|
||||||
static bool isInitialized = false; // Flag to indicate that page is initialized
|
static bool isInitialized = false; // Flag to indicate that page is initialized
|
||||||
static bool wndDataValid = false; // Flag to indicate if wind data is valid
|
static bool wndDataValid = false; // Flag to indicate if wind data is valid
|
||||||
static int numNoData; // Counter for multiple invalid data values in a row
|
static int numNoData; // Counter for multiple invalid data values in a row
|
||||||
static bool simulation = false;
|
|
||||||
static bool holdValues = false;
|
|
||||||
|
|
||||||
static int width; // Screen width
|
static int width; // Screen width
|
||||||
static int height; // Screen height
|
static int height; // Screen height
|
||||||
@@ -161,10 +212,8 @@ public:
|
|||||||
static int wndRight; // chart wind right value position
|
static int wndRight; // chart wind right value position
|
||||||
static int chrtRng; // Range of wind values from mid wind value to min/max wind value in degrees
|
static int chrtRng; // Range of wind values from mid wind value to min/max wind value in degrees
|
||||||
int diffRng; // Difference between mid and current wind value
|
int diffRng; // Difference between mid and current wind value
|
||||||
static const int dfltRng = 40; // Default range for chart
|
static const int dfltRng = 60; // Default range for chart
|
||||||
int midWndDir; // New value for wndCenter after chart start / shift
|
int midWndDir; // New value for wndCenter after chart start / shift
|
||||||
static int simTwd; // Simulation value for TWD
|
|
||||||
static float simTws; // Simulation value for TWS
|
|
||||||
|
|
||||||
int x, y; // x and y coordinates for drawing
|
int x, y; // x and y coordinates for drawing
|
||||||
static int prevX, prevY; // Last x and y coordinates for drawing
|
static int prevX, prevY; // Last x and y coordinates for drawing
|
||||||
@@ -172,30 +221,20 @@ public:
|
|||||||
int chrtVal; // Current wind value
|
int chrtVal; // Current wind value
|
||||||
static int chrtPrevVal; // Last wind value in chart area for check if value crosses 180 degree line
|
static int chrtPrevVal; // Last wind value in chart area for check if value crosses 180 degree line
|
||||||
|
|
||||||
LOG_DEBUG(GwLog::LOG, "Display page WindPlot");
|
logger->logDebug(GwLog::LOG, "Display PageWindPlot");
|
||||||
|
ulong timer = millis();
|
||||||
// Get config data
|
|
||||||
simulation = config->getBool(config->useSimuData);
|
|
||||||
holdValues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
|
|
||||||
if (!isInitialized) {
|
if (!isInitialized) {
|
||||||
width = getdisplay().width();
|
width = epd->width();
|
||||||
height = getdisplay().height();
|
height = epd->height();
|
||||||
xCenter = width / 2;
|
xCenter = width / 2;
|
||||||
cHeight = height - yOffset - 22;
|
cHeight = height - yOffset - 22;
|
||||||
bufSize = pageData.boatHstry.twdHstry->getCapacity();
|
|
||||||
numNoData = 0;
|
numNoData = 0;
|
||||||
simTwd = pageData.boatHstry.twdHstry->getLast() / 1000.0 * radToDeg;
|
|
||||||
simTws = 0;
|
|
||||||
twsValue = 0;
|
|
||||||
bufStart = 0;
|
bufStart = 0;
|
||||||
oldDataIntv = 0;
|
oldDataIntv = 0;
|
||||||
|
wsValue = 0;
|
||||||
numAddedBufVals, currIdx, lastIdx = 0;
|
numAddedBufVals, currIdx, lastIdx = 0;
|
||||||
lastAddedIdx = pageData.boatHstry.twdHstry->getLastIdx();
|
wndCenter = INT_MAX;
|
||||||
pageData.boatHstry.twdHstry->getMetaData(twdName, twdUnit, updFreq, twdLowest, twdHighest);
|
|
||||||
wndCenter = INT_MIN;
|
|
||||||
midWndDir = 0;
|
midWndDir = 0;
|
||||||
diffRng = dfltRng;
|
diffRng = dfltRng;
|
||||||
chrtRng = dfltRng;
|
chrtRng = dfltRng;
|
||||||
@@ -206,14 +245,7 @@ public:
|
|||||||
// read boat data values; TWD only for validation test, TWS for display of current value
|
// read boat data values; TWD only for validation test, TWS for display of current value
|
||||||
for (int i = 0; i < numBoatData; i++) {
|
for (int i = 0; i < numBoatData; i++) {
|
||||||
bvalue = pageData.values[i];
|
bvalue = pageData.values[i];
|
||||||
BDataName[i] = xdrDelete(bvalue->getName());
|
|
||||||
BDataName[i] = BDataName[i].substring(0, 6); // String length limit for value name
|
|
||||||
calibrationData.calibrateInstance(bvalue, logger); // Check if boat data value is to be calibrated
|
|
||||||
BDataValue[i] = bvalue->value; // Value as double in SI unit
|
|
||||||
BDataValid[i] = bvalue->valid;
|
BDataValid[i] = bvalue->valid;
|
||||||
BDataText[i] = formatValue(bvalue, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
|
||||||
BDataUnit[i] = formatValue(bvalue, *commonData).unit;
|
|
||||||
BDataFormat[i] = bvalue->getFormat(); // Unit of value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
// Optical warning by limit violation (unused)
|
||||||
@@ -222,9 +254,27 @@ public:
|
|||||||
setFlashLED(false);
|
setFlashLED(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (showTruW != oldShowTruW) {
|
||||||
|
if (showTruW) {
|
||||||
|
wdHstry = pageData.boatHstry->hstryBufList.twdHstry;
|
||||||
|
wsHstry = pageData.boatHstry->hstryBufList.twsHstry;
|
||||||
|
} else {
|
||||||
|
wdHstry = pageData.boatHstry->hstryBufList.awdHstry;
|
||||||
|
wsHstry = pageData.boatHstry->hstryBufList.awsHstry;
|
||||||
|
}
|
||||||
|
wdHstry->getMetaData(wdName, wdFormat);
|
||||||
|
wsHstry->getMetaData(wsName, wsFormat);
|
||||||
|
wdMAX_VAL = wdHstry->getMaxVal();
|
||||||
|
bufSize = wdHstry->getCapacity();
|
||||||
|
wsBVal->setFormat(wsHstry->getFormat());
|
||||||
|
lastAddedIdx = wdHstry->getLastIdx();
|
||||||
|
|
||||||
|
oldShowTruW = showTruW;
|
||||||
|
}
|
||||||
|
|
||||||
// Identify buffer size and buffer start position for chart
|
// Identify buffer size and buffer start position for chart
|
||||||
count = pageData.boatHstry.twdHstry->getCurrentSize();
|
count = wdHstry->getCurrentSize();
|
||||||
currIdx = pageData.boatHstry.twdHstry->getLastIdx();
|
currIdx = wdHstry->getLastIdx();
|
||||||
numAddedBufVals = (currIdx - lastAddedIdx + bufSize) % bufSize; // Number of values added to buffer since last display
|
numAddedBufVals = (currIdx - lastAddedIdx + bufSize) % bufSize; // Number of values added to buffer since last display
|
||||||
if (dataIntv != oldDataIntv || count == 1) {
|
if (dataIntv != oldDataIntv || count == 1) {
|
||||||
// new data interval selected by user
|
// new data interval selected by user
|
||||||
@@ -240,29 +290,25 @@ public:
|
|||||||
bufStart = max(0, bufStart - numAddedBufVals);
|
bufStart = max(0, bufStart - numAddedBufVals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Dataset: count: %d, TWD: %.0f, TWS: %.1f, TWD_valid? %d, intvBufSize: %d, numWndVals: %d, bufStart: %d, numAddedBufVals: %d, lastIdx: %d, old: %d, act: %d",
|
logger->logDebug(GwLog::DEBUG, "PageWindPlot Dataset: count: %d, xWD: %.1f, xWS: %.2f, xWD_valid? %d, intvBufSize: %d, numWndVals: %d, bufStart: %d, numAddedBufVals: %d, lastIdx: %d, wind source: %s",
|
||||||
count, pageData.boatHstry.twdHstry->getLast() / 1000.0 * radToDeg, pageData.boatHstry.twsHstry->getLast() / 10.0 * 1.94384, BDataValid[0],
|
count, wdHstry->getLast() / 1000.0 * radToDeg, wsHstry->getLast() / 1000.0 * 1.94384, BDataValid[0], intvBufSize, numWndVals, bufStart, numAddedBufVals, wdHstry->getLastIdx(),
|
||||||
intvBufSize, numWndVals, bufStart, numAddedBufVals, pageData.boatHstry.twdHstry->getLastIdx(), oldDataIntv, dataIntv);
|
showTruW ? "True" : "App");
|
||||||
|
|
||||||
// Set wndCenter from 1st real buffer value
|
// Set wndCenter from 1st real buffer value
|
||||||
if (wndCenter == INT_MIN || (wndCenter == 0 && count == 1)) {
|
if (wndCenter == INT_MAX || (wndCenter == 0 && count == 1)) {
|
||||||
midWndDir = pageData.boatHstry.twdHstry->getMid(numWndVals);
|
wndCenter = getCntr(*wdHstry, numWndVals);
|
||||||
if (midWndDir != INT16_MIN) {
|
logger->logDebug(GwLog::DEBUG, "PageWindPlot Range Init: count: %d, xWD: %.1f, wndCenter: %d, diffRng: %d, chrtRng: %d, Min: %.0f, Max: %.0f", count, wdHstry->getLast() / 1000.0 * radToDeg,
|
||||||
midWndDir = midWndDir / 1000.0 * radToDeg;
|
wndCenter, diffRng, chrtRng, wdHstry->getMin(numWndVals) / 1000.0 * radToDeg, wdHstry->getMax(numWndVals) / 1000.0 * radToDeg);
|
||||||
wndCenter = int((midWndDir + (midWndDir >= 0 ? 5 : -5)) / 10) * 10; // Set new center value; round to nearest 10 degree value
|
|
||||||
} else {
|
|
||||||
wndCenter = 0;
|
|
||||||
}
|
|
||||||
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Range Init: count: %d, TWD: %.0f, wndCenter: %d, diffRng: %d, chrtRng: %d", count, pageData.boatHstry.twdHstry->getLast() / 1000.0 * radToDeg,
|
|
||||||
wndCenter, diffRng, chrtRng);
|
|
||||||
} else {
|
} else {
|
||||||
// check and adjust range between left, center, and right chart limit
|
// check and adjust range between left, center, and right chart limit
|
||||||
diffRng = getRng(*pageData.boatHstry.twdHstry, wndCenter, numWndVals);
|
diffRng = getRng(*wdHstry, wndCenter, numWndVals);
|
||||||
diffRng = (diffRng == INT16_MIN ? 0 : diffRng);
|
diffRng = (diffRng == wdMAX_VAL ? 0 : diffRng);
|
||||||
if (diffRng > chrtRng) {
|
if (diffRng > chrtRng) {
|
||||||
chrtRng = int((diffRng + (diffRng >= 0 ? 9 : -1)) / 10) * 10; // Round up to next 10 degree value
|
chrtRng = int((diffRng + (diffRng >= 0 ? 9 : -1)) / 10) * 10; // Round up to next 10 degree value
|
||||||
} else if (diffRng + 10 < chrtRng) { // Reduce chart range for higher resolution if possible
|
} else if (diffRng + 10 < chrtRng) { // Reduce chart range for higher resolution if possible
|
||||||
chrtRng = max(dfltRng, int((diffRng + (diffRng >= 0 ? 9 : -1)) / 10) * 10);
|
chrtRng = max(dfltRng, int((diffRng + (diffRng >= 0 ? 9 : -1)) / 10) * 10);
|
||||||
|
logger->logDebug(GwLog::DEBUG, "PageWindPlot Range adjust: wndCenter: %d, diffRng: %d, chrtRng: %d, Min: %.0f, Max: %.0f", wndCenter, diffRng, chrtRng,
|
||||||
|
wdHstry->getMin(numWndVals) / 1000.0 * radToDeg, wdHstry->getMax(numWndVals) / 1000.0 * radToDeg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chrtScl = float(width) / float(chrtRng) / 2.0; // Chart scale: pixels per degree
|
chrtScl = float(width) / float(chrtRng) / 2.0; // Chart scale: pixels per degree
|
||||||
@@ -277,38 +323,38 @@ public:
|
|||||||
//***********************************************************************
|
//***********************************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, width, height); // Set partial update
|
epd->setPartialWindow(0, 0, width, height); // Set partial update
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
// chart lines
|
// chart lines
|
||||||
getdisplay().fillRect(0, yOffset, width, 2, commonData->fgcolor);
|
epd->fillRect(0, yOffset, width, 2, commonData->fgcolor);
|
||||||
getdisplay().fillRect(xCenter, yOffset, 1, cHeight, commonData->fgcolor);
|
epd->fillRect(xCenter, yOffset, 1, cHeight, commonData->fgcolor);
|
||||||
|
|
||||||
// chart labels
|
// chart labels
|
||||||
char sWndLbl[4]; // char buffer for Wind angle label
|
char sWndLbl[4]; // char buffer for Wind angle label
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(xCenter - 88, yOffset - 3);
|
epd->setCursor(xCenter - 88, yOffset - 3);
|
||||||
getdisplay().print("TWD"); // Wind data name
|
epd->print(wdName); // Wind data name
|
||||||
snprintf(sWndLbl, 4, "%03d", (wndCenter < 0) ? (wndCenter + 360) : wndCenter);
|
snprintf(sWndLbl, 4, "%03d", (wndCenter < 0) ? (wndCenter + 360) : wndCenter);
|
||||||
drawTextCenter(xCenter, yOffset - 11, sWndLbl);
|
drawTextCenter(xCenter, yOffset - 11, sWndLbl);
|
||||||
getdisplay().drawCircle(xCenter + 25, yOffset - 17, 2, commonData->fgcolor); // <degree> symbol
|
epd->drawCircle(xCenter + 25, yOffset - 17, 2, commonData->fgcolor); // <degree> symbol
|
||||||
getdisplay().drawCircle(xCenter + 25, yOffset - 17, 3, commonData->fgcolor); // <degree> symbol
|
epd->drawCircle(xCenter + 25, yOffset - 17, 3, commonData->fgcolor); // <degree> symbol
|
||||||
getdisplay().setCursor(1, yOffset - 3);
|
epd->setCursor(1, yOffset - 3);
|
||||||
snprintf(sWndLbl, 4, "%03d", (wndLeft < 0) ? (wndLeft + 360) : wndLeft);
|
snprintf(sWndLbl, 4, "%03d", (wndLeft < 0) ? (wndLeft + 360) : wndLeft);
|
||||||
getdisplay().print(sWndLbl); // Wind left value
|
epd->print(sWndLbl); // Wind left value
|
||||||
getdisplay().drawCircle(46, yOffset - 17, 2, commonData->fgcolor); // <degree> symbol
|
epd->drawCircle(46, yOffset - 17, 2, commonData->fgcolor); // <degree> symbol
|
||||||
getdisplay().drawCircle(46, yOffset - 17, 3, commonData->fgcolor); // <degree> symbol
|
epd->drawCircle(46, yOffset - 17, 3, commonData->fgcolor); // <degree> symbol
|
||||||
getdisplay().setCursor(width - 50, yOffset - 3);
|
epd->setCursor(width - 50, yOffset - 3);
|
||||||
snprintf(sWndLbl, 4, "%03d", (wndRight < 0) ? (wndRight + 360) : wndRight);
|
snprintf(sWndLbl, 4, "%03d", (wndRight < 0) ? (wndRight + 360) : wndRight);
|
||||||
getdisplay().print(sWndLbl); // Wind right value
|
epd->print(sWndLbl); // Wind right value
|
||||||
getdisplay().drawCircle(width - 5, yOffset - 17, 2, commonData->fgcolor); // <degree> symbol
|
epd->drawCircle(width - 5, yOffset - 17, 2, commonData->fgcolor); // <degree> symbol
|
||||||
getdisplay().drawCircle(width - 5, yOffset - 17, 3, commonData->fgcolor); // <degree> symbol
|
epd->drawCircle(width - 5, yOffset - 17, 3, commonData->fgcolor); // <degree> symbol
|
||||||
|
|
||||||
if (pageData.boatHstry.twdHstry->getMax() == pageData.boatHstry.twdHstry->getMinVal()) {
|
if (wdHstry->getMax() == wdMAX_VAL) {
|
||||||
// only <INT16_MIN> values in buffer -> no valid wind data available
|
// only <MAX_VAL> values in buffer -> no valid wind data available
|
||||||
wndDataValid = false;
|
wndDataValid = false;
|
||||||
} else if (!BDataValid[0]) {
|
} else if (!BDataValid[0] && !simulation) {
|
||||||
// currently no valid TWD data available
|
// currently no valid xWD data available and no simulation mode
|
||||||
numNoData++;
|
numNoData++;
|
||||||
wndDataValid = true;
|
wndDataValid = true;
|
||||||
if (numNoData > 3) {
|
if (numNoData > 3) {
|
||||||
@@ -323,19 +369,18 @@ public:
|
|||||||
//***********************************************************************
|
//***********************************************************************
|
||||||
if (wndDataValid) {
|
if (wndDataValid) {
|
||||||
for (int i = 0; i < (numWndVals / dataIntv); i++) {
|
for (int i = 0; i < (numWndVals / dataIntv); i++) {
|
||||||
chrtVal = static_cast<int>(pageData.boatHstry.twdHstry->get(bufStart + (i * dataIntv))); // show the latest wind values in buffer; keep 1st value constant in a rolling buffer
|
chrtVal = static_cast<int>(wdHstry->get(bufStart + (i * dataIntv))); // show the latest wind values in buffer; keep 1st value constant in a rolling buffer
|
||||||
if (chrtVal == INT16_MIN) {
|
if (chrtVal == wdMAX_VAL) {
|
||||||
chrtPrevVal = INT16_MIN;
|
chrtPrevVal = wdMAX_VAL;
|
||||||
} else {
|
} else {
|
||||||
chrtVal = static_cast<int>((chrtVal / 1000.0 * radToDeg) + 0.5); // Convert to degrees and round
|
chrtVal = static_cast<int>((chrtVal / 1000.0 * radToDeg) + 0.5); // Convert to degrees and round
|
||||||
x = ((chrtVal - wndLeft + 360) % 360) * chrtScl;
|
x = ((chrtVal - wndLeft + 360) % 360) * chrtScl;
|
||||||
y = yOffset + cHeight - i; // Position in chart area
|
y = yOffset + cHeight - i; // Position in chart area
|
||||||
|
|
||||||
// if (i >= (numWndVals / dataIntv) - 10)
|
if (i >= (numWndVals / dataIntv) - 1) // log chart data of 1 line (adjust for test purposes)
|
||||||
if (i >= (numWndVals / dataIntv) - 1)
|
logger->logDebug(GwLog::DEBUG, "PageWindPlot Chart: i: %d, chrtVal: %d, bufStart: %d, count: %d, linesToShow: %d", i, chrtVal, bufStart, count, (numWndVals / dataIntv));
|
||||||
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot Chart: i: %d, chrtVal: %d, bufStart: %d, count: %d, linesToShow: %d", i, chrtVal, bufStart, count, (numWndVals / dataIntv));
|
|
||||||
|
|
||||||
if ((i == 0) || (chrtPrevVal == INT16_MIN)) {
|
if ((i == 0) || (chrtPrevVal == wdMAX_VAL)) {
|
||||||
// just a dot for 1st chart point or after some invalid values
|
// just a dot for 1st chart point or after some invalid values
|
||||||
prevX = x;
|
prevX = x;
|
||||||
prevY = y;
|
prevY = y;
|
||||||
@@ -347,15 +392,15 @@ public:
|
|||||||
if (((chrtPrevVal180 >= -180) && (chrtPrevVal180 < -90) && (chrtVal180 > 90)) || ((chrtPrevVal180 <= 179) && (chrtPrevVal180 > 90) && chrtVal180 <= -90)) {
|
if (((chrtPrevVal180 >= -180) && (chrtPrevVal180 < -90) && (chrtVal180 > 90)) || ((chrtPrevVal180 <= 179) && (chrtPrevVal180 > 90) && chrtVal180 <= -90)) {
|
||||||
// If current value crosses chart borders compared to previous value, split line
|
// If current value crosses chart borders compared to previous value, split line
|
||||||
int xSplit = (((chrtPrevVal180 > 0 ? wndRight : wndLeft) - wndLeft + 360) % 360) * chrtScl;
|
int xSplit = (((chrtPrevVal180 > 0 ? wndRight : wndLeft) - wndLeft + 360) % 360) * chrtScl;
|
||||||
getdisplay().drawLine(prevX, prevY, xSplit, y, commonData->fgcolor);
|
epd->drawLine(prevX, prevY, xSplit, y, commonData->fgcolor);
|
||||||
getdisplay().drawLine(prevX, prevY - 1, ((xSplit != prevX) ? xSplit : xSplit - 1), ((xSplit != prevX) ? y - 1 : y), commonData->fgcolor);
|
epd->drawLine(prevX, prevY - 1, ((xSplit != prevX) ? xSplit : xSplit - 1), ((xSplit != prevX) ? y - 1 : y), commonData->fgcolor);
|
||||||
prevX = (((chrtVal180 > 0 ? wndRight : wndLeft) - wndLeft + 360) % 360) * chrtScl;
|
prevX = (((chrtVal180 > 0 ? wndRight : wndLeft) - wndLeft + 360) % 360) * chrtScl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw line with 2 pixels width + make sure vertical line are drawn correctly
|
// Draw line with 2 pixels width + make sure vertical line are drawn correctly
|
||||||
getdisplay().drawLine(prevX, prevY, x, y, commonData->fgcolor);
|
epd->drawLine(prevX, prevY, x, y, commonData->fgcolor);
|
||||||
getdisplay().drawLine(prevX, prevY - 1, ((x != prevX) ? x : x - 1), ((x != prevX) ? y - 1 : y), commonData->fgcolor);
|
epd->drawLine(prevX, prevY - 1, ((x != prevX) ? x : x - 1), ((x != prevX) ? y - 1 : y), commonData->fgcolor);
|
||||||
chrtPrevVal = chrtVal;
|
chrtPrevVal = chrtVal;
|
||||||
prevX = x;
|
prevX = x;
|
||||||
prevY = y;
|
prevY = y;
|
||||||
@@ -364,41 +409,27 @@ public:
|
|||||||
if (i >= (cHeight - 1)) {
|
if (i >= (cHeight - 1)) {
|
||||||
oldDataIntv = 0; // force reset of buffer start and number of values to show in next display loop
|
oldDataIntv = 0; // force reset of buffer start and number of values to show in next display loop
|
||||||
|
|
||||||
int minWndDir = pageData.boatHstry.twdHstry->getMin(numWndVals) / 1000.0 * radToDeg;
|
int minWndDir = wdHstry->getMin(numWndVals) / 1000.0 * radToDeg;
|
||||||
int maxWndDir = pageData.boatHstry.twdHstry->getMax(numWndVals) / 1000.0 * radToDeg;
|
int maxWndDir = wdHstry->getMax(numWndVals) / 1000.0 * radToDeg;
|
||||||
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot FreeTop: Minimum: %d, Maximum: %d, OldwndCenter: %d", minWndDir, maxWndDir, wndCenter);
|
logger->logDebug(GwLog::DEBUG, "PageWindPlot FreeTop: Minimum: %d, Maximum: %d, OldwndCenter: %d", minWndDir, maxWndDir, wndCenter);
|
||||||
// if ((minWndDir + 540 >= wndCenter + 540) || (maxWndDir + 540 <= wndCenter + 540)) {
|
// if (((minWndDir - wndCenter >= 0) && (minWndDir - wndCenter < 180)) || ((maxWndDir - wndCenter <= 0) && (maxWndDir - wndCenter >=180))) {
|
||||||
if (((minWndDir - wndCenter >= 0) && (minWndDir - wndCenter < 180)) || ((maxWndDir - wndCenter <= 0) && (maxWndDir - wndCenter >=180))) {
|
if ((wndRight > wndCenter && (minWndDir >= wndCenter && minWndDir <= wndRight)) || (wndRight <= wndCenter && (minWndDir >= wndCenter || minWndDir <= wndRight)) || (wndLeft < wndCenter && (maxWndDir <= wndCenter && maxWndDir >= wndLeft)) || (wndLeft >= wndCenter && (maxWndDir <= wndCenter || maxWndDir >= wndLeft))) {
|
||||||
// Check if all wind value are left or right of center value -> optimize chart range
|
// Check if all wind value are left or right of center value -> optimize chart center
|
||||||
midWndDir = pageData.boatHstry.twdHstry->getMid(numWndVals) / 1000.0 * radToDeg;
|
wndCenter = getCntr(*wdHstry, numWndVals);
|
||||||
if (midWndDir != INT16_MIN) {
|
|
||||||
wndCenter = int((midWndDir + (midWndDir >= 0 ? 5 : -5)) / 10) * 10; // Set new center value; round to nearest 10 degree value
|
|
||||||
}
|
}
|
||||||
}
|
logger->logDebug(GwLog::DEBUG, "PageWindPlot FreeTop: cHeight: %d, bufStart: %d, numWndVals: %d, wndCenter: %d", cHeight, bufStart, numWndVals, wndCenter);
|
||||||
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot FreeTop: cHeight: %d, bufStart: %d, numWndVals: %d, wndCenter: %d", cHeight, bufStart, numWndVals, wndCenter);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
// Print wind speed value
|
||||||
// No valid data available
|
|
||||||
LOG_DEBUG(GwLog::LOG, "PageWindPlot: No valid data available");
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold10pt8b);
|
|
||||||
getdisplay().fillRect(xCenter - 33, height / 2 - 20, 66, 24, commonData->bgcolor); // Clear area for message
|
|
||||||
drawTextCenter(xCenter, height / 2 - 10, "No data");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print TWS value
|
|
||||||
if (showTWS) {
|
|
||||||
int currentZone;
|
int currentZone;
|
||||||
static int lastZone = 0;
|
static int lastZone = 0;
|
||||||
static bool flipTws = false;
|
static bool flipTws = false;
|
||||||
int xPosTws;
|
int xPosTws;
|
||||||
static const int yPosTws = yOffset + 40;
|
static const int yPosTws = yOffset + 40;
|
||||||
|
|
||||||
twsValue = pageData.boatHstry.twsHstry->getLast() / 10.0 * 1.94384; // TWS value in knots
|
xPosTws = flipTws ? 20 : width - 145;
|
||||||
|
|
||||||
xPosTws = flipTws ? 20 : width - 138;
|
|
||||||
currentZone = (y >= yPosTws - 38) && (y <= yPosTws + 6) && (x >= xPosTws - 4) && (x <= xPosTws + 146) ? 1 : 0; // Define current zone for TWS value
|
currentZone = (y >= yPosTws - 38) && (y <= yPosTws + 6) && (x >= xPosTws - 4) && (x <= xPosTws + 146) ? 1 : 0; // Define current zone for TWS value
|
||||||
if (currentZone != lastZone) {
|
if (currentZone != lastZone) {
|
||||||
// Only flip when x moves to a different zone
|
// Only flip when x moves to a different zone
|
||||||
@@ -409,39 +440,49 @@ public:
|
|||||||
}
|
}
|
||||||
lastZone = currentZone;
|
lastZone = currentZone;
|
||||||
|
|
||||||
getdisplay().fillRect(xPosTws - 4, yPosTws - 38, 142, 44, commonData->bgcolor); // Clear area for TWS value
|
wsValue = wsHstry->getLast();
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b);
|
wsBVal->value = wsValue / 1000.0; // temp variable to retreive data unit from OBP60Formater
|
||||||
getdisplay().setCursor(xPosTws, yPosTws);
|
wsBVal->valid = (static_cast<uint16_t>(wsValue) != wsHstry->getMinVal());
|
||||||
if (!BDataValid[1]) {
|
String swsValue = commonData->fmt->formatValue(wsBVal, *commonData).svalue; // value (string)
|
||||||
getdisplay().print("--.-");
|
wsUnit = commonData->fmt->formatValue(wsBVal, *commonData).unit; // Unit of value
|
||||||
|
epd->fillRect(xPosTws - 4, yPosTws - 38, 142, 44, commonData->bgcolor); // Clear area for TWS value
|
||||||
|
epd->setFont(&DSEG7Classic_BoldItalic16pt7b);
|
||||||
|
epd->setCursor(xPosTws, yPosTws);
|
||||||
|
epd->print(swsValue); // Value
|
||||||
|
/* if (!wsBVal->valid) {
|
||||||
|
epd->print("--.-");
|
||||||
} else {
|
} else {
|
||||||
double dbl = BDataValue[1] * 3.6 / 1.852;
|
wsValue = wsValue / 10.0 * 1.94384; // Wind speed value in knots
|
||||||
if (dbl < 10.0) {
|
if (wsValue < 10.0) {
|
||||||
getdisplay().printf("!%3.1f", dbl); // Value, round to 1 decimal
|
epd->printf("!%3.1f", wsValue); // Value, round to 1 decimal
|
||||||
} else {
|
} else {
|
||||||
getdisplay().printf("%4.1f", dbl); // Value, round to 1 decimal
|
epd->printf("%4.1f", wsValue); // Value, round to 1 decimal
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(xPosTws + 82, yPosTws - 14);
|
epd->setCursor(xPosTws + 82, yPosTws - 14);
|
||||||
// getdisplay().print("TWS"); // Name
|
epd->print(wsName); // Name
|
||||||
getdisplay().print(BDataName[1]); // Name
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setCursor(xPosTws + 82, yPosTws + 1);
|
||||||
// getdisplay().setCursor(xPosTws + 78, yPosTws + 1);
|
epd->print(wsUnit); // Unit
|
||||||
getdisplay().setCursor(xPosTws + 82, yPosTws + 1);
|
|
||||||
// getdisplay().printf(" kn"); // Unit
|
} else {
|
||||||
getdisplay().print(BDataUnit[1]); // Unit
|
// No valid data available
|
||||||
|
LOG_DEBUG(GwLog::LOG, "PageWindPlot: No valid data available");
|
||||||
|
epd->setFont(&Ubuntu_Bold10pt8b);
|
||||||
|
epd->fillRect(xCenter - 33, height / 2 - 20, 66, 24, commonData->bgcolor); // Clear area for message
|
||||||
|
drawTextCenter(xCenter, height / 2 - 10, "No data");
|
||||||
}
|
}
|
||||||
|
|
||||||
// chart Y axis labels; print at last to overwrite potential chart lines in label area
|
// chart Y axis labels; print at last to overwrite potential chart lines in label area
|
||||||
int yPos;
|
int yPos;
|
||||||
int chrtLbl;
|
int chrtLbl;
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
for (int i = 1; i <= 3; i++) {
|
for (int i = 1; i <= 3; i++) {
|
||||||
yPos = yOffset + (i * 60);
|
yPos = yOffset + (i * 60);
|
||||||
getdisplay().fillRect(0, yPos, width, 1, commonData->fgcolor);
|
epd->fillRect(0, yPos, width, 1, commonData->fgcolor);
|
||||||
getdisplay().fillRect(0, yPos - 8, 24, 16, commonData->bgcolor); // Clear small area to remove potential chart lines
|
epd->fillRect(0, yPos - 8, 24, 16, commonData->bgcolor); // Clear small area to remove potential chart lines
|
||||||
getdisplay().setCursor(1, yPos + 4);
|
epd->setCursor(1, yPos + 4);
|
||||||
if (count >= intvBufSize) {
|
if (count >= intvBufSize) {
|
||||||
// Calculate minute value for label
|
// Calculate minute value for label
|
||||||
chrtLbl = ((i - 1 + (prevY < yOffset + 30)) * dataIntv) * -1; // change label if last data point is more than 30 lines (= seconds) from chart line
|
chrtLbl = ((i - 1 + (prevY < yOffset + 30)) * dataIntv) * -1; // change label if last data point is more than 30 lines (= seconds) from chart line
|
||||||
@@ -449,9 +490,10 @@ public:
|
|||||||
int j = 3 - i;
|
int j = 3 - i;
|
||||||
chrtLbl = (int((((numWndVals / dataIntv) - 50) * dataIntv / 60) + 1) - (j * dataIntv)) * -1; // 50 lines left below last chart line
|
chrtLbl = (int((((numWndVals / dataIntv) - 50) * dataIntv / 60) + 1) - (j * dataIntv)) * -1; // 50 lines left below last chart line
|
||||||
}
|
}
|
||||||
getdisplay().printf("%3d", chrtLbl); // Wind value label
|
epd->printf("%3d", chrtLbl); // Wind value label
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger->logDebug(GwLog::DEBUG, "PageWindPlot time: %ld", millis() - timer);
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -460,19 +502,17 @@ static Page* createPage(CommonData& common)
|
|||||||
{
|
{
|
||||||
return new PageWindPlot(common);
|
return new PageWindPlot(common);
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* with the code below we make this page known to the PageTask
|
/* with the code below we make this page known to the PageTask
|
||||||
* we give it a type (name) that can be selected in the config
|
* we give it a type (name) that can be selected in the config
|
||||||
* we define which function is to be called
|
* we define which function is to be called
|
||||||
* and we provide the number of user parameters we expect (0 here)
|
* and we provide the number of user parameters we expect (0 here)
|
||||||
* and will will provide the names of the fixed values we need
|
* and will will provide the names of the fixed values we need */
|
||||||
*/
|
|
||||||
PageDescription registerPageWindPlot(
|
PageDescription registerPageWindPlot(
|
||||||
"WindPlot", // Page name
|
"WindPlot", // Page name
|
||||||
createPage, // Action
|
createPage, // Action
|
||||||
0, // Number of bus values depends on selection in Web configuration
|
0, // Number of bus values depends on selection in Web configuration
|
||||||
{ "TWD", "TWS" }, // Bus values we need in the page
|
{ "TWD", "AWD"}, // Bus values we need in the page
|
||||||
// {}, // Bus values we need in the page
|
|
||||||
true // Show display header on/off
|
true // Show display header on/off
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,30 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
#include "OBP60Extensions.h"
|
#include "OBP60Extensions.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
#include "BoatDataCalibration.h"
|
#include "BoatDataCalibration.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class PageWindRose : public Page
|
class PageWindRose : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String lengthformat;
|
||||||
int16_t lp = 80; // Pointer length
|
int16_t lp = 80; // Pointer length
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageWindRose(CommonData &common){
|
PageWindRose(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageWindRose");
|
logger->logDebug(GwLog::LOG, "Instantiate PageWindRose");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
String lengthformat = config->getString(config->lengthFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Key functions
|
// Key functions
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key) {
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -24,222 +33,179 @@ public:
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
int displayPage(PageData &pageData){
|
void displayNew(PageData &pageData) {
|
||||||
GwConfigHandler *config = commonData->config;
|
#ifdef BOARD_OBP60S3
|
||||||
GwLog *logger = commonData->logger;
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
static String svalue1old = "";
|
|
||||||
static String unit1old = "";
|
|
||||||
static String svalue2old = "";
|
|
||||||
static String unit2old = "";
|
|
||||||
static String svalue3old = "";
|
|
||||||
static String unit3old = "";
|
|
||||||
static String svalue4old = "";
|
|
||||||
static String unit4old = "";
|
|
||||||
static String svalue5old = "";
|
|
||||||
static String unit5old = "";
|
|
||||||
static String svalue6old = "";
|
|
||||||
static String unit6old = "";
|
|
||||||
|
|
||||||
// Get config data
|
|
||||||
String lengthformat = config->getString(config->lengthFormat);
|
|
||||||
bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
|
|
||||||
// Get boat value for AWA
|
|
||||||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
|
||||||
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
|
||||||
name1 = name1.substring(0, 6); // String length limit for value name
|
|
||||||
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
|
||||||
double value1 = bvalue1->value; // Value as double in SI unit
|
|
||||||
bool valid1 = bvalue1->valid; // Valid information
|
|
||||||
value1 = formatValue(bvalue1, *commonData).value;// Format only nesaccery for simulation data for pointer
|
|
||||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
|
||||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
|
||||||
if(valid1 == true){
|
|
||||||
svalue1old = svalue1; // Save old value
|
|
||||||
unit1old = unit1; // Save old unit
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get boat value for AWS
|
|
||||||
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
|
|
||||||
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
|
||||||
name2 = name2.substring(0, 6); // String length limit for value name
|
|
||||||
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
|
|
||||||
double value2 = bvalue2->value; // Value as double in SI unit
|
|
||||||
bool valid2 = bvalue2->valid; // Valid information
|
|
||||||
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
|
||||||
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
|
||||||
if(valid2 == true){
|
|
||||||
svalue2old = svalue2; // Save old value
|
|
||||||
unit2old = unit2; // Save old unit
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get boat value for TWD
|
|
||||||
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list
|
|
||||||
String name3 = xdrDelete(bvalue3->getName()); // Value name
|
|
||||||
name3 = name3.substring(0, 6); // String length limit for value name
|
|
||||||
calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated
|
|
||||||
double value3 = bvalue3->value; // Value as double in SI unit
|
|
||||||
bool valid3 = bvalue3->valid; // Valid information
|
|
||||||
String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
|
||||||
String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value
|
|
||||||
if(valid3 == true){
|
|
||||||
svalue3old = svalue3; // Save old value
|
|
||||||
unit3old = unit3; // Save old unit
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get boat value for TWS
|
|
||||||
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Fourth element in list
|
|
||||||
String name4 = xdrDelete(bvalue4->getName()); // Value name
|
|
||||||
name4 = name4.substring(0, 6); // String length limit for value name
|
|
||||||
calibrationData.calibrateInstance(bvalue4, logger); // Check if boat data value is to be calibrated
|
|
||||||
double value4 = bvalue4->value; // Value as double in SI unit
|
|
||||||
bool valid4 = bvalue4->valid; // Valid information
|
|
||||||
String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
|
||||||
String unit4 = formatValue(bvalue4, *commonData).unit; // Unit of value
|
|
||||||
if(valid4 == true){
|
|
||||||
svalue4old = svalue4; // Save old value
|
|
||||||
unit4old = unit4; // Save old unit
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get boat value for DBT
|
|
||||||
GwApi::BoatValue *bvalue5 = pageData.values[4]; // Fifth element in list
|
|
||||||
String name5 = xdrDelete(bvalue5->getName()); // Value name
|
|
||||||
name5 = name5.substring(0, 6); // String length limit for value name
|
|
||||||
calibrationData.calibrateInstance(bvalue5, logger); // Check if boat data value is to be calibrated
|
|
||||||
double value5 = bvalue5->value; // Value as double in SI unit
|
|
||||||
bool valid5 = bvalue5->valid; // Valid information
|
|
||||||
String svalue5 = formatValue(bvalue5, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
|
||||||
String unit5 = formatValue(bvalue5, *commonData).unit; // Unit of value
|
|
||||||
if(valid5 == true){
|
|
||||||
svalue5old = svalue5; // Save old value
|
|
||||||
unit5old = unit5; // Save old unit
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get boat value for STW
|
|
||||||
GwApi::BoatValue *bvalue6 = pageData.values[5]; // Sixth element in list
|
|
||||||
String name6 = xdrDelete(bvalue6->getName()); // Value name
|
|
||||||
name6 = name6.substring(0, 6); // String length limit for value name
|
|
||||||
calibrationData.calibrateInstance(bvalue6, logger); // Check if boat data value is to be calibrated
|
|
||||||
double value6 = bvalue6->value; // Value as double in SI unit
|
|
||||||
bool valid6 = bvalue6->valid; // Valid information
|
|
||||||
String svalue6 = formatValue(bvalue6, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
|
||||||
String unit6 = formatValue(bvalue6, *commonData).unit; // Unit of value
|
|
||||||
if(valid6 == true){
|
|
||||||
svalue6old = svalue6; // Save old value
|
|
||||||
unit6old = unit6; // Save old unit
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
|
||||||
if(String(flashLED) == "Limit Violation"){
|
|
||||||
setBlinkingLED(false);
|
setBlinkingLED(false);
|
||||||
setFlashLED(false);
|
setFlashLED(false);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
// Logging boat values
|
int displayPage(PageData &pageData) {
|
||||||
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageWindRose, %s:%f, %s:%f, %s:%f, %s:%f, %s:%f, %s:%f", name1.c_str(), value1, name2.c_str(), value2, name3.c_str(), value3, name4.c_str(), value4, name5.c_str(), value5, name6.c_str(), value6);
|
// storage for hold valued
|
||||||
|
static FormattedData bvf_awa_old;
|
||||||
|
static FormattedData bvf_aws_old;
|
||||||
|
static FormattedData bvf_twd_old;
|
||||||
|
static FormattedData bvf_tws_old;
|
||||||
|
static FormattedData bvf_dbt_old;
|
||||||
|
static FormattedData bvf_stw_old;
|
||||||
|
|
||||||
|
// Get boat value for AWA
|
||||||
|
GwApi::BoatValue *bv_awa = pageData.values[0]; // First element in list
|
||||||
|
String name_awa = xdrDelete(bv_awa->getName(), 6); // get name without prefix and limit length
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
|
calibrationData.calibrateInstance(bv_awa, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
|
FormattedData bvf_awa = commonData->fmt->formatValue(bv_awa, *commonData);
|
||||||
|
if (bv_awa->valid) { // Save formatted data for hold feature
|
||||||
|
bvf_awa_old = bvf_awa;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get boat value for AWS
|
||||||
|
GwApi::BoatValue *bv_aws = pageData.values[1]; // Second element in list
|
||||||
|
String name_aws = xdrDelete(bv_aws->getName(), 6); // get name without prefix and limit length
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
|
calibrationData.calibrateInstance(bv_aws, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
|
FormattedData bvf_aws = commonData->fmt->formatValue(bv_aws, *commonData);
|
||||||
|
if (bv_aws->valid) { // Save formatted data for hold feature
|
||||||
|
bvf_aws_old = bvf_aws;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get boat value for TWD
|
||||||
|
GwApi::BoatValue *bv_twd = pageData.values[2]; // Third element in list
|
||||||
|
String name_twd = xdrDelete(bv_twd->getName(), 6); // get name without prefix and limit length
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
|
calibrationData.calibrateInstance(bv_twd, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
|
FormattedData bvf_twd = commonData->fmt->formatValue(bv_twd, *commonData);
|
||||||
|
if (bv_twd->valid) { // Save formatted data for hold feature
|
||||||
|
bvf_twd_old = bvf_twd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get boat value for TWS
|
||||||
|
GwApi::BoatValue *bv_tws = pageData.values[3]; // Fourth element in list
|
||||||
|
String name_tws = xdrDelete(bv_tws->getName(), 6); // get name without prefix and limit length
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
|
calibrationData.calibrateInstance(bv_tws, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
|
FormattedData bvf_tws = commonData->fmt->formatValue(bv_tws, *commonData);
|
||||||
|
if (bv_tws->valid) { // Save formatted data for hold feature
|
||||||
|
bvf_tws_old = bvf_tws;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get boat value for DBT
|
||||||
|
GwApi::BoatValue *bv_dbt = pageData.values[4]; // Fifth element in list
|
||||||
|
String name_dbt = xdrDelete(bv_dbt->getName(), 6); // get name without prefix and limit length
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
|
calibrationData.calibrateInstance(bv_dbt, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
|
FormattedData bvf_dbt = commonData->fmt->formatValue(bv_dbt, *commonData);
|
||||||
|
if (bv_dbt->valid) { // Save formatted data for hold feature
|
||||||
|
bvf_dbt_old = bvf_dbt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get boat value for STW
|
||||||
|
GwApi::BoatValue *bv_stw = pageData.values[5]; // Sixth element in list
|
||||||
|
String name_stw = xdrDelete(bv_stw->getName(), 6); // get name without prefix and limit length
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
|
calibrationData.calibrateInstance(bv_stw, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
|
FormattedData bvf_stw = commonData->fmt->formatValue(bv_stw, *commonData);
|
||||||
|
if (bv_stw->valid) { // Save formatted data for hold feature
|
||||||
|
bvf_stw_old = bvf_stw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log boat values
|
||||||
|
logger->logDebug(GwLog::LOG, "Drawing at PageWindRose, %s:%f, %s:%f, %s:%f, %s:%f, %s:%f, %s:%f",
|
||||||
|
name_awa.c_str(), bv_awa->value,
|
||||||
|
name_aws.c_str(), bv_aws->value,
|
||||||
|
name_twd.c_str(), bv_twd->value,
|
||||||
|
name_tws.c_str(), bv_tws->value,
|
||||||
|
name_dbt.c_str(), bv_dbt->value,
|
||||||
|
name_stw.c_str(), bv_stw->value);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
// *********************************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height());
|
||||||
|
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
// Show values AWA
|
// Show values AWA
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(10, 65);
|
epd->setCursor(10, 65);
|
||||||
getdisplay().print(svalue1); // Value
|
epd->print(holdvalues ? bvf_awa_old.value : bvf_awa.value);
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(10, 95);
|
epd->setCursor(10, 95);
|
||||||
getdisplay().print(name1); // Name
|
epd->print(name_awa);
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(10, 115);
|
epd->setCursor(10, 115);
|
||||||
getdisplay().print(" ");
|
epd->print(" ");
|
||||||
if(holdvalues == false){
|
epd->print(holdvalues ? bvf_awa_old.unit : bvf_awa.unit);
|
||||||
getdisplay().print(unit1); // Unit
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
getdisplay().print(unit1old); // Unit
|
|
||||||
}
|
|
||||||
|
|
||||||
// Horizintal separator left
|
// Horizintal separator left
|
||||||
getdisplay().fillRect(0, 149, 60, 3, commonData->fgcolor);
|
epd->fillRect(0, 149, 60, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// Show values AWS
|
// Show values AWS
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(10, 270);
|
epd->setCursor(10, 270);
|
||||||
getdisplay().print(svalue2); // Value
|
epd->print(holdvalues ? bvf_aws_old.value : bvf_aws.value);
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(10, 220);
|
epd->setCursor(10, 220);
|
||||||
getdisplay().print(name2); // Name
|
epd->print(name_aws);
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(10, 190);
|
epd->setCursor(10, 190);
|
||||||
getdisplay().print(" ");
|
epd->print(" ");
|
||||||
if(holdvalues == false){
|
epd->print(holdvalues ? bvf_aws_old.unit : bvf_aws.unit);
|
||||||
getdisplay().print(unit2); // Unit
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
getdisplay().print(unit2old); // Unit
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show values TWD
|
// Show value TWD
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(295, 65);
|
epd->setCursor(295, 65);
|
||||||
if(valid3 == true){
|
// TODO WTF? Der Formatter sollte das korrekt machen
|
||||||
getdisplay().print(abs(value3 * 180 / PI), 0); // Value
|
if (bv_twd->valid) {
|
||||||
|
epd->print(abs(bv_twd->value * 180 / PI), 0); // Value
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
getdisplay().print("---"); // Value
|
epd->print(commonData->fmt->placeholder);
|
||||||
}
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
|
||||||
getdisplay().setCursor(335, 95);
|
|
||||||
getdisplay().print(name3); // Name
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
|
||||||
getdisplay().setCursor(335, 115);
|
|
||||||
getdisplay().print(" ");
|
|
||||||
if(holdvalues == false){
|
|
||||||
getdisplay().print(unit3); // Unit
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
getdisplay().print(unit3old); // Unit
|
|
||||||
}
|
}
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(335, 95);
|
||||||
|
epd->print(name_twd); // Name
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
epd->setCursor(335, 115);
|
||||||
|
epd->print(" ");
|
||||||
|
epd->print(holdvalues ? bvf_twd_old.unit : bvf_twd.unit);
|
||||||
|
|
||||||
// Horizintal separator right
|
// Horizintal separator right
|
||||||
getdisplay().fillRect(340, 149, 80, 3, commonData->fgcolor);
|
epd->fillRect(340, 149, 80, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// Show values TWS
|
// Show values TWS
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(295, 270);
|
epd->setCursor(295, 270);
|
||||||
getdisplay().print(svalue4); // Value
|
epd->print(name_tws);
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(335, 220);
|
epd->setCursor(335, 220);
|
||||||
getdisplay().print(name4); // Name
|
epd->print(holdvalues ? bvf_tws_old.value : bvf_tws.value);
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(335, 190);
|
epd->setCursor(335, 190);
|
||||||
getdisplay().print(" ");
|
epd->print(" ");
|
||||||
if(holdvalues == false){
|
epd->print(holdvalues ? bvf_tws_old.unit : bvf_tws.unit);
|
||||||
getdisplay().print(unit4); // Unit
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
getdisplay().print(unit4old); // Unit
|
|
||||||
}
|
|
||||||
|
|
||||||
//*******************************************************************************************
|
// *********************************************************************
|
||||||
|
|
||||||
// Draw wind rose
|
// Draw wind rose
|
||||||
int rInstrument = 110; // Radius of grafic instrument
|
int rInstrument = 110; // Radius of grafic instrument
|
||||||
float pi = 3.141592;
|
float pi = 3.141592;
|
||||||
|
|
||||||
getdisplay().fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle
|
epd->fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle
|
||||||
getdisplay().fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle
|
epd->fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle
|
||||||
getdisplay().fillCircle(200, 150, rInstrument - 10, commonData->fgcolor); // Inner circle
|
epd->fillCircle(200, 150, rInstrument - 10, commonData->fgcolor); // Inner circle
|
||||||
getdisplay().fillCircle(200, 150, rInstrument - 13, commonData->bgcolor); // Inner circle
|
epd->fillCircle(200, 150, rInstrument - 13, commonData->bgcolor); // Inner circle
|
||||||
|
|
||||||
for(int i=0; i<360; i=i+10)
|
for(int i=0; i<360; i=i+10)
|
||||||
{
|
{
|
||||||
@@ -247,8 +213,7 @@ public:
|
|||||||
float x = 200 + (rInstrument-30)*sin(i/180.0*pi); // x-coordinate dots
|
float x = 200 + (rInstrument-30)*sin(i/180.0*pi); // x-coordinate dots
|
||||||
float y = 150 - (rInstrument-30)*cos(i/180.0*pi); // y-coordinate cots
|
float y = 150 - (rInstrument-30)*cos(i/180.0*pi); // y-coordinate cots
|
||||||
const char *ii = "";
|
const char *ii = "";
|
||||||
switch (i)
|
switch (i) {
|
||||||
{
|
|
||||||
case 0: ii="0"; break;
|
case 0: ii="0"; break;
|
||||||
case 30 : ii="30"; break;
|
case 30 : ii="30"; break;
|
||||||
case 60 : ii="60"; break;
|
case 60 : ii="60"; break;
|
||||||
@@ -267,17 +232,17 @@ public:
|
|||||||
// Print text centered on position x, y
|
// Print text centered on position x, y
|
||||||
int16_t x1, y1; // Return values of getTextBounds
|
int16_t x1, y1; // Return values of getTextBounds
|
||||||
uint16_t w, h; // Return values of getTextBounds
|
uint16_t w, h; // Return values of getTextBounds
|
||||||
getdisplay().getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string
|
epd->getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string
|
||||||
getdisplay().setCursor(x-w/2, y+h/2);
|
epd->setCursor(x-w/2, y+h/2);
|
||||||
if (i % 30 == 0) {
|
if (i % 30 == 0) {
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b); // TODO move out of loop
|
||||||
getdisplay().print(ii);
|
epd->print(ii);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw sub scale with dots
|
// Draw sub scale with dots
|
||||||
float x1c = 200 + rInstrument*sin(i/180.0*pi);
|
float x1c = 200 + rInstrument*sin(i/180.0*pi);
|
||||||
float y1c = 150 - rInstrument*cos(i/180.0*pi);
|
float y1c = 150 - rInstrument*cos(i/180.0*pi);
|
||||||
getdisplay().fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor);
|
epd->fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor);
|
||||||
float sinx=sin(i/180.0*pi);
|
float sinx=sin(i/180.0*pi);
|
||||||
float cosx=cos(i/180.0*pi);
|
float cosx=cos(i/180.0*pi);
|
||||||
|
|
||||||
@@ -288,10 +253,10 @@ public:
|
|||||||
float xx2 = +dx;
|
float xx2 = +dx;
|
||||||
float yy1 = -(rInstrument-10);
|
float yy1 = -(rInstrument-10);
|
||||||
float yy2 = -(rInstrument+10);
|
float yy2 = -(rInstrument+10);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),
|
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),
|
||||||
200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor);
|
||||||
}
|
}
|
||||||
@@ -299,16 +264,16 @@ public:
|
|||||||
|
|
||||||
// Draw wind pointer
|
// Draw wind pointer
|
||||||
float startwidth = 8; // Start width of pointer
|
float startwidth = 8; // Start width of pointer
|
||||||
if(valid2 == true || holdvalues == true || simulation == true){
|
if (bv_aws->valid || holdvalues || simulation) {
|
||||||
float sinx=sin(value1); // Wind direction
|
float sinx = sin(bv_awa->value); // Wind direction
|
||||||
float cosx=cos(value1);
|
float cosx = cos(bv_awa->value);
|
||||||
// Normal pointer
|
// Normal pointer
|
||||||
// Pointer as triangle with center base 2*width
|
// Pointer as triangle with center base 2*width
|
||||||
float xx1 = -startwidth;
|
float xx1 = -startwidth;
|
||||||
float xx2 = startwidth;
|
float xx2 = startwidth;
|
||||||
float yy1 = -startwidth;
|
float yy1 = -startwidth;
|
||||||
float yy2 = -(rInstrument-15);
|
float yy2 = -(rInstrument-15);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
||||||
// Inverted pointer
|
// Inverted pointer
|
||||||
@@ -318,47 +283,42 @@ public:
|
|||||||
float ix2 = -endwidth;
|
float ix2 = -endwidth;
|
||||||
float iy1 = -(rInstrument-15);
|
float iy1 = -(rInstrument-15);
|
||||||
float iy2 = -endwidth;
|
float iy2 = -endwidth;
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1),
|
epd->fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1),
|
||||||
200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1),
|
200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1),
|
||||||
200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Center circle
|
// Center circle
|
||||||
getdisplay().fillCircle(200, 150, startwidth + 6, commonData->bgcolor);
|
epd->fillCircle(200, 150, startwidth + 6, commonData->bgcolor);
|
||||||
getdisplay().fillCircle(200, 150, startwidth + 4, commonData->fgcolor);
|
epd->fillCircle(200, 150, startwidth + 4, commonData->fgcolor);
|
||||||
|
|
||||||
//*******************************************************************************************
|
// *********************************************************************
|
||||||
|
|
||||||
// Show values DBT
|
// Show value DBT
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic16pt7b);
|
||||||
getdisplay().setCursor(160, 200);
|
epd->setCursor(160, 200);
|
||||||
getdisplay().print(svalue5); // Value
|
epd->print(holdvalues ? bvf_dbt_old.value : bvf_dbt.value);
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(190, 215);
|
epd->setCursor(190, 215);
|
||||||
getdisplay().print(" ");
|
epd->print(" ");
|
||||||
if(holdvalues == false){
|
epd->print(holdvalues ? bvf_dbt_old.unit : bvf_dbt.unit);
|
||||||
getdisplay().print(unit5); // Unit
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
getdisplay().print(unit5old); // Unit
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show values STW
|
// Show value STW
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic16pt7b);
|
||||||
getdisplay().setCursor(160, 130);
|
epd->setCursor(160, 130);
|
||||||
getdisplay().print(svalue6); // Value
|
epd->print(holdvalues ? bvf_stw_old.value : bvf_stw.value);
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(190, 90);
|
epd->setCursor(190, 90);
|
||||||
getdisplay().print(" ");
|
epd->print(" ");
|
||||||
if(holdvalues == false){
|
epd->print(holdvalues ? bvf_stw_old.unit : bvf_stw.unit);
|
||||||
getdisplay().print(unit6); // Unit
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
getdisplay().print(unit6old); // Unit
|
|
||||||
}
|
|
||||||
|
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void leavePage(PageData &pageData) {
|
||||||
|
logger->logDebug(GwLog::LOG, "Leaving PageWindRose");
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static Page *createPage(CommonData &common){
|
static Page *createPage(CommonData &common){
|
||||||
|
|||||||
@@ -1,21 +1,37 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
#include "OBP60Extensions.h"
|
#include "OBP60Extensions.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
#include "BoatDataCalibration.h"
|
#include "BoatDataCalibration.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class PageWindRoseFlex : public Page
|
class PageWindRoseFlex : public Page
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
String lengthformat;
|
||||||
int16_t lp = 80; // Pointer length
|
int16_t lp = 80; // Pointer length
|
||||||
|
char source = 'A'; // data source (A)pparent | (T)rue
|
||||||
|
String ssource="App."; // String for Data Source
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageWindRoseFlex(CommonData &common){
|
PageWindRoseFlex(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageWindRoseFlex");
|
logger->logDebug(GwLog::LOG, "Instantiate PageWindRoseFlex");
|
||||||
|
|
||||||
|
// Get config data
|
||||||
|
lengthformat = config->getString(config->lengthFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupKeys() {
|
||||||
|
Page::setupKeys();
|
||||||
|
commonData->keydata[1].label = "SRC";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Key functions
|
// Key functions
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key) {
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -24,9 +40,17 @@ public:
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void displayNew(PageData &pageData) {
|
||||||
|
#ifdef BOARD_OBP60S3
|
||||||
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
|
setBlinkingLED(false);
|
||||||
|
setFlashLED(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
int displayPage(PageData &pageData) {
|
int displayPage(PageData &pageData) {
|
||||||
GwConfigHandler *config = commonData->config;
|
|
||||||
GwLog *logger = commonData->logger;
|
|
||||||
|
|
||||||
static String svalue1old = "";
|
static String svalue1old = "";
|
||||||
static String unit1old = "";
|
static String unit1old = "";
|
||||||
@@ -41,206 +65,198 @@ public:
|
|||||||
static String svalue6old = "";
|
static String svalue6old = "";
|
||||||
static String unit6old = "";
|
static String unit6old = "";
|
||||||
|
|
||||||
// Get config data
|
GwApi::BoatValue *bvalue1; // Value 1 for angle
|
||||||
String lengthformat = config->getString(config->lengthFormat);
|
GwApi::BoatValue *bvalue2; // Value 2 for speed
|
||||||
bool simulation = config->getBool(config->useSimuData);
|
|
||||||
bool holdvalues = config->getBool(config->holdvalues);
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
|
|
||||||
// Get boat values #1
|
// Get boat value for wind angle (AWA/TWA), shown by pointer
|
||||||
GwApi::BoatValue *bvalue1 = pageData.values[0]; // First element in list (only one value by PageOneValue)
|
if (source == 'A') {
|
||||||
String name1 = xdrDelete(bvalue1->getName()); // Value name
|
bvalue1 = pageData.values[4];
|
||||||
|
} else {
|
||||||
|
bvalue1 = pageData.values[6];
|
||||||
|
}
|
||||||
|
String name1 = bvalue1->getName().c_str(); // Value name
|
||||||
name1 = name1.substring(0, 6); // String length limit for value name
|
name1 = name1.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue1, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value1 = bvalue1->value; // Value as double in SI unit
|
double value1 = bvalue1->value; // Value as double in SI unit
|
||||||
bool valid1 = bvalue1->valid; // Valid information
|
bool valid1 = bvalue1->valid; // Valid information
|
||||||
value1 = formatValue(bvalue1, *commonData).value;// Format only nesaccery for simulation data for pointer
|
String svalue1 = commonData->fmt->formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String svalue1 = formatValue(bvalue1, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String unit1 = commonData->fmt->formatValue(bvalue1, *commonData).unit; // Unit of value
|
||||||
String unit1 = formatValue(bvalue1, *commonData).unit; // Unit of value
|
|
||||||
if (valid1 == true) {
|
if (valid1 == true) {
|
||||||
svalue1old = svalue1; // Save old value
|
svalue1old = svalue1; // Save old value
|
||||||
unit1old = unit1; // Save old unit
|
unit1old = unit1; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get boat values #2
|
// Get boat value for wind speed (AWS/TWS), shown in top left corner
|
||||||
GwApi::BoatValue *bvalue2 = pageData.values[1]; // Second element in list
|
if (source == 'A') {
|
||||||
String name2 = xdrDelete(bvalue2->getName()); // Value name
|
bvalue2 =pageData.values[5];
|
||||||
|
} else {
|
||||||
|
bvalue2 = pageData.values[7];
|
||||||
|
}
|
||||||
|
String name2 = bvalue2->getName().c_str(); // Value name
|
||||||
name2 = name2.substring(0, 6); // String length limit for value name
|
name2 = name2.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue2, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value2 = bvalue2->value; // Value as double in SI unit
|
double value2 = bvalue2->value; // Value as double in SI unit
|
||||||
bool valid2 = bvalue2->valid; // Valid information
|
bool valid2 = bvalue2->valid; // Valid information
|
||||||
String svalue2 = formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
if (simulation) {
|
||||||
String unit2 = formatValue(bvalue2, *commonData).unit; // Unit of value
|
value2 = 0.62731; // some random value
|
||||||
|
}
|
||||||
|
String svalue2 = commonData->fmt->formatValue(bvalue2, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
|
String unit2 = commonData->fmt->formatValue(bvalue2, *commonData).unit; // Unit of value
|
||||||
if (valid2 == true) {
|
if (valid2 == true) {
|
||||||
svalue2old = svalue2; // Save old value
|
svalue2old = svalue2; // Save old value
|
||||||
unit2old = unit2; // Save old unit
|
unit2old = unit2; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get boat values #3
|
// Get boat value for bottom left corner
|
||||||
GwApi::BoatValue *bvalue3 = pageData.values[2]; // Third element in list
|
GwApi::BoatValue *bvalue3 = pageData.values[0];
|
||||||
String name3 = xdrDelete(bvalue3->getName()); // Value name
|
String name3 = xdrDelete(bvalue3->getName()); // Value name
|
||||||
name3 = name3.substring(0, 6); // String length limit for value name
|
name3 = name3.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue3, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value3 = bvalue3->value; // Value as double in SI unit
|
double value3 = bvalue3->value; // Value as double in SI unit
|
||||||
bool valid3 = bvalue3->valid; // Valid information
|
bool valid3 = bvalue3->valid; // Valid information
|
||||||
String svalue3 = formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue3 = commonData->fmt->formatValue(bvalue3, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit3 = formatValue(bvalue3, *commonData).unit; // Unit of value
|
String unit3 = commonData->fmt->formatValue(bvalue3, *commonData).unit; // Unit of value
|
||||||
if(valid3 == true){
|
if(valid3 == true){
|
||||||
svalue3old = svalue3; // Save old value
|
svalue3old = svalue3; // Save old value
|
||||||
unit3old = unit3; // Save old unit
|
unit3old = unit3; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get boat values #4
|
// Get boat value for top right corner
|
||||||
GwApi::BoatValue *bvalue4 = pageData.values[3]; // Fourth element in list
|
GwApi::BoatValue *bvalue4 = pageData.values[1];
|
||||||
String name4 = xdrDelete(bvalue4->getName()); // Value name
|
String name4 = xdrDelete(bvalue4->getName()); // Value name
|
||||||
name4 = name4.substring(0, 6); // String length limit for value name
|
name4 = name4.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue4, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue4, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value4 = bvalue4->value; // Value as double in SI unit
|
double value4 = bvalue4->value; // Value as double in SI unit
|
||||||
bool valid4 = bvalue4->valid; // Valid information
|
bool valid4 = bvalue4->valid; // Valid information
|
||||||
String svalue4 = formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue4 = commonData->fmt->formatValue(bvalue4, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit4 = formatValue(bvalue4, *commonData).unit; // Unit of value
|
String unit4 = commonData->fmt->formatValue(bvalue4, *commonData).unit; // Unit of value
|
||||||
if(valid4 == true){
|
if(valid4 == true){
|
||||||
svalue4old = svalue4; // Save old value
|
svalue4old = svalue4; // Save old value
|
||||||
unit4old = unit4; // Save old unit
|
unit4old = unit4; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get boat values #5
|
// Get boat value for bottom right corner
|
||||||
GwApi::BoatValue *bvalue5 = pageData.values[4]; // Fifth element in list
|
GwApi::BoatValue *bvalue5 = pageData.values[2];
|
||||||
String name5 = xdrDelete(bvalue5->getName()); // Value name
|
String name5 = xdrDelete(bvalue5->getName()); // Value name
|
||||||
name5 = name5.substring(0, 6); // String length limit for value name
|
name5 = name5.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue5, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue5, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value5 = bvalue5->value; // Value as double in SI unit
|
double value5 = bvalue5->value; // Value as double in SI unit
|
||||||
bool valid5 = bvalue5->valid; // Valid information
|
bool valid5 = bvalue5->valid; // Valid information
|
||||||
String svalue5 = formatValue(bvalue5, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue5 = commonData->fmt->formatValue(bvalue5, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit5 = formatValue(bvalue5, *commonData).unit; // Unit of value
|
String unit5 = commonData->fmt->formatValue(bvalue5, *commonData).unit; // Unit of value
|
||||||
if(valid5 == true){
|
if(valid5 == true){
|
||||||
svalue5old = svalue5; // Save old value
|
svalue5old = svalue5; // Save old value
|
||||||
unit5old = unit5; // Save old unit
|
unit5old = unit5; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get boat values #5
|
// Get boat value for center
|
||||||
GwApi::BoatValue *bvalue6 = pageData.values[5]; // Sixth element in list
|
GwApi::BoatValue *bvalue6 = pageData.values[3];
|
||||||
String name6 = xdrDelete(bvalue6->getName()); // Value name
|
String name6 = xdrDelete(bvalue6->getName()); // Value name
|
||||||
name6 = name6.substring(0, 6); // String length limit for value name
|
name6 = name6.substring(0, 6); // String length limit for value name
|
||||||
|
#ifdef ENABLE_CALIBRATION
|
||||||
calibrationData.calibrateInstance(bvalue6, logger); // Check if boat data value is to be calibrated
|
calibrationData.calibrateInstance(bvalue6, logger); // Check if boat data value is to be calibrated
|
||||||
|
#endif
|
||||||
double value6 = bvalue6->value; // Value as double in SI unit
|
double value6 = bvalue6->value; // Value as double in SI unit
|
||||||
bool valid6 = bvalue6->valid; // Valid information
|
bool valid6 = bvalue6->valid; // Valid information
|
||||||
String svalue6 = formatValue(bvalue6, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
String svalue6 = commonData->fmt->formatValue(bvalue6, *commonData).svalue; // Formatted value as string including unit conversion and switching decimal places
|
||||||
String unit6 = formatValue(bvalue6, *commonData).unit; // Unit of value
|
String unit6 = commonData->fmt->formatValue(bvalue6, *commonData).unit; // Unit of value
|
||||||
if(valid6 == true){
|
if(valid6 == true){
|
||||||
svalue6old = svalue6; // Save old value
|
svalue6old = svalue6; // Save old value
|
||||||
unit6old = unit6; // Save old unit
|
unit6old = unit6; // Save old unit
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
|
||||||
if(String(flashLED) == "Limit Violation"){
|
|
||||||
setBlinkingLED(false);
|
|
||||||
setFlashLED(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logging boat values
|
// Logging boat values
|
||||||
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
if (bvalue1 == NULL) return PAGE_OK; // WTF why this statement?
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageWindRoseFlex, %s:%f, %s:%f, %s:%f, %s:%f, %s:%f, %s:%f", name1.c_str(), value1, name2.c_str(), value2, name3.c_str(), value3, name4.c_str(), value4, name5.c_str(), value5, name6.c_str(), value6);
|
logger->logDebug(GwLog::LOG, "Drawing at PageWindRoseFlex, %s:%f, %s:%f, %s:%f, %s:%f, %s:%f, %s:%f", name1.c_str(), value1, name2.c_str(), value2, name3.c_str(), value3, name4.c_str(), value4, name5.c_str(), value5, name6.c_str(), value6);
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
// Show value 2 at position of value 1 (top left)
|
// Show AWS or TWS top left
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(10, 65);
|
epd->setCursor(10, 65);
|
||||||
getdisplay().print(svalue2); // Value
|
epd->print(svalue2); // Value
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(10, 95);
|
epd->setCursor(10, 95);
|
||||||
getdisplay().print(name2); // Name
|
epd->print(name2); // Name
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(10, 115);
|
epd->setCursor(10, 115);
|
||||||
getdisplay().print(" ");
|
epd->print(" ");
|
||||||
if(holdvalues == false){
|
epd->print(holdvalues ? unit2old : unit2);
|
||||||
getdisplay().print(unit2); // Unit
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
getdisplay().print(unit2old); // Unit
|
|
||||||
}
|
|
||||||
|
|
||||||
// Horizintal separator left
|
// Horizintal separator left
|
||||||
getdisplay().fillRect(0, 149, 60, 3, commonData->fgcolor);
|
epd->fillRect(0, 149, 60, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// Show value 3 at bottom left
|
// Show value 3 (=first user-configured parameter) at bottom left
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
getdisplay().setCursor(10, 270);
|
epd->setCursor(10, 270);
|
||||||
getdisplay().print(svalue3); // Value
|
epd->print(svalue3); // Value
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
getdisplay().setCursor(10, 220);
|
epd->setCursor(10, 220);
|
||||||
getdisplay().print(name3); // Name
|
epd->print(name3); // Name
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(10, 190);
|
epd->setCursor(10, 190);
|
||||||
getdisplay().print(" ");
|
epd->print(" ");
|
||||||
if(holdvalues == false){
|
epd->print(holdvalues ? unit3old : unit3);
|
||||||
getdisplay().print(unit3); // Unit
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
getdisplay().print(unit3old); // Unit
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show value 4 at top right
|
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
// Show value 4 (=second user-configured parameter) at top right
|
||||||
getdisplay().setCursor(295, 65);
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
|
epd->setCursor(295, 65);
|
||||||
if(valid3 == true){
|
if(valid3 == true){
|
||||||
// getdisplay().print(abs(value3 * 180 / M_PI), 0); // Value
|
epd->print(svalue4); // Value
|
||||||
getdisplay().print(svalue4); // Value
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().print("---"); // Value
|
epd->print(commonData->fmt->placeholder);
|
||||||
}
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
|
||||||
getdisplay().setCursor(335, 95);
|
|
||||||
getdisplay().print(name4); // Name
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
|
||||||
getdisplay().setCursor(335, 115);
|
|
||||||
getdisplay().print(" ");
|
|
||||||
if(holdvalues == false){
|
|
||||||
getdisplay().print(unit4); // Unit
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
getdisplay().print(unit4old); // Unit
|
|
||||||
}
|
}
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(335, 95);
|
||||||
|
epd->print(name4); // Name
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
epd->setCursor(335, 115);
|
||||||
|
epd->print(" ");
|
||||||
|
epd->print(holdvalues ? unit4old : unit4);
|
||||||
|
|
||||||
|
|
||||||
// Horizintal separator right
|
// Horizintal separator right
|
||||||
getdisplay().fillRect(340, 149, 80, 3, commonData->fgcolor);
|
epd->fillRect(340, 149, 80, 3, commonData->fgcolor);
|
||||||
|
|
||||||
// Show value 5 at bottom right
|
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic20pt7b);
|
|
||||||
getdisplay().setCursor(295, 270);
|
|
||||||
getdisplay().print(svalue5); // Value
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold12pt8b);
|
|
||||||
getdisplay().setCursor(335, 220);
|
|
||||||
getdisplay().print(name5); // Name
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
|
||||||
getdisplay().setCursor(335, 190);
|
|
||||||
getdisplay().print(" ");
|
|
||||||
if(holdvalues == false){
|
|
||||||
getdisplay().print(unit5); // Unit
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
getdisplay().print(unit5old); // Unit
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Show value 5 (=third user-configured parameter) at bottom right
|
||||||
|
epd->setFont(&DSEG7Classic_BoldItalic20pt7b);
|
||||||
|
epd->setCursor(295, 270);
|
||||||
|
epd->print(svalue5); // Value
|
||||||
|
epd->setFont(&Ubuntu_Bold12pt8b);
|
||||||
|
epd->setCursor(335, 220);
|
||||||
|
epd->print(name5); // Name
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
epd->setCursor(335, 190);
|
||||||
|
epd->print(" ");
|
||||||
|
epd->print(holdvalues ? unit5old : unit5);
|
||||||
|
|
||||||
//*******************************************************************************************
|
//*******************************************************************************************
|
||||||
|
|
||||||
// Draw wind rose
|
// Draw wind rose
|
||||||
int rInstrument = 110; // Radius of grafic instrument
|
int rInstrument = 110; // Radius of grafic instrument
|
||||||
|
|
||||||
getdisplay().fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle
|
epd->fillCircle(200, 150, rInstrument + 10, commonData->fgcolor); // Outer circle
|
||||||
getdisplay().fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle
|
epd->fillCircle(200, 150, rInstrument + 7, commonData->bgcolor); // Outer circle
|
||||||
getdisplay().fillCircle(200, 150, rInstrument - 10, commonData->fgcolor); // Inner circle
|
epd->fillCircle(200, 150, rInstrument - 10, commonData->fgcolor); // Inner circle
|
||||||
getdisplay().fillCircle(200, 150, rInstrument - 13, commonData->bgcolor); // Inner circle
|
epd->fillCircle(200, 150, rInstrument - 13, commonData->bgcolor); // Inner circle
|
||||||
|
|
||||||
for(int i=0; i<360; i=i+10)
|
for(int i=0; i<360; i=i+10)
|
||||||
{
|
{
|
||||||
@@ -267,17 +283,17 @@ public:
|
|||||||
// Print text centered on position x, y
|
// Print text centered on position x, y
|
||||||
int16_t x1, y1; // Return values of getTextBounds
|
int16_t x1, y1; // Return values of getTextBounds
|
||||||
uint16_t w, h; // Return values of getTextBounds
|
uint16_t w, h; // Return values of getTextBounds
|
||||||
getdisplay().getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string
|
epd->getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string
|
||||||
getdisplay().setCursor(x-w/2, y+h/2);
|
epd->setCursor(x-w/2, y+h/2);
|
||||||
if(i % 30 == 0){
|
if(i % 30 == 0){
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().print(ii);
|
epd->print(ii);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw sub scale with dots
|
// Draw sub scale with dots
|
||||||
float x1c = 200 + rInstrument*sin(i/180.0*M_PI);
|
float x1c = 200 + rInstrument*sin(i/180.0*M_PI);
|
||||||
float y1c = 150 - rInstrument*cos(i/180.0*M_PI);
|
float y1c = 150 - rInstrument*cos(i/180.0*M_PI);
|
||||||
getdisplay().fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor);
|
epd->fillCircle((int)x1c, (int)y1c, 2, commonData->fgcolor);
|
||||||
float sinx=sin(i/180.0*M_PI);
|
float sinx=sin(i/180.0*M_PI);
|
||||||
float cosx=cos(i/180.0*M_PI);
|
float cosx=cos(i/180.0*M_PI);
|
||||||
|
|
||||||
@@ -288,10 +304,10 @@ public:
|
|||||||
float xx2 = +dx;
|
float xx2 = +dx;
|
||||||
float yy1 = -(rInstrument-10);
|
float yy1 = -(rInstrument-10);
|
||||||
float yy2 = -(rInstrument+10);
|
float yy2 = -(rInstrument+10);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),commonData->fgcolor);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),
|
200+(int)(cosx*xx1-sinx*yy2),150+(int)(sinx*xx1+cosx*yy2),
|
||||||
200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*xx2-sinx*yy2),150+(int)(sinx*xx2+cosx*yy2),commonData->fgcolor);
|
||||||
}
|
}
|
||||||
@@ -308,7 +324,7 @@ public:
|
|||||||
float xx2 = startwidth;
|
float xx2 = startwidth;
|
||||||
float yy1 = -startwidth;
|
float yy1 = -startwidth;
|
||||||
float yy2 = -(rInstrument-15);
|
float yy2 = -(rInstrument-15);
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
epd->fillTriangle(200+(int)(cosx*xx1-sinx*yy1),150+(int)(sinx*xx1+cosx*yy1),
|
||||||
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
200+(int)(cosx*xx2-sinx*yy1),150+(int)(sinx*xx2+cosx*yy1),
|
||||||
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*yy2),150+(int)(sinx*0+cosx*yy2),commonData->fgcolor);
|
||||||
// Inverted pointer
|
// Inverted pointer
|
||||||
@@ -318,36 +334,49 @@ public:
|
|||||||
float ix2 = -endwidth;
|
float ix2 = -endwidth;
|
||||||
float iy1 = -(rInstrument-15);
|
float iy1 = -(rInstrument-15);
|
||||||
float iy2 = -endwidth;
|
float iy2 = -endwidth;
|
||||||
getdisplay().fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1),
|
epd->fillTriangle(200+(int)(cosx*ix1-sinx*iy1),150+(int)(sinx*ix1+cosx*iy1),
|
||||||
200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1),
|
200+(int)(cosx*ix2-sinx*iy1),150+(int)(sinx*ix2+cosx*iy1),
|
||||||
200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor);
|
200+(int)(cosx*0-sinx*iy2),150+(int)(sinx*0+cosx*iy2),commonData->fgcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Center circle
|
// Center circle
|
||||||
getdisplay().fillCircle(200, 150, startwidth + 6, commonData->bgcolor);
|
epd->fillCircle(200, 150, startwidth + 6, commonData->bgcolor);
|
||||||
getdisplay().fillCircle(200, 150, startwidth + 4, commonData->fgcolor);
|
epd->fillCircle(200, 150, startwidth + 4, commonData->fgcolor);
|
||||||
|
|
||||||
//*******************************************************************************************
|
//*******************************************************************************************
|
||||||
|
|
||||||
// Show value6, so that it does not collide with the wind pointer
|
// Show value6 (=fourth user-configured parameter) and ssource, so that they do not collide with the wind pointer
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic16pt7b);
|
|
||||||
if (cos(value1) > 0) {
|
if (cos(value1) > 0) {
|
||||||
getdisplay().setCursor(160, 200);
|
// pointer points upwards
|
||||||
getdisplay().print(svalue6); // Value
|
epd->setFont(&DSEG7Classic_BoldItalic16pt7b);
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setCursor(160, 200);
|
||||||
getdisplay().setCursor(190, 215);
|
epd->print(svalue6); // Value
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
epd->setCursor(190, 215);
|
||||||
|
epd->print(" ");
|
||||||
|
epd->print(holdvalues ? unit6old : unit6);
|
||||||
|
if (sin(value1) > 0) {
|
||||||
|
epd->setCursor(160, 130);
|
||||||
} else {
|
} else {
|
||||||
getdisplay().setCursor(160, 130);
|
epd->setCursor(220, 130);
|
||||||
getdisplay().print(svalue6); // Value
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
|
||||||
getdisplay().setCursor(190, 90);
|
|
||||||
}
|
}
|
||||||
getdisplay().print(" ");
|
epd->print(ssource); // true or app.
|
||||||
if(holdvalues == false){
|
|
||||||
getdisplay().print(unit6); // Unit
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
getdisplay().print(unit6old); // Unit
|
// pointer points downwards
|
||||||
|
epd->setFont(&DSEG7Classic_BoldItalic16pt7b);
|
||||||
|
epd->setCursor(160, 130);
|
||||||
|
epd->print(svalue6);
|
||||||
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
|
epd->setCursor(190, 90);
|
||||||
|
epd->print(" ");
|
||||||
|
epd->print(holdvalues ? unit6old : unit6);
|
||||||
|
if (sin(value1) > 0) {
|
||||||
|
epd->setCursor(160, 200);
|
||||||
|
} else {
|
||||||
|
epd->setCursor(220, 200);
|
||||||
|
}
|
||||||
|
epd->print(ssource); //true or app.
|
||||||
}
|
}
|
||||||
|
|
||||||
return PAGE_UPDATE;
|
return PAGE_UPDATE;
|
||||||
@@ -361,13 +390,14 @@ static Page *createPage(CommonData &common){
|
|||||||
* with the code below we make this page known to the PageTask
|
* with the code below we make this page known to the PageTask
|
||||||
* we give it a type (name) that can be selected in the config
|
* we give it a type (name) that can be selected in the config
|
||||||
* we define which function is to be called
|
* we define which function is to be called
|
||||||
* and we provide the number of user parameters we expect (0 here)
|
* and we provide the number of user parameters we expect (4 here)
|
||||||
* and will will provide the names of the fixed values we need
|
* and will will provide the names of the fixed values we need
|
||||||
*/
|
*/
|
||||||
PageDescription registerPageWindRoseFlex(
|
PageDescription registerPageWindRoseFlex(
|
||||||
"WindRoseFlex", // Page name
|
"WindRoseFlex", // Page name
|
||||||
createPage, // Action
|
createPage, // Action
|
||||||
6, // Number of bus values depends on selection in Web configuration; was zero
|
4, // Number of bus values depends on selection in Web configuration
|
||||||
|
{"AWA", "AWS", "TWA", "TWS"}, // fixed values we need in the page. They are inserted AFTER the web-configured values.
|
||||||
true // Show display header on/off
|
true // Show display header on/off
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
|
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
@@ -28,15 +29,18 @@ static unsigned char ship_bits[] PROGMEM = {
|
|||||||
|
|
||||||
class PageXTETrack : public Page
|
class PageXTETrack : public Page
|
||||||
{
|
{
|
||||||
bool simulation = false;
|
private:
|
||||||
bool holdvalues = false;
|
String trackStep;
|
||||||
|
double seg_step;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageXTETrack(CommonData &common){
|
PageXTETrack(CommonData &common) : Page(common)
|
||||||
commonData = &common;
|
{
|
||||||
common.logger->logDebug(GwLog::LOG,"Instantiate PageXTETrack");
|
logger->logDebug(GwLog::LOG, "Instantiate PageXTETrack");
|
||||||
simulation = common.config->getBool(common.config->useSimuData);
|
|
||||||
holdvalues = common.config->getBool(common.config->holdvalues);
|
// Get config data
|
||||||
|
String trackStep = config->getString(config->trackStep);
|
||||||
|
seg_step = trackStep.toDouble() * M_PI / 180;
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawSegment(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,
|
void drawSegment(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,
|
||||||
@@ -45,18 +49,18 @@ class PageXTETrack : public Page
|
|||||||
if (fill == true) {
|
if (fill == true) {
|
||||||
// no primitive for quadrangular object
|
// no primitive for quadrangular object
|
||||||
// we create it from 2 triangles
|
// we create it from 2 triangles
|
||||||
getdisplay().fillTriangle(x0, y0, x1, y1, x3, y3, color);
|
epd->fillTriangle(x0, y0, x1, y1, x3, y3, color);
|
||||||
getdisplay().fillTriangle(x1, y1, x2, y2, x3, y3, color);
|
epd->fillTriangle(x1, y1, x2, y2, x3, y3, color);
|
||||||
} else {
|
} else {
|
||||||
// draw outline
|
// draw outline
|
||||||
getdisplay().drawLine(x0, y0, x1, y1, color);
|
epd->drawLine(x0, y0, x1, y1, color);
|
||||||
getdisplay().drawLine(x1, y1, x2, y2, color);
|
epd->drawLine(x1, y1, x2, y2, color);
|
||||||
getdisplay().drawLine(x2, y2, x3, y3, color);
|
epd->drawLine(x2, y2, x3, y3, color);
|
||||||
getdisplay().drawLine(x3, y3, x0, y0, color);
|
epd->drawLine(x3, y3, x0, y0, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int handleKey(int key){
|
int handleKey(int key) {
|
||||||
// Code for keylock
|
// Code for keylock
|
||||||
if(key == 11){
|
if(key == 11){
|
||||||
commonData->keylock = !commonData->keylock;
|
commonData->keylock = !commonData->keylock;
|
||||||
@@ -65,96 +69,93 @@ class PageXTETrack : public Page
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
int displayPage(PageData &pageData){
|
void displayNew(PageData &pageData) {
|
||||||
GwConfigHandler *config = commonData->config;
|
#ifdef BOARD_OBP60S3
|
||||||
GwLog *logger = commonData->logger;
|
// Clear optical warning
|
||||||
|
if (flashLED == "Limit Violation") {
|
||||||
// Get config data
|
|
||||||
String flashLED = config->getString(config->flashLED);
|
|
||||||
String backlightMode = config->getString(config->backlight);
|
|
||||||
|
|
||||||
String trackStep = config->getString(config->trackStep);
|
|
||||||
double seg_step = trackStep.toFloat() * PI / 180;
|
|
||||||
|
|
||||||
// Optical warning by limit violation (unused)
|
|
||||||
if(String(flashLED) == "Limit Violation"){
|
|
||||||
setBlinkingLED(false);
|
setBlinkingLED(false);
|
||||||
setFlashLED(false);
|
setFlashLED(false);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int displayPage(PageData &pageData) {
|
||||||
|
|
||||||
// Logging boat values
|
// Logging boat values
|
||||||
LOG_DEBUG(GwLog::LOG,"Drawing at PageXTETrack");
|
logger->logDebug(GwLog::LOG, "Drawing at PageXTETrack");
|
||||||
|
|
||||||
// Draw page
|
// Draw page
|
||||||
//***********************************************************
|
//***********************************************************
|
||||||
|
|
||||||
// Set display in partial refresh mode
|
// Set display in partial refresh mode
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
|
|
||||||
getdisplay().setTextColor(commonData->fgcolor);
|
epd->setTextColor(commonData->fgcolor);
|
||||||
|
|
||||||
// descriptions
|
// descriptions
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(50, 188);
|
epd->setCursor(50, 188);
|
||||||
getdisplay().print("Cross-track error");
|
epd->print("Cross-track error");
|
||||||
getdisplay().setCursor(270, 188);
|
epd->setCursor(270, 188);
|
||||||
getdisplay().print("Track");
|
epd->print("Track");
|
||||||
getdisplay().setCursor(45, 275);
|
epd->setCursor(45, 275);
|
||||||
getdisplay().print("Distance to waypoint");
|
epd->print("Distance to waypoint");
|
||||||
getdisplay().setCursor(260, 275);
|
epd->setCursor(260, 275);
|
||||||
getdisplay().print("Bearing");
|
epd->print("Bearing");
|
||||||
|
|
||||||
// values
|
// values
|
||||||
getdisplay().setFont(&DSEG7Classic_BoldItalic30pt7b);
|
epd->setFont(&DSEG7Classic_BoldItalic30pt7b);
|
||||||
|
|
||||||
int16_t x, y;
|
int16_t x, y;
|
||||||
uint16_t w, h;
|
uint16_t w, h;
|
||||||
|
|
||||||
GwApi::BoatValue *bv_xte = pageData.values[0]; // XTE
|
GwApi::BoatValue *bv_xte = pageData.values[0]; // XTE
|
||||||
String sval_xte = formatValue(bv_xte, *commonData).svalue;
|
String sval_xte = commonData->fmt->formatValue(bv_xte, *commonData).svalue;
|
||||||
getdisplay().getTextBounds(sval_xte, 0, 0, &x, &y, &w, &h);
|
epd->getTextBounds(sval_xte, 0, 0, &x, &y, &w, &h);
|
||||||
getdisplay().setCursor(160-w, 170);
|
epd->setCursor(160-w, 170);
|
||||||
getdisplay().print(sval_xte);
|
epd->print(sval_xte);
|
||||||
|
|
||||||
GwApi::BoatValue *bv_cog = pageData.values[1]; // COG
|
GwApi::BoatValue *bv_cog = pageData.values[1]; // COG
|
||||||
String sval_cog = formatValue(bv_cog, *commonData).svalue;
|
String sval_cog = commonData->fmt->formatValue(bv_cog, *commonData).svalue;
|
||||||
getdisplay().getTextBounds(sval_cog, 0, 0, &x, &y, &w, &h);
|
epd->getTextBounds(sval_cog, 0, 0, &x, &y, &w, &h);
|
||||||
getdisplay().setCursor(360-w, 170);
|
epd->setCursor(360-w, 170);
|
||||||
getdisplay().print(sval_cog);
|
epd->print(sval_cog);
|
||||||
|
|
||||||
GwApi::BoatValue *bv_dtw = pageData.values[2]; // DTW
|
GwApi::BoatValue *bv_dtw = pageData.values[2]; // DTW
|
||||||
String sval_dtw = formatValue(bv_dtw, *commonData).svalue;
|
String sval_dtw = commonData->fmt->formatValue(bv_dtw, *commonData).svalue;
|
||||||
getdisplay().getTextBounds(sval_dtw, 0, 0, &x, &y, &w, &h);
|
epd->getTextBounds(sval_dtw, 0, 0, &x, &y, &w, &h);
|
||||||
getdisplay().setCursor(160-w, 257);
|
epd->setCursor(160-w, 257);
|
||||||
getdisplay().print(sval_dtw);
|
epd->print(sval_dtw);
|
||||||
|
|
||||||
GwApi::BoatValue *bv_btw = pageData.values[3]; // BTW
|
GwApi::BoatValue *bv_btw = pageData.values[3]; // BTW
|
||||||
String sval_btw = formatValue(bv_btw, *commonData).svalue;
|
String sval_btw = commonData->fmt->formatValue(bv_btw, *commonData).svalue;
|
||||||
getdisplay().getTextBounds(sval_btw, 0, 0, &x, &y, &w, &h);
|
epd->getTextBounds(sval_btw, 0, 0, &x, &y, &w, &h);
|
||||||
getdisplay().setCursor(360-w, 257);
|
epd->setCursor(360-w, 257);
|
||||||
getdisplay().print(sval_btw);
|
epd->print(sval_btw);
|
||||||
|
|
||||||
|
GwApi::BoatValue *bv_wpname = pageData.values[4]; // WPName
|
||||||
|
|
||||||
bool valid = bv_cog->valid && bv_btw->valid;
|
bool valid = bv_cog->valid && bv_btw->valid;
|
||||||
|
|
||||||
// XTETrack view
|
// XTETrack view
|
||||||
|
|
||||||
// draw ship symbol (as bitmap)
|
// draw ship symbol (as bitmap)
|
||||||
getdisplay().drawXBitmap(184, 68, ship_bits, ship_width, ship_height, commonData->fgcolor);
|
epd->drawXBitmap(184, 68, ship_bits, ship_width, ship_height, commonData->fgcolor);
|
||||||
|
|
||||||
// draw next waypoint name
|
// draw next waypoint name
|
||||||
String sval_wpname = "no data";
|
String sval_wpname = "no data";
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
sval_wpname = "Tonne 122";
|
sval_wpname = bv_wpname->svalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
getdisplay().setFont(&Ubuntu_Bold10pt8b);
|
epd->setFont(&Ubuntu_Bold10pt8b);
|
||||||
getdisplay().getTextBounds(sval_wpname, 0, 150, &x, &y, &w, &h);
|
epd->getTextBounds(sval_wpname, 0, 150, &x, &y, &w, &h);
|
||||||
// TODO if text don't fix use smaller font size.
|
// TODO if text don't fix use smaller font size.
|
||||||
// if smallest size does not fit use 2 lines
|
// if smallest size does not fit use 2 lines
|
||||||
// last resort: clip with ellipsis
|
// last resort: clip with ellipsis
|
||||||
getdisplay().setCursor(200 - w / 2, 60);
|
epd->setCursor(200 - w / 2, 60);
|
||||||
getdisplay().print(sval_wpname);
|
epd->print(sval_wpname);
|
||||||
|
|
||||||
// draw course segments
|
// draw course segments
|
||||||
|
|
||||||
@@ -226,7 +227,7 @@ PageDescription registerPageXTETrack(
|
|||||||
"XTETrack", // Page name
|
"XTETrack", // Page name
|
||||||
createPage, // Action
|
createPage, // Action
|
||||||
0, // Number of bus values depends on selection in Web configuration
|
0, // Number of bus values depends on selection in Web configuration
|
||||||
{"XTE", "COG", "DTW", "BTW"}, // Bus values we need in the page
|
{"XTE", "COG", "DTW", "BTW", "WPName"}, // Bus values we need in the page
|
||||||
true // Show display header on/off
|
true // Show display header on/off
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "GwApi.h"
|
#include "GwApi.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "LedSpiTask.h"
|
#include "LedSpiTask.h"
|
||||||
#include "OBPRingBuffer.h"
|
|
||||||
#include "OBPDataOperations.h"
|
#include "OBPDataOperations.h"
|
||||||
|
|
||||||
#define MAX_PAGE_NUMBER 10 // Max number of pages for show data
|
#define MAX_PAGE_NUMBER 10 // Max number of pages for show data
|
||||||
@@ -12,11 +13,12 @@
|
|||||||
typedef std::vector<GwApi::BoatValue *> ValueList;
|
typedef std::vector<GwApi::BoatValue *> ValueList;
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
|
GwApi *api;
|
||||||
String pageName;
|
String pageName;
|
||||||
uint8_t pageNumber; // page number in sequence of visible pages
|
uint8_t pageNumber; // page number in sequence of visible pages
|
||||||
//the values will always contain the user defined values first
|
//the values will always contain the user defined values first
|
||||||
ValueList values;
|
ValueList values;
|
||||||
tBoatHstryData boatHstry;
|
HstryBuf* boatHstry;
|
||||||
} PageData;
|
} PageData;
|
||||||
|
|
||||||
// Sensor data structure (only for extended sensors, not for NMEA bus sensors)
|
// Sensor data structure (only for extended sensors, not for NMEA bus sensors)
|
||||||
@@ -98,17 +100,24 @@ typedef struct{
|
|||||||
uint8_t length_sec; // seconds until alarm disappeares without user interaction
|
uint8_t length_sec; // seconds until alarm disappeares without user interaction
|
||||||
} AlarmData;
|
} AlarmData;
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
int voltage = 0;
|
||||||
|
} AvgData;
|
||||||
|
|
||||||
|
class Formatter; // forward declaration
|
||||||
typedef struct{
|
typedef struct{
|
||||||
GwApi::Status status;
|
GwApi::Status status;
|
||||||
GwLog *logger=NULL;
|
GwLog *logger = nullptr;
|
||||||
GwConfigHandler *config=NULL;
|
GwConfigHandler *config = nullptr;
|
||||||
|
Formatter *fmt = nullptr;
|
||||||
SensorData data;
|
SensorData data;
|
||||||
SunData sundata;
|
SunData sundata;
|
||||||
TouchKeyData keydata[6];
|
TouchKeyData keydata[6];
|
||||||
BacklightData backlight;
|
BacklightData backlight;
|
||||||
AlarmData alarm;
|
AlarmData alarm;
|
||||||
GwApi::BoatValue *time=NULL;
|
AvgData avgdata;
|
||||||
GwApi::BoatValue *date=NULL;
|
GwApi::BoatValue *time = nullptr;
|
||||||
|
GwApi::BoatValue *date = nullptr;
|
||||||
uint16_t fgcolor;
|
uint16_t fgcolor;
|
||||||
uint16_t bgcolor;
|
uint16_t bgcolor;
|
||||||
bool keylock = false;
|
bool keylock = false;
|
||||||
@@ -118,11 +127,29 @@ typedef struct{
|
|||||||
//a base class that all pages must inherit from
|
//a base class that all pages must inherit from
|
||||||
class Page{
|
class Page{
|
||||||
protected:
|
protected:
|
||||||
|
// TODO Future: GwApi *api;
|
||||||
CommonData *commonData;
|
CommonData *commonData;
|
||||||
|
GwConfigHandler *config;
|
||||||
|
GwLog *logger;
|
||||||
|
bool simulation = false;
|
||||||
|
bool holdvalues = false;
|
||||||
|
String flashLED;
|
||||||
|
String backlightMode;
|
||||||
public:
|
public:
|
||||||
|
Page(CommonData &common) {
|
||||||
|
commonData = &common;
|
||||||
|
config = commonData->config;
|
||||||
|
logger = commonData->logger;
|
||||||
|
// preload generic configuration data
|
||||||
|
simulation = config->getBool(config->useSimuData);
|
||||||
|
holdvalues = config->getBool(config->holdvalues);
|
||||||
|
flashLED = config->getString(config->flashLED);
|
||||||
|
backlightMode = config->getString(config->backlight);
|
||||||
|
}
|
||||||
int refreshtime = 1000;
|
int refreshtime = 1000;
|
||||||
virtual int displayPage(PageData &pageData)=0;
|
virtual int displayPage(PageData &pageData)=0;
|
||||||
virtual void displayNew(PageData &pageData){}
|
virtual void displayNew(PageData &pageData){}
|
||||||
|
virtual void leavePage(PageData &pageData){}
|
||||||
virtual void setupKeys() {
|
virtual void setupKeys() {
|
||||||
#ifdef HARDWARE_V21
|
#ifdef HARDWARE_V21
|
||||||
commonData->keydata[0].label = "";
|
commonData->keydata[0].label = "";
|
||||||
@@ -181,23 +208,7 @@ class PageDescription{
|
|||||||
|
|
||||||
class PageStruct{
|
class PageStruct{
|
||||||
public:
|
public:
|
||||||
Page *page=NULL;
|
Page *page = nullptr;
|
||||||
PageData parameters;
|
PageData parameters;
|
||||||
PageDescription *description=NULL;
|
PageDescription *description = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Standard format functions without overhead
|
|
||||||
String formatDate(String fmttype, uint16_t year, uint8_t month, uint8_t day);
|
|
||||||
String formatTime(char fmttype, uint8_t hour, uint8_t minute, uint8_t second);
|
|
||||||
String formatLatitude(double lat);
|
|
||||||
String formatLongitude(double lon);
|
|
||||||
|
|
||||||
// Structure for formatted boat values
|
|
||||||
typedef struct{
|
|
||||||
double value;
|
|
||||||
String svalue;
|
|
||||||
String unit;
|
|
||||||
} FormattedData;
|
|
||||||
|
|
||||||
// Formatter for boat values
|
|
||||||
FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata);
|
|
||||||
|
|||||||
97
lib/obp60task/README
Normal file
97
lib/obp60task/README
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
Development information
|
||||||
|
=======================
|
||||||
|
|
||||||
|
This file contains some hints concerning building the firmware as well as
|
||||||
|
developing and debugging it.
|
||||||
|
|
||||||
|
Coding style
|
||||||
|
------------
|
||||||
|
WIP
|
||||||
|
Please format your new code the same as already existing code.
|
||||||
|
|
||||||
|
Some rules:
|
||||||
|
- Preprocessor directives go to column zero
|
||||||
|
- Identation is 4 spaces
|
||||||
|
|
||||||
|
Git commands
|
||||||
|
------------
|
||||||
|
Some useful commands are
|
||||||
|
|
||||||
|
git status
|
||||||
|
git fetch upstream
|
||||||
|
git diff --name-status upstream/master
|
||||||
|
git checkout upstream/master platformio.ini
|
||||||
|
|
||||||
|
# how to reset my Repo to match norbert's status
|
||||||
|
|
||||||
|
git remote add upstream https://github.com/norbert-walter/esp32-nmea2000-obp60
|
||||||
|
git fetch upstream
|
||||||
|
git checkout master
|
||||||
|
git reset --hard upstream/master
|
||||||
|
git push origin master --force
|
||||||
|
|
||||||
|
|
||||||
|
New pages
|
||||||
|
---------
|
||||||
|
To create a new page for OBP60 the following steps are necessary:
|
||||||
|
|
||||||
|
1. Create a page under /lib/obp60task/PageXXXX.cpp. You can use a simple
|
||||||
|
page e.g. PageOneValue.cpp as template
|
||||||
|
2. Set page name in PageXXXX.cpp on file name
|
||||||
|
3. Register new page in /lib/obp60task/obp60task.cpp in function
|
||||||
|
'registerAllPages'
|
||||||
|
4. Add new page in /lib/obp60task/config.json for each page type
|
||||||
|
or use gen_set.py to auto-generate the relevant section of
|
||||||
|
config.json. For further information on that read the comments
|
||||||
|
in gen_set.py.
|
||||||
|
5. Copy the changes in config.json to config_obp40.json and rename
|
||||||
|
strings accordingly. E.g. obp60 to obp40.
|
||||||
|
|
||||||
|
Using Gitpod
|
||||||
|
------------
|
||||||
|
|
||||||
|
Warning: You have to register with gitpod!
|
||||||
|
|
||||||
|
Open web page:
|
||||||
|
https://gitpod.io/#https://github.com/norbert-walter/esp32-nmea2000-obp60/tree/master/lib/obp60task
|
||||||
|
|
||||||
|
Input in terminal:
|
||||||
|
cd /workspace/esp32-nmea2000-obp60
|
||||||
|
bash /workspace/esp32-nmea2000-obp60/lib/obp60task/run_installing_tools
|
||||||
|
bash /workspace/esp32-nmea2000-obp60/lib/obp60task/run_obp60_s3
|
||||||
|
bash /workspace/esp32-nmea2000-obp60/lib/obp60task/run_obp40_s3
|
||||||
|
|
||||||
|
Compile result for OBP60:
|
||||||
|
/workspace/esp32-nmea2000-obp60/.pio/build/obp60_s3/bootloader.bin
|
||||||
|
/workspace/esp32-nmea2000-obp60/.pio/build/obp60_s3/firmware.bin
|
||||||
|
/workspace/esp32-nmea2000-obp60/.pio/build/obp60_s3/partitions.bin
|
||||||
|
|
||||||
|
/workspace/esp32-nmea2000-obp60/.pio/build/obp60_s3/obp60_s3-all.bin
|
||||||
|
/workspace/esp32-nmea2000-obp60/.pio/build/obp60_s3/obp60_s3-dev<yyyymmdd>-all.bin
|
||||||
|
/workspace/esp32-nmea2000-obp60/.pio/build/obp60_s3/obp60_s3-dev<yyyymmdd>-update.bin
|
||||||
|
|
||||||
|
/workspace/esp32-nmea2000-obp60/.pio/build/obp60_s3/obp60_s3-all.bin, ready to flash to offset 0x0000
|
||||||
|
|
||||||
|
Compile result for OBP40 (CrowPanel 4.2):
|
||||||
|
|
||||||
|
/workspace/esp32-nmea2000-obp60/.pio/build/obp40_s3/bootloader.bin
|
||||||
|
/workspace/esp32-nmea2000-obp60/.pio/build/obp40_s3/firmware.bin
|
||||||
|
/workspace/esp32-nmea2000-obp60/.pio/build/obp40_s3/partitions.bin
|
||||||
|
|
||||||
|
/workspace/esp32-nmea2000-obp60/.pio/build/obp40_s3/obp40_s3-all.bin
|
||||||
|
/workspace/esp32-nmea2000-obp60/.pio/build/obp40_s3/obp40_s3-dev<yyyymmdd>-all.bin
|
||||||
|
/workspace/esp32-nmea2000-obp60/.pio/build/obp40_s3/obp40_s3-dev<yyyymmdd>-update.bin
|
||||||
|
|
||||||
|
/workspace/esp32-nmea2000-obp60/.pio/build/obp40_s3/obp40_s3-all.bin, ready to flash to offset 0x0000
|
||||||
|
|
||||||
|
Compilation issues
|
||||||
|
------------------
|
||||||
|
? Error while linking: "undefined reference to `registerPageXXX'"
|
||||||
|
: Check if the required page is enabled for current board/environment: #if defined ...
|
||||||
|
|
||||||
|
Debugging tool
|
||||||
|
--------------
|
||||||
|
|
||||||
|
log.txt = text file with error messages from terminal console
|
||||||
|
|
||||||
|
tools/decoder.py -p ESP32S3 -t ~/.platformio/packages/toolchain-xtensa-esp32s3/ -e .pio/build/obp60_s3/firmware.elf log.txt
|
||||||
19
lib/obp60task/TODO
Normal file
19
lib/obp60task/TODO
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
- fix unstable accesspoint availability
|
||||||
|
|
||||||
|
- page refresh after page change and not connected to key codes
|
||||||
|
|
||||||
|
- config: getFloat, getDouble
|
||||||
|
|
||||||
|
- dseg7 font to new version
|
||||||
|
|
||||||
|
- new pages: ais, autopilot, epropulsion
|
||||||
|
|
||||||
|
- automate config.json generation with extra_task.py
|
||||||
|
|
||||||
|
- extend boatdata: ais, waypoints, alarms
|
||||||
|
|
||||||
|
- page clock: sunrise / sunset in local time or UTC
|
||||||
|
|
||||||
|
- implement alerts
|
||||||
|
|
||||||
|
- implement formatter as class
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
Using Gitpod
|
|
||||||
############
|
|
||||||
|
|
||||||
Open web page:
|
|
||||||
https://gitpod.io/#https://github.com/norbert-walter/esp32-nmea2000-obp60/tree/master/lib/obp60task
|
|
||||||
|
|
||||||
Input in terminal:
|
|
||||||
cd /workspace/esp32-nmea2000-obp60
|
|
||||||
bash /workspace/esp32-nmea2000-obp60/lib/obp60task/run_installing_tools
|
|
||||||
bash /workspace/esp32-nmea2000-obp60/lib/obp60task/run_obp60_s3
|
|
||||||
bash /workspace/esp32-nmea2000-obp60/lib/obp60task/run_obp40_s3
|
|
||||||
|
|
||||||
Compile result for OBP60
|
|
||||||
########################
|
|
||||||
|
|
||||||
/workspace/esp32-nmea2000-obp60/.pio/build/obp60_s3/bootloader.bin
|
|
||||||
/workspace/esp32-nmea2000-obp60/.pio/build/obp60_s3/firmware.bin
|
|
||||||
/workspace/esp32-nmea2000-obp60/.pio/build/obp60_s3/partitions.bin
|
|
||||||
|
|
||||||
/workspace/esp32-nmea2000-obp60/.pio/build/obp60_s3/obp60_s3-all.bin
|
|
||||||
/workspace/esp32-nmea2000-obp60/.pio/build/obp60_s3/obp60_s3-dev20231220-all.bin
|
|
||||||
/workspace/esp32-nmea2000-obp60/.pio/build/obp60_s3/obp60_s3-dev20231220-update.bin
|
|
||||||
|
|
||||||
/workspace/esp32-nmea2000-obp60/.pio/build/obp60_s3/obp60_s3-all.bin, ready to flash to offset 0x0000
|
|
||||||
|
|
||||||
Compile result for OBP40 (CrowPanel 4.2)
|
|
||||||
########################################
|
|
||||||
|
|
||||||
/workspace/esp32-nmea2000-obp60/.pio/build/obp40_s3/bootloader.bin
|
|
||||||
/workspace/esp32-nmea2000-obp60/.pio/build/obp40_s3/firmware.bin
|
|
||||||
/workspace/esp32-nmea2000-obp60/.pio/build/obp40_s3/partitions.bin
|
|
||||||
|
|
||||||
/workspace/esp32-nmea2000-obp60/.pio/build/obp40_s3/obp40_s3-all.bin
|
|
||||||
/workspace/esp32-nmea2000-obp60/.pio/build/obp40_s3/obp40_s3-dev20231220-all.bin
|
|
||||||
/workspace/esp32-nmea2000-obp60/.pio/build/obp40_s3/obp40_s3-dev20231220-update.bin
|
|
||||||
|
|
||||||
/workspace/esp32-nmea2000-obp60/.pio/build/obp40_s3/obp40_s3-all.bin, ready to flash to offset 0x0000
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
|||||||
Debugging tool
|
|
||||||
##############
|
|
||||||
|
|
||||||
log.txt = text file with error messages from terminal console
|
|
||||||
|
|
||||||
tools/decoder.py -p ESP32S3 -t ~/.platformio/packages/toolchain-xtensa-esp32s3/ -e .pio/build/obp60_s3/firmware.elf log.txt
|
|
||||||
@@ -28,3 +28,4 @@ except:
|
|||||||
env["CPPDEFINES"].extend([("BOARD", env["BOARD"]), ("EPDTYPE", epdtype), ("PCBVERS", pcbvers), ("GXEPD2VERS", gxepd2vers)])
|
env["CPPDEFINES"].extend([("BOARD", env["BOARD"]), ("EPDTYPE", epdtype), ("PCBVERS", pcbvers), ("GXEPD2VERS", gxepd2vers)])
|
||||||
|
|
||||||
print("added hardware info to CPPDEFINES")
|
print("added hardware info to CPPDEFINES")
|
||||||
|
print("friendly board name is '{}'".format(env.GetProjectOption("board_name")))
|
||||||
|
|||||||
273
lib/obp60task/fonts/Atari6px8b.h
Normal file
273
lib/obp60task/fonts/Atari6px8b.h
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
const uint8_t Atari6pxBitmaps[] PROGMEM = {
|
||||||
|
0x00, 0xF0, 0x30, 0xCF, 0x38, 0x80, 0x53, 0xF5, 0x14, 0xFD, 0x40, 0x7E,
|
||||||
|
0x47, 0x85, 0x13, 0xE1, 0x00, 0xC7, 0x21, 0x00, 0x4E, 0x30, 0x63, 0x26,
|
||||||
|
0x39, 0xC3, 0x26, 0x40, 0x6F, 0x00, 0x7B, 0x24, 0xC0, 0xCD, 0xA5, 0x80,
|
||||||
|
0x8B, 0x3E, 0x00, 0x44, 0x10, 0x4F, 0xC4, 0x10, 0x40, 0x6F, 0x00, 0xF8,
|
||||||
|
0xF0, 0x0C, 0x66, 0x18, 0x82, 0x00, 0x7A, 0x39, 0x58, 0x61, 0xE0, 0x75,
|
||||||
|
0x50, 0xF8, 0x17, 0xA0, 0x83, 0xF0, 0xF8, 0x17, 0x80, 0x07, 0xE0, 0x39,
|
||||||
|
0x28, 0xA2, 0xFC, 0x20, 0xFE, 0x0F, 0x80, 0x07, 0xE0, 0x7A, 0x0F, 0xC0,
|
||||||
|
0x01, 0xE0, 0xF8, 0x44, 0x02, 0x10, 0x7A, 0x17, 0x80, 0x85, 0xE0, 0x7A,
|
||||||
|
0x17, 0xC0, 0x01, 0xE0, 0xF0, 0xF0, 0xF3, 0x58, 0x1B, 0x30, 0x42, 0x0C,
|
||||||
|
0xF8, 0x3E, 0xC3, 0x06, 0xC4, 0x60, 0x7A, 0x31, 0x86, 0x00, 0x01, 0x80,
|
||||||
|
0x7A, 0x19, 0xE6, 0x82, 0x07, 0xC0, 0x7A, 0x1F, 0xE1, 0x86, 0x10, 0xFA,
|
||||||
|
0x1F, 0xA0, 0x87, 0xE0, 0x7E, 0x08, 0x00, 0x01, 0xF0, 0xFA, 0x18, 0x60,
|
||||||
|
0x83, 0xE0, 0xFE, 0x0F, 0xA0, 0x83, 0xF0, 0xFE, 0x0F, 0xA0, 0x82, 0x00,
|
||||||
|
0x7E, 0x08, 0xC1, 0x05, 0xF0, 0x86, 0x1F, 0xE1, 0x86, 0x10, 0xF4, 0x44,
|
||||||
|
0x4F, 0x04, 0x10, 0x41, 0x85, 0xE0, 0x8C, 0xB9, 0x09, 0x44, 0x84, 0x21,
|
||||||
|
0x08, 0x7C, 0x83, 0xDE, 0x4C, 0x18, 0x30, 0x40, 0x83, 0xC6, 0x4C, 0x18,
|
||||||
|
0xF0, 0x40, 0x7A, 0x18, 0x40, 0x01, 0xE0, 0xFA, 0x1F, 0xA0, 0x82, 0x00,
|
||||||
|
0x7A, 0x18, 0x40, 0x01, 0xE0, 0xC0, 0xFA, 0x1F, 0xA4, 0x92, 0x30, 0x7E,
|
||||||
|
0x07, 0x80, 0x07, 0xE0, 0xFC, 0x41, 0x04, 0x10, 0x40, 0x86, 0x18, 0x61,
|
||||||
|
0x85, 0xE0, 0x86, 0x10, 0x00, 0x48, 0x40, 0x83, 0x06, 0x4C, 0x1E, 0xF0,
|
||||||
|
0x40, 0x85, 0x21, 0x00, 0x4A, 0x10, 0x86, 0x14, 0x80, 0x10, 0x40, 0xFC,
|
||||||
|
0x21, 0x10, 0x43, 0xF0, 0xFC, 0xCC, 0xCF, 0xC1, 0x81, 0x86, 0x04, 0x10,
|
||||||
|
0xF3, 0x33, 0x3F, 0x11, 0xEC, 0xC0, 0xFC, 0xD9, 0x80, 0x78, 0x10, 0x7F,
|
||||||
|
0x7C, 0x83, 0xE8, 0x61, 0x83, 0xE0, 0x7E, 0x08, 0x00, 0x7C, 0x05, 0xF8,
|
||||||
|
0x61, 0x05, 0xF0, 0x7B, 0xF8, 0x00, 0x78, 0x1A, 0x3E, 0x84, 0x20, 0x7E,
|
||||||
|
0x17, 0xC1, 0x07, 0xE0, 0x81, 0x33, 0x8C, 0x18, 0x30, 0x40, 0xC4, 0x44,
|
||||||
|
0xF0, 0x08, 0x42, 0x10, 0x87, 0xC0, 0x82, 0x2F, 0x20, 0x8A, 0x10, 0xC4,
|
||||||
|
0x44, 0x4F, 0x4B, 0xF9, 0x61, 0x84, 0xFA, 0x18, 0x61, 0x84, 0x7A, 0x18,
|
||||||
|
0x40, 0x78, 0xFA, 0x18, 0x60, 0xFA, 0x00, 0x7E, 0x18, 0x41, 0x7C, 0x10,
|
||||||
|
0xF4, 0x61, 0x08, 0x00, 0x7E, 0x00, 0x3F, 0x00, 0x4F, 0x44, 0x41, 0x86,
|
||||||
|
0x10, 0x41, 0x7C, 0x86, 0x10, 0x12, 0x10, 0x83, 0x26, 0x4C, 0x1E, 0xE0,
|
||||||
|
0x8B, 0x18, 0x08, 0x80, 0x86, 0x17, 0xC1, 0x07, 0xE0, 0xF8, 0x94, 0x8F,
|
||||||
|
0x80, 0x76, 0xC6, 0x67, 0xFF, 0xFC, 0xE6, 0x36, 0x6E, 0x41, 0x0B, 0x6F,
|
||||||
|
0x08, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD,
|
||||||
|
0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD,
|
||||||
|
0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD,
|
||||||
|
0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD,
|
||||||
|
0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD,
|
||||||
|
0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD,
|
||||||
|
0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD,
|
||||||
|
0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD,
|
||||||
|
0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD,
|
||||||
|
0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD,
|
||||||
|
0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD,
|
||||||
|
0xFC, 0x11, 0xEC, 0x71, 0xFC, 0x11, 0xEC, 0xC4, 0x10, 0x41, 0x00, 0x10,
|
||||||
|
0x40, 0x33, 0x49, 0xE1, 0x00, 0x08, 0x1B, 0xD8, 0x40, 0x81, 0x00, 0x10,
|
||||||
|
0xE3, 0x39, 0x01, 0x02, 0x00, 0x7A, 0x5E, 0xC4, 0x11, 0xE0, 0xFF, 0xEF,
|
||||||
|
0x3C, 0xC6, 0x30, 0xEE, 0x57, 0xA1, 0x87, 0xB0, 0x06, 0x1A, 0x64, 0x86,
|
||||||
|
0x08, 0x00, 0x7D, 0x06, 0x4C, 0xD8, 0x30, 0x5F, 0x00, 0x18, 0xF9, 0xF7,
|
||||||
|
0xF0, 0x00, 0x06, 0x00, 0x08, 0x30, 0x9E, 0x7B, 0xE6, 0x00, 0xF1, 0x03,
|
||||||
|
0xBC, 0x48, 0x81, 0x82, 0x00, 0xF1, 0x02, 0x77, 0xA1, 0x43, 0x85, 0x80,
|
||||||
|
0x12, 0x24, 0x48, 0x97, 0x3E, 0x70, 0x80, 0x92, 0x4D, 0xD8, 0xFF, 0x1C,
|
||||||
|
0x73, 0xCF, 0x3F, 0xC0, 0xC4, 0x4F, 0xFF, 0xF0, 0x7C, 0x1F, 0xF0, 0xC3,
|
||||||
|
0x0F, 0xC0, 0xF8, 0x2F, 0xC3, 0x0C, 0x3F, 0xC0, 0xC3, 0x0C, 0xFF, 0x0C,
|
||||||
|
0x30, 0xC0, 0xFB, 0x0F, 0xC3, 0x0C, 0x3F, 0xC0, 0xC3, 0x0F, 0xE3, 0xCF,
|
||||||
|
0x3F, 0xC0, 0xFC, 0x13, 0xCC, 0x30, 0xC3, 0x00, 0x71, 0x47, 0x37, 0xDF,
|
||||||
|
0x7F, 0xC0, 0xFF, 0x3C, 0x7F, 0x0C, 0x30, 0xC0, 0x78, 0x00, 0x7F, 0x78,
|
||||||
|
0xF0, 0x80, 0xEF, 0x88, 0x88, 0xF8, 0x0F, 0x1E, 0xFF, 0x84, 0x08, 0x1E,
|
||||||
|
0x26, 0x00, 0xF3, 0x20, 0xC1, 0x05, 0xF1, 0x40, 0x42, 0x2C, 0x50, 0x40,
|
||||||
|
0x1E, 0xF0, 0x00, 0x07, 0x24, 0x80, 0x93, 0x80, 0xFC, 0x7F, 0xDD, 0xFC,
|
||||||
|
0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC,
|
||||||
|
0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC,
|
||||||
|
0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC,
|
||||||
|
0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC,
|
||||||
|
0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC,
|
||||||
|
0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC,
|
||||||
|
0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC,
|
||||||
|
0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC,
|
||||||
|
0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC,
|
||||||
|
0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC, 0xFC, 0x7F, 0xDD, 0xFC,
|
||||||
|
0xFC, 0x7F, 0xDD, 0xFC };
|
||||||
|
|
||||||
|
const GFXglyph Atari6pxGlyphs[] PROGMEM = {
|
||||||
|
{ 0, 1, 1, 7, 0, 0 }, // 0x20 ' ' U+0020
|
||||||
|
{ 1, 2, 6, 6, 2, -5 }, // 0x21 '!' U+0021
|
||||||
|
{ 3, 6, 3, 7, 0, -5 }, // 0x22 '"' U+0022
|
||||||
|
{ 6, 6, 6, 7, 0, -5 }, // 0x23 '#' U+0023
|
||||||
|
{ 11, 6, 7, 7, 0, -5 }, // 0x24 '$' U+0024
|
||||||
|
{ 17, 6, 6, 7, 0, -5 }, // 0x25 '%' U+0025
|
||||||
|
{ 22, 6, 7, 7, 0, -6 }, // 0x26 '&' U+0026
|
||||||
|
{ 28, 3, 3, 6, 1, -5 }, // 0x27 ''' U+0027
|
||||||
|
{ 30, 3, 6, 6, 1, -5 }, // 0x28 '(' U+0028
|
||||||
|
{ 33, 3, 6, 6, 1, -5 }, // 0x29 ')' U+0029
|
||||||
|
{ 36, 5, 6, 7, 1, -5 }, // 0x2a '*' U+002A
|
||||||
|
{ 40, 6, 6, 7, 0, -5 }, // 0x2b '+' U+002B
|
||||||
|
{ 45, 3, 3, 6, 1, -1 }, // 0x2c ',' U+002C
|
||||||
|
{ 47, 5, 1, 7, 1, -3 }, // 0x2d '-' U+002D
|
||||||
|
{ 48, 2, 2, 6, 2, -1 }, // 0x2e '.' U+002E
|
||||||
|
{ 49, 6, 6, 7, 0, -5 }, // 0x2f '/' U+002F
|
||||||
|
{ 54, 6, 6, 7, 0, -5 }, // 0x30 '0' U+0030
|
||||||
|
{ 59, 2, 6, 7, 3, -5 }, // 0x31 '1' U+0031
|
||||||
|
{ 61, 6, 6, 7, 0, -5 }, // 0x32 '2' U+0032
|
||||||
|
{ 66, 6, 6, 7, 0, -5 }, // 0x33 '3' U+0033
|
||||||
|
{ 71, 6, 6, 7, 0, -5 }, // 0x34 '4' U+0034
|
||||||
|
{ 76, 6, 6, 7, 0, -5 }, // 0x35 '5' U+0035
|
||||||
|
{ 81, 6, 6, 7, 0, -5 }, // 0x36 '6' U+0036
|
||||||
|
{ 86, 5, 6, 7, 0, -5 }, // 0x37 '7' U+0037
|
||||||
|
{ 90, 6, 6, 7, 0, -5 }, // 0x38 '8' U+0038
|
||||||
|
{ 95, 6, 6, 7, 0, -5 }, // 0x39 '9' U+0039
|
||||||
|
{ 100, 2, 6, 6, 2, -5 }, // 0x3a ':' U+003A
|
||||||
|
{ 102, 2, 7, 6, 2, -5 }, // 0x3b ';' U+003B
|
||||||
|
{ 104, 5, 6, 7, 1, -5 }, // 0x3c '<' U+003C
|
||||||
|
{ 108, 5, 3, 7, 1, -4 }, // 0x3d '=' U+003D
|
||||||
|
{ 110, 5, 6, 7, 1, -5 }, // 0x3e '>' U+003E
|
||||||
|
{ 114, 6, 7, 7, 0, -5 }, // 0x3f '?' U+003F
|
||||||
|
{ 120, 6, 7, 7, 0, -5 }, // 0x40 '@' U+0040
|
||||||
|
{ 126, 6, 6, 7, 0, -5 }, // 0x41 'A' U+0041
|
||||||
|
{ 131, 6, 6, 7, 0, -5 }, // 0x42 'B' U+0042
|
||||||
|
{ 136, 6, 6, 7, 0, -5 }, // 0x43 'C' U+0043
|
||||||
|
{ 141, 6, 6, 7, 0, -5 }, // 0x44 'D' U+0044
|
||||||
|
{ 146, 6, 6, 7, 0, -5 }, // 0x45 'E' U+0045
|
||||||
|
{ 151, 6, 6, 7, 0, -5 }, // 0x46 'F' U+0046
|
||||||
|
{ 156, 6, 6, 7, 0, -5 }, // 0x47 'G' U+0047
|
||||||
|
{ 161, 6, 6, 7, 0, -5 }, // 0x48 'H' U+0048
|
||||||
|
{ 166, 4, 6, 7, 1, -5 }, // 0x49 'I' U+0049
|
||||||
|
{ 169, 6, 6, 7, 0, -5 }, // 0x4a 'J' U+004A
|
||||||
|
{ 174, 5, 6, 7, 1, -5 }, // 0x4b 'K' U+004B
|
||||||
|
{ 178, 5, 6, 7, 1, -5 }, // 0x4c 'L' U+004C
|
||||||
|
{ 182, 7, 6, 8, 0, -5 }, // 0x4d 'M' U+004D
|
||||||
|
{ 188, 7, 6, 8, 0, -5 }, // 0x4e 'N' U+004E
|
||||||
|
{ 194, 6, 6, 7, 0, -5 }, // 0x4f 'O' U+004F
|
||||||
|
{ 199, 6, 6, 7, 0, -5 }, // 0x50 'P' U+0050
|
||||||
|
{ 204, 6, 7, 7, 0, -5 }, // 0x51 'Q' U+0051
|
||||||
|
{ 210, 6, 6, 7, 0, -5 }, // 0x52 'R' U+0052
|
||||||
|
{ 215, 6, 6, 7, 0, -5 }, // 0x53 'S' U+0053
|
||||||
|
{ 220, 6, 6, 7, 0, -5 }, // 0x54 'T' U+0054
|
||||||
|
{ 225, 6, 6, 7, 0, -5 }, // 0x55 'U' U+0055
|
||||||
|
{ 230, 6, 6, 7, 0, -5 }, // 0x56 'V' U+0056
|
||||||
|
{ 235, 7, 6, 8, 0, -5 }, // 0x57 'W' U+0057
|
||||||
|
{ 241, 6, 6, 7, 0, -5 }, // 0x58 'X' U+0058
|
||||||
|
{ 246, 6, 6, 7, 0, -5 }, // 0x59 'Y' U+0059
|
||||||
|
{ 251, 6, 6, 7, 0, -5 }, // 0x5a 'Z' U+005A
|
||||||
|
{ 256, 4, 6, 7, 1, -5 }, // 0x5b '[' U+005B
|
||||||
|
{ 259, 6, 6, 7, 0, -5 }, // 0x5c '\' U+005C
|
||||||
|
{ 264, 4, 6, 7, 2, -5 }, // 0x5d ']' U+005D
|
||||||
|
{ 267, 6, 3, 7, 0, -5 }, // 0x5e '^' U+005E
|
||||||
|
{ 270, 6, 1, 7, 0, 0 }, // 0x5f '_' U+005F
|
||||||
|
{ 271, 3, 3, 6, 1, -5 }, // 0x60 '`' U+0060
|
||||||
|
{ 273, 6, 5, 7, 0, -4 }, // 0x61 'a' U+0061
|
||||||
|
{ 277, 6, 6, 7, 0, -5 }, // 0x62 'b' U+0062
|
||||||
|
{ 282, 6, 5, 7, 0, -4 }, // 0x63 'c' U+0063
|
||||||
|
{ 286, 6, 6, 7, 0, -5 }, // 0x64 'd' U+0064
|
||||||
|
{ 291, 6, 5, 7, 0, -4 }, // 0x65 'e' U+0065
|
||||||
|
{ 295, 5, 6, 7, 1, -5 }, // 0x66 'f' U+0066
|
||||||
|
{ 299, 6, 6, 7, 0, -4 }, // 0x67 'g' U+0067
|
||||||
|
{ 304, 7, 6, 8, 0, -5 }, // 0x68 'h' U+0068
|
||||||
|
{ 310, 4, 5, 7, 1, -4 }, // 0x69 'i' U+0069
|
||||||
|
{ 313, 5, 7, 7, 0, -5 }, // 0x6a 'j' U+006A
|
||||||
|
{ 318, 6, 6, 7, 0, -5 }, // 0x6b 'k' U+006B
|
||||||
|
{ 323, 4, 6, 7, 1, -5 }, // 0x6c 'l' U+006C
|
||||||
|
{ 326, 6, 5, 7, 0, -4 }, // 0x6d 'm' U+006D
|
||||||
|
{ 330, 6, 5, 7, 0, -4 }, // 0x6e 'n' U+006E
|
||||||
|
{ 334, 6, 5, 7, 0, -4 }, // 0x6f 'o' U+006F
|
||||||
|
{ 338, 6, 6, 7, 0, -4 }, // 0x70 'p' U+0070
|
||||||
|
{ 343, 6, 6, 7, 0, -4 }, // 0x71 'q' U+0071
|
||||||
|
{ 348, 5, 5, 7, 1, -4 }, // 0x72 'r' U+0072
|
||||||
|
{ 352, 5, 5, 7, 1, -4 }, // 0x73 's' U+0073
|
||||||
|
{ 356, 4, 6, 7, 1, -5 }, // 0x74 't' U+0074
|
||||||
|
{ 359, 6, 5, 7, 0, -4 }, // 0x75 'u' U+0075
|
||||||
|
{ 363, 6, 5, 7, 0, -4 }, // 0x76 'v' U+0076
|
||||||
|
{ 367, 7, 5, 8, 0, -4 }, // 0x77 'w' U+0077
|
||||||
|
{ 372, 5, 5, 7, 0, -4 }, // 0x78 'x' U+0078
|
||||||
|
{ 376, 6, 6, 7, 0, -4 }, // 0x79 'y' U+0079
|
||||||
|
{ 381, 5, 5, 7, 1, -4 }, // 0x7a 'z' U+007A
|
||||||
|
{ 385, 4, 6, 6, 1, -5 }, // 0x7b '{' U+007B
|
||||||
|
{ 388, 2, 7, 7, 4, -5 }, // 0x7c '|' U+007C
|
||||||
|
{ 390, 4, 6, 6, 1, -5 }, // 0x7d '}' U+007D
|
||||||
|
{ 393, 6, 5, 7, 0, -5 }, // 0x7e '~' U+007E
|
||||||
|
{ 397, 5, 6, 6, 0, -5 }, // 0x7f 'REPLACEMENT CHARACTER *' U+2370
|
||||||
|
{ 401, 5, 6, 6, 0, -5 }, // 0x80 'NO-BREAK SPACE' U+00A0
|
||||||
|
{ 405, 5, 6, 6, 0, -5 }, // 0x81 'INVERTED EXCLAMATION MARK' U+00A1
|
||||||
|
{ 409, 5, 6, 6, 0, -5 }, // 0x82 'CENT SIGN' U+00A2
|
||||||
|
{ 413, 5, 6, 6, 0, -5 }, // 0x83 'POUND SIGN' U+00A3
|
||||||
|
{ 417, 5, 6, 6, 0, -5 }, // 0x84 'CURRENCY SIGN' U+00A4
|
||||||
|
{ 421, 5, 6, 6, 0, -5 }, // 0x85 'YEN SIGN' U+00A5
|
||||||
|
{ 425, 5, 6, 6, 0, -5 }, // 0x86 'BROKEN BAR' U+00A6
|
||||||
|
{ 429, 5, 6, 6, 0, -5 }, // 0x87 'SECTION SIGN' U+00A7
|
||||||
|
{ 433, 5, 6, 6, 0, -5 }, // 0x88 'DIAERESIS' U+00A8
|
||||||
|
{ 437, 5, 6, 6, 0, -5 }, // 0x89 'COPYRIGHT SIGN' U+00A9
|
||||||
|
{ 441, 5, 6, 6, 0, -5 }, // 0x8a 'FEMININE ORDINAL INDICATOR' U+00AA
|
||||||
|
{ 445, 5, 6, 6, 0, -5 }, // 0x8b 'LEFT-POINTING DOUBLE ANGLE QUOTATION MARK' U+00AB
|
||||||
|
{ 449, 5, 6, 6, 0, -5 }, // 0x8c 'NOT SIGN' U+00AC
|
||||||
|
{ 453, 5, 6, 6, 0, -5 }, // 0x8d 'SOFT HYPHEN' U+00AD
|
||||||
|
{ 457, 5, 6, 6, 0, -5 }, // 0x8e 'REGISTERED SIGN' U+00AE
|
||||||
|
{ 461, 5, 6, 6, 0, -5 }, // 0x8f 'MACRON' U+00AF
|
||||||
|
{ 465, 5, 6, 6, 0, -5 }, // 0x90 'DEGREE SIGN' U+00B0
|
||||||
|
{ 469, 5, 6, 6, 0, -5 }, // 0x91 'PLUS-MINUS SIGN' U+00B1
|
||||||
|
{ 473, 5, 6, 6, 0, -5 }, // 0x92 'SUPERSCRIPT TWO' U+00B2
|
||||||
|
{ 477, 5, 6, 6, 0, -5 }, // 0x93 'SUPERSCRIPT THREE' U+00B3
|
||||||
|
{ 481, 5, 6, 6, 0, -5 }, // 0x94 'ACUTE ACCENT' U+00B4
|
||||||
|
{ 485, 5, 6, 6, 0, -5 }, // 0x95 'MICRO SIGN' U+00B5
|
||||||
|
{ 489, 5, 6, 6, 0, -5 }, // 0x96 'PILCROW SIGN' U+00B6
|
||||||
|
{ 493, 5, 6, 6, 0, -5 }, // 0x97 'MIDDLE DOT' U+00B7
|
||||||
|
{ 497, 5, 6, 6, 0, -5 }, // 0x98 'CEDILLA' U+00B8
|
||||||
|
{ 501, 5, 6, 6, 0, -5 }, // 0x99 'SUPERSCRIPT ONE' U+00B9
|
||||||
|
{ 505, 5, 6, 6, 0, -5 }, // 0x9a 'MASCULINE ORDINAL INDICATOR' U+00BA
|
||||||
|
{ 509, 5, 6, 6, 0, -5 }, // 0x9b 'RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK' U+00BB
|
||||||
|
{ 513, 5, 6, 6, 0, -5 }, // 0x9c 'VULGAR FRACTION ONE QUARTER' U+00BC
|
||||||
|
{ 517, 5, 6, 6, 0, -5 }, // 0x9d 'VULGAR FRACTION ONE HALF' U+00BD
|
||||||
|
{ 521, 5, 6, 6, 0, -5 }, // 0x9e 'VULGAR FRACTION THREE QUARTERS' U+00BE
|
||||||
|
{ 525, 5, 6, 6, 0, -5 }, // 0x9f 'INVERTED QUESTION MARK' U+00BF
|
||||||
|
{ 529, 6, 5, 7, 0, -4 }, // 0xa0 'LATIN CAPITAL LETTER A WITH GRAVE' U+00C0
|
||||||
|
{ 533, 6, 7, 7, 0, -5 }, // 0xa1 'LATIN CAPITAL LETTER A WITH ACUTE' U+00C1
|
||||||
|
{ 539, 6, 7, 7, 0, -5 }, // 0xa2 'LATIN CAPITAL LETTER A WITH CIRCUMFLEX' U+00C2
|
||||||
|
{ 545, 7, 6, 7, 0, -5 }, // 0xa3 'LATIN CAPITAL LETTER A WITH TILDE' U+00C3
|
||||||
|
{ 551, 7, 6, 7, 0, -5 }, // 0xa4 'LATIN CAPITAL LETTER A WITH DIAERESIS' U+00C4
|
||||||
|
{ 557, 6, 6, 7, 0, -5 }, // 0xa5 'LATIN CAPITAL LETTER A WITH RING ABOVE' U+00C5
|
||||||
|
{ 562, 6, 6, 7, 0, -5 }, // 0xa6 'LATIN CAPITAL LETTER AE' U+00C6
|
||||||
|
{ 567, 6, 6, 7, 0, -5 }, // 0xa7 'LATIN CAPITAL LETTER C WITH CEDILLA' U+00C7
|
||||||
|
{ 572, 7, 6, 7, 0, -5 }, // 0xa8 'LATIN CAPITAL LETTER E WITH GRAVE' U+00C8
|
||||||
|
{ 578, 7, 7, 7, 0, -5 }, // 0xa9 'LATIN CAPITAL LETTER E WITH ACUTE' U+00C9
|
||||||
|
{ 585, 7, 7, 7, 0, -5 }, // 0xaa 'LATIN CAPITAL LETTER E WITH CIRCUMFLEX' U+00CA
|
||||||
|
{ 592, 6, 7, 7, 0, -5 }, // 0xab 'LATIN CAPITAL LETTER E WITH DIAERESIS' U+00CB
|
||||||
|
{ 598, 7, 7, 7, 0, -5 }, // 0xac 'LATIN CAPITAL LETTER I WITH GRAVE' U+00CC
|
||||||
|
{ 605, 7, 7, 7, 0, -5 }, // 0xad 'LATIN CAPITAL LETTER I WITH ACUTE' U+00CD
|
||||||
|
{ 612, 7, 7, 8, 1, -5 }, // 0xae 'LATIN CAPITAL LETTER I WITH CIRCUMFLEX' U+00CE
|
||||||
|
{ 619, 3, 7, 6, 1, -5 }, // 0xaf 'LATIN CAPITAL LETTER I WITH DIAERESIS' U+00CF
|
||||||
|
{ 622, 6, 7, 7, 0, -5 }, // 0xb0 'LATIN CAPITAL LETTER ETH' U+00D0
|
||||||
|
{ 628, 4, 7, 7, 1, -5 }, // 0xb1 'LATIN CAPITAL LETTER N WITH TILDE' U+00D1
|
||||||
|
{ 632, 6, 7, 7, 0, -5 }, // 0xb2 'LATIN CAPITAL LETTER O WITH GRAVE' U+00D2
|
||||||
|
{ 638, 6, 7, 7, 0, -5 }, // 0xb3 'LATIN CAPITAL LETTER O WITH ACUTE' U+00D3
|
||||||
|
{ 644, 6, 7, 7, 0, -5 }, // 0xb4 'LATIN CAPITAL LETTER O WITH CIRCUMFLEX' U+00D4
|
||||||
|
{ 650, 6, 7, 7, 0, -5 }, // 0xb5 'LATIN CAPITAL LETTER O WITH TILDE' U+00D5
|
||||||
|
{ 656, 6, 7, 7, 0, -5 }, // 0xb6 'LATIN CAPITAL LETTER O WITH DIAERESIS' U+00D6
|
||||||
|
{ 662, 6, 7, 7, 0, -5 }, // 0xb7 'MULTIPLICATION SIGN' U+00D7
|
||||||
|
{ 668, 6, 7, 7, 0, -5 }, // 0xb8 'LATIN CAPITAL LETTER O WITH STROKE' U+00D8
|
||||||
|
{ 674, 6, 7, 7, 0, -5 }, // 0xb9 'LATIN CAPITAL LETTER U WITH GRAVE' U+00D9
|
||||||
|
{ 680, 6, 5, 7, 0, -4 }, // 0xba 'LATIN CAPITAL LETTER U WITH ACUTE' U+00DA
|
||||||
|
{ 684, 8, 7, 8, 0, -5 }, // 0xbb 'LATIN CAPITAL LETTER U WITH CIRCUMFLEX' U+00DB
|
||||||
|
{ 691, 7, 7, 8, 1, -5 }, // 0xbc 'LATIN CAPITAL LETTER U WITH DIAERESIS' U+00DC
|
||||||
|
{ 698, 6, 7, 7, 0, -5 }, // 0xbd 'LATIN CAPITAL LETTER Y WITH ACUTE' U+00DD
|
||||||
|
{ 704, 7, 7, 7, 0, -5 }, // 0xbe 'LATIN CAPITAL LETTER THORN' U+00DE
|
||||||
|
{ 711, 6, 6, 7, 0, -5 }, // 0xbf 'LATIN SMALL LETTER SHARP S' U+00DF
|
||||||
|
{ 716, 5, 6, 6, 0, -5 }, // 0xc0 'LATIN SMALL LETTER A WITH GRAVE' U+00E0
|
||||||
|
{ 720, 5, 6, 6, 0, -5 }, // 0xc1 'LATIN SMALL LETTER A WITH ACUTE' U+00E1
|
||||||
|
{ 724, 5, 6, 6, 0, -5 }, // 0xc2 'LATIN SMALL LETTER A WITH CIRCUMFLEX' U+00E2
|
||||||
|
{ 728, 5, 6, 6, 0, -5 }, // 0xc3 'LATIN SMALL LETTER A WITH TILDE' U+00E3
|
||||||
|
{ 732, 5, 6, 6, 0, -5 }, // 0xc4 'LATIN SMALL LETTER A WITH DIAERESIS' U+00E4
|
||||||
|
{ 736, 5, 6, 6, 0, -5 }, // 0xc5 'LATIN SMALL LETTER A WITH RING ABOVE' U+00E5
|
||||||
|
{ 740, 5, 6, 6, 0, -5 }, // 0xc6 'LATIN SMALL LETTER AE' U+00E6
|
||||||
|
{ 744, 5, 6, 6, 0, -5 }, // 0xc7 'LATIN SMALL LETTER C WITH CEDILLA' U+00E7
|
||||||
|
{ 748, 5, 6, 6, 0, -5 }, // 0xc8 'LATIN SMALL LETTER E WITH GRAVE' U+00E8
|
||||||
|
{ 752, 5, 6, 6, 0, -5 }, // 0xc9 'LATIN SMALL LETTER E WITH ACUTE' U+00E9
|
||||||
|
{ 756, 5, 6, 6, 0, -5 }, // 0xca 'LATIN SMALL LETTER E WITH CIRCUMFLEX' U+00EA
|
||||||
|
{ 760, 5, 6, 6, 0, -5 }, // 0xcb 'LATIN SMALL LETTER E WITH DIAERESIS' U+00EB
|
||||||
|
{ 764, 5, 6, 6, 0, -5 }, // 0xcc 'LATIN SMALL LETTER I WITH GRAVE' U+00EC
|
||||||
|
{ 768, 5, 6, 6, 0, -5 }, // 0xcd 'LATIN SMALL LETTER I WITH ACUTE' U+00ED
|
||||||
|
{ 772, 5, 6, 6, 0, -5 }, // 0xce 'LATIN SMALL LETTER I WITH CIRCUMFLEX' U+00EE
|
||||||
|
{ 776, 5, 6, 6, 0, -5 }, // 0xcf 'LATIN SMALL LETTER I WITH DIAERESIS' U+00EF
|
||||||
|
{ 780, 5, 6, 6, 0, -5 }, // 0xd0 'LATIN SMALL LETTER ETH' U+00F0
|
||||||
|
{ 784, 5, 6, 6, 0, -5 }, // 0xd1 'LATIN SMALL LETTER N WITH TILDE' U+00F1
|
||||||
|
{ 788, 5, 6, 6, 0, -5 }, // 0xd2 'LATIN SMALL LETTER O WITH GRAVE' U+00F2
|
||||||
|
{ 792, 5, 6, 6, 0, -5 }, // 0xd3 'LATIN SMALL LETTER O WITH ACUTE' U+00F3
|
||||||
|
{ 796, 5, 6, 6, 0, -5 }, // 0xd4 'LATIN SMALL LETTER O WITH CIRCUMFLEX' U+00F4
|
||||||
|
{ 800, 5, 6, 6, 0, -5 }, // 0xd5 'LATIN SMALL LETTER O WITH TILDE' U+00F5
|
||||||
|
{ 804, 5, 6, 6, 0, -5 }, // 0xd6 'LATIN SMALL LETTER O WITH DIAERESIS' U+00F6
|
||||||
|
{ 808, 5, 6, 6, 0, -5 }, // 0xd7 'DIVISION SIGN' U+00F7
|
||||||
|
{ 812, 5, 6, 6, 0, -5 }, // 0xd8 'LATIN SMALL LETTER O WITH STROKE' U+00F8
|
||||||
|
{ 816, 5, 6, 6, 0, -5 }, // 0xd9 'LATIN SMALL LETTER U WITH GRAVE' U+00F9
|
||||||
|
{ 820, 5, 6, 6, 0, -5 }, // 0xda 'LATIN SMALL LETTER U WITH ACUTE' U+00FA
|
||||||
|
{ 824, 5, 6, 6, 0, -5 }, // 0xdb 'LATIN SMALL LETTER U WITH CIRCUMFLEX' U+00FB
|
||||||
|
{ 828, 5, 6, 6, 0, -5 }, // 0xdc 'LATIN SMALL LETTER U WITH DIAERESIS' U+00FC
|
||||||
|
{ 832, 5, 6, 6, 0, -5 }, // 0xdd 'LATIN SMALL LETTER Y WITH ACUTE' U+00FD
|
||||||
|
{ 836, 5, 6, 6, 0, -5 }, // 0xde 'LATIN SMALL LETTER THORN' U+00FE
|
||||||
|
{ 840, 5, 6, 6, 0, -5 } }; // 0xdf 'LATIN SMALL LETTER Y WITH DIAERESIS' U+000FF
|
||||||
|
|
||||||
|
const GFXfont Atari6px PROGMEM = {
|
||||||
|
(uint8_t *)Atari6pxBitmaps,
|
||||||
|
(GFXglyph *)Atari6pxGlyphs,
|
||||||
|
0x20, 0xDF, 9 };
|
||||||
|
|
||||||
|
// Approx. 2195 bytes
|
||||||
@@ -20,7 +20,7 @@ import getopt
|
|||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
|
|
||||||
__version__ = "0.2"
|
__version__ = "1.2"
|
||||||
|
|
||||||
def detect_pages(filename):
|
def detect_pages(filename):
|
||||||
# returns a dictionary with page name and the number of gui fields
|
# returns a dictionary with page name and the number of gui fields
|
||||||
@@ -110,11 +110,10 @@ def create_json(device, no_of_pages, pagedata):
|
|||||||
"description": "The display for field {}".format(number_to_text(field_no)),
|
"description": "The display for field {}".format(number_to_text(field_no)),
|
||||||
"category": f"{device.upper()} Page {page_no}",
|
"category": f"{device.upper()} Page {page_no}",
|
||||||
"capabilities": {device.lower(): "true"},
|
"capabilities": {device.lower(): "true"},
|
||||||
"condition": [
|
"condition": {
|
||||||
{f"page{page_no}type": page}
|
f"page{page_no}type": [page for page in pages if pagedata[page] >= field_no],
|
||||||
for page in pages
|
"visiblePages": [vp for vp in range(page_no, no_of_pages + 1)]
|
||||||
if pagedata[page] >= field_no
|
},
|
||||||
],
|
|
||||||
}
|
}
|
||||||
output.append(field_data)
|
output.append(field_data)
|
||||||
|
|
||||||
@@ -149,12 +148,13 @@ def usage():
|
|||||||
print("Command line options")
|
print("Command line options")
|
||||||
print(" -d --device device name to use e.g. obp60")
|
print(" -d --device device name to use e.g. obp60")
|
||||||
print(" -p --pages number of pages to create")
|
print(" -p --pages number of pages to create")
|
||||||
|
print(" -m --merge json with device config to merge to")
|
||||||
print(" -h show this help")
|
print(" -h show this help")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
try:
|
try:
|
||||||
options, remainder = getopt.getopt(sys.argv[1:], 'd:p:', ['device=','--pages='])
|
options, remainder = getopt.getopt(sys.argv[1:], 'd:p:m:', ['device=','--pages=','--merge'])
|
||||||
except getopt.GetoptError as err:
|
except getopt.GetoptError as err:
|
||||||
print(err)
|
print(err)
|
||||||
usage()
|
usage()
|
||||||
@@ -162,11 +162,14 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
device = "obp60"
|
device = "obp60"
|
||||||
no_of_pages = 10
|
no_of_pages = 10
|
||||||
|
merge_json = None
|
||||||
for opt, arg in options:
|
for opt, arg in options:
|
||||||
if opt in ('-d', '--device'):
|
if opt in ('-d', '--device'):
|
||||||
device = arg
|
device = arg
|
||||||
elif opt in ('-p', '--pages'):
|
elif opt in ('-p', '--pages'):
|
||||||
no_of_pages = int(arg)
|
no_of_pages = int(arg)
|
||||||
|
elif opt in ('-m', '--merge'):
|
||||||
|
merge_json = arg
|
||||||
elif opt == '-h':
|
elif opt == '-h':
|
||||||
usage()
|
usage()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
@@ -175,5 +178,12 @@ if __name__ == '__main__':
|
|||||||
pagedata = detect_pages("obp60task.cpp")
|
pagedata = detect_pages("obp60task.cpp")
|
||||||
|
|
||||||
json_output = create_json(device, no_of_pages, pagedata)
|
json_output = create_json(device, no_of_pages, pagedata)
|
||||||
|
if merge_json and os.path.isfile(merge_json):
|
||||||
|
with open(merge_json, 'r') as fh:
|
||||||
|
device_json = json.load(fh)
|
||||||
|
page_json = json.loads(json_output)
|
||||||
|
device_json.extend(page_json)
|
||||||
|
print(json.dumps(device_json, indent=4))
|
||||||
|
else:
|
||||||
# print omitting first line containing [ of JSON array
|
# print omitting first line containing [ of JSON array
|
||||||
print(json_output[1:])
|
print(json_output[1:])
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
git status
|
|
||||||
git fetch upstream
|
|
||||||
git diff --name-status upstream/master
|
|
||||||
git checkout upstream/master platformio.ini
|
|
||||||
|
|
||||||
# how to reset my Repo to match norbert'status
|
|
||||||
|
|
||||||
git remote add upstream https://github.com/norbert-walter/esp32-nmea2000-obp60
|
|
||||||
git fetch upstream
|
|
||||||
git checkout master
|
|
||||||
git reset --hard upstream/master
|
|
||||||
git push origin master --force
|
|
||||||
88
lib/obp60task/hbuffer.cpp
Normal file
88
lib/obp60task/hbuffer.cpp
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/* History Buffer
|
||||||
|
*
|
||||||
|
* Storage backed buffer for sensordata
|
||||||
|
* Permanent storage only supported type: FRAM on I2C-Bus
|
||||||
|
*
|
||||||
|
* Values can be 1 to 4 bytes in length
|
||||||
|
*
|
||||||
|
* Header: 32 bytes of size
|
||||||
|
* 0 0x00 HB00 4 magic number
|
||||||
|
* 4 0x04 xxxxxxxxxxxxxxxx 16 name, space padded
|
||||||
|
* 20 0x14 n 1 byte size of values in buffer
|
||||||
|
* 21 0x15 mm 2 buffer size in count of values
|
||||||
|
* 23 0x17 dd 2 time step in seconds between values
|
||||||
|
* 25 0x19 tttt 4 unix timestamp of head
|
||||||
|
* 29 0x1d hh 2 head pointer
|
||||||
|
* 31 0x1f 0xff 1 header end sign
|
||||||
|
*
|
||||||
|
* 32 0x20 ... start of buffer data
|
||||||
|
*
|
||||||
|
* Usage example: 7 hours of data collected every 75 seconds
|
||||||
|
* TODO
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
class HistoryBuffer {
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Header prototype for permanent storage
|
||||||
|
uint8_t header[32] = {
|
||||||
|
0x41, 0x48, 0x30, 0x30, // magic: HB00
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // empty name
|
||||||
|
0x01, // byte size
|
||||||
|
0x50, 0x01, // value count
|
||||||
|
0x4b, 0x00, // time step
|
||||||
|
0x00, 0x00, 0x00, 0x00, // unix time stamp
|
||||||
|
0x00, 0x00, // head pointer
|
||||||
|
0xff // end sign
|
||||||
|
};
|
||||||
|
uint16_t head = 0; // head pointer to next new value position
|
||||||
|
time_t timestamp; // last modification time of head
|
||||||
|
uint16_t delta_t; // time step in seconds
|
||||||
|
|
||||||
|
public:
|
||||||
|
HistoryBuffer(uint16_t size) {
|
||||||
|
}
|
||||||
|
~HistoryBuffer() {
|
||||||
|
// free memory
|
||||||
|
}
|
||||||
|
void begin() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
void finish() {
|
||||||
|
}
|
||||||
|
uint16_t add() {
|
||||||
|
// returns new head value pointer
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uint8_t* get() {
|
||||||
|
// returns complete buffer in order new to old
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uint8_t getvalue(uint16_t dt) {
|
||||||
|
// Return a single value delta seconds ago
|
||||||
|
uint16_t index = head - abs(dt) / delta_t;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uint8_t getvalue3() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bool clear() {
|
||||||
|
// clears buffer and permanent storage
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class History {
|
||||||
|
public:
|
||||||
|
History() {
|
||||||
|
}
|
||||||
|
~History() {
|
||||||
|
}
|
||||||
|
void *addSeries() {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
21
lib/obp60task/hbuffer.h
Normal file
21
lib/obp60task/hbuffer.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef __HBUFFER_H__
|
||||||
|
#define __HBUFFER_H__
|
||||||
|
|
||||||
|
class HistoryBuffer {
|
||||||
|
public:
|
||||||
|
HistoryBuffer(uint16_t size);
|
||||||
|
void begin();
|
||||||
|
void finish();
|
||||||
|
uint16_t add();
|
||||||
|
uint8_t* get() ;
|
||||||
|
uint8_t getvalue(uint16_t dt);
|
||||||
|
uint8_t getvalue3();
|
||||||
|
void clear();
|
||||||
|
};
|
||||||
|
class History {
|
||||||
|
public:
|
||||||
|
History();
|
||||||
|
void *addSeries();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
14
lib/obp60task/index.js
Normal file
14
lib/obp60task/index.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// Add a new register card in web configuration interface
|
||||||
|
// This is a Java Script!
|
||||||
|
(function(){
|
||||||
|
const api=window.esp32nmea2k;
|
||||||
|
if (! api) return;
|
||||||
|
const tabName="Screen";
|
||||||
|
api.registerListener((id, data) => {
|
||||||
|
// if (!data.testboard) return; //do nothing if we are not active
|
||||||
|
let page = api.addTabPage(tabName, "Screen");
|
||||||
|
api.addEl('button', '', page, 'Screenshot').addEventListener('click', function (ev) {
|
||||||
|
window.open('/api/user/OBP60Task/screenshot', 'screenshot');
|
||||||
|
})
|
||||||
|
}, api.EVENTS.init);
|
||||||
|
})();
|
||||||
807
lib/obp60task/obp40.conf
Normal file
807
lib/obp60task/obp40.conf
Normal file
@@ -0,0 +1,807 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
calibration_fields = AWA, AWS, COG, DBT, HDM, PRPOS, RPOS, SOG, STW, TWA, TWS, TWD, WTemp
|
||||||
|
|
||||||
|
[deviceName]
|
||||||
|
label = system name
|
||||||
|
type = string
|
||||||
|
default = OBP40
|
||||||
|
description = system name, used for the access point and for services
|
||||||
|
check = checkSystemName
|
||||||
|
category = system
|
||||||
|
|
||||||
|
[timeServer]
|
||||||
|
label = time server
|
||||||
|
type = string
|
||||||
|
default = pool.ntp.org
|
||||||
|
description = NTP time server. Use only one hostname or IP address
|
||||||
|
category = wifi client
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[timeZone]
|
||||||
|
label = Time Zone
|
||||||
|
type = number
|
||||||
|
default = 0.00
|
||||||
|
description = Time zone [UTC -12...+14]
|
||||||
|
check = checkMinMax
|
||||||
|
min = -12.0
|
||||||
|
max = 14.0
|
||||||
|
category = OBP40 Settings
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[homeLAT]
|
||||||
|
label = Home latitude
|
||||||
|
type = number
|
||||||
|
default = 0.00000
|
||||||
|
description = Latitude of boat home location [-90.0...+90.0]
|
||||||
|
check = checkMinMax
|
||||||
|
min = -90.0
|
||||||
|
max = 90.0
|
||||||
|
category = OBP40 Settings
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[homeLON]
|
||||||
|
label = Home longitude
|
||||||
|
type = number
|
||||||
|
default = 0.00000
|
||||||
|
description = Longitude of boat home location [-180.0...+180.0]
|
||||||
|
check = checkMinMax
|
||||||
|
min = -180.0
|
||||||
|
max = 180.0
|
||||||
|
category = OBP40 Settings
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[draft]
|
||||||
|
label = Boat Draft [m]
|
||||||
|
type = number
|
||||||
|
default = 0.00
|
||||||
|
description = The draft of the boat [0...50m]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0.0
|
||||||
|
max = 50.0
|
||||||
|
category = OBP40 Settings
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[chainLength]
|
||||||
|
label = Anchor Chain Length [m]
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = The length of the anchor chain [0...255m]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 255
|
||||||
|
category = OBP40 Settings
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[fuelTank]
|
||||||
|
label = Fuel Tank [l]
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Fuel tank capacity [0...5000l]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 5000
|
||||||
|
category = OBP40 Settings
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[fuelConsumption]
|
||||||
|
label = Fuel Consuption [l/h]
|
||||||
|
type = number
|
||||||
|
default = 0.00
|
||||||
|
description = Medium fuel consumption [0...1000l/h]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0.0
|
||||||
|
max = 1000.0
|
||||||
|
category = OBP40 Settings
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[waterTank]
|
||||||
|
label = Water Tank [l]
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Water tank capacity [0...5000l]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 5000
|
||||||
|
category = OBP40 Settings
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[wasteTank]
|
||||||
|
label = Waste Tank [l]
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Waste tank capacity [0...5000l]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 5000
|
||||||
|
category = OBP40 Settings
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[batteryVoltage]
|
||||||
|
label = Battery Voltage [V]
|
||||||
|
type = list
|
||||||
|
default = 12V
|
||||||
|
description = Battery Voltage [12V|24V]
|
||||||
|
list = 12V, 24V
|
||||||
|
category = OBP40 Settings
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[batteryType]
|
||||||
|
label = Battery Type
|
||||||
|
type = list
|
||||||
|
default = Pb
|
||||||
|
description = Type of battery [Pb|Gel|AGM|LiFePo4]
|
||||||
|
list = Pb, Gel, AGM, LiFePo4
|
||||||
|
category = OBP40 Settings
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[batteryCapacity]
|
||||||
|
label = Battery Capacity [Ah]
|
||||||
|
type = number
|
||||||
|
default = 0.0
|
||||||
|
description = Battery capacity [0...10000Ah]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0.0
|
||||||
|
max = 10000.0
|
||||||
|
category = OBP40 Settings
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[solarPower]
|
||||||
|
label = Solar Power [W]
|
||||||
|
type = number
|
||||||
|
default = 0.0
|
||||||
|
description = Solar power [0...10000W]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0.0
|
||||||
|
max = 10000.0
|
||||||
|
category = OBP40 Settings
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[genPower]
|
||||||
|
label = Genarator Power [W]
|
||||||
|
type = number
|
||||||
|
default = 0.0
|
||||||
|
description = Generator power [0...10000W]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0.0
|
||||||
|
max = 10000.0
|
||||||
|
category = OBP40 Settings
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[trackStep]
|
||||||
|
label = angle [deg]
|
||||||
|
type = number
|
||||||
|
default = 3.0
|
||||||
|
description = track step offset [1...12deg]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 1.0
|
||||||
|
max = 12.0
|
||||||
|
category = OBP40 Settings
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[calcTrueWnds]
|
||||||
|
label = Calculate True Wind
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = If not available, calculate true wind data from appearant wind and other boat data
|
||||||
|
category = OBP40 Settings
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[lengthFormat]
|
||||||
|
label = Length Format
|
||||||
|
type = list
|
||||||
|
default = m
|
||||||
|
description = Length format [m|ft]
|
||||||
|
list = m, ft
|
||||||
|
category = OBP40 Units
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[distanceFormat]
|
||||||
|
label = Distance Format
|
||||||
|
type = list
|
||||||
|
default = nm
|
||||||
|
description = Distance format [m|km|nm]
|
||||||
|
list = m, km, nm
|
||||||
|
category = OBP40 Units
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[speedFormat]
|
||||||
|
label = Speed Format
|
||||||
|
type = list
|
||||||
|
default = kn
|
||||||
|
description = Distance format [m/s|km/h|kn]
|
||||||
|
list = m/s, km/h, kn
|
||||||
|
category = OBP40 Units
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[windspeedFormat]
|
||||||
|
label = Wind Speed Format
|
||||||
|
type = list
|
||||||
|
default = kn
|
||||||
|
description = Wind speed format [m/s|km/h|kn|bft]
|
||||||
|
list = m/s, km/h, kn, bft
|
||||||
|
category = OBP40 Units
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[tempFormat]
|
||||||
|
label = Temperature Format
|
||||||
|
type = list
|
||||||
|
default = C
|
||||||
|
description = Temperature format [K|C|F]
|
||||||
|
list = K, C, F
|
||||||
|
category = OBP40 Units
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[dateFormat]
|
||||||
|
label = Date Format
|
||||||
|
type = list
|
||||||
|
default = DE
|
||||||
|
description = Date format [DE|GB|US|ISO] DE: 31.12.2022, GB: 31/12/2022, US: 12/31/2022, ISO: 2022-12-31
|
||||||
|
list = DE, GB, US, ISO
|
||||||
|
category = OBP40 Units
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[cpuSpeed]
|
||||||
|
label = CPU Speed [MHz]
|
||||||
|
type = list
|
||||||
|
default = 160
|
||||||
|
description = CPU speed in MHz [80|160|240]
|
||||||
|
list = 80, 160, 240
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[useRTC]
|
||||||
|
label = RTC Modul
|
||||||
|
type = list
|
||||||
|
default = off
|
||||||
|
description = Use RTC module type [off|DS1388]
|
||||||
|
list = off, DS1388
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[useGPS]
|
||||||
|
label = GPS Sensor
|
||||||
|
type = list
|
||||||
|
default = off
|
||||||
|
description = Use internal GPS module type [off|NEO-6M|NEO-M8N|ATGM336H]
|
||||||
|
list = off, NEO-6M, NEO-M8N, ATGM336H
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[hdopAccuracy]
|
||||||
|
label = HDOP Accuracy [m]
|
||||||
|
type = number
|
||||||
|
default = 20
|
||||||
|
description = HDOP ccuracy in m for a valid GPS signal [1...50]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 1
|
||||||
|
max = 50
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[useEnvSensor]
|
||||||
|
label = Env. Sensor
|
||||||
|
type = list
|
||||||
|
default = off
|
||||||
|
description = Use internal or external environment sensor via I2C bus [off|BME280|BMP280|BMP180|BMP085|HTU21|SHT21]
|
||||||
|
list = off, BME280, BMP280, BMP180, BMP085, HTU21, SHT21
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[usePowSensor1]
|
||||||
|
label = Battery Sensor
|
||||||
|
type = list
|
||||||
|
default = off
|
||||||
|
description = Use external power management sensor via I2C bus for battery [off|INA219|INA226|]
|
||||||
|
list = off, INA219, INA226
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[shunt1]
|
||||||
|
label = Battery Shunt
|
||||||
|
type = list
|
||||||
|
default = 10
|
||||||
|
description = Shunt current value [10A|50A|100A|200A|300A|400A|500A]
|
||||||
|
list = 10, 50, 100, 200, 300, 400, 500
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[usePowSensor2]
|
||||||
|
label = Solar Sensor
|
||||||
|
type = list
|
||||||
|
default = off
|
||||||
|
description = Use external power management sensor via I2C bus for solar panels [off|INA219|INA226|]
|
||||||
|
list = off, INA219, INA226
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[shunt2]
|
||||||
|
label = Solar Shunt
|
||||||
|
type = list
|
||||||
|
default = 10
|
||||||
|
description = Shunt current value [10A|50A|100A|200A|300A|400A|500A]
|
||||||
|
list = 10, 50, 100, 200, 300, 400, 500
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[usePowSensor3]
|
||||||
|
label = Gen. Sensor
|
||||||
|
type = list
|
||||||
|
default = off
|
||||||
|
description = Use external power management sensor via I2C bus for generator [off|INA219|INA226|]
|
||||||
|
list = off, INA219, INA226
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[shunt3]
|
||||||
|
label = Gen. Shunt
|
||||||
|
type = list
|
||||||
|
default = 10
|
||||||
|
description = Shunt current value [10A|50A|100A|200A|300A|400A|500A] @ 75mV
|
||||||
|
list = 10, 50, 100, 200, 300, 400, 500
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[useRotSensor]
|
||||||
|
label = Rot. Sensor
|
||||||
|
type = list
|
||||||
|
default = off
|
||||||
|
description = Use external rotation sensor via I2C bus [off|AS5600]
|
||||||
|
list = off, AS5600
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[rotFunction]
|
||||||
|
label = Rot. Function
|
||||||
|
type = list
|
||||||
|
default = off
|
||||||
|
description = Function for rotation sensor [off|Rudder|Wind|Mast|Keel|Trim|Boom]
|
||||||
|
list = off, Rudder, Wind, Mast, Keel, Trim, Boom
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[rotOffset]
|
||||||
|
label = Rot. Offset
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Offset for rotation sensor [-180°...+180°]
|
||||||
|
check = checkMinMax
|
||||||
|
min = -180
|
||||||
|
max = 180
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[rollLimit]
|
||||||
|
label = Roll Limit
|
||||||
|
type = number
|
||||||
|
default = 25
|
||||||
|
description = Limit violation for roll angle [-90°...+90°]
|
||||||
|
check = checkMinMax
|
||||||
|
min = -90
|
||||||
|
max = 90
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[rollOffset]
|
||||||
|
label = Roll Offset
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Roll offset angle [-45°...+45°]
|
||||||
|
check = checkMinMax
|
||||||
|
min = -45
|
||||||
|
max = 45
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[pitchOffset]
|
||||||
|
label = Pitch Offset
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Pitch offset angle [-45°...+45°]
|
||||||
|
check = checkMinMax
|
||||||
|
min = -45
|
||||||
|
max = 45
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[useTempSensor]
|
||||||
|
label = Temp. Sensor
|
||||||
|
type = boolean
|
||||||
|
default = off
|
||||||
|
description = Use max. 8 external 1Wire devices [off|DS18B20]
|
||||||
|
list = off, DS18B20
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[useSDCard]
|
||||||
|
label = SD Card
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = Use internal SD card interface [off|on]
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[powerMode]
|
||||||
|
label = Power Mode
|
||||||
|
type = list
|
||||||
|
default = Max Power
|
||||||
|
description = Settings for power mode
|
||||||
|
list = Max Power, Only 5.0V, Min Power
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[underVoltage]
|
||||||
|
label = Undervoltage
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = Switch off device if LiPo voltage drops below 3.65V [on|off]
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[useSimuData]
|
||||||
|
label = Simulation Data
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = Use simulation data when bus data are missing [on|off]
|
||||||
|
category = OBP40 Hardware
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[tSensitivity]
|
||||||
|
label = Touch Sensitivity [%%]
|
||||||
|
type = number
|
||||||
|
default = 100
|
||||||
|
description = Touch sensitivity [0...100%%] for sensor buttons
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 100
|
||||||
|
category = OBP40 Calibrations
|
||||||
|
capabilities = obp40:false
|
||||||
|
|
||||||
|
[vOffset]
|
||||||
|
label = VSensor Offset
|
||||||
|
type = number
|
||||||
|
default = -1.00
|
||||||
|
description = Offset for internal voltage sensor (ESP32)
|
||||||
|
category = OBP40 Calibrations
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[vSlope]
|
||||||
|
label = VSensor Slope
|
||||||
|
type = number
|
||||||
|
default = 1.00
|
||||||
|
description = Slope for internal voltage sensor (ESP32)
|
||||||
|
category = OBP40 Calibrations
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[calInstance1]
|
||||||
|
label = Calibration Data Instance 1
|
||||||
|
type = list
|
||||||
|
default = ---
|
||||||
|
description = Data instance for calibration
|
||||||
|
list = ---, %(calibration_fields)s
|
||||||
|
category = OBP40 Calibrations
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[calOffset1]
|
||||||
|
label = Data Instance 1 Calibration Offset
|
||||||
|
type = number
|
||||||
|
default = 0.00
|
||||||
|
description = Offset for data instance 1
|
||||||
|
category = OBP40 Calibrations
|
||||||
|
capabilities = obp40:true
|
||||||
|
condition = calInstance1 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[calSlope1]
|
||||||
|
label = Data Instance 1 Calibration Slope
|
||||||
|
type = number
|
||||||
|
default = 1.00
|
||||||
|
description = Slope for data instance 1
|
||||||
|
category = OBP40 Calibrations
|
||||||
|
capabilities = obp40:true
|
||||||
|
condition = calInstance1 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[calSmooth1]
|
||||||
|
label = Data Instance 1 Smoothing
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Smoothing factor [0..10]; 0 = no smoothing
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 10
|
||||||
|
category = OBP40 Calibrations
|
||||||
|
capabilities = obp40:true
|
||||||
|
condition = calInstance1 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[calInstance2]
|
||||||
|
label = Calibration Data Instance 2
|
||||||
|
type = list
|
||||||
|
default = ---
|
||||||
|
description = Data instance for calibration
|
||||||
|
list = ---, %(calibration_fields)s
|
||||||
|
category = OBP40 Calibrations
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[calOffset2]
|
||||||
|
label = Data Instance 2 Calibration Offset
|
||||||
|
type = number
|
||||||
|
default = 0.00
|
||||||
|
description = Offset for data instance 2
|
||||||
|
category = OBP40 Calibrations
|
||||||
|
capabilities = obp40:true
|
||||||
|
condition = calInstance2 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[calSlope2]
|
||||||
|
label = Data Instance 2 Calibration Slope
|
||||||
|
type = number
|
||||||
|
default = 1.00
|
||||||
|
description = Slope for data instance 2
|
||||||
|
category = OBP40 Calibrations
|
||||||
|
capabilities = obp40:true
|
||||||
|
condition = calInstance2 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[calSmooth2]
|
||||||
|
label = Data Instance 2 Smoothing
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Smoothing factor [0..10]; 0 = no smoothing
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 10
|
||||||
|
category = OBP40 Calibrations
|
||||||
|
capabilities = obp40:true
|
||||||
|
condition = calInstance2 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[calInstance3]
|
||||||
|
label = Calibration Data Instance 3
|
||||||
|
type = list
|
||||||
|
default = ---
|
||||||
|
description = Data instance for calibration
|
||||||
|
list = ---, %(calibration_fields)s
|
||||||
|
category = OBP40 Calibrations
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[calOffset3]
|
||||||
|
label = Data Instance 3 Calibration Offset
|
||||||
|
type = number
|
||||||
|
default = 0.00
|
||||||
|
description = Offset for data instance 3
|
||||||
|
category = OBP40 Calibrations
|
||||||
|
capabilities = obp40:true
|
||||||
|
condition = calinstance3 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[calSlope3]
|
||||||
|
label = Data Instance 3 Calibration Slope
|
||||||
|
type = number
|
||||||
|
default = 1.00
|
||||||
|
description = Slope for data instance 3
|
||||||
|
category = OBP40 Calibrations
|
||||||
|
capabilities = obp40:true
|
||||||
|
condition = calinstance3 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[calSmooth3]
|
||||||
|
label = Data Instance 3 Smoothing
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Smoothing factor [0..10]; 0 = no smoothing
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 10
|
||||||
|
category = OBP40 Calibrations
|
||||||
|
capabilities = obp40:true
|
||||||
|
condition = calinstance3 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[display]
|
||||||
|
label = Display Mode
|
||||||
|
type = list
|
||||||
|
default = Logo + QR Code
|
||||||
|
description = Settings for startup display
|
||||||
|
list = White Screen, Logo, Logo + QR Code, Off
|
||||||
|
category = OBP40 Display
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[displaycolor]
|
||||||
|
label = Inverted Display Mode
|
||||||
|
type = list
|
||||||
|
default = Normal
|
||||||
|
description = Invert display to white letters on black background [Normal|Inverse]
|
||||||
|
list = Normal, Inverse
|
||||||
|
category = OBP40 Display
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[statusLine]
|
||||||
|
label = Status Line
|
||||||
|
type = boolean
|
||||||
|
default = true
|
||||||
|
description = Show status line [on|off]
|
||||||
|
category = OBP40 Display
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[timeSource]
|
||||||
|
label = Status Time Source
|
||||||
|
type = list
|
||||||
|
default = GPS
|
||||||
|
description = Data source for date and time display in status line [RTC|iRTC|GPS]
|
||||||
|
dict =
|
||||||
|
iRTC:Internal real time clock (iRTC)
|
||||||
|
RTC:External real time clock (RTC)
|
||||||
|
GPS:External time via bus (GPS)
|
||||||
|
category = OBP40 Display
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[refresh]
|
||||||
|
label = Refresh
|
||||||
|
type = boolean
|
||||||
|
default = true
|
||||||
|
description = Refresh e-paper display after each new page request to reduce ghost effects [on|off]
|
||||||
|
category = OBP40 Display
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[fastRefresh]
|
||||||
|
label = Fast Refresh
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = Fast refresh for e-paper display [on|off]
|
||||||
|
category = OBP40 Display
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[fullRefreshTime]
|
||||||
|
label = Full Refresh Time [min]
|
||||||
|
type = number
|
||||||
|
default = 1
|
||||||
|
description = E-Paper full refresh time all [1...10 min]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 1
|
||||||
|
max = 10
|
||||||
|
category = OBP40 Display
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[holdvalues]
|
||||||
|
label = Hold Values
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = Retain old values when data stream stops [on|off]
|
||||||
|
category = OBP40 Display
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[valueprecision]
|
||||||
|
label = Display value precision
|
||||||
|
type = list
|
||||||
|
default = 2
|
||||||
|
description = Maximum number of decimal places to display [1|2]
|
||||||
|
list = 1, 2
|
||||||
|
category = OBP40 Display
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[headerFormat]
|
||||||
|
label = Header Format
|
||||||
|
type = list
|
||||||
|
default = TEXT
|
||||||
|
description = Header format: Text or Symbols
|
||||||
|
dict =
|
||||||
|
TEXT:Text
|
||||||
|
ICON:Symbols
|
||||||
|
category = OBP40 Display
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[backlight]
|
||||||
|
label = Backlight Mode
|
||||||
|
type = list
|
||||||
|
default = off
|
||||||
|
description = Settings for automatic backlight mode
|
||||||
|
list = Off, Control by Sun, Control by Bus, Control by Time, Control by Key, On
|
||||||
|
category = OBP40 Display
|
||||||
|
capabilities = obp40:false
|
||||||
|
|
||||||
|
[blColor]
|
||||||
|
label = Backlight Color
|
||||||
|
type = list
|
||||||
|
default = Red
|
||||||
|
description = Backlight color
|
||||||
|
list = Red, Orange, Yellow, Green, Blue, Aqua, Violet, White
|
||||||
|
category = OBP40 Display
|
||||||
|
capabilities = obp40:false
|
||||||
|
|
||||||
|
[blBrightness]
|
||||||
|
label = Brightness [%%]
|
||||||
|
type = number
|
||||||
|
default = 50
|
||||||
|
description = Backlight brightness [20...100%%]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 20
|
||||||
|
max = 100
|
||||||
|
category = OBP40 Display
|
||||||
|
capabilities = obp40:false
|
||||||
|
|
||||||
|
[flashLED]
|
||||||
|
label = Flash LED Mode
|
||||||
|
type = list
|
||||||
|
default = Off
|
||||||
|
description = Settings for flash LED
|
||||||
|
list = Off, Bus Data, GPS Fix Lost, Limit Violation
|
||||||
|
category = OBP40 Display
|
||||||
|
capabilities = obp40:false
|
||||||
|
|
||||||
|
[buzzerError]
|
||||||
|
label = Buzzer Error
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = Sound on error [on|off]
|
||||||
|
category = OBP40 Buzzer
|
||||||
|
capabilities = obp40:false
|
||||||
|
|
||||||
|
[buzzerGps]
|
||||||
|
label = Buzzer GPS Fix
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = Sound on missing or lost GPS fix
|
||||||
|
category = OBP40 Buzzer
|
||||||
|
capabilities = obp40:false
|
||||||
|
|
||||||
|
[buzzerLim]
|
||||||
|
label = Buzzer by Limits
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = Sound on limit violation
|
||||||
|
category = OBP40 Buzzer
|
||||||
|
capabilities = obp40:false
|
||||||
|
|
||||||
|
[buzzerMode]
|
||||||
|
label = Buzzer Mode
|
||||||
|
type = list
|
||||||
|
default = Off
|
||||||
|
description = Settings for buzzer behaviour
|
||||||
|
list = Off, Short Single Beep, Longer Single Beep, Beep until Confirmation
|
||||||
|
category = OBP40 Buzzer
|
||||||
|
capabilities = obp40:false
|
||||||
|
|
||||||
|
[buzzerPower]
|
||||||
|
label = Buzzer Power [%%]
|
||||||
|
type = number
|
||||||
|
default = 50
|
||||||
|
description = Buzzer loudness [0...100%%]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 100
|
||||||
|
category = OBP40 Buzzer
|
||||||
|
capabilities = obp40:false
|
||||||
|
|
||||||
|
[visiblePages]
|
||||||
|
label = Number of Pages
|
||||||
|
type = number
|
||||||
|
default = 10
|
||||||
|
description = Number of visible data pages [1...10]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 1
|
||||||
|
max = 10
|
||||||
|
category = OBP40 Pages
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[startPage]
|
||||||
|
label = Start Page
|
||||||
|
type = number
|
||||||
|
default = 1
|
||||||
|
description = First page number to display after device startup
|
||||||
|
check = checkMinMax
|
||||||
|
min = 1
|
||||||
|
max = 10
|
||||||
|
category = OBP40 Pages
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[systemPage]
|
||||||
|
label = System Page
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = Use wheel button for system page or direct deep sleep mode
|
||||||
|
category = OBP40 Pages
|
||||||
|
capabilities = obp40:true
|
||||||
|
|
||||||
|
[imageFormat]
|
||||||
|
label = Screenshot Format
|
||||||
|
type = list
|
||||||
|
default = PBM
|
||||||
|
description = Graphics file format for screenshots [GIF|PBM|BMP]
|
||||||
|
dict =
|
||||||
|
GIF:Compressed image (GIF)
|
||||||
|
PBM:Portable bitmap (PBM)
|
||||||
|
BMP:Windows bitmap (BMP)
|
||||||
|
category = OBP40 Pages
|
||||||
|
capabilities = obp40:true
|
||||||
857
lib/obp60task/obp60.conf
Normal file
857
lib/obp60task/obp60.conf
Normal file
@@ -0,0 +1,857 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
calibration_fields = AWA, AWS, COG, DBT, HDM, PRPOS, RPOS, SOG, STW, TWA, TWS, TWD, WTemp
|
||||||
|
|
||||||
|
[deviceName]
|
||||||
|
label = system name
|
||||||
|
type = string
|
||||||
|
default = OBP60V2
|
||||||
|
description = system name, used for the access point and for services
|
||||||
|
check = checkSystemName
|
||||||
|
category = system
|
||||||
|
|
||||||
|
[timeServer]
|
||||||
|
label = time server
|
||||||
|
type = string
|
||||||
|
default = pool.ntp.org
|
||||||
|
description = NTP time server. Use only one hostname or IP address
|
||||||
|
category = wifi client
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[timeZone]
|
||||||
|
label = Time Zone
|
||||||
|
type = number
|
||||||
|
default = 0.00
|
||||||
|
description = Time zone [UTC -12...+14]
|
||||||
|
check = checkMinMax
|
||||||
|
min = -12.0
|
||||||
|
max = 14.0
|
||||||
|
category = OBP60 Settings
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[homeLAT]
|
||||||
|
label = Home latitude
|
||||||
|
type = number
|
||||||
|
default =
|
||||||
|
description = Latitude of boat home location [-90.0...+90.0]
|
||||||
|
check = checkMinMax
|
||||||
|
min = -90.0
|
||||||
|
max = 90.0
|
||||||
|
category = OBP60 Settings
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[homeLON]
|
||||||
|
label = Home longitude
|
||||||
|
type = number
|
||||||
|
default =
|
||||||
|
description = Longitude of boat home location [-180.0...+180.0]
|
||||||
|
check = checkMinMax
|
||||||
|
min = -180.0
|
||||||
|
max = 180.0
|
||||||
|
category = OBP60 Settings
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[draft]
|
||||||
|
label = Boat Draft [m]
|
||||||
|
type = number
|
||||||
|
default = 0.00
|
||||||
|
description = The draft of the boat [0...50m]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0.0
|
||||||
|
max = 50.0
|
||||||
|
category = OBP60 Settings
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[chainLength]
|
||||||
|
label = Anchor Chain Length [m]
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = The length of the anchor chain [0...255m]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 255
|
||||||
|
category = OBP60 Settings
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[fuelTank]
|
||||||
|
label = Fuel Tank [l]
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Fuel tank capacity [0...5000l]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 5000
|
||||||
|
category = OBP60 Settings
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[fuelConsumption]
|
||||||
|
label = Fuel Consuption [l/h]
|
||||||
|
type = number
|
||||||
|
default = 0.00
|
||||||
|
description = Medium fuel consumption [0...1000l/h]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0.0
|
||||||
|
max = 1000.0
|
||||||
|
category = OBP60 Settings
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[waterTank]
|
||||||
|
label = Water Tank [l]
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Water tank capacity [0...5000l]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 5000
|
||||||
|
category = OBP60 Settings
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[wasteTank]
|
||||||
|
label = Waste Tank [l]
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Waste tank capacity [0...5000l]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 5000
|
||||||
|
category = OBP60 Settings
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[batteryVoltage]
|
||||||
|
label = Battery Voltage [V]
|
||||||
|
type = list
|
||||||
|
default = 12V
|
||||||
|
description = Battery Voltage [12V|24V]
|
||||||
|
list = 12V, 24V
|
||||||
|
category = OBP60 Settings
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[batteryType]
|
||||||
|
label = Battery Type
|
||||||
|
type = list
|
||||||
|
default = Pb
|
||||||
|
description = Type of battery [Pb|Gel|AGM|LiFePo4]
|
||||||
|
list = Pb, Gel, AGM, LiFePo4
|
||||||
|
category = OBP60 Settings
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[batteryCapacity]
|
||||||
|
label = Battery Capacity [Ah]
|
||||||
|
type = number
|
||||||
|
default = 0.0
|
||||||
|
description = Battery capacity [0...10000Ah]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0.0
|
||||||
|
max = 10000.0
|
||||||
|
category = OBP60 Settings
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[solarPower]
|
||||||
|
label = Solar Power [W]
|
||||||
|
type = number
|
||||||
|
default = 0.0
|
||||||
|
description = Solar power [0...10000W]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0.0
|
||||||
|
max = 10000.0
|
||||||
|
category = OBP60 Settings
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[genPower]
|
||||||
|
label = Genarator Power [W]
|
||||||
|
type = number
|
||||||
|
default = 0.0
|
||||||
|
description = Generator power [0...10000W]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0.0
|
||||||
|
max = 10000.0
|
||||||
|
category = OBP60 Settings
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[trackStep]
|
||||||
|
label = angle [deg]
|
||||||
|
type = number
|
||||||
|
default = 3.0
|
||||||
|
description = track step offset [1...12deg]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 1.0
|
||||||
|
max = 12.0
|
||||||
|
category = OBP60 Settings
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[calcTrueWnds]
|
||||||
|
label = Calculate True Wind
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = If not available, calculate true wind data from appearant wind and other boat data
|
||||||
|
category = OBP60 Settings
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[lengthFormat]
|
||||||
|
label = Length Format
|
||||||
|
type = list
|
||||||
|
default = m
|
||||||
|
description = Length format [m|ft]
|
||||||
|
list = m, ft
|
||||||
|
category = OBP60 Units
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[distanceFormat]
|
||||||
|
label = Distance Format
|
||||||
|
type = list
|
||||||
|
default = nm
|
||||||
|
description = Distance format [m|km|nm]
|
||||||
|
list = m, km, nm
|
||||||
|
category = OBP60 Units
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[speedFormat]
|
||||||
|
label = Speed Format
|
||||||
|
type = list
|
||||||
|
default = kn
|
||||||
|
description = Distance format [m/s|km/h|kn]
|
||||||
|
list = m/s, km/h, kn
|
||||||
|
category = OBP60 Units
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[windspeedFormat]
|
||||||
|
label = Wind Speed Format
|
||||||
|
type = list
|
||||||
|
default = kn
|
||||||
|
description = Wind speed format [m/s|km/h|kn|bft]
|
||||||
|
list = m/s, km/h, kn, bft
|
||||||
|
category = OBP60 Units
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[tempFormat]
|
||||||
|
label = Temperature Format
|
||||||
|
type = list
|
||||||
|
default = C
|
||||||
|
description = Temperature format [K|C|F]
|
||||||
|
list = K, C, F
|
||||||
|
category = OBP60 Units
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[dateFormat]
|
||||||
|
label = Date Format
|
||||||
|
type = list
|
||||||
|
default = DE
|
||||||
|
description = Date format [DE|GB|US|ISO] DE: 31.12.2022, GB: 31/12/2022, US: 12/31/2022, ISO: 2022-12-31
|
||||||
|
list = DE, GB, US, ISO
|
||||||
|
category = OBP60 Units
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[cpuSpeed]
|
||||||
|
label = CPU Speed [MHz]
|
||||||
|
type = list
|
||||||
|
default = 160
|
||||||
|
description = CPU speed in MHz [80|160|240]
|
||||||
|
list = 80, 160, 240
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[useRTC]
|
||||||
|
label = RTC Modul
|
||||||
|
type = list
|
||||||
|
default = DS1388
|
||||||
|
description = Use internal RTC module type [off|DS1388]
|
||||||
|
list = off, DS1388
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[useGPS]
|
||||||
|
label = GPS Sensor
|
||||||
|
type = list
|
||||||
|
default = ATGM336H
|
||||||
|
description = Use internal GPS module type [off|NEO-6M|NEO-M8N|ATGM336H]
|
||||||
|
list = off, NEO-6M, NEO-M8N, ATGM336H
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[hdopAccuracy]
|
||||||
|
label = HDOP Accuracy [m]
|
||||||
|
type = number
|
||||||
|
default = 20
|
||||||
|
description = HDOP ccuracy in m for a valid GPS signal [1...50]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 1
|
||||||
|
max = 50
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[useEnvSensor]
|
||||||
|
label = Env. Sensor
|
||||||
|
type = list
|
||||||
|
default = BMP280
|
||||||
|
description = Use internal or external environment sensor via I2C bus [off|BME280|BMP280|BMP180|BMP085|HTU21|SHT21]
|
||||||
|
list = off, BME280, BMP280, BMP180, BMP085, HTU21, SHT21
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[usePowSensor1]
|
||||||
|
label = Battery Sensor
|
||||||
|
type = list
|
||||||
|
default = off
|
||||||
|
description = Use external power management sensor via I2C bus for battery [off|INA219|INA226|]
|
||||||
|
list = off, INA219, INA226
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[shunt1]
|
||||||
|
label = Battery Shunt
|
||||||
|
type = list
|
||||||
|
default = 10
|
||||||
|
description = Shunt current value [10A|50A|100A|200A|300A|400A|500A]
|
||||||
|
list = 10, 50, 100, 200, 300, 400, 500
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[usePowSensor2]
|
||||||
|
label = Solar Sensor
|
||||||
|
type = list
|
||||||
|
default = off
|
||||||
|
description = Use external power management sensor via I2C bus for solar panels [off|INA219|INA226|]
|
||||||
|
list = off, INA219, INA226
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[shunt2]
|
||||||
|
label = Solar Shunt
|
||||||
|
type = list
|
||||||
|
default = 10
|
||||||
|
description = Shunt current value [10A|50A|100A|200A|300A|400A|500A]
|
||||||
|
list = 10, 50, 100, 200, 300, 400, 500
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[usePowSensor3]
|
||||||
|
label = Gen. Sensor
|
||||||
|
type = list
|
||||||
|
default = off
|
||||||
|
description = Use external power management sensor via I2C bus for generator [off|INA219|INA226|]
|
||||||
|
list = off, INA219, INA226
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[shunt3]
|
||||||
|
label = Gen. Shunt
|
||||||
|
type = list
|
||||||
|
default = 10
|
||||||
|
description = Shunt current value [10A|50A|100A|200A|300A|400A|500A] @ 75mV
|
||||||
|
list = 10, 50, 100, 200, 300, 400, 500
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[useRotSensor]
|
||||||
|
label = Rot. Sensor
|
||||||
|
type = list
|
||||||
|
default = off
|
||||||
|
description = Use external rotation sensor via I2C bus [off|AS5600]
|
||||||
|
list = off, AS5600
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[rotFunction]
|
||||||
|
label = Rot. Function
|
||||||
|
type = list
|
||||||
|
default = off
|
||||||
|
description = Function for rotation sensor [off|Rudder|Wind|Mast|Keel|Trim|Boom]
|
||||||
|
list = off, Rudder, Wind, Mast, Keel, Trim, Boom
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[rotOffset]
|
||||||
|
label = Rot. Offset
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Offset for rotation sensor [-180°...+180°]
|
||||||
|
check = checkMinMax
|
||||||
|
min = -180
|
||||||
|
max = 180
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[rollLimit]
|
||||||
|
label = Roll Limit
|
||||||
|
type = number
|
||||||
|
default = 25
|
||||||
|
description = Limit violation for roll angle [-90°...+90°]
|
||||||
|
check = checkMinMax
|
||||||
|
min = -90
|
||||||
|
max = 90
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[rollOffset]
|
||||||
|
label = Roll Offset
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Roll offset angle [-45°...+45°]
|
||||||
|
check = checkMinMax
|
||||||
|
min = -45
|
||||||
|
max = 45
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[pitchOffset]
|
||||||
|
label = Pitch Offset
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Pitch offset angle [-45°...+45°]
|
||||||
|
check = checkMinMax
|
||||||
|
min = -45
|
||||||
|
max = 45
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[useTempSensor]
|
||||||
|
label = Temp. Sensor
|
||||||
|
type = boolean
|
||||||
|
default = off
|
||||||
|
description = Use max. 8 external 1Wire devices [off|DS18B20]
|
||||||
|
list = off, DS18B20
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[powerMode]
|
||||||
|
label = Power Mode
|
||||||
|
type = list
|
||||||
|
default = Max Power
|
||||||
|
description = Settings for power mode
|
||||||
|
list = Max Power, Only 5.0V, Min Power
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[underVoltage]
|
||||||
|
label = Undervoltage
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = Switch off device if voltage drops below 9V [on|off]
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[useSimuData]
|
||||||
|
label = Simulation Data
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = Use simulation data when bus data are missing [on|off]
|
||||||
|
category = OBP60 Hardware
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[tSensitivity]
|
||||||
|
label = Touch Sensitivity [%%]
|
||||||
|
type = number
|
||||||
|
default = 100
|
||||||
|
description = Touch sensitivity [0...100%%] for sensor buttons
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 100
|
||||||
|
category = OBP60 Calibrations
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[vOffset]
|
||||||
|
label = VSensor Offset
|
||||||
|
type = number
|
||||||
|
default = -1.00
|
||||||
|
description = Offset for internal voltage sensor (ESP32)
|
||||||
|
category = OBP60 Calibrations
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[vSlope]
|
||||||
|
label = VSensor Slope
|
||||||
|
type = number
|
||||||
|
default = 1.00
|
||||||
|
description = Slope for internal voltage sensor (ESP32)
|
||||||
|
category = OBP60 Calibrations
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[calInstance1]
|
||||||
|
label = Calibration Data Instance 1
|
||||||
|
type = list
|
||||||
|
default = ---
|
||||||
|
description = Data instance for calibration
|
||||||
|
list = ---, %(calibration_fields)s
|
||||||
|
category = OBP60 Calibrations
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[calOffset1]
|
||||||
|
label = Data Instance 1 Calibration Offset
|
||||||
|
type = number
|
||||||
|
default = 0.00
|
||||||
|
description = Offset for data instance 1
|
||||||
|
category = OBP60 Calibrations
|
||||||
|
capabilities = obp60:true
|
||||||
|
condition = calInstance1 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[calSlope1]
|
||||||
|
label = Data Instance 1 Calibration Slope
|
||||||
|
type = number
|
||||||
|
default = 1.00
|
||||||
|
description = Slope for data instance 1
|
||||||
|
category = OBP60 Calibrations
|
||||||
|
capabilities = obp60:true
|
||||||
|
condition = calInstance1 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[calSmooth1]
|
||||||
|
label = Data Instance 1 Smoothing
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Smoothing factor [0..10]; 0 = no smoothing
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 10
|
||||||
|
category = OBP60 Calibrations
|
||||||
|
capabilities = obp60:true
|
||||||
|
condition = calInstance1 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[calInstance2]
|
||||||
|
label = Calibration Data Instance 2
|
||||||
|
type = list
|
||||||
|
default = ---
|
||||||
|
description = Data instance for calibration
|
||||||
|
list = ---, %(calibration_fields)s
|
||||||
|
category = OBP60 Calibrations
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[calOffset2]
|
||||||
|
label = Data Instance 2 Calibration Offset
|
||||||
|
type = number
|
||||||
|
default = 0.00
|
||||||
|
description = Offset for data instance 2
|
||||||
|
category = OBP60 Calibrations
|
||||||
|
capabilities = obp60:true
|
||||||
|
condition = calInstance2 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[calSlope2]
|
||||||
|
label = Data Instance 2 Calibration Slope
|
||||||
|
type = number
|
||||||
|
default = 1.00
|
||||||
|
description = Slope for data instance 2
|
||||||
|
category = OBP60 Calibrations
|
||||||
|
capabilities = obp60:true
|
||||||
|
condition = calInstance2 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[calSmooth2]
|
||||||
|
label = Data Instance 2 Smoothing
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Smoothing factor [0..10]; 0 = no smoothing
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 10
|
||||||
|
category = OBP60 Calibrations
|
||||||
|
capabilities = obp60:true
|
||||||
|
condition = calInstance2 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[calInstance3]
|
||||||
|
label = Calibration Data Instance 3
|
||||||
|
type = list
|
||||||
|
default = ---
|
||||||
|
description = Data instance for calibration
|
||||||
|
list = ---, %(calibration_fields)s
|
||||||
|
category = OBP60 Calibrations
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[calOffset3]
|
||||||
|
label = Data Instance 3 Calibration Offset
|
||||||
|
type = number
|
||||||
|
default = 0.00
|
||||||
|
description = Offset for data instance 3
|
||||||
|
category = OBP60 Calibrations
|
||||||
|
capabilities = obp60:true
|
||||||
|
condition = calinstance3 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[calSlope3]
|
||||||
|
label = Data Instance 3 Calibration Slope
|
||||||
|
type = number
|
||||||
|
default = 1.00
|
||||||
|
description = Slope for data instance 3
|
||||||
|
category = OBP60 Calibrations
|
||||||
|
capabilities = obp60:true
|
||||||
|
condition = calinstance3 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[calSmooth3]
|
||||||
|
label = Data Instance 3 Smoothing
|
||||||
|
type = number
|
||||||
|
default = 0
|
||||||
|
description = Smoothing factor [0..10]; 0 = no smoothing
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 10
|
||||||
|
category = OBP60 Calibrations
|
||||||
|
capabilities = obp60:true
|
||||||
|
condition = calinstance3 IN %(calibration_fields)s
|
||||||
|
|
||||||
|
[display]
|
||||||
|
label = Display Mode
|
||||||
|
type = list
|
||||||
|
default = Logo + QR Code
|
||||||
|
description = Settings for startup display
|
||||||
|
list = White Screen, Logo, Logo + QR Code, Off
|
||||||
|
category = OBP60 Display
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[displaycolor]
|
||||||
|
label = Inverted Display Mode
|
||||||
|
type = list
|
||||||
|
default = Normal
|
||||||
|
description = Invert display to white letters on black background [Normal|Inverse]
|
||||||
|
list = Normal, Inverse
|
||||||
|
category = OBP60 Display
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[statusLine]
|
||||||
|
label = Status Line
|
||||||
|
type = boolean
|
||||||
|
default = true
|
||||||
|
description = Show status line [on|off]
|
||||||
|
category = OBP60 Display
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[timeSource]
|
||||||
|
label = Status Time Source
|
||||||
|
type = list
|
||||||
|
default = GPS
|
||||||
|
description = Data source for date and time display in status line [RTC|GPS]
|
||||||
|
dict =
|
||||||
|
RTC:Real time clock (RTC)
|
||||||
|
GPS:Time via bus (GPS)
|
||||||
|
category = OBP60 Display
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[refresh]
|
||||||
|
label = Refresh
|
||||||
|
type = boolean
|
||||||
|
default = true
|
||||||
|
description = Refresh e-paper display after each new page request to reduce ghost effects [on|off]
|
||||||
|
category = OBP60 Display
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[fastRefresh]
|
||||||
|
label = Fast Refresh
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = Fast refresh for e-paper display [on|off]
|
||||||
|
category = OBP60 Display
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[fullRefreshTime]
|
||||||
|
label = Full Refresh Time [min]
|
||||||
|
type = number
|
||||||
|
default = 1
|
||||||
|
description = E-Paper full refresh time all [1...10 min]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 1
|
||||||
|
max = 10
|
||||||
|
category = OBP60 Display
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[holdvalues]
|
||||||
|
label = Hold Values
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = Retain old values when data stream stops [on|off]
|
||||||
|
category = OBP60 Display
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[valueprecision]
|
||||||
|
label = Display value precision
|
||||||
|
type = list
|
||||||
|
default = 2
|
||||||
|
description = Maximum number of decimal places to display [1|2]
|
||||||
|
list = 1, 2
|
||||||
|
category = OBP60 Display
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[headerFormat]
|
||||||
|
label = Header Format
|
||||||
|
type = list
|
||||||
|
default = TEXT
|
||||||
|
description = Header format: Text or Symbols
|
||||||
|
dict =
|
||||||
|
TEXT:Text
|
||||||
|
ICON:Symbols
|
||||||
|
category = OBP60 Pages
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[backlight]
|
||||||
|
label = Backlight Mode
|
||||||
|
type = list
|
||||||
|
default = Control by Key
|
||||||
|
description = Settings for automatic backlight mode
|
||||||
|
list = Off, Control by Sun, Control by Bus, Control by Time, Control by Key, On
|
||||||
|
category = OBP60 Display
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[blColor]
|
||||||
|
label = Backlight Color
|
||||||
|
type = list
|
||||||
|
default = Red
|
||||||
|
description = Backlight color
|
||||||
|
list = Red, Orange, Yellow, Green, Blue, Aqua, Violet, White
|
||||||
|
category = OBP60 Display
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[blBrightness]
|
||||||
|
label = Brightness [%%]
|
||||||
|
type = number
|
||||||
|
default = 50
|
||||||
|
description = Backlight brightness [20...100%%]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 20
|
||||||
|
max = 100
|
||||||
|
category = OBP60 Display
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[flashLED]
|
||||||
|
label = Flash LED Mode
|
||||||
|
type = list
|
||||||
|
default = Limit Violation
|
||||||
|
description = Settings for flash LED
|
||||||
|
list = Off, Bus Data, GPS Fix Lost, Limit Violation
|
||||||
|
category = OBP60 Display
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[buzzerError]
|
||||||
|
label = Buzzer Error
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = Sound on error [on|off]
|
||||||
|
category = OBP60 Buzzer
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[buzzerGps]
|
||||||
|
label = Buzzer GPS Fix
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = Sound on missing or lost GPS fix
|
||||||
|
category = OBP60 Buzzer
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[buzzerLim]
|
||||||
|
label = Buzzer by Limits
|
||||||
|
type = boolean
|
||||||
|
default = false
|
||||||
|
description = Sound on limit violation
|
||||||
|
category = OBP60 Buzzer
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[buzzerMode]
|
||||||
|
label = Buzzer Mode
|
||||||
|
type = list
|
||||||
|
default = Off
|
||||||
|
description = Settings for buzzer behaviour
|
||||||
|
list = Off, Short Single Beep, Longer Single Beep, Beep until Confirmation
|
||||||
|
category = OBP60 Buzzer
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[buzzerPower]
|
||||||
|
label = Buzzer Power [%%]
|
||||||
|
type = number
|
||||||
|
default = 50
|
||||||
|
description = Buzzer loudness [0...100%%]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 0
|
||||||
|
max = 100
|
||||||
|
category = OBP60 Buzzer
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[visiblePages]
|
||||||
|
label = Number of Pages
|
||||||
|
type = number
|
||||||
|
default = 10
|
||||||
|
description = Number of visible data pages [1...10]
|
||||||
|
check = checkMinMax
|
||||||
|
min = 1
|
||||||
|
max = 10
|
||||||
|
category = OBP60 Pages
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[startPage]
|
||||||
|
label = Start Page
|
||||||
|
type = number
|
||||||
|
default = 1
|
||||||
|
description = First page number to display after device startup
|
||||||
|
check = checkMinMax
|
||||||
|
min = 1
|
||||||
|
max = 10
|
||||||
|
category = OBP60 Pages
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[imageFormat]
|
||||||
|
label = Screenshot Format
|
||||||
|
type = list
|
||||||
|
default = PBM
|
||||||
|
description = Graphics file format for screenshots [GIF|PBM|BMP]
|
||||||
|
dict =
|
||||||
|
GIF:Compressed image (GIF)
|
||||||
|
PBM:Portable bitmap (PBM)
|
||||||
|
BMP:Windows bitmap (BMP)
|
||||||
|
category = OBP60 Pages
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
# WIP
|
||||||
|
|
||||||
|
[trackerType]
|
||||||
|
label = Tracker Type
|
||||||
|
type = list
|
||||||
|
default = off
|
||||||
|
description = Type of tracker to use [OFF|SDCARD|SERVER|HERO]
|
||||||
|
dict = OFF:No tracker
|
||||||
|
SDCARD:Log to SD-Card
|
||||||
|
SERVER:Log to Server
|
||||||
|
HERO:Connect with Regatta Hero
|
||||||
|
category = OBP60 Pages
|
||||||
|
capabilities = obp60:true
|
||||||
|
|
||||||
|
[trackerOrganization]
|
||||||
|
label = Tracker team
|
||||||
|
type = string
|
||||||
|
default = demo
|
||||||
|
description = Tracker organization for login
|
||||||
|
category = OBP60 Pages
|
||||||
|
|
||||||
|
[trackerPasscode]
|
||||||
|
label = Tracker team
|
||||||
|
type = password
|
||||||
|
default = 291758
|
||||||
|
description = Your tracker team you belong to. E.g. short name of association
|
||||||
|
category = OBP60 Pages
|
||||||
|
|
||||||
|
[trackerTeam]
|
||||||
|
label = Tracker team
|
||||||
|
type = string
|
||||||
|
default = none
|
||||||
|
description = Your tracker team you belong to. E.g. short name of association
|
||||||
|
category = OBP60 Pages
|
||||||
|
|
||||||
|
[trackerHandicap]
|
||||||
|
label = Boat handicap
|
||||||
|
type = number
|
||||||
|
default = 100
|
||||||
|
check = checkMinMax
|
||||||
|
min = 50
|
||||||
|
max = 1000
|
||||||
|
description = The handicap value of your boat. E.g. yardstick value
|
||||||
|
category = OBP60 Pages
|
||||||
|
|
||||||
|
[boatName]
|
||||||
|
label = Boat Name
|
||||||
|
type = string
|
||||||
|
default = Unsinkbar II
|
||||||
|
description = name of your boat
|
||||||
|
category = OBP60 Pages
|
||||||
|
|
||||||
|
[boatClass]
|
||||||
|
label = Boat Class
|
||||||
|
type = string
|
||||||
|
default = One off
|
||||||
|
description = Class name of your boat if available or "One off"
|
||||||
|
category = OBP60 Pages
|
||||||
|
|
||||||
|
[sailNumber]
|
||||||
|
label = Sail number
|
||||||
|
type = string
|
||||||
|
default = GER 11
|
||||||
|
description = Identification number on sail
|
||||||
|
category = OBP60 Pages
|
||||||
|
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
#if defined BOARD_OBP60S3 || defined BOARD_OBP40S3
|
||||||
#include "obp60task.h"
|
#include "obp60task.h"
|
||||||
#include "Pagedata.h" // Data exchange for pages
|
#include "Pagedata.h" // Data exchange for pages
|
||||||
|
#include "OBP60Formatter.h" // Data formatting for boat values
|
||||||
#include "OBP60Hardware.h" // PIN definitions
|
#include "OBP60Hardware.h" // PIN definitions
|
||||||
#include <Wire.h> // I2C connections
|
#include <Wire.h> // I2C connections
|
||||||
#include <MCP23017.h> // MCP23017 extension Port
|
#include <MCP23017.h> // MCP23017 extension Port
|
||||||
@@ -11,29 +13,22 @@
|
|||||||
#include <NMEA0183Messages.h>
|
#include <NMEA0183Messages.h>
|
||||||
#include <GxEPD2_BW.h> // GxEPD2 lib for b/w E-Ink displays
|
#include <GxEPD2_BW.h> // GxEPD2 lib for b/w E-Ink displays
|
||||||
#include "OBP60Extensions.h" // Functions lib for extension board
|
#include "OBP60Extensions.h" // Functions lib for extension board
|
||||||
#include "OBP60Keypad.h" // Functions for keypad
|
#include "OBPKeyboardTask.h" // Functions lib for keyboard handling
|
||||||
#include "BoatDataCalibration.h" // Functions lib for data instance calibration
|
#include "BoatDataCalibration.h" // Functions lib for data instance calibration
|
||||||
#include "OBPRingBuffer.h" // Functions lib with ring buffer for history storage of some boat data
|
|
||||||
#include "OBPDataOperations.h" // Functions lib for data operations such as true wind calculation
|
#include "OBPDataOperations.h" // Functions lib for data operations such as true wind calculation
|
||||||
|
|
||||||
#ifdef BOARD_OBP40S3
|
|
||||||
#include "driver/rtc_io.h" // Needs for weakup from deep sleep
|
|
||||||
#include <FS.h> // SD-Card access
|
|
||||||
#include <SD.h>
|
|
||||||
#include <SPI.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// True type character sets includes
|
|
||||||
// See OBP60ExtensionPort.cpp
|
|
||||||
|
|
||||||
// Pictures
|
|
||||||
//#include GxEPD_BitmapExamples // Example picture
|
|
||||||
#include "MFD_OBP60_400x300_sw.h" // MFD with logo
|
|
||||||
#include "Logo_OBP_400x300_sw.h" // OBP Logo
|
|
||||||
#include "images/unknown.xbm" // unknown page indicator
|
|
||||||
#include "OBP60QRWiFi.h" // Functions lib for WiFi QR code
|
#include "OBP60QRWiFi.h" // Functions lib for WiFi QR code
|
||||||
#include "OBPSensorTask.h" // Functions lib for sensor data
|
#include "OBPSensorTask.h" // Functions lib for sensor data
|
||||||
|
|
||||||
|
#include "freertos/task.h" // WIP possible unused
|
||||||
|
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
#include "driver/rtc_io.h" // Needs for weakup from deep sleep
|
||||||
|
#include <SPI.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Pictures
|
||||||
|
#include "images/OBP_400x300.xbm" // OBP Logo
|
||||||
|
#include "images/unknown.xbm" // unknown page indicator
|
||||||
|
|
||||||
// Global vars
|
// Global vars
|
||||||
bool initComplete = false; // Initialization complete
|
bool initComplete = false; // Initialization complete
|
||||||
@@ -47,63 +42,23 @@ void OBP60Init(GwApi *api){
|
|||||||
GwConfigHandler *config = api->getConfig();
|
GwConfigHandler *config = api->getConfig();
|
||||||
|
|
||||||
// Set a new device name and hidden the original name in the main config
|
// Set a new device name and hidden the original name in the main config
|
||||||
String devicename = api->getConfig()->getConfigItem(api->getConfig()->deviceName,true)->asString();
|
String devicename = config->getConfigItem(config->deviceName, true)->asString();
|
||||||
api->getConfig()->setValue(GwConfigDefinitions::systemName, devicename, GwConfigInterface::ConfigType::HIDDEN);
|
config->setValue(GwConfigDefinitions::systemName, devicename, GwConfigInterface::ConfigType::HIDDEN);
|
||||||
|
|
||||||
api->getLogger()->logDebug(GwLog::LOG,"obp60init running");
|
logger->prefix = devicename + ":";
|
||||||
|
logger->logDebug(GwLog::LOG,"obp60init running");
|
||||||
|
|
||||||
// Check I2C devices
|
// Check I2C devices
|
||||||
|
|
||||||
|
// Init power
|
||||||
|
String powermode = config->getConfigItem(config->powerMode,true)->asString();
|
||||||
|
logger->logDebug(GwLog::DEBUG, "Power Mode is: %s", powermode.c_str());
|
||||||
|
powerInit(powermode);
|
||||||
|
|
||||||
// Init hardware
|
// Init hardware
|
||||||
hardwareInit(api);
|
hardwareInit(api);
|
||||||
|
|
||||||
// Init power rail 5.0V
|
|
||||||
String powermode = api->getConfig()->getConfigItem(api->getConfig()->powerMode,true)->asString();
|
|
||||||
api->getLogger()->logDebug(GwLog::DEBUG,"Power Mode is: %s", powermode.c_str());
|
|
||||||
if(powermode == "Max Power" || powermode == "Only 5.0V"){
|
|
||||||
#ifdef HARDWARE_V21
|
|
||||||
setPortPin(OBP_POWER_50, true); // Power on 5.0V rail
|
|
||||||
#endif
|
|
||||||
#ifdef BOARD_OBP40S3
|
#ifdef BOARD_OBP40S3
|
||||||
setPortPin(OBP_POWER_EPD, true);// Power on ePaper display
|
|
||||||
setPortPin(OBP_POWER_SD, true); // Power on SD card
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
#ifdef HARDWARE_V21
|
|
||||||
setPortPin(OBP_POWER_50, false); // Power off 5.0V rail
|
|
||||||
#endif
|
|
||||||
#ifdef BOARD_OBP40S3
|
|
||||||
setPortPin(OBP_POWER_EPD, false);// Power off ePaper display
|
|
||||||
setPortPin(OBP_POWER_SD, false); // Power off SD card
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef BOARD_OBP40S3
|
|
||||||
bool sdcard = config->getBool(config->useSDCard);
|
|
||||||
if (sdcard) {
|
|
||||||
SPIClass SD_SPI = SPIClass(HSPI);
|
|
||||||
SD_SPI.begin(SD_SPI_CLK, SD_SPI_MISO, SD_SPI_MOSI);
|
|
||||||
if (SD.begin(SD_SPI_CS, SD_SPI, 80000000)) {
|
|
||||||
String sdtype = "unknown";
|
|
||||||
uint8_t cardType = SD.cardType();
|
|
||||||
switch (cardType) {
|
|
||||||
case CARD_MMC:
|
|
||||||
sdtype = "MMC";
|
|
||||||
break;
|
|
||||||
case CARD_SD:
|
|
||||||
sdtype = "SDSC";
|
|
||||||
break;
|
|
||||||
case CARD_SDHC:
|
|
||||||
sdtype = "SDHC";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
|
|
||||||
LOG_DEBUG(GwLog::LOG,"SD card type %s of size %d MB detected", sdtype, cardSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deep sleep wakeup configuration
|
// Deep sleep wakeup configuration
|
||||||
esp_sleep_enable_ext0_wakeup(OBP_WAKEWUP_PIN, 0); // 1 = High, 0 = Low
|
esp_sleep_enable_ext0_wakeup(OBP_WAKEWUP_PIN, 0); // 1 = High, 0 = Low
|
||||||
rtc_gpio_pullup_en(OBP_WAKEWUP_PIN); // Activate pullup resistor
|
rtc_gpio_pullup_en(OBP_WAKEWUP_PIN); // Activate pullup resistor
|
||||||
@@ -111,8 +66,8 @@ void OBP60Init(GwApi *api){
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Settings for e-paper display
|
// Settings for e-paper display
|
||||||
String fastrefresh = api->getConfig()->getConfigItem(api->getConfig()->fastRefresh,true)->asString();
|
String fastrefresh = config->getConfigItem(config->fastRefresh,true)->asString();
|
||||||
api->getLogger()->logDebug(GwLog::DEBUG,"Fast Refresh Mode is: %s", fastrefresh.c_str());
|
logger->logDebug(GwLog::DEBUG, "Fast Refresh Mode is: %s", fastrefresh.c_str());
|
||||||
#ifdef DISPLAY_GDEY042T81
|
#ifdef DISPLAY_GDEY042T81
|
||||||
if(fastrefresh == "true"){
|
if(fastrefresh == "true"){
|
||||||
static const bool useFastFullUpdate = true; // Enable fast full display update only for GDEY042T81
|
static const bool useFastFullUpdate = true; // Enable fast full display update only for GDEY042T81
|
||||||
@@ -131,27 +86,27 @@ void OBP60Init(GwApi *api){
|
|||||||
|
|
||||||
// Get CPU speed
|
// Get CPU speed
|
||||||
int freq = getCpuFrequencyMhz();
|
int freq = getCpuFrequencyMhz();
|
||||||
api->getLogger()->logDebug(GwLog::LOG,"CPU speed at boot: %i MHz", freq);
|
logger->logDebug(GwLog::LOG,"CPU speed at boot: %i MHz", freq);
|
||||||
|
|
||||||
// Settings for backlight
|
// Settings for backlight
|
||||||
String backlightMode = api->getConfig()->getConfigItem(api->getConfig()->backlight,true)->asString();
|
String backlightMode = config->getConfigItem(config->backlight,true)->asString();
|
||||||
api->getLogger()->logDebug(GwLog::DEBUG,"Backlight Mode is: %s", backlightMode.c_str());
|
logger->logDebug(GwLog::DEBUG, "Backlight Mode is: %s", backlightMode.c_str());
|
||||||
uint brightness = uint(api->getConfig()->getConfigItem(api->getConfig()->blBrightness,true)->asInt());
|
uint brightness = uint(config->getConfigItem(config->blBrightness,true)->asInt());
|
||||||
String backlightColor = api->getConfig()->getConfigItem(api->getConfig()->blColor,true)->asString();
|
String backlightColor = config->getConfigItem(config->blColor,true)->asString();
|
||||||
if(String(backlightMode) == "On"){
|
if (backlightMode == "On") {
|
||||||
setBacklightLED(brightness, colorMapping(backlightColor));
|
setBacklightLED(brightness, colorMapping(backlightColor));
|
||||||
}
|
}
|
||||||
else if(String(backlightMode) == "Off"){
|
else if (backlightMode == "Off") {
|
||||||
setBacklightLED(0, COLOR_BLACK); // Backlight LEDs off (blue without britghness)
|
setBacklightLED(0, COLOR_BLACK); // Backlight LEDs off (blue without britghness)
|
||||||
}
|
}
|
||||||
else if(String(backlightMode) == "Control by Key"){
|
else if (backlightMode == "Control by Key") {
|
||||||
setBacklightLED(0, COLOR_BLUE); // Backlight LEDs off (blue without britghness)
|
setBacklightLED(0, COLOR_BLUE); // Backlight LEDs off (blue without britghness)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Settings flash LED mode
|
// Settings flash LED mode
|
||||||
String ledMode = api->getConfig()->getConfigItem(api->getConfig()->flashLED,true)->asString();
|
String ledMode = config->getConfigItem(config->flashLED,true)->asString();
|
||||||
api->getLogger()->logDebug(GwLog::DEBUG,"LED Mode is: %s", ledMode.c_str());
|
logger->logDebug(GwLog::DEBUG,"LED Mode is: %s", ledMode.c_str());
|
||||||
if(String(ledMode) == "Off"){
|
if (ledMode == "Off") {
|
||||||
setBlinkingLED(false);
|
setBlinkingLED(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,50 +115,33 @@ void OBP60Init(GwApi *api){
|
|||||||
initComplete = true;
|
initComplete = true;
|
||||||
|
|
||||||
// Buzzer tone for initialization finish
|
// Buzzer tone for initialization finish
|
||||||
setBuzzerPower(uint(api->getConfig()->getConfigItem(api->getConfig()->buzzerPower,true)->asInt()));
|
setBuzzerPower(uint(config->getConfigItem(config->buzzerPower,true)->asInt()));
|
||||||
buzzer(TONE4, 500);
|
buzzer(TONE4, 500);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
/* ux-functions not working WTF?
|
||||||
int page0=0;
|
bool listTasks(GwLog *logger) {
|
||||||
QueueHandle_t queue;
|
UBaseType_t taskCount = uxTaskGetNumberOfTasks();
|
||||||
GwLog* logger = NULL;
|
TaskStatus_t *taskStatusArray;
|
||||||
// GwApi* api = NULL;
|
|
||||||
uint sensitivity = 100;
|
|
||||||
bool use_syspage = true;
|
|
||||||
} MyData;
|
|
||||||
|
|
||||||
// Keyboard Task
|
taskStatusArray = (TaskStatus_t *)pvPortMalloc(taskCount * sizeof(TaskStatus_t));
|
||||||
void keyboardTask(void *param){
|
if (taskStatusArray != NULL) {
|
||||||
MyData *data=(MyData *)param;
|
taskCount = uxTaskGetSystemState(taskStatusArray, taskCount, NULL);
|
||||||
|
for (UBaseType_t i = 0; i < taskCount; i++) {
|
||||||
int keycode = 0;
|
logger->logDebug(GwLog::LOG, "Task Name: %s (Stack=%d)", taskStatusArray[i].pcTaskName,
|
||||||
data->logger->logDebug(GwLog::LOG,"Start keyboard task");
|
taskStatusArray[i].usStackHighWaterMark);
|
||||||
|
// more fields in task status
|
||||||
// Loop for keyboard task
|
// xHandle, uxCurrentPriority, uxBasePriority, usStackHighWaterMark
|
||||||
while (true){
|
|
||||||
keycode = readKeypad(data->logger, data->sensitivity, data->use_syspage);
|
|
||||||
//send a key event
|
|
||||||
if(keycode != 0){
|
|
||||||
xQueueSend(data->queue, &keycode, 0);
|
|
||||||
data->logger->logDebug(GwLog::LOG,"Send keycode: %d", keycode);
|
|
||||||
}
|
}
|
||||||
delay(20); // 50Hz update rate (20ms)
|
vPortFree(taskStatusArray);
|
||||||
}
|
return true;
|
||||||
vTaskDelete(NULL);
|
|
||||||
}
|
}
|
||||||
|
logger->logDebug(GwLog::ERROR, "Failed to allocate memory for task list");
|
||||||
|
return false;
|
||||||
|
} */
|
||||||
|
|
||||||
class BoatValueList{
|
bool BoatValueList::addValueToList(GwApi::BoatValue *v){
|
||||||
public:
|
|
||||||
static const int MAXVALUES=100;
|
|
||||||
//we create a list containing all our BoatValues
|
|
||||||
//this is the list we later use to let the api fill all the values
|
|
||||||
//additionally we put the necessary values into the paga data - see below
|
|
||||||
GwApi::BoatValue *allBoatValues[MAXVALUES];
|
|
||||||
int numValues=0;
|
|
||||||
|
|
||||||
bool addValueToList(GwApi::BoatValue *v){
|
|
||||||
for (int i=0;i<numValues;i++){
|
for (int i=0;i<numValues;i++){
|
||||||
if (allBoatValues[i] == v){
|
if (allBoatValues[i] == v){
|
||||||
//already in list...
|
//already in list...
|
||||||
@@ -215,8 +153,9 @@ class BoatValueList{
|
|||||||
numValues++;
|
numValues++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//helper to ensure that each BoatValue is only queried once
|
//helper to ensure that each BoatValue is only queried once
|
||||||
GwApi::BoatValue *findValueOrCreate(String name){
|
GwApi::BoatValue *BoatValueList::findValueOrCreate(String name){
|
||||||
for (int i=0;i<numValues;i++){
|
for (int i=0;i<numValues;i++){
|
||||||
if (allBoatValues[i]->getName() == name) {
|
if (allBoatValues[i]->getName() == name) {
|
||||||
return allBoatValues[i];
|
return allBoatValues[i];
|
||||||
@@ -226,13 +165,11 @@ class BoatValueList{
|
|||||||
addValueToList(rt);
|
addValueToList(rt);
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
//we want to have a list that has all our page definitions
|
//we want to have a list that has all our page definitions
|
||||||
//this way each page can easily be added here
|
//this way each page can easily be added here
|
||||||
//needs some minor tricks for the safe static initialization
|
//needs some minor tricks for the safe static initialization
|
||||||
typedef std::vector<PageDescription*> Pages;
|
typedef std::vector<PageDescription*> Pages;
|
||||||
//the page list class
|
|
||||||
class PageList{
|
class PageList{
|
||||||
public:
|
public:
|
||||||
Pages pages;
|
Pages pages;
|
||||||
@@ -254,12 +191,13 @@ class PageList{
|
|||||||
* each page should have defined a registerXXXPage variable of type
|
* each page should have defined a registerXXXPage variable of type
|
||||||
* PageData that describes what it needs
|
* PageData that describes what it needs
|
||||||
*/
|
*/
|
||||||
void registerAllPages(PageList &list){
|
void registerAllPages(GwLog *logger, PageList &list){
|
||||||
//the next line says that this variable is defined somewhere else
|
//the next line says that this variable is defined somewhere else
|
||||||
//in our case in a separate C++ source file
|
//in our case in a separate C++ source file
|
||||||
//this way this separate source file can be compiled by it's own
|
//this way this separate source file can be compiled by it's own
|
||||||
//and has no access to any of our data except the one that we
|
//and has no access to any of our data except the one that we
|
||||||
//give as a parameter to the page function
|
//give as a parameter to the page function
|
||||||
|
logger->logDebug(GwLog::LOG, "Memory before registering pages: stack=%d, heap=%d", uxTaskGetStackHighWaterMark(NULL), ESP.getFreeHeap());
|
||||||
extern PageDescription registerPageSystem;
|
extern PageDescription registerPageSystem;
|
||||||
//we add the variable to our list
|
//we add the variable to our list
|
||||||
list.add(®isterPageSystem);
|
list.add(®isterPageSystem);
|
||||||
@@ -282,7 +220,7 @@ void registerAllPages(PageList &list){
|
|||||||
extern PageDescription registerPageWindRose;
|
extern PageDescription registerPageWindRose;
|
||||||
list.add(®isterPageWindRose);
|
list.add(®isterPageWindRose);
|
||||||
extern PageDescription registerPageWindRoseFlex;
|
extern PageDescription registerPageWindRoseFlex;
|
||||||
list.add(®isterPageWindRoseFlex); //
|
list.add(®isterPageWindRoseFlex);
|
||||||
extern PageDescription registerPageVoltage;
|
extern PageDescription registerPageVoltage;
|
||||||
list.add(®isterPageVoltage);
|
list.add(®isterPageVoltage);
|
||||||
extern PageDescription registerPageDST810;
|
extern PageDescription registerPageDST810;
|
||||||
@@ -313,41 +251,39 @@ void registerAllPages(PageList &list){
|
|||||||
list.add(®isterPageXTETrack);
|
list.add(®isterPageXTETrack);
|
||||||
extern PageDescription registerPageFluid;
|
extern PageDescription registerPageFluid;
|
||||||
list.add(®isterPageFluid);
|
list.add(®isterPageFluid);
|
||||||
|
extern PageDescription registerPageSkyView;
|
||||||
|
list.add(®isterPageSkyView);
|
||||||
|
extern PageDescription registerPageAnchor;
|
||||||
|
list.add(®isterPageAnchor);
|
||||||
|
extern PageDescription registerPageAIS;
|
||||||
|
list.add(®isterPageAIS);
|
||||||
|
extern PageDescription registerPageBarograph;
|
||||||
|
list.add(®isterPageBarograph);
|
||||||
|
extern PageDescription registerPageTracker;
|
||||||
|
list.add(®isterPageTracker);
|
||||||
|
logger->logDebug(GwLog::LOG,"Memory after registering pages: stack=%d, heap=%d", uxTaskGetStackHighWaterMark(NULL), ESP.getFreeHeap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Undervoltage detection for shutdown display
|
// Undervoltage detection for shutdown display
|
||||||
void underVoltageDetection(GwApi *api, CommonData &common){
|
void underVoltageError(CommonData &common) {
|
||||||
// Read settings
|
|
||||||
double voffset = (api->getConfig()->getConfigItem(api->getConfig()->vOffset,true)->asString()).toFloat();
|
|
||||||
double vslope = (api->getConfig()->getConfigItem(api->getConfig()->vSlope,true)->asString()).toFloat();
|
|
||||||
// Read supply voltage
|
|
||||||
#if defined VOLTAGE_SENSOR && defined LIPO_ACCU_1200
|
|
||||||
float actVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.53) * 2; // Vin = 1/2 for OBP40
|
|
||||||
float minVoltage = 3.65; // Absolut minimum volatge for 3,7V LiPo accu
|
|
||||||
#else
|
|
||||||
float actVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.17) * 20; // Vin = 1/20 for OBP60
|
|
||||||
float minVoltage = MIN_VOLTAGE;
|
|
||||||
#endif
|
|
||||||
double calVoltage = actVoltage * vslope + voffset; // Calibration
|
|
||||||
if(calVoltage < minVoltage){
|
|
||||||
#if defined VOLTAGE_SENSOR && defined LIPO_ACCU_1200
|
#if defined VOLTAGE_SENSOR && defined LIPO_ACCU_1200
|
||||||
// Switch off all power lines
|
// Switch off all power lines
|
||||||
setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off
|
setPortPin(OBP_BACKLIGHT_LED, false); // Backlight Off
|
||||||
setFlashLED(false); // Flash LED Off
|
setFlashLED(false); // Flash LED Off
|
||||||
buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms
|
buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms
|
||||||
// Shutdown EInk display
|
// Shutdown EInk display
|
||||||
getdisplay().setFullWindow(); // Set full Refresh
|
epd->setFullWindow(); // Set full Refresh
|
||||||
//getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
//epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
getdisplay().fillScreen(common.bgcolor);// Clear screen
|
epd->fillScreen(common.bgcolor);// Clear screen
|
||||||
getdisplay().setTextColor(common.fgcolor);
|
epd->setTextColor(common.fgcolor);
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(65, 150);
|
epd->setCursor(65, 150);
|
||||||
getdisplay().print("Undervoltage");
|
epd->print("Undervoltage");
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(65, 175);
|
epd->setCursor(65, 175);
|
||||||
getdisplay().print("Charge battery and restart system");
|
epd->print("Charge battery and restart system");
|
||||||
getdisplay().nextPage(); // Partial update
|
epd->nextPage(); // Partial update
|
||||||
getdisplay().powerOff(); // Display power off
|
epd->powerOff(); // Display power off
|
||||||
setPortPin(OBP_POWER_EPD, false); // Power off ePaper display
|
setPortPin(OBP_POWER_EPD, false); // Power off ePaper display
|
||||||
setPortPin(OBP_POWER_SD, false); // Power off SD card
|
setPortPin(OBP_POWER_SD, false); // Power off SD card
|
||||||
#else
|
#else
|
||||||
@@ -357,141 +293,34 @@ void underVoltageDetection(GwApi *api, CommonData &common){
|
|||||||
buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms
|
buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms
|
||||||
setPortPin(OBP_POWER_50, false); // Power rail 5.0V Off
|
setPortPin(OBP_POWER_50, false); // Power rail 5.0V Off
|
||||||
// Shutdown EInk display
|
// Shutdown EInk display
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
getdisplay().fillScreen(common.bgcolor);// Clear screen
|
epd->fillScreen(common.bgcolor);// Clear screen
|
||||||
getdisplay().setTextColor(common.fgcolor);
|
epd->setTextColor(common.fgcolor);
|
||||||
getdisplay().setFont(&Ubuntu_Bold20pt8b);
|
epd->setFont(&Ubuntu_Bold20pt8b);
|
||||||
getdisplay().setCursor(65, 150);
|
epd->setCursor(65, 150);
|
||||||
getdisplay().print("Undervoltage");
|
epd->print("Undervoltage");
|
||||||
getdisplay().setFont(&Ubuntu_Bold8pt8b);
|
epd->setFont(&Ubuntu_Bold8pt8b);
|
||||||
getdisplay().setCursor(65, 175);
|
epd->setCursor(65, 175);
|
||||||
getdisplay().print("To wake up repower system");
|
epd->print("To wake up repower system");
|
||||||
getdisplay().nextPage(); // Partial update
|
epd->nextPage(); // Partial update
|
||||||
getdisplay().powerOff(); // Display power off
|
epd->powerOff(); // Display power off
|
||||||
#endif
|
#endif
|
||||||
// Stop system
|
|
||||||
while (true) {
|
while (true) {
|
||||||
esp_deep_sleep_start(); // Deep Sleep without weakup. Weakup only after power cycle (restart).
|
esp_deep_sleep_start(); // Deep Sleep without wakeup. Wakeup only after power cycle (restart).
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//bool addTrueWind(GwApi* api, BoatValueList* boatValues, double *twd, double *tws, double *twa) {
|
inline bool underVoltageDetection(float voffset, float vslope) {
|
||||||
bool addTrueWind(GwApi* api, BoatValueList* boatValues) {
|
// Read supply voltage
|
||||||
// Calculate true wind data and add to obp60task boat data list
|
#if defined VOLTAGE_SENSOR && defined LIPO_ACCU_1200
|
||||||
|
float actVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.53) * 2; // Vin = 1/2 for OBP40
|
||||||
double awaVal, awsVal, cogVal, stwVal, sogVal, hdtVal, hdmVal, varVal;
|
float minVoltage = 3.65; // Absolut minimum volatge for 3,7V LiPo accu
|
||||||
double twd, tws, twa;
|
#else
|
||||||
bool isCalculated = false;
|
float actVoltage = (float(analogRead(OBP_ANALOG0)) * 3.3 / 4096 + 0.17) * 20; // Vin = 1/20 for OBP60
|
||||||
const double DBL_MIN = std::numeric_limits<double>::lowest();
|
float minVoltage = MIN_VOLTAGE;
|
||||||
|
#endif
|
||||||
GwApi::BoatValue *twdBVal = boatValues->findValueOrCreate("TWD");
|
float calVoltage = actVoltage * vslope + voffset; // Calibration
|
||||||
GwApi::BoatValue *twsBVal = boatValues->findValueOrCreate("TWS");
|
return (calVoltage < minVoltage);
|
||||||
GwApi::BoatValue *twaBVal = boatValues->findValueOrCreate("TWA");
|
|
||||||
GwApi::BoatValue *awaBVal = boatValues->findValueOrCreate("AWA");
|
|
||||||
GwApi::BoatValue *awsBVal = boatValues->findValueOrCreate("AWS");
|
|
||||||
GwApi::BoatValue *cogBVal = boatValues->findValueOrCreate("COG");
|
|
||||||
GwApi::BoatValue *stwBVal = boatValues->findValueOrCreate("STW");
|
|
||||||
GwApi::BoatValue *sogBVal = boatValues->findValueOrCreate("SOG");
|
|
||||||
GwApi::BoatValue *hdtBVal = boatValues->findValueOrCreate("HDT");
|
|
||||||
GwApi::BoatValue *hdmBVal = boatValues->findValueOrCreate("HDM");
|
|
||||||
GwApi::BoatValue *varBVal = boatValues->findValueOrCreate("VAR");
|
|
||||||
awaVal = awaBVal->valid ? awaBVal->value : DBL_MIN;
|
|
||||||
awsVal = awsBVal->valid ? awsBVal->value : DBL_MIN;
|
|
||||||
cogVal = cogBVal->valid ? cogBVal->value : DBL_MIN;
|
|
||||||
stwVal = stwBVal->valid ? stwBVal->value : DBL_MIN;
|
|
||||||
sogVal = sogBVal->valid ? sogBVal->value : DBL_MIN;
|
|
||||||
hdtVal = hdtBVal->valid ? hdtBVal->value : DBL_MIN;
|
|
||||||
hdmVal = hdmBVal->valid ? hdmBVal->value : DBL_MIN;
|
|
||||||
varVal = varBVal->valid ? varBVal->value : DBL_MIN;
|
|
||||||
api->getLogger()->logDebug(GwLog::DEBUG,"obp60task addTrueWind: AWA %.1f, AWS %.1f, COG %.1f, STW %.1f, SOG %.1f, HDT %.1f, HDM %.1f, VAR %.1f", awaBVal->value * RAD_TO_DEG, awsBVal->value * 3.6 / 1.852,
|
|
||||||
cogBVal->value * RAD_TO_DEG, stwBVal->value * 3.6 / 1.852, sogBVal->value * 3.6 / 1.852, hdtBVal->value * RAD_TO_DEG, hdmBVal->value * RAD_TO_DEG, varBVal->value * RAD_TO_DEG);
|
|
||||||
|
|
||||||
isCalculated = WindUtils::calcTrueWind(&awaVal, &awsVal, &cogVal, &stwVal, &sogVal, &hdtVal, &hdmVal, &varVal, &twd, &tws, &twa);
|
|
||||||
|
|
||||||
if (isCalculated) { // Replace values only, if successfully calculated and not already available
|
|
||||||
if (!twdBVal->valid) {
|
|
||||||
twdBVal->value = twd;
|
|
||||||
twdBVal->valid = true;
|
|
||||||
}
|
|
||||||
if (!twsBVal->valid) {
|
|
||||||
twsBVal->value = tws;
|
|
||||||
twsBVal->valid = true;
|
|
||||||
}
|
|
||||||
if (!twaBVal->valid) {
|
|
||||||
twaBVal->value = twa;
|
|
||||||
twaBVal->valid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
api->getLogger()->logDebug(GwLog::DEBUG,"obp60task addTrueWind: TWD_Valid %d, isCalculated %d, TWD %.1f, TWA %.1f, TWS %.1f", twdBVal->valid, isCalculated, twdBVal->value * RAD_TO_DEG,
|
|
||||||
twaBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852);
|
|
||||||
|
|
||||||
return isCalculated;
|
|
||||||
}
|
|
||||||
|
|
||||||
void initHstryBuf(GwApi* api, BoatValueList* boatValues, tBoatHstryData hstryBufList) {
|
|
||||||
// Init history buffers for TWD, TWS
|
|
||||||
|
|
||||||
GwApi::BoatValue *calBVal; // temp variable just for data calibration -> we don't want to calibrate the original data here
|
|
||||||
|
|
||||||
int hstryUpdFreq = 1000; // Update frequency for history buffers in ms
|
|
||||||
int hstryMinVal = 0; // Minimum value for these history buffers
|
|
||||||
int twdHstryMax = 6283; // Max value for wind direction (TWD) in rad (0...2*PI), shifted by 1000 for 3 decimals
|
|
||||||
int twsHstryMax = 1000; // Max value for wind speed (TWS) in m/s, shifted by 10 for 1 decimal
|
|
||||||
// Initialize history buffers with meta data
|
|
||||||
hstryBufList.twdHstry->setMetaData("TWD", "formatCourse", hstryUpdFreq, hstryMinVal, twdHstryMax);
|
|
||||||
hstryBufList.twsHstry->setMetaData("TWS", "formatKnots", hstryUpdFreq, hstryMinVal, twsHstryMax);
|
|
||||||
|
|
||||||
GwApi::BoatValue *twdBVal = boatValues->findValueOrCreate(hstryBufList.twdHstry->getName());
|
|
||||||
GwApi::BoatValue *twsBVal = boatValues->findValueOrCreate(hstryBufList.twsHstry->getName());
|
|
||||||
GwApi::BoatValue *twaBVal = boatValues->findValueOrCreate("TWA");
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleHstryBuf(GwApi* api, BoatValueList* boatValues, tBoatHstryData hstryBufList) {
|
|
||||||
// Handle history buffers for TWD, TWS
|
|
||||||
|
|
||||||
GwLog *logger = api->getLogger();
|
|
||||||
|
|
||||||
int16_t twdHstryMin = hstryBufList.twdHstry->getMinVal();
|
|
||||||
int16_t twdHstryMax = hstryBufList.twdHstry->getMaxVal();
|
|
||||||
int16_t twsHstryMin = hstryBufList.twsHstry->getMinVal();
|
|
||||||
int16_t twsHstryMax = hstryBufList.twsHstry->getMaxVal();
|
|
||||||
int16_t twdBuf, twsBuf;
|
|
||||||
GwApi::BoatValue *calBVal; // temp variable just for data calibration -> we don't want to calibrate the original data here
|
|
||||||
|
|
||||||
GwApi::BoatValue *twdBVal = boatValues->findValueOrCreate(hstryBufList.twdHstry->getName());
|
|
||||||
GwApi::BoatValue *twsBVal = boatValues->findValueOrCreate(hstryBufList.twsHstry->getName());
|
|
||||||
GwApi::BoatValue *twaBVal = boatValues->findValueOrCreate("TWA");
|
|
||||||
|
|
||||||
api->getLogger()->logDebug(GwLog::DEBUG,"obp60task handleHstryBuf: twdBVal: %.1f, twaBVal: %.1f, twsBVal: %.1f, TWD_isValid? %d", twdBVal->value * RAD_TO_DEG,
|
|
||||||
twaBVal->value * RAD_TO_DEG, twsBVal->value * 3.6 / 1.852, twdBVal->valid);
|
|
||||||
calBVal = new GwApi::BoatValue("TWD"); // temporary solution for calibration of history buffer values
|
|
||||||
calBVal->setFormat(twdBVal->getFormat());
|
|
||||||
if (twdBVal->valid) {
|
|
||||||
calBVal->value = twdBVal->value;
|
|
||||||
calBVal->valid = twdBVal->valid;
|
|
||||||
calibrationData.calibrateInstance(calBVal, logger); // Check if boat data value is to be calibrated
|
|
||||||
twdBuf = static_cast<int16_t>(std::round(calBVal->value * 1000));
|
|
||||||
if (twdBuf >= twdHstryMin && twdBuf <= twdHstryMax) {
|
|
||||||
hstryBufList.twdHstry->add(twdBuf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete calBVal;
|
|
||||||
calBVal = nullptr;
|
|
||||||
|
|
||||||
calBVal = new GwApi::BoatValue("TWS"); // temporary solution for calibration of history buffer values
|
|
||||||
calBVal->setFormat(twsBVal->getFormat());
|
|
||||||
if (twsBVal->valid) {
|
|
||||||
calBVal->value = twsBVal->value;
|
|
||||||
calBVal->valid = twsBVal->valid;
|
|
||||||
calibrationData.calibrateInstance(calBVal, logger); // Check if boat data value is to be calibrated
|
|
||||||
twsBuf = static_cast<int16_t>(std::round(calBVal->value * 10));
|
|
||||||
if (twsBuf >= twsHstryMin && twsBuf <= twsHstryMax) {
|
|
||||||
hstryBufList.twsHstry->add(twsBuf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete calBVal;
|
|
||||||
calBVal = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OBP60 Task
|
// OBP60 Task
|
||||||
@@ -505,10 +334,11 @@ void OBP60Task(GwApi *api){
|
|||||||
startLedTask(api);
|
startLedTask(api);
|
||||||
#endif
|
#endif
|
||||||
PageList allPages;
|
PageList allPages;
|
||||||
registerAllPages(allPages);
|
registerAllPages(logger, allPages);
|
||||||
CommonData commonData;
|
CommonData commonData;
|
||||||
commonData.logger = logger;
|
commonData.logger = logger;
|
||||||
commonData.config = config;
|
commonData.config = config;
|
||||||
|
commonData.fmt = new Formatter(config);
|
||||||
|
|
||||||
#ifdef HARDWARE_V21
|
#ifdef HARDWARE_V21
|
||||||
// Keyboard coordinates for page footer
|
// Keyboard coordinates for page footer
|
||||||
@@ -523,8 +353,8 @@ void OBP60Task(GwApi *api){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Init E-Ink display
|
// Init E-Ink display
|
||||||
String displaymode = api->getConfig()->getConfigItem(api->getConfig()->display,true)->asString();
|
String displaymode = config->getConfigItem(config->display,true)->asString();
|
||||||
String displaycolor = api->getConfig()->getConfigItem(api->getConfig()->displaycolor,true)->asString();
|
String displaycolor = config->getConfigItem(config->displaycolor,true)->asString();
|
||||||
if (displaycolor == "Normal") {
|
if (displaycolor == "Normal") {
|
||||||
commonData.fgcolor = GxEPD_BLACK;
|
commonData.fgcolor = GxEPD_BLACK;
|
||||||
commonData.bgcolor = GxEPD_WHITE;
|
commonData.bgcolor = GxEPD_WHITE;
|
||||||
@@ -533,47 +363,48 @@ void OBP60Task(GwApi *api){
|
|||||||
commonData.fgcolor = GxEPD_WHITE;
|
commonData.fgcolor = GxEPD_WHITE;
|
||||||
commonData.bgcolor = GxEPD_BLACK;
|
commonData.bgcolor = GxEPD_BLACK;
|
||||||
}
|
}
|
||||||
String systemname = api->getConfig()->getConfigItem(api->getConfig()->systemName,true)->asString();
|
String systemname = config->getConfigItem(config->systemName, true)->asString();
|
||||||
String wifipass = api->getConfig()->getConfigItem(api->getConfig()->apPassword,true)->asString();
|
String wifipass = config->getConfigItem(config->apPassword, true)->asString();
|
||||||
bool refreshmode = api->getConfig()->getConfigItem(api->getConfig()->refresh,true)->asBoolean();
|
bool refreshmode = config->getConfigItem(config->refresh, true)->asBoolean();
|
||||||
String fastrefresh = api->getConfig()->getConfigItem(api->getConfig()->fastRefresh,true)->asString();
|
bool symbolmode = (config->getString(config->headerFormat) == "ICON");
|
||||||
uint fullrefreshtime = uint(api->getConfig()->getConfigItem(api->getConfig()->fullRefreshTime,true)->asInt());
|
String fastrefresh = config->getConfigItem(config->fastRefresh, true)->asString();
|
||||||
|
uint fullrefreshtime = uint(config->getConfigItem(config->fullRefreshTime, true)->asInt());
|
||||||
#ifdef BOARD_OBP40S3
|
#ifdef BOARD_OBP40S3
|
||||||
bool syspage_enabled = config->getBool(config->systemPage);
|
bool syspage_enabled = config->getBool(config->systemPage);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DISPLAY_GDEY042T81
|
#ifdef DISPLAY_GDEY042T81
|
||||||
getdisplay().init(115200, true, 2, false); // Init for Waveshare boards with "clever" reset circuit, 2ms reset pulse
|
epd->init(115200, true, 2, false); // Init for Waveshare boards with "clever" reset circuit, 2ms reset pulse
|
||||||
#else
|
#else
|
||||||
getdisplay().init(115200); // Init for normal displays
|
epd->init(115200); // Init for normal displays
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
getdisplay().setRotation(0); // Set display orientation (horizontal)
|
epd->setRotation(0); // Set display orientation (horizontal)
|
||||||
getdisplay().setFullWindow(); // Set full Refresh
|
epd->setFullWindow(); // Set full Refresh
|
||||||
getdisplay().firstPage(); // set first page
|
epd->firstPage(); // set first page
|
||||||
getdisplay().fillScreen(commonData.bgcolor);
|
epd->fillScreen(commonData.bgcolor);
|
||||||
getdisplay().setTextColor(commonData.fgcolor);
|
epd->setTextColor(commonData.fgcolor);
|
||||||
getdisplay().nextPage(); // Full Refresh
|
epd->nextPage(); // Full Refresh
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
getdisplay().fillScreen(commonData.bgcolor);
|
epd->fillScreen(commonData.bgcolor);
|
||||||
getdisplay().nextPage(); // Fast Refresh
|
epd->nextPage(); // Fast Refresh
|
||||||
getdisplay().nextPage(); // Fast Refresh
|
epd->nextPage(); // Fast Refresh
|
||||||
if(String(displaymode) == "Logo + QR Code" || String(displaymode) == "Logo"){
|
if(String(displaymode) == "Logo + QR Code" || String(displaymode) == "Logo"){
|
||||||
getdisplay().fillScreen(commonData.bgcolor);
|
epd->fillScreen(commonData.bgcolor);
|
||||||
getdisplay().drawBitmap(0, 0, gImage_Logo_OBP_400x300_sw, getdisplay().width(), getdisplay().height(), commonData.fgcolor); // Draw start logo
|
epd->drawXBitmap(0, 0, OBP_400x300_bits, OBP_400x300_width, OBP_400x300_height, commonData.fgcolor);
|
||||||
getdisplay().nextPage(); // Fast Refresh
|
epd->nextPage(); // Fast Refresh
|
||||||
getdisplay().nextPage(); // Fast Refresh
|
epd->nextPage(); // Fast Refresh
|
||||||
delay(SHOW_TIME); // Logo show time
|
delay(SHOW_TIME); // Logo show time
|
||||||
if(String(displaymode) == "Logo + QR Code"){
|
if(String(displaymode) == "Logo + QR Code"){
|
||||||
getdisplay().fillScreen(commonData.bgcolor);
|
epd->fillScreen(commonData.bgcolor);
|
||||||
qrWiFi(systemname, wifipass, commonData.fgcolor, commonData.bgcolor); // Show QR code for WiFi connection
|
qrWiFi(systemname, wifipass, commonData.fgcolor, commonData.bgcolor); // Show QR code for WiFi connection
|
||||||
getdisplay().nextPage(); // Fast Refresh
|
epd->nextPage(); // Fast Refresh
|
||||||
getdisplay().nextPage(); // Fast Refresh
|
epd->nextPage(); // Fast Refresh
|
||||||
delay(SHOW_TIME); // QR code show time
|
delay(SHOW_TIME); // QR code show time
|
||||||
}
|
}
|
||||||
getdisplay().fillScreen(commonData.bgcolor);
|
epd->fillScreen(commonData.bgcolor);
|
||||||
getdisplay().nextPage(); // Fast Refresh
|
epd->nextPage(); // Fast Refresh
|
||||||
getdisplay().nextPage(); // Fast Refresh
|
epd->nextPage(); // Fast Refresh
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init pages
|
// Init pages
|
||||||
@@ -604,14 +435,11 @@ void OBP60Task(GwApi *api){
|
|||||||
int lastPage=pageNumber;
|
int lastPage=pageNumber;
|
||||||
|
|
||||||
BoatValueList boatValues; //all the boat values for the api query
|
BoatValueList boatValues; //all the boat values for the api query
|
||||||
|
HstryBuf hstryBufList(960); // Create ring buffers for history storage of some boat data
|
||||||
|
WindUtils trueWind(&boatValues); // Create helper object for true wind calculation
|
||||||
//commonData.distanceformat=config->getString(xxx);
|
//commonData.distanceformat=config->getString(xxx);
|
||||||
//add all necessary data to common data
|
//add all necessary data to common data
|
||||||
|
|
||||||
// Create ring buffers for history storage of some boat data
|
|
||||||
RingBuffer<int16_t> twdHstry(960); // Circular buffer to store wind direction values; store 960 TWD values for 16 minutes history
|
|
||||||
RingBuffer<int16_t> twsHstry(960); // Circular buffer to store wind speed values (TWS)
|
|
||||||
tBoatHstryData hstryBufList = {&twdHstry, &twsHstry};
|
|
||||||
|
|
||||||
//fill the page data from config
|
//fill the page data from config
|
||||||
numPages=config->getInt(config->visiblePages,1);
|
numPages=config->getInt(config->visiblePages,1);
|
||||||
if (numPages < 1) numPages=1;
|
if (numPages < 1) numPages=1;
|
||||||
@@ -632,6 +460,7 @@ void OBP60Task(GwApi *api){
|
|||||||
pages[i].page=description->creator(commonData);
|
pages[i].page=description->creator(commonData);
|
||||||
pages[i].parameters.pageName=pageType;
|
pages[i].parameters.pageName=pageType;
|
||||||
pages[i].parameters.pageNumber = i + 1;
|
pages[i].parameters.pageNumber = i + 1;
|
||||||
|
pages[i].parameters.api = api;
|
||||||
LOG_DEBUG(GwLog::DEBUG,"found page %s for number %d",pageType.c_str(),i);
|
LOG_DEBUG(GwLog::DEBUG,"found page %s for number %d",pageType.c_str(),i);
|
||||||
//fill in all the user defined parameters
|
//fill in all the user defined parameters
|
||||||
for (int uid=0;uid<description->userParam;uid++){
|
for (int uid=0;uid<description->userParam;uid++){
|
||||||
@@ -650,10 +479,8 @@ void OBP60Task(GwApi *api){
|
|||||||
LOG_DEBUG(GwLog::DEBUG,"added fixed value %s to page %d",value->getName().c_str(),i);
|
LOG_DEBUG(GwLog::DEBUG,"added fixed value %s to page %d",value->getName().c_str(),i);
|
||||||
pages[i].parameters.values.push_back(value);
|
pages[i].parameters.values.push_back(value);
|
||||||
}
|
}
|
||||||
if (pages[i].description->pageName == "WindPlot") {
|
|
||||||
// Add boat history data to page parameters
|
// Add boat history data to page parameters
|
||||||
pages[i].parameters.boatHstry = hstryBufList;
|
pages[i].parameters.boatHstry = &hstryBufList;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// add out of band system page (always available)
|
// add out of band system page (always available)
|
||||||
Page *syspage = allPages.pages[0]->creator(commonData);
|
Page *syspage = allPages.pages[0]->creator(commonData);
|
||||||
@@ -661,12 +488,12 @@ void OBP60Task(GwApi *api){
|
|||||||
// Read all calibration data settings from config
|
// Read all calibration data settings from config
|
||||||
calibrationData.readConfig(config, logger);
|
calibrationData.readConfig(config, logger);
|
||||||
|
|
||||||
// Check user setting for true wind calculation
|
// Check user settings for true wind calculation
|
||||||
bool calcTrueWnds = api->getConfig()->getBool(api->getConfig()->calcTrueWnds, false);
|
bool calcTrueWnds = api->getConfig()->getBool(api->getConfig()->calcTrueWnds, false);
|
||||||
// bool simulation = api->getConfig()->getBool(api->getConfig()->useSimuData, false);
|
bool useSimuData = api->getConfig()->getBool(api->getConfig()->useSimuData, false);
|
||||||
|
|
||||||
// Initialize history buffer for certain boat data
|
// Initialize history buffer for certain boat data
|
||||||
initHstryBuf(api, &boatValues, hstryBufList);
|
hstryBufList.init(&boatValues, logger);
|
||||||
|
|
||||||
// Display screenshot handler for HTTP request
|
// Display screenshot handler for HTTP request
|
||||||
// http://192.168.15.1/api/user/OBP60Task/screenshot
|
// http://192.168.15.1/api/user/OBP60Task/screenshot
|
||||||
@@ -676,15 +503,15 @@ void OBP60Task(GwApi *api){
|
|||||||
|
|
||||||
// now we have prepared the page data
|
// now we have prepared the page data
|
||||||
// we start a separate task that will fetch our keys...
|
// we start a separate task that will fetch our keys...
|
||||||
MyData allParameters;
|
KbTaskData kbparams;
|
||||||
allParameters.logger=api->getLogger();
|
kbparams.logger = api->getLogger();
|
||||||
allParameters.page0=3;
|
kbparams.queue = xQueueCreate(10, sizeof(int));
|
||||||
allParameters.queue=xQueueCreate(10,sizeof(int));
|
kbparams.sensitivity = api->getConfig()->getInt(GwConfigDefinitions::tSensitivity);
|
||||||
allParameters.sensitivity= api->getConfig()->getInt(GwConfigDefinitions::tSensitivity);
|
|
||||||
#ifdef BOARD_OBP40S3
|
#ifdef BOARD_OBP40S3
|
||||||
allParameters.use_syspage = syspage_enabled;
|
kbparams.use_syspage = syspage_enabled;
|
||||||
#endif
|
#endif
|
||||||
xTaskCreate(keyboardTask,"keyboard",2000,&allParameters,configMAX_PRIORITIES-1,NULL);
|
createKeyboardTask(&kbparams);
|
||||||
|
// we start a separate task to collect sensor data
|
||||||
SharedData *shared = new SharedData(api);
|
SharedData *shared = new SharedData(api);
|
||||||
createSensorTask(shared);
|
createSensorTask(shared);
|
||||||
|
|
||||||
@@ -692,26 +519,28 @@ void OBP60Task(GwApi *api){
|
|||||||
//####################################################################################
|
//####################################################################################
|
||||||
|
|
||||||
// Configuration values for main loop
|
// Configuration values for main loop
|
||||||
String gpsFix = api->getConfig()->getConfigItem(api->getConfig()->flashLED,true)->asString();
|
String gpsFix = config->getConfigItem(config->flashLED,true)->asString();
|
||||||
String gpsOn=api->getConfig()->getConfigItem(api->getConfig()->useGPS,true)->asString();
|
String gpsOn = config->getConfigItem(config->useGPS,true)->asString();
|
||||||
float tz = api->getConfig()->getConfigItem(api->getConfig()->timeZone,true)->asFloat();
|
float tz = config->getConfigItem(config->timeZone,true)->asFloat();
|
||||||
|
|
||||||
commonData.backlight.mode = backlightMapping(config->getConfigItem(config->backlight, true)->asString());
|
commonData.backlight.mode = backlightMapping(config->getConfigItem(config->backlight, true)->asString());
|
||||||
commonData.backlight.color = colorMapping(config->getConfigItem(config->blColor, true)->asString());
|
commonData.backlight.color = colorMapping(config->getConfigItem(config->blColor, true)->asString());
|
||||||
commonData.backlight.brightness = 2.55 * uint(config->getConfigItem(config->blBrightness, true)->asInt());
|
commonData.backlight.brightness = 2.55 * uint(config->getConfigItem(config->blBrightness, true)->asInt());
|
||||||
commonData.powermode = api->getConfig()->getConfigItem(api->getConfig()->powerMode, true)->asString();
|
commonData.powermode = api->getConfig()->getConfigItem(api->getConfig()->powerMode, true)->asString();
|
||||||
|
|
||||||
bool uvoltage = api->getConfig()->getConfigItem(api->getConfig()->underVoltage,true)->asBoolean();
|
bool uvoltage = config->getConfigItem(config->underVoltage, true)->asBoolean();
|
||||||
String cpuspeed = api->getConfig()->getConfigItem(api->getConfig()->cpuSpeed,true)->asString();
|
float voffset = (config->getConfigItem(config->vOffset,true)->asString()).toFloat();
|
||||||
uint hdopAccuracy = uint(api->getConfig()->getConfigItem(api->getConfig()->hdopAccuracy,true)->asInt());
|
float vslope = (config->getConfigItem(config->vSlope,true)->asString()).toFloat();
|
||||||
|
String cpuspeed = config->getConfigItem(config->cpuSpeed, true)->asString();
|
||||||
|
uint hdopAccuracy = uint(config->getConfigItem(config->hdopAccuracy, true)->asInt());
|
||||||
|
|
||||||
double homelat = commonData.config->getString(commonData.config->homeLAT).toDouble();
|
double homelat = config->getString(config->homeLAT).toDouble();
|
||||||
double homelon = commonData.config->getString(commonData.config->homeLON).toDouble();
|
double homelon = config->getString(config->homeLON).toDouble();
|
||||||
bool homevalid = homelat >= -180.0 and homelat <= 180 and homelon >= -90.0 and homelon <= 90.0;
|
bool homevalid = homelat >= -180.0 and homelat <= 180 and homelon >= -90.0 and homelon <= 90.0;
|
||||||
if (homevalid) {
|
if (homevalid) {
|
||||||
LOG_DEBUG(GwLog::LOG, "Home location set to %f : %f", homelat, homelon);
|
logger->logDebug(GwLog::LOG, "Home location set to lat=%f, lon=%f", homelat, homelon);
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG(GwLog::LOG, "No valid home location found");
|
logger->logDebug(GwLog::LOG, "No valid home location found");
|
||||||
}
|
}
|
||||||
|
|
||||||
// refreshmode defined in init section
|
// refreshmode defined in init section
|
||||||
@@ -739,10 +568,13 @@ void OBP60Task(GwApi *api){
|
|||||||
|
|
||||||
pages[pageNumber].page->setupKeys(); // Initialize keys for first page
|
pages[pageNumber].page->setupKeys(); // Initialize keys for first page
|
||||||
|
|
||||||
|
// listTasks(logger);
|
||||||
|
|
||||||
// Main loop runs with 100ms
|
// Main loop runs with 100ms
|
||||||
//####################################################################################
|
//####################################################################################
|
||||||
|
|
||||||
bool systemPage = false;
|
bool systemPage = false;
|
||||||
|
bool systemPageNew = false;
|
||||||
Page *currentPage;
|
Page *currentPage;
|
||||||
while (true){
|
while (true){
|
||||||
delay(100); // Delay 100ms (loop time)
|
delay(100); // Delay 100ms (loop time)
|
||||||
@@ -750,7 +582,10 @@ void OBP60Task(GwApi *api){
|
|||||||
|
|
||||||
// Undervoltage detection
|
// Undervoltage detection
|
||||||
if (uvoltage == true) {
|
if (uvoltage == true) {
|
||||||
underVoltageDetection(api, commonData);
|
if (underVoltageDetection(voffset, vslope)) {
|
||||||
|
LOG_DEBUG(GwLog::ERROR, "Undervoltage detected, shutting down!");
|
||||||
|
underVoltageError(commonData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set CPU speed after boot after 1min
|
// Set CPU speed after boot after 1min
|
||||||
@@ -786,7 +621,7 @@ void OBP60Task(GwApi *api){
|
|||||||
|
|
||||||
// Check the keyboard message
|
// Check the keyboard message
|
||||||
int keyboardMessage=0;
|
int keyboardMessage=0;
|
||||||
while (xQueueReceive(allParameters.queue,&keyboardMessage,0)){
|
while (xQueueReceive(kbparams.queue,&keyboardMessage, 0)) {
|
||||||
LOG_DEBUG(GwLog::LOG,"new key from keyboard %d",keyboardMessage);
|
LOG_DEBUG(GwLog::LOG,"new key from keyboard %d",keyboardMessage);
|
||||||
keypressed = true;
|
keypressed = true;
|
||||||
|
|
||||||
@@ -795,6 +630,7 @@ void OBP60Task(GwApi *api){
|
|||||||
systemPage = true; // System page is out of band
|
systemPage = true; // System page is out of band
|
||||||
syspage->setupKeys();
|
syspage->setupKeys();
|
||||||
keyboardMessage = 0;
|
keyboardMessage = 0;
|
||||||
|
systemPageNew = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
currentPage = pages[pageNumber].page;
|
currentPage = pages[pageNumber].page;
|
||||||
@@ -884,23 +720,23 @@ void OBP60Task(GwApi *api){
|
|||||||
if(millis() > starttime4 + 4000 && delayedDisplayUpdate == true){
|
if(millis() > starttime4 + 4000 && delayedDisplayUpdate == true){
|
||||||
starttime1 = millis();
|
starttime1 = millis();
|
||||||
starttime2 = millis();
|
starttime2 = millis();
|
||||||
getdisplay().setFullWindow(); // Set full update
|
epd->setFullWindow(); // Set full update
|
||||||
if(fastrefresh == "true"){
|
if(fastrefresh == "true"){
|
||||||
getdisplay().nextPage(); // Full update
|
epd->nextPage(); // Full update
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().fillScreen(commonData.fgcolor); // Clear display
|
epd->fillScreen(commonData.fgcolor); // Clear display
|
||||||
#ifdef DISPLAY_GDEY042T81
|
#ifdef DISPLAY_GDEY042T81
|
||||||
getdisplay().init(115200, true, 2, false); // Init for Waveshare boards with "clever" reset circuit, 2ms reset pulse
|
epd->init(115200, true, 2, false); // Init for Waveshare boards with "clever" reset circuit, 2ms reset pulse
|
||||||
#else
|
#else
|
||||||
getdisplay().init(115200); // Init for normal displays
|
epd->init(115200); // Init for normal displays
|
||||||
#endif
|
#endif
|
||||||
getdisplay().firstPage(); // Full update
|
epd->firstPage(); // Full update
|
||||||
getdisplay().nextPage(); // Full update
|
epd->nextPage(); // Full update
|
||||||
// getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
// epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
// getdisplay().fillScreen(commonData.bgcolor); // Clear display
|
// epd->fillScreen(commonData.bgcolor); // Clear display
|
||||||
// getdisplay().nextPage(); // Partial update
|
// epd->nextPage(); // Partial update
|
||||||
// getdisplay().nextPage(); // Partial update
|
// epd->nextPage(); // Partial update
|
||||||
}
|
}
|
||||||
delayedDisplayUpdate = false;
|
delayedDisplayUpdate = false;
|
||||||
}
|
}
|
||||||
@@ -911,23 +747,23 @@ void OBP60Task(GwApi *api){
|
|||||||
starttime1 = millis();
|
starttime1 = millis();
|
||||||
starttime2 = millis();
|
starttime2 = millis();
|
||||||
LOG_DEBUG(GwLog::DEBUG,"E-Ink full refresh first 5 min");
|
LOG_DEBUG(GwLog::DEBUG,"E-Ink full refresh first 5 min");
|
||||||
getdisplay().setFullWindow(); // Set full update
|
epd->setFullWindow(); // Set full update
|
||||||
if(fastrefresh == "true"){
|
if(fastrefresh == "true"){
|
||||||
getdisplay().nextPage(); // Full update
|
epd->nextPage(); // Full update
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().fillScreen(commonData.fgcolor); // Clear display
|
epd->fillScreen(commonData.fgcolor); // Clear display
|
||||||
#ifdef DISPLAY_GDEY042T81
|
#ifdef DISPLAY_GDEY042T81
|
||||||
getdisplay().init(115200, true, 2, false); // Init for Waveshare boards with "clever" reset circuit, 2ms reset pulse
|
epd->init(115200, true, 2, false); // Init for Waveshare boards with "clever" reset circuit, 2ms reset pulse
|
||||||
#else
|
#else
|
||||||
getdisplay().init(115200); // Init for normal displays
|
epd->init(115200); // Init for normal displays
|
||||||
#endif
|
#endif
|
||||||
getdisplay().firstPage(); // Full update
|
epd->firstPage(); // Full update
|
||||||
getdisplay().nextPage(); // Full update
|
epd->nextPage(); // Full update
|
||||||
// getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
// epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
// getdisplay().fillScreen(commonData.bgcolor); // Clear display
|
// epd->fillScreen(commonData.bgcolor); // Clear display
|
||||||
// getdisplay().nextPage(); // Partial update
|
// epd->nextPage(); // Partial update
|
||||||
// getdisplay().nextPage(); // Partial update
|
// epd->nextPage(); // Partial update
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -935,23 +771,23 @@ void OBP60Task(GwApi *api){
|
|||||||
if(millis() > starttime2 + fullrefreshtime * 60 * 1000){
|
if(millis() > starttime2 + fullrefreshtime * 60 * 1000){
|
||||||
starttime2 = millis();
|
starttime2 = millis();
|
||||||
LOG_DEBUG(GwLog::DEBUG,"E-Ink full refresh");
|
LOG_DEBUG(GwLog::DEBUG,"E-Ink full refresh");
|
||||||
getdisplay().setFullWindow(); // Set full update
|
epd->setFullWindow(); // Set full update
|
||||||
if(fastrefresh == "true"){
|
if(fastrefresh == "true"){
|
||||||
getdisplay().nextPage(); // Full update
|
epd->nextPage(); // Full update
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
getdisplay().fillScreen(commonData.fgcolor); // Clear display
|
epd->fillScreen(commonData.fgcolor); // Clear display
|
||||||
#ifdef DISPLAY_GDEY042T81
|
#ifdef DISPLAY_GDEY042T81
|
||||||
getdisplay().init(115200, true, 2, false); // Init for Waveshare boards with "clever" reset circuit, 2ms reset pulse
|
epd->init(115200, true, 2, false); // Init for Waveshare boards with "clever" reset circuit, 2ms reset pulse
|
||||||
#else
|
#else
|
||||||
getdisplay().init(115200); // Init for normal displays
|
epd->init(115200); // Init for normal displays
|
||||||
#endif
|
#endif
|
||||||
getdisplay().firstPage(); // Full update
|
epd->firstPage(); // Full update
|
||||||
getdisplay().nextPage(); // Full update
|
epd->nextPage(); // Full update
|
||||||
// getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
// epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
// getdisplay().fillScreen(commonData.bgcolor); // Clear display
|
// epd->fillScreen(commonData.bgcolor); // Clear display
|
||||||
// getdisplay().nextPage(); // Partial update
|
// epd->nextPage(); // Partial update
|
||||||
// getdisplay().nextPage(); // Partial update
|
// epd->nextPage(); // Partial update
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -971,42 +807,48 @@ void OBP60Task(GwApi *api){
|
|||||||
api->getStatus(commonData.status);
|
api->getStatus(commonData.status);
|
||||||
|
|
||||||
if (calcTrueWnds) {
|
if (calcTrueWnds) {
|
||||||
addTrueWind(api, &boatValues);
|
trueWind.addTrueWind(api, &boatValues, logger);
|
||||||
}
|
}
|
||||||
// Handle history buffers for TWD, TWS for wind plot page and other usage
|
// Handle history buffers for TWD, TWS for wind plot page and other usage
|
||||||
handleHstryBuf(api, &boatValues, hstryBufList);
|
hstryBufList.handleHstryBuf(useSimuData);
|
||||||
|
|
||||||
// Clear display
|
// Clear display
|
||||||
// getdisplay().fillRect(0, 0, getdisplay().width(), getdisplay().height(), commonData.bgcolor);
|
// epd->fillRect(0, 0, epd->width(), epd->height(), commonData.bgcolor);
|
||||||
getdisplay().fillScreen(commonData.bgcolor); // Clear display
|
epd->fillScreen(commonData.bgcolor); // Clear display
|
||||||
|
|
||||||
// Show header if enabled
|
// Show header if enabled
|
||||||
if (pages[pageNumber].description && pages[pageNumber].description->header or systemPage){
|
if (pages[pageNumber].description && pages[pageNumber].description->header or systemPage){
|
||||||
// build header using commonData
|
// build header using commonData
|
||||||
displayHeader(commonData, date, time, hdop); // Show page header
|
displayHeader(commonData, symbolmode, date, time, hdop); // Show page header
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the particular page
|
// Call the particular page
|
||||||
if (systemPage) {
|
if (systemPage) {
|
||||||
displayFooter(commonData);
|
displayFooter(commonData);
|
||||||
PageData sysparams; // empty
|
PageData sysparams; // empty
|
||||||
|
sysparams.api = api;
|
||||||
|
if (systemPageNew) {
|
||||||
|
syspage->displayNew(sysparams);
|
||||||
|
systemPageNew = false;
|
||||||
|
}
|
||||||
syspage->displayPage(sysparams);
|
syspage->displayPage(sysparams);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (currentPage == NULL){
|
if (currentPage == NULL){
|
||||||
LOG_DEBUG(GwLog::ERROR,"page number %d not found", pageNumber);
|
LOG_DEBUG(GwLog::ERROR,"page number %d not found", pageNumber);
|
||||||
// Error handling for missing page
|
// Error handling for missing page
|
||||||
getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update
|
epd->setPartialWindow(0, 0, epd->width(), epd->height()); // Set partial update
|
||||||
getdisplay().fillScreen(commonData.bgcolor); // Clear display
|
epd->fillScreen(commonData.bgcolor); // Clear display
|
||||||
getdisplay().drawXBitmap(200 - unknown_width / 2, 150 - unknown_height / 2, unknown_bits, unknown_width, unknown_height, commonData.fgcolor);
|
epd->drawXBitmap(200 - unknown_width / 2, 150 - unknown_height / 2, unknown_bits, unknown_width, unknown_height, commonData.fgcolor);
|
||||||
getdisplay().setCursor(140, 250);
|
epd->setCursor(140, 250);
|
||||||
getdisplay().setFont(&Atari16px);
|
epd->setFont(&Atari16px);
|
||||||
getdisplay().print("Here be dragons!");
|
epd->print("Here be dragons!");
|
||||||
getdisplay().nextPage(); // Partial update (fast)
|
epd->nextPage(); // Partial update (fast)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (lastPage != pageNumber){
|
if (lastPage != pageNumber){
|
||||||
if (hasFRAM) fram.write(FRAM_PAGE_NO, pageNumber); // remember page for device restart
|
pages[lastPage].page->leavePage(pages[lastPage].parameters); // call page cleanup code
|
||||||
|
if (hasFRAM) fram.write(FRAM_PAGE_NO, pageNumber); // remember new page for device restart
|
||||||
currentPage->setupKeys();
|
currentPage->setupKeys();
|
||||||
currentPage->displayNew(pages[pageNumber].parameters);
|
currentPage->displayNew(pages[pageNumber].parameters);
|
||||||
lastPage = pageNumber;
|
lastPage = pageNumber;
|
||||||
@@ -1022,10 +864,10 @@ void OBP60Task(GwApi *api){
|
|||||||
displayAlarm(commonData);
|
displayAlarm(commonData);
|
||||||
}
|
}
|
||||||
if (ret & PAGE_UPDATE) {
|
if (ret & PAGE_UPDATE) {
|
||||||
getdisplay().nextPage(); // Partial update (fast)
|
epd->nextPage(); // Partial update (fast)
|
||||||
}
|
}
|
||||||
if (ret & PAGE_HIBERNATE) {
|
if (ret & PAGE_HIBERNATE) {
|
||||||
getdisplay().hibernate();
|
epd->hibernate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "GwApi.h"
|
#include "GwApi.h"
|
||||||
//we only compile for some boards
|
//we only compile for some boards
|
||||||
@@ -41,5 +42,24 @@
|
|||||||
#ifdef BOARD_OBP40S3
|
#ifdef BOARD_OBP40S3
|
||||||
DECLARE_CAPABILITY(obp40,true)
|
DECLARE_CAPABILITY(obp40,true)
|
||||||
#endif
|
#endif
|
||||||
DECLARE_STRING_CAPABILITY(HELP_URL, "https://obp60-v2-docu.readthedocs.io/de/latest/"); // Link to help pages
|
#ifdef BOARD_OBP60S3
|
||||||
|
DECLARE_STRING_CAPABILITY(HELP_URL, "https://obp60-v2-docu.readthedocs.io/en/latest/"); // Link to help pages
|
||||||
|
#endif
|
||||||
|
#ifdef BOARD_OBP40S3
|
||||||
|
DECLARE_STRING_CAPABILITY(HELP_URL, "https://obp40-v1-docu.readthedocs.io/en/latest/"); // Link to help pages
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class BoatValueList{
|
||||||
|
public:
|
||||||
|
static const int MAXVALUES=100;
|
||||||
|
//we create a list containing all our BoatValues
|
||||||
|
//this is the list we later use to let the api fill all the values
|
||||||
|
//additionally we put the necessary values into the paga data - see below
|
||||||
|
GwApi::BoatValue *allBoatValues[MAXVALUES];
|
||||||
|
int numValues=0;
|
||||||
|
|
||||||
|
bool addValueToList(GwApi::BoatValue *v);
|
||||||
|
//helper to ensure that each BoatValue is only queried once
|
||||||
|
GwApi::BoatValue *findValueOrCreate(String name);
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ default_envs =
|
|||||||
obp40_s3
|
obp40_s3
|
||||||
|
|
||||||
[env:obp60_s3]
|
[env:obp60_s3]
|
||||||
platform = espressif32@6.8.1
|
|
||||||
board_build.variants_dir = variants
|
board_build.variants_dir = variants
|
||||||
#board = obp60_s3_n8 #ESP32-S3 N8, 8MB flash, no PSRAM
|
#board = obp60_s3_n8 #ESP32-S3 N8, 8MB flash, no PSRAM
|
||||||
#board = obp60_s3_n16 #ESP32-S3 N16,16MB flash, no PSRAM, zero series
|
#board = obp60_s3_n16 #ESP32-S3 N16,16MB flash, no PSRAM, zero series
|
||||||
@@ -16,20 +15,18 @@ board_build.variants_dir = variants
|
|||||||
board = obp60_s3_n16r8 #ESP32-S3 N16R8, 16MB flash, 8MB PSRAM, production series
|
board = obp60_s3_n16r8 #ESP32-S3 N16R8, 16MB flash, 8MB PSRAM, production series
|
||||||
#board_build.partitions = default_8MB.csv #ESP32-S3 N8, 8MB flash
|
#board_build.partitions = default_8MB.csv #ESP32-S3 N8, 8MB flash
|
||||||
board_build.partitions = default_16MB.csv #ESP32-S3 N16, 16MB flash
|
board_build.partitions = default_16MB.csv #ESP32-S3 N16, 16MB flash
|
||||||
|
board_name = OBP60
|
||||||
framework = arduino
|
framework = arduino
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${basedeps.lib_deps}
|
${basedeps.lib_deps}
|
||||||
Wire
|
Wire
|
||||||
SPI
|
SPI
|
||||||
ESP32time
|
ESP32time
|
||||||
esphome/AsyncTCP-esphome@2.0.1
|
|
||||||
robtillaart/PCF8574@0.3.9
|
robtillaart/PCF8574@0.3.9
|
||||||
adafruit/Adafruit Unified Sensor @ 1.1.13
|
adafruit/Adafruit Unified Sensor @ 1.1.13
|
||||||
blemasle/MCP23017@2.0.0
|
blemasle/MCP23017@2.0.0
|
||||||
adafruit/Adafruit BusIO@1.5.0
|
adafruit/Adafruit BusIO@1.5.0
|
||||||
adafruit/Adafruit GFX Library@1.11.9
|
adafruit/Adafruit GFX Library@1.11.9
|
||||||
#zinggjm/GxEPD2@1.5.8
|
|
||||||
#https://github.com/ZinggJM/GxEPD2
|
|
||||||
https://github.com/thooge/GxEPD2
|
https://github.com/thooge/GxEPD2
|
||||||
sstaub/Ticker@4.4.0
|
sstaub/Ticker@4.4.0
|
||||||
adafruit/Adafruit BMP280 Library@2.6.2
|
adafruit/Adafruit BMP280 Library@2.6.2
|
||||||
@@ -54,6 +51,8 @@ build_flags=
|
|||||||
# -D DISPLAY_GYE042A87 #alternativ E-Ink display from Genyo Optical, R10 2.2 ohm - medium
|
# -D DISPLAY_GYE042A87 #alternativ E-Ink display from Genyo Optical, R10 2.2 ohm - medium
|
||||||
# -D DISPLAY_SE0420NQ04 #alternativ E-Ink display from SID Technology, R10 2.2 ohm - bad (burn in effects)
|
# -D DISPLAY_SE0420NQ04 #alternativ E-Ink display from SID Technology, R10 2.2 ohm - bad (burn in effects)
|
||||||
# -D DISPLAY_ZJY400300-042CAAMFGN #alternativ E-Ink display from ZZE Technology, R10 2.2 ohm - very good
|
# -D DISPLAY_ZJY400300-042CAAMFGN #alternativ E-Ink display from ZZE Technology, R10 2.2 ohm - very good
|
||||||
|
# -D ENABLE_TRUEWIND # calculate true wind data (default off)
|
||||||
|
# -D ENABLE_CALIBRATION # boat data calibration (default off)
|
||||||
${env.build_flags}
|
${env.build_flags}
|
||||||
#CONFIG_ESP_TASK_WDT_TIMEOUT_S = 10 #Task Watchdog timeout period (seconds) [1...60] 5 default
|
#CONFIG_ESP_TASK_WDT_TIMEOUT_S = 10 #Task Watchdog timeout period (seconds) [1...60] 5 default
|
||||||
upload_port = /dev/ttyACM0 #OBP60 download via USB-C direct
|
upload_port = /dev/ttyACM0 #OBP60 download via USB-C direct
|
||||||
@@ -62,26 +61,22 @@ upload_speed = 230400
|
|||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|
||||||
[env:obp40_s3]
|
[env:obp40_s3]
|
||||||
platform = espressif32@6.8.1
|
|
||||||
board_build.variants_dir = variants
|
board_build.variants_dir = variants
|
||||||
board = obp40_s3_n8r8 #ESP32-S3 N8R8, 8MB flash, 8MB PSRAM, OBP60 clone (CrowPanel 4.2)
|
board = obp40_s3_n8r8 #ESP32-S3 N8R8, 8MB flash, 8MB PSRAM, OBP60 clone (CrowPanel 4.2)
|
||||||
board_build.partitions = default_8MB.csv #ESP32-S3 N8, 8MB flash
|
board_build.partitions = default_8MB.csv #ESP32-S3 N8, 8MB flash
|
||||||
|
board_name = OBP40
|
||||||
custom_config = config_obp40.json
|
custom_config = config_obp40.json
|
||||||
framework = arduino
|
framework = arduino
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${basedeps.lib_deps}
|
${basedeps.lib_deps}
|
||||||
Wire
|
Wire
|
||||||
SPI
|
SPI
|
||||||
SD
|
|
||||||
ESP32time
|
ESP32time
|
||||||
esphome/AsyncTCP-esphome@2.0.1
|
|
||||||
robtillaart/PCF8574@0.3.9
|
robtillaart/PCF8574@0.3.9
|
||||||
adafruit/Adafruit Unified Sensor @ 1.1.13
|
adafruit/Adafruit Unified Sensor @ 1.1.13
|
||||||
blemasle/MCP23017@2.0.0
|
blemasle/MCP23017@2.0.0
|
||||||
adafruit/Adafruit BusIO@1.5.0
|
adafruit/Adafruit BusIO@1.5.0
|
||||||
adafruit/Adafruit GFX Library@1.11.9
|
adafruit/Adafruit GFX Library@1.11.9
|
||||||
#zinggjm/GxEPD2@1.5.8
|
|
||||||
#https://github.com/ZinggJM/GxEPD2
|
|
||||||
https://github.com/thooge/GxEPD2
|
https://github.com/thooge/GxEPD2
|
||||||
sstaub/Ticker@4.4.0
|
sstaub/Ticker@4.4.0
|
||||||
adafruit/Adafruit BMP280 Library@2.6.2
|
adafruit/Adafruit BMP280 Library@2.6.2
|
||||||
@@ -101,6 +96,8 @@ build_flags=
|
|||||||
#-D DISPLAY_ZJY400300-042CAAMFGN #alternativ E-Ink display from ZZE Technology, R10 2.2 ohm - very good
|
#-D DISPLAY_ZJY400300-042CAAMFGN #alternativ E-Ink display from ZZE Technology, R10 2.2 ohm - very good
|
||||||
# -D LIPO_ACCU_1200 #Hardware extension, LiPo accu 3,7V 1200mAh
|
# -D LIPO_ACCU_1200 #Hardware extension, LiPo accu 3,7V 1200mAh
|
||||||
# -D VOLTAGE_SENSOR #Hardware extension, LiPo voltage sensor with two resistors
|
# -D VOLTAGE_SENSOR #Hardware extension, LiPo voltage sensor with two resistors
|
||||||
|
# -D ENABLE_TRUEWIND # calculate true wind data (default off)
|
||||||
|
# -D ENABLE_CALIBRATION # boat data calibration (default off)
|
||||||
${env.build_flags}
|
${env.build_flags}
|
||||||
upload_port = /dev/ttyUSB0 #OBP40 download via external USB/Serail converter
|
upload_port = /dev/ttyUSB0 #OBP40 download via external USB/Serail converter
|
||||||
upload_protocol = esptool #firmware upload via USB OTG seriell, by first upload need to set the ESP32-S3 in the upload mode with shortcut GND to Pin27
|
upload_protocol = esptool #firmware upload via USB OTG seriell, by first upload need to set the ESP32-S3 in the upload mode with shortcut GND to Pin27
|
||||||
|
|||||||
17
lib/obp60task/utils/auto_version.py
Normal file
17
lib/obp60task/utils/auto_version.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import subprocess
|
||||||
|
|
||||||
|
# Import("env")
|
||||||
|
|
||||||
|
def get_firmware_specifier_build_flag():
|
||||||
|
#ret = subprocess.run(["git", "describe"], stdout=subprocess.PIPE, text=True) #Uses only annotated tags
|
||||||
|
ret = subprocess.run(["git", "describe", "--tags"], stdout=subprocess.PIPE, text=True) #Uses any tags
|
||||||
|
build_version = ret.stdout.strip()
|
||||||
|
build_flag = "-D AUTO_VERSION=\\\"" + build_version + "\\\""
|
||||||
|
print ("Firmware Revision: " + build_version)
|
||||||
|
return (build_flag)
|
||||||
|
|
||||||
|
#env.Append(
|
||||||
|
# BUILD_FLAGS=[get_firmware_specifier_build_flag()]
|
||||||
|
#)
|
||||||
|
|
||||||
|
get_firmware_specifier_build_flag()
|
||||||
172
lib/obp60task/utils/make_json.py
Executable file
172
lib/obp60task/utils/make_json.py
Executable file
@@ -0,0 +1,172 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Convert config file to JSON
|
||||||
|
|
||||||
|
The JSON contains array of single fields. There is no hierarchy.
|
||||||
|
Fields are being grouped in GUI with "category".
|
||||||
|
A group is shown if a minimum of one field is visible.
|
||||||
|
|
||||||
|
Hints
|
||||||
|
capabilities is a dictionary
|
||||||
|
field:[true | false]
|
||||||
|
optional comma separated multiple values
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import getopt
|
||||||
|
import configparser
|
||||||
|
from io import StringIO
|
||||||
|
from pyparsing import alphas, alphanums, Word, Literal, Combine, Group, Forward, ZeroOrMore, delimitedList
|
||||||
|
|
||||||
|
__author__ = "Thomas Hooge"
|
||||||
|
__copyright__ = "Copyleft 2025, all rights reversed"
|
||||||
|
__version__ = "0.1"
|
||||||
|
__email__ = "thomas@hoogi.de"
|
||||||
|
__status__ = "Development"
|
||||||
|
|
||||||
|
infile = None
|
||||||
|
outfile = ""
|
||||||
|
force = False # overwrite outfile
|
||||||
|
|
||||||
|
# Variables for condition parsing
|
||||||
|
fieldname = Combine(Word(alphas, exact=1) + Word(alphanums, max=15))
|
||||||
|
fieldvalue = Word(alphanums, max=16)
|
||||||
|
equals = Literal("=")
|
||||||
|
in_op = Literal("IN")
|
||||||
|
and_op = Literal("AND")
|
||||||
|
or_op = Literal("OR")
|
||||||
|
comparison = Group(fieldname + equals + fieldvalue) \
|
||||||
|
| Group(fieldname + in_op + delimitedList(fieldvalue))
|
||||||
|
expr = Forward()
|
||||||
|
expr <<= comparison + ZeroOrMore((and_op | or_op) + comparison)
|
||||||
|
|
||||||
|
def parse_condition(condition):
|
||||||
|
try:
|
||||||
|
result = expr.parseString(condition, parseAll=True)
|
||||||
|
except Exception as e:
|
||||||
|
return ""
|
||||||
|
out = StringIO()
|
||||||
|
andlist = []
|
||||||
|
for token in result:
|
||||||
|
# list: field = value or field IN value [, value ...]
|
||||||
|
# str: AND, OR
|
||||||
|
# combine ANDs and output reaching OR
|
||||||
|
if type(token) == str:
|
||||||
|
if token == "OR":
|
||||||
|
andstr = ",\n".join(andlist)
|
||||||
|
out.write(f'\t\t{{ {andstr} }},\n')
|
||||||
|
andlist = []
|
||||||
|
else:
|
||||||
|
if token[1] == '=':
|
||||||
|
andlist.append(f'"{token[0]}": "{token[2]}"')
|
||||||
|
elif token[1] == 'IN':
|
||||||
|
n = len(token) - 2
|
||||||
|
if n == 1:
|
||||||
|
# no list, write single value
|
||||||
|
andlist.append(f'"{token[0]}": "{token[2]}"')
|
||||||
|
else:
|
||||||
|
# write list
|
||||||
|
inlist = '", "'.join(token[2:])
|
||||||
|
andlist.append(f'"{token[0]}": [ "{inlist}" ]\n')
|
||||||
|
|
||||||
|
if len(andlist) > 0:
|
||||||
|
out.write("\t\t{{ {} }}".format(", ".join(andlist)))
|
||||||
|
return out.getvalue()
|
||||||
|
|
||||||
|
def create_flist():
|
||||||
|
flist = []
|
||||||
|
for field in config.sections():
|
||||||
|
properties = [f'\t"name": "{field}"']
|
||||||
|
for prop, val in config.items(field):
|
||||||
|
if prop in ["label", "type", "default", "description", "category", "check"]:
|
||||||
|
properties.append(f'\t"{prop}": "{val}"')
|
||||||
|
elif prop == "capabilities":
|
||||||
|
# multiple values possible
|
||||||
|
capas = []
|
||||||
|
for capa in val.split(','):
|
||||||
|
k, v = capa.split(':')
|
||||||
|
capas.append(f'"{k.strip()}":"{v.strip()}"')
|
||||||
|
capalist = ','.join(capas)
|
||||||
|
properties.append(f'\t"{prop}": {{{capalist}}}')
|
||||||
|
elif prop in ("min", "max"):
|
||||||
|
properties.append(f'\t"{prop}": {val}')
|
||||||
|
elif prop == "list":
|
||||||
|
entries = '", "'.join([x.strip() for x in val.split(',')])
|
||||||
|
properties.append(f'\t"list": ["{entries}"]')
|
||||||
|
elif prop == "dict":
|
||||||
|
d = {}
|
||||||
|
for l in val.splitlines():
|
||||||
|
if len(l) < 3:
|
||||||
|
continue
|
||||||
|
k, v = l.split(':')
|
||||||
|
d[k.strip()] = v.strip()
|
||||||
|
lines = []
|
||||||
|
for k,v in d.items():
|
||||||
|
lines.append(f'\t\t{{"l":"{v}","v":"{k}"}}')
|
||||||
|
entries = ",\n".join(lines)
|
||||||
|
properties.append(f'\t"list": [\n{entries}\n\t]')
|
||||||
|
elif prop == "condition":
|
||||||
|
jsoncond = parse_condition(val)
|
||||||
|
properties.append(f'\t"{prop}": [\n{jsoncond}\n\t]\n')
|
||||||
|
else:
|
||||||
|
pass # ignore unknown stuff
|
||||||
|
fieldprops = ",\n".join(properties)
|
||||||
|
flist.append(f'{{\n{fieldprops}\n}}')
|
||||||
|
return flist
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
print("{} v{}".format(os.path.basename(__file__), __version__))
|
||||||
|
print(__copyright__)
|
||||||
|
print()
|
||||||
|
print("Command line options")
|
||||||
|
print(" -c --config config file name to use")
|
||||||
|
print(" -j --json json file name to generate")
|
||||||
|
print(" -f force overwrite of existing json file")
|
||||||
|
print(" -h show this help")
|
||||||
|
print()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
options, remainder = getopt.getopt(sys.argv[1:], 'c:j:fh', ['config=', 'json='])
|
||||||
|
except getopt.GetoptError as e:
|
||||||
|
print(e)
|
||||||
|
sys.exit(1)
|
||||||
|
filename = None
|
||||||
|
for opt, arg in options:
|
||||||
|
if opt in ('-c', '--config'):
|
||||||
|
infile = arg
|
||||||
|
elif opt in ('-j', '--json'):
|
||||||
|
outfile = arg
|
||||||
|
elif opt == '-h':
|
||||||
|
usage()
|
||||||
|
sys.exit(0)
|
||||||
|
elif opt == '-f':
|
||||||
|
force = True
|
||||||
|
if not infile:
|
||||||
|
print("Error: config filename missing")
|
||||||
|
sys.exit(1)
|
||||||
|
if not os.path.isfile(infile):
|
||||||
|
print(f"Error: configuration file '{filename} not found'")
|
||||||
|
sys.exit(1)
|
||||||
|
if os.path.isfile(outfile) and not force:
|
||||||
|
print(f"Error: json file '{outfile}' already exists")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
ret = config.read(infile)
|
||||||
|
if len(ret) == 0:
|
||||||
|
print(f"ERROR: Config file '{infile}' not found")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
flist = create_flist()
|
||||||
|
out = "[\n{}\n]\n".format(",\n".join(flist))
|
||||||
|
if not outfile:
|
||||||
|
# print to console
|
||||||
|
print(out)
|
||||||
|
else:
|
||||||
|
# write to file
|
||||||
|
with open(outfile, "w") as fh:
|
||||||
|
fh.write(out)
|
||||||
61
lib/obp60task/utils/xbmconvert.py
Executable file
61
lib/obp60task/utils/xbmconvert.py
Executable file
@@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
#
|
||||||
|
# Convert a Gimp-created XBM file to bitmap useable by drawBitmap()
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("Usage: xbmconvert.py <filename>")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
xbmfilename = sys.argv[1]
|
||||||
|
if not os.path.isfile(xbmfilename):
|
||||||
|
print(f"The file '{xbmfilename}' does not exists.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
im = Image.open(xbmfilename)
|
||||||
|
imname = "image"
|
||||||
|
with open(xbmfilename, 'r') as fh:
|
||||||
|
pattern = r'static\s+unsigned\s+char\s+(\w+)_bits$$$$'
|
||||||
|
for line in fh:
|
||||||
|
match = re.search(pattern, line)
|
||||||
|
if match:
|
||||||
|
imname = match.group(1)
|
||||||
|
break
|
||||||
|
bytecount = int(im.width * im.height / 8)
|
||||||
|
|
||||||
|
print(f"#ifndef _{imname.upper()}_H_")
|
||||||
|
print(f"#define _{imname.upper()}_H_ 1\n")
|
||||||
|
print(f"#define {imname}_width {im.width}")
|
||||||
|
print(f"#define {imname}_height {im.height}")
|
||||||
|
print(f"const unsigned char {imname}_bits[{bytecount}] PROGMEM = {{")
|
||||||
|
|
||||||
|
n = 0
|
||||||
|
print(" ", end='')
|
||||||
|
f = im.tobytes()
|
||||||
|
|
||||||
|
switched_bytes = bytearray()
|
||||||
|
for i in range(0, len(f), 2):
|
||||||
|
# Switch LSB and MSB
|
||||||
|
switched_bytes.append(f[i + 1]) # Append MSB
|
||||||
|
switched_bytes.append(f[i]) # Append LSB
|
||||||
|
|
||||||
|
#for b in im.tobytes():
|
||||||
|
for b in switched_bytes:
|
||||||
|
#b2 = 0
|
||||||
|
#for i in range(8):
|
||||||
|
# # b2 |= ((b >> i) & 1) << (7 - i)
|
||||||
|
# b2 <<= 1
|
||||||
|
# b2 |= b & 1
|
||||||
|
# b >>= 1
|
||||||
|
n += 1
|
||||||
|
print(f"0x{b:02x}", end='')
|
||||||
|
if n < bytecount:
|
||||||
|
print(', ', end='')
|
||||||
|
if n % 12 == 0:
|
||||||
|
print("\n ", end='')
|
||||||
|
print("};\n\n#endif")
|
||||||
@@ -216,6 +216,10 @@ public:
|
|||||||
{
|
{
|
||||||
return api->getLogger();
|
return api->getLogger();
|
||||||
}
|
}
|
||||||
|
virtual Nmea2kTwai *getNMEA2000()
|
||||||
|
{
|
||||||
|
return api->getNMEA2000();
|
||||||
|
}
|
||||||
virtual GwBoatData *getBoatData()
|
virtual GwBoatData *getBoatData()
|
||||||
{
|
{
|
||||||
return api->getBoatData();
|
return api->getBoatData();
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ lib_deps =
|
|||||||
ttlappalainen/NMEA2000-library @ 4.22.0
|
ttlappalainen/NMEA2000-library @ 4.22.0
|
||||||
ttlappalainen/NMEA0183 @ 1.10.1
|
ttlappalainen/NMEA0183 @ 1.10.1
|
||||||
ArduinoJson @ 6.18.5
|
ArduinoJson @ 6.18.5
|
||||||
AsyncTCP-esphome @ 2.0.1
|
ESP32Async/AsyncTCP @ 3.4.7
|
||||||
ottowinter/ESPAsyncWebServer-esphome@2.0.1
|
ESP32Async/ESPAsyncWebServer @ 3.8.0
|
||||||
FS
|
FS
|
||||||
Preferences
|
Preferences
|
||||||
ESPmDNS
|
ESPmDNS
|
||||||
@@ -30,7 +30,7 @@ lib_deps =
|
|||||||
Update
|
Update
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
platform = espressif32 @ 6.8.1
|
platform = espressif32 @ 6.11.0
|
||||||
framework = arduino
|
framework = arduino
|
||||||
;platform_packages=
|
;platform_packages=
|
||||||
; framework-arduinoespressif32 @ 3.20017.0
|
; framework-arduinoespressif32 @ 3.20017.0
|
||||||
@@ -56,6 +56,11 @@ lib_ldf_mode = off
|
|||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
build_flags =
|
build_flags =
|
||||||
-D PIO_ENV_BUILD=$PIOENV
|
-D PIO_ENV_BUILD=$PIOENV
|
||||||
|
# -D CONFIG_ASYNC_TCP_RUNNING_CORE=1 # async_tcp task core assignment (default is any core)
|
||||||
|
-D CONFIG_ASYNC_TCP_STACK_SIZE=4096 # reduce the stack size (default is 16K)
|
||||||
|
-std=gnu++17
|
||||||
|
build_unflags =
|
||||||
|
-std=gnu++11
|
||||||
|
|
||||||
[sensors]
|
[sensors]
|
||||||
; collect the libraries for sensors here
|
; collect the libraries for sensors here
|
||||||
|
|||||||
@@ -302,9 +302,15 @@ public:
|
|||||||
if (newValid != list[i]->valid) list[i]->changed=true;
|
if (newValid != list[i]->valid) list[i]->changed=true;
|
||||||
list[i]->valid=newValid;
|
list[i]->valid=newValid;
|
||||||
if (newValid){
|
if (newValid){
|
||||||
|
if (item->getCurrentType() == GWTYPE_STRING) {
|
||||||
|
String newValue=item->getStringValue();
|
||||||
|
if (newValue != list[i]->svalue) list[i]->changed=true;
|
||||||
|
list[i]->svalue=newValue;
|
||||||
|
} else {
|
||||||
double newValue=item->getDoubleValue();
|
double newValue=item->getDoubleValue();
|
||||||
if (newValue != list[i]->value) list[i]->changed=true;
|
if (newValue != list[i]->value) list[i]->changed=true;
|
||||||
list[i]->value=newValue;
|
list[i]->value=newValue;
|
||||||
|
}
|
||||||
int newSource=item->getLastSource();
|
int newSource=item->getLastSource();
|
||||||
if (newSource != list[i]->source){
|
if (newSource != list[i]->source){
|
||||||
list[i]->source=newSource;
|
list[i]->source=newSource;
|
||||||
@@ -333,6 +339,9 @@ public:
|
|||||||
status.n2kTx=countNMEA2KOut.getGlobal();
|
status.n2kTx=countNMEA2KOut.getGlobal();
|
||||||
channels.fillStatus(status);
|
channels.fillStatus(status);
|
||||||
}
|
}
|
||||||
|
virtual Nmea2kTwai *getNMEA2000(){
|
||||||
|
return &NMEA2000;
|
||||||
|
}
|
||||||
virtual GwBoatData *getBoatData(){
|
virtual GwBoatData *getBoatData(){
|
||||||
return &boatData;
|
return &boatData;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user