1
0
mirror of https://github.com/thooge/esp32-nmea2000-obp60.git synced 2025-12-16 15:33:05 +01:00

26 Commits

Author SHA1 Message Date
b728d6d643 Add page indicator for OBP40 2025-01-20 09:06:23 +01:00
10d1046c82 Some more improvements for OBP40, mainly building 2025-01-20 07:35:50 +01:00
66d88a8486 Merge branch 'master' into obp40 2025-01-19 09:11:28 +01:00
norbert-walter
87a7a79358 Change back to plaformio.ini OBP60 2025-01-19 00:23:22 +01:00
Norbert Walter
e7216e6d2b Merge branch 'wellenvogel:master' into master 2025-01-18 19:12:24 +01:00
Norbert Walter
e7f3430ed6 Merge pull request #141 from thooge/keyboard
Key label improvements: footer function
2025-01-18 19:10:33 +01:00
Norbert Walter
2c2d21535b Merge pull request #139 from TobiasE-github/master
Add SixValues and fix Fluid in gen_set.py
2025-01-18 19:06:40 +01:00
2be67f1659 Merge branch 'obp40' of github.com:thooge/esp32-nmea2000-obp60 into obp40 2025-01-18 17:16:11 +01:00
75e360a19d Modified keypad handling 2025-01-18 17:15:13 +01:00
Tobias E
27b02c4860 removed obsolete perl script gen_set.pl 2025-01-18 13:59:37 +00:00
b56c43767d Add/fix some documentation 2025-01-18 09:05:52 +01:00
e917a7fc76 Modification of footer layout and new swipe icon 2025-01-17 21:23:41 +01:00
Tobias E
10552763fb add explanation to gen_set.py 2025-01-17 19:24:16 +00:00
Tobias E
24386d4d42 add explanation to gen_set.py 2025-01-17 19:23:26 +00:00
norbert-walter
49be7f117a Modify pad detectionfor OBP60 Light 2025-01-17 18:00:32 +01:00
9af781318f Keyboard infos in readme and disabled unused LED task 2025-01-17 16:07:02 +01:00
081a73d8f8 Set adapted defaults 2025-01-17 15:18:22 +01:00
ff867beb9d Improve SD card code 2025-01-17 15:04:47 +01:00
2fd11c72b6 Make logging work 2025-01-17 12:42:17 +01:00
235cfd1c9c Fix SPI pin name 2025-01-17 11:25:53 +01:00
16e7b80230 Added readme file 2025-01-17 11:21:12 +01:00
5f5c520714 Make OBP40 compile and add some SD-card code 2025-01-17 11:18:01 +01:00
TobiasE-github
e70660c981 Merge branch 'norbert-walter:master' into master 2025-01-14 20:39:25 +01:00
TobiasE-github
4395c623ea Merge branch 'norbert-walter:master' into master 2025-01-13 06:30:15 +01:00
Tobias E
dfc79c80dc Add SixValues and fix Fluid in gen_set.py 2025-01-12 21:40:39 +00:00
wellenvogel
a129d865c9 warn the user if page translation is enabled for cibuild 2024-12-10 19:16:11 +01:00
16 changed files with 336 additions and 210 deletions

View File

@@ -10,7 +10,7 @@
"-DBOARD_HAS_PSRAM",
"-DARDUINO_ESP32S3_DEV",
"-DARDUINO_USB_MODE=1",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_CDC_ON_BOOT=0",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1"
],

View File

@@ -10,7 +10,7 @@ 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())
@@ -104,13 +104,22 @@ def writeFileIfChanged(fileName,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)
print("merge config {}".format(cname))
with open(cname,'rb') as ah:
merge=json.load(ah)
base=base+merge
base += json.load(ah)
return base
def replaceTexts(data,replacements):
@@ -274,9 +283,9 @@ class Grove:
def _ss(self,z=False):
if z:
return self.name
return self.name if self.name is not 'Z' else ''
return self.name if self.name != 'Z' else ''
def _suffix(self):
return '_'+self.name if self.name is not 'Z' else ''
return '_'+self.name if self.name != 'Z' else ''
def replace(self,line):
if line is None:
return line

View File

@@ -2,5 +2,5 @@ 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.pl and run it to auto-generate the relevant section of config.json
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

View File

@@ -326,17 +326,14 @@ void displayHeader(CommonData &commonData, GwApi::BoatValue *date, GwApi::BoatVa
usbRxOld = commonData.status.usbRx;
usbTxOld = commonData.status.usbTx;
#ifdef HARDWARE_V21
// Display key lock status
if (commonData.keylock) {
getdisplay().drawXBitmap(150, 1, lock_bits, icon_width, icon_height, commonData.fgcolor);
getdisplay().drawXBitmap(170, 1, lock_bits, icon_width, icon_height, commonData.fgcolor);
} else {
getdisplay().drawXBitmap(150, 1, swipe_bits, icon_width, icon_height, commonData.fgcolor);
getdisplay().drawXBitmap(166, 1, swipe_bits, swipe_width, swipe_height, commonData.fgcolor);
}
// Current page number in a small box
getdisplay().setFont(&Ubuntu_Bold8pt7b);
getdisplay().drawRect(170, 2, 20, 15, commonData.fgcolor);
drawTextCenter(179, 9, String(commonData.data.actpage));
#endif
// Heartbeat as dot
getdisplay().setTextColor(commonData.fgcolor);
@@ -381,14 +378,23 @@ void displayFooter(CommonData &commonData) {
getdisplay().setFont(&Atari16px);
getdisplay().setTextColor(commonData.fgcolor);
#ifdef HARDWARE_V21
// Frame around key icon area
getdisplay().drawLine(0, 280, 399, 280, commonData.fgcolor);
if (! commonData.keylock) {
getdisplay().drawLine(68, 280, 68, 299, commonData.fgcolor);
getdisplay().drawLine(134, 280, 134, 299, commonData.fgcolor);
getdisplay().drawLine(200, 280, 200, 299, commonData.fgcolor);
getdisplay().drawLine(266, 280, 266, 299, commonData.fgcolor);
getdisplay().drawLine(332, 280, 332, 299, commonData.fgcolor);
// horizontal elements
const uint16_t top = 280;
const uint16_t bottom = 299;
getdisplay().drawLine(commonData.keydata[0].x, top, commonData.keydata[0].x+10, top, commonData.fgcolor);
getdisplay().drawLine(commonData.keydata[1].x-10, top, commonData.keydata[1].x+10, top, commonData.fgcolor);
getdisplay().drawLine(commonData.keydata[2].x-10, top, commonData.keydata[2].x+10, top, commonData.fgcolor);
getdisplay().drawLine(commonData.keydata[4].x-10, top, commonData.keydata[4].x+10, top, commonData.fgcolor);
getdisplay().drawLine(commonData.keydata[5].x-10, top, commonData.keydata[5].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);
// vertical key separators
getdisplay().drawLine(commonData.keydata[0].x + commonData.keydata[0].w, top, commonData.keydata[0].x + commonData.keydata[0].w, bottom, commonData.fgcolor);
getdisplay().drawLine(commonData.keydata[1].x + commonData.keydata[1].w, top, commonData.keydata[1].x + commonData.keydata[1].w, bottom, commonData.fgcolor);
getdisplay().drawLine(commonData.keydata[3].x + commonData.keydata[3].w, top, commonData.keydata[3].x + commonData.keydata[3].w, bottom, commonData.fgcolor);
getdisplay().drawLine(commonData.keydata[4].x + commonData.keydata[4].w, top, commonData.keydata[4].x + commonData.keydata[4].w, bottom, commonData.fgcolor);
for (int i = 0; i < 6; i++) {
uint16_t x, y;
if (commonData.keydata[i].label.length() > 0) {
@@ -412,10 +418,28 @@ void displayFooter(CommonData &commonData) {
}
}
}
// Current page number in a small box
getdisplay().drawRect(190, 280, 23, 19, commonData.fgcolor);
drawTextCenter(200, 289, String(commonData.data.actpage));
} else {
getdisplay().setCursor(65, 295);
getdisplay().print("Press 1 and 6 fast to unlock keys");
}
#endif
#ifdef HARDWARE_LIGHT
// grapical page indicator
static const uint16_t r = 5;
static const uint16_t space = 4;
uint16_t w = commonData.data.maxpage * r * 2 + (commonData.data.maxpage - 1) * space;
uint16_t x0 = (GxEPD_WIDTH - w) / 2 + r * 2;
for (int i = 0; i < commonData.data.maxpage; i++) {
if (i == (commonData.data.actpage - 1)) {
getdisplay().fillCircle(x0 + i * (r * 2 + space), 290, r, commonData.fgcolor);
} else {
getdisplay().drawCircle(x0 + i * (r * 2 + space), 290, r, commonData.fgcolor);
}
}
#endif
}
// Sunset und sunrise calculation

View File

@@ -114,11 +114,6 @@ static unsigned char right_bits[] PROGMEM = {
0xfe, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0x80, 0x1f,
0x80, 0x0f, 0x80, 0x07, 0x80, 0x03, 0x00, 0x00 };
static unsigned char swipe_bits[] = {
0x30, 0x00, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0xc8, 0x05, 0x48, 0x0e,
0x4a, 0x12, 0x4d, 0x32, 0x09, 0x50, 0x41, 0x44, 0x62, 0x4c, 0xf2, 0x5f,
0x64, 0x2c, 0x48, 0x24, 0x10, 0x10, 0xe0, 0x0f };
static unsigned char lock_bits[] PROGMEM = {
0xc0, 0x03, 0x60, 0x06, 0x30, 0x0c, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08,
0xfc, 0x3f, 0x04, 0x20, 0x04, 0x20, 0x84, 0x21, 0x84, 0x21, 0x84, 0x21,
@@ -139,19 +134,38 @@ static unsigned char fram_bits[] PROGMEM = {
0xff, 0xff, 0xf8, 0x1f, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f,
0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f };
static unsigned char ap_bits[] = {
0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0xc2, 0x21, 0x30, 0x06, 0x08, 0x08,
0xc0, 0x01, 0x20, 0x02, 0x00, 0x00, 0x80, 0x00, 0xc0, 0x01, 0xc0, 0x01,
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00 };
static unsigned char dish_bits[] PROGMEM= {
0x3c, 0x00, 0x42, 0x18, 0xfa, 0x1b, 0x02, 0x04, 0x02, 0x0a, 0x02, 0x09,
0x82, 0x08, 0x06, 0x0a, 0x0e, 0x1b, 0x9c, 0x2b, 0x38, 0x2b, 0x74, 0x20,
0xec, 0x1f, 0x1c, 0x00, 0xf4, 0x00, 0xfe, 0x03 };
static std::map<String, unsigned char *> iconmap = {
{"LEFT", left_bits},
{"RIGHT", right_bits},
{"SWIPE", swipe_bits},
{"LOCK", lock_bits},
{"PLUS", plus_bits},
{"MINUS", minus_bits}
{"MINUS", minus_bits},
{"DISH", dish_bits},
{"AP", ap_bits}
};
// Other symbols
#define swipe_width 24
#define swipe_height 16
static unsigned char swipe_bits[] PROGMEM = {
0x00, 0x06, 0x00, 0x24, 0x09, 0x24, 0x12, 0x09, 0x48, 0x7f, 0x09, 0xfe,
0x12, 0xb9, 0x48, 0x24, 0xc9, 0x25, 0x40, 0x49, 0x02, 0xa0, 0x49, 0x06,
0x20, 0x01, 0x0a, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08,
0x80, 0x00, 0x04, 0x00, 0x01, 0x04, 0x00, 0x02, 0x02, 0x00, 0xfc, 0x01 };
#define exclamation_width 32
#define exclamation_height 32
static unsigned char exclamation_bits[] = {
static unsigned char exclamation_bits[] PROGMEM = {
0x00, 0xc0, 0x03, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0xb0, 0x0d, 0x00,
0x00, 0xd8, 0x1b, 0x00, 0x00, 0xec, 0x37, 0x00, 0x00, 0xf6, 0x6f, 0x00,
0x00, 0x3b, 0xdc, 0x00, 0x80, 0x3d, 0xbc, 0x01, 0xc0, 0x3e, 0x7c, 0x03,

View File

@@ -22,35 +22,40 @@ long starttime = 0; // Start time point for pressed key
void initKeys(CommonData &commonData) {
// coordinates for virtual keyboard keys
commonData.keydata[0].x = 1;
commonData.keydata[0].y = 281;
commonData.keydata[0].w = 67;
commonData.keydata[0].h = 18;
commonData.keydata[1].x = 69;
commonData.keydata[1].y = 281;
commonData.keydata[1].w = 66;
commonData.keydata[1].h = 18;
static uint16_t top = 281;
static uint16_t width = 65;
static uint16_t height = 18;
commonData.keydata[2].x = 135;
commonData.keydata[2].y = 281;
commonData.keydata[2].w = 66;
commonData.keydata[2].h = 18;
commonData.keydata[0].x = 0;
commonData.keydata[0].y = top;
commonData.keydata[0].w = width + 1;
commonData.keydata[0].h = height;
commonData.keydata[3].x = 201;
commonData.keydata[3].y = 281;
commonData.keydata[3].w = 66;
commonData.keydata[3].h = 18;
commonData.keydata[1].x = commonData.keydata[0].x + commonData.keydata[0].w + 1;
commonData.keydata[1].y = top;
commonData.keydata[1].w = width;
commonData.keydata[1].h = height;
commonData.keydata[4].x = 267;
commonData.keydata[4].y = 281;
commonData.keydata[4].w = 66;
commonData.keydata[4].h = 18;
commonData.keydata[2].x = commonData.keydata[1].x + commonData.keydata[1].w + 1;
commonData.keydata[2].y = top;
commonData.keydata[2].w = width;
commonData.keydata[2].h = height;
commonData.keydata[5].x = 333;
commonData.keydata[5].y = 281;
commonData.keydata[5].w = 66;
commonData.keydata[5].h = 18;
commonData.keydata[3].x = commonData.keydata[2].x + commonData.keydata[2].w + 1;
commonData.keydata[3].y = top;
commonData.keydata[3].w = width;
commonData.keydata[3].h = height;
commonData.keydata[4].x = commonData.keydata[3].x + commonData.keydata[3].w + 1;
commonData.keydata[4].y = top;
commonData.keydata[4].w = width;
commonData.keydata[4].h = height;
commonData.keydata[5].x = commonData.keydata[4].x + commonData.keydata[4].w + 1;
commonData.keydata[5].y = top;
commonData.keydata[5].w = width;
commonData.keydata[5].h = height;
}
#ifdef HARDWARE_V21
@@ -214,6 +219,29 @@ void initKeys(CommonData &commonData) {
#endif
#ifdef HARDWARE_LIGHT
int readSensorpads(){
// Read key code
if(digitalRead(UP) == LOW){
keycode = 10; // Left swipe
}
else if(digitalRead(DOWN) == LOW){
keycode = 9; // Right swipe
}
else if(digitalRead(CONF) == LOW){
keycode = 3; // Key 3
}
else if(digitalRead(MENUE) == LOW){
keycode = 1; // Key 1
}
else if(digitalRead(EXIT) == LOW){
keycode = 2; // Key 2
}
else{
keycode = 0; // No key activ
}
return keycode;
}
// Keypad functions for OBP60 clone (thSensitivity is inactiv)
int readKeypad(uint thSensitivity) {
pinMode(UP, INPUT);
@@ -222,25 +250,8 @@ void initKeys(CommonData &commonData) {
pinMode(MENUE, INPUT);
pinMode(EXIT, INPUT);
// Read key code
if(digitalRead(UP) == LOW){
keycode = 10; // Left swipe
}
else if(digitalRead(DOWN) == LOW){
keycode = 9; // Right swipe
}
else if(digitalRead(CONF) == LOW){
keycode = 3; // Key 3
}
else if(digitalRead(MENUE) == LOW){
keycode = 1; // Key 1
}
else if(digitalRead(EXIT) == LOW){
keycode = 2; // Key 2
}
else{
keycode = 0; // No key activ
}
// Read pad values
readSensorpads();
// Detect key
if (keycode > 0 ){
@@ -253,6 +264,7 @@ void initKeys(CommonData &commonData) {
keystatus = keycode;
// Copy keycode
keycodeold = keycode;
while(readSensorpads() > 0){} // Wait for pad release
delay(keydelay);
}
}

52
lib/obp60task/README Normal file
View File

@@ -0,0 +1,52 @@
OBP40
=====
Important information:
***************************************************
THIS BRANCH IS NOT INTENDED TO MERGE INTO "master"!
***************************************************
platformio.ini adapted to compile directly. For compile use matching
environent:
pio run -e obp40
for upload to device:
pio run -e obp40 -t upload
Differences to OBP60
--------------------
- no GPS
- no RTC
- no LEDs
- no environment sensor
- no key lock
- no swipe
- only 5 keys
+ SD card interface
GPIO assignments
----------------
NMEA0183
IO9 - RS485 TX
IO14 - RS485 RX
NMEA2000/CAN
IO15 - CAN TX
IO16 - CAN RX
Keyboard
--------
Keycode Key Function
-------- ---------------- -------------------------
1 Menu key Key 1 of OBP60 (left)
2 Exit key Key 2 of OBP60
3 Jog-Dial press
9 Jog-Dial down Next page
10 Jog-Dial up Previous page

View File

@@ -297,7 +297,7 @@
"name": "useRTC",
"label": "RTC Modul",
"type": "list",
"default": "DS1388",
"default": "off",
"description": "Use internal RTC module type [off|DS1388]",
"list": [
"off",
@@ -312,7 +312,7 @@
"name": "useGPS",
"label": "GPS Sensor",
"type": "list",
"default": "ATGM336H",
"default": "off",
"description": "Use internal GPS module type [off|NEO-6M|NEO-M8N|ATGM336H]",
"list": [
"off",
@@ -343,7 +343,7 @@
"name": "useEnvSensor",
"label": "Env. Sensor",
"type": "list",
"default": "BMP280",
"default": "off",
"description": "Use internal or external environment sensor via I2C bus [off|BME280|BMP280|BMP180|BMP085|HTU21|SHT21]",
"list": [
"off",
@@ -573,6 +573,21 @@
"obp60":"true"
}
},
{
"name": "useSDCard",
"label": "SD Card",
"type": "boolean",
"default": "off",
"description": "Use internal SD card interface [off|on]",
"list": [
"off",
"on"
],
"category": "OBP60 Hardware",
"capabilities": {
"obp60":"true"
}
},
{
"name": "powerMode",
"label": "Power Mode",
@@ -918,7 +933,7 @@
"name": "page1type",
"label": "Type",
"type": "list",
"default": "Voltage",
"default": "Clock",
"description": "Type of page for page 1",
"list": [
"BME280",
@@ -1178,7 +1193,7 @@
"name": "page2type",
"label": "Type",
"type": "list",
"default": "WindRose",
"default": "Wind",
"description": "Type of page for page 2",
"list": [
"BME280",
@@ -2676,7 +2691,7 @@
"name": "page8type",
"label": "Type",
"type": "list",
"default": "Clock",
"default": "Fluid",
"description": "Type of page for page 8",
"list": [
"BME280",

View File

@@ -1,112 +0,0 @@
#!/bin/perl -w
#A tool to generate the part of config.json that deals with pages and fields.
#DEPRECATED, moved to get_set.py
die "Please use gen_set.py instead";
#List of all pages and the number of parameters they expect.
%NoOfFieldsPerPage=qw(
ApparentWind 0
XTETrack 0
Battery2 0
Battery 0
BME280 0
Clock 0
DST810 0
FourValues2 4
FourValues 4
Generator 0
KeelPosition 0
OneValue 1
RollPitch 0
RudderPosition 0
Solar 0
ThreeValues 3
TwoValues 2
Voltage 0
White 0
WindRose 0
WindRoseFlex 6
);
# No changes needed beyond this point
#max number of pages supported by OBP60
$NoOfPages=10;
#Default selection for each page
@Defaults=qw(Voltage WindRose OneValue TwoValues ThreeValues FourValues FourValues2 Clock RollPitch Battery2);
@Numbers=qw(one two three four five six seven eight nine ten);
@Pages=sort(keys(%NoOfFieldsPerPage));
$MaxNoOfFieldsPerPage=0; # inital value, gets updated with maximum entry from %NoOfFieldsPerPage
#find max. number of fields without additional modules
foreach (values(%NoOfFieldsPerPage)){
if ($_ > $MaxNoOfFieldsPerPage){
$MaxNoOfFieldsPerPage=$_;
}
}
for ($PageNo=1;$PageNo<=$NoOfPages;$PageNo++){
print "{\n";
print "\t","\"name\": \"page", $PageNo,"type\",\n";
print "\t","\"label\": \"Type\",\n";
print "\t",'"type": "list",',"\n";
print "\t",'"default": "';
print "$Defaults[$PageNo-1]";
print'"',"\n";
print "\t",'"description": "Type of page for page ',$PageNo,'",',"\n";
print "\t",'"list": [';
for ($p=0;$p<=$#Pages;$p++) {
print '"', $Pages[$p], '"' ;
if ($p < $#Pages){print ","}
}
print "]\n";
print "\t",'"category": "OBP60 Page ',$PageNo,'",',"\n";
print "\t",'"capabilities": {',"\n";
print "\t\t",'"obp60":"true"',"\n";
print "\t",'}',"\n";
print "\t",'"condition":[';
for ($vp=$PageNo;$vp<=$NoOfPages;$vp++){
print '"{visiblePages":"',$vp,'"},';
}
print "\b",']',"\n";
print '},',"\n";
for ($FieldNo=1; $FieldNo<=$MaxNoOfFieldsPerPage;$FieldNo++){
print "{\n";
print "\t",'"name": "page',$PageNo,'value',$FieldNo,'",',"\n";
print "\t",'"label": "Field ',$FieldNo,'",',"\n";
print "\t",'"type": "boatData",',"\n";
print "\t",'"default": "",',"\n";
print "\t",'"description": "The display for field ',$Numbers[$FieldNo-1],'",',"\n";
print "\t",'"category": "OBP60 Page ',$PageNo,'",',"\n";
print "\t",'"capabilities": {',"\n";
print "\t",' "obp60":"true"',"\n";
print "\t",'}, ',"\n";
print "\t",'"condition":[';
foreach $page (@Pages) {
if($NoOfFieldsPerPage{$page}>=$FieldNo){
print '{"page',$PageNo,'type":"',$page,'"},';
}
}
print "\b],\n";
print '},',"\n";
}
print "{\n";
print "\t","\"name\": \"page", $PageNo,"fluid\",\n";
print "\t",'"label": "Fluid type",',"\n";
print "\t",'"type": "list",',"\n";
print "\t",'"default": "0",',"\n";
print "\t",'"list": [',"\n";
print "\t",'{"l":"Fuel (0)","v":"0"},',"\n";
print "\t",'{"l":"Water (1)","v":"1"},',"\n";
print "\t",'{"l":"Gray Water (2)","v":"2"},',"\n";
print "\t",'{"l":"Live Well (3)","v":"3"},',"\n";
print "\t",'{"l":"Oil (4)","v":"4"},',"\n";
print "\t",'{"l":"Black Water (5)","v":"5"},',"\n";
print "\t",'{"l":"Fuel Gasoline (6)","v":"6"}',"\n";
print "\t",'],',"\n";
print "\t",'"description": "Fluid type in tank",',"\n";
print "\t",'"category": "OBP60 Page ',$PageNo,'",',"\n";
print "\t",'"capabilities": {',"\n";
print "\t",'"obp60":"true"',"\n";
print "\t",'},',"\n";
print "\t",'"condition":[{"page',$PageNo,'type":"Fluid"}]',"\n";
print '},',"\n";
}

View File

@@ -1,18 +1,22 @@
#!/usr/bin/env python3
# A tool to generate that part of config.json that deals with pages and fields.
#
#Usage: 1. modify this script (e.g.add a page, change number of fields, etc.)
# 2. Delete all lines from config.json from the curly backet before "name": "page1type" to o the end of the file (as of today, delete from line 917 to the end of the File)
# 3. run ./gen_set.py >> config.json
import json
# List of all pages and the number of parameters they expect.
no_of_fields_per_page = {
"ApparentWind": 0,
"Wind": 0,
"XTETrack": 0,
"Battery2": 0,
"Battery": 0,
"BME280": 0,
"Clock": 0,
"DST810": 0,
"Fluid": 0,
"Fluid": 1,
"FourValues2": 4,
"FourValues": 4,
"Generator": 0,
@@ -27,6 +31,7 @@ no_of_fields_per_page = {
"White": 0,
"WindRose": 0,
"WindRoseFlex": 6,
"SixValues" : 6,
}
# No changes needed beyond this point
@@ -119,5 +124,7 @@ for page_no in range(1, no_of_pages + 1):
json_output = json.dumps(output, indent=4)
# print omitting first and last line containing [ ] of JSON array
print(json_output[1:-1])
#print(json_output[1:-1])
# print omitting first line containing [ of JSON array
print(json_output[1:])
# print(",")

View File

@@ -13,6 +13,10 @@
#include "OBP60Extensions.h" // Functions lib for extension board
#include "OBP60Keypad.h" // Functions for keypad
#include <FS.h> // SD-Card access
#include <SD.h>
#include <SPI.h>
// True type character sets includes
// See OBP60ExtensionPort.cpp
@@ -23,8 +27,6 @@
#include "OBP60QRWiFi.h" // Functions lib for WiFi QR code
#include "OBPSensorTask.h" // Functions lib for sensor data
#include "LedSpiTask.h"
// Global vars
bool initComplete = false; // Initialization complete
int taskRunCounter = 0; // Task couter for loop section
@@ -33,6 +35,9 @@ int taskRunCounter = 0; // Task couter for loop section
//####################################################################################
void OBP60Init(GwApi *api){
GwLog *logger = api->getLogger();
GwConfigHandler *config = api->getConfig();
// Set a new device name and hidden the original name in the main config
String devicename = api->getConfig()->getConfigItem(api->getConfig()->deviceName,true)->asString();
api->getConfig()->setValue(GwConfigDefinitions::systemName, devicename, GwConfigInterface::ConfigType::HIDDEN);
@@ -45,6 +50,31 @@ void OBP60Init(GwApi *api){
// Init hardware
hardwareInit(api);
String sdcard = config->getConfigItem(config->useSDCard, true)->asString();
if (sdcard == "on") {
setPortPin(OBP_POWER_SD, true); // Power on SD
delay(10);
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);
}
}
// 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());
@@ -288,15 +318,19 @@ void OBP60Task(GwApi *api){
// return;
GwLog *logger=api->getLogger();
GwConfigHandler *config=api->getConfig();
#ifdef HARDWARE_V21
startLedTask(api);
#endif
PageList allPages;
registerAllPages(allPages);
CommonData commonData;
commonData.logger=logger;
commonData.config=config;
#ifdef HARDWARE_V21
// Keyboard coordinates for page footer
initKeys(commonData);
#endif
tN2kMsg N2kMsg;

View File

@@ -19,7 +19,7 @@
#define ESP32_CAN_TX_PIN 15
#define ESP32_CAN_RX_PIN 16
// Bus load in 50mA steps
#define N2K_LOAD_LEVEL 2 // 5x50mA = 100mA max bus load with back light on
#define N2K_LOAD_LEVEL 2 // 2x50mA = 100mA max bus load
// RS485 NMEA0183
#define GWSERIAL_TX 9
#define GWSERIAL_RX 14
@@ -35,6 +35,11 @@
// OBP60 Task
void OBP60Task(GwApi *param);
DECLARE_USERTASK_PARAM(OBP60Task, 35000); // Need 35k RAM as stack size
#ifdef HARDWARE_V21
DECLARE_CAPABILITY(obp60,true);
#endif
#ifdef HARDWARE_LIGHT
DECLARE_CAPABILITY(obp40,true)
#endif
DECLARE_STRING_CAPABILITY(HELP_URL, "https://obp60-v2-docu.readthedocs.io/de/latest/"); // Link to help pages
#endif
#endif

View File

@@ -9,15 +9,16 @@ board_build.variants_dir = variants
#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_n8r8 #ESP32-S3 N8R8, 8MB flash, 8MB PSRAM
board = obp60_s3_n16r8 #ESP32-S3 N16R8, 16MB flash, 8MB PSRAM, production series
#board = obp60_s3_light_n8r8 #ESP32-S3 N8R8, 8MB flash, 8MB PSRAM, OBP60 clone
#board_build.partitions = default_8MB.csv #ESP32-S3 N8, 8MB flash
board_build.partitions = default_16MB.csv #ESP32-S3 N16, 16MB flash
#board = obp60_s3_n16r8 #ESP32-S3 N16R8, 16MB flash, 8MB PSRAM, production series
board = obp60_s3_light_n8r8 #ESP32-S3 N8R8, 8MB flash, 8MB PSRAM, OBP60 clone
board_build.partitions = default_8MB.csv #ESP32-S3 N8, 8MB flash
#board_build.partitions = default_16MB.csv #ESP32-S3 N16, 16MB flash
framework = arduino
lib_deps =
lib_deps =
${basedeps.lib_deps}
Wire
SPI
SD
esphome/AsyncTCP-esphome@2.0.1
robtillaart/PCF8574@0.3.9
adafruit/Adafruit Unified Sensor @ 1.1.13
@@ -40,22 +41,65 @@ lib_deps =
build_flags=
#https://thingpulse.com/usb-settings-for-logging-with-the-esp32-s3-in-platformio/?srsltid=AfmBOopGskbkr4GoeVkNlFaZXe_zXkLceKF6Rn-tmoXABCeAR2vWsdHL
# -D ARDUINO_USB_MODE=1 #0=OTG (to implement other external devices), 1=CDC (is a serial device)
# -D ARDUINO_USB_CDC_ON_BOOT=1 #0=JTAG, 1=CDC (serial device)
# -D ARDUINO_USB_CDC_ON_BOOT=0 #0=JTAG, 1=CDC (serial device)
# -D CORE_DEBUG_LEVEL=1 #Debug level for CPU core via CDC (seral device)
# -D TIME=$UNIX_TIME #Set PC time for RTC (only settable via VSC)
-D DISABLE_DIAGNOSTIC_OUTPUT #Disable diagnostic output for GxEPD2 lib
-D BOARD_OBP60S3 #Board OBP60 V2.1 with ESP32S3
# -D HARDWARE_V20 #OBP60 hardware revision V2.0
-D HARDWARE_V21 #OBP60 hardware revision V2.1
# -D HARDWARE_LIGHT #OBP60 hardware clone
# -D HARDWARE_V21 #OBP60 hardware revision V2.1
-D HARDWARE_LIGHT #OBP60 hardware clone
# -D DISPLAY_GDEW042T2 #old E-Ink display from Waveshare, R10 0.47 ohm
-D DISPLAY_GDEY042T81 #new E-Ink display from Waveshare, R10 2.2 ohm
# -D DISPLAY_GYE042A87 #alternativ E-Ink display from Genyo Optical, R10 2.2 ohm
# -D DISPLAY_SE0420NQ04 #alternativ E-Ink display from SID Technology, R10 2.2 ohm
${env.build_flags}
#CONFIG_ESP_TASK_WDT_TIMEOUT_S = 10 #Task Watchdog timeout period (seconds) [1...60] 5 default
upload_port = /dev/ttyACM0 #OBP60 original
#upload_port = /dev/ttyUSB0 #OBP60 clone
#upload_port = /dev/ttyACM0 #OBP60 original
upload_port = /dev/ttyUSB0 #OBP60 clone
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_speed = 230400
monitor_speed = 115200
[env:obp40]
platform = espressif32@6.8.1
board_build.variants_dir = variants
board = obp60_s3_light_n8r8 #ESP32-S3 N8R8, 8MB flash, 8MB PSRAM, OBP60 clone
board_build.partitions = default_8MB.csv #ESP32-S3 N8, 8MB flash
custom_config = config_obp40.json
framework = arduino
lib_deps =
${basedeps.lib_deps}
Wire
SPI
SD
esphome/AsyncTCP-esphome@2.0.1
robtillaart/PCF8574@0.3.9
adafruit/Adafruit Unified Sensor @ 1.1.13
blemasle/MCP23017@2.0.0
adafruit/Adafruit BusIO@1.5.0
adafruit/Adafruit GFX Library@1.11.9
#zinggjm/GxEPD2@1.5.8
#https://github.com/ZinggJM/GxEPD2
https://github.com/thooge/GxEPD2
sstaub/Ticker@4.4.0
adafruit/Adafruit BMP280 Library@2.6.2
adafruit/Adafruit BME280 Library@2.2.2
adafruit/Adafruit BMP085 Library@1.2.1
enjoyneering/HTU21D@1.2.1
robtillaart/INA226@0.2.0
paulstoffregen/OneWire@2.3.8
milesburton/DallasTemperature@3.11.0
signetica/SunRise@2.0.2
adafruit/Adafruit FRAM I2C@^2.0.3
build_flags=
#https://thingpulse.com/usb-settings-for-logging-with-the-esp32-s3-in-platformio/?srsltid=AfmBOopGskbkr4GoeVkNlFaZXe_zXkLceKF6Rn-tmoXABCeAR2vWsdHL
-D DISABLE_DIAGNOSTIC_OUTPUT #Disable diagnostic output for GxEPD2 lib
-D BOARD_OBP60S3 #Board OBP60 V2.1 with ESP32S3
-D HARDWARE_LIGHT #OBP60 hardware clone (OBP40)
-D DISPLAY_GDEY042T81 #new E-Ink display from Waveshare, R10 2.2 ohm
${env.build_flags}
upload_port = /dev/ttyUSB0 #OBP60 clone
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_speed = 230400
monitor_speed = 115200

View File

@@ -40,7 +40,7 @@ lib_deps =
build_flags=
#https://thingpulse.com/usb-settings-for-logging-with-the-esp32-s3-in-platformio/?srsltid=AfmBOopGskbkr4GoeVkNlFaZXe_zXkLceKF6Rn-tmoXABCeAR2vWsdHL
# -D ARDUINO_USB_MODE=1 #0=OTG (to implement other external devices), 1=CDC (is a serial device)
# -D ARDUINO_USB_CDC_ON_BOOT=1 #0=JTAG, 1=CDC (serial device)
-D ARDUINO_USB_CDC_ON_BOOT=0 #Serial output via RX/TX
# -D CORE_DEBUG_LEVEL=1 #Debug level for CPU core via CDC (seral device)
# -D TIME=$UNIX_TIME #Set PC time for RTC (only settable via VSC)
-D DISABLE_DIAGNOSTIC_OUTPUT #Disable diagnostic output for GxEPD2 lib

View File

@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html>
<html lang="en">
<head>
<script type="module" src="cibuild.js"></script>
@@ -83,4 +83,4 @@
</form>
</div>
</body>
</html>
</html>

View File

@@ -867,5 +867,27 @@ class PipelineInfo{
buildSelectors(ROOT_PATH,structure.config.children,true);
if (! isRunning()) findPipeline();
updateStatus();
const translationCheck=()=>{
const lang = document.documentElement.lang;
if (lang != "en"){
alert(
"This page will not work correctly with translation enabled"
);
}
}
// Works at least for Chrome, Firefox, Safari and probably more. Not Microsoft
// Edge though. They're special.
// Yell at clouds if a translator doesn't change it
const observer = new MutationObserver(() => {
translationCheck();
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['lang'],
childList: false,
characterData: false,
});
translationCheck();
}
})();