--- /dev/null
+// challenge-bot
+// GNU AGPLv3 (or later at your option)
+// project available at these locations:
+// https://gitorious.org/ozzloy/challenge-bot
+// https://github.com/waynegramlich/challenge-bot
+
+// use 10 ish for development, 60 or so for printing
+$fn = 60;
+
+standoff_radius = 14.732 / 2; // 0.580 / 2 inches from spec sheet
+standoff_height = 55; // eyeballed
+
+nut_short_side = 4.7; // from calipers
+nut_height = 1.6; // from calipers
+
+// eyeballed caster flange height, (0.580/5) inches, times 2 to be stronger
+caster_flange_height = 5;
+caster_flange_width = 20.32; // 0.800 inches
+caster_flange_screw_radius = 2.286 / 2; // 0.090 inches
+caster_flange_screw_length = 8; // eyeballed
+
+deck_grid_width = 25.4; // measured center to center on grid on pegboard
+deck_flange_height = 2.9464;
+deck_flange_screw_radius = 3.556 / 2; // For #6 machine screws
+deck_flange_radius = (deck_grid_width) / 2 + deck_flange_screw_radius + 3;
+
+module deck_flange(){
+ difference(){
+ cylinder(h = deck_flange_height, r = deck_flange_radius);
+ for(ii = [-1, 1]){
+ translate([deck_grid_width / 2 * ii, 0, -.1])
+ cylinder(h = deck_flange_height * 1.1,
+ r = deck_flange_screw_radius);
+ translate([0, deck_grid_width / 2 * ii, -.1])
+ cylinder(h = deck_flange_height * 1.1,
+ r = deck_flange_screw_radius);}}}
+
+module deck_flange_reinforcement(){
+ translate([-deck_flange_radius,
+ -.5 * deck_flange_height / 2,
+ deck_flange_height]){
+ difference (){
+ cube([deck_flange_radius, deck_flange_height / 2, deck_flange_radius]);
+ translate([-.1, -.05 * deck_flange_height, 0]){
+ rotate([0, -45, 0]){
+ cube([deck_flange_radius * 1.5, // 1.5 is bigger than sqrt(2)
+ deck_flange_height * 1.1, // 1.1 is bigger than 1
+ deck_flange_radius]);}}}}}
+
+module caster_flange_screws(){
+ translate([standoff_radius, 0, 0])
+ cylinder(h = caster_flange_screw_length,
+ r = caster_flange_screw_radius);
+ translate([-standoff_radius, 0, 0])
+ cylinder(h = caster_flange_screw_length,
+ r = caster_flange_screw_radius);}
+
+module caster_flange(){
+ side_radius = caster_flange_width / 2 - standoff_radius;
+ hull(){
+ cylinder(h = caster_flange_height, r = standoff_radius);
+ translate([standoff_radius, 0, 0])
+ cylinder(h = caster_flange_height, r = side_radius);
+ translate([-standoff_radius, 0, 0])
+ cylinder(h = caster_flange_height, r = side_radius);}}
+
+module nut(size, height){
+ width = size/1.75;
+ for (r = [-60, 0, 60]) rotate([0,0,r]) cube([width, size, height], true);}
+
+module nuts(){
+ translate([standoff_radius, 0, nut_height/2])
+ nut(nut_short_side, nut_height + .1);
+ translate([-standoff_radius, 0, nut_height/2])
+ nut(nut_short_side, nut_height + .1);}
+
+module _2_screw (){
+ //measured with calipers
+ screw_length = 8;
+ thread_radius = 2.17 / 2 - 0.1; // subtract 0.1 to make squeeze fit
+ head_height = 1.8;
+ head_radius = 4.1 / 2;
+ cylinder(r = thread_radius, h = screw_length);
+ cylinder(r = head_radius, h = head_height);}
+
+module caster_standoff_deck_side(){
+ difference(){
+ cylinder(h = standoff_height - caster_flange_height,
+ r = standoff_radius);
+ translate([0, 0, standoff_height - caster_flange_screw_length * 1.1 + 0.1])
+ scale([1, 1, 1.1])
+ caster_flange_screws();
+ translate([0, 0, standoff_height - (caster_flange_height + nut_height)])
+ nuts();
+ translate([0, 0, standoff_height]){
+ // make hole to get to screw head depth
+ cylinder(r = 4.1 / 2, h = 3, center = true);
+ translate([0, 0, -0.7])
+ rotate([180, 0, 0])
+ _2_screw(r = 0.5, h = 5);}}
+ deck_flange();
+ for(ii = [0:3]){
+ rotate([0, 0, 45 + 90 * ii])
+ deck_flange_reinforcement();}}
+
+module caster_standoff_caster_side(){
+ difference(){
+ caster_flange();
+ translate([0, 0, caster_flange_height - 0.7]){
+ rotate([180, 0, 0]){
+ _2_screw();}}
+ // make hole to get to screw head
+ translate([0, 0, caster_flange_height - 0.8]){
+ cylinder(r = 4.1 / 2, h = 10);}
+ translate([0, 0, -.1]){
+ caster_flange_screws();}}}
+
+caster_standoff_deck_side();
+translate([caster_flange_width / 2 + deck_flange_radius + 1, 0, 0]){
+ caster_standoff_caster_side();}
--- /dev/null
+// challenge-bot
+// GNU AGPLv3 (or later at your option)
+// project available at these locations:
+// https://gitorious.org/ozzloy/challenge-bot
+// https://github.com/waynegramlich/challenge-bot
+
+// use this drill jig for putting holes in a motor mount for screws
+// and motor shaft. the four tabs at the bottom are for clamping
+// the jig down.
+
+mm_per_inch = 25.4;
+
+material_width = (1 / 8) * mm_per_inch;
+
+board_length = 1.75 * mm_per_inch;
+board_width = 1.5 * mm_per_inch;
+board_depth = (3 / 16) * mm_per_inch;
+tab_length = 3 * mm_per_inch;
+tab_width = (1 / 4) * mm_per_inch;
+
+union(){
+ rotate(a = 90, v = [1, 0, 0]) {
+ cube([board_length + material_width,
+ 1.75 * mm_per_inch + material_width,
+ material_width]);}
+
+ translate(v = [0, -material_width, 0]){
+ rotate(a = -90, v = [0, 1, 0]) {
+ cube( [1.75 * mm_per_inch + material_width,
+ 1.5 * mm_per_inch + 2 * material_width,
+ material_width]);}}
+
+ translate(v = [(1.75 * mm_per_inch + material_width) / 2 + tab_width,
+ -tab_length,
+ 0]){
+ rotate(a = 90, v = [0 ,0 ,1 ]){
+ cube([3 * mm_per_inch, 0.5 * mm_per_inch , material_width]);}}
+
+ translate(v = [-tab_length,
+ (1.5 * mm_per_inch + material_width) / 2 - tab_width,
+ 0]){
+ cube([3 * mm_per_inch, 0.5 * mm_per_inch , material_width]);}
+
+ translate(v = [(1.75 * mm_per_inch + material_width) / 2 + tab_width,
+ (1.5 * mm_per_inch),
+ 0]){
+ rotate(a = 90, v = [0, 0, 1]){
+ cube([3 * mm_per_inch, 0.5 * mm_per_inch , material_width]);}}
+
+ translate(v = [(1.75 * mm_per_inch),
+ (1.5 * mm_per_inch + material_width) / 2 - tab_width,
+ 0]){
+ cube([3 * mm_per_inch, 0.5 * mm_per_inch , material_width]);}}
+
+_4_40 = 0.1285 * mm_per_inch / 2; // size of hole for 4x40
+_6_32 = 0.1495 * mm_per_inch / 2; // size of hole for 6x32
+
+module collar_hole(){
+ cylinder(h = board_depth, r = 2 * _6_32, $fn = 20);}
+
+module nubbin_hole(){
+ cylinder(h = board_depth, r = _6_32, $fn = 20);}
+
+module mounting_screw_hole(){
+ cylinder(h = board_depth, r = _6_32, $fn = 20);}
+
+module bracket_screw_hole(){
+ cylinder(h = board_depth, r = _6_32, $fn = 20);}
+
+module wheel_motor_holes(scale){
+ translate([51 - 26.78, 38 - 10.8, 0] * scale) {
+ collar_hole();}
+ translate([51 - 26.78, 38 - 22.23, 0] * scale){
+ nubbin_hole();}
+ translate([51 - 18.05 - 17.45, 38 - 30.81, 0] * scale){
+ mounting_screw_hole();}
+ translate([51 - 18.05, 38 - 30.81, 0] * scale){
+ mounting_screw_hole();}
+ translate([7.5, 8.5, 0] * scale){
+ bracket_screw_hole();}
+ translate([7.5, 21 + 8.5, 0] * scale){
+ bracket_screw_hole();}}
+
+module wheel_mount(scale){
+ difference(){
+ cube(scale * [board_length + material_width,
+ board_width + material_width,
+ material_width]);
+ wheel_motor_holes(scale);}}
+
+wheel_mount(1);
+
+translate(v = [0, 0, board_length]) jig_lid();
+
+module jig_lid() {
+ union() {
+ wheel_mount(1);
+ translate(v = [0, -2.1 * material_width, material_width]){
+ cube([board_length + material_width,
+ 3.1 * material_width,
+ material_width]);}
+ translate(v = [0, -2.1 * material_width, 0]){
+ cube([board_length + material_width, material_width, material_width]);}
+ translate(v = [-2.1 * material_width, 0, material_width]){
+ cube([3.1 * material_width,
+ board_width + material_width,
+ material_width]);}
+ translate(v = [-2.1 * material_width, 0, 0]){
+ cube([material_width, board_width+material_width, material_width]);}}}
--- /dev/null
+// challenge-bot
+// GNU AGPLv3 (or later at your option)
+// project available at these locations:
+// https://gitorious.org/ozzloy/challenge-bot
+// https://github.com/waynegramlich/challenge-bot
+
+// this needs to be updated with actual measurements
+length=5;
+width=5;
+thickness=1;
+
+module plate(length, width, thickness){
+ difference(){
+ cube([length, width, thickness]);
+ translate([0, 0, -0.05 * thickness])
+ scale([1, 1, 1.1])
+ translate([length / 2, (width + thickness) / 2, 0])
+ cylinder(h = thickness, r = 0.5, $fn = 20);}}
+
+
+module bracket (length, width, thickness){
+ translate ([0, thickness/2, thickness/2]){
+ translate([0, - thickness / 2, - thickness / 2])
+ plate(length, width, thickness);
+ rotate([90,0,0])
+ translate([0, - thickness / 2, - thickness / 2])
+ plate(length, width, thickness);}}
+
+bracket(length, width, thickness);
--- /dev/null
+// challenge-bot
+// GNU AGPLv3 (or later at your option)
+// project available at these locations:
+// https://gitorious.org/ozzloy/challenge-bot
+// https://github.com/waynegramlich/challenge-bot
+
+// using
+// https://github.com/josefprusa/Prusa3/blob/master/box_frame/x-carriage.scad
+// as an example of how to code in scad
+
+scale=10;
+
+deck_width = 8;
+deck_length = 8;
+deck_depth = 3/16;
+deck_dimensions = [deck_width, deck_length, deck_depth];
+
+module deck(scale){
+ cube(deck_dimensions * scale, center = true);}
+
+module collar_hole(scale){
+ cylinder(h = 5/16 * scale, r = 0.362/2 * scale);}
+
+module nubbin_hole(scale){
+ cylinder(h = 5/16 * scale, r = 0.145/2 * scale);}
+
+module mounting_screw_hole(scale){
+ cylinder(h = 5/16 * scale, r = 0.114/2 * scale);}
+
+module wheel_mount_reinforcement(scale){
+ diagonal = sqrt(deck_depth * deck_depth + deck_depth * deck_depth);
+ difference(){
+ cube([deck_depth * 2, deck_depth * 2, deck_depth * 2] * scale);
+ translate([-(diagonal - deck_depth) / 2, 0, 0] * scale)
+ rotate([45, 0, 0])
+ translate([0, -(diagonal * 1.1 - deck_depth) / 2, 0])
+ cube([diagonal * 2, diagonal * 2 * 1.1, deck_depth * 2] * scale);}}
+
+module wheel_motor_holes(scale){
+ translate([0.5, 0.938, -1/16] * scale) {
+ collar_hole(scale);}
+ translate([0.5 + 0.875 - 0.425, 0.938, -1/16] * scale){
+ nubbin_hole(scale);}
+ translate([0.5 + 1.213 - 0.425, 0.938 - 0.687/2, -1/16] * scale){
+ mounting_screw_hole(scale);}
+ translate([0.5 + 1.213 - 0.425, 0.938 + 0.687/2, -1/16] * scale){
+ mounting_screw_hole(scale);}}
+
+module wheel_mount(scale){
+ width = 1.5;
+ length = 2;
+ depth = deck_depth;
+
+ difference(){
+ cube([width, length, depth] * scale);
+ wheel_motor_holes(scale);}
+ translate([2 * depth, 2 * depth, depth] * scale)
+ rotate([0, 0, 180])
+ wheel_mount_reinforcement(scale);
+ translate([width, 2 * depth, depth] * scale)
+ rotate([0, 0, 180])
+ wheel_mount_reinforcement(scale);}
+
+module robot(scale){
+ translate([0, 0, (deck_depth)/2 * scale]){
+ color("blue") deck(scale);
+ translate([1.5, 4, (deck_depth)/2] * scale)
+ rotate([90, 0, 0])
+ wheel_mount(scale);
+ mirror([0, 1, 0])
+ translate([1.5, 4, (deck_depth)/2] * scale)
+ rotate([90, 0, 0])
+ wheel_mount(scale);}}
+
+robot(scale);
--- /dev/null
+// challenge-bot phase-2
+// GNU AGPLv3 (or later at your option)
+// project available at these locations:
+// https://gitorious.org/ozzloy/challenge-bot
+// https://github.com/waynegramlich/challenge-bot
+
+// using
+// https://github.com/josefprusa/Prusa3/blob/master/box_frame/x-carriage.scad
+// as an example of how to code in scad
+
+deck_dimensions = [8, 8, 3/16];
+
+module deck(){
+ cube(deck_dimensions);}
+
+module wheel_mount(){
+ difference(){
+ cube([1.5, 2, 3/16]);
+ // motor shaft and collar hole
+ translate([0.5, 0.938, -1/16]) {
+ cylinder(h = 5/16, r = 0.362/2, $fn = 100);}
+ // nubbin hole
+ translate([0.5 + 0.875 - 0.425, 0.938, -1/16]){
+ cylinder(h = 5/16, r = 0.145/2, $fn = 100);}
+ // mounting screw hole
+ translate([0.5 + 1.213 - 0.425, 0.938 - 0.687/2, -1/16]){
+ cylinder(h = 5/16, r = 0.114/2, $fn = 100);}
+ translate([0.5 + 1.213 - 0.425, 0.938 + 0.687/2, -1/16]){
+ cylinder(h = 5/16, r = 0.114/2, $fn = 100);}}}
+
+module wheel(){
+ cylinder(r = 2.75/2, h = 3/16, $fn = 100);}
+
+color("blue") deck();
+rotate([90, 0, 0]) translate([1.5, -2, 0]) wheel_mount();
+rotate([90, 0, 0]) translate([1.5, -2, -(8+3/16)]) wheel_mount();
+color("red") rotate([90, 0, 0]) translate([2, -(.938), 3/16]) wheel();
+color("red") rotate([90, 0, 0]) translate([2, -(.938), -(8 + 3/8)]) wheel();
--- /dev/null
+// challenge-bot
+// GNU AGPLv3 (or later at your option)
+// project available at these locations:
+// https://gitorious.org/ozzloy/challenge-bot
+// https://github.com/waynegramlich/challenge-bot
+
+$fn = 60;
+
+// 3/16 inch in mm deck_depth = 4.7625;
+// 1/4 inch in mm - a little to be a squeeze fit
+deck_depth = 6.35 - 0.4;
+sonar_plate_width = 20;
+// sonar sensor measurements taken with calipers:
+// 10.82 in between, 42.33 outside, 15.82 diameter
+// measured diameter of 15.82 with calipers,
+// but when printed ends up being too small
+sonar_sensor_radius = 15.82 / 2 + 0.3;
+sonar_sensor_height = 13.8;
+between_sensor_centers = 15.82 + 10.82;
+sonar_plate_length = 3 + between_sensor_centers + sonar_sensor_radius + 3;
+sonar_holder_length = sonar_plate_length + 10;
+sonar_holder_width = sonar_plate_width + 3;
+sonar_holder_depth = 4;
+
+deck_holder_length = 30;
+deck_holder_width = sonar_holder_width;
+
+module sensors(){
+ translate([between_sensor_centers / 2, 0, 0]){
+ cylinder(r = sonar_sensor_radius, h = sonar_sensor_height);}
+ translate([-between_sensor_centers / 2, 0, 0]){
+ cylinder(r = sonar_sensor_radius, h = sonar_sensor_height);}}
+
+module sensor_holder(){
+ difference(){
+ cube([sonar_holder_length, sonar_holder_width, sonar_holder_depth]);
+ translate([sonar_holder_length / 2, sonar_holder_width / 2, -0.05]){
+ sensors();}}
+ translate([sonar_holder_length, 0, 0]){
+ cube([sonar_holder_depth + 0.3, deck_depth - 0.3, deck_depth - 0.3]);
+ translate([sonar_holder_depth + 0.3, 0, 0]){
+ // subtract a little bit (0.3) to make it fit
+ cube([deck_depth - 0.3, sonar_holder_width, deck_depth - 0.3]);}}}
+
+module deck_holder(){
+ cube([deck_holder_length, sonar_holder_depth, sonar_holder_width]);
+ cube([sonar_holder_depth,
+ sonar_holder_depth * 2 + deck_depth,
+ sonar_holder_width]);
+ translate([0, sonar_holder_depth + deck_depth, 0]){
+ cube([deck_holder_length, sonar_holder_depth, sonar_holder_width]);}
+ translate([sonar_holder_depth + deck_depth, 0, 0]){
+ cube([sonar_holder_depth,
+ sonar_holder_depth * 2 + deck_depth,
+ sonar_holder_width]);}}
+
+module sonar_table_top_holder(){
+ difference(){
+ union(){
+ cube([sonar_holder_length, sonar_holder_width, sonar_holder_depth]);
+ translate([sonar_holder_length, 0, 0]){
+ deck_holder();}}
+ translate([between_sensor_centers / 2 + sonar_sensor_radius + 3,
+ sonar_holder_width / 2,
+ -1]){
+ sensors();}
+ // cut out a bit of the circle to make it 3d printable,
+ // no severe overhang
+ translate([3 + sonar_sensor_radius,
+ sonar_holder_width - 3.025,
+ sonar_holder_depth / 2 - 0.025]){
+ cube([10, 6.1, sonar_holder_depth + .1], center = true);
+ translate([between_sensor_centers, 0, 0]){
+ cube([10, 6.1, sonar_holder_depth + .1], center = true);}}}}
+
+sensor_holder();
--- /dev/null
+// challenge-bot
+// GNU AGPLv3 (or later at your option)
+// project available at these locations:
+// https://gitorious.org/ozzloy/challenge-bot
+// https://github.com/waynegramlich/challenge-bot
+
+// use $fn = 20 while developing, 100 when about to print
+// 20 will make previews fast
+// 100 will make printing smooth
+$fn = 20;
+
+wheel_depth = 6;
+wheel_radius = 68/2;
+
+module encoder_shaft(){
+ // measured with calipers, checked against the motor shaft
+ motor_shaft_big = 3.7; // radius, gets doubled in cylinder
+ motor_shaft_small = 4.8; // total length of box
+ motor_shaft_length = wheel_depth * 3 / 4;
+
+ intersection(){
+ cylinder(h = motor_shaft_length, r = motor_shaft_big, center = true);
+ // x direction is multiplied by 2 because the radius of the cylinder
+ // goes in both directions. the extra .1 is for overlap
+ cube([motor_shaft_big * 2.1, motor_shaft_small, motor_shaft_length],
+ center = true);}}
+
+module mounting_screw(){
+ cylinder(h = wheel_depth * 1.1, r = 1, center = true);}
+
+module wheel(){
+ translate([0, 0, wheel_depth / 2]){
+ difference(){
+ cylinder(h = wheel_depth, r = wheel_radius, center = true);
+ translate([0, 0, wheel_depth / 4]){
+ scale([1, 1, 1.1]){
+ encoder_shaft();}}
+ mounting_screw();
+ for(i = [1 : 5]){
+ rotate(i * 360/5, [0, 0, 1]){
+ translate([0, 0, -0.6 * wheel_depth])
+ between_spokes();}}
+ translate([0, 0, wheel_depth / 4]){
+ difference(){
+ cylinder(h = wheel_depth / 1.2,
+ r = 0.85 * wheel_radius,
+ center = true);
+ cylinder(h = wheel_depth / 1.2,
+ r = 0.23 * wheel_radius,
+ center = true);}}}}}
+
+module wheel_block(){
+ cube([wheel_radius, wheel_radius, wheel_depth]);}
+
+module pie_slice(){
+ intersection(){
+ translate([0, 0, wheel_depth / 2]){
+ cylinder(h = wheel_depth,
+ r = 0.85 * wheel_radius,
+ center = true);}
+ translate([0, wheel_radius * 0.3, 0]){
+ rotate([0, 0, (360 / 5) / 2]){
+ intersection(){
+ wheel_block();
+ rotate([0, 0, 90 - 360 / 5])
+ wheel_block();}}}}}
+
+module between_spokes(){
+ minkowski(){
+ pie_slice();
+ cylinder(h = wheel_depth / 2, r = 1);}}
+
+wheel();
--- /dev/null
+(how to use this
+ (connect your robot to your computer via usb cable)
+ (open arduino ide)
+ (in arduino ide, open motor.ino)
+ (hit the upload button)
+ (your robot's wheels should start moving forward slowly)
+ (yaay!)
+ (you can reverse the direction a motor spins by plugging it into
+ the motor controller differently. take the wires that come out of
+ the motor and swap where they plug into the motor controller)
+ (yaay!))
--- /dev/null
+/*
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// define which pins are connected to which components
+int right_motor_speed_pin = 3;
+int right_motor_forward_pin = 4;
+int right_motor_backward_pin = 5;
+
+int left_motor_speed_pin = 8;
+int left_motor_forward_pin = 9;
+int left_motor_backward_pin = 10;
+
+void setup(){
+ // the arduino will change the voltage on these pins
+ // therefore, these pins are OUTPUT pins
+ pinMode(left_motor_speed_pin, OUTPUT);
+ pinMode(left_motor_forward_pin, OUTPUT);
+ pinMode(left_motor_backward_pin, OUTPUT);
+
+ pinMode(right_motor_speed_pin, OUTPUT);
+ pinMode(right_motor_forward_pin, OUTPUT);
+ pinMode(right_motor_backward_pin, OUTPUT);}
+
+void loop(){
+ digitalWrite(left_motor_backward_pin, LOW);
+ digitalWrite(left_motor_forward_pin, HIGH);
+ analogWrite(left_motor_speed_pin, 128);
+
+ digitalWrite(right_motor_backward_pin, LOW);
+ digitalWrite(right_motor_forward_pin, HIGH);
+ analogWrite(right_motor_speed_pin, 128);}
--- /dev/null
+### Phase 1: Arduino + Blinky LED's:
+
+Goals:
+
+* Cut peg board to size using hack saw
+* Get Arduino IDE installed on laptop.
+* Drill Arduino mounting holes in peg board
+* Mount Arduino to peg board using screws
+* Mount Mini Breadboard to peg board
+* Install LED + resistor on breadboard
+* Hook up LED to Arduino
+* Download Blinky LED program
+
+Bill of Materials:
+
+* 1 Arduino(tm) board + USB Cable (SainSmart: 20-011-110: ~$14/10)
+* 1 Mini BreadBoard (Ebay: ~$3/10)
+* 1 Breadboard cables (Ebay: ~$4/10)
+* 1 4in x 5in peg board to mount arduino + miniboard
+* 4 small squares of double sided tape
+* 3 #4-40 Phillips 1/2" flat-head screws
+* 6 #4-40 hex nuts
+* 3 #4 lock washers
+* 2 Red LED's
+* 2 Yellow LED's
+* 2 Green LED's
+* 6 330 Ohm Resistors
+
+Required Tools:
+
+* 1 Safety glasses!!!
+* 1 Laptop Windows or MacOS or Linux
+* 1 Hack saw (to cut peg board)
+* 1 Phillips screw driver
+* 1 Drill + Drill Bits
+* 1 Pliers
--- /dev/null
+/*
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * traffic lights
+ */
+
+int red0 = 12;
+int yellow0 = 11;
+int green0 = 10;
+
+int red1 = 7;
+int yellow1 = 6;
+int green1 = 5;
+
+void setup() {
+ pinMode(red0, OUTPUT);
+ pinMode(red1, OUTPUT);
+ pinMode(yellow0, OUTPUT);
+ pinMode(yellow1, OUTPUT);
+ pinMode(green0, OUTPUT);
+ pinMode(green1, OUTPUT);
+}
+
+/*
+ on(pinNumber);
+ turn on pin 'pinNumber'.
+ digitalWrite(pinNumber, HIGH); turns the voltage on for that pin.
+ */
+void on(int pinToTurnOn) {
+ digitalWrite(pinToTurnOn, HIGH);
+}
+
+/*
+ off(pinNumber);
+ turn off pin 'pinNumber'.
+ digitalWrite(pinNumber, LOW); turns the voltage off for that pin.
+*/
+void off(int pinToTurnOff) {
+ digitalWrite(pinToTurnOff, LOW);
+}
+
+void onsOffs(int* pinsToTurnOn, int numberOfPinsToTurnOn,
+ int* pinsToTurnOff, int numberOfPinsToTurnOff){
+ // generic index used for arrays of pins to turn on or off
+ int index;
+ // turn off pins in pinsToTurnOff
+ for(index = 0; index < numberOfPinsToTurnOff; index++) {
+ off(pinsToTurnOff[index]);
+ }
+ // turn on pins in pinsToTurnOn
+ for(index = 0; index < numberOfPinsToTurnOn; index++) {
+ on(pinsToTurnOn[index]);
+ }
+}
+
+void loop() {
+ int redWait = 300;
+ int yellowWait = 800;
+ int greenWait = 1600;
+
+ onsOffs((int[]){red0, green1}, 2,
+ (int[]){yellow0, green0, red1, yellow1}, 4);
+ delay(greenWait);
+
+ onsOffs((int[]){red0, yellow1}, 2,
+ (int[]){yellow0, green0, red1, green1}, 4);
+ delay(yellowWait);
+
+ onsOffs((int[]){red0, red1}, 2,
+ (int[]){yellow0, green0, yellow1, green1}, 4);
+ delay(redWait);
+
+ onsOffs((int[]){green0, red1}, 2,
+ (int[]){red0, yellow0, yellow1, green1}, 4);
+ delay(greenWait);
+
+ onsOffs((int[]){yellow0, red1}, 2,
+ (int[]){red0, green0, yellow1, green1}, 4);
+ delay(yellowWait);
+
+ onsOffs((int[]){red0, red1}, 2,
+ (int[]){yellow0, green0, yellow1, green1}, 4);
+ delay(redWait);
+}
--- /dev/null
+### Phase 1: Build Robot Platform
+
+Goals:
+
+* Solder 2 motor wires to each motor
+* Mount Motors to brackets
+* Mount brackets to base
+* Attach to caster to base
+* Attach Arduino+Breadboard to peg board base with screws
+* Install SN754410NE on breadboard
+* Connect motors to breadboard
+* Connect Arduino to breadboard
+* Download a program to make the base move forward and backward
+
+Bill of Materials:
+
+* 1 8in x 8in peg board for robot base
+* 2 GM3 gear motors (Solarbotics: $11.50/2)
+* 2 GMPW Wheels (Solarbotics: $6.50/2)
+* 2 Wheel brackets (custom: ~$3/2)
+* 1 4AA Battery Holder w/cover&switch (Jameco: 216187: ~$1.05)
+* 1 9V Battery Holder w/cover&switch (Jameco: 2128067: ~$1.40)
+* 4 AA Batteries (Brooklyn Batteries)
+* 1 9V Battery (Brooklyn Batteries)
+* 1 Ball Castor (Walgreens: Roll-on Deoderant: ~$3)
+* 1 SN754410NE Dual H-Bridge (Future: ~$1)
+* 14 #6-32 3/4in Phillips Pan-Head screws (Olander)
+* 21 #6 Washers (Olander)
+* 28 #6-32 Hex Nuts (Olander)
+* 14 #6 internal tooth lock washers (Olander)
+* 4 #4-40 1in Phillips Flat-Head screws (Olander)
+* 4 #4-40 Regular Pattern Hex Nut (Olander)
+* 2 #4-40 3/4in Phillips Flat-Head screws (Olander)
+* 2 #4-40 Small Pattern Hex Nut (Olander)
+* 2 Nylon ties (Frys)
+* 5 Rubber bands (Office Depot)
+
+Additional Required Tools:
+
+* 1 Soldering iron
+* 1 Roll of solder
+* 1 Solder tip cleaner
+* 1 Diagonal cutter
+* 1 Wire Stripper
--- /dev/null
+/*
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// use pin 13's LED to indicate intended travel direction.
+// on == forward, off == backward
+int led = 13;
+
+int leftMotorEnable = 10;
+int leftMotorA = 9;
+int leftMotorB = 8;
+
+int rightMotorEnable = 3;
+int rightMotorA = 4;
+int rightMotorB = 5;
+
+void setupMotor(int motorEnable, int motorA, int motorB){
+ pinMode(motorEnable, OUTPUT);
+ pinMode(motorA, OUTPUT);
+ pinMode(motorB, OUTPUT);
+
+ digitalWrite(motorEnable, LOW);
+ digitalWrite(motorA, LOW);
+ digitalWrite(motorB, LOW);
+}
+
+// the setup routine runs once when you press reset:
+void setup() {
+ // initialize the digital pin as an output.
+ setupMotor(leftMotorEnable, leftMotorA, leftMotorB);
+ setupMotor(rightMotorEnable, rightMotorA, rightMotorB);
+
+ pinMode(led, OUTPUT);
+}
+
+void motorsRun(int left, int right, int msDelay) {
+ // Set left motor direction:
+ if (left > 0) {
+ // Set left motor to go forward:
+ digitalWrite(leftMotorA, HIGH);
+ digitalWrite(leftMotorB, LOW);
+ } else {
+ // Set left motor to go backward:
+ digitalWrite(leftMotorA, LOW);
+ digitalWrite(leftMotorB, HIGH);
+ left = -left; // Make left a positive value:
+ }
+
+ analogWrite(rightMotorEnable, left); // Start motor in right direction
+ // Set left motor direction:
+ if (right > 0) {
+ // Set right motor to go forward:
+ digitalWrite(rightMotorA, HIGH);
+ digitalWrite(rightMotorB, LOW);
+ } else {
+ // Set right motor to go backward:
+ digitalWrite(rightMotorA, LOW);
+ digitalWrite(rightMotorB, HIGH);
+ right = -right; // Make right a positive value:
+ }
+ analogWrite(leftMotorEnable, left); // Start motor in right direction
+
+ delay(msDelay); // Wait the specified amount of time
+
+ // Stop both motors:
+ analogWrite(leftMotorEnable, 0);
+ analogWrite(rightMotorEnable, 0);
+}
+
+// the loop routine runs over and over again forever:
+void loop() {
+ digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
+ motorsRun(100, 100, 2000);// Run the robot forward
+ digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
+ motorsRun(-100, -100, 2000); // Run the robot backward
+}
--- /dev/null
+### Phase 2: Build TableTop Challenge Phase 1
+
+Goals:
+
+* Cut out two pieces of Peg Board
+* Drill mounting holes for sonar module
+* Crimp connectors to cable
+* Mount Sonar modules to Robot base
+* Plug Sonar modules into breadboard + Arduino
+* Develop table top challenge code
+
+Bill of Materials:
+
+* 1 ?in x ?in peg board sonar holders
+* 2 Sonar sensors (EBay: HC-SR04 ~$4/2)
+* 4 2x8 .1in Female IDC connectors
+* 2 12in 8 conductor ribbon cable
+* 2 1x4 .1in Male-to-Male Headers
+* 4 #4-40 Phillips Pan Head Screws
+* 8 #4-40 Hex nuts
+* 4 #4 Washers
+* 4 #4 internal tooth lock washers
+* 2 #6-32 Phillips Pan Head Screws
+* 2 #6-32 Hex Nuts
+* 4 #6 Washers
+* 2 #6 internal tool lock washers
+* 1 18" of twine (for a Wyland leash)
+
+Additional Required Tools:
+
+* 1 Benchtop vice
+
+That provides the basic configuration.
+
+## Rechargable Battery Upgrade
+
+This gets rid of the hassle of buying and throwing
+away AA batteries.
+
+Bill of Materials:
+
+* 2 7.2V 1300mAh LiPo Battery Packs (Trossen: BAT-7V1300M: $26/2)
+* 1 LiPo Battery Charger (Trossen: KIT-CHG-LIPO: ($16+$11)/1)
+* 2 Female Deans Connector (TBD)
+* 1 DPDT Power Switch (TBD)
+
+## Raspberry Pi Upgrade
+
+The DC-DC convert is rated for 1.5A and can be
+plugged into the breadboard. The ribbon cable
+can be assembled with just a vise. The RasPi
+allows 5V to be injected over the cable. Obviously
+the RasPi allows people to start trying out ROS.
+
+Bill of Materials:
+
+* 1 Raspberry Pi Model B 512MB (Newark: $35)
+* 1 OKI-78SR-5/1.5-W36: 5V@1.5A DC/DC Switcher (Digikey: $4.30)
+* 1 2x13 Female Ribbon Cable Header
+* 1 16-conductor chunk of ribbon cable
+* 1 2x8 Female Ribbon Cable Header
+* 1 1x8 Male to Male pins header pins
+
+## Odometry Upgrade
+
+This upgrade requires some work.
+
+Bill of Materials:
+
+* 2 AS5055 ($10/2)
+* 2 AS5055 PCB's
+* 2 Appropriate magnet ($2/2)
+* 2 GM3 to magnet shaft adaptor
+
+An adaptor from the GM3 to Magnet is needed;
+this would be custom made out of some plastic.
+In addition a custom PCB is needed to hold
+the AS5055 which is a surface mount chip.
+
+## WiFi Upgrade
+
+Something like the GMYLE using the RTL8191SU should
+do the trick. With this it is possible to network
+into your robot. There it may be necessary to have
+separate power injection for the Wi-Fi.
+
+Bill of Materials:
+
+* 1 USB WiFi Dongle with decent antenna (Amazon: ~9)
+
+## Camera Upgrade
+
+This RasPi camera has not shipped yet, but it seems
+to be nearing the end of prototyping. A USB camera
+is another alternative.
+
+Bill of Materials:
+
+* 1 RasPi Camera (~$25)
+
+## Cheap Arm Upgrade
+
+Bill of Materials:
+* 4 Hobby servos (base twist, shoulder, elbow, gripper)
+* 1 Gripper (Jameco 358811: $20)
+* Appropriate struts
+
+This is a low payload arm that can lift 10-20 oz max.
--- /dev/null
+/*
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+/*
+ Motor.
+ Runs both motors back and forth.
+n
+ This example code is in the public domain.
+ */
+
+int motor1_enable = 10;
+int motor1a = 9;
+int motor1b = 8;
+int motor2_enable = 3;
+int motor2a = 4;
+int motor2b = 5;
+
+// ping sensors
+int left_trigger = 12;
+int left_echo = 11;
+int right_trigger = 7;
+int right_echo = 6;
+
+// the setup routine runs once when you press reset:
+void setup() {
+ Serial.begin(9600);
+
+ // initialize the digital pin as an output.
+ pinMode(motor1_enable, OUTPUT);
+ pinMode(motor1a, OUTPUT);
+ pinMode(motor1b, OUTPUT);
+ pinMode(motor2_enable, OUTPUT);
+ pinMode(motor2a, OUTPUT);
+ pinMode(motor2b, OUTPUT);
+
+ // ping sensors
+ pinMode(left_trigger, OUTPUT);
+ pinMode(left_echo, INPUT);
+ pinMode(right_trigger, OUTPUT);
+ pinMode(right_echo, INPUT);
+
+ digitalWrite(motor1_enable, LOW);
+ digitalWrite(motor1a, LOW);
+ digitalWrite(motor1b, LOW);
+ digitalWrite(motor2_enable, LOW);
+ digitalWrite(motor2a, LOW);
+ digitalWrite(motor2b, LOW);
+}
+
+void
+on(int pin)
+{
+ digitalWrite (pin, HIGH);
+}
+
+void
+off(int pin)
+{
+ digitalWrite (pin, LOW);
+}
+
+int
+ping(int trigger, int echo)
+{
+ int ping_time;
+ on(trigger);
+ delayMicroseconds(12);
+ off(trigger);
+ ping_time = pulseIn (echo, HIGH);
+ if (ping_time <= 0)
+ ping_time = 3000;
+ return ping_time;
+}
+
+void motorsRun(int left, int right, int ms_delay) {
+ // Set left motor direction:
+ if (left > 0) {
+ // Set left motor to go forward:
+ digitalWrite(motor1a, HIGH);
+ digitalWrite(motor1b, LOW);
+ } else {
+ // Set left motor to go backward:
+ digitalWrite(motor1a, LOW);
+ digitalWrite(motor1b, HIGH);
+ left = -left; // Make left a positive value:
+ }
+ analogWrite(motor1_enable, left); // Start motor in right direction
+
+ // Set left motor direction:
+ if (right > 0) {
+ // Set right motor to go forward:
+ digitalWrite(motor2a, HIGH);
+ digitalWrite(motor2b, LOW);
+ } else {
+ // Set right motor to go backward:
+ digitalWrite(motor2a, LOW);
+ digitalWrite(motor2b, HIGH);
+ right = -right; // Make right a positive value:
+ }
+ analogWrite(motor2_enable, right); // Start motor in right direction
+
+ delay(ms_delay); // Wait the specified amount of time
+}
+
+// the loop routine runs over and over again forever:
+void
+loop()
+{
+ int left_speed = 0;
+ int right_speed = 0;
+
+ int left_ping = ping (left_trigger, left_echo);
+ int right_ping = ping (right_trigger, right_echo);
+
+ /*
+ Serial.print ("left ping = ");
+ Serial.print (left_ping);
+
+ Serial.print (" right ping = ");
+ Serial.println (right_ping);
+ */
+
+ if (left_ping < 400)
+ {
+ left_speed = 250;
+ }
+
+ if (right_ping < 400)
+ {
+ right_speed = 250;
+ }
+
+ if (left_speed == 0 && right_speed == 0)
+ {
+ // backup
+ motorsRun(-250, -250, 2000);
+ // turn around
+ motorsRun(-250, 250, 3200);
+ }
+ else
+ {
+ motorsRun(left_speed, right_speed, 0);
+ }
+}
--- /dev/null
+/*
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+// This program implements table top challenge level ###?### --
+// The robot follows a flat vertical surface at a distance of a couple inches.
+
+// Set *debug* to 1 to enable debugging statements:
+int debug = 1;
+
+// Set *stop_at_edge* to 1 to have robot stop at the edge;
+// otherwise, it will back away from edge:
+int stop_at_edge = 0;
+
+// Set *table_top_threshold* to a value that captures the
+// tabletop distance for *your* robot:
+int table_top_threshold = 600;
+
+// Set *sonar_timeout* to a value a 200-300 uSec longer
+// that your table top threshold:
+
+int sonar_timeout = 1600;
+
+// Set *sonar_set_point* to a value that specifies the approximate
+// follow distance:
+
+int sonar_follow_distance = 800;
+
+// Pin definitions:
+int led = 13;
+int left_motor_enable = 3;
+int left_motor_a = 4;
+int left_motor_b = 5;
+int right_motor_enable = 10;
+int right_motor_a = 9;
+int right_motor_b = 8;
+int right_sonar_trigger = 7;
+int right_sonar_echo = 6;
+int left_sonar_trigger = 12;
+int left_sonar_echo = 11;
+
+// the setup routine runs once when you press reset:
+void setup() {
+ // If debugging is enabled,
+ if (debug) {
+ // 115200 is the fastest "standard" baud rate for debugging.
+ // Be sure to set the baud Tools=>Serial Monitor to 115200:
+ Serial.begin(9600);
+ }
+
+ // Set LED output pin:
+ pinMode(led, OUTPUT);
+
+ // Set H-bridge control pins:
+ pinMode(left_motor_enable, OUTPUT);
+ pinMode(left_motor_a, OUTPUT);
+ pinMode(left_motor_b, OUTPUT);
+ pinMode(right_motor_enable, OUTPUT);
+ pinMode(right_motor_a, OUTPUT);
+ pinMode(right_motor_b, OUTPUT);
+
+ // Set control pins for both left and right sonars:
+ pinMode(left_sonar_trigger, OUTPUT);
+ pinMode(left_sonar_echo, INPUT);
+ pinMode(right_sonar_trigger, OUTPUT);
+ pinMode(right_sonar_echo, INPUT);
+
+ // Set all the pin values to predefined values:
+ digitalWrite(led, HIGH);
+ digitalWrite(left_motor_enable, LOW);
+ digitalWrite(left_motor_a, LOW);
+ digitalWrite(left_motor_b, LOW);
+ digitalWrite(right_motor_enable, LOW);
+ digitalWrite(right_motor_a, LOW);
+ digitalWrite(right_motor_b, LOW);
+ digitalWrite(left_sonar_trigger, LOW);
+ digitalWrite(right_sonar_trigger, LOW);
+ digitalWrite(left_sonar_trigger, LOW);
+ digitalWrite(right_sonar_trigger, LOW);
+}
+
+void motors_run(int left, int right, int ms_delay) {
+ // Set left motor direction:
+ if (left > 0) {
+ // Set left motor to go forward:
+ digitalWrite(left_motor_a, HIGH);
+ digitalWrite(left_motor_b, LOW);
+ } else {
+ // Set left motor to go backward:
+ digitalWrite(left_motor_a, LOW);
+ digitalWrite(left_motor_b, HIGH);
+ left = -left; // Make left a positive value:
+ }
+ // Make sure we cap the speed at 255:
+ if (left > 255) {
+ left = 255;
+ }
+ analogWrite(left_motor_enable, left); // Start motor in right direction
+
+ // Set right motor direction:
+ if (right > 0) {
+ // Set right motor to go forward:
+ digitalWrite(right_motor_a, HIGH);
+ digitalWrite(right_motor_b, LOW);
+ } else {
+ // Set right motor to go backward:
+ digitalWrite(right_motor_a, LOW);
+ digitalWrite(right_motor_b, HIGH);
+ right = -right; // Make right a positive value:
+ }
+ // Make sure we cap the speed at 255:
+ if (right > 255) {
+ right = 255;
+ }
+ analogWrite(right_motor_enable, right); // Start motor in right direction
+
+ delay(ms_delay); // Wait the specified amount of time
+}
+
+// This routine will trigger a HC-SR04 sonar that has its
+// trigger pin attached to *sonar_trigger* and its echo
+// pin attached to *sonar_echo*. If the echo response
+// takes longer than *timeout* microseconds, *timeout* is
+// returned.
+int ping(int sonar_trigger, int sonar_echo, int timeout) {
+ int result = timeout;
+ if (!digitalRead(sonar_echo)) {
+ // *sonar_echo* is LOW, so we can safely trigger a 12uS
+ // trigger pulse:
+ digitalWrite(sonar_trigger, HIGH);
+ delayMicroseconds(12);
+ digitalWrite(sonar_trigger, LOW);
+
+ // Time the resulting echo pulse. If the resulting echo pulse
+ // is longer than *timeout*, *pulseIn* returns 0.
+ result = pulseIn(sonar_echo, HIGH, timeout);
+
+ if (result == 0) {
+ // We timed out, so return *timeout*:
+ result = timeout;
+ }
+ }
+ // else *sonar_echo* is still high from the previous trigger;
+ // return *timeout* when this occurs.
+ return result;
+}
+
+// the loop routine runs over and over again forever:
+void loop() {
+ // Get the left and right sonar values:
+ int left_ping = ping(left_sonar_trigger, left_sonar_echo, sonar_timeout);
+ int right_ping = ping(right_sonar_trigger, right_sonar_echo, sonar_timeout);
+
+ // Set the left and right motor speed:
+ int left_speed = left_ping - sonar_follow_distance;
+ int right_speed = right_ping - sonar_follow_distance;
+
+ // Debugging code:
+ if (debug) {
+ // Print some debugging information:
+ Serial.print("lp=");
+ Serial.print(left_ping);
+ Serial.print(" rp=");
+ Serial.print(right_ping);
+ Serial.print(" ls=");
+ Serial.print(left_speed);
+ Serial.print(" rs=");
+ Serial.println(right_speed);
+
+ // Delay a little so that the serial port does not get
+ // swamped with debugging information:
+ delay(100);
+ }
+
+ // Set the motor speeds:
+ motors_run(left_speed, right_speed, 0);
+}
--- /dev/null
+(how to use this
+ (connect your robot to your computer via usb cable)
+ (open arduino ide)
+ (in arduino ide, open pushbutton.ino)
+ (hit the upload button)
+ (hit control+shift+m,
+ or go to the menu item tools, and down to serial monitor)
+ (in the bottom right, select "9600 baud")
+ (connect the breadboard and pushbutton as shown in "pushed.jpg")
+ (hit the upload button in the arduino ide)
+ (press the button!)
+ (the message "button state changed!" should appear,
+ and the arduino's built in LED should light up)
+ (yaaay!))
--- /dev/null
+/*
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// pin 13 controls the arduino's built-in LED
+int led_pin = 13;
+// connect the button to pin 2
+int button_pin = 2;
+// initially, the button is not pressed.
+// 0 means not pressed, 1 means pressed
+int button_value = 0;
+
+void setup(){
+ Serial.begin(9600);}
+
+void loop(){
+ // see if you can figure out how this logic works
+ if(digitalRead(button_pin) != button_value){
+ Serial.println("button state changed!");}
+ // read the value of the button pin during this loop,
+ // and save it in a box named "button_value"
+ button_value = digitalRead(button_pin);
+ // write the value to the led pin
+ digitalWrite(led_pin, button_value);}
--- /dev/null
+(how to use this
+ (connect your robot to your computer via usb cable)
+ (open arduino ide)
+ (in arduino ide, open serial.ino)
+ (hit the upload button)
+ (hit control+shift+m,
+ or go to the menu item tools, and down to serial monitor)
+ (in the bottom right, select "9600 baud")
+ (hit the reset button on the arduino)
+ (you should see "hello computer!" each time you hit the reset button,
+ (this means your arduino is talking to your computer when it starts))
+ (yaaay!))
--- /dev/null
+/*
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+void setup(){
+ Serial.begin(9600);
+ Serial.println("hello computer!");}
+
+void loop(){}
--- /dev/null
+/*
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// define which pins are connected to which components
+int right_motor_speed_pin = 3; // orange wire
+int right_motor_forward_pin = 4; // brown
+int right_motor_backward_pin = 5; // purple
+
+int right_echo_pin = 6; // white
+int right_trigger_pin = 7; // blue
+
+int left_motor_speed_pin = 8; // orange
+int left_motor_forward_pin = 9; // brown
+int left_motor_backward_pin = 10; // purple
+
+int left_echo_pin = 11; // white
+int left_trigger_pin = 12; // blue
+
+void on(int pin){
+ digitalWrite(pin, HIGH);}
+
+void off(int pin){
+ digitalWrite(pin, LOW);}
+
+void set_motor(int speed_pin,
+ int forward_pin,
+ int backward_pin,
+ int speed){
+ if(speed > 0){
+ off(backward_pin);
+ on(forward_pin);}
+ else if(speed < 0){
+ off(forward_pin);
+ on(backward_pin);
+ speed = -speed;}
+ else{ // speed is 0
+ off(forward_pin);
+ off(backward_pin);}
+ if(speed > 255){
+ speed = 255;}
+ analogWrite(speed_pin, speed);}
+
+void go(int left_motor_speed, int right_motor_speed){
+ set_motor(left_motor_speed_pin,
+ left_motor_forward_pin,
+ left_motor_backward_pin,
+ left_motor_speed);
+ set_motor(right_motor_speed_pin,
+ right_motor_forward_pin,
+ right_motor_backward_pin,
+ right_motor_speed);}
+
+int ping(int trigger, int echo){
+ int ping_time = 0;
+ // turn off trigger
+ off(trigger);
+ delayMicroseconds(2);
+ // turn on the trigger and leave it on long enough for the
+ // sonar sensor to notice
+ on(trigger);
+ delayMicroseconds(10);
+ off(trigger);
+ ping_time = pulseIn(echo, HIGH);
+ if(ping_time <= 0){
+ ping_time = 3000;}
+ // sonar needs some time to recover before pinging again,
+ // so make sure it gets enough sleep right here. 50 milliseconds
+ delay(50);
+ return ping_time;}
+
+void backup(int backup_time){
+ go(-250, -250);
+ delay(backup_time);}
+
+void turn_around(int turn_around_time){
+ go(-250, 250);
+ delay(turn_around_time);}
+
+void setup(){
+ Serial.begin(9600);
+
+ pinMode(right_motor_speed_pin, OUTPUT);
+ pinMode(right_motor_forward_pin, OUTPUT);
+ pinMode(right_motor_backward_pin, OUTPUT);
+
+ pinMode(right_echo_pin, INPUT);
+ pinMode(right_trigger_pin, OUTPUT);
+
+ pinMode(left_motor_speed_pin, OUTPUT);
+ pinMode(left_motor_forward_pin, OUTPUT);
+ pinMode(left_motor_backward_pin, OUTPUT);
+
+ pinMode(left_echo_pin, INPUT);
+ pinMode(left_trigger_pin, OUTPUT);
+
+ off(left_motor_speed_pin);
+ off(left_motor_forward_pin);
+ off(left_motor_backward_pin);
+ off(left_trigger_pin);
+
+ off(right_motor_speed_pin);
+ off(right_motor_forward_pin);
+ off(right_motor_backward_pin);
+ off(right_trigger_pin);}
+
+void loop(){
+ int left_speed;
+ int right_speed;
+
+ int forward_speed = 250;
+ int stop_speed = 0;
+
+ // adjust this number as necessary for your robot.
+ // it represents how far the table is from your sonar sensor.
+ // larger values mean larger distance. default is 400
+ int right_max_ping_time_over_table = 400;
+ int left_max_ping_time_over_table = 400;
+ int backup_time = 2000;
+ // the exact amount of time for turning around might need
+ // twerking for your robot. the default value is 3200
+ int turn_around_time = 3200;
+
+ int actual_left_ping_time = ping(left_trigger_pin, left_echo_pin);
+ int actual_right_ping_time = ping(right_trigger_pin, right_echo_pin);
+
+ Serial.print("left ping = ");
+ Serial.print(actual_left_ping_time);
+ Serial.print("\tright_ping = ");
+ Serial.println(actual_right_ping_time);
+
+ // if the left sonar senses a table, keep driving left side forward,
+ // otherwise, stop left side
+ if(actual_left_ping_time < left_max_ping_time_over_table){
+ left_speed = forward_speed;}
+ else{
+ left_speed = stop_speed;}
+ // if the right sonar senses a table, keep driving right side forward,
+ // otherwise, stop right side
+ if(actual_right_ping_time < right_max_ping_time_over_table){
+ right_speed = forward_speed;}
+ else{
+ right_speed = stop_speed;}
+
+ // if both sonars detect being off the table, backup and turn around
+ // otherwise, go the correct speed for each wheel
+ if(actual_left_ping_time >= left_max_ping_time_over_table
+ && actual_right_ping_time >= right_max_ping_time_over_table){
+ Serial.println("backing up");
+ backup(backup_time);
+ Serial.println("turning around");
+ turn_around(turn_around_time);}
+ else{
+ Serial.println("going");
+ go(left_speed, right_speed);}}
+++ /dev/null
-Bill of Materials:
-
-* 1 Arduino(tm) board + USB Cable (SainSmart: 20-011-110: ~$14/10)
-* 1 Mini BreadBoard (Ebay: ~$3/10)
-* 1 Breadboard cables (Ebay: ~$4/10)
-* 1 4in x 5in peg board to mount arduino + miniboard
-* 4 small squares of double sided tape
-* 3 #4-40 Phillips 1/2" flat-head screws
-* 6 #4-40 hex nuts
-* 3 #4 lock washers
-* 2 Red LED's
-* 2 Yellow LED's
-* 2 Green LED's
-* 6 330 Ohm Resistors
+++ /dev/null
-// challenge-bot
-// GNU AGPLv3 (or later at your option)
-// project available at these locations:
-// https://gitorious.org/ozzloy/challenge-bot
-// https://github.com/waynegramlich/challenge-bot
-
-// use 10 ish for development, 60 or so for printing
-$fn = 60;
-
-standoff_radius = 14.732 / 2; // 0.580 / 2 inches from spec sheet
-standoff_height = 55; // eyeballed
-
-nut_short_side = 4.7; // from calipers
-nut_height = 1.6; // from calipers
-
-// eyeballed caster flange height, (0.580/5) inches, times 2 to be stronger
-caster_flange_height = 5;
-caster_flange_width = 20.32; // 0.800 inches
-caster_flange_screw_radius = 2.286 / 2; // 0.090 inches
-caster_flange_screw_length = 8; // eyeballed
-
-deck_grid_width = 25.4; // measured center to center on grid on pegboard
-deck_flange_height = 2.9464;
-deck_flange_screw_radius = 3.556 / 2; // For #6 machine screws
-deck_flange_radius = (deck_grid_width) / 2 + deck_flange_screw_radius + 3;
-
-module deck_flange(){
- difference(){
- cylinder(h = deck_flange_height, r = deck_flange_radius);
- for(ii = [-1, 1]){
- translate([deck_grid_width / 2 * ii, 0, -.1])
- cylinder(h = deck_flange_height * 1.1,
- r = deck_flange_screw_radius);
- translate([0, deck_grid_width / 2 * ii, -.1])
- cylinder(h = deck_flange_height * 1.1,
- r = deck_flange_screw_radius);}}}
-
-module deck_flange_reinforcement(){
- translate([-deck_flange_radius,
- -.5 * deck_flange_height / 2,
- deck_flange_height]){
- difference (){
- cube([deck_flange_radius, deck_flange_height / 2, deck_flange_radius]);
- translate([-.1, -.05 * deck_flange_height, 0]){
- rotate([0, -45, 0]){
- cube([deck_flange_radius * 1.5, // 1.5 is bigger than sqrt(2)
- deck_flange_height * 1.1, // 1.1 is bigger than 1
- deck_flange_radius]);}}}}}
-
-module caster_flange_screws(){
- translate([standoff_radius, 0, 0])
- cylinder(h = caster_flange_screw_length,
- r = caster_flange_screw_radius);
- translate([-standoff_radius, 0, 0])
- cylinder(h = caster_flange_screw_length,
- r = caster_flange_screw_radius);}
-
-module caster_flange(){
- side_radius = caster_flange_width / 2 - standoff_radius;
- hull(){
- cylinder(h = caster_flange_height, r = standoff_radius);
- translate([standoff_radius, 0, 0])
- cylinder(h = caster_flange_height, r = side_radius);
- translate([-standoff_radius, 0, 0])
- cylinder(h = caster_flange_height, r = side_radius);}}
-
-module nut(size, height){
- width = size/1.75;
- for (r = [-60, 0, 60]) rotate([0,0,r]) cube([width, size, height], true);}
-
-module nuts(){
- translate([standoff_radius, 0, nut_height/2])
- nut(nut_short_side, nut_height + .1);
- translate([-standoff_radius, 0, nut_height/2])
- nut(nut_short_side, nut_height + .1);}
-
-module _2_screw (){
- //measured with calipers
- screw_length = 8;
- thread_radius = 2.17 / 2 - 0.1; // subtract 0.1 to make squeeze fit
- head_height = 1.8;
- head_radius = 4.1 / 2;
- cylinder(r = thread_radius, h = screw_length);
- cylinder(r = head_radius, h = head_height);}
-
-module caster_standoff_deck_side(){
- difference(){
- cylinder(h = standoff_height - caster_flange_height,
- r = standoff_radius);
- translate([0, 0, standoff_height - caster_flange_screw_length * 1.1 + 0.1])
- scale([1, 1, 1.1])
- caster_flange_screws();
- translate([0, 0, standoff_height - (caster_flange_height + nut_height)])
- nuts();
- translate([0, 0, standoff_height]){
- // make hole to get to screw head depth
- cylinder(r = 4.1 / 2, h = 3, center = true);
- translate([0, 0, -0.7])
- rotate([180, 0, 0])
- _2_screw(r = 0.5, h = 5);}}
- deck_flange();
- for(ii = [0:3]){
- rotate([0, 0, 45 + 90 * ii])
- deck_flange_reinforcement();}}
-
-module caster_standoff_caster_side(){
- difference(){
- caster_flange();
- translate([0, 0, caster_flange_height - 0.7]){
- rotate([180, 0, 0]){
- _2_screw();}}
- // make hole to get to screw head
- translate([0, 0, caster_flange_height - 0.8]){
- cylinder(r = 4.1 / 2, h = 10);}
- translate([0, 0, -.1]){
- caster_flange_screws();}}}
-
-caster_standoff_deck_side();
-translate([caster_flange_width / 2 + deck_flange_radius + 1, 0, 0]){
- caster_standoff_caster_side();}
+++ /dev/null
-// challenge-bot
-// GNU AGPLv3 (or later at your option)
-// project available at these locations:
-// https://gitorious.org/ozzloy/challenge-bot
-// https://github.com/waynegramlich/challenge-bot
-
-// use this drill jig for putting holes in a motor mount for screws
-// and motor shaft. the four tabs at the bottom are for clamping
-// the jig down.
-
-mm_per_inch = 25.4;
-
-material_width = (1 / 8) * mm_per_inch;
-
-board_length = 1.75 * mm_per_inch;
-board_width = 1.5 * mm_per_inch;
-board_depth = (3 / 16) * mm_per_inch;
-tab_length = 3 * mm_per_inch;
-tab_width = (1 / 4) * mm_per_inch;
-
-union(){
- rotate(a = 90, v = [1, 0, 0]) {
- cube([board_length + material_width,
- 1.75 * mm_per_inch + material_width,
- material_width]);}
-
- translate(v = [0, -material_width, 0]){
- rotate(a = -90, v = [0, 1, 0]) {
- cube( [1.75 * mm_per_inch + material_width,
- 1.5 * mm_per_inch + 2 * material_width,
- material_width]);}}
-
- translate(v = [(1.75 * mm_per_inch + material_width) / 2 + tab_width,
- -tab_length,
- 0]){
- rotate(a = 90, v = [0 ,0 ,1 ]){
- cube([3 * mm_per_inch, 0.5 * mm_per_inch , material_width]);}}
-
- translate(v = [-tab_length,
- (1.5 * mm_per_inch + material_width) / 2 - tab_width,
- 0]){
- cube([3 * mm_per_inch, 0.5 * mm_per_inch , material_width]);}
-
- translate(v = [(1.75 * mm_per_inch + material_width) / 2 + tab_width,
- (1.5 * mm_per_inch),
- 0]){
- rotate(a = 90, v = [0, 0, 1]){
- cube([3 * mm_per_inch, 0.5 * mm_per_inch , material_width]);}}
-
- translate(v = [(1.75 * mm_per_inch),
- (1.5 * mm_per_inch + material_width) / 2 - tab_width,
- 0]){
- cube([3 * mm_per_inch, 0.5 * mm_per_inch , material_width]);}}
-
-_4_40 = 0.1285 * mm_per_inch / 2; // size of hole for 4x40
-_6_32 = 0.1495 * mm_per_inch / 2; // size of hole for 6x32
-
-module collar_hole(){
- cylinder(h = board_depth, r = 2 * _6_32, $fn = 20);}
-
-module nubbin_hole(){
- cylinder(h = board_depth, r = _6_32, $fn = 20);}
-
-module mounting_screw_hole(){
- cylinder(h = board_depth, r = _6_32, $fn = 20);}
-
-module bracket_screw_hole(){
- cylinder(h = board_depth, r = _6_32, $fn = 20);}
-
-module wheel_motor_holes(scale){
- translate([51 - 26.78, 38 - 10.8, 0] * scale) {
- collar_hole();}
- translate([51 - 26.78, 38 - 22.23, 0] * scale){
- nubbin_hole();}
- translate([51 - 18.05 - 17.45, 38 - 30.81, 0] * scale){
- mounting_screw_hole();}
- translate([51 - 18.05, 38 - 30.81, 0] * scale){
- mounting_screw_hole();}
- translate([7.5, 8.5, 0] * scale){
- bracket_screw_hole();}
- translate([7.5, 21 + 8.5, 0] * scale){
- bracket_screw_hole();}}
-
-module wheel_mount(scale){
- difference(){
- cube(scale * [board_length + material_width,
- board_width + material_width,
- material_width]);
- wheel_motor_holes(scale);}}
-
-wheel_mount(1);
-
-translate(v = [0, 0, board_length]) jig_lid();
-
-module jig_lid() {
- union() {
- wheel_mount(1);
- translate(v = [0, -2.1 * material_width, material_width]){
- cube([board_length + material_width,
- 3.1 * material_width,
- material_width]);}
- translate(v = [0, -2.1 * material_width, 0]){
- cube([board_length + material_width, material_width, material_width]);}
- translate(v = [-2.1 * material_width, 0, material_width]){
- cube([3.1 * material_width,
- board_width + material_width,
- material_width]);}
- translate(v = [-2.1 * material_width, 0, 0]){
- cube([material_width, board_width+material_width, material_width]);}}}
+++ /dev/null
-(how to use this
- (connect your robot to your computer via usb cable)
- (open arduino ide)
- (in arduino ide, open motor.ino)
- (hit the upload button)
- (your robot's wheels should start moving forward slowly)
- (yaay!)
- (you can reverse the direction a motor spins by plugging it into
- the motor controller differently. take the wires that come out of
- the motor and swap where they plug into the motor controller)
- (yaay!))
+++ /dev/null
-/*
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-// define which pins are connected to which components
-int right_motor_speed_pin = 3;
-int right_motor_forward_pin = 4;
-int right_motor_backward_pin = 5;
-
-int left_motor_speed_pin = 8;
-int left_motor_forward_pin = 9;
-int left_motor_backward_pin = 10;
-
-void setup(){
- // the arduino will change the voltage on these pins
- // therefore, these pins are OUTPUT pins
- pinMode(left_motor_speed_pin, OUTPUT);
- pinMode(left_motor_forward_pin, OUTPUT);
- pinMode(left_motor_backward_pin, OUTPUT);
-
- pinMode(right_motor_speed_pin, OUTPUT);
- pinMode(right_motor_forward_pin, OUTPUT);
- pinMode(right_motor_backward_pin, OUTPUT);}
-
-void loop(){
- digitalWrite(left_motor_backward_pin, LOW);
- digitalWrite(left_motor_forward_pin, HIGH);
- analogWrite(left_motor_speed_pin, 128);
-
- digitalWrite(right_motor_backward_pin, LOW);
- digitalWrite(right_motor_forward_pin, HIGH);
- analogWrite(right_motor_speed_pin, 128);}
+++ /dev/null
-// challenge-bot
-// GNU AGPLv3 (or later at your option)
-// project available at these locations:
-// https://gitorious.org/ozzloy/challenge-bot
-// https://github.com/waynegramlich/challenge-bot
-
-// this needs to be updated with actual measurements
-length=5;
-width=5;
-thickness=1;
-
-module plate(length, width, thickness){
- difference(){
- cube([length, width, thickness]);
- translate([0, 0, -0.05 * thickness])
- scale([1, 1, 1.1])
- translate([length / 2, (width + thickness) / 2, 0])
- cylinder(h = thickness, r = 0.5, $fn = 20);}}
-
-
-module bracket (length, width, thickness){
- translate ([0, thickness/2, thickness/2]){
- translate([0, - thickness / 2, - thickness / 2])
- plate(length, width, thickness);
- rotate([90,0,0])
- translate([0, - thickness / 2, - thickness / 2])
- plate(length, width, thickness);}}
-
-bracket(length, width, thickness);
+++ /dev/null
-### Phase 1: Arduino + Blinky LED's:
-
-Goals:
-
-* Cut peg board to size using hack saw
-* Get Arduino IDE installed on laptop.
-* Drill Arduino mounting holes in peg board
-* Mount Arduino to peg board using screws
-* Mount Mini Breadboard to peg board
-* Install LED + resistor on breadboard
-* Hook up LED to Arduino
-* Download Blinky LED program
-
-Bill of Materials:
-
-* 1 Arduino(tm) board + USB Cable (SainSmart: 20-011-110: ~$14/10)
-* 1 Mini BreadBoard (Ebay: ~$3/10)
-* 1 Breadboard cables (Ebay: ~$4/10)
-* 1 4in x 5in peg board to mount arduino + miniboard
-* 4 small squares of double sided tape
-* 3 #4-40 Phillips 1/2" flat-head screws
-* 6 #4-40 hex nuts
-* 3 #4 lock washers
-* 2 Red LED's
-* 2 Yellow LED's
-* 2 Green LED's
-* 6 330 Ohm Resistors
-
-Required Tools:
-
-* 1 Safety glasses!!!
-* 1 Laptop Windows or MacOS or Linux
-* 1 Hack saw (to cut peg board)
-* 1 Phillips screw driver
-* 1 Drill + Drill Bits
-* 1 Pliers
+++ /dev/null
-/*
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of
- the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * traffic lights
- */
-
-int red0 = 12;
-int yellow0 = 11;
-int green0 = 10;
-
-int red1 = 7;
-int yellow1 = 6;
-int green1 = 5;
-
-void setup() {
- pinMode(red0, OUTPUT);
- pinMode(red1, OUTPUT);
- pinMode(yellow0, OUTPUT);
- pinMode(yellow1, OUTPUT);
- pinMode(green0, OUTPUT);
- pinMode(green1, OUTPUT);
-}
-
-/*
- on(pinNumber);
- turn on pin 'pinNumber'.
- digitalWrite(pinNumber, HIGH); turns the voltage on for that pin.
- */
-void on(int pinToTurnOn) {
- digitalWrite(pinToTurnOn, HIGH);
-}
-
-/*
- off(pinNumber);
- turn off pin 'pinNumber'.
- digitalWrite(pinNumber, LOW); turns the voltage off for that pin.
-*/
-void off(int pinToTurnOff) {
- digitalWrite(pinToTurnOff, LOW);
-}
-
-void onsOffs(int* pinsToTurnOn, int numberOfPinsToTurnOn,
- int* pinsToTurnOff, int numberOfPinsToTurnOff){
- // generic index used for arrays of pins to turn on or off
- int index;
- // turn off pins in pinsToTurnOff
- for(index = 0; index < numberOfPinsToTurnOff; index++) {
- off(pinsToTurnOff[index]);
- }
- // turn on pins in pinsToTurnOn
- for(index = 0; index < numberOfPinsToTurnOn; index++) {
- on(pinsToTurnOn[index]);
- }
-}
-
-void loop() {
- int redWait = 300;
- int yellowWait = 800;
- int greenWait = 1600;
-
- onsOffs((int[]){red0, green1}, 2,
- (int[]){yellow0, green0, red1, yellow1}, 4);
- delay(greenWait);
-
- onsOffs((int[]){red0, yellow1}, 2,
- (int[]){yellow0, green0, red1, green1}, 4);
- delay(yellowWait);
-
- onsOffs((int[]){red0, red1}, 2,
- (int[]){yellow0, green0, yellow1, green1}, 4);
- delay(redWait);
-
- onsOffs((int[]){green0, red1}, 2,
- (int[]){red0, yellow0, yellow1, green1}, 4);
- delay(greenWait);
-
- onsOffs((int[]){yellow0, red1}, 2,
- (int[]){red0, green0, yellow1, green1}, 4);
- delay(yellowWait);
-
- onsOffs((int[]){red0, red1}, 2,
- (int[]){yellow0, green0, yellow1, green1}, 4);
- delay(redWait);
-}
+++ /dev/null
-### Phase 1: Build Robot Platform
-
-Goals:
-
-* Solder 2 motor wires to each motor
-* Mount Motors to brackets
-* Mount brackets to base
-* Attach to caster to base
-* Attach Arduino+Breadboard to peg board base with screws
-* Install SN754410NE on breadboard
-* Connect motors to breadboard
-* Connect Arduino to breadboard
-* Download a program to make the base move forward and backward
-
-Bill of Materials:
-
-* 1 8in x 8in peg board for robot base
-* 2 GM3 gear motors (Solarbotics: $11.50/2)
-* 2 GMPW Wheels (Solarbotics: $6.50/2)
-* 2 Wheel brackets (custom: ~$3/2)
-* 1 4AA Battery Holder w/cover&switch (Jameco: 216187: ~$1.05)
-* 1 9V Battery Holder w/cover&switch (Jameco: 2128067: ~$1.40)
-* 4 AA Batteries (Brooklyn Batteries)
-* 1 9V Battery (Brooklyn Batteries)
-* 1 Ball Castor (Walgreens: Roll-on Deoderant: ~$3)
-* 1 SN754410NE Dual H-Bridge (Future: ~$1)
-* 14 #6-32 3/4in Phillips Pan-Head screws (Olander)
-* 21 #6 Washers (Olander)
-* 28 #6-32 Hex Nuts (Olander)
-* 14 #6 internal tooth lock washers (Olander)
-* 4 #4-40 1in Phillips Flat-Head screws (Olander)
-* 4 #4-40 Regular Pattern Hex Nut (Olander)
-* 2 #4-40 3/4in Phillips Flat-Head screws (Olander)
-* 2 #4-40 Small Pattern Hex Nut (Olander)
-* 2 Nylon ties (Frys)
-* 5 Rubber bands (Office Depot)
-
-Additional Required Tools:
-
-* 1 Soldering iron
-* 1 Roll of solder
-* 1 Solder tip cleaner
-* 1 Diagonal cutter
-* 1 Wire Stripper
+++ /dev/null
-/*
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-// use pin 13's LED to indicate intended travel direction.
-// on == forward, off == backward
-int led = 13;
-
-int leftMotorEnable = 10;
-int leftMotorA = 9;
-int leftMotorB = 8;
-
-int rightMotorEnable = 3;
-int rightMotorA = 4;
-int rightMotorB = 5;
-
-void setupMotor(int motorEnable, int motorA, int motorB){
- pinMode(motorEnable, OUTPUT);
- pinMode(motorA, OUTPUT);
- pinMode(motorB, OUTPUT);
-
- digitalWrite(motorEnable, LOW);
- digitalWrite(motorA, LOW);
- digitalWrite(motorB, LOW);
-}
-
-// the setup routine runs once when you press reset:
-void setup() {
- // initialize the digital pin as an output.
- setupMotor(leftMotorEnable, leftMotorA, leftMotorB);
- setupMotor(rightMotorEnable, rightMotorA, rightMotorB);
-
- pinMode(led, OUTPUT);
-}
-
-void motorsRun(int left, int right, int msDelay) {
- // Set left motor direction:
- if (left > 0) {
- // Set left motor to go forward:
- digitalWrite(leftMotorA, HIGH);
- digitalWrite(leftMotorB, LOW);
- } else {
- // Set left motor to go backward:
- digitalWrite(leftMotorA, LOW);
- digitalWrite(leftMotorB, HIGH);
- left = -left; // Make left a positive value:
- }
-
- analogWrite(rightMotorEnable, left); // Start motor in right direction
- // Set left motor direction:
- if (right > 0) {
- // Set right motor to go forward:
- digitalWrite(rightMotorA, HIGH);
- digitalWrite(rightMotorB, LOW);
- } else {
- // Set right motor to go backward:
- digitalWrite(rightMotorA, LOW);
- digitalWrite(rightMotorB, HIGH);
- right = -right; // Make right a positive value:
- }
- analogWrite(leftMotorEnable, left); // Start motor in right direction
-
- delay(msDelay); // Wait the specified amount of time
-
- // Stop both motors:
- analogWrite(leftMotorEnable, 0);
- analogWrite(rightMotorEnable, 0);
-}
-
-// the loop routine runs over and over again forever:
-void loop() {
- digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
- motorsRun(100, 100, 2000);// Run the robot forward
- digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
- motorsRun(-100, -100, 2000); // Run the robot backward
-}
+++ /dev/null
-### Phase 2: Build TableTop Challenge Phase 1
-
-Goals:
-
-* Cut out two pieces of Peg Board
-* Drill mounting holes for sonar module
-* Crimp connectors to cable
-* Mount Sonar modules to Robot base
-* Plug Sonar modules into breadboard + Arduino
-* Develop table top challenge code
-
-Bill of Materials:
-
-* 1 ?in x ?in peg board sonar holders
-* 2 Sonar sensors (EBay: HC-SR04 ~$4/2)
-* 4 2x8 .1in Female IDC connectors
-* 2 12in 8 conductor ribbon cable
-* 2 1x4 .1in Male-to-Male Headers
-* 4 #4-40 Phillips Pan Head Screws
-* 8 #4-40 Hex nuts
-* 4 #4 Washers
-* 4 #4 internal tooth lock washers
-* 2 #6-32 Phillips Pan Head Screws
-* 2 #6-32 Hex Nuts
-* 4 #6 Washers
-* 2 #6 internal tool lock washers
-* 1 18" of twine (for a Wyland leash)
-
-Additional Required Tools:
-
-* 1 Benchtop vice
-
-That provides the basic configuration.
-
-## Rechargable Battery Upgrade
-
-This gets rid of the hassle of buying and throwing
-away AA batteries.
-
-Bill of Materials:
-
-* 2 7.2V 1300mAh LiPo Battery Packs (Trossen: BAT-7V1300M: $26/2)
-* 1 LiPo Battery Charger (Trossen: KIT-CHG-LIPO: ($16+$11)/1)
-* 2 Female Deans Connector (TBD)
-* 1 DPDT Power Switch (TBD)
-
-## Raspberry Pi Upgrade
-
-The DC-DC convert is rated for 1.5A and can be
-plugged into the breadboard. The ribbon cable
-can be assembled with just a vise. The RasPi
-allows 5V to be injected over the cable. Obviously
-the RasPi allows people to start trying out ROS.
-
-Bill of Materials:
-
-* 1 Raspberry Pi Model B 512MB (Newark: $35)
-* 1 OKI-78SR-5/1.5-W36: 5V@1.5A DC/DC Switcher (Digikey: $4.30)
-* 1 2x13 Female Ribbon Cable Header
-* 1 16-conductor chunk of ribbon cable
-* 1 2x8 Female Ribbon Cable Header
-* 1 1x8 Male to Male pins header pins
-
-## Odometry Upgrade
-
-This upgrade requires some work.
-
-Bill of Materials:
-
-* 2 AS5055 ($10/2)
-* 2 AS5055 PCB's
-* 2 Appropriate magnet ($2/2)
-* 2 GM3 to magnet shaft adaptor
-
-An adaptor from the GM3 to Magnet is needed;
-this would be custom made out of some plastic.
-In addition a custom PCB is needed to hold
-the AS5055 which is a surface mount chip.
-
-## WiFi Upgrade
-
-Something like the GMYLE using the RTL8191SU should
-do the trick. With this it is possible to network
-into your robot. There it may be necessary to have
-separate power injection for the Wi-Fi.
-
-Bill of Materials:
-
-* 1 USB WiFi Dongle with decent antenna (Amazon: ~9)
-
-## Camera Upgrade
-
-This RasPi camera has not shipped yet, but it seems
-to be nearing the end of prototyping. A USB camera
-is another alternative.
-
-Bill of Materials:
-
-* 1 RasPi Camera (~$25)
-
-## Cheap Arm Upgrade
-
-Bill of Materials:
-* 4 Hobby servos (base twist, shoulder, elbow, gripper)
-* 1 Gripper (Jameco 358811: $20)
-* Appropriate struts
-
-This is a low payload arm that can lift 10-20 oz max.
+++ /dev/null
-/*
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-/*
- Motor.
- Runs both motors back and forth.
-n
- This example code is in the public domain.
- */
-
-int motor1_enable = 10;
-int motor1a = 9;
-int motor1b = 8;
-int motor2_enable = 3;
-int motor2a = 4;
-int motor2b = 5;
-
-// ping sensors
-int left_trigger = 12;
-int left_echo = 11;
-int right_trigger = 7;
-int right_echo = 6;
-
-// the setup routine runs once when you press reset:
-void setup() {
- Serial.begin(9600);
-
- // initialize the digital pin as an output.
- pinMode(motor1_enable, OUTPUT);
- pinMode(motor1a, OUTPUT);
- pinMode(motor1b, OUTPUT);
- pinMode(motor2_enable, OUTPUT);
- pinMode(motor2a, OUTPUT);
- pinMode(motor2b, OUTPUT);
-
- // ping sensors
- pinMode(left_trigger, OUTPUT);
- pinMode(left_echo, INPUT);
- pinMode(right_trigger, OUTPUT);
- pinMode(right_echo, INPUT);
-
- digitalWrite(motor1_enable, LOW);
- digitalWrite(motor1a, LOW);
- digitalWrite(motor1b, LOW);
- digitalWrite(motor2_enable, LOW);
- digitalWrite(motor2a, LOW);
- digitalWrite(motor2b, LOW);
-}
-
-void
-on(int pin)
-{
- digitalWrite (pin, HIGH);
-}
-
-void
-off(int pin)
-{
- digitalWrite (pin, LOW);
-}
-
-int
-ping(int trigger, int echo)
-{
- int ping_time;
- on(trigger);
- delayMicroseconds(12);
- off(trigger);
- ping_time = pulseIn (echo, HIGH);
- if (ping_time <= 0)
- ping_time = 3000;
- return ping_time;
-}
-
-void motorsRun(int left, int right, int ms_delay) {
- // Set left motor direction:
- if (left > 0) {
- // Set left motor to go forward:
- digitalWrite(motor1a, HIGH);
- digitalWrite(motor1b, LOW);
- } else {
- // Set left motor to go backward:
- digitalWrite(motor1a, LOW);
- digitalWrite(motor1b, HIGH);
- left = -left; // Make left a positive value:
- }
- analogWrite(motor1_enable, left); // Start motor in right direction
-
- // Set left motor direction:
- if (right > 0) {
- // Set right motor to go forward:
- digitalWrite(motor2a, HIGH);
- digitalWrite(motor2b, LOW);
- } else {
- // Set right motor to go backward:
- digitalWrite(motor2a, LOW);
- digitalWrite(motor2b, HIGH);
- right = -right; // Make right a positive value:
- }
- analogWrite(motor2_enable, right); // Start motor in right direction
-
- delay(ms_delay); // Wait the specified amount of time
-}
-
-// the loop routine runs over and over again forever:
-void
-loop()
-{
- int left_speed = 0;
- int right_speed = 0;
-
- int left_ping = ping (left_trigger, left_echo);
- int right_ping = ping (right_trigger, right_echo);
-
- /*
- Serial.print ("left ping = ");
- Serial.print (left_ping);
-
- Serial.print (" right ping = ");
- Serial.println (right_ping);
- */
-
- if (left_ping < 400)
- {
- left_speed = 250;
- }
-
- if (right_ping < 400)
- {
- right_speed = 250;
- }
-
- if (left_speed == 0 && right_speed == 0)
- {
- // backup
- motorsRun(-250, -250, 2000);
- // turn around
- motorsRun(-250, 250, 3200);
- }
- else
- {
- motorsRun(left_speed, right_speed, 0);
- }
-}
+++ /dev/null
-/*
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-// This program implements table top challenge level ###?### --
-// The robot follows a flat vertical surface at a distance of a couple inches.
-
-// Set *debug* to 1 to enable debugging statements:
-int debug = 1;
-
-// Set *stop_at_edge* to 1 to have robot stop at the edge;
-// otherwise, it will back away from edge:
-int stop_at_edge = 0;
-
-// Set *table_top_threshold* to a value that captures the
-// tabletop distance for *your* robot:
-int table_top_threshold = 600;
-
-// Set *sonar_timeout* to a value a 200-300 uSec longer
-// that your table top threshold:
-
-int sonar_timeout = 1600;
-
-// Set *sonar_set_point* to a value that specifies the approximate
-// follow distance:
-
-int sonar_follow_distance = 800;
-
-// Pin definitions:
-int led = 13;
-int left_motor_enable = 3;
-int left_motor_a = 4;
-int left_motor_b = 5;
-int right_motor_enable = 10;
-int right_motor_a = 9;
-int right_motor_b = 8;
-int right_sonar_trigger = 7;
-int right_sonar_echo = 6;
-int left_sonar_trigger = 12;
-int left_sonar_echo = 11;
-
-// the setup routine runs once when you press reset:
-void setup() {
- // If debugging is enabled,
- if (debug) {
- // 115200 is the fastest "standard" baud rate for debugging.
- // Be sure to set the baud Tools=>Serial Monitor to 115200:
- Serial.begin(9600);
- }
-
- // Set LED output pin:
- pinMode(led, OUTPUT);
-
- // Set H-bridge control pins:
- pinMode(left_motor_enable, OUTPUT);
- pinMode(left_motor_a, OUTPUT);
- pinMode(left_motor_b, OUTPUT);
- pinMode(right_motor_enable, OUTPUT);
- pinMode(right_motor_a, OUTPUT);
- pinMode(right_motor_b, OUTPUT);
-
- // Set control pins for both left and right sonars:
- pinMode(left_sonar_trigger, OUTPUT);
- pinMode(left_sonar_echo, INPUT);
- pinMode(right_sonar_trigger, OUTPUT);
- pinMode(right_sonar_echo, INPUT);
-
- // Set all the pin values to predefined values:
- digitalWrite(led, HIGH);
- digitalWrite(left_motor_enable, LOW);
- digitalWrite(left_motor_a, LOW);
- digitalWrite(left_motor_b, LOW);
- digitalWrite(right_motor_enable, LOW);
- digitalWrite(right_motor_a, LOW);
- digitalWrite(right_motor_b, LOW);
- digitalWrite(left_sonar_trigger, LOW);
- digitalWrite(right_sonar_trigger, LOW);
- digitalWrite(left_sonar_trigger, LOW);
- digitalWrite(right_sonar_trigger, LOW);
-}
-
-void motors_run(int left, int right, int ms_delay) {
- // Set left motor direction:
- if (left > 0) {
- // Set left motor to go forward:
- digitalWrite(left_motor_a, HIGH);
- digitalWrite(left_motor_b, LOW);
- } else {
- // Set left motor to go backward:
- digitalWrite(left_motor_a, LOW);
- digitalWrite(left_motor_b, HIGH);
- left = -left; // Make left a positive value:
- }
- // Make sure we cap the speed at 255:
- if (left > 255) {
- left = 255;
- }
- analogWrite(left_motor_enable, left); // Start motor in right direction
-
- // Set right motor direction:
- if (right > 0) {
- // Set right motor to go forward:
- digitalWrite(right_motor_a, HIGH);
- digitalWrite(right_motor_b, LOW);
- } else {
- // Set right motor to go backward:
- digitalWrite(right_motor_a, LOW);
- digitalWrite(right_motor_b, HIGH);
- right = -right; // Make right a positive value:
- }
- // Make sure we cap the speed at 255:
- if (right > 255) {
- right = 255;
- }
- analogWrite(right_motor_enable, right); // Start motor in right direction
-
- delay(ms_delay); // Wait the specified amount of time
-}
-
-// This routine will trigger a HC-SR04 sonar that has its
-// trigger pin attached to *sonar_trigger* and its echo
-// pin attached to *sonar_echo*. If the echo response
-// takes longer than *timeout* microseconds, *timeout* is
-// returned.
-int ping(int sonar_trigger, int sonar_echo, int timeout) {
- int result = timeout;
- if (!digitalRead(sonar_echo)) {
- // *sonar_echo* is LOW, so we can safely trigger a 12uS
- // trigger pulse:
- digitalWrite(sonar_trigger, HIGH);
- delayMicroseconds(12);
- digitalWrite(sonar_trigger, LOW);
-
- // Time the resulting echo pulse. If the resulting echo pulse
- // is longer than *timeout*, *pulseIn* returns 0.
- result = pulseIn(sonar_echo, HIGH, timeout);
-
- if (result == 0) {
- // We timed out, so return *timeout*:
- result = timeout;
- }
- }
- // else *sonar_echo* is still high from the previous trigger;
- // return *timeout* when this occurs.
- return result;
-}
-
-// the loop routine runs over and over again forever:
-void loop() {
- // Get the left and right sonar values:
- int left_ping = ping(left_sonar_trigger, left_sonar_echo, sonar_timeout);
- int right_ping = ping(right_sonar_trigger, right_sonar_echo, sonar_timeout);
-
- // Set the left and right motor speed:
- int left_speed = left_ping - sonar_follow_distance;
- int right_speed = right_ping - sonar_follow_distance;
-
- // Debugging code:
- if (debug) {
- // Print some debugging information:
- Serial.print("lp=");
- Serial.print(left_ping);
- Serial.print(" rp=");
- Serial.print(right_ping);
- Serial.print(" ls=");
- Serial.print(left_speed);
- Serial.print(" rs=");
- Serial.println(right_speed);
-
- // Delay a little so that the serial port does not get
- // swamped with debugging information:
- delay(100);
- }
-
- // Set the motor speeds:
- motors_run(left_speed, right_speed, 0);
-}
+++ /dev/null
-(how to use this
- (connect your robot to your computer via usb cable)
- (open arduino ide)
- (in arduino ide, open pushbutton.ino)
- (hit the upload button)
- (hit control+shift+m,
- or go to the menu item tools, and down to serial monitor)
- (in the bottom right, select "9600 baud")
- (connect the breadboard and pushbutton as shown in "pushed.jpg")
- (hit the upload button in the arduino ide)
- (press the button!)
- (the message "button state changed!" should appear,
- and the arduino's built in LED should light up)
- (yaaay!))
+++ /dev/null
-/*
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of
- the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-// pin 13 controls the arduino's built-in LED
-int led_pin = 13;
-// connect the button to pin 2
-int button_pin = 2;
-// initially, the button is not pressed.
-// 0 means not pressed, 1 means pressed
-int button_value = 0;
-
-void setup(){
- Serial.begin(9600);}
-
-void loop(){
- // see if you can figure out how this logic works
- if(digitalRead(button_pin) != button_value){
- Serial.println("button state changed!");}
- // read the value of the button pin during this loop,
- // and save it in a box named "button_value"
- button_value = digitalRead(button_pin);
- // write the value to the led pin
- digitalWrite(led_pin, button_value);}
+++ /dev/null
-// challenge-bot
-// GNU AGPLv3 (or later at your option)
-// project available at these locations:
-// https://gitorious.org/ozzloy/challenge-bot
-// https://github.com/waynegramlich/challenge-bot
-
-// using
-// https://github.com/josefprusa/Prusa3/blob/master/box_frame/x-carriage.scad
-// as an example of how to code in scad
-
-scale=10;
-
-deck_width = 8;
-deck_length = 8;
-deck_depth = 3/16;
-deck_dimensions = [deck_width, deck_length, deck_depth];
-
-module deck(scale){
- cube(deck_dimensions * scale, center = true);}
-
-module collar_hole(scale){
- cylinder(h = 5/16 * scale, r = 0.362/2 * scale);}
-
-module nubbin_hole(scale){
- cylinder(h = 5/16 * scale, r = 0.145/2 * scale);}
-
-module mounting_screw_hole(scale){
- cylinder(h = 5/16 * scale, r = 0.114/2 * scale);}
-
-module wheel_mount_reinforcement(scale){
- diagonal = sqrt(deck_depth * deck_depth + deck_depth * deck_depth);
- difference(){
- cube([deck_depth * 2, deck_depth * 2, deck_depth * 2] * scale);
- translate([-(diagonal - deck_depth) / 2, 0, 0] * scale)
- rotate([45, 0, 0])
- translate([0, -(diagonal * 1.1 - deck_depth) / 2, 0])
- cube([diagonal * 2, diagonal * 2 * 1.1, deck_depth * 2] * scale);}}
-
-module wheel_motor_holes(scale){
- translate([0.5, 0.938, -1/16] * scale) {
- collar_hole(scale);}
- translate([0.5 + 0.875 - 0.425, 0.938, -1/16] * scale){
- nubbin_hole(scale);}
- translate([0.5 + 1.213 - 0.425, 0.938 - 0.687/2, -1/16] * scale){
- mounting_screw_hole(scale);}
- translate([0.5 + 1.213 - 0.425, 0.938 + 0.687/2, -1/16] * scale){
- mounting_screw_hole(scale);}}
-
-module wheel_mount(scale){
- width = 1.5;
- length = 2;
- depth = deck_depth;
-
- difference(){
- cube([width, length, depth] * scale);
- wheel_motor_holes(scale);}
- translate([2 * depth, 2 * depth, depth] * scale)
- rotate([0, 0, 180])
- wheel_mount_reinforcement(scale);
- translate([width, 2 * depth, depth] * scale)
- rotate([0, 0, 180])
- wheel_mount_reinforcement(scale);}
-
-module robot(scale){
- translate([0, 0, (deck_depth)/2 * scale]){
- color("blue") deck(scale);
- translate([1.5, 4, (deck_depth)/2] * scale)
- rotate([90, 0, 0])
- wheel_mount(scale);
- mirror([0, 1, 0])
- translate([1.5, 4, (deck_depth)/2] * scale)
- rotate([90, 0, 0])
- wheel_mount(scale);}}
-
-robot(scale);
+++ /dev/null
-// challenge-bot phase-2
-// GNU AGPLv3 (or later at your option)
-// project available at these locations:
-// https://gitorious.org/ozzloy/challenge-bot
-// https://github.com/waynegramlich/challenge-bot
-
-// using
-// https://github.com/josefprusa/Prusa3/blob/master/box_frame/x-carriage.scad
-// as an example of how to code in scad
-
-deck_dimensions = [8, 8, 3/16];
-
-module deck(){
- cube(deck_dimensions);}
-
-module wheel_mount(){
- difference(){
- cube([1.5, 2, 3/16]);
- // motor shaft and collar hole
- translate([0.5, 0.938, -1/16]) {
- cylinder(h = 5/16, r = 0.362/2, $fn = 100);}
- // nubbin hole
- translate([0.5 + 0.875 - 0.425, 0.938, -1/16]){
- cylinder(h = 5/16, r = 0.145/2, $fn = 100);}
- // mounting screw hole
- translate([0.5 + 1.213 - 0.425, 0.938 - 0.687/2, -1/16]){
- cylinder(h = 5/16, r = 0.114/2, $fn = 100);}
- translate([0.5 + 1.213 - 0.425, 0.938 + 0.687/2, -1/16]){
- cylinder(h = 5/16, r = 0.114/2, $fn = 100);}}}
-
-module wheel(){
- cylinder(r = 2.75/2, h = 3/16, $fn = 100);}
-
-color("blue") deck();
-rotate([90, 0, 0]) translate([1.5, -2, 0]) wheel_mount();
-rotate([90, 0, 0]) translate([1.5, -2, -(8+3/16)]) wheel_mount();
-color("red") rotate([90, 0, 0]) translate([2, -(.938), 3/16]) wheel();
-color("red") rotate([90, 0, 0]) translate([2, -(.938), -(8 + 3/8)]) wheel();
+++ /dev/null
-(how to use this
- (connect your robot to your computer via usb cable)
- (open arduino ide)
- (in arduino ide, open serial.ino)
- (hit the upload button)
- (hit control+shift+m,
- or go to the menu item tools, and down to serial monitor)
- (in the bottom right, select "9600 baud")
- (hit the reset button on the arduino)
- (you should see "hello computer!" each time you hit the reset button,
- (this means your arduino is talking to your computer when it starts))
- (yaaay!))
+++ /dev/null
-/*
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of
- the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-void setup(){
- Serial.begin(9600);
- Serial.println("hello computer!");}
-
-void loop(){}
+++ /dev/null
-// challenge-bot
-// GNU AGPLv3 (or later at your option)
-// project available at these locations:
-// https://gitorious.org/ozzloy/challenge-bot
-// https://github.com/waynegramlich/challenge-bot
-
-$fn = 60;
-
-// 3/16 inch in mm deck_depth = 4.7625;
-// 1/4 inch in mm - a little to be a squeeze fit
-deck_depth = 6.35 - 0.4;
-sonar_plate_width = 20;
-// sonar sensor measurements taken with calipers:
-// 10.82 in between, 42.33 outside, 15.82 diameter
-// measured diameter of 15.82 with calipers,
-// but when printed ends up being too small
-sonar_sensor_radius = 15.82 / 2 + 0.3;
-sonar_sensor_height = 13.8;
-between_sensor_centers = 15.82 + 10.82;
-sonar_plate_length = 3 + between_sensor_centers + sonar_sensor_radius + 3;
-sonar_holder_length = sonar_plate_length + 10;
-sonar_holder_width = sonar_plate_width + 3;
-sonar_holder_depth = 4;
-
-deck_holder_length = 30;
-deck_holder_width = sonar_holder_width;
-
-module sensors(){
- translate([between_sensor_centers / 2, 0, 0]){
- cylinder(r = sonar_sensor_radius, h = sonar_sensor_height);}
- translate([-between_sensor_centers / 2, 0, 0]){
- cylinder(r = sonar_sensor_radius, h = sonar_sensor_height);}}
-
-module sensor_holder(){
- difference(){
- cube([sonar_holder_length, sonar_holder_width, sonar_holder_depth]);
- translate([sonar_holder_length / 2, sonar_holder_width / 2, -0.05]){
- sensors();}}
- translate([sonar_holder_length, 0, 0]){
- cube([sonar_holder_depth + 0.3, deck_depth - 0.3, deck_depth - 0.3]);
- translate([sonar_holder_depth + 0.3, 0, 0]){
- // subtract a little bit (0.3) to make it fit
- cube([deck_depth - 0.3, sonar_holder_width, deck_depth - 0.3]);}}}
-
-module deck_holder(){
- cube([deck_holder_length, sonar_holder_depth, sonar_holder_width]);
- cube([sonar_holder_depth,
- sonar_holder_depth * 2 + deck_depth,
- sonar_holder_width]);
- translate([0, sonar_holder_depth + deck_depth, 0]){
- cube([deck_holder_length, sonar_holder_depth, sonar_holder_width]);}
- translate([sonar_holder_depth + deck_depth, 0, 0]){
- cube([sonar_holder_depth,
- sonar_holder_depth * 2 + deck_depth,
- sonar_holder_width]);}}
-
-module sonar_table_top_holder(){
- difference(){
- union(){
- cube([sonar_holder_length, sonar_holder_width, sonar_holder_depth]);
- translate([sonar_holder_length, 0, 0]){
- deck_holder();}}
- translate([between_sensor_centers / 2 + sonar_sensor_radius + 3,
- sonar_holder_width / 2,
- -1]){
- sensors();}
- // cut out a bit of the circle to make it 3d printable,
- // no severe overhang
- translate([3 + sonar_sensor_radius,
- sonar_holder_width - 3.025,
- sonar_holder_depth / 2 - 0.025]){
- cube([10, 6.1, sonar_holder_depth + .1], center = true);
- translate([between_sensor_centers, 0, 0]){
- cube([10, 6.1, sonar_holder_depth + .1], center = true);}}}}
-
-sensor_holder();
+++ /dev/null
-// challenge-bot
-// GNU AGPLv3 (or later at your option)
-// project available at these locations:
-// https://gitorious.org/ozzloy/challenge-bot
-// https://github.com/waynegramlich/challenge-bot
-
-// use $fn = 20 while developing, 100 when about to print
-// 20 will make previews fast
-// 100 will make printing smooth
-$fn = 20;
-
-wheel_depth = 6;
-wheel_radius = 68/2;
-
-module encoder_shaft(){
- // measured with calipers, checked against the motor shaft
- motor_shaft_big = 3.7; // radius, gets doubled in cylinder
- motor_shaft_small = 4.8; // total length of box
- motor_shaft_length = wheel_depth * 3 / 4;
-
- intersection(){
- cylinder(h = motor_shaft_length, r = motor_shaft_big, center = true);
- // x direction is multiplied by 2 because the radius of the cylinder
- // goes in both directions. the extra .1 is for overlap
- cube([motor_shaft_big * 2.1, motor_shaft_small, motor_shaft_length],
- center = true);}}
-
-module mounting_screw(){
- cylinder(h = wheel_depth * 1.1, r = 1, center = true);}
-
-module wheel(){
- translate([0, 0, wheel_depth / 2]){
- difference(){
- cylinder(h = wheel_depth, r = wheel_radius, center = true);
- translate([0, 0, wheel_depth / 4]){
- scale([1, 1, 1.1]){
- encoder_shaft();}}
- mounting_screw();
- for(i = [1 : 5]){
- rotate(i * 360/5, [0, 0, 1]){
- translate([0, 0, -0.6 * wheel_depth])
- between_spokes();}}
- translate([0, 0, wheel_depth / 4]){
- difference(){
- cylinder(h = wheel_depth / 1.2,
- r = 0.85 * wheel_radius,
- center = true);
- cylinder(h = wheel_depth / 1.2,
- r = 0.23 * wheel_radius,
- center = true);}}}}}
-
-module wheel_block(){
- cube([wheel_radius, wheel_radius, wheel_depth]);}
-
-module pie_slice(){
- intersection(){
- translate([0, 0, wheel_depth / 2]){
- cylinder(h = wheel_depth,
- r = 0.85 * wheel_radius,
- center = true);}
- translate([0, wheel_radius * 0.3, 0]){
- rotate([0, 0, (360 / 5) / 2]){
- intersection(){
- wheel_block();
- rotate([0, 0, 90 - 360 / 5])
- wheel_block();}}}}}
-
-module between_spokes(){
- minkowski(){
- pie_slice();
- cylinder(h = wheel_depth / 2, r = 1);}}
-
-wheel();