Uncategorized – Intro to Physical Computing: Student Work Spring 2020 https://courses.ideate.cmu.edu/60-223/s2020/work Intro to Physical Computing: Student Work Tue, 31 Mar 2020 14:46:00 +0000 en-US hourly 1 https://wordpress.org/?v=5.3.17 Smart Happy Plant Chamber https://courses.ideate.cmu.edu/60-223/s2020/work/smart-happy-plant-chamber/ Tue, 31 Mar 2020 10:55:40 +0000 https://courses.ideate.cmu.edu/60-223/s2020/work/?p=10372 [High quality pictures were not available, but I used all pictures I have. For the documentation, I used all pictures I have, and either reused pictures throughout the document depending on needs or recreated the model digitally.]

Overview

Smart Happy Plant Chamber is an Arduino project designed to assist growing plants by implementing automatic watering and lighting systems.

A digitally recreated picture of the completed model of chamber

The overview of a final chamber. The top has two holes each for a soil moisture sensor and motor hoses

The front (Holes for an LCD screen and three switches – each labeled)

 

Process images and review

I had two important decision points in my project each from the software and the physical structure.

  • Software

In the beginning, I was naive about designing the details of software so the machine was designed to water plants every two days and turn on the light 24 hours even without setting the default plant for the project. However, I realize not only making the physical result and making it work, but also those software choices matter in the end, so I did some research on plant growths.

I set it as house garden plants so that the user can use it for a wide range of plants. I found out, with the sensor I used a SparkFun moisture sensor, the soil moisture level should be around 50%, which is done at the household by watering the plants every 3-4 days. With these in consideration, I designed the automatic watering system to water the plant every 3 days; however, If the soil moisture level is below 50% of the water threshold point anytime during 3 days, the system will water the plant until it gets to the point, and restart the 3 days.

Moreover for the lighting, I had problems with the amount and the duration of lighting. I thought the more light the better, and white light only would be enough. However, plants also have biorhythm, so they need some time to “sleep” and to be “awake” just like us. Thus, I implemented a real-time clock into the software, so the lighting system turns on during the daytime, specifically from 7 A.M., so if the natural light is below the threshold, then the LEDs would turn on, and after 7 P.M., the lighting system turns off completely. On top of that, plants need different frequency ranges of light, from red to blue to white, which I could improve by software, fortunately. Thus, I changed my software for WS2801 LED strip to have those RGB values alternatively for each LED unit such as RGBW RGBW RGBW. I learned that conducting a project on real life is not always about technical issues, but I need to be significantly knowledgeable about the area that I am developing the technologies, which in this case was basic biology on plant growths.

  • Physical Structure

Regarding the physical structure of the project, I needed to break down the structure into the bottom and top because they serve different purposes. The bottom part mainly stores most elements such as circuits, Arduino Uno, motor. For aesthetic purposes, everything that does not need to be outside for functional reasons was stored inside the bottom. The top part is where users put the actual plant. Thus it needed a flat floor for the plant, and also a proper structure for LEDs, a light sensor, water pipes, and soil moisture sensor.

For the bottom part, I was planning to make it as a cuboid, and have an LCD screen and switches on one side. However, I realized if those elements are on a side of the cuboid that is perpendicular to the floor, it will not be user friendly. Thus, I changed the bottom part to be a trapezoid column, so that the front side can be tilted to 45 degrees and users can easily use it.

For the top part, I planned to have a cuboid frame like the initial image below, but I realize first, it is not good for plants to spray water on its leaves, and second, it’s unnecessarily complicated to design. Therefore, I changed it as having two columns that will have LEDs inside and a light sensor on a top, and directly put water pipes and a moisture sensor in a plant vase.

The original ideation drawing (It has a cuboid frame that carries watering and lighting systems, and does not have a bottom part that can store the rest of the model such as circuits)

The final model of chamber (The bottom is of trapezoid column with the tilted front. The top has two columns on each side for LED strips and a photoresistor)

The planar figure of the bottom box (a screenshot of dxf file used for laser cutting)

 

Discussion

In retrospect, the most exciting part of this project was ideation in the beginning when I brainstormed which problem I would want to address. I had multiple ideas of machines that can assist my life, but in the end, I narrowed it down to a few by thinking which problems are relatable to others just as to myself. One of the project ideas that I narrowed down in this way was “Ramen Cooker”. I personally cannot cook instant ramen, so I was planning to make a ramen cooker Arduino project in the beginning. I realized this is not a common problem people have, so it might not be relatable to many other people. Some people might even ask questions like “why would you need a ‘machine’ to cook ramen?” I think this thought process helped me decide which project to work on, and I ended up making a smart chamber that grows plants automatically. I got many positive comments about the project idea, especially on how it can be useful to people who cannot grow plants well like me such as “it’s a good idea to help people who struggle with growing plants” and “the idea is very useful for people who are not good at raising plants”. I think my effort in trying to find a problem I have but also what other people can accept and relate to have worked in this kind of project where I need to perform and introduce my project to others, which is the case of most projects. Therefore, for future projects, I would want to use the same thought processes in the ideation process.

However, one significant part I missed during the planning was time management. I thought, if I make the physical outcomes of the project with appropriate design, circuits, and codes that would be the end of this project, and if I want to check it, then I can just run it. It may be true for some other types of projects; however, unlike other projects, the ultimate functionality check for this project would be growing plants at least for a week. Just as one of the comments I got, “ [I] am not sure about the functionality because we didn’t test it with a plant…”, I could not see if the plants actually grow well with the machine in the end. From this trial and error, I have learned that whenever I start any project, I need to study the environment of a project and then decide how to evaluate the results in the end, and include that into the schedule. Moreover, I had an issue with overall time management as well. Finding necessary parts and wiring them into Arduino circuits took a few days more than I expected, so I had a delay in my whole project schedule; thus, in the end, I could not finish combining everything, which I regretted the most. This was also an issue of setting a precise timeline not too tight but with the considerations of some buffers.

There were also some changes that I needed to make due to the time restraint. Originally, I did plan to have multiple modes for different types of plants because they all require different water cycles and light intensity. If I get the opportunity to repeat but improve this project in the future, I am going to plan from the start to the end in the beginning of the project including a few days to revise the semi-final outcomes and also to evaluate the result in the way I wanted to use the machine which is growing a plant with it. Moreover, I would like to add different modes for different types of plants that people often have in their houses such as herbs, succulents, etc. I am going to add a button in the front panel that users can change the mode and set the plant they have, and will add some codes according to the changes.

 

Technical information

A hand-drawn schematic for the chamber

/*
 * Project2: Smart Happy Plant Chamber
 * Jeongyun Lee(jeongyul)
 * 
 * Description: Following is a code for Smart Happy Plant Chamber. 
 * For the lighting system, during the daytime, it turns on the LED depending on the amount of light determined by the photoresistor 
 * value. During the night time, it always turns off the LED. However, when the LED manual switch is on, 
 * no matter of the light value and the real time, it turns on the LED.
 * For the watering system, it evaluate whether the plant needs more water from the soil moisture sensor value,
 * and if the soil is dry, it turns on the water pump and vice versa. However, when the water manual switch is on, 
 * no matter of the soil mositure value, it turns on the water pump.
 * 
 * Collaboration: N/A
 * Reference: I used a part of "Adafruit Neopixel" Library "simple" example codes to initiate LED strip 
 * 
 * Pin mapping:
 * 
 * pin    / mode    / description
 * -------/---------/------------
 * 9        input     water switch
 * 10       input     LED switch
 * A0       input     photoresistor
 * 4        output    water pump 
 */

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "RTClib.h"
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

LiquidCrystal_I2C screen(0x27, 16, 2);

const int WATERSWITCHPIN2 = 9; //water manual button
const int LIGHTSWITCHPIN3 = 10; //light manual button
const int WATERPIN = 4; //water pump pin
const int LEDPIN = 6; //led strip pin
const int MOISTUREPIN1 = A1; //moisture sensor analaog pin
const int LIGHTSENSORPIN = A0; //light sensor pin
const int NUMPIXELS = 24;

const int moistThres = 511; //below 511 = dry, above 511 = enough water
const int lightThres1 = 50; //below lightThres1: very deem
const int lightThres2 = 100; //below lightThres2: mildly deem

//current status for Automatic/Manual, for LED, and for water pump
String curStat = "AUTO";
String LEDstat = "ON ";
String WATERstat = "ON ";


RTC_DS3231 rtc;

Adafruit_NeoPixel pixels(NUMPIXELS, LEDPIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pinMode(WATERSWITCHPIN2, INPUT);
  pinMode(LIGHTSWITCHPIN3, INPUT);
  pinMode(LIGHTSENSORPIN, INPUT);

  pinMode(WATERPIN, OUTPUT);
  digitalWrite(WATERPIN, LOW);

  screen.init();
  screen.backlight();
  screen.home();
  screen.print("tree happy!");
  delay(7000);
  screen.clear();

//some codes from basic real time clock library 
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
#ifndef ESP8266
  while (!Serial); // for Leonardo/Micro/Zero
#endif
  pixels.begin();
  Serial.begin(9600);

//the error cases when the real time clock does not work
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // If the RTC have lost power it will sets the RTC to the date & time this sketch was compiled in the following line
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
} 

//A helper function for turning on a side of LED strip
void led1() {
  pixels.setPixelColor(0, pixels.Color(0, 0, 255));
  pixels.setPixelColor(1, pixels.Color(0, 255, 0));
  pixels.setPixelColor(2, pixels.Color(255, 0, 0));
  pixels.setPixelColor(3, pixels.Color(255, 255, 255));
  
  pixels.setPixelColor(4, pixels.Color(0, 0, 255));
  pixels.setPixelColor(5, pixels.Color(0, 255, 0));
  pixels.setPixelColor(6, pixels.Color(255, 0, 0));
  pixels.setPixelColor(7, pixels.Color(255, 255, 255));
  
  pixels.setPixelColor(8, pixels.Color(0, 0, 255));
  pixels.setPixelColor(9, pixels.Color(0, 255, 0));
  pixels.setPixelColor(10, pixels.Color(255, 0, 0));
  pixels.setPixelColor(11, pixels.Color(255, 255, 255));

  pixels.show();
}

//A helper function for turning on the other side of LED strip
void led2 () {
  pixels.setPixelColor(12, pixels.Color(0, 0, 255));
  pixels.setPixelColor(13, pixels.Color(0, 255, 0));
  pixels.setPixelColor(14, pixels.Color(255, 0, 0));
  pixels.setPixelColor(15, pixels.Color(255, 255, 255));

  pixels.setPixelColor(16, pixels.Color(0, 0, 255));
  pixels.setPixelColor(17, pixels.Color(0, 255, 0));
  pixels.setPixelColor(18, pixels.Color(255, 0, 0));
  pixels.setPixelColor(19, pixels.Color(255, 255, 255));

  pixels.setPixelColor(20, pixels.Color(0, 0, 255));
  pixels.setPixelColor(21, pixels.Color(0, 255, 0));
  pixels.setPixelColor(22, pixels.Color(255, 0, 0));
  pixels.setPixelColor(23, pixels.Color(255, 255, 255));

  pixels.show();
}

//A helpter function for turning on/off the water pump
void water() {
  delay(10);
  int moistVal = analogRead(MOISTUREPIN1);
  //when there is enough mositure in soil: water pump off
  if (moistVal >= moistThres) {
      WATERstat = "OFF";
      digitalWrite(WATERPIN, LOW);
  }
  //when there isn't enough mositure in soil: water pump on
  else {
      WATERstat = "ON ";
      digitalWrite(WATERPIN, HIGH);
      delay(5000);
  }
}

//A helper function for turning on/off the LEDs
void light(int hour) {
  int lightVal = analogRead(LIGHTSENSORPIN);
  
  //Daytime
  if (hour >= 7 && hour <= 16) {
    if (lightVal < lightThres1) {
      //when the light is very deem
      LEDstat = "ON ";
      led1();
    }
    else if (lightVal >= lightThres1 && lightVal < lightThres2) {
      //when the light is mildly deem
      LEDstat = "ON ";
      led1();
      led2();
    }
    else {
      //when the light is enough
      LEDstat = "OFF";
      pixels.clear();
    }
  }
  
  //Night time
  else {
    //at night, the light is always off
    digitalWrite(LEDPIN, LOW);
    LEDstat = "OFF";
  }
}

void loop() {
  DateTime now = rtc.now();
  
  //manual mode buttons
  int waterState = digitalRead(WATERSWITCHPIN2); //water manual on/off
  int lightState = digitalRead(LIGHTSWITCHPIN3); //water manual on/off
  
  //Setting modes
  //Water: manual, LED: manual
  if (waterState == HIGH && lightState == HIGH)
  {
    curStat = "MANU";
    digitalWrite(WATERPIN, HIGH);
    digitalWrite(LEDPIN, HIGH);
    LEDstat = "ON ";
    led1();
    led2();
  }
  //Water: manual, LED: auto
  else if (waterState == HIGH && lightState == LOW)
  {
      curStat = "MANU";
      digitalWrite(WATERPIN, HIGH);
      light(now.hour());
  }
  //Water: auto, LED: manual
  else if (waterState == LOW && lightState == HIGH)
  {
    curStat = "MANU";
    water();
    digitalWrite(LEDPIN, HIGH);
    led1();
    led2();
    LEDstat = "ON ";
    //delay(500);
  }
  //Water: auto, LED: auto
  else
  {
    curStat = "AUTO";
    water();
    light(now.hour());
  }

  //LCD screen print 
  screen.clear();
  screen.setCursor(1, 0);
  screen.print("Now: ");
  screen.setCursor(6, 0);
  screen.print(now.hour());
  screen.setCursor(8, 0);
  screen.print(":");
  screen.setCursor(9, 0);
  screen.print(now.minute());
  screen.setCursor(12, 0);
  screen.print(curStat); 
  screen.setCursor(1, 1);
  screen.print("L: ");
  screen.setCursor(4, 1);
  screen.print(LEDstat);
  screen.setCursor(7, 1);
  screen.print("  W: ");
  screen.setCursor(12, 1);
  screen.print(WATERstat);
  Serial.print(analogRead(LIGHTSENSORPIN));
}
]]>
Double Transducer: Vibration Strength to Color https://courses.ideate.cmu.edu/60-223/s2020/work/double-transducer-vibration-strength-to-color/ Sun, 16 Feb 2020 01:15:38 +0000 https://courses.ideate.cmu.edu/60-223/s2020/work/?p=9373 Title

Double Transducer – Vibration Strength to Distance to Color

 Video of the machine doing it’s task

Description

The machine created first senses vibration strength using an accelerometer and depending on the vibration strength, will rotate a servo motor to a specific angle between 0 and 90 degrees. The rotation of the servo motor will push or pull a toy car to a specific linear location. This distance will be detected by an IR sensor and depending on the sensor’s reading, it will change the color of a diffused RGB LED.

Progress Images

accelerometer casee

Creating a case for the accelerometer

servo motor car

Creating a servo motor that pushes and pulls a toy car

RGB LED

Configuring of the RGB LED

Process Discussion

1. Detecting vibration strength

We decided to use an accelerometer to detect vibration strength. In order to ensure that it is stable, we built a case for it and ensured that it is attached to our board.

The readings for the accelerometer at rest was around 300 for all the three axis. We decided that we wanted to take into account all the different axis to detect the strength of the vibration to provide with more flexibility and accuracy for the orientation of the source of vibration. One thing we realized was that depending on slight movements of the case on the board or the position of the entire board, the readings for the accelerometer would change. This was not ideal because it meant that the baseline was constantly changing between runs. We decided to add a momentary pushbutton to set the baseline of the values.

We calculated the strength of vibration by taking the average of the absolute difference between the actual x, y and z axis accelerometer reading with the baseline x, y, z axis accelerometer reading.

In order to test out the accuracy of our vibration strength sensor, we used a pancake sensor, which the team before us are using. By using the 5V and 3.3V pins, we were able to create different vibration strengths. With this, we could also figure out what would be the upper bound of the vibration strength.

It was challenging working with the pancake motor because the legs were really short. In order to solve this, we would strip the legs and solder them to more sturdy wires. However, it was very fragile and did not last long. In the end, we settled with taping the pancake motor to the sensor.

2. Improving accuracy of intermediate step

One of the problems about using a servo motor to move a toy car is the accuracy of it.  In order to improve the accuracy, we decided to create railings for the car so that it would make it a linear movement.

 

Another thing we did to improve the readings from the IR sensor is attaching a black aluminium foil to the front of the toy car.

attaching foil to toy car

Increasing accuracy of IR sensor reading

3. selecting the colored lights

We took some time to figure out how to get the RGB LED working because there were different types of LED – some LEDs would require connection to ground whereas some others would require us to connect to power. We also found out that the readings for the LED we were using was inverse of the software code we had to write.

After we got past figuring out how to make the LED light up, we had to decide how to make the colors change from red to purple. We wanted to make it very gradual, where it would have multiple intermediate colors between two main colors (like red and yellow would go through the entire shade of red to red-orange, to orange to orange-yellow). This was taking a lot of time and we felt that it would be more efficient to hard code the specific colors.

One last problem we faced was that it was hard for the next team to detect the colors from the RGB LED we were using. We then explored different alternatives available and realized that diffused RGB LED make the colors eas

rgb led comparisonn

rgb led comparison

Comparing between RGB LED and Diffused RGB LED

testing diffused RGB LED

Testing diffused RGB LED

Schematic

Code submission

/*
 * Project 1: Double Transducer
 * Estevan Chairez & Zoe Teoh
 * 
 * Description:  
 * 
 * Double Transducer - Vibration Strength to Distance to Color
 * -------------------------------------------------------------
 * The machine created first senses vibration strength using an accelerometer and 
 * depending on the vibration strength, will rotate a servo motor to a specific angle 
 * between 0 and 90 degrees. The rotation of the servo motor will push or pull a toy 
 * car to a specific linear location. This distance will be detected by an IR sensor 
 * and depending on the sensor's reading, it will change the color of a diffused RGB LED.
 * 
 * PHASE 1: Vibration strength
 * This code will wait for momentary button to be pressed to start
 * storing all the values of the accelerometer and convert it into a single value.
 * 
 * PHASE 2: Distance
 * This will then be converted to a value between that a servo can accept. This value
 * will then cause the servo to push a car closer/further to an IR Sensor.
 * 
 * PHASE 3: Color
 * The IR Sensor will detect the car's distance and convert
 * that to a separate RGB value with a function to power an RGB LED with a 
 * certain color.
 * 
 * 
 * Pin mapping:
 * 
 * pin   | mode   | description
 * ------|--------|------------
 * A0      input    Y-Axis of accelerometer   
 * A1      input    X-Axis of accelerometer 
 * A2      input    Z-Axis of accelerometer
 * A3      input    IR Sensor
 * SCL     output   LCD Screen
 * SDL     output   LCD Screen
 * 2       input    momentary push button
 * 6       output   servo motor
 * 9       output   blue LED
 * 10      output   green LED
 * 11      output   red LED
 */
 
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Servo.h>


const int RED = 11;
const int GREEN = 10;
const int BLUE = 9;
const int Z = A2;
const int Y = A0;
const int X = A1;
const int SERVO = 6;
const int IR = A3;
const int BUTTON = 2;

int baseX;
int baseY;
int baseZ;
int angle;
int middle_1;
int input;
int accel_difference;
bool start = false;


// RGB values to send to LED
int colors[][3] = {{255, 0, 0}, {255, 255, 0}, {0, 255, 0}, {0, 255, 255}, {0, 0, 255}, {255, 0, 255}};

// command to send RGB [R, G, B] color to RBG LED
void rgb(int red_light_value, int green_light_value, int blue_light_value) {
  analogWrite(RED, 255 - red_light_value);
  analogWrite(GREEN, 255 - green_light_value);
  analogWrite(BLUE, 255 - blue_light_value);
}


// command to convert an int to a color in R, G, B spectrum "int -> [R, G, B]"
void intToRGB(int val) {
  int r = colors[val][0];
  int g = colors[val][1];
  int b = colors[val][2];
  rgb(r, g, b);
}


// set up LCD and display certain values in the form
// i: input  m: middle_1
//              middle_2  o: output
//
void lcd(LiquidCrystal_I2C screen, int input, int middle_1, int middle_2, int output) {
  input = constrain(input, 0, 99);
  middle_1 = constrain(middle_1, 0, 99);
  middle_2 = constrain(middle_2, 0, 99);
  output = constrain(output, 0, 99);
  
  screen.clear();
  screen.setCursor(0, 0);
  screen.print("i:");
  screen.setCursor(2, 0);
  screen.print(input);
  screen.setCursor(6, 0);
  screen.print("m:");
  screen.setCursor(8, 0);
  screen.print(middle_1);
  screen.setCursor(8, 1);
  screen.print(middle_2);
  screen.setCursor(12, 1);
  screen.print("o:");
  screen.setCursor(14, 1);
  screen.print(output);
  delay(500);
}

LiquidCrystal_I2C screen(0x27, 16, 2);
Servo servo;

void setup() {
  // ACCELEROMETER Setup
  pinMode(Z, INPUT);
  pinMode(Y, INPUT);
  pinMode(X, INPUT);

  // LCD Screen Setup
  screen.init();
  screen.backlight();
  screen.home();

  // SERVO Setup
  servo.attach(SERVO);

  // OTHER PINS 
  pinMode(BUTTON, INPUT);
  pinMode(RED, OUTPUT);
  pinMode(BLUE, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(IR, INPUT);

  
  Serial.begin(9600);
}


void loop() {

                                                                                   
  // ACCELEROMETER CODE

  int zVal = analogRead(Z);
  int yVal = analogRead(Y);
  int xVal = analogRead(X);
  int buttonState = digitalRead(BUTTON);

  

  // will not do anything until momentary push button is pressed
  if (buttonState && !start) {

    baseX = xVal;
    baseY = yVal;
    baseZ = zVal;
    start = true;
  } else {

    accel_difference = abs(baseX - xVal) + abs(baseY - yVal) + abs(baseZ - zVal);
    input = map(accel_difference, 0, 250, 0, 99);

    // CAR - SERVO CODE
    if (baseX != 0 && baseY != 0 && baseZ != 0){
      angle = map(accel_difference, 0, 250, 0, 90);
      servo.write(angle);
      middle_1 = map(angle, 0, 90, 0, 99);
    }
    
  
    
    // DISTANCE SENSOR CODE
    int dis = analogRead(IR);
    int middle_2 = map(dis, 465 , 300, 0, 99);
  
    
    // LED CODE
    int convertedVal = constrain(map(dis, 465, 300, 0, 5), 0, 5);
    intToRGB(convertedVal);
    int output = map(convertedVal, 0, 5, 0, 99);
  
  
    // LCD DISPLAY
    lcd(screen, input, middle_1, middle_2, output);
  }
    
}

 

]]>
Cat Food Access Control https://courses.ideate.cmu.edu/60-223/s2020/work/cat-food-access-control/ Tue, 14 Jan 2020 02:50:34 +0000 https://courses.ideate.cmu.edu/60-223/s2020/work/?p=9137 Project Title: Cat Food Access Control

Project Creator: Becky Stern

Short Description: Becky Stern designed an automated food bowl for her cat that should not eat food at night in order to follow the insulin schedule. The bowl closes between midnight and 7:30 am, functioning by using Network Time Protocol(NTP).

 

Cat eating food while the bowl is open (daytime)

Response: I think it is great that the project creator customized her own automated bowl for her dog in a minimal but effective way. Many products in the market are overpriced and sometimes have unnecessary functions or details, but this one is simple and it works well.

Like she mentioned, cats that are younger and stronger could open the lid because it is not very secure. I think an improvement to resolve this would be making the lid fit tightly below the rim of the bowl so that it is difficult for cats to open, instead of having the lid close above the rim.

]]>
Mini CNC Machine https://courses.ideate.cmu.edu/60-223/s2020/work/mini-cnc-machine/ Mon, 13 Jan 2020 22:44:55 +0000 https://courses.ideate.cmu.edu/60-223/s2020/work/?p=9148 Project Title: How To Make Mini CNC Machine

Creator: Shubham Suresh

Short Description: An Electronics Engineer and hobbyist created a mini CNC machine at home using old computer parts (DVD writer) and Arduino UNO. The machine is able to both write and draw, and it requires 11 steps and requires very little and accessible materials.

Step 8: Programming and Operation

Response: As an architecture student, I have always wanted my own fabrication machines (i.e. laser cutter, 3D printer, CNC machine). To be able to make a mini CNC machine using Arduino and with ease is fascinating to me!

]]>