# Results <video width="640" height="440" controls> <source src="./GrpProjectVideo.mp4" type="video/mp4"> </video> # Brainstorming Ideas We did some research and found the following projects 1. [Cat laser (Pan Tilt Motion)](https://fabacademy.org/2021/labs/taipei/assignments/week10/) 2. [Pen Plotter](https://fabacademy.org/2021/labs/berytech/Machine_Building.html) Steven chimed in and gave a few suggestions 1. Panorama capture tool 2. Egg Plotter 3. CNC machines To make this assignment to be more manageable, we've decided to embark on the Panorama Capture Tool project. ## Drawing inspiration from available examples <img src="./dolly_example.jpg" width="480" height="480" /> We took a look at this design. Making the dolly motorized at the stand however was too big of an undertaking. Some of the things we identified that needed to be designed are: 1. Linear Motion 2. Camera Mount 3. Left and Right Stands Next we did a task allocation among ourselves. Jon will be designing most of the mechanical aspects of the Dolly, while Bryan will focus on automating the entire Camera Dolly procedure. # Mechanical Design _Goal: machine that has mechanism + actuation + automation, manually operate it._ ### List of Materials These were the items that we acquired for the project. |Item|Quantity| |----|--------| |Timing belt + bore|~1meter| |Ball Bearing (diameter 8mm)|1| |Stepper motor|1| |Stepper driver (TB6600)|1| |20mmx20mm Aluminium profile 600mm|1| |M5 screws|4| |M5 nuts|8| |M5 washers|4| |M3 screws|2| |M3 nuts|2| |Breadboard|1| These were the items that needed to be fabricated: |Item|Quantity| |----|--------| |[Rollers]()|4| |[Movement platform]()|1| |[Phone holder]()|1| |[Stepper holder]()|1| |[Ball bearing holder](./roller_holder.f3d)|1| |[Axle clamp](./axle.stl)|1| |[M8 spacers]()|1| |[M4 spacers]()|1| |Micro-Controller [traces](./hello_world.png) [outline](./hello_world.outline.png)|1| ## Mechanism The main mechanism is a single axis linear motion. Since the example above motorizes near the camera mount and seemed a bit complicated, we decided to take inspiration from a more replicable design. Looking at the various Ender 3 V2 in our lab, we noticed that there was potential in reproducing the x-axis linear motion. <img src="./ender3_docs_image.jpg" width="480" height="480" /> To start, we designed a move platform for the camera. This is done by 3D printing M4 spaces and Rollers, and screwed on a piece of 3mm acrylic. Next, we designed a holder for the camera (in this case it is our phone). It sits on a piece of 3mm acrylic. We were debating over to use a singular platform or just have one single platform has both functionalities. To save some time and prototype more efficiently, we decided to go with the latter, where the moving platform is constructed first, then the camera mount is screwed on the moving platform. This is a test of moving the platform manually. We zip tied the timing belt on the moving platform and tried to pull it to check for smoothness of motion. ## Actuation The actuation is our stepper motor, where we convert the rotation motion to linear motion, similar to how Ender 3 oeprates. To realize this, we need to construct the following: 1. Stepper holder 2. Ball bearing holder ### Right hand side holder Designed a clamp to hold the stepper, and have space to fit the timing belt. This part was 3D printed. <img src="./left_stepper_holder.jpg" width="480" height="480" /> ### Ball Bearing holder + Dolly Left Side Support The dolly is supported on the left hand side by a stand. We measured the height from the stepper and the bottom support, and placed the ball bearing axis at the same height as the right hand side. This component was 3D printed. The construction was an 8mm diameter axis through the 3D print. spacers were used to offset the ball bearing to the center, and its position fixed. <iframe src="https://myhub.autodesk360.com/ue2fa8fb0/shares/public/SH35dfcQT936092f0e43df1486e4632d83e7?mode=embed" width="640" height="480" allowfullscreen="true" webkitallowfullscreen="true" mozallowfullscreen="true" frameborder="0"></iframe> ### Driving the Stepper Motor <img src="./circuit_diagram.jpg" width="480" height="480" /> For the microcontroller, we decided to use [Bryan's ATTiny1614 Microcontroller](https://fabacademy.org/2022/labs/singapore/students/bryan-tee/assignments/week06/) as he has pulled out all of the pins for his hello world board. - [.sch](https://fabacademy.org/2022/labs/singapore/students/bryan-tee/files/week06/hello_world.sch) - [.brd](https://fabacademy.org/2022/labs/singapore/students/bryan-tee/files/week06/hello_world.brd) We decided to drive the stepper at 12Vs, and power the Mircontroller via USB. ### Testing [Code to control stepper](./test-stepper.ino) We have decided to use just Bang Bang motion, as the Dolly's speed should be constant to take a perfect Panorama Shot. ``` #define EN 0 // PA4 #define PUL 1 // PA5 #define DIR 2 // PA6 #define REV 800 // steps/rev => 38mm #define STEP_DIST 38 // mm void rotate_CW(float distance) { Serial.print("Rotate CW by "); Serial.println(distance); int steps = (distance / STEP_DIST) * REV; digitalWrite(EN, LOW); digitalWrite(DIR, LOW); for(int i = 0; i < steps; i++) { digitalWrite(PUL, LOW); delay(1); digitalWrite(PUL, HIGH); } digitalWrite(EN, HIGH); } void rotate_CCW(float distance) { Serial.print("Rotate CCW by "); Serial.println(distance); int steps = (distance / STEP_DIST) * REV; digitalWrite(EN, LOW); digitalWrite(DIR, HIGH); for(int i = 0; i < steps; i++) { digitalWrite(PUL, LOW); delay(1); digitalWrite(PUL, HIGH); } digitalWrite(EN, HIGH); } void rotate(float distance) { if (distance > 0) { rotate_CW(distance); } else { rotate_CCW(-distance); } } void setup() { // put your setup code here, to run once: pinMode(EN, OUTPUT); pinMode(PUL, OUTPUT); pinMode(DIR, OUTPUT); // initialize stepper digitalWrite(PUL, HIGH); Serial.begin(9600); } void loop() { // put your main code here, to run repeatedly: if (Serial.available()) { float input_distance = Serial.parseFloat(); if (input_distance > 0 || input_distance < 0) { // filter out 0 values rotate(input_distance); } delay(1000); } } ``` <video width="640" height="440" controls> <source src="./test_actuator.mp4" type="video/mp4"> </video> We tested to see that the stepper moves in our intended distance, which means the abstraction would start from moving the platform by `x` distance. ## Automation This is the panorama code logic flowchart: <img src="./logic_flow_min.jpg" width="480" height="480" /> [Code for Panorama view](./panorama.ino) ``` #define EN 0 // PA4 #define PUL 1 // PA5 #define DIR 2 // PA6 #define LIMIT_SW 8 // PA3 #define GO_SW 9 //PA2 #define REV 800 // steps/rev => 38mm #define STEP_DIST 38 // mm / rev #define MAX_DIST 550 // 550mm // Global variables bool is_zeroed = false; float curr_dist = 0; float delta_dist = (STEP_DIST * 1.0) / REV; // Note: define CCW as negative distance void rotate_CW(float distance) { Serial.print("Rotate CW by "); Serial.println(distance); int steps = (distance / STEP_DIST) * REV; digitalWrite(EN, HIGH); digitalWrite(DIR, LOW); for (int i = 0; i < steps; i++) { digitalWrite(PUL, LOW); delay(1); digitalWrite(PUL, HIGH); curr_dist += delta_dist; if (curr_dist + delta_dist > MAX_DIST) break; } digitalWrite(EN, LOW); Serial.println("Done CW"); } void rotate_CCW(float distance) { Serial.print("Rotate CCW by "); Serial.println(distance); int steps = (distance / STEP_DIST) * REV; digitalWrite(EN, HIGH); digitalWrite(DIR, HIGH); for (int i = 0; i < steps; i++) { digitalWrite(PUL, LOW); delay(1); digitalWrite(PUL, HIGH); curr_dist -= delta_dist; if (curr_dist - delta_dist < 0) break; } digitalWrite(EN, LOW); Serial.println("Done CCW"); } void rotate(float distance) { if (distance > 0) { rotate_CW(distance); } else { rotate_CCW(-distance); } } void zeroPan() { digitalWrite(EN, HIGH); digitalWrite(DIR, HIGH); while (!is_zeroed) { digitalWrite(PUL, LOW); delay(1); digitalWrite(PUL, HIGH); is_zeroed = !digitalRead(LIMIT_SW); } digitalWrite(EN, LOW); rotate_CW(10); is_zeroed = false; Serial.println("Done zero!"); curr_dist = 0; } void runPan() { rotate_CW(MAX_DIST); } void setup() { // put your setup code here, to run once: pinMode(EN, OUTPUT); pinMode(PUL, OUTPUT); pinMode(DIR, OUTPUT); pinMode(LIMIT_SW, INPUT); pinMode(GO_SW, INPUT); // initialize stepper // digitalWrite(EN, HIGH); digitalWrite(PUL, HIGH); Serial.begin(9600); zeroPan(); } void loop() { // put your main code here, to run repeatedly: if (Serial.available()) { float input_distance = Serial.parseFloat(); if (input_distance > 0 || input_distance < 0) { rotate(input_distance); } delay(1000); } bool go = !digitalRead(GO_SW); if (go) { runPan(); delay(2000); zeroPan(); } } ``` Results are as per video. Here is a demo of the logic: <video width="640" height="440" controls> <source src="./panorama_test.mp4" type="video/mp4"> </video> <br/> This is a screenshot of some of the circuits that we still have in our archive. The machine has since been dismantled and repurposed for other projects. <img src="./partial_circuit_2.jpg" width="720" /> The circuit itself was quite messy, we wired it according to the circuit diagram above, and powered the system with a lab bench power supply, as shown in the video at the top of the page at timestamp 0:45. Our teammate Jon had lost his phone, which contained better images. Nonetheless, I think the "better images" are still as messy as the one shown above. # Future improvements 1. Make Microcontroller specific for Dolly 2. Better Roller designs 3. Increase length of Dolly for more effective Panorama shots ## Some fun works that were done but not included: Stepper clip that worked really well. This was intended to be used with the custom microcontroller, and pasted at the back of the stepper. <iframe src="https://myhub.autodesk360.com/ue2fa8fb0/shares/public/SH35dfcQT936092f0e43dafe88fc359a66c5?mode=embed" width="640" height="480" allowfullscreen="true" webkitallowfullscreen="true" mozallowfullscreen="true" frameborder="0"></iframe>