Compare commits
9 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
7dc82932be | |
|
|
201c3cafc7 | |
|
|
a4e042dd2d | |
|
|
0a2a92b356 | |
|
|
9ff4e22796 | |
|
|
04bbd2c141 | |
|
|
44df6d4bbe | |
|
|
3a85ce8538 | |
|
|
4a092f2ba3 |
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,2 @@
|
||||||
|
(kicad_pcb (version 20240108) (generator "pcbnew") (generator_version "8.0")
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
{
|
||||||
|
"board": {
|
||||||
|
"active_layer": 0,
|
||||||
|
"active_layer_preset": "",
|
||||||
|
"auto_track_width": true,
|
||||||
|
"hidden_netclasses": [],
|
||||||
|
"hidden_nets": [],
|
||||||
|
"high_contrast_mode": 0,
|
||||||
|
"net_color_mode": 1,
|
||||||
|
"opacity": {
|
||||||
|
"images": 0.6,
|
||||||
|
"pads": 1.0,
|
||||||
|
"tracks": 1.0,
|
||||||
|
"vias": 1.0,
|
||||||
|
"zones": 0.6
|
||||||
|
},
|
||||||
|
"selection_filter": {
|
||||||
|
"dimensions": true,
|
||||||
|
"footprints": true,
|
||||||
|
"graphics": true,
|
||||||
|
"keepouts": true,
|
||||||
|
"lockedItems": false,
|
||||||
|
"otherItems": true,
|
||||||
|
"pads": true,
|
||||||
|
"text": true,
|
||||||
|
"tracks": true,
|
||||||
|
"vias": true,
|
||||||
|
"zones": true
|
||||||
|
},
|
||||||
|
"visible_items": [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
8,
|
||||||
|
9,
|
||||||
|
10,
|
||||||
|
11,
|
||||||
|
12,
|
||||||
|
13,
|
||||||
|
15,
|
||||||
|
16,
|
||||||
|
17,
|
||||||
|
18,
|
||||||
|
19,
|
||||||
|
20,
|
||||||
|
21,
|
||||||
|
22,
|
||||||
|
23,
|
||||||
|
24,
|
||||||
|
25,
|
||||||
|
26,
|
||||||
|
27,
|
||||||
|
28,
|
||||||
|
29,
|
||||||
|
30,
|
||||||
|
32,
|
||||||
|
33,
|
||||||
|
34,
|
||||||
|
35,
|
||||||
|
36,
|
||||||
|
39,
|
||||||
|
40
|
||||||
|
],
|
||||||
|
"visible_layers": "fffffff_ffffffff",
|
||||||
|
"zone_display_mode": 0
|
||||||
|
},
|
||||||
|
"git": {
|
||||||
|
"repo_password": "",
|
||||||
|
"repo_type": "",
|
||||||
|
"repo_username": "",
|
||||||
|
"ssh_key": ""
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"filename": "pianist_robot.kicad_prl",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"project": {
|
||||||
|
"files": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,392 @@
|
||||||
|
{
|
||||||
|
"board": {
|
||||||
|
"3dviewports": [],
|
||||||
|
"design_settings": {
|
||||||
|
"defaults": {},
|
||||||
|
"diff_pair_dimensions": [],
|
||||||
|
"drc_exclusions": [],
|
||||||
|
"rules": {},
|
||||||
|
"track_widths": [],
|
||||||
|
"via_dimensions": []
|
||||||
|
},
|
||||||
|
"ipc2581": {
|
||||||
|
"dist": "",
|
||||||
|
"distpn": "",
|
||||||
|
"internal_id": "",
|
||||||
|
"mfg": "",
|
||||||
|
"mpn": ""
|
||||||
|
},
|
||||||
|
"layer_presets": [],
|
||||||
|
"viewports": []
|
||||||
|
},
|
||||||
|
"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_to_bus_conflict": "error",
|
||||||
|
"bus_to_net_conflict": "error",
|
||||||
|
"conflicting_netclasses": "error",
|
||||||
|
"different_unit_footprint": "error",
|
||||||
|
"different_unit_net": "error",
|
||||||
|
"duplicate_reference": "error",
|
||||||
|
"duplicate_sheet_names": "error",
|
||||||
|
"endpoint_off_grid": "warning",
|
||||||
|
"extra_units": "error",
|
||||||
|
"global_label_dangling": "warning",
|
||||||
|
"hier_label_mismatch": "error",
|
||||||
|
"label_dangling": "error",
|
||||||
|
"lib_symbol_issues": "warning",
|
||||||
|
"missing_bidi_pin": "warning",
|
||||||
|
"missing_input_pin": "warning",
|
||||||
|
"missing_power_pin": "error",
|
||||||
|
"missing_unit": "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",
|
||||||
|
"simulation_model_issue": "ignore",
|
||||||
|
"unannotated": "error",
|
||||||
|
"unit_value_mismatch": "error",
|
||||||
|
"unresolved_variable": "error",
|
||||||
|
"wire_dangling": "error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libraries": {
|
||||||
|
"pinned_footprint_libs": [],
|
||||||
|
"pinned_symbol_libs": []
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"filename": "pianist_robot.kicad_pro",
|
||||||
|
"version": 1
|
||||||
|
},
|
||||||
|
"net_settings": {
|
||||||
|
"classes": [
|
||||||
|
{
|
||||||
|
"bus_width": 12,
|
||||||
|
"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.2,
|
||||||
|
"via_diameter": 0.6,
|
||||||
|
"via_drill": 0.3,
|
||||||
|
"wire_width": 6
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meta": {
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"net_colors": null,
|
||||||
|
"netclass_assignments": null,
|
||||||
|
"netclass_patterns": []
|
||||||
|
},
|
||||||
|
"pcbnew": {
|
||||||
|
"last_paths": {
|
||||||
|
"gencad": "",
|
||||||
|
"idf": "",
|
||||||
|
"netlist": "",
|
||||||
|
"plot": "",
|
||||||
|
"pos_files": "",
|
||||||
|
"specctra_dsn": "",
|
||||||
|
"step": "",
|
||||||
|
"svg": "",
|
||||||
|
"vrml": ""
|
||||||
|
},
|
||||||
|
"page_layout_descr_file": ""
|
||||||
|
},
|
||||||
|
"schematic": {
|
||||||
|
"annotate_start_num": 0,
|
||||||
|
"bom_export_filename": "",
|
||||||
|
"bom_fmt_presets": [],
|
||||||
|
"bom_fmt_settings": {
|
||||||
|
"field_delimiter": ",",
|
||||||
|
"keep_line_breaks": false,
|
||||||
|
"keep_tabs": false,
|
||||||
|
"name": "CSV",
|
||||||
|
"ref_delimiter": ",",
|
||||||
|
"ref_range_delimiter": "",
|
||||||
|
"string_delimiter": "\""
|
||||||
|
},
|
||||||
|
"bom_presets": [],
|
||||||
|
"bom_settings": {
|
||||||
|
"exclude_dnp": false,
|
||||||
|
"fields_ordered": [
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Reference",
|
||||||
|
"name": "Reference",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "Value",
|
||||||
|
"name": "Value",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Datasheet",
|
||||||
|
"name": "Datasheet",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Footprint",
|
||||||
|
"name": "Footprint",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": false,
|
||||||
|
"label": "Qty",
|
||||||
|
"name": "${QUANTITY}",
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group_by": true,
|
||||||
|
"label": "DNP",
|
||||||
|
"name": "${DNP}",
|
||||||
|
"show": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"filter_string": "",
|
||||||
|
"group_symbols": true,
|
||||||
|
"name": "Grouped By Value",
|
||||||
|
"sort_asc": true,
|
||||||
|
"sort_field": "Reference"
|
||||||
|
},
|
||||||
|
"connection_grid_size": 50.0,
|
||||||
|
"drawing": {
|
||||||
|
"dashed_lines_dash_length_ratio": 12.0,
|
||||||
|
"dashed_lines_gap_length_ratio": 3.0,
|
||||||
|
"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.375,
|
||||||
|
"operating_point_overlay_i_precision": 3,
|
||||||
|
"operating_point_overlay_i_range": "~A",
|
||||||
|
"operating_point_overlay_v_precision": 3,
|
||||||
|
"operating_point_overlay_v_range": "~V",
|
||||||
|
"overbar_offset_ratio": 1.23,
|
||||||
|
"pin_symbol_size": 25.0,
|
||||||
|
"text_offset_ratio": 0.15
|
||||||
|
},
|
||||||
|
"legacy_lib_dir": "",
|
||||||
|
"legacy_lib_list": [],
|
||||||
|
"meta": {
|
||||||
|
"version": 1
|
||||||
|
},
|
||||||
|
"net_format_name": "",
|
||||||
|
"page_layout_descr_file": "",
|
||||||
|
"plot_directory": "",
|
||||||
|
"spice_current_sheet_as_root": false,
|
||||||
|
"spice_external_command": "spice \"%I\"",
|
||||||
|
"spice_model_current_sheet_as_root": true,
|
||||||
|
"spice_save_all_currents": false,
|
||||||
|
"spice_save_all_dissipations": false,
|
||||||
|
"spice_save_all_voltages": false,
|
||||||
|
"subpart_first_id": 65,
|
||||||
|
"subpart_id_separator": 0
|
||||||
|
},
|
||||||
|
"sheets": [
|
||||||
|
[
|
||||||
|
"80af7aa2-e50e-4aba-a849-d06f270efa9f",
|
||||||
|
"Root"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"text_variables": {}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
|
|
@ -1,37 +0,0 @@
|
||||||
|
|
||||||
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 convention is to give header files names that end with `.h'.
|
|
||||||
|
|
||||||
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
|
|
||||||
46
lib/README
46
lib/README
|
|
@ -1,46 +0,0 @@
|
||||||
|
|
||||||
This directory is intended for project specific (private) libraries.
|
|
||||||
PlatformIO will compile them to static libraries and link into the executable file.
|
|
||||||
|
|
||||||
The source code of each library should be placed in a separate directory
|
|
||||||
("lib/your_library_name/[Code]").
|
|
||||||
|
|
||||||
For example, see the structure of the following example libraries `Foo` and `Bar`:
|
|
||||||
|
|
||||||
|--lib
|
|
||||||
| |
|
|
||||||
| |--Bar
|
|
||||||
| | |--docs
|
|
||||||
| | |--examples
|
|
||||||
| | |--src
|
|
||||||
| | |- Bar.c
|
|
||||||
| | |- Bar.h
|
|
||||||
| | |- library.json (optional. for 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
|
|
||||||
|
|
||||||
Example contents of `src/main.c` using Foo and Bar:
|
|
||||||
```
|
|
||||||
#include <Foo.h>
|
|
||||||
#include <Bar.h>
|
|
||||||
|
|
||||||
int main (void)
|
|
||||||
{
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
The PlatformIO Library Dependency Finder will find automatically dependent
|
|
||||||
libraries by scanning project source files.
|
|
||||||
|
|
||||||
More information about PlatformIO Library Dependency Finder
|
|
||||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
|
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
|
@ -0,0 +1 @@
|
||||||
|
OK
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
model_checkpoint_path: "model"
|
||||||
|
all_model_checkpoint_paths: "model"
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1 @@
|
||||||
|
OK
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
model_checkpoint_path: "model"
|
||||||
|
all_model_checkpoint_paths: "model"
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1 @@
|
||||||
|
OK
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
model_checkpoint_path: "model"
|
||||||
|
all_model_checkpoint_paths: "model"
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -6,7 +6,7 @@ import serial.tools.list_ports
|
||||||
|
|
||||||
# Define the paths
|
# Define the paths
|
||||||
#Short notes
|
#Short notes
|
||||||
NOTES_PATH = "Player\\notes\\mp3-master\\"
|
NOTES_PATH = "pysrc\\notes\\mp3-master\\"
|
||||||
#Long notes
|
#Long notes
|
||||||
#NOTES_PATH = r"C:\Users\Balthazar\Shared\ECAM\Advance Robotique\Project\Player\notes\high-quality-master\renamed\\"
|
#NOTES_PATH = r"C:\Users\Balthazar\Shared\ECAM\Advance Robotique\Project\Player\notes\high-quality-master\renamed\\"
|
||||||
SERIAL_PORT = "COM5"
|
SERIAL_PORT = "COM5"
|
||||||
|
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
import serial
|
|
||||||
import time
|
|
||||||
import pygame
|
|
||||||
from pydub import AudioSegment
|
|
||||||
import serial.tools.list_ports
|
|
||||||
|
|
||||||
# Define the paths
|
|
||||||
#Short notes
|
|
||||||
NOTES_PATH = "Player\\notes\\mp3-master\\"
|
|
||||||
#Long notes
|
|
||||||
#NOTES_PATH = r"C:\Users\Balthazar\Shared\ECAM\Advance Robotique\Project\Player\notes\high-quality-master\renamed\\"
|
|
||||||
SERIAL_PORT = "COM5" #"COM3"
|
|
||||||
BAUD_RATE = 115200
|
|
||||||
|
|
||||||
# New Features
|
|
||||||
wait_note_finish = False # Set to False to play without waiting for the note to finish
|
|
||||||
keyboard_input = False # Set to False to disable keyboard note input
|
|
||||||
check_com3 = True # Set to False to skip COM3 check
|
|
||||||
|
|
||||||
pygame.mixer.init()
|
|
||||||
|
|
||||||
octave = 4
|
|
||||||
|
|
||||||
notes = ["C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B"]
|
|
||||||
|
|
||||||
|
|
||||||
def play_note_with_pygame(note):
|
|
||||||
try:
|
|
||||||
pygame_sound = pygame.mixer.Sound(f"{NOTES_PATH}{note}.mp3")
|
|
||||||
pygame_sound.play()
|
|
||||||
if wait_note_finish:
|
|
||||||
while pygame.mixer.get_busy(): # Wait until sound is finished
|
|
||||||
pygame.time.Clock().tick(10)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error playing {note}: {e}")
|
|
||||||
|
|
||||||
|
|
||||||
# Check if COM3 is connected
|
|
||||||
if check_com3:
|
|
||||||
ports = list(serial.tools.list_ports.comports())
|
|
||||||
com3_found = any(port.device == SERIAL_PORT for port in ports)
|
|
||||||
if not com3_found:
|
|
||||||
print(f"{SERIAL_PORT} not found. Switching to keyboard input mode.")
|
|
||||||
keyboard_input = True
|
|
||||||
|
|
||||||
try:
|
|
||||||
ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=1)
|
|
||||||
time.sleep(2)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error opening {SERIAL_PORT}: {e}")
|
|
||||||
keyboard_input = True
|
|
||||||
|
|
||||||
print("Listening for Arduino input...")
|
|
||||||
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
# Keyboard input for playing notes
|
|
||||||
if keyboard_input:
|
|
||||||
user_input = input("Enter note (C, Db, D, ... B) or 'q' to quit: ")
|
|
||||||
if user_input == 'q':
|
|
||||||
break
|
|
||||||
if user_input in notes:
|
|
||||||
play_note_with_pygame(f"{user_input}{octave}")
|
|
||||||
|
|
||||||
# Arduino input for playing notes
|
|
||||||
data = ser.readline().decode('utf-8', errors='ignore').strip()
|
|
||||||
if data:
|
|
||||||
print("data : " + data)
|
|
||||||
note = data
|
|
||||||
if note in notes:
|
|
||||||
play_note_with_pygame(f"{note}{octave}")
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Exiting...")
|
|
||||||
break
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error: {e}")
|
|
||||||
|
|
||||||
ser.close()
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
import subprocess
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def separate_audio(input_file,stems,output_folder="output"):
|
||||||
|
try:
|
||||||
|
# Create output directory if it doesn't exist
|
||||||
|
os.makedirs(output_folder, exist_ok=True)
|
||||||
|
|
||||||
|
input_file_name=input_file
|
||||||
|
input_file_name= input_file_name.replace(".mp3","")
|
||||||
|
# Use python -m to ensure the correct module is called
|
||||||
|
command = [
|
||||||
|
sys.executable, "-m", "spleeter", "separate",
|
||||||
|
"-o", output_folder+"\\"+input_file_name+stems,
|
||||||
|
"-p", "spleeter:"+stems,
|
||||||
|
"C:\\Users\\louis\\Desktop\\VScode\\Python\\Songs\\"+input_file,
|
||||||
|
]
|
||||||
|
|
||||||
|
print(f"Running command: {' '.join(command)}")
|
||||||
|
subprocess.run(command, check=True)
|
||||||
|
print(f"Separation complete! Files saved in {output_folder}/")
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"Error running Spleeter: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Unexpected error: {e}")
|
||||||
|
|
||||||
|
# Example usage
|
||||||
|
separate_audio("TheSylversRememberTheRain.mp3" , "4stems")
|
||||||
|
|
@ -0,0 +1,211 @@
|
||||||
|
import crepe
|
||||||
|
from scipy.io import wavfile
|
||||||
|
import json
|
||||||
|
import csv
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
# Define file paths
|
||||||
|
fileName = "NujabesFeather4stems/other.wav"
|
||||||
|
audio_file = "output/"+fileName
|
||||||
|
# Replace the slash with nothing to flatten the path
|
||||||
|
flat_name = fileName.replace("/", "")
|
||||||
|
# Remove the .wav extension
|
||||||
|
without_extension = flat_name[:-4] # removes last 4 characters (.wav)
|
||||||
|
# Create the output filename
|
||||||
|
output_csv = "crepe_output" + without_extension + ".csv"
|
||||||
|
|
||||||
|
def getNotesFromFreq(freqNotesArray, freqNotesConfidence):
|
||||||
|
notes_json='''{
|
||||||
|
"notes": [
|
||||||
|
{"note": "A", "octave": 0, "frequency": 27.5},
|
||||||
|
{"note": "Bb", "octave": 0, "frequency": 29.135},
|
||||||
|
{"note": "B", "octave": 0, "frequency": 30.868},
|
||||||
|
|
||||||
|
{"note": "C", "octave": 1, "frequency": 32.703},
|
||||||
|
{"note": "Db", "octave": 1, "frequency": 34.648},
|
||||||
|
{"note": "D", "octave": 1, "frequency": 36.708},
|
||||||
|
{"note": "Eb", "octave": 1, "frequency": 38.891},
|
||||||
|
{"note": "E", "octave": 1, "frequency": 41.203},
|
||||||
|
{"note": "F", "octave": 1, "frequency": 43.654},
|
||||||
|
{"note": "Gb", "octave": 1, "frequency": 46.249},
|
||||||
|
{"note": "G", "octave": 1, "frequency": 48.999},
|
||||||
|
{"note": "Ab", "octave": 1, "frequency": 51.913},
|
||||||
|
{"note": "A", "octave": 1, "frequency": 55.0},
|
||||||
|
{"note": "Bb", "octave": 1, "frequency": 58.27},
|
||||||
|
{"note": "B", "octave": 1, "frequency": 61.735},
|
||||||
|
|
||||||
|
{"note": "C", "octave": 2, "frequency": 65.406},
|
||||||
|
{"note": "Db", "octave": 2, "frequency": 69.296},
|
||||||
|
{"note": "D", "octave": 2, "frequency": 73.416},
|
||||||
|
{"note": "Eb", "octave": 2, "frequency": 77.782},
|
||||||
|
{"note": "E", "octave": 2, "frequency": 82.407},
|
||||||
|
{"note": "F", "octave": 2, "frequency": 87.307},
|
||||||
|
{"note": "Gb", "octave": 2, "frequency": 92.499},
|
||||||
|
{"note": "G", "octave": 2, "frequency": 97.999},
|
||||||
|
{"note": "Ab", "octave": 2, "frequency": 103.826},
|
||||||
|
{"note": "A", "octave": 2, "frequency": 110.0},
|
||||||
|
{"note": "Bb", "octave": 2, "frequency": 116.541},
|
||||||
|
{"note": "B", "octave": 2, "frequency": 123.471},
|
||||||
|
|
||||||
|
{"note": "C", "octave": 3, "frequency": 130.813},
|
||||||
|
{"note": "Db", "octave": 3, "frequency": 138.591},
|
||||||
|
{"note": "D", "octave": 3, "frequency": 146.832},
|
||||||
|
{"note": "Eb", "octave": 3, "frequency": 155.563},
|
||||||
|
{"note": "E", "octave": 3, "frequency": 164.814},
|
||||||
|
{"note": "F", "octave": 3, "frequency": 174.614},
|
||||||
|
{"note": "Gb", "octave": 3, "frequency": 184.997},
|
||||||
|
{"note": "G", "octave": 3, "frequency": 195.998},
|
||||||
|
{"note": "Ab", "octave": 3, "frequency": 207.652},
|
||||||
|
{"note": "A", "octave": 3, "frequency": 220.0},
|
||||||
|
{"note": "Bb", "octave": 3, "frequency": 233.082},
|
||||||
|
{"note": "B", "octave": 3, "frequency": 246.942},
|
||||||
|
|
||||||
|
{"note": "C", "octave": 4, "frequency": 261.626},
|
||||||
|
{"note": "Db", "octave": 4, "frequency": 277.183},
|
||||||
|
{"note": "D", "octave": 4, "frequency": 293.665},
|
||||||
|
{"note": "Eb", "octave": 4, "frequency": 311.127},
|
||||||
|
{"note": "E", "octave": 4, "frequency": 329.628},
|
||||||
|
{"note": "F", "octave": 4, "frequency": 349.228},
|
||||||
|
{"note": "Gb", "octave": 4, "frequency": 369.994},
|
||||||
|
{"note": "G", "octave": 4, "frequency": 391.995},
|
||||||
|
{"note": "Ab", "octave": 4, "frequency": 415.305},
|
||||||
|
{"note": "A", "octave": 4, "frequency": 440.0},
|
||||||
|
{"note": "Bb", "octave": 4, "frequency": 466.164},
|
||||||
|
{"note": "B", "octave": 4, "frequency": 493.883},
|
||||||
|
|
||||||
|
{"note": "C", "octave": 5, "frequency": 523.251},
|
||||||
|
{"note": "Db", "octave": 5, "frequency": 554.365},
|
||||||
|
{"note": "D", "octave": 5, "frequency": 587.33},
|
||||||
|
{"note": "Eb", "octave": 5, "frequency": 622.254},
|
||||||
|
{"note": "E", "octave": 5, "frequency": 659.255},
|
||||||
|
{"note": "F", "octave": 5, "frequency": 698.456},
|
||||||
|
{"note": "Gb", "octave": 5, "frequency": 739.989},
|
||||||
|
{"note": "G", "octave": 5, "frequency": 783.991},
|
||||||
|
{"note": "Ab", "octave": 5, "frequency": 830.609},
|
||||||
|
{"note": "A", "octave": 5, "frequency": 880.0},
|
||||||
|
{"note": "Bb", "octave": 5, "frequency": 932.328},
|
||||||
|
{"note": "B", "octave": 5, "frequency": 987.767},
|
||||||
|
|
||||||
|
{"note": "C", "octave": 6, "frequency": 1046.502},
|
||||||
|
{"note": "Db", "octave": 6, "frequency": 1108.731},
|
||||||
|
{"note": "D", "octave": 6, "frequency": 1174.659},
|
||||||
|
{"note": "Eb", "octave": 6, "frequency": 1244.508},
|
||||||
|
{"note": "E", "octave": 6, "frequency": 1318.51},
|
||||||
|
{"note": "F", "octave": 6, "frequency": 1396.913},
|
||||||
|
{"note": "Gb", "octave": 6, "frequency": 1479.978},
|
||||||
|
{"note": "G", "octave": 6, "frequency": 1567.982},
|
||||||
|
{"note": "Ab", "octave": 6, "frequency": 1661.219},
|
||||||
|
{"note": "A", "octave": 6, "frequency": 1760.0},
|
||||||
|
{"note": "Bb", "octave": 6, "frequency": 1864.655},
|
||||||
|
{"note": "B", "octave": 6, "frequency": 1975.533},
|
||||||
|
|
||||||
|
{"note": "C", "octave": 7, "frequency": 2093.005},
|
||||||
|
{"note": "Db", "octave": 7, "frequency": 2217.461},
|
||||||
|
{"note": "D", "octave": 7, "frequency": 2349.318},
|
||||||
|
{"note": "Eb", "octave": 7, "frequency": 2489.016},
|
||||||
|
{"note": "E", "octave": 7, "frequency": 2637.021},
|
||||||
|
{"note": "F", "octave": 7, "frequency": 2793.826},
|
||||||
|
{"note": "Gb", "octave": 7, "frequency": 2959.955},
|
||||||
|
{"note": "G", "octave": 7, "frequency": 3135.964},
|
||||||
|
{"note": "Ab", "octave": 7, "frequency": 3322.438},
|
||||||
|
{"note": "A", "octave": 7, "frequency": 3520.0},
|
||||||
|
{"note": "Bb", "octave": 7, "frequency": 3729.31},
|
||||||
|
{"note": "B", "octave": 7, "frequency": 3951.066},
|
||||||
|
|
||||||
|
{"note": "C", "octave": 8, "frequency": 4186.009}
|
||||||
|
]
|
||||||
|
}'''
|
||||||
|
notes_data = json.loads(notes_json)
|
||||||
|
finalNoteArray = []
|
||||||
|
|
||||||
|
for i, freq in enumerate(freqNotesArray):
|
||||||
|
bestFreqDif = float('inf')
|
||||||
|
if freqNotesConfidence[i] < 0.5:
|
||||||
|
finalNote = "NoNoteFound"
|
||||||
|
else :
|
||||||
|
for note_data in notes_data['notes']:
|
||||||
|
freqDif = abs(note_data['frequency'] - freq)
|
||||||
|
if freqDif < bestFreqDif:
|
||||||
|
bestFreqDif = freqDif
|
||||||
|
finalNote = note_data['note']
|
||||||
|
finalNoteArray.append(finalNote)
|
||||||
|
|
||||||
|
|
||||||
|
return finalNoteArray
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Try to read existing CSV
|
||||||
|
with open(output_csv, newline='') as csvfile:
|
||||||
|
reader = csv.DictReader(csvfile)
|
||||||
|
data = list(reader)
|
||||||
|
|
||||||
|
# Extract frequency and confidence from CSV
|
||||||
|
time = [float(row['time']) for row in data]
|
||||||
|
frequency = [float(row['frequency']) for row in data]
|
||||||
|
confidence = [float(row['confidence']) for row in data]
|
||||||
|
|
||||||
|
print(f"Loaded {len(frequency)} data points from existing CSV")
|
||||||
|
|
||||||
|
except (FileNotFoundError, KeyError) as e:
|
||||||
|
# If file doesn't exist or has incorrect format, process the audio
|
||||||
|
print(f"Processing audio file: {audio_file}")
|
||||||
|
|
||||||
|
# Read audio file
|
||||||
|
sr, audio = wavfile.read(audio_file)
|
||||||
|
|
||||||
|
# Ensure audio is mono (if stereo, take first channel)
|
||||||
|
if len(audio.shape) > 1 and audio.shape[1] > 1:
|
||||||
|
audio = audio[:, 0]
|
||||||
|
|
||||||
|
# Convert audio to float32 if needed
|
||||||
|
if audio.dtype != np.float32:
|
||||||
|
# Normalize based on data type
|
||||||
|
if audio.dtype == np.int16:
|
||||||
|
audio = audio.astype(np.float32) / 32768.0
|
||||||
|
elif audio.dtype == np.int32:
|
||||||
|
audio = audio.astype(np.float32) / 2147483648.0
|
||||||
|
|
||||||
|
# Run CREPE pitch detection
|
||||||
|
time, frequency, confidence, activation = crepe.predict(audio, sr, viterbi=True)
|
||||||
|
|
||||||
|
# Write results to CSV
|
||||||
|
with open(output_csv, 'w', newline='') as csvfile:
|
||||||
|
fieldnames = ['time', 'frequency', 'confidence']
|
||||||
|
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
|
||||||
|
|
||||||
|
writer.writeheader()
|
||||||
|
for i,ArrayCombined in enumerate(zip(time, frequency, confidence)):
|
||||||
|
if confidence[i] >= 0.5:
|
||||||
|
writer.writerow({
|
||||||
|
'time': ArrayCombined[0],
|
||||||
|
'frequency': ArrayCombined[1],
|
||||||
|
'confidence': ArrayCombined[2]
|
||||||
|
})
|
||||||
|
|
||||||
|
print(f"Saved {len(frequency)} data points to {output_csv}")
|
||||||
|
|
||||||
|
# Convert frequencies to notes
|
||||||
|
notes = getNotesFromFreq(frequency, confidence)
|
||||||
|
|
||||||
|
# Save notes to another CSV file
|
||||||
|
notes_csv = "notes_output.csv"
|
||||||
|
with open(notes_csv, 'w', newline='') as csvfile:
|
||||||
|
fieldnames = ['time', 'frequency', 'confidence', 'note']
|
||||||
|
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
|
||||||
|
|
||||||
|
writer.writeheader()
|
||||||
|
for i,ArrayCombined in enumerate(zip(time, frequency, confidence, notes)):
|
||||||
|
if confidence[i] >= 0.5:
|
||||||
|
writer.writerow({
|
||||||
|
'time': ArrayCombined[0],
|
||||||
|
'frequency': ArrayCombined[1],
|
||||||
|
'confidence': ArrayCombined[2],
|
||||||
|
'note': ArrayCombined[3]
|
||||||
|
})
|
||||||
|
print(frequency[:30])
|
||||||
|
print(f"Saved {len(notes)} notes to {notes_csv}")
|
||||||
|
print(f"Sample of notes: {notes[:10]}")
|
||||||
|
|
@ -0,0 +1,254 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
|
||||||
|
# Read the sensors positions from the sensor_positions.json file
|
||||||
|
with open('sensor_positions.json', 'r') as f:
|
||||||
|
config = json.load(f)
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
## SET THE NOTES TO PLAY AS SUCH:
|
||||||
|
## notes_to_play = [NOTE1, NOTE2,...,NOTEx]
|
||||||
|
## with the notes being
|
||||||
|
## C, C#, D, D#, E, F, F#, G, G#, A, A#, B
|
||||||
|
## = 1, 2 , 3, 4 , 5, 6, 7 , 8, 9 ,10, 11, 12
|
||||||
|
##
|
||||||
|
## To play at rythm, the duration of a note must be added after the ID
|
||||||
|
## like so: notes_to_play = [NOTE1, NOTE2,'half', NOTE3, 'eigth',...,NOTEx]
|
||||||
|
## to play NOTE2 for longer and NOTE3 faster
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
#note_to_play = 2 #note id to play (see sensor_positions.json)
|
||||||
|
|
||||||
|
#notes_to_play = [1,2,3,4,5,6,7,8,9,10,11,12]
|
||||||
|
|
||||||
|
#play Au clair de la Lune
|
||||||
|
#notes_to_play = [1, 1, 1, 3, 5,'half', 3,'half', 1, 5, 3, 3, 1, 'half']
|
||||||
|
|
||||||
|
#play Ode yo Joy
|
||||||
|
#notes_to_play = [5, 5, 6, 8, 8, 6, 5, 3, 1, 1, 3, 5, 5, 3, 3, 'half', 5, 5, 6, 8, 8, 6, 5, 3, 1, 1, 3, 5, 3, 1, 1, 'half', 3, 3, 5, 1, 3, 5,'eigth', 6,'eigth', 5, 1, 3, 5,'eigth', 6,'eigth', 5, 3, 1, 3, 8, 'half', 5, 5, 6, 8, 8, 6, 5, 3, 1, 1, 3, 5, 3, 1, 1]
|
||||||
|
|
||||||
|
#play Happy Birthday
|
||||||
|
notes_to_play = [1, 1, 3, 1, 6, 5,'half', 1, 1, 3, 1, 8, 6,'half', 1, 1, 10, 8, 6, 5, 3,'eigth', 3,'half', 11, 11, 10, 6, 8, 6]
|
||||||
|
|
||||||
|
#play megalovania
|
||||||
|
#notes_to_play = [3, 3, 10, 9, 8, 6, 3, 6, 8]
|
||||||
|
|
||||||
|
notes_to_play = [3,3, 5,3, 10 ,5 ,10,12,6,5,3]
|
||||||
|
|
||||||
|
notes_to_play.append('end') #to know when it is the end of the array
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
delay = 0.1
|
||||||
|
note_delay = 0.2 #delay between notes, corresponding to tempo
|
||||||
|
init_note_delay = note_delay
|
||||||
|
|
||||||
|
if os.name == 'nt':
|
||||||
|
import msvcrt
|
||||||
|
def getch():
|
||||||
|
return msvcrt.getch().decode()
|
||||||
|
else:
|
||||||
|
import sys, tty, termios
|
||||||
|
fd = sys.stdin.fileno()
|
||||||
|
old_settings = termios.tcgetattr(fd)
|
||||||
|
def getch():
|
||||||
|
try:
|
||||||
|
tty.setraw(sys.stdin.fileno())
|
||||||
|
ch = sys.stdin.read(1)
|
||||||
|
finally:
|
||||||
|
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
|
||||||
|
return ch
|
||||||
|
|
||||||
|
from dynamixel_sdk import * # Uses Dynamixel SDK library
|
||||||
|
|
||||||
|
# Control table address
|
||||||
|
ADDR_PRO_TORQUE_ENABLE = 24 # Control table address is different in Dynamixel model
|
||||||
|
ADDR_PRO_GOAL_POSITION = 30
|
||||||
|
ADDR_PRO_PRESENT_POSITION = 37
|
||||||
|
|
||||||
|
# Protocol version
|
||||||
|
PROTOCOL_VERSION = 2.0 # See which protocol version is used in the Dynamixel
|
||||||
|
|
||||||
|
# Set Dynamixel motors IDs
|
||||||
|
DXL1_ID = 1
|
||||||
|
DXL2_ID = 2
|
||||||
|
DXL3_ID = 3
|
||||||
|
|
||||||
|
BAUDRATE = 1000000 # Dynamixel baudrate : 1000000
|
||||||
|
DEVICENAME = 'COM10' # Check which port is being used on your controller
|
||||||
|
# ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*"
|
||||||
|
|
||||||
|
TORQUE_ENABLE = 1 # Value for enabling the torque
|
||||||
|
TORQUE_DISABLE = 0 # Value for disabling the torque
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#CONNECT TO ROBOT
|
||||||
|
# Initialize PortHandler instance
|
||||||
|
# Set the port path
|
||||||
|
# Get methods and members of PortHandlerLinux or PortHandlerWindows
|
||||||
|
portHandler = PortHandler(DEVICENAME)
|
||||||
|
|
||||||
|
# Initialize PacketHandler instance
|
||||||
|
# Set the protocol version
|
||||||
|
# Get methods and members of Protocol1PacketHandler or Protocol2PacketHandler
|
||||||
|
packetHandler = PacketHandler(PROTOCOL_VERSION)
|
||||||
|
|
||||||
|
# Open port
|
||||||
|
if portHandler.openPort():
|
||||||
|
print("Succeeded to open the port")
|
||||||
|
else:
|
||||||
|
print("Failed to open the port")
|
||||||
|
print("Press any key to terminate...")
|
||||||
|
getch()
|
||||||
|
quit()
|
||||||
|
|
||||||
|
# Set port baudrate
|
||||||
|
if portHandler.setBaudRate(BAUDRATE):
|
||||||
|
print("Succeeded to change the baudrate")
|
||||||
|
else:
|
||||||
|
print("Failed to change the baudrate")
|
||||||
|
print("Press any key to terminate...")
|
||||||
|
getch()
|
||||||
|
quit()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ENABLE TORQUES
|
||||||
|
# Enable Dynamixel#1 Torque
|
||||||
|
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL1_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_ENABLE)
|
||||||
|
if dxl_comm_result != COMM_SUCCESS:
|
||||||
|
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||||
|
elif dxl_error != 0:
|
||||||
|
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||||
|
else:
|
||||||
|
print("Dynamixel#%d has been successfully connected" % DXL1_ID)
|
||||||
|
|
||||||
|
# Enable Dynamixel#2 Torque
|
||||||
|
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL2_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_ENABLE)
|
||||||
|
if dxl_comm_result != COMM_SUCCESS:
|
||||||
|
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||||
|
elif dxl_error != 0:
|
||||||
|
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||||
|
else:
|
||||||
|
print("Dynamixel#%d has been successfully connected" % DXL2_ID)
|
||||||
|
|
||||||
|
# Enable Dynamixel#3 Torque
|
||||||
|
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL3_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_ENABLE)
|
||||||
|
if dxl_comm_result != COMM_SUCCESS:
|
||||||
|
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||||
|
elif dxl_error != 0:
|
||||||
|
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||||
|
else:
|
||||||
|
print("Dynamixel#%d has been successfully connected" % DXL3_ID)
|
||||||
|
|
||||||
|
|
||||||
|
#PLAY NOTES
|
||||||
|
index = 0
|
||||||
|
dxl2_goal_position = config["sensors"][0]["q2"] # Goal position 2
|
||||||
|
while index < len(notes_to_play):
|
||||||
|
if notes_to_play[index]=='end': #end the loop if after last note
|
||||||
|
break
|
||||||
|
|
||||||
|
time.sleep(note_delay)
|
||||||
|
note_delay = init_note_delay
|
||||||
|
|
||||||
|
packetHandler.write4ByteTxRx(portHandler, 2, ADDR_PRO_GOAL_POSITION, dxl2_goal_position-80) #move up between notes to avoid collisions
|
||||||
|
|
||||||
|
note_to_play = notes_to_play[index] #check the current note
|
||||||
|
if note_to_play == 'half' or note_to_play == 'eigth': #skip the position if it is a 'half' or an 'eigth'
|
||||||
|
index = index+1
|
||||||
|
note_to_play = notes_to_play[index]
|
||||||
|
|
||||||
|
|
||||||
|
if notes_to_play[index+1] == 'half': #if the next position is /'half' wait longer/ after playing the current note
|
||||||
|
note_delay = init_note_delay*4
|
||||||
|
elif notes_to_play[index+1] == 'eigth': #if the next position is /'eigth' wait less/ after playing the current note
|
||||||
|
note_delay = init_note_delay/4
|
||||||
|
|
||||||
|
#Get note joint values from Json file
|
||||||
|
dxl1_goal_position = config["sensors"][note_to_play-1]["q1"] # Goal position 1
|
||||||
|
dxl2_goal_position = config["sensors"][note_to_play-1]["q2"] # Goal position 2
|
||||||
|
dxl3_goal_position = config["sensors"][note_to_play-1]["q3"] # Goal position 3
|
||||||
|
|
||||||
|
while 1:
|
||||||
|
#print("Press any key to continue! (or press ESC to quit!)") #
|
||||||
|
#if getch() == chr(0x1b): #causes errors
|
||||||
|
# break #
|
||||||
|
|
||||||
|
|
||||||
|
# Move motor 1, then 3, and then 2 to avoid collisions
|
||||||
|
|
||||||
|
# Motor 1
|
||||||
|
# Write goal position 1
|
||||||
|
dxl_comm_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, DXL1_ID, ADDR_PRO_GOAL_POSITION, dxl1_goal_position)
|
||||||
|
if dxl_comm_result != COMM_SUCCESS:
|
||||||
|
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||||
|
elif dxl_error != 0:
|
||||||
|
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||||
|
time.sleep(delay)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Motor 3
|
||||||
|
# Write goal position 3
|
||||||
|
dxl_comm_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, DXL3_ID, ADDR_PRO_GOAL_POSITION, dxl3_goal_position)
|
||||||
|
if dxl_comm_result != COMM_SUCCESS:
|
||||||
|
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||||
|
elif dxl_error != 0:
|
||||||
|
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||||
|
time.sleep(delay)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Motor 2
|
||||||
|
# Write goal position 2
|
||||||
|
dxl_comm_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, DXL2_ID, ADDR_PRO_GOAL_POSITION, dxl2_goal_position)
|
||||||
|
if dxl_comm_result != COMM_SUCCESS:
|
||||||
|
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||||
|
elif dxl_error != 0:
|
||||||
|
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||||
|
time.sleep(delay)
|
||||||
|
|
||||||
|
|
||||||
|
index = index + 1
|
||||||
|
break
|
||||||
|
# go to next position
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#GO TO MIDDLE POSITION
|
||||||
|
dxl_comm_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, DXL2_ID, ADDR_PRO_GOAL_POSITION, 30)
|
||||||
|
time.sleep(0.5)
|
||||||
|
dxl_comm_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, DXL3_ID, ADDR_PRO_GOAL_POSITION, 500)
|
||||||
|
time.sleep(0.5)
|
||||||
|
dxl_comm_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, DXL1_ID, ADDR_PRO_GOAL_POSITION, 500)
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
# DISABLE DYNAMIXEL TORQUES 1 2 3
|
||||||
|
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL1_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_DISABLE)
|
||||||
|
if dxl_comm_result != COMM_SUCCESS:
|
||||||
|
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||||
|
elif dxl_error != 0:
|
||||||
|
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||||
|
|
||||||
|
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL2_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_DISABLE)
|
||||||
|
if dxl_comm_result != COMM_SUCCESS:
|
||||||
|
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||||
|
elif dxl_error != 0:
|
||||||
|
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||||
|
|
||||||
|
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL3_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_DISABLE)
|
||||||
|
if dxl_comm_result != COMM_SUCCESS:
|
||||||
|
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||||
|
elif dxl_error != 0:
|
||||||
|
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Close port
|
||||||
|
portHandler.closePort()
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
{
|
||||||
|
"sensors": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"note": "C",
|
||||||
|
"type": "natural",
|
||||||
|
"q1": 770,
|
||||||
|
"q2": 170,
|
||||||
|
"q3": 530
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"note": "C",
|
||||||
|
"type": "sharp",
|
||||||
|
"q1": 800,
|
||||||
|
"q2": 89,
|
||||||
|
"q3": 735
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"note": "D",
|
||||||
|
"type": "natural",
|
||||||
|
"q1": 715,
|
||||||
|
"q2": 170,
|
||||||
|
"q3": 530
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"note": "D",
|
||||||
|
"type": "sharp",
|
||||||
|
"q1": 650,
|
||||||
|
"q2": 89,
|
||||||
|
"q3": 735
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"note": "E",
|
||||||
|
"type": "natural",
|
||||||
|
"q1": 600 ,
|
||||||
|
"q2": 170,
|
||||||
|
"q3": 530
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"note": "F",
|
||||||
|
"type": "natural",
|
||||||
|
"q1": 520,
|
||||||
|
"q2": 170,
|
||||||
|
"q3": 530
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 7,
|
||||||
|
"note": "F",
|
||||||
|
"type": "sharp",
|
||||||
|
"q1": 516,
|
||||||
|
"q2": 89,
|
||||||
|
"q3": 735
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"note": "G",
|
||||||
|
"type": "natural",
|
||||||
|
"q1": 445,
|
||||||
|
"q2": 170,
|
||||||
|
"q3": 530
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 9,
|
||||||
|
"note": "G",
|
||||||
|
"type": "sharp",
|
||||||
|
"q1": 360,
|
||||||
|
"q2": 89,
|
||||||
|
"q3": 735
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 10,
|
||||||
|
"note": "A",
|
||||||
|
"type": "natural",
|
||||||
|
"q1": 333,
|
||||||
|
"q2": 170,
|
||||||
|
"q3": 530
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 11,
|
||||||
|
"note": "A",
|
||||||
|
"type": "sharp",
|
||||||
|
"q1": 229,
|
||||||
|
"q2": 89,
|
||||||
|
"q3": 735
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 12,
|
||||||
|
"note": "B",
|
||||||
|
"type": "natural",
|
||||||
|
"q1": 270,
|
||||||
|
"q2": 170,
|
||||||
|
"q3": 530
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
/**
|
|
||||||
* This file is used for debugging the analog values of the pins on the ESP32.
|
|
||||||
* It reads the analog values from the specified pins and prints them to the Serial Monitor.
|
|
||||||
* The values are color-coded based on a defined threshold.
|
|
||||||
* Values below the threshold are printed in green, while values above the threshold are printed in red.
|
|
||||||
*/
|
|
||||||
#include <Arduino.h>
|
|
||||||
|
|
||||||
#define THRESHOLD 3000 // Define the threshold value for analog readings
|
|
||||||
#define COLOR_RED "\033[31m" // ANSI escape code for red color
|
|
||||||
#define COLOR_GREEN "\033[32m" // ANSI escape code for green color
|
|
||||||
#define COLOR_RST "\033[0m" // ANSI escape code to reset color
|
|
||||||
|
|
||||||
//const int pinList[] = {34, 35, 32, 33, 25, 26, 27, 14, 15, 2, 0, 4}; // Array of the pins you want to use
|
|
||||||
const int pinList[] = {4, 0, 2, 15, 14, 27, 26, 25, 33, 32, 35, 34}; // Array of the pins you want to use
|
|
||||||
const int numPins = sizeof(pinList) / sizeof(pinList[0]); // Number of pins in the array
|
|
||||||
|
|
||||||
int ArrayStates[numPins]; // Array to store previous states of pins
|
|
||||||
float ArrayValues[numPins]; // Array to store analog values of pins
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void printArray(T array[], int size);
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(115200);
|
|
||||||
|
|
||||||
// Initialize each pin in the pinList as an input
|
|
||||||
for (int i = 0; i < numPins; i++) {
|
|
||||||
pinMode(pinList[i], INPUT); // Set pins as input
|
|
||||||
ArrayStates[i] = 0; // Set initial state to 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
for (int i = 0; i < numPins; i++) {
|
|
||||||
int analogValue = analogRead(pinList[i]); // Read the analog value of the pin
|
|
||||||
ArrayStates[i] = (analogValue < THRESHOLD) ? 1 : 0; // Compare with threshold
|
|
||||||
ArrayValues[i] = analogValue; // Store the analog value
|
|
||||||
}
|
|
||||||
printArray(ArrayValues, numPins);
|
|
||||||
//Serial.print(">States: ");
|
|
||||||
//printArray(ArrayStates, numPins);
|
|
||||||
//delay(0); // Add a small delay to avoid flooding the output
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void printArray(T array[], int size) {
|
|
||||||
Serial.print("["); // Start of the message
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
if (array[i] < THRESHOLD) {
|
|
||||||
Serial.print(COLOR_GREEN); // Change color to red if below threshold
|
|
||||||
} else {
|
|
||||||
Serial.print(COLOR_RED); // Change color to green if above threshold
|
|
||||||
}
|
|
||||||
Serial.print(array[i]); // Print the value
|
|
||||||
Serial.print(COLOR_RST); // Reset color to default
|
|
||||||
if (i < size - 1) {
|
|
||||||
Serial.print(", "); // Add a comma and space if it's not the last element
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Serial.println("]"); // End of the message
|
|
||||||
}
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
/**
|
|
||||||
* This file is used for debugging the analog values of the pins on the ESP32.
|
|
||||||
* It reads the analog values from the specified pins and prints them to the Serial Monitor.
|
|
||||||
* The values are color-coded based on a defined threshold.
|
|
||||||
* Values below the threshold are printed in green, while values above the threshold are printed in red.
|
|
||||||
*/
|
|
||||||
#include <Arduino.h>
|
|
||||||
|
|
||||||
#define THRESHOLD 3000 // Define the threshold value for analog readings
|
|
||||||
|
|
||||||
//const int pinList[] = {34, 35, 32, 33, 25, 26, 27, 14, 15, 2, 0, 4}; // Array of the pins you want to use
|
|
||||||
const int pinList[] = {4, 0, 2, 15, 14, 27, 26, 25, 33, 32, 35, 34}; // Array of the pins you want to use
|
|
||||||
const int numPins = sizeof(pinList) / sizeof(pinList[0]); // Number of pins in the array
|
|
||||||
const char* noteList[] = {"C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B"}; // Array of note names
|
|
||||||
|
|
||||||
int ArrayStates[numPins]; // Array to store previous states of pins
|
|
||||||
int LastSentStates[numPins]; // Array to store last sent states of pins
|
|
||||||
float ArrayValues[numPins]; // Array to store analog values of pins
|
|
||||||
|
|
||||||
bool isArrayEmpty(int array[], int size) {
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
if (array[i] != 0) { // Check if any element is not zero
|
|
||||||
return false; // Array is not empty
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true; // Array is empty
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(115200);
|
|
||||||
|
|
||||||
// Initialize each pin in the pinList as an input
|
|
||||||
for (int i = 0; i < numPins; i++) {
|
|
||||||
pinMode(pinList[i], INPUT); // Set pins as input
|
|
||||||
ArrayStates[i] = 0; // Set initial state to 0
|
|
||||||
}
|
|
||||||
Serial.println("Starting up..."); // Print a message indicating startup
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
for (int i = 0; i < numPins; i++) {
|
|
||||||
int analogValue = analogRead(pinList[i]); // Read the analog value of the pin
|
|
||||||
ArrayStates[i] = (analogValue < THRESHOLD) ? 1 : 0; // Compare with threshold
|
|
||||||
ArrayValues[i] = analogValue; // Store the analog value
|
|
||||||
}
|
|
||||||
if (memcmp(ArrayStates, LastSentStates, sizeof(ArrayStates)) != 0) {
|
|
||||||
memcpy(LastSentStates, ArrayStates, sizeof(ArrayStates)); // Update last sent states
|
|
||||||
if (isArrayEmpty(ArrayStates, numPins) == false) {
|
|
||||||
for (int i = 0; i < numPins; i++) {
|
|
||||||
if (ArrayStates[i] == 1) {
|
|
||||||
Serial.print(noteList[i]); // Print the note name if the state is 1
|
|
||||||
Serial.print(" "); // Add a space between note names
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Serial.println(); // Print a new line after printing all note names
|
|
||||||
delay(250); //avoid flickering in the sensing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
11
test/README
11
test/README
|
|
@ -1,11 +0,0 @@
|
||||||
|
|
||||||
This directory is intended for PlatformIO Test Runner 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/en/latest/advanced/unit-testing/index.html
|
|
||||||
Loading…
Reference in New Issue