21 Commits

Author SHA1 Message Date
08c00efbdf Added BOM Excel 2022-01-14 21:28:01 +01:00
cdbeb2b8c3 converted Schematic to KiCad V6.0 2022-01-14 15:39:59 +01:00
cfc6b144f3 Reworked Button-Stuff 2022-01-14 15:36:17 +01:00
e1ca503bd2 Adjusted Pulse/Pause to match Requirements of Pump 2022-01-13 22:00:31 +01:00
d68b562126 Some Debugs and Corrections for LED-Status 2022-01-13 21:59:53 +01:00
2217d68026 Added Button-Function Rain/Normal Switch 2022-01-13 21:59:32 +01:00
acb3c97c02 periodic Update of WebUI 2022-01-12 01:10:21 +01:00
70ea944dc3 made Bleeding/Purging stored to EEPROM 2022-01-12 00:53:22 +01:00
cff7c7b29c shorter Pulses for Pump 2022-01-12 00:52:59 +01:00
ea4895c262 fixed Warnings 2022-01-12 00:52:27 +01:00
87e3d2e739 Updated PCB 2022-01-12 00:51:36 +01:00
a3d5c4ef6f fixed correct Calculation of Lube-Distance 2022-01-10 23:17:07 +01:00
febb658bf8 changed pinning and added EEPROM 2022-01-10 23:16:37 +01:00
bfa4272334 Basic Function works 2022-01-10 00:55:04 +01:00
402535051a need to reset TravelDistance after LubePulse 2022-01-10 00:03:11 +01:00
829e70d11a LED-Tweak and some first Functions für LubeApp 2022-01-10 00:02:21 +01:00
ffe943f187 WebUI config stuff 2022-01-09 20:51:16 +01:00
2e3a9f6e3f Work on EEPROM-Stuff 2022-01-08 03:14:26 +01:00
435a0e1f5a Build-Defines and stuff updated 2022-01-07 23:36:02 +01:00
01ecf5a4a4 changes in ceredentials-handling of sourcefiles 2022-01-07 21:35:06 +01:00
4bffdf932e Base Software System 2022-01-07 21:02:27 +01:00
25 changed files with 17328 additions and 1793 deletions

1
Hardware/.gitignore vendored
View File

@@ -28,3 +28,4 @@ fp-info-cache
*.csv
gerber/
*-backups/

Binary file not shown.

View File

@@ -169,6 +169,33 @@ X 5V 9 -100 800 100 D 50 50 1 1 W
ENDDRAW
ENDDEF
#
# Memory_EEPROM_24LC64
#
DEF Memory_EEPROM_24LC64 U 0 20 Y Y 1 F N
F0 "U" -250 250 50 H V C CNN
F1 "Memory_EEPROM_24LC64" 50 250 50 H V L CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
ALIAS 24LC02 24LC00 24LC04 24LC08 24LC01 24LC512 24LC64 24LC1025 24LC32 24LC256 24LC128 CAT24C256 CAT24C128
$FPLIST
DIP*W7.62mm*
SOIC*3.9x4.9mm*
TSSOP*4.4x3mm*P0.65mm*
DFN*3x2mm*P0.5mm*
$ENDFPLIST
DRAW
S -300 200 300 -200 1 1 10 f
X A0 1 -400 100 100 R 50 50 1 1 I
X A1 2 -400 0 100 R 50 50 1 1 I
X A2 3 -400 -100 100 R 50 50 1 1 I
X GND 4 0 -300 100 U 50 50 1 1 W
X SDA 5 400 100 100 L 50 50 1 1 B
X SCL 6 400 0 100 L 50 50 1 1 I
X WP 7 400 -100 100 L 50 50 1 1 I
X VCC 8 0 300 100 D 50 50 1 1 W
ENDDRAW
ENDDEF
#
# Regulator_Switching_R-78C5.0-1.0
#
DEF Regulator_Switching_R-78C5.0-1.0 U 0 10 Y Y 1 F N

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,443 @@
{
"board": {
"design_settings": {
"defaults": {
"board_outline_line_width": 0.049999999999999996,
"copper_line_width": 0.19999999999999998,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.049999999999999996,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.09999999999999999,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.09999999999999999,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.762,
"height": 1.524,
"width": 1.524
},
"silk_line_width": 0.12,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.15,
"silk_text_upright": false,
"zones": {
"45_degree_only": false,
"min_clearance": 0.254
}
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"meta": {
"filename": "board_design_settings.json",
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"copper_edge_clearance": "error",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint_type_mismatch": "error",
"hole_clearance": "error",
"hole_near_hole": "error",
"invalid_outline": "error",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "error",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zone_has_empty_net": "error",
"zones_intersect": "error"
},
"rule_severitieslegacy_courtyards_overlap": true,
"rule_severitieslegacy_no_courtyard_defined": false,
"rules": {
"allow_blind_buried_vias": false,
"allow_microvias": false,
"max_error": 0.005,
"min_clearance": 0.0,
"min_copper_edge_clearance": 0.049999999999999996,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.19999999999999998,
"min_microvia_drill": 0.09999999999999999,
"min_silk_clearance": 0.0,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.19999999999999998,
"min_via_annular_width": 0.049999999999999996,
"min_via_diameter": 0.39999999999999997,
"use_height_for_length_calcs": true
},
"track_widths": [
0.0,
0.5,
1.0,
2.0
],
"via_dimensions": [
{
"diameter": 0.0,
"drill": 0.0
},
{
"diameter": 0.7,
"drill": 0.35
},
{
"diameter": 1.0,
"drill": 0.6
},
{
"diameter": 2.0,
"drill": 1.0
}
],
"zones_allow_external_fillets": false,
"zones_use_no_outline": true
},
"layer_presets": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_label_syntax": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "oiler SMD.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12.0,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.25,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6.0
}
],
"meta": {
"version": 2
},
"net_colors": null
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "Rehoiler SMD.net",
"specctra_dsn": "",
"step": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"drawing": {
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.25,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.08
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "Pcbnew",
"ngspice": {
"fix_include_paths": true,
"fix_passive_vals": false,
"meta": {
"version": 0
},
"model_mode": 0,
"workbook_filename": ""
},
"page_layout_descr_file": "",
"plot_directory": "",
"spice_adjust_passive_values": false,
"spice_external_command": "spice \"%I\"",
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"b1ddb058-f7b2-429c-9489-f4e2242ad7e5",
""
]
],
"text_variables": {}
}

2199
Hardware/oiler SMD.kicad_sch Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -92,8 +92,6 @@ F 3 "" H 6500 4200 50 0001 C CNN
$EndComp
Wire Wire Line
6500 4200 6500 3950
Wire Wire Line
8450 3050 8450 3750
Wire Wire Line
8450 3750 8600 3750
Wire Wire Line
@@ -218,8 +216,9 @@ U 1 1 61D2CD57
P 8250 4400
F 0 "D2" V 8296 4320 50 0000 R CNN
F 1 "BAT42" V 8205 4320 50 0000 R CNN
F 2 "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal" H 8250 4225 50 0001 C CNN
F 2 "Diode_SMD:D_SOD-123" H 8250 4225 50 0001 C CNN
F 3 "http://www.vishay.com/docs/85660/bat42.pdf" H 8250 4400 50 0001 C CNN
F 4 "BAT 42" H 8250 4400 50 0001 C CNN "Reichelt Order No."
1 8250 4400
0 -1 -1 0
$EndComp
@@ -239,7 +238,7 @@ Wire Wire Line
Wire Wire Line
8250 4700 8250 4550
Wire Wire Line
8250 4250 8250 3150
8250 4250 8250 3350
$Comp
L Device:C C1
U 1 1 61D2F740
@@ -254,23 +253,23 @@ $EndComp
$Comp
L Device:C C2
U 1 1 61D32638
P 8000 3400
F 0 "C2" H 8115 3446 50 0000 L CNN
F 1 "10n" H 8115 3355 50 0000 L CNN
F 2 "Capacitor_SMD:C_0805_2012Metric_Pad1.18x1.45mm_HandSolder" H 8038 3250 50 0001 C CNN
F 3 "~" H 8000 3400 50 0001 C CNN
1 8000 3400
P 8000 3700
F 0 "C2" H 8115 3746 50 0000 L CNN
F 1 "10n" H 8115 3655 50 0000 L CNN
F 2 "Capacitor_SMD:C_0805_2012Metric_Pad1.18x1.45mm_HandSolder" H 8038 3550 50 0001 C CNN
F 3 "~" H 8000 3700 50 0001 C CNN
1 8000 3700
1 0 0 -1
$EndComp
$Comp
L power:GND #PWR0109
U 1 1 61D32EB9
P 8000 3550
F 0 "#PWR0109" H 8000 3300 50 0001 C CNN
F 1 "GND" H 8005 3377 50 0000 C CNN
F 2 "" H 8000 3550 50 0001 C CNN
F 3 "" H 8000 3550 50 0001 C CNN
1 8000 3550
P 8000 3850
F 0 "#PWR0109" H 8000 3600 50 0001 C CNN
F 1 "GND" H 8005 3677 50 0000 C CNN
F 2 "" H 8000 3850 50 0001 C CNN
F 3 "" H 8000 3850 50 0001 C CNN
1 8000 3850
1 0 0 -1
$EndComp
$Comp
@@ -284,32 +283,15 @@ F 3 "" H 7400 3850 50 0001 C CNN
1 7400 3850
1 0 0 -1
$EndComp
Wire Wire Line
6900 3150 8000 3150
Wire Wire Line
6900 3050 8450 3050
Wire Wire Line
7400 3250 7400 3550
Wire Wire Line
8000 3250 8000 3150
Connection ~ 8000 3150
Wire Wire Line
8000 3150 8250 3150
Wire Wire Line
6900 3250 7400 3250
Wire Wire Line
7400 3250 7750 3250
Wire Wire Line
7750 3250 7750 4250
Connection ~ 7400 3250
$Comp
L Diode:BAT42 D1
U 1 1 61D35ED1
P 7750 4400
F 0 "D1" V 7796 4320 50 0000 R CNN
F 1 "BAT42" V 7705 4320 50 0000 R CNN
F 2 "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal" H 7750 4225 50 0001 C CNN
F 2 "Diode_SMD:D_SOD-123" H 7750 4225 50 0001 C CNN
F 3 "http://www.vishay.com/docs/85660/bat42.pdf" H 7750 4400 50 0001 C CNN
F 4 "BAT 42" H 7750 4400 50 0001 C CNN "Reichelt Order No."
1 7750 4400
0 -1 -1 0
$EndComp
@@ -319,7 +301,7 @@ U 1 1 61D36E68
P 9100 2750
F 0 "D3" H 9100 2967 50 0000 C CNN
F 1 "1N4001" H 9100 2876 50 0000 C CNN
F 2 "Diode_THT:D_DO-41_SOD81_P10.16mm_Horizontal" H 9100 2575 50 0001 C CNN
F 2 "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal" H 9100 2575 50 0001 C CNN
F 3 "http://www.vishay.com/docs/88503/1n4001.pdf" H 9100 2750 50 0001 C CNN
1 9100 2750
1 0 0 -1
@@ -338,6 +320,7 @@ F 0 "C3" H 9568 2246 50 0000 L CNN
F 1 "470µF" H 9568 2155 50 0000 L CNN
F 2 "Capacitor_SMD:CP_Elec_8x10" H 9488 2050 50 0001 C CNN
F 3 "~" H 9450 2200 50 0001 C CNN
F 4 "ECC MZS350ARA471" H 9450 2200 50 0001 C CNN "Reichelt Order No."
1 9450 2200
1 0 0 -1
$EndComp
@@ -363,6 +346,7 @@ F 0 "C4" H 10668 2246 50 0000 L CNN
F 1 "100µ" H 10668 2155 50 0000 L CNN
F 2 "Capacitor_SMD:CP_Elec_6.3x7.7" H 10588 2050 50 0001 C CNN
F 3 "~" H 10550 2200 50 0001 C CNN
F 4 "ECC HXE250ARA101" H 10550 2200 50 0001 C CNN "Reichelt Order No."
1 10550 2200
1 0 0 -1
$EndComp
@@ -378,8 +362,6 @@ F 3 "" H 10550 2350 50 0001 C CNN
1 10550 2350
1 0 0 -1
$EndComp
Wire Wire Line
7150 3350 6900 3350
$Comp
L power:GND #PWR0113
U 1 1 61D3BF4D
@@ -423,7 +405,7 @@ U 1 1 61D3DFDC
P 9300 3350
F 0 "D4" V 9254 3430 50 0000 L CNN
F 1 "1N4001" V 9345 3430 50 0000 L CNN
F 2 "Diode_THT:D_DO-41_SOD81_P10.16mm_Horizontal" H 9300 3175 50 0001 C CNN
F 2 "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal" H 9300 3175 50 0001 C CNN
F 3 "http://www.vishay.com/docs/88503/1n4001.pdf" H 9300 3350 50 0001 C CNN
1 9300 3350
0 1 1 0
@@ -455,8 +437,6 @@ Wire Wire Line
7850 5400 7850 5450
Wire Wire Line
7150 5300 7300 5300
Wire Wire Line
7150 3350 7150 5300
Wire Wire Line
7750 4550 7750 5200
Wire Wire Line
@@ -481,94 +461,238 @@ Wire Wire Line
$Comp
L Connector_Generic:Conn_01x04 J5
U 1 1 61E12B85
P 7650 2500
F 0 "J5" H 7730 2492 50 0000 L CNN
F 1 "I2C" H 7730 2401 50 0000 L CNN
F 2 "Connector_PinHeader_2.54mm:PinHeader_1x04_P2.54mm_Vertical" H 7650 2500 50 0001 C CNN
F 3 "~" H 7650 2500 50 0001 C CNN
1 7650 2500
P 8450 2500
F 0 "J5" H 8530 2492 50 0000 L CNN
F 1 "I2C" H 8530 2401 50 0000 L CNN
F 2 "Connector_PinHeader_2.54mm:PinHeader_1x04_P2.54mm_Horizontal" H 8450 2500 50 0001 C CNN
F 3 "~" H 8450 2500 50 0001 C CNN
1 8450 2500
1 0 0 -1
$EndComp
$Comp
L power:+3.3V #PWR0116
U 1 1 61E137AF
P 7250 1550
F 0 "#PWR0116" H 7250 1400 50 0001 C CNN
F 1 "+3.3V" H 7265 1723 50 0000 C CNN
F 2 "" H 7250 1550 50 0001 C CNN
F 3 "" H 7250 1550 50 0001 C CNN
1 7250 1550
P 8050 1550
F 0 "#PWR0116" H 8050 1400 50 0001 C CNN
F 1 "+3.3V" H 8065 1723 50 0000 C CNN
F 2 "" H 8050 1550 50 0001 C CNN
F 3 "" H 8050 1550 50 0001 C CNN
1 8050 1550
1 0 0 -1
$EndComp
$Comp
L power:GND #PWR0117
U 1 1 61E147DB
P 7400 2750
F 0 "#PWR0117" H 7400 2500 50 0001 C CNN
F 1 "GND" H 7405 2577 50 0000 C CNN
F 2 "" H 7400 2750 50 0001 C CNN
F 3 "" H 7400 2750 50 0001 C CNN
1 7400 2750
P 8200 2750
F 0 "#PWR0117" H 8200 2500 50 0001 C CNN
F 1 "GND" H 8205 2577 50 0000 C CNN
F 2 "" H 8200 2750 50 0001 C CNN
F 3 "" H 8200 2750 50 0001 C CNN
1 8200 2750
1 0 0 -1
$EndComp
Wire Wire Line
7450 2700 7400 2700
8250 2700 8200 2700
Wire Wire Line
7400 2700 7400 2750
8200 2700 8200 2750
Wire Wire Line
6900 2950 7250 2950
8050 2950 8050 2400
Wire Wire Line
7250 2950 7250 2400
8050 2400 8250 2400
Wire Wire Line
7250 2400 7450 2400
7950 2850 7950 2500
Wire Wire Line
6900 2850 7150 2850
Wire Wire Line
7150 2850 7150 2500
Wire Wire Line
7150 2500 7450 2500
7950 2500 8250 2500
$Comp
L Device:R R4
U 1 1 61E189A2
P 7150 1850
F 0 "R4" H 7080 1804 50 0000 R CNN
F 1 "4k7" H 7080 1895 50 0000 R CNN
F 2 "Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder" V 7080 1850 50 0001 C CNN
F 3 "~" H 7150 1850 50 0001 C CNN
1 7150 1850
P 7950 1850
F 0 "R4" H 7880 1804 50 0000 R CNN
F 1 "4k7" H 7880 1895 50 0000 R CNN
F 2 "Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder" V 7880 1850 50 0001 C CNN
F 3 "~" H 7950 1850 50 0001 C CNN
1 7950 1850
-1 0 0 1
$EndComp
$Comp
L Device:R R5
U 1 1 61E1955B
P 7250 2150
F 0 "R5" H 7180 2104 50 0000 R CNN
F 1 "4k7" H 7180 2195 50 0000 R CNN
F 2 "Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder" V 7180 2150 50 0001 C CNN
F 3 "~" H 7250 2150 50 0001 C CNN
1 7250 2150
P 8050 2150
F 0 "R5" H 7980 2104 50 0000 R CNN
F 1 "4k7" H 7980 2195 50 0000 R CNN
F 2 "Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder" V 7980 2150 50 0001 C CNN
F 3 "~" H 8050 2150 50 0001 C CNN
1 8050 2150
-1 0 0 1
$EndComp
Wire Wire Line
7450 2600 7050 2600
8250 2600 7850 2600
Wire Wire Line
7050 2600 7050 1600
7850 2600 7850 1600
Wire Wire Line
7050 1600 7150 1600
7850 1600 7950 1600
Wire Wire Line
7250 1600 7250 1550
Connection ~ 7150 1600
8050 1600 8050 1550
Connection ~ 7950 1600
Wire Wire Line
7150 1600 7250 1600
7950 1600 8050 1600
Wire Wire Line
7250 2000 7250 1600
Connection ~ 7250 1600
8050 2000 8050 1600
Connection ~ 8050 1600
Wire Wire Line
7150 1600 7150 1700
7950 1600 7950 1700
Wire Wire Line
7250 2300 7250 2400
Connection ~ 7250 2400
8050 2300 8050 2400
Connection ~ 8050 2400
Wire Wire Line
7150 2000 7150 2500
Connection ~ 7150 2500
7950 2000 7950 2500
Connection ~ 7950 2500
Wire Wire Line
6900 3550 7150 3550
Wire Wire Line
7150 3550 7150 5300
Wire Wire Line
6900 3450 7400 3450
Connection ~ 7400 3450
Wire Wire Line
7400 3450 7400 3550
Wire Wire Line
7400 3450 7750 3450
Wire Wire Line
7750 3450 7750 4250
Wire Wire Line
6900 3350 8000 3350
Wire Wire Line
8000 3350 8000 3550
Wire Wire Line
8000 3350 8250 3350
Connection ~ 8000 3350
Wire Wire Line
8450 3250 8450 3750
Wire Wire Line
6900 3250 8450 3250
$Comp
L Memory_EEPROM:24LC64 U3
U 1 1 61DDD4E7
P 6750 1550
F 0 "U3" H 6750 2031 50 0000 C CNN
F 1 "24LC64" H 6750 1940 50 0000 C CNN
F 2 "Package_SO:SOIC-8_3.9x4.9mm_P1.27mm" H 6750 1550 50 0001 C CNN
F 3 "http://ww1.microchip.com/downloads/en/DeviceDoc/21189f.pdf" H 6750 1550 50 0001 C CNN
1 6750 1550
1 0 0 -1
$EndComp
$Comp
L power:+3.3V #PWR0118
U 1 1 61DDE198
P 6750 1250
F 0 "#PWR0118" H 6750 1100 50 0001 C CNN
F 1 "+3.3V" H 6765 1423 50 0000 C CNN
F 2 "" H 6750 1250 50 0001 C CNN
F 3 "" H 6750 1250 50 0001 C CNN
1 6750 1250
1 0 0 -1
$EndComp
$Comp
L power:GND #PWR0119
U 1 1 61DDE4C0
P 6750 1850
F 0 "#PWR0119" H 6750 1600 50 0001 C CNN
F 1 "GND" H 6755 1677 50 0000 C CNN
F 2 "" H 6750 1850 50 0001 C CNN
F 3 "" H 6750 1850 50 0001 C CNN
1 6750 1850
1 0 0 -1
$EndComp
$Comp
L power:GND #PWR0120
U 1 1 61DDE71F
P 6300 1850
F 0 "#PWR0120" H 6300 1600 50 0001 C CNN
F 1 "GND" H 6305 1677 50 0000 C CNN
F 2 "" H 6300 1850 50 0001 C CNN
F 3 "" H 6300 1850 50 0001 C CNN
1 6300 1850
1 0 0 -1
$EndComp
Wire Wire Line
6350 1650 6300 1650
Wire Wire Line
6300 1650 6300 1850
Wire Wire Line
6350 1450 6300 1450
Wire Wire Line
6300 1450 6300 1550
Connection ~ 6300 1650
Wire Wire Line
6350 1550 6300 1550
Connection ~ 6300 1550
Wire Wire Line
6300 1550 6300 1650
Wire Wire Line
6900 2850 7400 2850
Wire Wire Line
6900 2950 7500 2950
Wire Wire Line
7150 1550 7400 1550
Wire Wire Line
7400 1550 7400 2850
Connection ~ 7400 2850
Wire Wire Line
7400 2850 7950 2850
Wire Wire Line
7500 1450 7500 2950
Wire Wire Line
7150 1450 7500 1450
Connection ~ 7500 2950
Wire Wire Line
7500 2950 8050 2950
$Comp
L power:GND #PWR0121
U 1 1 61DFBD18
P 7250 1850
F 0 "#PWR0121" H 7250 1600 50 0001 C CNN
F 1 "GND" H 7255 1677 50 0000 C CNN
F 2 "" H 7250 1850 50 0001 C CNN
F 3 "" H 7250 1850 50 0001 C CNN
1 7250 1850
1 0 0 -1
$EndComp
Wire Wire Line
7150 1650 7250 1650
Wire Wire Line
7250 1650 7250 1850
$Comp
L power:GND #PWR0122
U 1 1 61DEAC05
P 6000 1700
F 0 "#PWR0122" H 6000 1450 50 0001 C CNN
F 1 "GND" H 6005 1527 50 0000 C CNN
F 2 "" H 6000 1700 50 0001 C CNN
F 3 "" H 6000 1700 50 0001 C CNN
1 6000 1700
1 0 0 -1
$EndComp
$Comp
L Device:C C5
U 1 1 61DEA081
P 6000 1550
F 0 "C5" H 6115 1596 50 0000 L CNN
F 1 "10n" H 6115 1505 50 0000 L CNN
F 2 "Capacitor_SMD:C_0805_2012Metric_Pad1.18x1.45mm_HandSolder" H 6038 1400 50 0001 C CNN
F 3 "~" H 6000 1550 50 0001 C CNN
1 6000 1550
1 0 0 -1
$EndComp
$Comp
L power:+3.3V #PWR0123
U 1 1 61DEAFE2
P 6000 1400
F 0 "#PWR0123" H 6000 1250 50 0001 C CNN
F 1 "+3.3V" H 6015 1573 50 0000 C CNN
F 2 "" H 6000 1400 50 0001 C CNN
F 3 "" H 6000 1400 50 0001 C CNN
1 6000 1400
1 0 0 -1
$EndComp
$EndSCHEMATC

6
Software/ChainLube/.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
wifi_credentials.ini

View File

@@ -0,0 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
]
}

View File

@@ -0,0 +1,8 @@
import subprocess
revision = (
subprocess.check_output(["git", "rev-parse", "--short=10", "HEAD"])
.strip()
.decode("utf-8")
)
print("-DGIT_REV='\"%s\"'" % revision)

View File

@@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

View File

@@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

View File

@@ -0,0 +1,47 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
extra_configs =
wifi_credentials.ini
[env:d1_mini]
platform = espressif8266
board = d1_mini
framework = arduino
upload_protocol = esptool
upload_speed = 921600
;upload_port = ChainLube_DDEFB2
;upload_protocol = espota
;upload_flags =
; --auth=${wifi_cred.admin_password}
build_flags =
!python git_rev_macro.py
-DWIFI_SSID=${wifi_cred.wifi_ssid}
-DWIFI_PASSWORD=${wifi_cred.wifi_password}
-DADMIN_PASSWORD=${wifi_cred.admin_password}
-DWIFI_AP_PASSWORD=${wifi_cred.wifi_ap_password}
-DWIFI_AP_IP_GW=10,0,0,1
board_build.filesystem = littlefs
monitor_filters = esp8266_exception_decoder
monitor_speed = 115200
board_build.ldscript = eagle.flash.4m.ld
lib_ldf_mode = deep
lib_deps =
olikraus/U8g2 @ ^2.28.8
joaolopesf/RemoteDebug @ ^2.1.2
fastled/FastLED @ ^3.5.0
sstaub/Ticker @ ^4.2.0
s00500/ESPUI @ ^2.0.0

View File

@@ -0,0 +1,33 @@
#ifndef _COMMON_H_
#define _COMMON_H_
#define Q(x) #x
#define QUOTE(x) Q(x)
#define GPIO_BUTTON D5
#define GPIO_LED D6
#define GPIO_TRIGGER D4
#define GPIO_PUMP D3
#ifndef HOST_NAME
#define HOST_NAME "ChainLube_%06X" // Use printf-Formatting - Chip-ID (uin32_t) will be added
#endif
#ifndef OTA_DELAY
#define OTA_DELAY 50 // ticks -> 10ms / tick
#endif
#ifndef ADMIN_PASSWORD
#error "You need to define ADMIN_PASSWORD for OTA-Update"
#endif
#ifndef WIFI_PASSWORD
#error "You must define an WIFI_PASSWORD for OTA-Update"
#endif
#ifndef WIFI_SSID
#error "You must define an WIFI_SSID for OTA-Update"
#endif
#ifndef WIFI_AP_PASSWORD
#error "You must define an WIFI_AP_PASSWORD for Standalone AP-Mode"
#endif
#endif

View File

@@ -0,0 +1,44 @@
#include <Arduino.h>
#include "config.h"
LubeConfig_t LubeConfig;
void StoreConfig_EEPROM()
{
LubeConfig.checksum = 0;
LubeConfig.checksum = Checksum_EEPROM((uint8_t *)&LubeConfig, sizeof(LubeConfig));
EEPROM.begin(512);
EEPROM.put(0, LubeConfig);
EEPROM.commit();
EEPROM.end();
}
void GetConfig_EEPROM()
{
EEPROM.begin(512);
EEPROM.get(0, LubeConfig);
EEPROM.end();
uint32_t checksum = LubeConfig.checksum;
LubeConfig.checksum = 0;
if (Checksum_EEPROM((uint8_t *)&LubeConfig, sizeof(LubeConfig)) == checksum)
Serial.printf("Checksum OK");
else
Serial.printf("Checksum BAD");
}
uint32_t Checksum_EEPROM(uint8_t const *data, size_t len)
{
if (data == NULL)
return 0;
uint32_t crc = 0;
while (len--)
{
crc ^= *data++;
for (uint8_t k = 0; k < 8; k++)
crc = crc & 1 ? (crc >> 1) ^ 0xb2 : crc >> 1;
}
return crc ^ 0xff;
}

View File

@@ -0,0 +1,30 @@
#ifndef _CONFIG_H_
#define _CONFIG_H_
#include <Arduino.h>
#include <EEPROM.h>
typedef struct
{
uint32_t DistancePerLube_Default = 0;
uint32_t DistancePerLube_Rain = 0;
uint32_t tankCapacity_ml = 320;
uint32_t amountPerDose_µl = 0;
uint32_t tankRemain_µl = 0;
uint8_t TankRemindAtPercentage = 30;
uint8_t PulsePerRevolution = 1;
uint32_t TireWidth_mm = 150;
uint32_t TireWidthHeight_Ratio = 70;
uint32_t RimDiameter_Inch = 18;
uint32_t DistancePerRevolution_mm = 2000;
uint8_t BleedingPulses = 25;
uint32_t checksum = 0;
} LubeConfig_t;
void StoreConfig_EEPROM();
void GetConfig_EEPROM();
uint32_t Checksum_EEPROM(uint8_t const *data, size_t len);
extern LubeConfig_t LubeConfig;
#endif // _CONFIG_H_

View File

@@ -0,0 +1,27 @@
#ifndef _GLOBALS_H_
#define _GLOBALS_H_
#include <Arduino.h>
typedef enum eSystem_Status
{
sysStat_NOP,
sysStat_Startup,
sysStat_Normal,
sysStat_Rain,
sysStat_Purge,
sysStat_Error
} tSystem_Status;
typedef struct Globals_s {
tSystem_Status systemStatus = sysStat_Startup;
uint8_t purgePulses= 0;
tSystem_Status resumeStatus = sysStat_Startup;
char systemStatustxt[16] = "";
}Globals_t;
extern Globals_t globals;
extern uint32_t TravelDistance_highRes;
#endif

View File

@@ -0,0 +1,83 @@
#include "lubeapp.h"
uint32_t lubePulseTimestamp = 0;
void RunLubeApp(volatile uint32_t *wheelPulseCounter)
{
// Calculate traveled Distance in mm
TravelDistance_highRes += (*wheelPulseCounter * (LubeConfig.DistancePerRevolution_mm / LubeConfig.PulsePerRevolution));
*wheelPulseCounter = 0;
// check if we have to Lube!
switch (globals.systemStatus)
{
case sysStat_Startup:
if (millis() > STARTUP_DELAY)
{
globals.systemStatus = sysStat_Normal;
globals.resumeStatus = sysStat_Normal;
}
break;
case sysStat_Normal:
if (TravelDistance_highRes / 1000 > LubeConfig.DistancePerLube_Default)
{
LubePulse();
TravelDistance_highRes = 0;
}
break;
case sysStat_Rain:
if (TravelDistance_highRes / 1000 > LubeConfig.DistancePerLube_Rain)
{
LubePulse();
TravelDistance_highRes = 0;
}
break;
case sysStat_Purge:
if (globals.purgePulses > 0)
{
if (lubePulseTimestamp + LUBE_PULSE_PAUSE_MS < millis())
{
LubePulse();
globals.purgePulses--;
}
}
else
{
globals.systemStatus = globals.resumeStatus;
}
break;
case sysStat_Error:
default:
break;
}
switch (globals.systemStatus)
{
case sysStat_Normal:
strcpy(globals.systemStatustxt, "Normal");
break;
case sysStat_Purge:
strcpy(globals.systemStatustxt, "Purge");
break;
case sysStat_Rain:
strcpy(globals.systemStatustxt, "Rain");
break;
case sysStat_Startup:
strcpy(globals.systemStatustxt, "Startup");
break;
}
// maintain Pin-State of Lube-Pump
if (lubePulseTimestamp > millis())
digitalWrite(GPIO_PUMP, HIGH);
else
digitalWrite(GPIO_PUMP, LOW);
}
void LubePulse()
{
lubePulseTimestamp = millis() + LUBE_PULSE_LENGHT_MS;
LubeConfig.tankRemain_µl = LubeConfig.tankRemain_µl - LubeConfig.amountPerDose_µl;
}

View File

@@ -0,0 +1,17 @@
#ifndef _LUBEAPP_H_
#define _LUBEAPP_H_
#include <Arduino.h>
#include <stdlib.h>
#include "config.h"
#include "common.h"
#include "globals.h"
#define LUBE_PULSE_LENGHT_MS 160
#define LUBE_PULSE_PAUSE_MS 100
#define STARTUP_DELAY 5000
void RunLubeApp(volatile uint32_t * wheelPulseCounter);
void LubePulse();
#endif

View File

@@ -0,0 +1,496 @@
#include <Arduino.h>
#include <Wire.h>
#include <U8g2lib.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266mDNS.h>
#include <ArduinoOTA.h>
#include <RemoteDebug.h>
#include <FastLED.h>
#include <Ticker.h>
#include "common.h"
#include "rmtdbghelp.h"
#include "lubeapp.h"
#include "webui.h"
#include "config.h"
#include "globals.h"
const char *ssid = QUOTE(WIFI_SSID);
const char *password = QUOTE(WIFI_PASSWORD);
const uint32_t connectTimeoutMs = 5000;
#ifdef DEBUG
const bool debug_flag = true;
#else
const bool debug_flag = false;
#endif
bool startSetupMode = false;
char DeviceName[33];
Globals_t globals;
uint32_t TravelDistance_highRes;
volatile uint32_t wheel_pulse = 0;
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(-1);
RemoteDebug Debug;
ESP8266WiFiMulti wifiMulti;
CRGB leds[1];
// Function-Prototypes
String IpAddress2String(const IPAddress &ipAddress);
void processCmdRemoteDebug();
void RemotDebug_printSystemInfo();
void RemoteDebug_printWifiInfo();
void wifiMaintainConnectionTicker_callback();
void updateWebUITicker_callback();
void IRAM_ATTR trigger_ISR();
void LED_Process(uint8_t override = false, CRGB setColor = CRGB::White);
void Display_Process();
void Button_Process();
void startWiFiAP();
Ticker WiFiMaintainConnectionTicker(wifiMaintainConnectionTicker_callback, 1000, 0, MILLIS);
Ticker UpdateWebUITicker(updateWebUITicker_callback, 5000, 0, MILLIS);
void setup()
{
system_update_cpu_freq(SYS_CPU_80MHZ);
snprintf(DeviceName, 32, HOST_NAME, ESP.getChipId());
WiFi.mode(WIFI_OFF);
WiFi.persistent(false);
Serial.begin(115200);
Serial.setDebugOutput(true);
Serial.println("Souko's ChainLube Mk1");
Serial.println(DeviceName);
GetConfig_EEPROM();
u8x8.begin();
u8x8.setFont(u8x8_font_chroma48medium8_r);
FastLED.addLeds<WS2811, GPIO_LED, GRB>(leds, 1); // GRB ordering is assumed
pinMode(GPIO_TRIGGER, INPUT_PULLUP);
pinMode(GPIO_BUTTON, INPUT_PULLUP);
pinMode(GPIO_PUMP, OUTPUT);
attachInterrupt(digitalPinToInterrupt(GPIO_TRIGGER), trigger_ISR, FALLING);
WiFi.mode(WIFI_STA);
WiFi.setHostname(DeviceName);
wifiMulti.addAP(QUOTE(WIFI_SSID), QUOTE(WIFI_PASSWORD));
WiFiMaintainConnectionTicker.start();
if (MDNS.begin(DeviceName))
MDNS.addService("telnet", "tcp", 23);
Debug.begin(DeviceName); // Initialize the WiFi server
Debug.setResetCmdEnabled(true); // Enable the reset command
Debug.showProfiler(true); // Profiler (Good to measure times, to optimize codes)
Debug.showColors(true); // Colors
Debug.setPassword(QUOTE(ADMIN_PASSWORD));
Debug.setHelpProjectsCmds(helpCmd);
Debug.setCallBackProjectCmds(&processCmdRemoteDebug);
ArduinoOTA.setPort(8266);
ArduinoOTA.setHostname(DeviceName);
ArduinoOTA.setPassword(QUOTE(ADMIN_PASSWORD));
ArduinoOTA.onStart([]()
{
u8x8.clearDisplay();
u8x8.drawString(0, 0, "OTA-Update");
u8x8.refreshDisplay(); });
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total)
{
static bool refreshed = false;
if (!refreshed)
{
u8x8.clearDisplay();
refreshed = true;
u8x8.drawString(0, 0, "OTA Upload");
}
uint32_t percent = progress / (total / 100);
u8x8.setCursor(0, 1);
u8x8.printf("%d %%", percent);
u8x8.refreshDisplay(); });
ArduinoOTA.onEnd([]()
{
u8x8.clearDisplay();
u8x8.drawString(0, 0, "OTA-Restart");
u8x8.refreshDisplay(); });
ArduinoOTA.begin();
u8x8.clearDisplay();
u8x8.drawString(4, 0, "Souko's");
u8x8.drawString(1, 1, "ChainLube Mk1");
u8x8.refreshDisplay();
initWebUI();
UpdateWebUITicker.start();
}
void loop()
{
RunLubeApp(&wheel_pulse);
WiFiMaintainConnectionTicker.update();
UpdateWebUITicker.update();
Display_Process();
Button_Process();
LED_Process();
ArduinoOTA.handle();
Debug.handle();
yield();
}
String IpAddress2String(const IPAddress &ipAddress)
{
return String(ipAddress[0]) + String(".") +
String(ipAddress[1]) + String(".") +
String(ipAddress[2]) + String(".") +
String(ipAddress[3]);
}
void processCmdRemoteDebug()
{
String lastCmd = Debug.getLastCommand();
if (lastCmd == "sysinfo")
RemotDebug_printSystemInfo();
else if (lastCmd == "netinfo")
RemoteDebug_printWifiInfo();
}
void RemotDebug_printSystemInfo()
{
debugA("Souko's ChainOiler Mk1");
debugA("Hostname: %s", DeviceName);
FlashMode_t ideMode = ESP.getFlashChipMode();
debugA("Sdk version: %s", ESP.getSdkVersion());
debugA("Core Version: %s", ESP.getCoreVersion().c_str());
debugA("Boot Version: %u", ESP.getBootVersion());
debugA("Boot Mode: %u", ESP.getBootMode());
debugA("CPU Frequency: %u MHz", ESP.getCpuFreqMHz());
debugA("Reset reason: %s", ESP.getResetReason().c_str());
debugA("Flash Size: %d", ESP.getFlashChipRealSize());
debugA("Flash Size IDE: %d", ESP.getFlashChipSize());
debugA("Flash ide mode: %s", (ideMode == FM_QIO ? "QIO" : ideMode == FM_QOUT ? "QOUT"
: ideMode == FM_DIO ? "DIO"
: ideMode == FM_DOUT ? "DOUT"
: "UNKNOWN"));
debugA("OTA-Pass: %s", QUOTE(ADMIN_PASSWORD));
}
void RemoteDebug_printWifiInfo()
{
}
void wifiMaintainConnectionTicker_callback()
{
static uint32_t WiFiFailCount = 0;
const uint32_t WiFiFailMax = 20;
if (wifiMulti.run(connectTimeoutMs) == WL_CONNECTED)
{
return;
}
else
{
if (WiFiFailCount < WiFiFailMax)
{
WiFiFailCount++;
}
else
{
Serial.println("WiFi not connected! - Start AP");
startWiFiAP();
}
}
}
void updateWebUITicker_callback()
{
UpdateWebUI();
}
void trigger_ISR()
{
wheel_pulse++;
}
void LED_Process(uint8_t override, CRGB SetColor)
{
typedef enum
{
LED_Startup,
LED_Normal,
LED_Confirm_Normal,
LED_Rain,
LED_Confirm_Rain,
LED_Purge,
LED_Error,
LED_Override
} tLED_Status;
static tSystem_Status oldSysStatus = sysStat_NOP;
static tLED_Status LED_Status = LED_Startup;
static CRGB LED_override_color = 0;
static tLED_Status LED_ResumeOverrideStatus = LED_Startup;
uint8_t color = 0;
uint32_t timer = 0;
static uint32_t timestamp = 0;
timer = millis();
if (override == 1)
{
if (LED_Status != LED_Override)
{
LED_ResumeOverrideStatus = LED_Status;
debugA("Override LED_Status");
}
LED_Status = LED_Override;
LED_override_color = SetColor;
}
if (override == 2)
{
if (LED_Status == LED_Override)
{
LED_Status = LED_ResumeOverrideStatus;
debugA("Resume LED_Status");
}
}
if (oldSysStatus != globals.systemStatus)
{
switch (globals.systemStatus)
{
case sysStat_Startup:
LED_Status = LED_Startup;
debugA("sysStat: Startup");
break;
case sysStat_Normal:
timestamp = timer + 3500;
LED_Status = LED_Confirm_Normal;
debugA("sysStat: Normal");
break;
case sysStat_Rain:
timestamp = timer + 3500;
LED_Status = LED_Confirm_Rain;
debugA("sysStat: Rain");
break;
case sysStat_Purge:
LED_Status = LED_Purge;
debugA("sysStat: Purge");
break;
case sysStat_Error:
LED_Status = LED_Error;
debugA("sysStat: Error");
break;
case sysStat_NOP:
default:
break;
}
oldSysStatus = globals.systemStatus;
}
uint32_t percentage = LubeConfig.tankRemain_µl / (LubeConfig.tankCapacity_ml * 10);
switch (LED_Status)
{
case LED_Startup:
FastLED.setBrightness(255);
if (percentage < LubeConfig.TankRemindAtPercentage)
leds[0] = CRGB::OrangeRed;
else
leds[0] = CRGB::White;
break;
case LED_Confirm_Normal:
FastLED.setBrightness(255);
leds[0] = timer % 250 > 125 ? CRGB(0, 255, 0) : CRGB(0, 4, 0);
if (timestamp < timer)
{
LED_Status = LED_Normal;
FastLED.setBrightness(64);
debugA("LED_Status: Confirm -> Normal");
}
break;
case LED_Normal:
leds[0] = timer % 2000 > 1950 ? CRGB(0, 255, 0) : CRGB(0, 4, 0);
break;
case LED_Confirm_Rain:
FastLED.setBrightness(255);
leds[0] = timer % 250 > 125 ? CRGB(0, 0, 255) : CRGB(0, 0, 4);
if (timestamp < timer)
{
LED_Status = LED_Rain;
FastLED.setBrightness(64);
debugA("LED_Status: Confirm -> Rain");
}
break;
case LED_Rain:
leds[0] = timer % 2000 > 1950 ? CRGB(0, 0, 255) : CRGB(0, 0, 4);
break;
case LED_Purge:
timer = timer % 500;
color = timer / 2;
leds[0] = CRGB::DeepPink;
if (timer < 250)
FastLED.setBrightness(color);
else
FastLED.setBrightness(250 - color);
break;
case LED_Error:
leds[0] = timer % 500 > 250 ? CRGB::Red : CRGB::Black;
break;
case LED_Override:
leds[0] = LED_override_color;
break;
default:
break;
}
FastLED.show();
}
void Display_Process()
{
u8x8.setCursor(0, 3);
uint32_t DistRemain = globals.systemStatus == sysStat_Normal ? LubeConfig.DistancePerLube_Default : LubeConfig.DistancePerLube_Rain;
DistRemain -= TravelDistance_highRes / 1000;
u8x8.printf("Mode: %10s\n\n", globals.systemStatustxt);
u8x8.printf("next Lube: %4dm\n\n", DistRemain);
u8x8.printf("Tank: %8dml\n\n", LubeConfig.tankRemain_µl / 1000);
u8x8.refreshDisplay();
}
void Button_Process()
{
#define BUTTON_ACTION_DELAY_TOGGLEMODE 500
#define BUTTON_ACTION_DELAY_PURGE 3500
#define BUTTON_ACTION_DELAY_WIFI 6500
#define BUTTON_ACTION_DELAY_NOTHING 9500
typedef enum buttonAction_e
{
BTN_INACTIVE,
BTN_NOTHING,
BTN_TOGGLEMODE,
BTN_TOGGLEWIFI,
BTN_STARTPURGE
} buttonAction_t;
static uint32_t buttonTimestamp = 0;
static buttonAction_t buttonAction = BTN_INACTIVE;
if (digitalRead(GPIO_BUTTON) == LOW)
{
if (buttonTimestamp == 0)
buttonTimestamp = millis();
if (buttonTimestamp + BUTTON_ACTION_DELAY_NOTHING < millis())
{
LED_Process(1, CRGB::White);
buttonAction = BTN_NOTHING;
}
else if (buttonTimestamp + BUTTON_ACTION_DELAY_WIFI < millis())
{
LED_Process(1, CRGB::Yellow);
buttonAction = BTN_TOGGLEWIFI;
}
else if (buttonTimestamp + BUTTON_ACTION_DELAY_PURGE < millis())
{
LED_Process(1, CRGB::DeepPink);
buttonAction = BTN_STARTPURGE;
}
else if (buttonTimestamp + BUTTON_ACTION_DELAY_TOGGLEMODE < millis())
{
CRGB color = globals.systemStatus == sysStat_Normal ? CRGB::Blue : CRGB::Green;
LED_Process(1, color);
buttonAction = BTN_TOGGLEMODE;
}
}
else
{
if (buttonAction != BTN_INACTIVE)
{
switch (buttonAction)
{
case BTN_TOGGLEWIFI:
startWiFiAP();
debugA("Starting WiFi AP");
break;
case BTN_STARTPURGE:
globals.systemStatus = sysStat_Purge;
globals.purgePulses = LubeConfig.BleedingPulses;
debugA("Starting Purge");
break;
case BTN_TOGGLEMODE:
switch (globals.systemStatus)
{
case sysStat_Normal:
globals.systemStatus = sysStat_Rain;
globals.resumeStatus = sysStat_Rain;
break;
case sysStat_Rain:
globals.systemStatus = sysStat_Normal;
globals.resumeStatus = sysStat_Normal;
break;
default:
break;
}
debugA("Toggling Mode");
break;
case BTN_NOTHING:
default:
debugA("Nothing or invalid");
break;
}
LED_Process(2);
}
buttonAction = BTN_INACTIVE;
buttonTimestamp = 0;
}
}
void startWiFiAP()
{
WiFi.mode(WIFI_OFF);
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(IPAddress(WIFI_AP_IP_GW), IPAddress(WIFI_AP_IP_GW), IPAddress(255, 255, 255, 0));
WiFi.softAP(DeviceName, QUOTE(WIFI_AP_PASSWORD));
WiFiMaintainConnectionTicker.stop();
Serial.println("WiFi AP started, stopped Maintain-Timer");
}

View File

@@ -0,0 +1,2 @@
const char helpCmd[] = "sysinfo - System Info\r\n"
"netinfo - WiFi Info\r\n";

View File

@@ -0,0 +1,137 @@
#include "webui.h"
uint16_t tab_lube;
uint16_t tab_wheel;
uint16_t tab_tank;
uint16_t tab_maintenance;
uint16_t tab_store;
uint16_t num_lubedist_normal;
uint16_t num_lubedist_rain;
uint16_t button_lubedist;
uint16_t num_wheel_width;
uint16_t num_wheel_ratio;
uint16_t num_wheel_rim;
uint16_t button_wheelcalc;
uint16_t num_wheel_ppr;
uint16_t num_wheel_dist;
uint16_t num_tank_capacity;
uint16_t num_tank_notify;
uint16_t num_dose_per_pulse;
uint16_t label_tankRemain;
uint16_t button_reset_tank;
uint16_t num_purge_pulses;
uint16_t button_purge;
uint16_t button_store;
uint16_t button_reload;
uint16_t label_storeStatus;
void SettingChanged_Callback(Control *sender, int type)
{
if (sender->id == num_lubedist_normal)
LubeConfig.DistancePerLube_Default = ESPUI.getControl(num_lubedist_normal)->value.toInt();
else if (sender->id == num_lubedist_rain)
LubeConfig.DistancePerLube_Rain = ESPUI.getControl(num_lubedist_rain)->value.toInt();
else if (sender->id == num_wheel_width)
LubeConfig.TireWidth_mm = ESPUI.getControl(num_wheel_width)->value.toInt();
else if (sender->id == num_wheel_ratio)
LubeConfig.TireWidthHeight_Ratio = ESPUI.getControl(num_wheel_ratio)->value.toInt();
else if (sender->id == num_wheel_rim)
LubeConfig.RimDiameter_Inch = ESPUI.getControl(num_wheel_rim)->value.toInt();
else if (sender->id == num_wheel_ppr)
LubeConfig.PulsePerRevolution = ESPUI.getControl(num_wheel_ppr)->value.toInt();
else if (sender->id == num_wheel_dist)
LubeConfig.DistancePerRevolution_mm = ESPUI.getControl(num_wheel_dist)->value.toInt();
else if (sender->id == num_tank_capacity)
LubeConfig.tankCapacity_ml = ESPUI.getControl(num_tank_capacity)->value.toInt();
else if (sender->id == num_tank_notify)
LubeConfig.TankRemindAtPercentage = ESPUI.getControl(num_tank_notify)->value.toInt();
else if (sender->id == num_dose_per_pulse)
LubeConfig.amountPerDose_µl = ESPUI.getControl(num_dose_per_pulse)->value.toInt();
else if (sender->id == num_purge_pulses)
LubeConfig.BleedingPulses = ESPUI.getControl(num_purge_pulses)->value.toInt();
}
void buttons_Callback(Control *sender, int type)
{
if (type != B_UP)
return;
if (sender->id == button_wheelcalc)
{
LubeConfig.TireWidth_mm = ESPUI.getControl(num_wheel_width)->value.toInt();
LubeConfig.RimDiameter_Inch = ESPUI.getControl(num_wheel_rim)->value.toInt();
LubeConfig.TireWidthHeight_Ratio = ESPUI.getControl(num_wheel_ratio)->value.toInt();
LubeConfig.DistancePerRevolution_mm = (uint32_t)((((((float)LubeConfig.TireWidthHeight_Ratio / 100.0) * (float)LubeConfig.TireWidth_mm) * 2.0) + ((float)LubeConfig.RimDiameter_Inch * 25.4)) * 3.1416);
ESPUI.updateControlValue(num_wheel_dist, String(LubeConfig.DistancePerRevolution_mm));
}
if (sender->id == button_reset_tank)
{
LubeConfig.tankRemain_µl = LubeConfig.tankCapacity_ml * 1000;
ESPUI.print(label_tankRemain, String(LubeConfig.tankRemain_µl / 1000));
}
if (sender->id == button_purge)
{
Serial.printf("Starting to Purge with %d pulses", LubeConfig.BleedingPulses);
globals.purgePulses = LubeConfig.BleedingPulses;
globals.resumeStatus = globals.systemStatus;
globals.systemStatus = sysStat_Purge;
}
if (sender->id == button_store)
{
StoreConfig_EEPROM();
ESPUI.print(label_storeStatus, "Successfully Stored Settings");
}
if (sender->id == button_reload)
{
GetConfig_EEPROM();
ESPUI.print(label_storeStatus, "Successfully Reloaded Settings");
}
}
void initWebUI()
{
tab_lube = ESPUI.addControl(ControlType::Tab, "Dosierung", "Dosierung");
tab_wheel = ESPUI.addControl(ControlType::Tab, "Erfassung", "Erfassung");
tab_tank = ESPUI.addControl(ControlType::Tab, "Tank", "Tank");
tab_maintenance = ESPUI.addControl(ControlType::Tab, "Wartung", "Wartung");
tab_store = ESPUI.addControl(ControlType::Tab, "Speichern", "Speichern");
num_lubedist_normal = ESPUI.addControl(ControlType::Number, "Öl-Impuls alle x Meter (Normal)", String(LubeConfig.DistancePerLube_Default), ControlColor::Emerald, tab_lube, &SettingChanged_Callback);
num_lubedist_rain = ESPUI.addControl(ControlType::Number, "Öl-Impuls alle x Meter (Regen)", String(LubeConfig.DistancePerLube_Rain), ControlColor::Emerald, tab_lube, &SettingChanged_Callback);
num_wheel_width = ESPUI.addControl(ControlType::Number, "Reifenbreite (mm)", String(LubeConfig.TireWidth_mm), ControlColor::Peterriver, tab_wheel, &SettingChanged_Callback);
num_wheel_ratio = ESPUI.addControl(ControlType::Number, "Höhe/Breite-Verhältniss", String(LubeConfig.TireWidthHeight_Ratio), ControlColor::Peterriver, tab_wheel, &SettingChanged_Callback);
num_wheel_rim = ESPUI.addControl(ControlType::Number, "Felgendurchmesser (Zoll)", String(LubeConfig.RimDiameter_Inch), ControlColor::Peterriver, tab_wheel, &SettingChanged_Callback);
button_wheelcalc = ESPUI.addControl(ControlType::Button, "Abrollumfang aus Reifendaten berechnen", "Berechnen", ControlColor::Peterriver, tab_wheel, &buttons_Callback);
num_wheel_dist = ESPUI.addControl(ControlType::Number, "Wegstrecke pro Radumdrehung (mm)", String(LubeConfig.DistancePerRevolution_mm), ControlColor::Wetasphalt, tab_wheel, &SettingChanged_Callback);
num_wheel_ppr = ESPUI.addControl(ControlType::Number, "Sensorimpulse pro Umdrehung", String(LubeConfig.PulsePerRevolution), ControlColor::Wetasphalt, tab_wheel, &SettingChanged_Callback);
num_tank_capacity = ESPUI.addControl(ControlType::Number, "Tankinhalt maximal (ml)", String(LubeConfig.tankCapacity_ml), ControlColor::Carrot, tab_tank, &SettingChanged_Callback);
num_tank_notify = ESPUI.addControl(ControlType::Number, "Tankinhalt Warnung (%)", String(LubeConfig.TankRemindAtPercentage), ControlColor::Carrot, tab_tank, &SettingChanged_Callback);
num_dose_per_pulse = ESPUI.addControl(ControlType::Number, "Menge pro Pumpenimpuls (µl)", String(LubeConfig.amountPerDose_µl), ControlColor::Carrot, tab_tank, &SettingChanged_Callback);
label_tankRemain = ESPUI.addControl(ControlType::Label, "Tankinhalt verbleibend (ml, geschätzt)", String(LubeConfig.tankRemain_µl / 1000), ControlColor::Alizarin, tab_maintenance);
button_reset_tank = ESPUI.addControl(ControlType::Button, "Tankinhalt zurücksetzen", "Reset", ControlColor::Alizarin, tab_maintenance, &buttons_Callback);
num_purge_pulses = ESPUI.addControl(ControlType::Number, "Entlüftung Impulse", String(LubeConfig.BleedingPulses), ControlColor::Alizarin, tab_maintenance, &SettingChanged_Callback);
button_purge = ESPUI.addControl(ControlType::Button, "Leitung Entlüften", "Start", ControlColor::Alizarin, tab_maintenance, &buttons_Callback);
button_store = ESPUI.addControl(ControlType::Button, "Einstellungen permanent speichern", "Speichern", ControlColor::Turquoise, tab_store, &buttons_Callback);
button_reload = ESPUI.addControl(ControlType::Button, "Einstellungen neu laden", "Laden", ControlColor::Turquoise, tab_store, &buttons_Callback);
label_storeStatus = ESPUI.addControl(ControlType::Label, "Status", "", ControlColor::Turquoise, tab_store);
ESPUI.begin("Souko's ChainLube Mk1");
}
void UpdateWebUI()
{
ESPUI.print(label_tankRemain, String(LubeConfig.tankRemain_µl / 1000) + " ml" );
}

View File

@@ -0,0 +1,13 @@
#ifndef _WEBUI_H_
#define _WEBUI_H_
#include <Arduino.h>
#include <ESPUI.h>
#include "config.h"
#include "globals.h"
void initWebUI();
void UpdateWebUI();
#endif

View File

@@ -0,0 +1,11 @@
This directory is intended for PlatformIO Unit Testing and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/page/plus/unit-testing.html

View File

@@ -0,0 +1,5 @@
[wifi_cred]
admin_password = adminpass
wifi_ap_password = wifiappass
wifi_ssid = wifi-ssid
wifi_password = wifi-pass