Compare commits

...

5 Commits

Author SHA1 Message Date
e4dacce882 optimize 2022-09-16 12:25:01 +02:00
034eb4c393 added HA integration (not discovered) 2022-09-16 12:13:13 +02:00
938c6f7481 update Ibom 2022-09-16 09:48:07 +02:00
708cc2f83d change direction add commutask 2022-09-16 09:32:03 +02:00
c465a9ed93 added stl 2022-08-30 20:20:56 +02:00
33 changed files with 9993 additions and 217 deletions

1
.gitignore vendored
View File

@@ -29,3 +29,4 @@ build/
__pycache__
**/.DS_Store

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,76 @@
{
"board": {
"active_layer": 0,
"active_layer_preset": "",
"auto_track_width": true,
"hidden_nets": [],
"high_contrast_mode": 0,
"net_color_mode": 1,
"opacity": {
"pads": 1.0,
"tracks": 1.0,
"vias": 1.0,
"zones": 0.6
},
"ratsnest_display_mode": 0,
"selection_filter": {
"dimensions": true,
"footprints": true,
"graphics": true,
"keepouts": true,
"lockedItems": true,
"otherItems": true,
"pads": true,
"text": true,
"tracks": true,
"vias": true,
"zones": true
},
"visible_items": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
32,
33,
34,
35,
36
],
"visible_layers": "003ffc8_00000000",
"zone_display_mode": 0
},
"meta": {
"filename": "view_base.kicad_prl",
"version": 3
},
"project": {
"files": []
}
}

View File

@@ -0,0 +1,421 @@
{
"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.0,
"height": 1.65,
"width": 1.65
},
"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": true,
"min_clearance": 0.15
}
},
"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.09999999999999999,
"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.127,
"min_via_annular_width": 0.049999999999999996,
"min_via_diameter": 0.39999999999999997,
"use_height_for_length_calcs": true
},
"track_widths": [
0.0,
0.25,
0.4,
0.65
],
"via_dimensions": [],
"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": "view_base.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12.0,
"clearance": 0.15,
"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.15,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6.0
}
],
"meta": {
"version": 2
},
"net_colors": null
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"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": 0.0,
"text_offset_ratio": 0.08
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "",
"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": [],
"text_variables": {}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,76 @@
{
"board": {
"active_layer": 0,
"active_layer_preset": "",
"auto_track_width": true,
"hidden_nets": [],
"high_contrast_mode": 0,
"net_color_mode": 1,
"opacity": {
"pads": 1.0,
"tracks": 1.0,
"vias": 1.0,
"zones": 0.6
},
"ratsnest_display_mode": 0,
"selection_filter": {
"dimensions": true,
"footprints": true,
"graphics": true,
"keepouts": true,
"lockedItems": true,
"otherItems": true,
"pads": true,
"text": true,
"tracks": true,
"vias": true,
"zones": true
},
"visible_items": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
32,
33,
34,
35,
36
],
"visible_layers": "fffffff_ffffffff",
"zone_display_mode": 0
},
"meta": {
"filename": "view_screen.kicad_prl",
"version": 3
},
"project": {
"files": []
}
}

View File

@@ -0,0 +1,419 @@
{
"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.09999999999999999,
"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.4
],
"via_dimensions": [],
"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": "view_screen.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": "",
"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": 0.0,
"text_offset_ratio": 0.08
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "",
"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": [],
"text_variables": {}
}

View File

@@ -19,138 +19,122 @@ monitor_flags =
--eol=CRLF
--echo
--filter=esp32_exception_decoder
lib_deps =
askuric/Simple FOC @ 2.2.0
infineon/TLV493D-Magnetic-Sensor @ 1.0.3
bxparks/AceButton @ 1.9.1
build_flags =
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
lib_deps =
askuric/Simple FOC @ 2.2.0
infineon/TLV493D-Magnetic-Sensor @ 1.0.3
bxparks/AceButton @ 1.9.1
build_flags =
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
[env:view]
extends = base_config
; platform = https://github.com/platformio/platform-espressif32.git#feature/arduino-upstream
; platform_packages =
; framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32#master
board = esp32doit-devkit-v1
lib_deps =
; askuric/Simple FOC @ 2.2.1
; bxparks/AceButton @ 1.9.1
${base_config.lib_deps}
bodmer/TFT_eSPI@2.4.25
fastled/FastLED @ 3.5.0
bogde/HX711 @ 0.7.5
adafruit/Adafruit VEML7700 Library @ 1.1.1
lib_deps =
${base_config.lib_deps}
bodmer/TFT_eSPI@2.4.25
fastled/FastLED @ 3.5.0
bogde/HX711 @ 0.7.5
adafruit/Adafruit VEML7700 Library @ 1.1.1
dawidchyrzynski/home-assistant-integration@^1.3.0
build_flags =
${base_config.build_flags}
-DSK_DISPLAY=1
-DSK_LEDS=1
-DNUM_LEDS=8
-DSENSOR_MT6701=1
-DSK_STRAIN=1
-DSK_INVERT_ROTATION=1
-DSK_ALS=1
-DPIN_UH=26
-DPIN_UL=25
-DPIN_VH=27
-DPIN_VL=32
-DPIN_WH=12
-DPIN_WL=33
-DPIN_BUTTON_NEXT=-1
-DPIN_BUTTON_PREV=-1
-DPIN_SDA=15
-DPIN_SCL=8
-DPIN_MT_DATA=37
-DPIN_MT_CLOCK=13
-DPIN_MT_CSN=14
-DPIN_LED_DATA=7
-DPIN_LCD_BACKLIGHT=19
-DDESCRIPTION_FONT=Roboto_Thin_24
-DDESCRIPTION_Y_OFFSET=20
-DVALUE_OFFSET=30
-DDRAW_ARC=0
-DUSER_SETUP_LOADED=1
-DGC9A01_DRIVER=1
-DCGRAM_OFFSET=1
-DTFT_WIDTH=240
-DTFT_HEIGHT=240
-DTFT_MISO=-1
-DTFT_MOSI=5
-DTFT_SCLK=20
-DTFT_CS=21
-DTFT_DC=22
-DTFT_RST=4
-DTFT_BL=-1
-DLOAD_GLCD=1
-DLOAD_GFXFF=1
-DSPI_FREQUENCY=40000000
-DFASTLED_UNUSABLE_PIN_MASK=0x100740LL
-DSOC_GPIO_VALID_GPIO_MASK=0xFF0EFFFFFF
-DSOC_GPIO_VALID_OUTPUT_GPIO_MASK=0x30EFFFFFF
build_flags =
${base_config.build_flags}
-DSK_DISPLAY=1
-DSK_LEDS=1
-DNUM_LEDS=8
-DSENSOR_MT6701=1
-DSK_STRAIN=1
-DSK_INVERT_ROTATION=1
-DSK_ALS=1
-DPIN_UH=26
-DPIN_UL=25
-DPIN_VH=27
-DPIN_VL=32
-DPIN_WH=12
-DPIN_WL=33
-DPIN_BUTTON_NEXT=-1
-DPIN_BUTTON_PREV=-1
-DPIN_SDA=15
-DPIN_SCL=8
-DPIN_MT_DATA=37
-DPIN_MT_CLOCK=13
-DPIN_MT_CSN=14
-DPIN_LED_DATA=7
-DPIN_LCD_BACKLIGHT=19
-DDESCRIPTION_FONT=Roboto_Thin_24
-DDESCRIPTION_Y_OFFSET=20
-DVALUE_OFFSET=30
-DDRAW_ARC=0
-DUSER_SETUP_LOADED=1
-DGC9A01_DRIVER=1
-DCGRAM_OFFSET=1
-DTFT_WIDTH=240
-DTFT_HEIGHT=240
-DTFT_MISO=-1
-DTFT_MOSI=5
-DTFT_SCLK=20
-DTFT_CS=21
-DTFT_DC=22
-DTFT_RST=4
-DTFT_BL=-1
-DLOAD_GLCD=1
-DLOAD_GFXFF=1
-DSPI_FREQUENCY=40000000
; Reduce loop task stack size (only works on newer IDF Arduino core)
; -DARDUINO_LOOP_STACK_SIZE=2048
; Modify the default unusable pin mask to allow GPIO 7 (allowed to use on ESP32-PICO-V3-02)
; Unusable bits: 6, 8, 9, 10, 20
; (0ULL | _FL_BIT(6) | _FL_BIT(8) | _FL_BIT(9) | _FL_BIT(10) | _FL_BIT(20))
-DFASTLED_UNUSABLE_PIN_MASK=0x100740LL
; 0~39 except from 24, 28~31 are valid
; (0xFFFFFFFFFFULL & ~(0ULL | _FL_BIT(24) | _FL_BIT(28) | _FL_BIT(29) | _FL_BIT(30) | _FL_BIT(31)))
-DSOC_GPIO_VALID_GPIO_MASK=0xFF0EFFFFFF
; GPIO >= 34 are input only
; (SOC_GPIO_VALID_GPIO_MASK & ~(0ULL | _FL_BIT(34) | _FL_BIT(35) | _FL_BIT(36) | _FL_BIT(37) | _FL_BIT(38) | _FL_BIT(39)))
-DSOC_GPIO_VALID_OUTPUT_GPIO_MASK=0x30EFFFFFF
[env:handheld_tdisplay]
extends = base_config
board = esp32doit-devkit-v1
lib_deps =
${base_config.lib_deps}
bodmer/TFT_eSPI@2.4.25
build_flags =
${base_config.build_flags}
-DSK_DISPLAY=1
-DSK_STRAIN=0
-DSK_LEDS=0
-DPIN_UH=17
-DPIN_UL=2
-DPIN_VH=13
-DPIN_VL=32
-DPIN_WH=33
-DPIN_WL=25
-DPIN_BUTTON_NEXT=35
-DPIN_BUTTON_PREV=0
-DPIN_SDA=-1
-DPIN_SCL=-1
-DSENSOR_MT6701=1
-DPIN_MT_DATA=21
-DPIN_MT_CLOCK=22
-DPIN_MT_CSN=12
-DPIN_LCD_BACKLIGHT=4
-DDESCRIPTION_FONT=FreeSans9pt7b
-DDESCRIPTION_Y_OFFSET=80
-DVALUE_OFFSET=0
-DDRAW_ARC=1
-DUSER_SETUP_LOADED=1
-DST7789_DRIVER=1
-DCGRAM_OFFSET=1
-DTFT_WIDTH=135
-DTFT_HEIGHT=240
-DTFT_MISO=-1
-DTFT_MOSI=19
-DTFT_SCLK=18
-DTFT_CS=5
-DTFT_DC=16
-DTFT_RST=23
-DTFT_BL=-1
-DLOAD_GLCD=1
-DLOAD_GFXFF=1
-DSPI_FREQUENCY=40000000
lib_deps =
${base_config.lib_deps}
bodmer/TFT_eSPI@2.4.25
dawidchyrzynski/home-assistant-integration@^1.3.0
build_flags =
${base_config.build_flags}
-DSK_DISPLAY=1
-DSK_STRAIN=0
-DSK_LEDS=0
-DPIN_UH=17
-DPIN_UL=2
-DPIN_VH=13
-DPIN_VL=32
-DPIN_WH=33
-DPIN_WL=25
-DPIN_BUTTON_NEXT=35
-DPIN_BUTTON_PREV=0
-DPIN_SDA=-1
-DPIN_SCL=-1
-DSENSOR_MT6701=1
-DPIN_MT_DATA=21
-DPIN_MT_CLOCK=22
-DPIN_MT_CSN=12
-DPIN_LCD_BACKLIGHT=4
-DDESCRIPTION_FONT=FreeSans9pt7b
-DDESCRIPTION_Y_OFFSET=80
-DVALUE_OFFSET=0
-DDRAW_ARC=1
-DUSER_SETUP_LOADED=1
-DST7789_DRIVER=1
-DCGRAM_OFFSET=1
-DTFT_WIDTH=135
-DTFT_HEIGHT=240
-DTFT_MISO=-1
-DTFT_MOSI=19
-DTFT_SCLK=18
-DTFT_CS=5
-DTFT_DC=16
-DTFT_RST=23
-DTFT_BL=-1
-DLOAD_GLCD=1
-DLOAD_GFXFF=1
-DSPI_FREQUENCY=40000000

View File

@@ -0,0 +1,93 @@
#include "commu_task.h"
#include "semaphore_guard.h"
static byte mac[] = {0x00, 0x10, 0xFA, 0x6E, 0x38, 0x4A};
WiFiClient client;
HADevice device(mac, sizeof(mac));
HAMqtt mqtt(client, device);
HASensor angle("angle");
CommuTask::CommuTask(const uint8_t task_core) : Task{"Communication", 4048, 1, task_core} {
knob_state_queue_ = xQueueCreate(1, sizeof(KnobState));
assert(knob_state_queue_ != NULL);
mutex_ = xSemaphoreCreateMutex();
assert(mutex_ != NULL);
}
CommuTask::~CommuTask()
{
vQueueDelete(knob_state_queue_);
vSemaphoreDelete(mutex_);
}
QueueHandle_t CommuTask::getKnobStateQueue() {
return knob_state_queue_;
}
void CommuTask::setAngleValue(int32_t angle)
{
if(angle_ != angle)
{
angle_ = angle;
valuesUpdated = true;
log_d("new Angle valeu: %u", angle_);
}
//log_d("setAngleCalled = %u", angle);
}
void CommuTask::run() {
WiFi.begin("poes", "Rijnstraat214");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
KnobState state;
device.setName("SmartKnob001");
device.setSoftwareVersion("1.0.0");
angle.setUnitOfMeasurement("°");
angle.setDeviceClass("None");
angle.setName("SmartKnob Angle");
mqtt.begin(BROKER_ADDR, BROKER_USERNAME, BROKER_PASSWORD);
uint32_t lastSensorUpdate = millis();
angle.setValue(angle_);
if(mqtt.isConnected())
{
printf("mqtt connected");
}
else{
printf("mqtt NOT connected");
}
while(1)
{
if (xQueueReceive(knob_state_queue_, &state, portMAX_DELAY) == pdFALSE) {
continue;
}
setAngleValue(state.current_position);
if(millis() - lastSensorUpdate > 1000 && valuesUpdated)
{
angle.setValue(angle_);
log_d("new angle=%u", angle_);
lastSensorUpdate = millis();
valuesUpdated = false;
}
mqtt.loop();
delay(10);
}
}

44
firmware/src/commu_task.h Normal file
View File

@@ -0,0 +1,44 @@
#pragma once
#include <Arduino.h>
#include <WiFi.h>
#include <Client.h>
#include <ArduinoHA.h>
#include "knob_data.h"
#include "task.h"
#define BROKER_ADDR IPAddress(192,168,4,58)
#define BROKER_USERNAME "mqtt_broker_user" // replace with your credentials
#define BROKER_PASSWORD "mqtt2022"
//HA vars
class CommuTask : public Task<CommuTask> {
friend class Task<CommuTask>; // Allow base Task to invoke protected run()
public:
CommuTask(const uint8_t task_core);
~CommuTask();
void setAngleValue(int32_t angle);
QueueHandle_t getKnobStateQueue();
protected:
void run();
private:
int32_t angle_ =0;
SemaphoreHandle_t mutex_;
bool valuesUpdated = false;
QueueHandle_t knob_state_queue_;
};

View File

@@ -6,7 +6,7 @@
static const uint8_t LEDC_CHANNEL_LCD_BACKLIGHT = 0;
DisplayTask::DisplayTask(const uint8_t task_core) : Task{"Display", 4048, 1, task_core} {
DisplayTask::DisplayTask(const uint8_t task_core) : Task{"Display", 2048, 1, task_core} {
knob_state_queue_ = xQueueCreate(1, sizeof(KnobState));
assert(knob_state_queue_ != NULL);
@@ -19,66 +19,11 @@ DisplayTask::~DisplayTask() {
vSemaphoreDelete(mutex_);
}
static void HSV_to_RGB(float h, float s, float v, uint8_t *r, uint8_t *g, uint8_t *b)
{
int i;
float f,p,q,t;
h = fmax(0.0, fmin(360.0, h));
s = fmax(0.0, fmin(100.0, s));
v = fmax(0.0, fmin(100.0, v));
s /= 100;
v /= 100;
if(s == 0) {
// Achromatic (grey)
*r = *g = *b = round(v*255);
return;
}
h /= 60; // sector 0 to 5
i = floor(h);
f = h - i; // factorial part of h
p = v * (1 - s);
q = v * (1 - s * f);
t = v * (1 - s * (1 - f));
switch(i) {
case 0:
*r = round(255*v);
*g = round(255*t);
*b = round(255*p);
break;
case 1:
*r = round(255*q);
*g = round(255*v);
*b = round(255*p);
break;
case 2:
*r = round(255*p);
*g = round(255*v);
*b = round(255*t);
break;
case 3:
*r = round(255*p);
*g = round(255*q);
*b = round(255*v);
break;
case 4:
*r = round(255*t);
*g = round(255*p);
*b = round(255*v);
break;
default: // case 5:
*r = round(255*v);
*g = round(255*p);
*b = round(255*q);
}
}
void DisplayTask::run() {
tft_.begin();
tft_.invertDisplay(1);
spr_.setColorDepth(8);
tft_.setRotation(0);
tft_.fillScreen(TFT_DARKGREEN);
@@ -86,7 +31,7 @@ void DisplayTask::run() {
ledcAttachPin(PIN_LCD_BACKLIGHT, LEDC_CHANNEL_LCD_BACKLIGHT);
ledcWrite(LEDC_CHANNEL_LCD_BACKLIGHT, UINT16_MAX);
spr_.setColorDepth(16);
//spr_.setColorDepth(16);
if (spr_.createSprite(TFT_WIDTH, TFT_HEIGHT) == nullptr) {
Serial.println("ERROR: sprite allocation failed!");
@@ -103,10 +48,10 @@ void DisplayTask::run() {
const uint16_t FILL_COLOR = spr_.color565(90, 18, 151);
const uint16_t DOT_COLOR = spr_.color565(80, 100, 200);
int32_t pointer_center_x = TFT_WIDTH / 2;
int32_t pointer_center_y = TFT_HEIGHT / 2;
int32_t pointer_length_short = 10;
int32_t pointer_length_long = TFT_WIDTH / 2 - 5;
// int32_t pointer_center_x = TFT_WIDTH / 2;
// int32_t pointer_center_y = TFT_HEIGHT / 2;
// int32_t pointer_length_short = 10;
// int32_t pointer_length_long = TFT_WIDTH / 2 - 5;
spr_.setTextDatum(CC_DATUM);
spr_.setTextColor(TFT_WHITE);
@@ -165,6 +110,7 @@ void DisplayTask::run() {
float raw_angle = left_bound - state.current_position * state.config.position_width_radians;
float adjusted_angle = raw_angle - adjusted_sub_position;
if (state.config.num_positions > 0 && ((state.current_position == 0 && state.sub_position_unit < 0) || (state.current_position == state.config.num_positions - 1 && state.sub_position_unit > 0))) {
spr_.fillCircle(TFT_WIDTH/2 + (RADIUS - 10) * cosf(raw_angle), TFT_HEIGHT/2 - (RADIUS - 10) * sinf(raw_angle), 5, DOT_COLOR);
@@ -189,6 +135,7 @@ void DisplayTask::run() {
SemaphoreGuard lock(mutex_);
ledcWrite(LEDC_CHANNEL_LCD_BACKLIGHT, brightness_);
}
delay(2);
}
}

View File

@@ -35,6 +35,8 @@ class DisplayTask : public Task<DisplayTask> {
SemaphoreHandle_t mutex_;
uint16_t brightness_;
uint32_t last_printupdate = 0;
};
#else

View File

@@ -123,7 +123,11 @@ static KnobConfig configs[] = {
},
};
InterfaceTask::InterfaceTask(const uint8_t task_core, MotorTask& motor_task, DisplayTask* display_task) : Task("Interface", 4048, 1, task_core), motor_task_(motor_task), display_task_(display_task) {
InterfaceTask::InterfaceTask(const uint8_t task_core, MotorTask& motor_task, DisplayTask* display_task, CommuTask& commu_task) :
Task("Interface", 4048, 1, task_core),
motor_task_(motor_task),
display_task_(display_task),
commu_task_(commu_task){
#if SK_DISPLAY
assert(display_task != nullptr);
#endif
@@ -195,11 +199,13 @@ void InterfaceTask::run() {
float lux = veml.readLux();
lux_avg = lux * LUX_ALPHA + lux_avg * (1 - LUX_ALPHA);
static uint32_t last_als;
if (millis() - last_als > 1000) {
if (millis() - last_als >5000) {
Serial.print("millilux: "); Serial.println(lux*1000);
last_als = millis();
}
#endif
#if SK_STRAIN
// TODO: calibrate and track (long term moving average) zero point (lower); allow calibration of set point offset
@@ -220,7 +226,7 @@ void InterfaceTask::run() {
press_value_unit = 1. * (value - lower) / (upper - lower);
static bool pressed;
if (!pressed && press_value_unit > 0.75) {
if (!pressed && press_value_unit > 0.3) {
motor_task_.playHaptic(true);
pressed = true;
changeConfig(true);
@@ -234,14 +240,14 @@ void InterfaceTask::run() {
#if SK_LEDS
for (uint8_t i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB::Red;
leds[i] = CRGB::White;
}
FastLED.show();
#endif
}
#endif
uint16_t brightness = UINT16_MAX;
// TODO: brightness scale factor should be configurable (depends on reflectivity of surface)
#if SK_ALS
brightness = (uint16_t)CLAMP(lux_avg * 13000, (float)1280, (float)UINT16_MAX);

View File

@@ -5,13 +5,16 @@
#include "display_task.h"
#include "motor_task.h"
#include "commu_task.h"
#include "task.h"
#define ALSCHECKINTERVAL 4000
class InterfaceTask : public Task<InterfaceTask>, public ace_button::IEventHandler {
friend class Task<InterfaceTask>; // Allow base Task to invoke protected run()
public:
InterfaceTask(const uint8_t task_core, MotorTask& motor_task, DisplayTask* display_task);
InterfaceTask(const uint8_t task_core, MotorTask& motor_task, DisplayTask* display_task, CommuTask& commu_task);
~InterfaceTask();
void handleEvent(ace_button::AceButton* button, uint8_t event_type, uint8_t button_state) override;
@@ -22,8 +25,11 @@ class InterfaceTask : public Task<InterfaceTask>, public ace_button::IEventHandl
private:
MotorTask& motor_task_;
DisplayTask* display_task_;
CommuTask& commu_task_;
int current_config_ = 0;
uint16_t brightness = UINT16_MAX;
void changeConfig(bool next);
};

View File

@@ -4,17 +4,19 @@
#include "display_task.h"
#include "interface_task.h"
#include "motor_task.h"
#include "commu_task.h"
#if SK_DISPLAY
static DisplayTask display_task = DisplayTask(0);
static DisplayTask display_task = DisplayTask(1);
static DisplayTask* display_task_p = &display_task;
#else
static DisplayTask* display_task_p = nullptr;
#endif
static MotorTask motor_task = MotorTask(1);
static MotorTask motor_task = MotorTask(0);
static CommuTask commu_Task = CommuTask(0);
InterfaceTask interface_task = InterfaceTask(0, motor_task, display_task_p);
InterfaceTask interface_task = InterfaceTask(0, motor_task, display_task_p, commu_Task);
static QueueHandle_t knob_state_debug_queue;
@@ -23,6 +25,7 @@ void setup() {
motor_task.begin();
interface_task.begin();
commu_Task.begin();
#if SK_DISPLAY
display_task.begin();
@@ -31,6 +34,8 @@ void setup() {
motor_task.addListener(display_task.getKnobStateQueue());
#endif
motor_task.addListener(commu_Task.getKnobStateQueue());
// Create a queue and register it with motor_task to print knob state to serial (see loop() below)
knob_state_debug_queue = xQueueCreate(1, sizeof(KnobState));
assert(knob_state_debug_queue != NULL);
@@ -61,6 +66,8 @@ void loop() {
#endif
Serial.printf("motor: %d\n", uxTaskGetStackHighWaterMark(motor_task.getHandle()));
Serial.printf("interface: %d\n", uxTaskGetStackHighWaterMark(interface_task.getHandle()));
Serial.printf("communication: %d\n", uxTaskGetStackHighWaterMark(commu_Task.getHandle()));
last_stack_debug = millis();
}
}

View File

@@ -53,7 +53,7 @@ void MotorTask::run() {
// float zero_electric_offset = -0.8; // handheld 2
// float zero_electric_offset = 2.93; //0.15; // 17mm test
// float zero_electric_offset = 0.66; // 15mm handheld
float zero_electric_offset = 7.34;
float zero_electric_offset = 5.44;
Direction foc_direction = Direction::CW;
motor.pole_pairs = 7;

View File

@@ -6,44 +6,48 @@
#include "knob_data.h"
#include "task.h"
enum class CommandType {
enum class CommandType
{
CONFIG,
HAPTIC,
};
struct HapticData {
struct HapticData
{
bool press;
};
struct Command {
struct Command
{
CommandType command_type;
union CommandData {
union CommandData
{
KnobConfig config;
HapticData haptic;
};
CommandData data;
};
class MotorTask : public Task<MotorTask> {
class MotorTask : public Task<MotorTask>
{
friend class Task<MotorTask>; // Allow base Task to invoke protected run()
public:
MotorTask(const uint8_t task_core);
~MotorTask();
public:
MotorTask(const uint8_t task_core);
~MotorTask();
void setConfig(const KnobConfig& config);
void playHaptic(bool press);
void setConfig(const KnobConfig &config);
void playHaptic(bool press);
void addListener(QueueHandle_t queue);
void addListener(QueueHandle_t queue);
protected:
void run();
protected:
void run();
private:
QueueHandle_t queue_;
private:
QueueHandle_t queue_;
std::vector<QueueHandle_t> listeners_;
std::vector<QueueHandle_t> listeners_;
void publish(const KnobState& state);
void publish(const KnobState &state);
};