Uncategorized – Intro to Physical Computing: Student Work Fall 2021 https://courses.ideate.cmu.edu/60-223/f2021/work Intro to Physical Computing: Student Work Tue, 09 Nov 2021 14:07:38 +0000 en-US hourly 1 https://wordpress.org/?v=5.8.9 Team Apricots: Interview with Connie https://courses.ideate.cmu.edu/60-223/f2021/work/team-apricots-interview-with-connie/ Tue, 09 Nov 2021 14:07:38 +0000 https://courses.ideate.cmu.edu/60-223/f2021/work/?p=14544 Introduction:

This project is done with the intent of creating an assistive device for a client who faces certain challenges, and to start it off, an interview was done to help familiarize the team and client. This meeting was conducted in October 2021, with the purpose of Team Apricots, consisting of Peter, Evangeline, and Nathan, learning more about their client, Connie, and what sort of challenges their project could address. The meeting was held online through Zoom, with each individual in their own separate spaces.

Agenda:

In terms of setting up the meeting, a text group chat was created, and from there, the group was able to come up with an appropriate time for said meeting.

Meeting Agenda (follows the suggested agenda on the course website):

  • Group member introductions followed by Connie’s introduction.
    • talk about her disability and what that means for her
    • ask about what she does for a living and her day to day lifestyle
    • share personal stories about interests/hobbies
  • Overview of expectations for the final product that we will be developing
    • Non-professionals, all new to building devices from a hands on approach
    • Not intended to invent something completely new and scalable as a product
    • We are trying to build a useful prototype of an assistive device
    • Ending with a reasonably well done product at the end of the 5 week timeframe
  • Discussion of daily tasks that Connie has trouble with and potential solutions
    • Start with asking her if she has any specific tasks that she struggles with
      • where do these problems come from?
      • what would need to happen for this to be solved?
      • how does she generally work around this problem?
    • Ask about hobbies that she likes doing at home
      • what are some struggles she has with these hobbies?
      • what are workarounds that she has found for any problems she has?
  • Whiteboard initial ideas and drawings
  • Make sure we share contact info, emails, phone numbers, best way to contact each other

Summary:

The interview began with brief introductions, and then, what specific disabilities Connie has. However, in terms of the bulk of the interview, most of the content of the interview involved the team learning more about what challenges Connie and people that have similar disabilities to her face in their day-to-day life, rather than brainstorm specific ideas to address said challenges. As the team learned more about Connie, it was more clear what sort of device we could build in terms of feasibility, as well as what things to look out to help make an assistive device that was not intrusive. For instance, because Connie does not have much hand dexterity or strength, it becomes difficult when it comes to activities such as cutting meat, unlocking her door, and gripping shampoo bottles. Other tasks, such as tying shoes or putting socks were difficult, and even on-market “solutions” such as sock aids were not that comfortable or easy to use. We also learned about more about the wheelchair she uses, and certain limitations that come with her wheelchair. Connie mentioned how her wheelchair has hooks located on the back of her wheelchair, but for Connie, the accessibility of these hooks is not satisfactory, and additional side hooks would also be helpful. In addition to problems specific to Connie herself, Connie also outlined more general issues for other people with disabilities, such as how certain products/services are hard to get or access because these people live in rural areas. If their products or services require external management or maintenance, then this becomes even more difficult and frustrating for people in more rural areas.

Peter drawing out image of an idea that could help with turning door knobs.

Image of some of the notes taken during the interview.

Reflection:

Looking back at how the interview meeting, it went pleasantly well, as some of the team felt a bit nervous going into the interview, but as it progressed, a good pace and ambience was established. We did not experience any sort of long lulls in our interview, and Connie was able to articulate clearly difficulties she had and was eager to answer any questions we had. While the interview did not go exactly as planned, the insights the team was able to obtain was conducive in ideation. If one aspect was lacking, it would have helped for Connie to have shown us her wheelchair and the extent of her physical strength and dexterity, but unfortunately, time ran out before we could get that far. What was perhaps unexpected, was how everyday tasks that we would do without second thought were not as simple for people with certain disabilities, and coming out the interview, this made a strong impression on us. Another point that stood out to the group was how some services and products’ accessibility was not equal across all populations, as rural areas have more difficulty.

]]>
Out the Door Cabinet https://courses.ideate.cmu.edu/60-223/f2021/work/out-the-door-reminder/ Tue, 02 Nov 2021 13:01:14 +0000 https://courses.ideate.cmu.edu/60-223/f2021/work/?p=14418 Description

This “Out the Door Cabinet” is a cabinet that reminds me to take all the items inside the cabinet with me every time I leave my apartment, and also reminds me to put these items back to the cabinet when I enter. When I am in a hurry, I often times leave an important item, such as my keys, mask, umbrella, and etc., when I leave my apartment room, and when I come back home I tend to leave these items all over the place at random places. For my self-assisting device, I wanted to make a device that would help me fix these bad habits and remind me to take and put back these items from the cabinet when I leave and enter the door.

Images

Out the Door Cabinet

Inside of the cabinet: a removable middle shelf

Close-up of the lever switch and magnet that keeps the door closed when it is shut.

An ultrasonic ranger, a lever switch, a magnet that keeps the door closed, a removable middle shelf, and door hinges that allows the door to open and close.

Cabinet installed at home near the front door

Videos

Process Images

Cabinet design in Fusion 360

Testing LED Strip lights.

Hand-cut wooden case for the ultrasonic ranger. Cut a hole in the bottom of the cabinet to hide all the wires inside the back of the cabinet.

The arduino, breadboard, and all the wires are hidden inside the back of the cabinet, and there is another shelf that hides all these parts so that they are not visible.

Review

The way I worked on this project was, I worked on the wiring and computing part of the project and the fabrication part of the project separately. Therefore, after I was nearly completed with both parts I ran into the problem of how I put these together aesthetically, without ruining the design. Some of the solutions I came up with is first, I attached door hinges to the cabinet door so that I can easily open and close the cabinet. I also realized when I close the door, the door did not want to stay shut, so I decided to add a magnet so that the door will stay closed. Another problem was that I did not know where I should put the ultrasonic ranger, so I made a quickly made a case and attached it to the bottom of the cabinet, so that it can easily detect motion when I go near the cabinet. To hide all the wires I created a shelf to cover the back of the inside cabinet so that they are not visible.

Discussion

At first, I was not so enthusiastic about this idea of making a key reminder self assisting device. My concern was that the project would turn out to be either too simple and easy, or too complicated. I was sure that I wanted to use the ultrasonic ranger to detect motion when I am near my front door, and when it does, the LED strip lights would turn on. But this is a simple input and output therefore I wanted to add an extra component that would advance my idea. I thought about playing with the ultrasonic ranger so that it can tell whether I am leaving or entering the apartment, however I thought that it would be too complicated and not really necessary. I struggled to find the middle between too simple and too complicated, however during my prototype critique, some of the feedbacks I received from my classmates were really helpful. After hours of brainstorming, the solution that I came up with was to add a lever switch that detects whether the door is open or closed, and when the switch is closed, the blinking LED lights would turn off. Another problem I ran into was the wiring of the lever switch. I made a stupid mistake and didn’t remember to add a pull-down resistor. Because of this mistake, the switch was not functioning properly. Fabrication wise, I struggled to cut out a case for the ultrasonic ranger last minute since I did not have access to the laser cutter, however I went to the woodshop to cut it out by hand. It took me a while to figure out how to hide all the wires so that it does not look messy. I decided that I can use the back half part of my cabinet and hide it inside of the cabinet so that they are not visible. I cut a hole on the bottom of the cabinet so that the wires of the LED strip lights and the ultrasonic ranger are still connected, and I hand cut a shelf to hide all these components inside the cabinet.

During the final critique, I received some great feedbacks from my fellow students. First, I really appreciated their comments on the fabrication part of my project. It is definitely something I spent a lot of time on so I felt very relieved that people seemed to like it. Another comment that I really appreciated was, “Nice use of switch for detecting open/close state of the door”. It was really great to hear that people liked this component of my cabinet because it was a solution I came up with to a problem that I ran into in the beginning state of my project ideation. Another comment I would like to address is “Ultrasonic ranger seems finicky”. I would have to agree that the ultrasonic ranger was not working properly during the time of the critique. There was a small accident right before the critique and there were some wires that got disconnected that caused parts of my project to not work properly. However, they were all quickly fixed. 

Overall, I am satisfied with how my project turned out. This project was definitely a challenge for me, however I learned a lot from this experience. What I found the most enjoyable was the fabrication and design portion of this project. Fusion 360 is definitely something I would use again in the future so learning this program was very useful and valuable, and the same applies for learning how to use the laser cutter. As someone without any coding experience and background in engineering, I would say the most difficult part was the coding portion of the project. I tried to teach myself by searching up examples and watching several video tutorials and I would say it was a difficult and a frustrating process for me. However, through this experience, I definitely learned a lot.

I definitely am open to build another iteration of this project. This device is something that I needed and is something that will help me not only as a reminder, but as a product to help me fix my bad habits, such as leaving things at random places in the house. Some things I would do different is maybe add a speaker system that will remind me upcoming important events that will happen throughout the day. I think that would be a cool device, working as both a reminder to take/return items from cabinet and an agenda for the day.

Block Diagram & Schematics

Code

//Out the Door Reminder
//A cabinet that reminds me to take the itmes inside the cabinet when I leave the door, and put back the items into the cabinet when I enter the door.
//The Ultrasonic Ranger detects motion when I am near the door and when it detects motion, the LED strip lights up.
//When the cabinet door is open, the lights turn off.
//Credit: LED Strip code borrowed from PololuLedStrip library example: LedStripGradient.
//Credit: Some code borrowed from class website and arduino project hub
//https://courses.ideate.cmu.edu/60-223/f2021/tutorials/button-and-switch
//https://create.arduino.cc/projecthub/abdularbi17/ultrasonic-sensor-hc-sr04-with-arduino-tutorial-327ff6


#include <PololuLedStrip.h>

// ULTRASONIC RANGER
const int TRIG_PIN = 11; // Arduino pin connected to Ultrasonic Sensor's TRIG pin
const int ECHO_PIN = 10; // Arduino pin connected to Ultrasonic Sensor's ECHO pin
const int DISTANCE_THRESHOLD = 50 ; // centimeters

long duration;
int distance;


//LEVER MICROSWITCH
const int lswitch = 2;


//LED STRIP
PololuLedStrip<12> ledStrip;

//buffer for holding the colors (3 bytes per color).
#define LED_COUNT 47
rgb_color colors[LED_COUNT];


void setup()
{
  Serial.begin (9600);       // initialize serial port

  //Ultrasongic Ranger
  pinMode(TRIG_PIN, OUTPUT); // set arduino pin to output mode
  pinMode(ECHO_PIN, INPUT);  // set arduino pin to input mode

  //Lever Micro Switch
  pinMode(lswitch, INPUT);  //set arduino pin to input mode

}

void loop()
{
  //generate pulse to TRIG pin
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(5);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);


  //measure duration of pulse from ECHO pin
  duration = pulseIn(ECHO_PIN, HIGH);
  // calculate the distance
  distance = (duration / 2) * 0.0344;



  //if the ultrasonic ranger detects motion/distance, then the LED strips light up

  if (distance < DISTANCE_THRESHOLD)

  {
    // Update the colors.
    byte time = millis() >> 2;
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      byte x = time - 8 * i;
      colors[i] = rgb_color(x, 255 - x, x);
    }

    delay(10);
  }

  // if the ultrasonic ranger does not detect any motion/distance, the the LED strips do not light up

  else {
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = rgb_color(0, 0, 0);
    }
  }


  //if door is open, it turns off the LED light that was turned on due to the detection of motion/distance
  if ( digitalRead(lswitch) == HIGH )
  {
    for (uint16_t i = 0; i < LED_COUNT; i++)
    {
      colors[i] = rgb_color(0, 0, 0);
    }
  }



  //  //if the door is closed it prints "door is closed"
  //    if ( digitalRead(lswitch) == LOW)
  //    {
  //      Serial.println("door is closed");
  //      //      delay(20);
  //    }
  //
  //    //if the door is open it prints "door is opened"
  //    if ( digitalRead(lswitch) == HIGH )
  //    {
  //      Serial.println("door is opened");
  //      //      delay(20);
  //    }


  //  //     print the value to Serial Monitor
  //  Serial.print("distance: ");
  //  Serial.print(distance);
  //  Serial.println(" cm");
  //  delay(250);


  // Write the colors to the LED strip.
  ledStrip.write(colors, LED_COUNT);
}

 

]]>
Automatic Blind Opener https://courses.ideate.cmu.edu/60-223/f2021/work/automatic-blind-opener/ Tue, 02 Nov 2021 12:33:39 +0000 https://courses.ideate.cmu.edu/60-223/f2021/work/?p=14448 A device that opens and closes the blinds automatically depending on how bright it is outside.

An overall view of the device.

An image of the LED display when the blinds are closed.

An image of some of the inner parts of the device including the motor, power light, and some wiring.

An image of the photoresistor being used to detect light on the inside of the room.

Process Images

These are sketches of my device during early ideation stages. I had a few designs made, but I decided to go with the one on the left because I wanted a sophisticated look without having to build something too complex.

This is a picture of my electronics being soldered. I was considering using a breadboard because I knew that there were a lot of connections that had to be made, but at the same time I didn’t want anything to come undone while piecing everything together.

This is a picture of how my project orignially looked once I fabricated it. I had tried to form the shell by hand, but since I was inexperienced, I made a lot of mistakes that ended up having a huge effect on stability and aesthetic. I was reluctant to use a laser cutter, but it turned out for the better.

Discussion

After reflecting with my friend about all we had gone through with our projects, I realized a lot about my skills and deficiencies.

One huge realization is that I’m a lot better at conceptualizing than physically fabricating. I got supportive feedback about my functionality like, “Even though you went through a lot of design changes I think it still works well,” and, “I like the idea of contrasting light sources and rotating based on that,” but nobody commented on my structure or design except for one, “oof the wobbling stick.” One person even commented, “overall love the idea and would def purchase…,” and I genuinely think they would, just not my model. Even I could tell that my device had poor aesthetic!

Problems with electronics or programming were much more manageable than the ones that propped up during fabrication. I felt frustrated since it seemed like everyone else’s project seemed to come together cleanly while mine was a mess. I realized, however, that even though my fabrication skills weren’t where I wanted them to be, I could troubleshoot electronics and code pretty well. That was a relief for me to realize because I couldn’t celebrate the fact that my device worked since it’s look had me feeling like I completely failed.

This project has also helped me to be easier on myself. I hardly have any experience with fabrication; I hardly took any art classes where these skills were taught, I rarely ever engaged in personal projects that required this sort of skill, and I was generally unprepared for fabrication. Even now, my Mechanical Engineering curriculum is preparing me to be an extremely adept problem solver, but so far it’s been lacking in developing me as a designer/manufacturer. Regardless, I have a lot more respect for myself as a problem solver and can now see my blind spots.

If I were to build my device again, I would go with the exact same model. This time however, I would be much more intentional about assembling the parts in a way that was aesthetically pleasing. Overall though, I’m happy with the way everything turned out and I’m excited to apply what I learned to my next project.

Technical Information

Functional Block Diagram & Schematic

Code

// Automatic Blind Opener
// David Oladosu
// Turns a stepper motor to a certain position if the light on one
// photoresistor is higher than the other.

// INITIALIZE
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <AccelStepper.h>
const int STEP_PIN = 3;
const int DIR_PIN = 4;
const int WINDOWSENSOR = A0;
const int ROOMSENSOR = A1;
int motorPos = 0;
int blindsOpen = 3; // Value that keeps track of whether or not blinds are open
int currentWindowBrightness = 0;
int currentRoomBrightness = 0;
AccelStepper myMotor(1, STEP_PIN, DIR_PIN);
LiquidCrystal_I2C screen(0x27, 16, 2);

void setup() {
  Serial.begin(9600);
  pinMode(WINDOWSENSOR, INPUT);
  pinMode(ROOMSENSOR, INPUT);
  myMotor.setMaxSpeed(1000);
  myMotor.setAcceleration(500);
  screen.init();
  screen.backlight();
  

}

void loop() {
  int windowVal = analogRead(WINDOWSENSOR)* .78; //This value may have to be adjusted depending on the value of
  int roomVal = analogRead(ROOMSENSOR);          //the photoresistor you use.
  int windowBrightness = map(windowVal, 0, 970, 9, 1); //analogRead values mean nothing, but brightness on a
  int roomBrightness = map(roomVal, 0, 970, 9, 1);     //scale from 1-9 is useful. 1 is dark, 9 is bright.
  
  //The following conditionals have nested conditionals so that the LED screen only changes it's display when
  //it needs to. Otherwise, data constantly being sent to the screen slows down the stepper motor.
  
  if( roomBrightness > windowBrightness){
    if( blindsOpen != 0 ){ //If blinds aren't opened, open them and run this block of code
      blindsOpen = 0;
      currentWindowBrightness = windowBrightness;
      currentRoomBrightness = roomBrightness;
      screen.clear();
      screen.home();
      screen.print((String) "Wnd: " + windowBrightness);
      screen.setCursor(10,0);
      screen.print((String) "Rm:" + roomBrightness);
      screen.setCursor(0,1);
      screen.print("Closing blinds");
    }
    motorPos = 1000;
    myMotor.moveTo(motorPos);
    myMotor.run();
    if (myMotor.distanceToGo() == 0){
      screen.setCursor(0,1);
      screen.print("Blinds closed.");
    }
  }
  else{
    if( blindsOpen != 1 ){
      blindsOpen = 1;
      currentWindowBrightness = windowBrightness;
      currentRoomBrightness = roomBrightness;
      screen.clear();
      screen.home();
      screen.print((String) "Wnd: " + windowBrightness);
      screen.setCursor(10,0);
      screen.print((String) "Rm:" + roomBrightness);
      screen.setCursor(0,1);
      screen.print("Opening blinds");
    }
    motorPos = 0;
    myMotor.moveTo(motorPos);
    myMotor.run();
    if (myMotor.distanceToGo() == 0){
      screen.setCursor(0,1);
      screen.print("Blinds opened.");
    }
  }

  //If the numbers on the LED display should change but they haven't, change them.
  if(currentWindowBrightness != windowBrightness || currentRoomBrightness != roomBrightness){
      currentWindowBrightness = windowBrightness;
      currentRoomBrightness = roomBrightness;
      screen.home();
      screen.print((String) "Wnd: " + windowBrightness);
      screen.setCursor(10,0);
      screen.print((String) "Rm:" + roomBrightness);
    }
  myMotor.run();
  

}

 

]]>
Reusable Daily To Do List https://courses.ideate.cmu.edu/60-223/f2021/work/reusable-daily-to-do-list/ Tue, 02 Nov 2021 05:32:59 +0000 https://courses.ideate.cmu.edu/60-223/f2021/work/?p=14225 A reusable to do list that resets itself every morning to help you keep track of your daily tasks.

Photos

Final to do list – overall photo

Detail view of the separate components: the list, the stand, and the marker holder

Detailed view of the servo arms activating the switches and turning the LEDs back on

Demonstration of the whiteboard areas for easy editing and changing of daily tasks

View of the list in context, being placed by the bed for reminders in the morning and review at night

Process: Decision Points

One of the biggest decision points for me along this process was figuring out how I would reset the tasks each day. I had decided to use these manual switches in my design since I felt that turning them on and off reflected the same satisfaction of crossing something off a list, but this made it more difficult to reset the tasks compared to a button, as well as the challenge to scale up my design to accommodate five tasks. I contemplated several different methods such as a panel that could shift up and down to turn the switches back on, changing which side was “To Do” and which was “Done” each day, or finding a way to flip the switches internally, but these all had quite adverse effects on the human interaction with these switches, often compromising the ability to flip the switches manually. In my prototype and later my final design, I decided to use a servo arm to flip the switches manually since they worked consistently and did not interfere with the human interaction when not in use. While this was mechanically heavy and required many servos when applied to five tasks, I felt that this was the most efficient and effective method for my time.

Another major decision point in this process was what the layout of the items would be on the final product. This had to be done later in the process since it was largely driven by the side of the components relative to one another, but it was also the deciding factor in much of my final wiring layout and had to take that into consideration as well. While I had initially envisioned the board being taller than it was wide, being close to 8.5 by 11 paper dimensions, the dimensions for ideal writing space as well as the mechanics made it much shorter than I expected. In the end, I opted for square proportions as it seemed to fit five tasks (my average amount of daily tasks) nicely while also providing enough housing space for the internal components.

Process Images

My initial concept sketch at the bottom of the page had all the right components, but it was definitely a whole other challenge to determine the logistics and actually build it.

The highly simplified wiring diagram I made for myself before attempting to wire the same structure five times over.

With the same wiring repeated five times, it was important that I kept the wires as organized as possible, leading me to color code them (yellow for the servo, purple for the switches, blue for the LEDs, and so on).

Despite my careful planning of the wiring and implementation, some wires inevitably changed order, leaving my inputs and outputs quite jumbled. While the LEDs, servos, and switches sections stayed together, Switch 1 would turn off LED 4 and the servos would activate all out of order, making it quite hard to sort out. I decided to make the switch wiring the “driving” control by keeping that in place and changing the mapping of the LEDs and servos to match them.

Discussion

Overall, I am quite happy with how this project turned out! Coming from very little coding experience and no experience with electronics, I think I am quite proud of what I have been able to accomplish. The main goal I had for myself with this project, in the words of one of my professors, was to have “simple things done well” and choose something that would allow me to ensure it would be functional and resolved to the best of my ability. While I had some feedback regarding “a reward / punishment route” to provide motivation for these tasks, I wanted to focus more on what made traditional to-do lists helpful and satisfying for me and what works best for my lifestyle. I didn’t want to add a punishment system because I felt that would hinder the likelihood of me using this in the future, and I enjoy the passive, no pressure nature of to-do lists as they are now with more gentle reminders of what I should get done. While the code and wiring seemed like it would be quite simple and straightforward, it was surprisingly still quite the challenge, especially when doing things five times over! One of the biggest challenges for me was getting the mechanism of the servos to actually flip the switches, as I had spent many hours troubleshooting having them hit and go too far, being at the wrong height to hit and have enough force, having servos that did not work or were too weak, and so on. The main takeaway from that experience for me was how many different problems can show up with the same error and to be mindful that what worked to solve the problem last time may not work again in the same way. Despite these challenges, I think I learned a lot about making something “real” as in design we often stop our process at the concept and rarely resolve the finer details to make a model that works as intended. If I were to do this project again, knowing what I know now, I would love to implement some of the feedback that I got from my peers, such as “being to control each section”, as I think that would make the product much more refined by only switching on the ones that had been turned off.

Block Diagram

Schematic Diagram

Code

/*
    Reusable To Do List

    Description: This project creates a 5 switch task system with LEDs to signal whether or not they are
    flipped and the task is done, additionally with a real-time-clock plugin for servo motors to
    reset the switches and tasks at aspecified time each day.

    Resources Used:
    Real Time Clock: https://create.arduino.cc/projecthub/MisterBotBreak/how-to-use-a-real-time-clock-module-ds3231-bc90fe
    Mechanism Inspiration: https://create.arduino.cc/projecthub/viorelracoviteanu/useless-box-with-arduino-d67b47
*/

// PIN MAPPING
//  pin   | mode   | description
//  ------|--------|------------
//  2      input    Switch 1
//  3      input    Switch 2
//  4      input    Switch 3
//  5      input    Switch 4
//  6      input    Switch 5
//  8      ouput    LED 5
//  9      output   LED 4
//  10     output   LED 3
//  11     output   LED 1
//  12     output   LED 2
//  A0     output   Servo 4
//  A1     output   Servo 5
//  A2     output   Servo 3
//  A3     output   Servo 2
//  A4     output   Servo 1
//

//#include <Wire.h>
//#include <ds3231.h>
#include <Servo.h> // Servo library

//struct ts t;

Servo servo1; // one servo for each switch, top to bottom
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;

const int SERVOPIN1 = A4; //Mappings change to fit wiring of switches
const int SERVOPIN2 = A3;
const int SERVOPIN3 = A2;
const int SERVOPIN4 = A0;
const int SERVOPIN5 = A1;

const int SWITCHPIN1 = 2;
const int SWITCHPIN2 = 3;
const int SWITCHPIN3 = 4;
const int SWITCHPIN4 = 5;
const int SWITCHPIN5 = 6;

const int LEDPIN1 = 11;
const int LEDPIN2 = 12;
const int LEDPIN3 = 10;
const int LEDPIN4 = 9;
const int LEDPIN5 = 8;

unsigned long timerOne = 0; //Timer for demo mode reset

void setup() {
  Serial.begin(9600);
  //Wire.begin();
  //DS3231_init(DS3231_CONTROL_INTCN); //RTC setup
  //t.hour=9;
  //t.min=0;
  //t.sec=0;
  //t.mday=26;
  //t.mon=10;
  //t.year=2021;

  //DS3231_set(t);

  pinMode(SERVOPIN1, OUTPUT);
  pinMode(SERVOPIN2, OUTPUT);
  pinMode(SERVOPIN3, OUTPUT);
  pinMode(SERVOPIN4, OUTPUT);
  pinMode(SERVOPIN5, OUTPUT);

  pinMode (SWITCHPIN1, INPUT);
  pinMode (SWITCHPIN1, INPUT);
  pinMode (SWITCHPIN1, INPUT);
  pinMode (SWITCHPIN1, INPUT);
  pinMode (SWITCHPIN1, INPUT);

  pinMode (LEDPIN1, OUTPUT);
  pinMode (LEDPIN1, OUTPUT);
  pinMode (LEDPIN1, OUTPUT);
  pinMode (LEDPIN1, OUTPUT);
  pinMode (LEDPIN1, OUTPUT);

  servo1.attach(SERVOPIN1); // set up each servo on the corresponding data pin
  servo2.attach(SERVOPIN2);
  servo3.attach(SERVOPIN3);
  servo4.attach(SERVOPIN4);
  servo5.attach(SERVOPIN5);

  servo1.write(140); // servo reset to neutral position
  servo2.write(140);
  servo3.write(140);
  servo4.write(140);
  servo5.write(140);
}

void loop() {
  int switch1State;
  switch1State = digitalRead(SWITCHPIN1);
  int switch2State;
  switch2State = digitalRead(SWITCHPIN2);
  int switch3State;
  switch3State = digitalRead(SWITCHPIN3);
  int switch4State;
  switch4State = digitalRead(SWITCHPIN4);
  int switch5State;
  switch5State = digitalRead(SWITCHPIN5);


  if (switch1State == 1) {
    digitalWrite (LEDPIN1, HIGH); //Mapping switch state to LED state
  }
  if (switch1State == 0) {
    digitalWrite (LEDPIN1, LOW);
  }

  if (switch2State == 1) {
    digitalWrite (LEDPIN2, HIGH);
  }
  if (switch2State == 0) {
    digitalWrite (LEDPIN2, LOW);
  }

  if (switch3State == 1) {
    digitalWrite (LEDPIN3, HIGH);
  }
  if (switch3State == 0) {
    digitalWrite (LEDPIN3, LOW);
  }

  if (switch4State == 1) {
    digitalWrite (LEDPIN4, HIGH);
  }
  if (switch4State == 0) {
    digitalWrite (LEDPIN4, LOW);
  }

  if (switch5State == 1) {
    digitalWrite (LEDPIN5, HIGH);
  }
  if (switch5State == 0) {
    digitalWrite (LEDPIN5, LOW);
  }

  if (millis() - timerOne >= 30000) { //Refresh rate of screen every 30000 milliseconds
    // this is demo mode, in real mode: if (t.hour == 9 && millis - timerOne >= 3600000) { to occur once a day
    servo1.write(30); // tell the servo to go to 90º
    delay(200);
    servo1.write(140);
    delay(500);

    servo2.write(30);
    delay(200);
    servo2.write(140);
    delay(500);

    servo3.write(30);
    delay(200);
    servo3.write(140);
    delay(500);

    servo4.write(30);
    delay(200);
    servo4.write(140);
    delay(500);

    servo5.write(30);
    delay(200);
    servo5.write(140);
    delay(500);

    timerOne = millis();
  }
}

 

]]>
Nice Things Alarm https://courses.ideate.cmu.edu/60-223/f2021/work/nice-things-alarm/ Tue, 02 Nov 2021 05:02:05 +0000 https://courses.ideate.cmu.edu/60-223/f2021/work/?p=14333 Overview

An accessory to an alarm clock which prints out nice quotes in response to sensing the sound of an alarm.

A more in-depth video of the full functionality, including responsiveness to sound:

 

A video of the final project:

 

Featured image of the overall project.

 

Detail shot 1: Thermal printer which uses heat (as one might expect) to print text onto a roll of receipt paper.

 

Detail shot 2: SD card for storing large sets of data (text, in this case).

 

Detail shot 3: Microphone to sense input sound.

 

Usage shot 1: Alarm clock sits comfortably beside the box; with clock speakers next to the microphone.

 

Usage shot 2: Speaker against the clock.

Process images and review

One pivot point was deciding how to import a large-ish amount of data into the Arduino. Rather than storing all the string data on the Arduino’s tiny brain, I split my Google doc full of quotes (perpetually accumulating) into many little .txt files with a Python script.

Decision point 1: Quotes and a quote splitter.

Another pivot point was when I realized my dxf for the wooden box didn’t have a kern that allowed press-fitting. I considered recutting and perhaps modulating the design of the final product, but owing to the time constraints, I ended up rapidly locating wood glue and gluing my box together, hoping it would cure overnight (and it mostly did!)

Decision point 2: Having to construct a box with wood glue.

Additionally, here are a few more pictures of the process:

The first successful run of the printer!

 

…and a buggy run of the printer when trying to sort out multiple serial ports. It’s modern art?

 

The SVG for the graphics on top of the box that I then laser cut!

Discussion

“I wonder if there is a place that already has a “hub” of positive messages that you could source from, that way it could be more of a surprise for you?”

I really like the idea of the messages being pleasant surprises. However, I feel like the large hubs of positive quotes that I might find online would be those really cheesy, hashtag-inspirational ones that are nice but somewhat grating and simplistic. This does spawn another idea, though. I have most of my conversations with my partner over Discord (…haha) and Discord has a really solid and in-depth data request system, so I think I could do some text parsing to create little snippets from nice past conversations that I could randomly output every morning. That would fulfill all the personal, warm, and random categories.

“The printing format is super flexible and lets you print everything from jokes and riddles to memories and reminders.”

I like it too—I think if I were to continue developing this work, a large part would be increasing the diversity of the text repository. Another critiquer mentioned the receipts as a way to get news or weather so that he might check his phone less in the mornings, and I also like that intention.

Overall, I am moderately happy with how the project came out. I got burnt-out/sick during the middle of it, losing some momentum, and also realized that I would have to purchase ~$100 worth of materials (plus replenishing the receipt paper regularly) in order to keep using the project, which kind of deterred me from being as invested in the final product. I think the final product’s physical fabrication is a little shaky, and I would like to get better at this aspect of physical computing. However, I like the artistic implications of the project and the organic touches that I added to it. The process of crowdsourcing poetry and chopping it up into little bits was therapeutic, especially knowing that I would have something that I could hold in my hands at the end of it. Really though, my favorite parts of this project involved community, i.e., learning people’s favorite poems or handing out the “test cases” and seeing people’s faces light up with joy.

I found some limitations in knowledge when I spent an embarrassing amount of time in the laser room trying to piece my box together around my project. I would like to get better at CAD so I can create nicer, organic forms. I also hit some roadblocks with maintaining two separate serial communication lines (with the SoftwareSerial library, which turns any pair of digital pins into data RX/TX lines)—one for debugging, and another for the thermal printer. And I had a weirdly hard time trying to figure out how to convert ints to strings because it’s different for C, normal C++, and Arduino C++?

I am not sure if I want to invest in another, long-term version of this project, but if I were to, there are a few things I would do differently. I’d probably make the speaker a little more sturdy—perhaps panel mounted with a hood above it so it stays in place nicely and outside sound doesn’t interfere as much. I’d probably manipulate the strings a little better so words don’t break in the middle (the printer seems to simply split strings into new lines wherever the receipt isn’t wide enough). I’d also position the printer a bit more nicely, so the receipt paper is closer to the top of the box and feeding and tearing it out is easier.

Technical information

 

Block diagram

Schematic

Code:

/*------------------------------------------------------------------------
Copyright 2021 Shenai Chan

Permission is hereby granted, free of charge, to any person obtaining a 
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation 
the rights to use, copy, modify, merge, publish, distribute, sublicense, 
and/or sell copies of the Software, and to permit persons to whom the 
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included 
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
IN THE SOFTWARE.
--------------------------------------------------------------------------*/

/*------------------------------------------------------------------------
Description:
Data is read into the Arduino by way of a micro SD card reader and printed
onto a receipt with a thermal printer when the appropriate threshold of 
sound is reached (as detected by sound detector).
--------------------------------------------------------------------------*/

/*------------------------------------------------------------------------
Connections:
Printer RX              <-->  6 Output
Printer TX              <-->  5 Input
SD MOSI                 <--> 11 Input
SD MISO                 <--> 12 Input
SD CLK                  <--> 13 Input
SD CS                   <-->  4 Input
Sound Detector Gate     <-->  2 Input
Sound Detector Envelope <--> A0 Input
--------------------------------------------------------------------------*/

// Initializing the printer:

#include "Adafruit_Thermal.h"

// Creating a separate serial channel for the printer specifically
// to talk to the Arduino
#include "SoftwareSerial.h"
#define TX_PIN 6 // Arduino transmit  YELLOW WIRE  labeled RX on printer
#define RX_PIN 5 // Arduino receive   GREEN WIRE   labeled TX on printer

SoftwareSerial mySerial(RX_PIN, TX_PIN); // Declare SoftwareSerial obj first
Adafruit_Thermal printer(&mySerial);     // Pass addr to printer constructor

/*-----------------------------------------------------------------------*/

// Initializing the SD card:

#include <SPI.h>
#include <SD.h>

const int chipSelect = 4;

/*-----------------------------------------------------------------------*/

// Initializing the sound detector connections

#define PIN_GATE_IN 2
#define PIN_ANALOG_IN A0

/*-----------------------------------------------------------------------*/

// Timer variables

unsigned long timer = 0;
const int wait = 5000;

/*-----------------------------------------------------------------------*/

void setup() {

  mySerial.begin(19200);  // Initialize SoftwareSerial
  printer.begin();        // Init printer (same regardless of serial type)
  
  // Open serial communications and wait for port to open:
  Serial.begin(19200);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");

  // init pin for sound detector
  pinMode(PIN_GATE_IN, INPUT);
  
  delay(10000);

}

void loop() {
  int value;

  // Check the envelope input
  value = analogRead(PIN_ANALOG_IN);

  // Convert envelope value into a message
  Serial.print("Status: ");
  Serial.println(value);
  delay(1000);

  // If sound is loud enough
  if (value >= 20) {
    // and it's been long enough since the last printing
    if ((millis() - timer) >= wait) {
      timer = millis();
      int i = random(0, 19);

      // take a random .txt file
      String path = "text" + String(i, DEC) + ".txt";
      File myFile = SD.open(path);
      String text = "";

      // and print it
      if (myFile) { 
        while (myFile.available()) { //execute while file is available
          char letter = myFile.read(); //read next character from file
          text += letter;
        }
        myFile.close(); //close file
        printer.println("");
        printer.println(text);
        printer.println("");
      }
      else {
          Serial.println("error opening "+path);
      }
    }
  } 
}

 

]]>
Dice Lightning https://courses.ideate.cmu.edu/60-223/f2021/work/dice-lightning/ Mon, 01 Nov 2021 22:57:08 +0000 https://courses.ideate.cmu.edu/60-223/f2021/work/?p=14263  

Final completed project

 

Highlighted Part

Here is the keypad which I soldered and screwed onto the wood board

 

Item in Action

Pushing the 5 button to set the number of kicks

 

Pushing the * button to initiate kicking

 

Here is the first kick with the dice in the air

 

Decisions that affected Output

The first big decision that changed the outcome significantly was the change from IR remote and IR sensor for wireless input to the metal keypad. This was because I felt like the keypad would be more fun to use and since this device is going to e used really close by to me anyways so there really isn’t any need for the wireless device.

The second big decision was the removal of the wooden prongs that would hold the top dice platform in place when it got kicked up. As I was putting the wooden pieces in they weren’t placed perfectly and created friction with the wooden platform preventing it from kicking up as hard as it could. It was also making the glueing of the device really difficult since I had put them in before glueing the whole device together.

Here is what it looked like with the wooden rods in

This is the attachment of the keypad to the rest of the circuit with the big rainbow cable

This is the first prototype of the project before any external components were added

 

Discussion

I think some additional stability for the upper platform would help a lot for actually flipping dice so that it does not tilt, as well as some more height with the plastic cover so the dice can bounce/flip.” I agree about the additional stability for the platform but the way I was implementing was not a viable option because the order that I did things in, but the plastic cover doesn’t need any more height added to it since the solenoids don’t kick it high enough to ever hit the ceiling anyways.

“Doesn’t seem to actually flip the dice consistently, but that could be fixed with a little more iteration.” This is true as the solenoids struggle with the weight of the wooden platform and the dice on it, this could be solved by adding more solenoids to simply kick the platform up with more force.

I am extremely proud and happy with the project, for the most part it does everything I want it to and it looks really nice. I would have liked for it to only need one cable connecting it instead of two on the back since having two makes it a little annoying to use. I would also make the top platform out of a lighter wood like balsa without having to use a laser cutter. Other than that though the project works exactly as intended and is really fun to use and look at.

I really enjoyed using the laser cutters. Working with the wood and acrylic and putting the pieces together was a lot of fun and I think I’ll definitely be doing it again in the future. If I could go back I would tell myself to start with the box and then put the circuitry inside the box and go from there instead of the other way around since I just shoved all of my circuits in the box haphazardly instead of putting everything in a nice spot to make it look good.

If I were to build another iteration I would for sure add more solenoids to make it kick harder since that was the main issue that I was having. I would also add some sort of voltage transformer to the circuit to power the Arduino inside so that I don’t have to have two cables coming out of the back of the project to make it easier to use.

 

Schematic and Block Diagram

Block diagram

 

Circuit schematic

Code

/*
 * Dice Lightning
 * 
 * Team: Ronald Gonzalez
 * 
 * Description:
 *   The code takes turns turning on the input pins
 *   of the keypad and then depending on where it 
 *   read an output it knows what the key pressed
 *   was.
 *   
 *   Then it will call the solenoid function which
 *   based on the number in keypadVal will turn off
 *   and on the solenoid so that it starts kicking
 *   the dice around.
 * 
 *     Arduino Pin | Description
 *     ------------|---------------------
 *     2           | SolenoidOn
 *     3           | KeypadIn1       
 *     5           | KeypadIn2   
 *     6           | KeypadIn3      
 *     8           | KeypadOut1     
 *     9           | KeypadOut2   
 *     10          | KeypadOut3
 *     11          | KeypadOut4
 *   
 */

// Solenoid Control
#define SOLENOIDON 2

// Keypad Input Signals
#define KEYPADIN1 3
#define KEYPADIN2 5
#define KEYPADIN3 6

// Keypad Output Signals
#define KEYPADOUT1 8
#define KEYPADOUT2 9
#define KEYPADOUT3 10
#define KEYPADOUT4 11

// Delay for Button Pushes
#define DELAY 250

// Keeps track of number being pressed
unsigned int keypadVal = 0;

// Tells the solenoid to start firing
bool start = false;


void setup() {
  // Keypad setup
  pinMode(KEYPADIN1, OUTPUT);
  pinMode(KEYPADIN2, OUTPUT);
  pinMode(KEYPADIN3, OUTPUT);
  pinMode(KEYPADOUT1, INPUT);
  pinMode(KEYPADOUT2, INPUT);
  pinMode(KEYPADOUT3, INPUT);
  pinMode(KEYPADOUT4, INPUT);

  // Solenoid setup
  pinMode(SOLENOIDON, OUTPUT);
}

//Makes the solenoid kick keypadVal number of times
void solenoid(){
  
  start = false; //reset start so that it doesn't keep firing
  
  if(keypadVal == 0) return;
  
  for(int i = 0; i < keypadVal; i++) {
    digitalWrite(SOLENOIDON, HIGH);
    delay(2 * DELAY);
    digitalWrite(SOLENOIDON, LOW);
    delay(3 * DELAY);
  }
  
  keypadVal = 0; //reset keypadVal
}

// Reads from the keys on the keypad and changes keypadVal
// or start depending on the button pressed
void key(int row){
  int keys[4];
  int sig; //signal being sent to key

  /* 
   * Based on the row of the keypad that we are 
   * working with the keys and where we send the
   * signal to change
   *
   */
  if(row == 1) {
    int keys[] = {11, 1, 4, 7};
    sig = KEYPADIN3;
  }
  else if(row == 2) {
    int keys[] = {0, 2, 5, 8};
    sig = KEYPADIN1;
  }
  else if(row == 3) {
    int keys[] = {12, 3, 6, 9};
    sig = KEYPADIN2;
  }

  // Send a signal to the keypad
  digitalWrite(sig, HIGH);

  // Read from all keypadOuts to see what key is being pressed
  if(digitalRead(KEYPADOUT1) == HIGH) {
    if(row == 1) start = true; // * key, also the start
    else if(row == 2) keypadVal = 0; // # key, also the reset
    else if(row == 3) keypadVal * 10; // 0 key
    delay(DELAY);
  }
  if(digitalRead(KEYPADOUT2) == HIGH) {
    keypadVal = keypadVal * 10 + keys[1];
    delay(DELAY); 
  }
  if(digitalRead(KEYPADOUT3) == HIGH) {
    keypadVal = keypadVal * 10 + keys[2];
    delay(DELAY);
  }
  if(digitalRead(KEYPADOUT4) == HIGH) {
    keypadVal = keypadVal * 10 + keys[3];
    delay(DELAY);
  }

  // Turn signal back off
  digitalWrite(sig, LOW);

}

// Send all signals to the keypad in order
void loop() {
  
  for(int i = 1; i <= 3; i++) key(i);

  // If the start button has been pressed the solenoid will fire
  if(start) solenoid();
}

 

]]>