diff --git a/OpenSCAD/.M5CoreTX-V1.scad.swp b/OpenSCAD/.M5CoreTX-V1.scad.swp deleted file mode 100644 index e81188d..0000000 Binary files a/OpenSCAD/.M5CoreTX-V1.scad.swp and /dev/null differ diff --git a/OpenSCAD/M5CoreTX-V1.scad b/OpenSCAD/M5CoreTX-V1.scad index 3299029..5dc2d7e 100644 --- a/OpenSCAD/M5CoreTX-V1.scad +++ b/OpenSCAD/M5CoreTX-V1.scad @@ -1,763 +1,680 @@ -// For printing individually -// gimbal_ring(); - -// translate([0,0,0]) -// display_backcover(); -// battery_backcover_full(); -// body_full(); - -round_quality = 100; // round_quality = 200; -// round_quality = 20; -// draft = true; -draft = false; - -/**** -translate([0,0,5]) - back_cover_full(); - -translate([0,0,-20]) - difference() { - backcover_lowprofile(); - - translate([-21.5,-12.5,-46]) - rotate([0,0,0]) - cube([25,46,15], center=true); - - translate([-21.5,-12.5,-36]) - rotate([0,0,0]) - cube([25,37.4,2], center=true); - +// draft = false; +// show_m5 = true; +// show_gimbal_r = true; // Rings +// show_right_g = false; // Only show one gimbal +// show_gimbal = true; // Gimbals +// show_gimbal_u = false; // Upper +// show_left = true; +// show_right = true; +// show_left_b = true; +// show_right_b = true; +// show_gimbal_b = false; // Lower +// show_battery = true; +// show_bars = true; +// show_bars_1 = true; +// show_bars_2 = true; + +round_quality = 200; +draft = true; +show_top_only = false; +show_bottom_only = false; +show_m5 = true; +show_gimbal_r = true; // Rings +show_right_g = false; // Only show one gimbal +show_gimbal = true; // Gimbals +show_gimbal_u = false; // Upper +show_left = true; +show_right = true; +show_left_b = true; +show_right_b = true; +show_gimbal_b = false; // Lower +show_battery = true; +show_bars = false; +show_bars_1 = false; +show_bars_2 = false; +show_bottom_legs = false; +show_bottom_single = false; +show_bottom_H = true; +show_top_bars = true; +show_bottom_spacers = true; +show_bottom_extenders = true; +show_top_spacers = true; +show_top_cover = true; + +//round_quality = 200; +//draft = true; +//show_top_only = false; +//show_bottom_only = false; +//show_m5 = false; +//show_gimbal_r = false; // Rings +//show_right_g = false; // Only show one gimbal +//show_gimbal = false; // Gimbals +//show_gimbal_u = false; // Upper +//show_left = false; +//show_right = true; +//show_left_b = true; +//show_right_b = true; +//show_gimbal_b = false; // Lower +//show_battery = false; +//show_bars = false; +//show_bars_1 = false; +//show_bars_2 = false; +//show_bottom_legs = false; +//show_bottom_single = false; +//show_bottom_H = false; +//show_top_bars = false; +//show_bottom_spacers = false; +//show_bottom_extenders = false; +//show_top_spacers = true; +//show_top_cover = false; + +if(show_top_cover) { + translate([-20,11,6]) { + top_cover(); } - - -translate([0,0,-20]) - difference() { - transceiver_cover(); - translate([-25.8,6,-39]) - rotate([90,0,0]) - cube([5.5,13,10], center=true); - } - -translate([0,-80,-20]) - battery_backcover_full(); -translate([0,0,-25]) - display_backcover(); -translate([0,0,20]) - gimbal_ring(); -translate([-41,0,40]) { - translate([135,0,-20]) - gimbal_ring(); } - ****/ -// back_cover_full(); - -// translate([0,0,10]) -// battery_backcover_full(); - -// all(); - -// m5core2(); -body_full(); -translate([0,-20,12]) - rotate([180,0,180]) - m5_body(); - -module m5core2() { - translate([0,-25,10]) - cube([54,54,18], center=true); +if(show_top_spacers) { + top_spacers(); } -module transceiver_cover() { - translate([-21.5,-14.2,-46.5]) - cube([24,42.4,1.3], center=true); - translate([-21.5,6.5,-42.9]) - rotate([90,0,0]) - cube([24,8.5,1.3], center=true); - translate([-21.5,-36,-45.2]) - rotate([0,0,0]) - cube([24.5,5,1.3], center=true); - translate([-25.5,-3,-44.4]) - rotate([0,0,0]) - cube([14.5,3,3], center=true); - translate([-25.5,-9,-44.4]) - rotate([0,0,0]) - cube([14.5,3,3], center=true); - translate([-25.5,-21,-44.4]) - rotate([0,0,0]) - cube([14.5,3,3], center=true); - translate([-25.5,-27,-44.4]) - rotate([0,0,0]) - cube([14.5,3,3], center=true); - translate([-12.5,-15,-44.4]) - rotate([0,0,90]) - cube([34.5,3,3], center=true); - - translate([-21.5,5,-44.4]) - rotate([0,0,0]) - cube([24,3,3], center=true); - - translate([-25.5,-15,-44.4]) - rotate([0,0,0]) - cube([14.5,3,3], center=true); - difference() { - translate([-21.5,5.2,-39]) - rotate([90,0,0]) - cube([24,6.5,1.3], center=true); +module top_spacers() { + translate([-18,7,15.3]) + cube([20,3,10], center=true); + translate([18,7,15.3]) + cube([20,3,10], center=true); +} - translate([-21.5,5.5,-43]) - rotate([-45,0,0]) - cube([25.5,6.5,1.3], center=true); - } - translate([-21.5,6,-36.3]) - rotate([90,0,0]) - cube([24,1.1,1.3], center=true); +module top_cover() { + top_legs(); + translate([40,0,0]) + top_legs(); + // Battery Cover + translate([20,-1.5,4.5]) + difference() { + cube([50,1.5,54], center=true); + translate([0,0,4.5]) + rotate([90,0,0]) + cylinder(h=4, d=10, center=true, $fn=round_quality); + translate([0,0,7]) + cube([10,10,5], center=true); + } } -module backcover_lowprofile() { +module top_legs() { + translate([0,0,4.5]) + rotate([0,0,180]) difference() { - battery_backcover(); + cube([14,4.5,54], center=true); - // Left Screw Hold on the Battery Cover - translate([41,-23,-30]) - cylinder(h=round_quality, d=2, center=true, $fn=round_quality); + // Screw top + translate([0,0,5]) + rotate([90,0,0]) + cylinder(h=10, d=2, center=true, $fn=round_quality); + translate([0,-2,5]) + rotate([90,0,0]) + cylinder(h=4, d=4.6, center=true, $fn=round_quality); - // Right Screw Hold on the Battery Cover - translate([-41,-23,-30]) - cylinder(h=round_quality, d=2, center=true, $fn=round_quality); + // Screw bottom + translate([0,0,-8]) + rotate([90,0,0]) + cylinder(h=10, d=2, center=true, $fn=round_quality); + translate([0,-2,-8]) + rotate([90,0,0]) + cylinder(h=4, d=4.6, center=true, $fn=round_quality); - // Charger Port - // translate([0,-50,-30]) - // cube([10,3,6], center=true); - translate([0,-23,-30]) - cube([76,58,5], center=true); + // Sides + translate([10,0,0]) + rotate([0,0,45]) + cube([20,4.5,63], center=true); + translate([-10,0,0]) + rotate([0,0,-45]) + cube([20,4.5,63], center=true); } +} - translate([0,6.35,-37.5]) - rotate([90,0,0]) - cube([78,17,1.3], center=true); - - translate([0,-52.35,-37.5]) - rotate([90,0,0]) - cube([78,17,1.3], center=true); - - translate([-38.6,-23,-37.5]) - rotate([90,0,90]) - cube([60,17,1.3], center=true); - - translate([38.6,-23,-37.5]) - rotate([90,0,90]) - cube([60,17,1.3], center=true); - translate([0,-23,-46.5]) - rotate([0,0,0]) - cube([78.5,60,1.3], center=true); +if(show_bottom_extenders) { + translate([-20,-57,17]) + bottom_extenders(); + translate([20,-57,17]) + bottom_extenders(); +} +module bottom_extenders() { difference() { - translate([0,-51.1,-30.5]) - rotate([90,0,0]) - cube([75,5,1.3], center=true); + cube([14,3,8], center=true); - translate([0,-51.1,-33.5]) - rotate([45,0,0]) - cube([75,5,1.3], center=true); + // Screw top + translate([0,0,-2]) + rotate([90,0,0]) + cylinder(h=10, d=2, center=true, $fn=round_quality); } } - -// Battery back cover -module battery_backcover() { - translate([0,-23,-30]) - cube([90,60,2], center=true); +if(show_bottom_spacers) { + translate([-20,-61,6]) + bottom_spacers(); } -module back_cover() { - translate([-47,-25,-8]) - cube([67.4,67.4,2], center=true); - translate([47,-25,-8]) - cube([67.4,67.4,2], center=true); - translate([0,-23,-8]) - cube([29,62,2], center=true); - translate([-53,20,-8]) - cube([43.5,27.5,2], center=true); - translate([53,20,-8]) - cube([43.5,27.5,2], center=true); - - // PCB & Battery Holder - translate([0,-23,-12]) { - difference() { - cube([90,60,10], center=true); - cube([88,58,12], center=true); - } - translate([41,0,0]) - difference() { - cube([7,10,6], center=true); - cylinder(h=round_quality, d=3, center=true); - } - translate([-41,0,0]) - difference() { - cube([7,10,6], center=true); - cylinder(h=round_quality, d=3, center=true); - } - translate([0,28,0]) - cube([90,2,6], center=true); - translate([0,-28,0]) - cube([90,2,6], center=true); - } - - // Left Holder - translate([-63,-25,6]) - rotate([90,0,0]) - difference() { - cylinder(h=67, d=45.5, center=true); - translate([0,10,0]) - cube([50,50,70], center=true); - } +module bottom_spacers() { + translate([0,0,0]) + bottom_legs(); + translate([20,0,-1]) + rotate([0,90,0]) + bottom_legs(); + translate([40,0,0]) + bottom_legs(); +} - // Right Holder - translate([63,-25,6]) - rotate([90,0,0]) - difference() { - cylinder(h=67, d=45.5, center=true); - translate([0,10,0]) - cube([50,50,70], center=true); - } - /**** - // Battery + Capacitor Area - translate([0,6,-19]) - cube([70,2,20], center=true); - translate([0,-52,-19]) - cube([70,2,20], center=true); - translate([36,-23,-19]) - cube([2,60,20], center=true); - translate([-36,-23,-19]) - cube([2,60,20], center=true); - - // Back Cover Holder - translate([41,-23,-19]) - cylinder(h=round_quality, d=10, center=true); - translate([39,-23,-19]) - cube([5,10,20], center=true); - translate([-41,-23,-19]) - cylinder(h=round_quality, d=10, center=true); - translate([-39,-23,-19]) - cube([5,10,20], center=true); - ***/ +if(show_bottom_H) { + translate([-85,-61,6]) { + bottom_H(); + } + translate([45,-61,6]) { + bottom_H(); + } } -// Display BackCover -module display_backcover() { - difference() { - translate([0,21,7]) { - difference() { - cube([45.5,29.5,2], center=true); - - translate([21.5,13.5,0]) - cylinder(h=3, d=1, center=true); - - translate([-21.5,13.5,0]) - cylinder(h=3, d=1, center=true); - - translate([-21.5,-8.5,0]) - cylinder(h=3, d=1, center=true); - - translate([21.5,-8.5,0]) - cylinder(h=3, d=1, center=true); +module bottom_H() { + translate([0,0,0]) + bottom_legs(); + translate([20,0,0]) + rotate([0,90,0]) + bottom_legs(); + translate([40,0,0]) + bottom_legs(); +} - translate([0,-27,0]) - cube([50,35,5], center=true); - } - } - } - /* - translate([9,23,11]) { - cube([5,10,9], center=true); - translate([2,0,-2]) - cube([10,2,3], center=true); +if(show_top_bars) { + translate([-85,11,6]) { + rotate([180,0,0]) + bottom_H(); } - - translate([-9,23,11]) { - cube([5,10,9], center=true); - translate([-2,0,-2]) - cube([10,2,3], center=true); + translate([45,11,6]) { + rotate([180,0,0]) + bottom_H(); } - */ } -module battery_backcover_full() { +module top_bars() { + rotate([0,0,180]) difference() { - battery_backcover(); + cube([14,4.5,30], center=true); - // Left Screw Hold on the Battery Cover - translate([41,-23,-30]) - cylinder(h=round_quality, d=2, center=true, $fn=round_quality); + // Screw top + translate([0,0,9]) + rotate([90,0,0]) + cylinder(h=10, d=2, center=true, $fn=round_quality); + translate([0,-2,9]) + rotate([90,0,0]) + cylinder(h=4, d=4.6, center=true, $fn=round_quality); - // Right Screw Hold on the Battery Cover - translate([-41,-23,-30]) - cylinder(h=round_quality, d=2, center=true, $fn=round_quality); + // Screw bottom + translate([0,0,-6]) + rotate([90,0,0]) + cylinder(h=10, d=2, center=true, $fn=round_quality); + translate([0,-2,-6]) + rotate([90,0,0]) + cylinder(h=4, d=4.6, center=true, $fn=round_quality); - // Charger Port - // translate([0,-50,-30]) - // cube([10,3,6], center=true); - translate([0,-23,-30]) - cube([76,50,5], center=true); + // Sides + translate([10,0,0]) + rotate([0,0,45]) + cube([20,4.5,33], center=true); + translate([-10,0,0]) + rotate([0,0,-45]) + cube([20,4.5,33], center=true); } - // Upper box area - translate([0,-23,-45]) { - difference() { - cube([77,54,31.4], center=true); - translate([0,0,3.5]) - cube([74,51,35.4], center=true); - translate([27,25,11]) - cube([6.6,12,14], center=true); - translate([0,-15,-19]) - cube([2,5,12], center=true); - } - } } -module back_cover_full() { - translate([53,20,-10]) { - rotate([0,0,30]) - cube([45,2,2], center=true); - rotate([0,0,-30]) - cube([45,2,2], center=true); - cube([10,10,2], center=true); +if(show_bottom_legs) { + translate([-85,-61,6]) { + bottom_legs(); } - - translate([-53,20,-10]) { - rotate([0,0,30]) - cube([45,2,2], center=true); - rotate([0,0,-30]) - cube([45,2,2], center=true); - cube([10,10,2], center=true); + translate([-45,-61,6]) { + bottom_legs(); + } + translate([45,-61,6]) { + bottom_legs(); } + translate([85,-61,6]) { + bottom_legs(); + } +} else if(show_bottom_single) { + translate([0,0,0]) + rotate([-90,0,0]) + bottom_legs(); + translate([20,0,0]) + rotate([-90,0,0]) + bottom_legs(); + translate([40,0,0]) + rotate([-90,0,0]) + bottom_legs(); + translate([60,0,0]) + rotate([-90,0,0]) + bottom_legs(); + translate([80,0,0]) + rotate([-90,0,0]) + bottom_legs(); + translate([100,0,0]) + rotate([-90,0,0]) + bottom_legs(); + translate([120,0,0]) + rotate([-90,0,0]) + bottom_legs(); + translate([140,0,0]) + rotate([-90,0,0]) + bottom_legs(); +} +module bottom_legs() { difference() { - back_cover(); + cube([14,4.5,30], center=true); - // Left Holder Hollow area - translate([-63,-25,9]) + // Screw top + translate([0,0,9]) rotate([90,0,0]) - difference() { - cylinder(h=60, d=45.5, center=true); - translate([0,10,0]) - cube([50,50,70], center=true); - } - - // Right Holder Hollow area - translate([63,-25,9]) + cylinder(h=10, d=2, center=true, $fn=round_quality); + translate([0,-2,9]) rotate([90,0,0]) - difference() { - cylinder(h=60, d=45.5, center=true); - translate([0,10,0]) - cube([50,50,70], center=true); - } + cylinder(h=4, d=4.6, center=true, $fn=round_quality); + // Screw bottom + translate([0,0,-6]) + rotate([90,0,0]) + cylinder(h=10, d=2, center=true, $fn=round_quality); + translate([0,-2,-6]) + rotate([90,0,0]) + cylinder(h=4, d=4.6, center=true, $fn=round_quality); - translate([0,-20,-10]) - cube([20,20,10], center=true); - - // Left Screw Hold on the Battery Cover - translate([41,-23,-30]) - cylinder(h=round_quality, d=2, center=true); - - // Right Screw Hold on the Battery Cover - translate([-41,-23,-30]) - cylinder(h=round_quality, d=2, center=true); - - /************* - // Screw Holes at backcover gimbal area - translate([-79.5,7.5,-10]) - cylinder(h=10, d=1, center=true); - translate([79.5,7.5,-10]) - cylinder(h=10, d=1, center=true); - translate([79.5,-57.5,-10]) - cylinder(h=10, d=1, center=true); - translate([-79.5,-57.5,-10]) - cylinder(h=10, d=1, center=true); - translate([-14.5,-57.5,-10]) - cylinder(h=10, d=1, center=true); - translate([14.5,-57.5,-10]) - cylinder(h=10, d=1, center=true); - - // Screws holes at switches panel - translate([73.5,12.5,-10]) - cylinder(h=10, d=1, center=true); - translate([32.5,12.5,-10]) - cylinder(h=10, d=1, center=true); - translate([32.5,32.5,-10]) - cylinder(h=10, d=1, center=true); - translate([73.5,32.5,-10]) - cylinder(h=10, d=1, center=true); - - translate([-32.5,32.5,-10]) - cylinder(h=10, d=1, center=true); - translate([-32.5,12.5,-10]) - cylinder(h=10, d=1, center=true); - translate([-73.5,12.5,-10]) - cylinder(h=10, d=1, center=true); - translate([-73.5,32.5,-10]) - cylinder(h=10, d=1, center=true); - ********/ + // Sides + translate([10,0,0]) + rotate([0,0,45]) + cube([20,4.5,33], center=true); + translate([-10,0,0]) + rotate([0,0,-45]) + cube([20,4.5,33], center=true); } -} - -module body_full() { - body(); - translate([-16,0,0]) - gimbal_ring(); - translate([110,0,0]) { - gimbal_ring(); - } } -module all() { - // Display Backcover - display_backcover(); - - // Battery Backcover - battery_backcover_full(); - - // Main BackCover - back_cover_full(); - - // Full Body - body_full(); - - // Gimbal Ring - gimbal_ring(); - - translate([-41,0,20]) { - translate([135,0,-20]) - gimbal_ring(); +if(show_top_only) { + difference() { + body_full(); + translate([0,0,-37.5]) + cube([200,200,100], center=true); } +} else if(show_bottom_only) { + difference() { + body_full(); + translate([0,0,27]) + cube([200,200,30], center=true); + } +} else { + body_full(); } +// Ruler only +// translate([24.5,0,0]) +// rotate([0,0,0]) +// cube([10,10,10], center=true); -module body() { - // Left Switch Panel - // switch_panel(); +if(show_bars) { + if(show_bars_1) { + translate([0,-10,0]) + difference() { + show_bars_plate(0); - // Right Switch Panel - // mirror([-1,0,0]) - // switch_panel(); + translate([15,20,0]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); - // Top Display of the OLED Area - // translate([0,2,0]) - // top_display(); + translate([45,20,0]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); - // Center GAP - // translate([0,0,-5]) - // center_face(); + translate([45,20,15]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); - // Left gimbal - translate([25,0,20]) - gimbal_unit_face(); + translate([85,20,0]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); - // translate([-87,-25,6]) - // gimbal_side(); - - // Right gimbal - translate([-25,0,20]) { - mirror([-1,0,0]) - gimbal_unit_face(); + translate([85,20,15]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); + + translate([-15,20,0]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); + + translate([-45,20,0]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); - // mirror([-1,0,0]) - // translate([-107,-25,-14]) - // gimbal_side(); + translate([-45,20,15]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); + + translate([-85,20,0]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); + + translate([-85,20,15]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); + } + } + if(show_bars_2) { + translate([0,-80,0]) { + difference() { + show_bars_plate(1); + + translate([15,20,0]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); + + translate([45,20,0]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); + + translate([45,20,15]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); + + translate([85,20,0]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); + + translate([85,20,15]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); + + translate([-15,20,0]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); + + translate([-45,20,0]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); + + translate([-45,20,15]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); + + translate([-85,20,0]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); + + translate([-85,20,15]) + rotate([90,0,0]) + cylinder(h=5, d=1.5, center=true, $fn=round_quality); + } + } } } -/*********** -// To measure the size and location to put the PCB. To be hidden once done. -translate([0,-22,-12.5]) - tx_board(); - ************/ - -module pcb_case() { +if(show_m5) { + translate([0,-20,28]) + rotate([180,0,180]) + m5_body(); } -//display_bracket(); -module display_bracket() { - translate([0,18.5,22]) - difference() { - cube([50,25,3], center=true); - - translate([0,-0.5,0]) - rotate([0,0,90]) - cube([13.4,23.5,5], center=true); +if(show_gimbal_r) { + if(show_right_g) { + translate([-16,0,0]) + gimbal_ring(); + } else { + translate([-16,0,0]) + gimbal_ring(); + translate([110,0,0]) + gimbal_ring(); } } -// OLED Display -module top_display() { - // Measurement: 13.4mm x 23.5mm - translate([0,20.8,20]) - difference() { - cube([50,26.4,2], center=true); - - translate([0,0.5,0]) - rotate([0,0,90]) - cube([17.4,24.9,5], center=true); +module show_bars_plate(bar_types) { + if(bar_types == 0) { + translate([0,20,0]) + rotate([0,0,0]) + difference() { + cube([180,2,8], center=true); + translate([0,0,4]) + rotate([90,0,0]) + cylinder(h=4, d=10, center=true, $fn=round_quality); + } + } else { + translate([0,20,0]) + rotate([0,0,0]) + cube([180,2,8], center=true); } + + translate([85,20,10]) + rotate([0,0,0]) { + cube([10,2,20], center=true); + } - // Top cover - translate([0,35,13.5]) - rotate([90,0,0]) - cube([50,15,2], center=true); - - // Bottom Cover - translate([0,8,13.5]) - rotate([90,0,0]) - cube([50,15,2], center=true); + translate([45,20,10]) + rotate([0,0,0]) + cube([10,2,20], center=true); - // Top Cover Left - translate([-24,21.5,13.5]) - rotate([90,0,90]) - cube([25,15,2], center=true); + translate([-85,20,10]) + rotate([0,0,0]) + cube([10,2,20], center=true); - // Top Cover Right - translate([24,21.5,13.5]) - rotate([90,0,90]) - cube([25,15,2], center=true); + translate([-45,20,10]) + rotate([0,0,0]) + cube([10,2,20], center=true); +} - // Screws - Top Left - translate([-21.5,32.5,14]) - difference() { - cylinder(h=13, d=4, center=true); - cylinder(h=33, d=1.5, center=true); +module body_full() { + if(show_gimbal) { + if(show_right_b && show_left_b) { + body(); + } else if(show_right_b && !show_left_b) { + difference() { + body(); + translate([-60,0,0]) + cube([80,200,80], center=true); + } + } else if(!show_right_b && show_left_b) { + difference() { + body(); + translate([60,0,0]) + cube([80,200,80], center=true); + } } + } - // Screws - Top Right - translate([21.5,32.5,14]) - difference() { - cylinder(h=13, d=4, center=true); - cylinder(h=33, d=1.5, center=true); - } + if(show_battery) { + translate([0,-20,17]) + rotate([180,0,180]) { + difference() { + battery_area(); - // Screw - Bottom Left - translate([-21.5,10.5,14]) - difference() { - cylinder(h=13, d=4, center=true); - cylinder(h=33, d=1.5, center=true); - } + translate([-30,-6,22]) + rotate([0,0,0]) + cube([10,30,7], center=true); - // Screw - Bottom Right - translate([21.5,10.5,14]) - difference() { - cylinder(h=13, d=4, center=true); - cylinder(h=33, d=1.5, center=true); + translate([30,-6,22]) + rotate([0,0,0]) + cube([10,30,7], center=true); + } + } } } -// Switch Panels -module switch_panel() { - difference() { - translate([-53,20,20]) - rotate([0,0,0]) - cube([45,30,2], center=true); +module body() { + // Left gimbal + if(show_left) { + translate([25,0,20]) { + if(show_gimbal_u) { + difference() { + gimbal_unit_face(); + + translate([-85,-15,-55]) + cube([90,90,80], center=true); + } + } else if(show_gimbal_b) { + difference() { + gimbal_unit_face(); + + translate([-85,-15,25]) + cube([90,90,80], center=true); + } + } else { + gimbal_unit_face(); + } + } + } - translate([-66,22,20]) - rocker_switch(false); + // Right gimbal + if(show_right) { + translate([-25,0,20]) + mirror([-1,0,0]) + if(show_gimbal_u) { + difference() { + gimbal_unit_face(); - translate([-53,22,20]) - rocker_switch(false); + translate([-85,-15,-55]) + cube([90,90,80], center=true); + } + } else if(show_gimbal_b) { + difference() { + gimbal_unit_face(); - translate([-40,22,20]) - rocker_switch(false); + translate([-85,-15,25]) + cube([90,90,80], center=true); + } + } else { + gimbal_unit_face(); + } } - - // Side - Left - translate([76,23,6]) - rotate([0,90,0]) - cube([30,24,2], center=true); - - // Side - Right - translate([30,23,6]) - rotate([0,90,0]) - cube([30,24,2], center=true); - - // Side - Top - translate([53,35,6]) - rotate([90,0,0]) - cube([48,30,2], center=true); - - // Screw holders - // Screw - Top Left - translate([73.5,32.5,7]) - difference() { - cylinder(h=28, d=4, center=true); - cylinder(h=29, d=1.5, center=true); - } - - // Screw - Top Right - translate([32.5,32.5,7]) - difference() { - cylinder(h=28, d=4, center=true); - cylinder(h=29, d=1.5, center=true); - } - - // Screw - Bottom Left - translate([73.5,12.5,7]) - difference() { - cylinder(h=28, d=4, center=true); - cylinder(h=29, d=1.5, center=true); - } - - // Screen - Bottom Right - translate([32.5,12.5,7]) - difference() { - cylinder(h=28, d=4, center=true); - cylinder(h=29, d=1.5, center=true); - } } -// Center Top Part -module center_face() { - // Side Walls - translate([-10,-22.5,11]) - rotate([90,0,90]) - cube([65,20,2], center=true); - translate([10,-22.5,11]) - rotate([90,0,90]) - cube([65,20,2], center=true); - +module gimbal_ring() { difference() { - // Center Gap - translate([0,-25,20]) - rotate([0,0,90]) - cube([70,20,2], center=true); - - // Center - Top Switch - translate([0,-10,18]) - rotate([0,90,90]) - rocker_switch(false); - - // Center - Middle Switch - translate([0,-25,18]) - rotate([0,90,90]) - rocker_switch(false); - - // Center - Bottom Switch - translate([0,-40,18]) - rotate([0,90,90]) - rocker_switch(false); + gimbal_ring_full(); - // Remove bottom... - translate([0,-60,20]) - rotate([0,0,90]) - cube([10,30,5], center=true); + translate([-47,-25,23.5]) + cylinder(h=6, d1=47.5, d2=57.5, center=true, $fn=round_quality); } +} - // Bottom - translate([0,-55.5,8.5]) - rotate([90,0,0]) - cube([22,25,2], center=true); +module battery_area() { + // Battery base top + /*** + translate([0,-5,18]) + rotate([0,0,0]) + difference() { + cube([60,67,1], center=true); - // Top - translate([0,9.5,11]) - rotate([90,0,0]) - cube([22,30,3], center=true); + // Side hole for Throttle, Yaw, Pitch and Roll connectors + translate([16,3,0]) + cube([15,55,2], center=true); - // Bottom HOOK - translate([0,-57.5,18.5]) { - difference() { - rotate([90,0,0]) - cube([10,5,5], center=true); - translate([0,-2,0]) - cylinder(h=6, d=5, center=true); - } - translate([0,-3,0]) - difference() { - cylinder(h=5, d=10, center=true); - cylinder(h=6, d=5, center=true); - } - } + // Hole for Power input + translate([0,-19.5,0]) + cube([10,10,2], center=true); + } + ***/ - /*** - // Screw - Top Left - translate([-7.5,7,11]) - difference() { - cylinder(h=16, d=4, center=true); - cylinder(h=round_quality, d=1.5, center=true); - } + // Battery base top side left + // translate([28.5,-5,13]) + // rotate([0,90,0]) + // cube([10,65,3], center=true); + + // Battery base top side right + // translate([-28.5,-5,13]) + // rotate([0,90,0]) + // cube([10,65,3], center=true); - // Screw - Top Right - translate([7.5,7,11]) - difference() { - cylinder(h=16, d=4, center=true); - cylinder(h=round_quality, d=1.5, center=true); - } + // Battery base top side bottom + translate([0,-38,15]) + rotate([90,0,0]) { + difference() { + cube([60,20,1], center=true); - // Screw - Bottom Left - translate([-7.5,-53,11]) - difference() { - cylinder(h=16, d=4, center=true); - cylinder(h=round_quality, d=1.5, center=true); - } + translate([15,-3,0]) + cylinder(h=10, d=1.5, center=true, $fn=round_quality); - // Screw - Bottom Right - translate([7.5,-53,11]) - difference() { - cylinder(h=16, d=4, center=true); - cylinder(h=round_quality, d=1.5, center=true); + translate([-15,-3,0]) + cylinder(h=10, d=1.5, center=true, $fn=round_quality); + } } - ***/ -} + translate([0,-37,15]) + rotate([90,0,0]) + cube([60,20,2], center=true); -// Rocker Switch Hole Dimension 8.5mm x 13.2mm (Bracket size 10.3mm x 14.8mm) -module rocker_switch(bracket = false) { - if(bracket) - cube([10.7,15.2,9.5], center=true); - else - cube([9,14.2,9.5], center=true); -} + // Battery base top side top + translate([0,27,12]) + rotate([90,0,0]) { + difference() { + cube([60,10,3], center=true); -// The MOCK UP PCB -module tx_board() { - difference() { - translate([0,0,0]) - rotate([0,0,0]) - cube([75,50,1.2], center=true); - - // Left groove - groove(); + translate([0,-4,0]) + cylinder(h=4, d=10, center=true, $fn=round_quality); - // Right Groove - mirror([1,0,0]) { - groove(); + translate([15,-1,0]) + cylinder(h=10, d=1.5, center=true, $fn=round_quality); + + translate([-15,-1,0]) + cylinder(h=10, d=1.5, center=true, $fn=round_quality); + } + translate([0,6,0]) + cube([60,10,3], center=true); } - } -} -module groove() { - translate([-35,0,0]) - rotate([90,0,90]) - cube([20,2,5], center=true); - - translate([-38,10,0]) - rotate([0,0,45]) - cube([8,8,2.5], center=true); + // Supporters + translate([0,27.5,28]) + cube([2,2,10], center=true); + translate([10,27.5,28]) + cube([2,2,10], center=true); + translate([-10,27.5,28]) + cube([2,2,10], center=true); + translate([-20,27.5,28]) + cube([2,2,10], center=true); + translate([20,27.5,28]) + cube([2,2,10], center=true); + + // Seperator + // translate([0,-5,23]) + // rotate([0,0,0]) { + // cube([60,67,1], center=true); + // } + + // Battery base bottom + translate([0,-5,33]) + rotate([0,0,0]) { + cube([60,67,1], center=true); + } - translate([-38,-10,0]) - rotate([0,0,45]) - cube([8,8,2.5], center=true); -} + // Battery base top cover + translate([0,-38,28]) + rotate([90,0,0]) + cube([62,10,1], center=true); -module gimbal_ring() { - difference() { - gimbal_ring_full(); + // Battery base bottom sides + translate([28.5,-5,26]) + rotate([0,90,0]) + cube([15,67,2], center=true); + translate([28.5,-5,23.5]) + rotate([0,90,0]) + cube([10,67,2], center=true); + translate([-28.5,-5,26]) + rotate([0,90,0]) + cube([15,67,2], center=true); + translate([-28.5,-5,23.5]) + rotate([0,90,0]) + cube([10,67,2], center=true); - translate([-47,-25,23.5]) - cylinder(h=6, d1=47.5, d2=57.5, center=true, $fn=round_quality); - } + } module gimbal_ring_full() { @@ -849,27 +766,120 @@ module gimbal_unit_face() { translate([-88,-25,0]) { // Left translate([-32.5,0,-14]) - rotate([90,0,90]) + rotate([90,0,90]) { cube([63,30,2], center=true); + translate([0,0,41.4]) + rotate([0,90,0]) + difference() { + cylinder(h=67, d=90, center=true, $fn=800); + + translate([-2.6,0,0]) + cube([90,90,90], center=true); + } + } + // Right - translate([32.5,0,-14]) + translate([32.5,0,-14]) { rotate([90,0,90]) difference() { cube([63,30,2], center=true); translate([-27.5,6.1,0]) cylinder(h=64, d=3, center=true, $fn=100); + translate([0,-2.5,0]) + cube([20,20,5], center=true); } + // Rod Holder + /*** + if(!show_gimbal_b) { + if(show_right && show_left) { + translate([32,-27.5,6]) + rotate([0,90,0]) + difference() { + cylinder(h=62, d=10.5, center=true, $fn=100); + cylinder(h=69, d=2, center=true, $fn=100); + + // Small Gaps between the Rods + translate([0,0,0]) + rotate([0,0,0]) + cube([20,20,60], center=true); + + } + } + } + ***/ + + if((show_left) && (!show_right)) { + translate([32,-27.5,6]) + rotate([0,90,0]) + difference() { + cylinder(h=62, d=10.5, center=true, $fn=100); + cylinder(h=69, d=2, center=true, $fn=100); + + // Small Gaps between the Rods + translate([0,0,1]) + rotate([0,0,0]) + cube([20,20,62], center=true); + + } + } + + if((!show_left) && (show_right)) { + translate([32,-27.5,6]) + rotate([0,90,0]) + difference() { + cylinder(h=62, d=10.5, center=true, $fn=100); + cylinder(h=69, d=2, center=true, $fn=100); + + // Small Gaps between the Rods + translate([0,0,1]) + rotate([0,0,0]) + cube([20,20,62], center=true); + + } + } + } + // Bottom translate([0,-32.5,-14]) - rotate([90,0,0]) - cube([67,30,2], center=true); + rotate([90,0,0]) { + difference() { + cube([67,30,2], center=true); + + translate([-22,9,0]) + cylinder(h=8, d=1.5, center=true, $fn=100); + + translate([-22,-6,0]) + cylinder(h=8, d=1.5, center=true, $fn=100); + + translate([18,-6,0]) + cylinder(h=8, d=1.5, center=true, $fn=100); + + translate([18,9,0]) + cylinder(h=8, d=1.5, center=true, $fn=100); + } + } // Top translate([0,32.5,-14]) - rotate([90,0,0]) - cube([67,30,2], center=true); + rotate([90,0,0]) { + difference() { + cube([67,30,2], center=true); + + translate([-22,9,0]) + cylinder(h=8, d=1.5, center=true, $fn=100); + + translate([-22,-6,0]) + cylinder(h=8, d=1.5, center=true, $fn=100); + + translate([18,-6,0]) + cylinder(h=8, d=1.5, center=true, $fn=100); + + translate([18,9,0]) + cylinder(h=8, d=1.5, center=true, $fn=100); + } + } difference() { translate([0,0,0]) @@ -900,81 +910,67 @@ module gimbal_unit_face() { translate([27.25,-27.25,0]) rotate([0,0,0]) cylinder(h=5,d=5.6, center=true, $fn=round_quality); - /* - translate([0,0,0]) - rotate([0,0,0]) - cube([77,51,4], center=true); - */ } } - // Just a ruler - /*** - translate([-13.9,-44.4]) - cube([100,10,10], center=true); - ***/ - - // Screw Holders - // Top Left - /********** - translate([70.5,7.5,-13]) - difference() { - cylinder(h=27, d=4, center=true, $fn=round_quality); - cylinder(h=33, d=1.5, center=true, $fn=round_quality); - } - - // Top Right - translate([-55.5,7.5,-13]) - difference() { - cylinder(h=27, d=4, center=true, $fn=round_quality); - cylinder(h=33, d=1.5, center=true, $fn=round_quality); - } - - // Bottom Left - translate([70.5,-57.5,-13]) + if(!show_gimbal_u) { + // Back cover... difference() { - cylinder(h=27, d=4, center=true, $fn=round_quality); - cylinder(h=33, d=1.5, center=true, $fn=round_quality); - } - - // Bottom Right - translate([-55.5,-57.5,-13]) - difference() { - cylinder(h=27, d=4, center=true, $fn=round_quality); - cylinder(h=33, d=1.5, center=true, $fn=round_quality); + back_cover_slim(); + + translate([39,4.5,-38]) + rotate([45,0,0]) + cube([66,40,6], center=true); + + translate([39,-60.4,-32.3]) + rotate([-45,0,0]) + cube([65,40,6], center=true); + + translate([69,-25,-35.3]) + rotate([0,-36,0]) + cube([12,67,6], center=true); } - *******/ + } } +module back_cover_slim() { + translate([34,-25,-35.5]) + cube([55,55,2], center=true); + translate([39,4.5,-32.3]) + rotate([45,0,0]) + cube([66,10,2], center=true); + translate([39,-54.5,-32.3]) + rotate([-45,0,0]) + cube([65,10,2], center=true); + translate([66,-25,-32.3]) + rotate([0,-36,0]) + cube([12,67,2], center=true); + translate([5.5,-25,-32.3]) + rotate([0,90,0]) + cube([8.4,67,2], center=true); +} -// module roundedcube(size = [1, 1, 1], center = false, radius = 0.5, apply_to = "all") { module m5_body() { + translate([0,0,-1]) difference() { if(!draft) { - rounded_corner_cube(8, [56.6,56.6,18]); + rounded_corner_cube(8, [56.6,56.6,17.5]); } else { - roundedcube([56.6,56.6,18], center = true, 0.5); + roundedcube([56.6,56.6,17.5], center = true, 0.5); } // cube([50.6, 50.6, 25], center=true); if(!draft) { - rounded_corner_cube(8, [50.6,50.6,18]); + rounded_corner_cube(8, [50.6,50.6,17.5]); } else { - roundedcube([50.6,50.6,18], center = true, 0.5); + roundedcube([50.6,50.6,17.5], center = true, 0.5); } translate([0,0,1]) if(!draft) { - rounded_corner_cube(8, [54.6,54.6,18]); + rounded_corner_cube(8, [54.6,54.6,17.5]); } else { - roundedcube([54.6,54.6,18], center = true); + roundedcube([54.6,54.6,17.5], center = true); } - // Reset Button - /***** - translate([-16,-30,0]) - rotate([90,0,0]) - cylinder(h=10, d=8, center=true, $fn=round_quality); - *****/ - // Power Button translate([25,13,0]) rotate([90,90,90]) @@ -985,9 +981,42 @@ module m5_body() { rotate([0,90,90]) cube([4,18.5,10], center=true); + // Speaker Holes + translate([-25,11,0]) + rotate([90,0,90]) + cylinder(h=10, d=3, center=true, $fn=round_quality); + translate([-25,5,0]) + rotate([90,0,90]) + cylinder(h=10, d=3, center=true, $fn=round_quality); + translate([-25,-1,0]) + rotate([90,0,90]) + cylinder(h=10, d=3, center=true, $fn=round_quality); + translate([-25,-7,0]) + rotate([90,0,90]) + cylinder(h=10, d=3, center=true, $fn=round_quality); + translate([-25,-13,0]) + rotate([90,0,90]) + cylinder(h=10, d=3, center=true, $fn=round_quality); } + // Center Holder + translate([0,-31.5,4.3]) + rotate([0,0,0]) { + difference() { + cube([58,8,28], center=true); + + // Screw Holders + translate([20,-3,9]) + rotate([90,0,0]) + cylinder(h=10, d=2, center=true, $fn=round_quality); + translate([-20,-3,9]) + rotate([90,0,0]) + cylinder(h=10, d=2, center=true, $fn=round_quality); + } + } + // Center Rod + /**** translate([0,-32.5,0]) rotate([0,90,0]) difference() { @@ -998,41 +1027,36 @@ module m5_body() { translate([0,0,28]) rotate([0,0,0]) cube([20,20,0.5], center=true); + translate([0,0,30.7]) + rotate([0,0,0]) + cube([20,20,5], center=true); translate([0,0,-28]) rotate([0,0,0]) cube([20,20,0.5], center=true); + translate([0,0,-30.7]) + rotate([0,0,0]) + cube([20,20,5], center=true); } - - // Battery base top - translate([0,-5,18]) - rotate([0,0,0]) + ***/ + // Bottom HOOK + rotate([0,0,0]) { + translate([0,-35,-7.2]) { difference() { - cube([60,67,1], center=true); - - // Side hole for Throttle, Yaw, Pitch and Roll connectors - translate([16,3,0]) - cube([15,55,2], center=true); - - // Hole for Power input - translate([0,-19.5,0]) - cube([10,10,2], center=true); + rotate([90,0,0]) + cube([10,5,5], center=true); + translate([0,-2,0]) + cylinder(h=6, d=5, center=true, $fn=round_quality); } - - // Battery base top side bottom - translate([0,-38,11]) - rotate([90,0,0]) - cube([60,20,1], center=true); - - // Battery base top side top - translate([0,28,14]) - rotate([90,0,0]) + translate([0,3.5,0]) + cube([10,5,5], center=true); + translate([0,-3,0]) difference() { - cube([60,10,1], center=true); - - translate([0,-4,0]) - cylinder(h=4, d=10, center=true, $fn=round_quality); + cylinder(h=5, d=10, center=true, $fn=round_quality); + cylinder(h=6, d=5, center=true, $fn=round_quality); } + } + } } module rounded_corner_cube(diameter, dimension) { diff --git a/README.md b/README.md index 67a9ffe..ec61824 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ ESP32 Dev Pinout: U2_TXD / GPIO17 | [ ] [ ] | GPIO26 / ADC2_9 / DAC2 V_SPI_CS0 / GPIO5 | [ ] ___________ [ ] | GPIO25 / ADC2_8 / DAC1 SCK / V_SPI_CLK / GPIO18 | [ ] | | [ ] | GPIO33 / ADC1_5 / Touch8 / XTAL32 - U0_CTS / MSIO / V_SPI_Q / GPIO19 | [ ] | | [ ] | GPIO32 / ADC1_4 / Touch9 / XTAL32 + U0_CTS / MISO / V_SPI_Q / GPIO19 | [ ] | | [ ] | GPIO32 / ADC1_4 / Touch9 / XTAL32 SDA / V_SPI_HD / GPIO21 | [ ] | | [ ] | GPIO35 / ADC1_7 CLK2 / U0_RXD / GPIO3 | [ ] | | [ ] | GPIO34 / ADC1_6 CLK3 / U0_TXD / GPIO1 | [ ] | | [ ] | GPIO39 / ADC1_3 / SensVN @@ -64,3 +64,14 @@ ESP32 Dev Pinout: # REF: Pinout and labels - https://docs.m5stack.com/en/core/core2_for_aws MP3 Sound generator - https://ttsmp3.com/ + +GPIO35 - Throttle +GPIO36 - Yaw +GPIO32 - Pitch +GPIO33 - Roll + +GPIO27 - CSN - BLUE +GPIO19 - CE - WHITE + - SCK - GREEN + - MOSI - YELLOW + - MISO - RED diff --git a/platformio.ini b/platformio.ini index 05a619e..9d5610a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -18,3 +18,4 @@ board_build.partitions = bert2M_fat12M_16MB.csv lib_deps = m5stack/M5Core2@^0.1.0 lorol/LittleFS_esp32@^1.0.6 + lemmingdev/ESP32-BLE-Gamepad@^0.3.4 diff --git a/src/BLE.cpp b/src/BLE.cpp new file mode 100644 index 0000000..ee495b3 --- /dev/null +++ b/src/BLE.cpp @@ -0,0 +1,51 @@ +#include "BLE.h" + +BleGamepad bleGamepad; + +BLE::BLE(void) { + updated = true; +} + +void BLE::begin(void) { + updated = true; + ble_begin = true; +} + + +void BLE::end(void) { + ble_begin = false; + ble_started = false; + + Serial.printf("BLEGamepad is disconnected"); + bleGamepad.end(); +} + + +void BLE::update(void) { + // Starts to connect when receive this... + if(ble_begin) { + if(!ble_started) { + Serial.printf("Starting BLEGamepad."); + bleGamepad.begin(); + Serial.printf("BLEGamepad OK"); + ble_started = true; + } + + + if(bleGamepad.isConnected()) { + if((uint32_t)(millis() - last_updated) > 30) { + int16_t throttle = map(inputs.throttle, 0, 4096, -32767, 32767); // Throttle + int16_t yaw = map(inputs.yaw, 0, 4096, -32767, 32767); // Yaw + int16_t pitch = map(inputs.pitch, 0, 4096, -32767, 32767); // Pitch + int16_t roll = map(inputs.roll, 0, 4096, -32767, 32767); // Roll + + bleGamepad.setAxes(yaw, throttle, roll, pitch, 0, 0, DPAD_CENTERED); + + last_updated = millis(); + // Serial.printf("Sent\n"); + } + } + } +} + +BLE ble; diff --git a/src/BLE.h b/src/BLE.h new file mode 100644 index 0000000..04fb17b --- /dev/null +++ b/src/BLE.h @@ -0,0 +1,25 @@ +#ifndef _BLE_H +#define _BLE_H + +#include +#include +#include +#include "Inputs.h" + +class BLE { + public: + bool ble_begin = false; + bool updated = false; + bool ble_started = false; + + BLE(void); + void begin(void); + void end(void); + void update(void); + + private: + uint32_t last_updated = 0; +}; + +extern BLE ble; +#endif diff --git a/src/BLEGamepad.cpp b/src/BLEGamepad.cpp new file mode 100644 index 0000000..173e85d --- /dev/null +++ b/src/BLEGamepad.cpp @@ -0,0 +1,61 @@ +#include "BLEGamepad.h" + +BLEGamepad::BLEGamepad(void) { + updated = true; +} + +void BLEGamepad::begin(void) { + updated = true; +} + + +void BLEGamepad::show(TFT_eSprite *m) { + if(!ble_begin) { + ble_begin = true; + ble.begin(); + } + + if((uint32_t) (millis() - last_updated) > 50) { + updated = true; + } + + if(updated) { + m->fillRect(0, 0, 320, 240, BLACK); + m->setTextColor(WHITE, BLACK); + m->setTextSize(2); + m->setCursor(0,0); + m->print(String(inputs.throttle)); + m->setCursor(0,16); + m->print(String(inputs.yaw)); + m->setCursor(0,32); + m->print(String(inputs.pitch)); + m->setCursor(0,48); + m->print(String(inputs.roll)); + + m->setCursor(64,64); + m->print("BLE GAMEPAD"); + + m->pushSprite(0,0); + + updated = false; + last_updated = millis(); + } + + + // Key Input Handler + if(M5.BtnC.wasPressed()) { + if(ble_begin) { + ble_begin = false; + ble.end(); + } + + screen.current_screen = SCREEN_MENU; + screen.updated = true; + } + + // Temporary connect from here... + if(M5.BtnA.wasPressed()) { + } +} + +BLEGamepad blegamepad; diff --git a/src/BLEGamepad.h b/src/BLEGamepad.h new file mode 100644 index 0000000..676e99c --- /dev/null +++ b/src/BLEGamepad.h @@ -0,0 +1,24 @@ +#ifndef _BLEGAMEPAD_H +#define _BLEGAMEPAD_H + +#include +#include +#include "BLE.h" +#include "Inputs.h" +#include "Screen.h" + +class BLEGamepad { + public: + bool ble_begin = false; + bool updated = false; + + BLEGamepad(void); + void begin(void); + void show(TFT_eSprite *m); + + private: + uint32_t last_updated = 0; +}; + +extern BLEGamepad blegamepad; +#endif diff --git a/src/GimbalGraph.cpp b/src/GimbalGraph.cpp new file mode 100644 index 0000000..7349516 --- /dev/null +++ b/src/GimbalGraph.cpp @@ -0,0 +1,5 @@ +#include "GimbalGraph.h" + +GimbalGraph::GimbalGraph(void) { +} + diff --git a/src/GimbalGraph.h b/src/GimbalGraph.h new file mode 100644 index 0000000..4df5ec3 --- /dev/null +++ b/src/GimbalGraph.h @@ -0,0 +1,14 @@ +#ifndef _GIMBAL_GRAPH_H +#define _GIMBAL_GRAPH_H + +#include + +class GimbalGraph { + public: + GimbalGraph(void); + + private: +}; + +extern GimbalGraph gimbalgraph; +#endif diff --git a/src/Inputs.cpp b/src/Inputs.cpp new file mode 100644 index 0000000..e04e8fd --- /dev/null +++ b/src/Inputs.cpp @@ -0,0 +1,259 @@ +#include "Inputs.h" + +Inputs::Inputs(void) { +} + + +void Inputs::begin(void) { + throttle_raw = 0; + yaw_raw = 0; + pitch_raw = 0; + roll_raw = 0; + + // Prepare the storage engine for TYPR + for(int i = 0; i < MEDIAN_TOTAL; i++) { + throttle_pool[i] = 0; + yaw_pool[i] = 0; + pitch_pool[i] = 0; + roll_pool[i] = 0; + } +} + + +void Inputs::read(void) { + throttle_raw = analogRead(THROTTLE_PIN); + yaw_raw = analogRead(YAW_PIN); + pitch_raw = analogRead(PITCH_PIN); + roll_raw = analogRead(ROLL_PIN); + + throttle = pool_insert(THROTTLE, throttle_raw); + yaw = pool_insert(YAW, yaw_raw); + pitch = pool_insert(PITCH, pitch_raw); + roll = pool_insert(ROLL, roll_raw); +} + + +/* + * median_get: + * To get the median from the data depending on the median_type + * + * E.g.: + * retval = median_get(THROTTLE); + */ +uint16_t Inputs::median_get(uint8_t median_type) { + bool inserted = false; + + uint16_t median_tmp[MEDIAN_TOTAL]; + + // Loop through the variable to determine position to insert + // [ 12, 32, 4 ,0, 50, 2, 10, 10, 5, 20, 0 ] + /* + [ 12 ] + [ 12, 32 ] + [ 4, 12, 32 ] + [ 0, 4, 12, 32 ] + [ 0, 4, 12, 32, 50 ] + [ 0, 2, 4, 12, 32, 50 ] + + */ + + // Initial + uint16_t temp_val = 0; + uint16_t total_insert = 1; + + // Search on type + if(median_type == THROTTLE) { + median_tmp[0] = throttle_pool[0]; + } else if(median_type == YAW) { + median_tmp[0] = yaw_pool[0]; + } else if(median_type == PITCH) { + median_tmp[0] = pitch_pool[0]; + } else if(median_type == ROLL) { + median_tmp[0] = roll_pool[0]; + } + + // Loop insert and sort + for(int raw_count = 1; raw_count < MEDIAN_TOTAL; raw_count++) { + inserted = false; + + if(median_type == THROTTLE) { + temp_val = throttle_pool[raw_count]; + } else if(median_type == YAW) { + temp_val = yaw_pool[raw_count]; + } else if(median_type == PITCH) { + temp_val = pitch_pool[raw_count]; + } else if(median_type == ROLL) { + temp_val = roll_pool[raw_count]; + } + + for(int median_count = 0; median_count < total_insert; median_count++) { + if(!inserted) { + + if(temp_val < median_tmp[median_count]) { + inserted = true; + + // Reverse copy and insert + for(int median_reverse = total_insert + 1; median_reverse > median_count; median_reverse--) { + median_tmp[median_reverse] = median_tmp[median_reverse - 1]; + } + + // Insert the detected + median_tmp[median_count] = temp_val; + + // Increase total insertion + total_insert++; + } + } + } + + // Nothing was inserted... so put at the last. + if(!inserted) { + median_tmp[total_insert++] = temp_val; + } + } + + // Return the result + // return median_tmp[MEDIAN_POS]; + // Using RC dead band way....**** NEED TO IMPROvE!! + if(median_type == THROTTLE) { + if(throttle > median_tmp[MEDIAN_POS]) { + if(throttle - median_tmp[MEDIAN_POS] > RC_DEADBAND) { + return median_tmp[MEDIAN_POS]; + } else { + if(median_tmp[MEDIAN_POS] - throttle > RC_DEADBAND) { + return median_tmp[MEDIAN_POS]; + } else { + return throttle; + } + } + } + } else if(median_type == YAW) { + if(yaw > median_tmp[MEDIAN_POS]) { + if(yaw - median_tmp[MEDIAN_POS] > RC_DEADBAND) { + return median_tmp[MEDIAN_POS]; + } else { + if(median_tmp[MEDIAN_POS] - yaw > RC_DEADBAND) { + return median_tmp[MEDIAN_POS]; + } else { + return yaw; + } + } + } + } else if(median_type == PITCH) { + if(pitch > median_tmp[MEDIAN_POS]) { + if(pitch - median_tmp[MEDIAN_POS] > RC_DEADBAND) { + return median_tmp[MEDIAN_POS]; + } else { + if(median_tmp[MEDIAN_POS] - pitch > RC_DEADBAND) { + return median_tmp[MEDIAN_POS]; + } else { + return pitch; + } + } + } + } else if(median_type == ROLL) { + if(roll > median_tmp[MEDIAN_POS]) { + if(roll - median_tmp[MEDIAN_POS] > RC_DEADBAND) { + return median_tmp[MEDIAN_POS]; + } else { + if(median_tmp[MEDIAN_POS] - roll > RC_DEADBAND) { + return median_tmp[MEDIAN_POS]; + } else { + return roll; + } + } + } + } + +} + + +uint16_t Inputs::throttle_insert(uint16_t val) { + // Insert to the array...at the last + for(int i = 1; i < MEDIAN_TOTAL; i++) + // Shift to left + throttle_pool[i - 1] = throttle_pool[i]; + + throttle_pool[MEDIAN_TOTAL - 1] = val; + + // Find median.... + return median_get(THROTTLE); +} + + +uint16_t Inputs::yaw_insert(uint16_t val) { + // Insert to the array...at the last + for(int i = 1; i < MEDIAN_TOTAL; i++) + // Shift to left + yaw_pool[i - 1] = yaw_pool[i]; + + yaw_pool[MEDIAN_TOTAL - 1] = val; + + // Find median.... + return median_get(YAW); +} + + +uint16_t Inputs::pitch_insert(uint16_t val) { + // Insert to the array...at the last + for(int i = 1; i < MEDIAN_TOTAL; i++) + // Shift to left + pitch_pool[i - 1] = pitch_pool[i]; + + pitch_pool[MEDIAN_TOTAL - 1] = val; + + // Find median.... + return median_get(PITCH); +} + + +uint16_t Inputs::roll_insert(uint16_t val) { + // Insert to the array...at the last + for(int i = 1; i < MEDIAN_TOTAL; i++) + // Shift to left + roll_pool[i - 1] = roll_pool[i]; + + roll_pool[MEDIAN_TOTAL - 1] = val; + + // Find median.... + return median_get(ROLL); +} + + +/* + * pool_insert: + * To insert the data into the median pool depending on type of the variable + * + * E.g.: + * throttle_value = pool_insert(THROTTLE); + */ +uint16_t Inputs::pool_insert(uint8_t pool_type, uint16_t val) { + // Insert to the array...at the last of the array + for(int i = 1; i < MEDIAN_TOTAL; i++) { + // Shift to left + if(pool_type == THROTTLE) { + throttle_pool[i - 1] = throttle_pool[i]; + } else if(pool_type == YAW) { + yaw_pool[i - 1] = yaw_pool[i]; + } else if(pool_type == PITCH) { + pitch_pool[i - 1] = pitch_pool[i]; + } else if(pool_type == ROLL) { + roll_pool[i - 1] = roll_pool[i]; + } + } + + // Find median.... + if(pool_type == THROTTLE) { + throttle_pool[MEDIAN_TOTAL - 1] = val; + } else if(pool_type == YAW) { + yaw_pool[MEDIAN_TOTAL - 1] = val; + } else if(pool_type == ROLL) { + roll_pool[MEDIAN_TOTAL - 1] = val; + } else if(pool_type == PITCH) { + pitch_pool[MEDIAN_TOTAL - 1] = val; + } + return median_get(pool_type); +} + + +Inputs inputs; diff --git a/src/Inputs.h b/src/Inputs.h new file mode 100644 index 0000000..b077a6e --- /dev/null +++ b/src/Inputs.h @@ -0,0 +1,56 @@ +#ifndef _INPUTS_H +#define _INPUTS_H + +#include + +#define THROTTLE_PIN 35 +#define YAW_PIN 36 +#define PITCH_PIN 32 +#define ROLL_PIN 33 + +#define MEDIAN_TOTAL 11 +#define MEDIAN_POS MEDIAN_TOTAL/2 + +// For RC Deadband +#define RC_DEADBAND 5 + +enum input_names { + THROTTLE = 0, + YAW, + PITCH, + ROLL +}; + +class Inputs { + public: + uint16_t throttle = 0; + uint16_t yaw = 0; + uint16_t pitch = 0; + uint16_t roll = 0; + + Inputs(void); + void begin(void); + void read(void); + + private: + uint16_t throttle_pool[MEDIAN_TOTAL]; + uint16_t yaw_pool[MEDIAN_TOTAL]; + uint16_t pitch_pool[MEDIAN_TOTAL]; + uint16_t roll_pool[MEDIAN_TOTAL]; + uint16_t tmp_median_store[MEDIAN_TOTAL]; + + uint16_t throttle_raw; + uint16_t yaw_raw; + uint16_t pitch_raw; + uint16_t roll_raw; + + uint16_t median_get(uint8_t median_type); + uint16_t throttle_insert(uint16_t val); + uint16_t yaw_insert(uint16_t val); + uint16_t pitch_insert(uint16_t val); + uint16_t roll_insert(uint16_t val); + uint16_t pool_insert(uint8_t pool_type, uint16_t val); +}; + +extern Inputs inputs; +#endif diff --git a/src/Screen.cpp b/src/Screen.cpp index fac842d..7e44a93 100644 --- a/src/Screen.cpp +++ b/src/Screen.cpp @@ -20,6 +20,9 @@ void Screen::begin(void) { */ // Initial value updated = true; + + stickcalibration.begin(); + M5.Lcd.fillScreen(BLACK); mainscreen_buffer.createSprite(320, 240); } @@ -36,6 +39,10 @@ void Screen::update(void) { menu_reboot(); } else if(current_screen == SCREEN_MENU_POWEROFF) { menu_poweroff(); + } else if(current_screen == SCREEN_MENU_BLUETOOTH) { + blegamepad.show(&mainscreen_buffer); + } else if(current_screen == SCREEN_MENU_STICK_CALIBRATION) { + stickcalibration.mydebug(&mainscreen_buffer); } last_screen_update = millis(); @@ -171,6 +178,9 @@ void Screen::menu(void) { current_screen = SCREEN_MENU_POWEROFF; } else if(current_menu == MENU_BLUETOOTH) { current_screen = SCREEN_MENU_BLUETOOTH; + } else if(current_menu == MENU_STICK_CALIBRATION) { + current_screen = SCREEN_MENU_STICK_CALIBRATION; + stickcalibration.updated = true; } updated = true; } diff --git a/src/Screen.h b/src/Screen.h index 20ec59b..4c4d6b5 100644 --- a/src/Screen.h +++ b/src/Screen.h @@ -3,7 +3,9 @@ #include #include +#include "BLEGamepad.h" #include "Speak.h" +#include "StickCalibration.h" #define REFRESH_TIME 1 #define INTRO_TIME 100 @@ -19,7 +21,8 @@ enum screen_names { SCREEN_MENU, SCREEN_MENU_REBOOT, SCREEN_MENU_POWEROFF, - SCREEN_MENU_BLUETOOTH + SCREEN_MENU_BLUETOOTH, + SCREEN_MENU_STICK_CALIBRATION }; enum menu_items { @@ -46,6 +49,9 @@ enum selection_choice_yesno { class Screen { public: + uint8_t current_screen = SCREEN_INTRO; + bool updated = false; + Screen(void); void begin(void); void intro(void); @@ -56,9 +62,7 @@ class Screen { void update(void); private: - uint8_t current_screen = SCREEN_INTRO; uint32_t last_screen_update = 0; - bool updated = false; }; extern Screen screen; diff --git a/src/StickCalibration.cpp b/src/StickCalibration.cpp new file mode 100644 index 0000000..0ca9461 --- /dev/null +++ b/src/StickCalibration.cpp @@ -0,0 +1,44 @@ +#include "StickCalibration.h" + +StickCalibration::StickCalibration(void) { + updated = true; +} + +void StickCalibration::begin(void) { + updated = true; +} + + +void StickCalibration::mydebug(TFT_eSprite *m) { + if((uint32_t) (millis() - last_updated) > 50) { + updated = true; + } + + if(updated) { + m->fillRect(0, 0, 320, 240, BLACK); + m->setTextColor(WHITE, BLACK); + m->setTextSize(2); + m->setCursor(0,0); + m->print(String(inputs.throttle)); + m->setCursor(0,16); + m->print(String(inputs.yaw)); + m->setCursor(0,32); + m->print(String(inputs.pitch)); + m->setCursor(0,48); + m->print(String(inputs.roll)); + + m->pushSprite(0,0); + + updated = false; + last_updated = millis(); + } + + + // Key Input Handler + if(M5.BtnC.wasPressed()) { + screen.current_screen = SCREEN_MENU; + screen.updated = true; + } +} + +StickCalibration stickcalibration; diff --git a/src/StickCalibration.h b/src/StickCalibration.h new file mode 100644 index 0000000..2a5722b --- /dev/null +++ b/src/StickCalibration.h @@ -0,0 +1,21 @@ +#ifndef _STICK_CALIBRATION_H +#define _STICK_CALIBRATION_H + +#include +#include +#include "Inputs.h" +#include "Screen.h" + +class StickCalibration { + public: + StickCalibration(void); + void begin(void); + void mydebug(TFT_eSprite *m); + bool updated = false; + + private: + uint32_t last_updated = 0; +}; + +extern StickCalibration stickcalibration; +#endif diff --git a/src/main.cpp b/src/main.cpp index 51d943c..23e2209 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,9 +23,11 @@ void setup() { storage.begin(); customwifi.begin(); + inputs.begin(); web.begin(); speak.welcome(); + // Task Creation xTaskCreatePinnedToCore( taskScreen, @@ -39,7 +41,7 @@ void setup() { xTaskCreatePinnedToCore( taskWeb, - "TaskWeb", // Name of the process + "TaskWeb", // Name of the process 4096, // This stack size can be checked & adjusted by reading the Stack Highwater NULL, 4, // Priority @@ -57,6 +59,26 @@ void setup() { CPU_0 ); + xTaskCreatePinnedToCore( + taskInput, + "TaskInput", // Name of the process + 8192, // This stack size can be checked & adjusted by reading the Stack Highwater + NULL, + 4, // Priority + NULL, + CPU_0 + ); + + xTaskCreatePinnedToCore( + taskBLE, + "TaskBLE", // Name of the process + 8192, // This stack size can be checked & adjusted by reading the Stack Highwater + NULL, + 4, // Priority + NULL, + CPU_0 + ); + } @@ -101,3 +123,23 @@ void taskWeb(void *pvParameters) { vTaskDelay(100); } } + + +void taskInput(void *pvParameters) { + (void) pvParameters; + + for(;;) { + inputs.read(); + vTaskDelay(10); + } +} + + +void taskBLE(void *pvParameters) { + (void) pvParameters; + + for(;;) { + ble.update(); + vTaskDelay(10); + } +} diff --git a/src/main.h b/src/main.h index 03f6483..a6cbdaf 100644 --- a/src/main.h +++ b/src/main.h @@ -6,6 +6,8 @@ #define CPU_0 0 #include +#include "Inputs.h" +#include "BLE.h" #include "Speak.h" #include "Screen.h" #include "Storage.h" @@ -16,5 +18,7 @@ void taskScreen(void *pvParameters); void taskSpeak(void *pvParameters); void taskWeb(void *pvParameters); +void taskInput(void *pvParameters); +void taskBLE(void *pvParameters); #endif