From 9e3679b6dd5d07b92af2d59a5e41dd78db4fba7f Mon Sep 17 00:00:00 2001 From: Dejvino Date: Sat, 28 Aug 2021 18:03:33 +0200 Subject: [PATCH] First version --- BatteryBank.scad | 83 ++++++++++++++++++++++++++ Main.scad | 67 +++++++++++++++++++++ SensorBox.scad | 127 ++++++++++++++++++++++++++++++++++++++++ ServoGauge.scad | 143 +++++++++++++++++++++++++++++++++++++++++++++ Vitamins.scad | 22 +++++++ geiger_counter.ino | 119 +++++++++++++++++++++++++++++++++++++ 6 files changed, 561 insertions(+) create mode 100644 BatteryBank.scad create mode 100644 Main.scad create mode 100644 SensorBox.scad create mode 100644 ServoGauge.scad create mode 100644 Vitamins.scad create mode 100644 geiger_counter.ino diff --git a/BatteryBank.scad b/BatteryBank.scad new file mode 100644 index 0000000..042ef77 --- /dev/null +++ b/BatteryBank.scad @@ -0,0 +1,83 @@ +include +use +use + +model = 0; + +bank_wall = 2; +bank_inside_size = [94, 19, 19]; +bank_socket_size = [bank_inside_size.x + 2, bank_inside_size.y + 2, 4]; +pcb_size = [20, 19, 1]; +separator_size = [2.5, pcb_size.y - 3, 12.5]; +separator_pos = [bank_inside_size.x/2 - pcb_size.x - 0.2 - separator_size.x/2, -3, -bank_inside_size.z/2 + separator_size.z/2]; +joiner_size = [5, 5, bank_inside_size.z]; +joiner_pos = [0, bank_inside_size.y/2 + bank_wall + joiner_size.y/2, 0]; +joiner_spread = 60; +bank_joiner_screw_diam = 2.2; +window_pos = [bank_inside_size.x/2, 0, 0]; +window_size = [10, bank_inside_size.y - 1.8*2, 12]; + +module bank_inside() { + cube(bank_inside_size, center=true); +} + +module bank_joiner() { + difference() { + cuboid(joiner_size, chamfer=1, edges=EDGES_Z_BK); + down(joiner_size.z/2) cylinder(d=bank_joiner_screw_diam, h=joiner_size.z, $fn=12); + } +} + +module bank() { + difference() { + minkowski() { + cube(bank_inside_size, center=true); + sphere(r=bank_wall, $fn=18); + } + bank_inside(); + translate(window_pos) cube(window_size, center=true); + } + translate(separator_pos) cube(separator_size, center=true); + translate(joiner_pos) { + left(joiner_spread/2) bank_joiner(); + right(joiner_spread/2) bank_joiner(); + } +} + +module bank_divider(socket) { + up(5.5) { + difference() { + down(50) cube([500, 100, 100], center=true); + scale(socket ? 1 : [0.995, 0.97, 0.96]) cube(bank_socket_size, center=true); + } + } +} + +module model_bank_bottom() { + up(bank_wall + bank_inside_size.z/2) + intersection() { + bank(); + bank_divider(socket=true); + } +} + +module model_bank_top() { + up(bank_wall + bank_inside_size.z/2) + difference() { + bank(); + bank_divider(socket=false); + } +} + +if (model == 0) { + model_bank_bottom(); + model_bank_top(); +} + +if (model == 1) { + model_bank_bottom(); +} + +if (model == 2) { + model_bank_top(); +} \ No newline at end of file diff --git a/Main.scad b/Main.scad new file mode 100644 index 0000000..3d45a3e --- /dev/null +++ b/Main.scad @@ -0,0 +1,67 @@ +include +use + +use +use +use +use + +module joiner_box_battery() { + up(9) fwd(35) cube([90, 2, 14], center=true); +} + +module pathway_box_battery() { + up(12) fwd(35) left(38) cube([12, 10, 6], center=true); + up(12) fwd(32) right(10) cube([90, 2, 6], center=true); +} + +module pathway_box_servo() { + up(8) fwd(0) right(58) cube([12, 45, 6], center=true); +} + +model = 0; +function isModel(m) = (model == 0 || m == model); + +sb_x = 72; +pb_x = 0; +pb_y = 47; + +if (isModel(1)) { + difference() { + union() { + difference() { + model_box(); + right(sb_x) model_servo_box(); + } + joiner_box_battery(); + fwd(pb_y) right(pb_x) zrot(180) model_bank_bottom(); + fwd(0) right(sb_x) { + difference() { + model_servo_box_bottom(); + up(12) fwd(get_servo_box_size().y/2 - 4) { + left(6) xrot(90) { + %switch(); + switch(); + } + right(6) xrot(90) { + %switch(); + switch(); + } + right(18) xrot(90) { + %switch(); + switch(); + } + } + } + } + } + pathway_box_battery(); + pathway_box_servo(); + } +} +if (isModel(2)) { + fwd(pb_y) right(pb_x) zrot(180) model_bank_top(); +} +if (isModel(3)) { + right(sb_x) model_servo_box_top(); +} diff --git a/SensorBox.scad b/SensorBox.scad new file mode 100644 index 0000000..3fc15d1 --- /dev/null +++ b/SensorBox.scad @@ -0,0 +1,127 @@ +include +use +use + +xray = false; +model = 1; + +pcb_pos = [0, 0, 6]; +pcb_size = [108, 63, 2]; +sensor_size = [pcb_size.x, pcb_size.y, 18 + 2]; +pcb_stand_diam = 5.2; +pcb_hole_diam = 3; + +box_wall = 2; +box_wall_rounding = 1; +box_core_size = [sensor_size.x + 9 + box_wall*2, sensor_size.y + 3 + box_wall*2, sensor_size.z + box_wall*1.8]; +/*box_switchboard_size = [16, box_core_size.y, box_core_size.z]; +box_switchboard_chamber_pos = [(box_core_size.x + box_switchboard_size.x)/2 - 2*box_wall, 0, box_switchboard_size.z/2]; +box_switchboard_chamber_size = [box_switchboard_size.x + box_wall, box_switchboard_size.y - box_wall*2, box_switchboard_size.z - box_wall*3];*/ +box_cavity_size = [sensor_size.x + 4, sensor_size.y + 1, sensor_size.z + box_wall*2]; +box_lid_pos = [0, 0, sensor_size.z]; +box_lid_size = [115, 67.5, 1.7]; +box_pos = [/*box_switchboard_size.x/2*/0, 0, 0]; +box_size = [box_core_size.x /*+ box_switchboard_size.x*/, box_core_size.y, box_core_size.z]; + +function get_servo_box_size() = box_size; + +module foreach_mount_hole() { + for (x = [0:1]) { + for (y = [0:1]) { + left((1-2*x)*(pcb_size.x/2 - pcb_stand_diam/2 - pcb_hole_diam/4 + 0.5)) + fwd((1-2*y)*(pcb_size.y/2 - pcb_stand_diam/2 - pcb_hole_diam/4)) + children(); + } + } +} + +module pcb_mount_holes() { + foreach_mount_hole() { + cylinder(h=sensor_size.z, d=pcb_hole_diam, $fn=10); + } +} + +module pcb_stands() { + foreach_mount_hole() { + cylinder(h=sensor_size.z, d=pcb_stand_diam + 1.8, $fn=15); + cylinder(h=sensor_size.z + 5.6, d=pcb_hole_diam + 1.0, $fn=10); + } +} + +module sensor_connectors_power() { + pwr_diam=10; + fwd(pcb_size.y/2 - 22.3) right(pcb_size.x/2 - 2) up(pcb_pos.z + 8.2) zrot(-90) xrot(-90) cylinder(h=50, d1=pwr_diam, d2=pwr_diam+2, $fn=20); +} + +module sensor_connectors_space() { + jack_diam=12; + fwd(pcb_size.y/2 - 15.5) left(pcb_size.x/2 - 2) up(pcb_pos.z + 4) zrot(-90) xrot(90) cylinder(h=/*20*/7, d=jack_diam, $fn=20); + + //sensor_connectors_power(); + + /*switch_size=[20, 8, 3.8]; + back(pcb_size.y/2 - 28.2) right(pcb_size.x/2 + switch_size.x/2 - 2) up(pcb_pos.z + switch_size.z/2 + 2.3) cube(switch_size, center=true);*/ + + /*conn_size=[20, 8, 3.8]; + back(3) left(pcb_size.x/2 + conn_size.x/2 - 2) up(pcb_pos.z + conn_size.z/2 + 2.3) cube(conn_size, center=true);*/ +} + +module sensor() { + difference() { + translate(pcb_pos) up(pcb_size.z/2) + cube(pcb_size, center=true); + pcb_mount_holes(); + } + pcb_stands(); +} + +module sensor_lid() { + difference() { + translate(box_lid_pos) up(box_lid_size.z/2) + cube(box_lid_size, center=true); + pcb_mount_holes(); + } +} + +// ---- + + +module box() { + difference() { + translate(box_pos) up(box_size.z/2) cuboid(box_size, chamfer=box_wall_rounding); + up(sensor_size.z/2 + box_wall*2.5) cube(box_cavity_size, center=true); + up(box_lid_size.z/2 + box_wall) translate(box_lid_pos) cube(box_lid_size, center=true); + up(box_wall) sensor_connectors_space(); + up(box_wall) pcb_stands(); + up(box_wall) up(sensor_size.z) xrot(180) pcb_stands(); + + /*up(box_size.z - box_wall) { + back(box_size.y/2 - 12) right(box_size.x/2 - 2) switch(); + back(box_size.y/2 - 32) right(box_size.x/2 - 2) switch(); + fwd(box_size.y/2 - 12) right(box_size.x/2 - 2) switch(); + }*/ + //translate(box_switchboard_chamber_pos) cuboid(box_switchboard_chamber_size, chamfer=1); + } +} + +module model_box() { + box(); +} + +// ---- + +if (xray) { + intersection() { + box(); + down(500) left(10) fwd(10) cube([1000, 1000, 1000]); + } +} else { + box(); +} +if (model == 0) { + up(box_wall) union() { + //sensor(); + //sensor_lid(); + %sensor_connectors_space(); + } +} \ No newline at end of file diff --git a/ServoGauge.scad b/ServoGauge.scad new file mode 100644 index 0000000..f52fa73 --- /dev/null +++ b/ServoGauge.scad @@ -0,0 +1,143 @@ +include +use +use + +use +use + +servo_mount_size = [12, 32, 2.5]; +servo_mount_pos = [0, 0, 16]; +servo_mount_hole_diam = 2; +servo_core_size = [12, 23, 22.3]; +servo_gears_size = [servo_core_size.x, servo_core_size.x, 26.5]; +servo_gears_pos = [0, -(servo_core_size.y/2 - servo_gears_size.y/2), 0]; +servo_centergears_size = [servo_core_size.x/2, servo_core_size.x/2, servo_gears_size.z]; +servo_centergears_pos = [0, 0, 0]; +servo_shaft_size = [1, 1, 28.5]; +servo_shaft_pos = servo_gears_pos; +display_pos = [0, 8, servo_core_size.z]; +box_wall = 2; +servo_box_round = 1; +servo_box_size = [40, get_servo_box_size().y, servo_core_size.z + box_wall*2]; +servo_box_chamber = [servo_box_size.x - box_wall*2, servo_box_size.y - box_wall*2, servo_box_size.z - box_wall*2]; +servo_box_chamber_walled = [servo_box_chamber.x + box_wall, servo_box_chamber.y + box_wall, servo_box_chamber.z + box_wall]; +servo_box_pos = [6, 0, servo_box_size.z/2 - box_wall]; +servo_box_socket_size = [servo_box_size.x, servo_box_size.y, 4]; +servo_box_screw_joiner_size = [5, 5, 20]; +servo_box_screw_joiner_pos = [servo_box_size.x/2 + servo_box_screw_joiner_size.x/2, 0, 2]; + +module servo_mount_holes() { + for (i = [0:1]) { + down(servo_mount_size.z) + fwd((1-2*i)*(servo_mount_size.y/2 - servo_mount_hole_diam) + 0.5*(i+1)) + cylinder(h=servo_mount_size.z*4, d=servo_mount_hole_diam, $fn=10); + } +} + +module servo() { + up(servo_core_size.z/2) + cube(servo_core_size, center=true); + + up(servo_mount_size.z/2) translate(servo_mount_pos) + difference() { + cube(servo_mount_size, center=true); + servo_mount_holes(); + } + + translate(servo_gears_pos) cylinder(d=servo_gears_size.x, h=servo_gears_size.z, $fn=30); + translate(servo_centergears_pos) cylinder(d=servo_centergears_size.x, h=servo_centergears_size.z, $fn=20); + + translate(servo_shaft_pos) cylinder(d=servo_shaft_size.x, h=servo_shaft_size.z, $fn=20); +} + +display_needle_length = 15; +module display_mount_holes() { + translate(-servo_shaft_pos) { + #servo_mount_holes(); + } +} +module display() { + angle_max = 180; + angle_gap = 8; + + module display_pie() { + up(1) zrot(-90 + angle_gap/2) + pie_slice(ang=angle_max-angle_gap, l=2, r=display_needle_length); + } + + difference() { + //up(2/2) cube([20, 40, 2], center=true); + + minkowski() { + display_pie(); + cylinder(r=7,h=0.1); + } + up(1.5) display_pie(); + translate(-servo_shaft_pos) { + down(servo_core_size.z) servo(); + } + display_mount_holes(); + } + slices=20; + for (i = [0:slices]) { + zrot(i * (angle_max - angle_gap)/slices + angle_gap/2) fwd(display_needle_length) up(3) scale(i%5==0 ? 1 : 0.5) cube([1, 4, 2], center=true); + } +} + +module servo_box() { + up(box_wall) translate(servo_box_pos) { + difference() { + cuboid(servo_box_size, chamfer=servo_box_round); + cuboid(servo_box_chamber, chamfer=servo_box_round); + } + translate(servo_box_screw_joiner_pos) { + fwd(20) screw_joiner(servo_box_screw_joiner_size, edges=EDGES_Z_RT); + back(20) screw_joiner(servo_box_screw_joiner_size, edges=EDGES_Z_RT); + } + } +} + +module servo_box_divider(socket) { + up(3) { + difference() { + up(50 + servo_box_size.z/2 + 5) cube([500, 100, 100], center=true); + up(-box_wall) translate(servo_box_pos) scale(socket ? 1 : [0.97, 0.99, 0.98]) cube(servo_box_chamber_walled, center=true); + } + } +} + +module model_display() { + up(box_wall) translate(display_pos) display(); +} + +module model_servo_box() { + difference() { + servo_box(); + translate(display_pos) { + down(servo_core_size.z - 2) fwd(servo_gears_pos.y) servo(); + display_mount_holes(); + } + } +} + +module model_servo_box_top() { + //up(box_wall + bank_inside_size.z/2) + intersection() { + model_servo_box(); + servo_box_divider(socket=true); + } + model_display(); +} + +module model_servo_box_bottom() { + //up(box_wall + bank_inside_size.z/2) + difference() { + model_servo_box(); + servo_box_divider(socket=false); + } +} + +translate(display_pos) down(servo_core_size.z - 4) fwd(servo_gears_pos.y) %servo(); + +model_servo_box_top(); +model_servo_box_bottom(); diff --git a/Vitamins.scad b/Vitamins.scad new file mode 100644 index 0000000..3e1a6ae --- /dev/null +++ b/Vitamins.scad @@ -0,0 +1,22 @@ +include +use +use + +switch_body_size = [8, 13, 16]; + +module switch() { + down(switch_body_size.z/2) cube(switch_body_size, center=true); + cylinder(d=6.5, h=8.5); + up(8.5) xrot(15) cylinder(d=2.5, h=10); +} + +switch(); + +module screw_joiner(size, screw_diam=2.2, chamfer=1, edges=EDGES_Z_ALL) { + difference() { + cuboid(size, chamfer=chamfer, edges=edges); + down(size.z/2) cylinder(d=screw_diam, h=size.z, $fn=12); + } +} + +left(20) screw_joiner([5, 5, 10]); diff --git a/geiger_counter.ino b/geiger_counter.ino new file mode 100644 index 0000000..7f88fbf --- /dev/null +++ b/geiger_counter.ino @@ -0,0 +1,119 @@ +/* + * Geiger counter Kit could get on: https://www.aliexpress.com search: geiger counter kit +* -------------------------------------------------------------------------------------- +* WHAT IS CPM? +* CPM (or counts per minute) is events quantity from Geiger Tube you get during one minute. Usually it used to +* calculate a radiation level. Different GM Tubes has different quantity of CPM for background. Some tubes can produce +* about 10-50 CPM for normal background, other GM Tube models produce 50-100 CPM or 0-5 CPM for same radiation level. +* Please refer your GM Tube datasheet for more information. Just for reference here, J305 and SBM-20 can generate +* about 10-50 CPM for normal background. +* -------------------------------------------------------------------------------------- +* HOW TO CONNECT GEIGER KIT? +* The kit 3 wires that should be connected to Arduino UNO board: 5V, GND and INT. PullUp resistor is included on +* kit PCB. Connect INT wire to Digital Pin#2 (INT0), 5V to 5V, GND to GND. Then connect the Arduino with +* USB cable to the computer and upload this sketch. +* + * Author:JiangJie Zhang * If you have any questions, please connect cajoetech@qq.com + * Author:Dejvino + * + * License: MIT License + * + * Please use freely with attribution. Thank you! +*/ + +// include the Servo library +#include +Servo myServo; // create a servo object + +int const PIN_SERVO = 9; +int angle; // variable to hold the angle for the servo motor + +int const PIN_TUBE 2; + +int const PIN_FRESH = LED_BUILTIN; +int freshState = 0; + +#include +//#define LOG_PERIOD 15000 //Logging period in milliseconds, recommended value 15000-60000. +#define LOG_PERIOD 30000 +#define MAX_PERIOD 60000 //Maximum logging period without modifying this sketch + +unsigned long counts; //variable for GM Tube events +unsigned long cpm; //variable for CPM +unsigned int multiplier; //variable for calculation CPM in this sketch +unsigned long previousMillis; //variable for time measurement + +int const subDiv = 60; +int const subTimespan = LOG_PERIOD / subDiv; +int subCounts = 0; +int subTime = 0; + +void tube_impulse(){ //subprocedure for capturing events from Geiger Kit + counts++; +} + +void setup(){ //setup subprocedure + myServo.attach(PIN_SERVO); // attaches the servo on pin 9 to the servo object + myServo.write(angle); + + counts = 0; + cpm = 0; + multiplier = MAX_PERIOD / LOG_PERIOD; //calculating multiplier, depend on your log period + Serial.begin(9600); + attachInterrupt(0, tube_impulse, FALLING); //define external interrupts + + pinMode(PIN_FRESH, OUTPUT); + digitalWrite(PIN_FRESH, LOW); + + delay(500); + myServo.write(0); + delay(1000); + myServo.write(200); + delay(1000); + myServo.write(100); + delay(1000); + myServo.write(0); +} + +void loop(){ //main cycle + unsigned long currentMillis = millis(); + unsigned long timeDiff = currentMillis - previousMillis; + if (freshState == 1 && timeDiff > LOG_PERIOD / 4) { + freshState = 0; + digitalWrite(PIN_FRESH, LOW); + } + if(timeDiff > LOG_PERIOD){ + previousMillis = currentMillis; + cpm = counts * multiplier; + + angle = cpm; + //myServo.write(angle); + + Serial.print("CPM: "); + Serial.println(cpm); + counts = 0; + + digitalWrite(PIN_FRESH, HIGH); + freshState = 1; + + subCounts = 0; + subTime = currentMillis; + } + + int subDiff = currentMillis - subTime; + if (subDiff >= subTimespan) { + subTime = currentMillis; + int subTimeSteps = timeDiff / subTimespan; + subCounts = counts; + int change = (counts * multiplier) - (cpm * subTimeSteps / subDiv); + angle = cpm + change; + if (angle < 0) { angle = 0; } + if (angle > 200) { angle = 200; } + myServo.write(angle); + + Serial.print("R: "); + Serial.print(angle); + Serial.println(); + } +} +